-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit e1b292e
Showing
10 changed files
with
1,113 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
tests/build/ |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
|
||
# DebouncedLDR | ||
|
||
This library implements a class that applies quantization and hysteresis to the | ||
analog readings of a Light Dependent Resistor (LDR) so that applications can | ||
work with logical light levels instead of physical light readings. Using this | ||
library, applications can easily avoid the flickering effects that can happen | ||
with simple thresholding. | ||
|
||
## Theory of operation | ||
|
||
The `DebouncedLDR` class does not do any of the actual GPIO manipulation. The | ||
client application is expected to call `DebouncedLDR::update` frequently | ||
(i.e. every few milliseconds) with the latest reading from the analog pin. The | ||
`update` method returns the current logical light level. | ||
|
||
The light level value returned by `update` represents a logical light level | ||
between zero and the maximum level passed to the instance's constructor. The | ||
`noise` parameter to the constructor is used to define "meaningful" changes in | ||
the LDR reading, a higher `noise` value requires a larger change in the readings | ||
to cause a change in the reported light level, and a `noise` value of zero will | ||
do no debouncing of the readings. | ||
|
||
## Testing | ||
|
||
This library includes unit tests that can be run on a host system (not on the | ||
Arduino) using CMake. From the top-level of the library repo, these commands | ||
should run the tests: | ||
|
||
``` | ||
cd tests | ||
cmake -S . -B build | ||
cmake --build build && (cd build; ctest --output-on-failure) | ||
``` | ||
|
||
The first `cmake` command above only needs to be run once, the second command | ||
can be run each time the source is changed to check the test status. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
SerialLDRTester | ||
Reads an LDR attached to an analog input pin and prints the current light | ||
level to the serial port. | ||
This example code is in the public domain. | ||
*/ | ||
|
||
|
||
#include <DebouncedLDR.h> | ||
|
||
constexpr static int LDR_PIN = A0; | ||
|
||
// An LDR with readings between [0, 1023] that will return ten light levels | ||
// and will consider readings within 100 of each other to be the same level. | ||
DebouncedLDR ldr(1023, 9, 100); | ||
|
||
void setup() | ||
{ | ||
Serial.begin(115200); | ||
|
||
pinMode(LDR_PIN, INPUT); | ||
} | ||
|
||
void loop() | ||
{ | ||
static DebouncedLDR::Level prev_level = 0; | ||
|
||
auto level = ldr.update(analogRead(LDR_PIN)); | ||
|
||
if (level != prev_level) { | ||
Serial.print("Light level now "); | ||
Serial.println(level); | ||
prev_level = level; | ||
} | ||
|
||
delay(50); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
DebouncedLDR KEYWORD1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
name=DebouncedLDR | ||
version=1.0.0 | ||
author=Zach Vonler | ||
maintainer=Zach Vonler <zvonler@gmail.com> | ||
sentence=Library for debouncing a light-dependent resistor. | ||
paragraph=Applies hysteresis to analog readings to prevent flicker. | ||
category=Sensors | ||
url=https://github.com/zvonler/DebouncedLDR | ||
architectures=* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* | ||
Copyright 2023 Zach Vonler <zvonler@gmail.com> | ||
This file is part of DebouncedLDR. | ||
DebouncedLDR is free software: you can redistribute it and/or modify it | ||
under the terms of the GNU General Public License as published by the Free | ||
Software Foundation, either version 3 of the License, or (at your option) | ||
any later version. | ||
DebouncedLDR is distributed in the hope that it will be useful, but | ||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
more details. | ||
You should have received a copy of the GNU General Public License along with | ||
DebouncedLDR. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include "DebouncedLDR.h" | ||
|
||
/*---------------------------------------------------------------------------*/ | ||
|
||
DebouncedLDR::DebouncedLDR(Reading max_reading, Level max_level, Reading noise) | ||
: _max_reading(max_reading) | ||
, _max_level(max_level) | ||
, _noise(noise) | ||
, _level_width(_max_reading / (_max_level + 1.0f)) | ||
{ | ||
} | ||
|
||
DebouncedLDR::Level | ||
DebouncedLDR::update(Reading reading) | ||
{ | ||
Level new_level; | ||
if (reading >= _max_reading) { | ||
new_level = _max_level; | ||
} else { | ||
new_level = floor(reading / _level_width); | ||
} | ||
|
||
if (new_level != _level) { | ||
Reading diff = max(reading, _last_reading_on_change) - min(reading, _last_reading_on_change); | ||
if (diff > _noise) { | ||
_level = new_level; | ||
_last_reading_on_change = reading; | ||
} | ||
} | ||
|
||
return _level; | ||
} | ||
|
||
/*---------------------------------------------------------------------------*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* | ||
Copyright 2023 Zach Vonler <zvonler@gmail.com> | ||
This file is part of DebouncedLDR. | ||
DebouncedLDR is free software: you can redistribute it and/or modify it | ||
under the terms of the GNU General Public License as published by the Free | ||
Software Foundation, either version 3 of the License, or (at your option) | ||
any later version. | ||
DebouncedLDR is distributed in the hope that it will be useful, but | ||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
more details. | ||
You should have received a copy of the GNU General Public License along with | ||
DebouncedLDR. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#ifndef debounced_ldr_h | ||
#define debounced_ldr_h | ||
|
||
#ifdef UNIT_TESTING | ||
#include <algorithm> | ||
#include <cmath> | ||
#include <cstdint> | ||
#define floor std::floor | ||
#define min std::min | ||
#define max std::max | ||
#else | ||
#include <Arduino.h> | ||
#endif | ||
|
||
/*---------------------------------------------------------------------------*/ | ||
|
||
/** | ||
* Represents an LDR with latching light levels to prevent flicker. | ||
*/ | ||
class DebouncedLDR { | ||
public: | ||
using Reading = uint16_t; | ||
using Level = uint16_t; | ||
|
||
/** | ||
* Creates an instance that will map readings in the range [0, max_reading] | ||
* to light level values in the range [0, max_level], and will require the | ||
* reading to change by more than noise to cause a light level change. | ||
*/ | ||
DebouncedLDR(Reading max_reading, Level max_level, Reading noise); | ||
|
||
/** | ||
* Adds the reading and returns the current level. | ||
*/ | ||
Level update(Reading reading); | ||
|
||
Level light_level() const { return _level; } | ||
|
||
Reading max_reading() const { return _max_reading; } | ||
Level max_level() const { return _max_level; } | ||
Reading noise() const { return _noise; } | ||
|
||
private: | ||
Reading _max_reading; | ||
Level _max_level; | ||
Reading _noise; | ||
float _level_width; | ||
Level _level = 0; | ||
Reading _last_reading_on_change = 0; | ||
}; | ||
|
||
/*---------------------------------------------------------------------------*/ | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
cmake_minimum_required(VERSION 3.14) | ||
project(my_project) | ||
|
||
# GoogleTest requires at least C++14 | ||
set(CMAKE_CXX_STANDARD 14) | ||
set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||
|
||
include(FetchContent) | ||
FetchContent_Declare( | ||
googletest | ||
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip | ||
) | ||
# For Windows: Prevent overriding the parent project's compiler/linker settings | ||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) | ||
FetchContent_MakeAvailable(googletest) | ||
|
||
enable_testing() | ||
|
||
add_compile_definitions(UNIT_TESTING) | ||
|
||
add_executable( | ||
test_debounced_ldr | ||
test_debounced_ldr.cpp | ||
../src/DebouncedLDR.cpp | ||
) | ||
target_link_libraries( | ||
test_debounced_ldr | ||
GTest::gtest_main | ||
) | ||
|
||
include(GoogleTest) | ||
gtest_discover_tests(test_debounced_ldr) |
Oops, something went wrong.