@@ -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/* *********************************************************/
323326bool 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
0 commit comments