Skip to content

Commit db82188

Browse files
committed
Switch Analog On_Change to adjust hysterisis as it scales up
1 parent f7eebe6 commit db82188

File tree

2 files changed

+54
-12
lines changed

2 files changed

+54
-12
lines changed

src/components/analogIO/Wippersnapper_AnalogIO.cpp

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ void Wippersnapper_AnalogIO::setADCResolution(int resolution) {
8787
analogReadResolution(16);
8888
_nativeResolution = 12;
8989
#elif defined(ARDUINO_ARCH_ESP32)
90-
scaleAnalogRead = false; // probably should be false, handled in bsp
90+
scaleAnalogRead = false; // should be false, handled in bsp (analogReadResolution)
91+
analogReadResolution(resolution); // 16 bit values (shifted from 12 or 13bit)
9192
#if defined(ESP32S3)
9293
_nativeResolution = 13; // S3 ADC is 13-bit, others are 12-bit
9394
#else
@@ -317,13 +318,17 @@ bool Wippersnapper_AnalogIO::encodePinEvent(
317318
The current software timer value.
318319
@param pin
319320
The desired analog pin to check
321+
@param periodOffset
322+
Offset to add to the pin's period (used for on_change).
320323
@returns True if pin's period expired, False otherwise.
321324
*/
322325
/**********************************************************/
323326
bool Wippersnapper_AnalogIO::timerExpired(long currentTime,
324-
analogInputPin pin) {
325-
if (currentTime - pin.prvPeriod > pin.period && pin.period != 0L)
326-
return true;
327+
analogInputPin pin, long periodOffset) {
328+
if (pin.period + periodOffset != 0L &&
329+
currentTime - pin.prvPeriod > (pin.period + periodOffset)) {
330+
return true;
331+
}
327332
return false;
328333
}
329334

@@ -342,9 +347,8 @@ void Wippersnapper_AnalogIO::update() {
342347
if (_analog_input_pins[i].enabled == true) {
343348

344349
// Does the pin execute on-period?
345-
if ((long)millis() - _analog_input_pins[i].prvPeriod >
346-
_analog_input_pins[i].period &&
347-
_analog_input_pins[i].period != 0L) {
350+
if (_analog_input_pins[i].period != 0L &&
351+
timerExpired(millis(), _analog_input_pins[i])) {
348352
WS_DEBUG_PRINT("Executing periodic event on A");
349353
WS_DEBUG_PRINTLN(_analog_input_pins[i].pinName);
350354

@@ -366,22 +370,57 @@ void Wippersnapper_AnalogIO::update() {
366370
encodePinEvent(_analog_input_pins[i].pinName,
367371
_analog_input_pins[i].readMode, pinValRaw, pinValVolts);
368372

369-
// IMPT - reset the digital pin
373+
// mark last execution time
370374
_analog_input_pins[i].prvPeriod = millis();
371375
}
372376
// Does the pin execute on_change?
373377
else if (_analog_input_pins[i].period == 0L) {
374378

379+
// TODO: after testing combine these two conditionals to just send the event and not debug print.
380+
if (_analog_input_pins[i].prvPeriod == 0L) {
381+
// first time reading pin, no previous timestamp so send event + update prvPeriod
382+
WS_DEBUG_PRINT("First time reading pin A");
383+
WS_DEBUG_PRINTLN(_analog_input_pins[i].pinName);
384+
}
385+
else if (timerExpired(millis(), _analog_input_pins[i], 500)) {
386+
// timer expired, send event + update prvPeriod
387+
WS_DEBUG_PRINT("Timer passed for pin A");
388+
WS_DEBUG_PRINTLN(_analog_input_pins[i].pinName);
389+
}
390+
else {
391+
// last event was too recently, skip this one...
392+
WS_DEBUG_PRINTLN("Timer has not expired, continue...");
393+
continue;
394+
}
395+
375396
// note: on-change requires ADC DEFAULT_HYSTERISIS to check against prv
376397
// pin value
377398
uint16_t pinValRaw = getPinValue(_analog_input_pins[i].pinName);
378399

400+
// All boards ADC values scaled to 16bit, in future we may need to adjust dynamically
401+
uint16_t maxDecimalValue = 65535;
402+
403+
// Calculate threshold values - using DEFAULT_HYSTERISIS for first third (1/3) of the range,
404+
// then 2x DEFAULT_HYSTERISIS for the middle 1/3, and 4x DEFAULT_HYSTERISIS for the last 1/3.
405+
// This should allow a more wifi blip tolerant threshold for the both ends of the range.
406+
float CURRENT_HYSTERISIS;
407+
if (pinValRaw < maxDecimalValue / 3) {
408+
CURRENT_HYSTERISIS = DEFAULT_HYSTERISIS;
409+
} else if (pinValRaw < (maxDecimalValue / 3) * 2) {
410+
CURRENT_HYSTERISIS = DEFAULT_HYSTERISIS * 2;
411+
} else {
412+
CURRENT_HYSTERISIS = DEFAULT_HYSTERISIS * 4;
413+
}
414+
415+
416+
417+
// get the threshold values for previous pin value
379418
uint16_t _pinValThreshHi =
380419
_analog_input_pins[i].prvPinVal +
381-
(_analog_input_pins[i].prvPinVal * DEFAULT_HYSTERISIS);
420+
(_analog_input_pins[i].prvPinVal * CURRENT_HYSTERISIS);
382421
uint16_t _pinValThreshLow =
383422
_analog_input_pins[i].prvPinVal -
384-
(_analog_input_pins[i].prvPinVal * DEFAULT_HYSTERISIS);
423+
(_analog_input_pins[i].prvPinVal * CURRENT_HYSTERISIS);
385424

386425
if (pinValRaw > _pinValThreshHi || pinValRaw < _pinValThreshLow) {
387426
// Perform voltage conversion if we need to
@@ -395,8 +434,11 @@ void Wippersnapper_AnalogIO::update() {
395434
_analog_input_pins[i].readMode, pinValRaw,
396435
pinValVolts);
397436

437+
// mark last execution time
438+
_analog_input_pins[i].prvPeriod = millis();
439+
398440
} else {
399-
// WS_DEBUG_PRINTLN("ADC has not changed enough, continue...");
441+
WS_DEBUG_PRINTLN("ADC has not changed enough, continue...");
400442
continue;
401443
}
402444
// set the pin value in the digital pin object for comparison on next

src/components/analogIO/Wippersnapper_AnalogIO.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class Wippersnapper_AnalogIO {
6363
void setADCResolution(int resolution);
6464
int getADCresolution();
6565
int getNativeResolution();
66-
bool timerExpired(long currentTime, analogInputPin pin);
66+
bool timerExpired(long currentTime, analogInputPin pin, long periodOffset = 0);
6767

6868
void update();
6969
bool encodePinEvent(

0 commit comments

Comments
 (0)