@@ -87,16 +87,20 @@ void Wippersnapper_AnalogIO::setADCResolution(int resolution) {
8787 analogReadResolution (16 );
8888 _nativeResolution = 12 ;
8989#elif defined(ARDUINO_ARCH_ESP32)
90- scaleAnalogRead = true ;
91- _nativeResolution = 13 ;
90+ scaleAnalogRead = false ; // handled in bsp (analogReadResolution)
91+ analogReadResolution (resolution); // 16 bit values (shifted from 12 or 13bit)
92+ #if defined(ESP32S3)
93+ _nativeResolution = 13 ; // S3 ADC is 13-bit, others are 12-bit
94+ #else
95+ _nativeResolution = 12 ;
96+ #endif
9297#elif defined(ARDUINO_ARCH_RP2040)
9398 scaleAnalogRead = true ;
9499 _nativeResolution = 10 ;
95100#else
96101 scaleAnalogRead = true ;
97102 _nativeResolution = 10 ;
98103#endif
99-
100104 _adcResolution = resolution;
101105}
102106
@@ -232,8 +236,12 @@ uint16_t Wippersnapper_AnalogIO::getPinValue(int pin) {
232236*/
233237/* *********************************************************/
234238float Wippersnapper_AnalogIO::getPinValueVolts (int pin) {
239+ #ifdef ARDUINO_ARCH_ESP32
240+ return analogReadMilliVolts (pin) / 1000.0 ;
241+ #else
235242 uint16_t rawValue = getPinValue (pin);
236243 return rawValue * getAref () / 65536 ;
244+ #endif
237245}
238246
239247/* *****************************************************************/
@@ -310,13 +318,17 @@ bool Wippersnapper_AnalogIO::encodePinEvent(
310318 The current software timer value.
311319 @param pin
312320 The desired analog pin to check
321+ @param periodOffset
322+ Offset to add to the pin's period (used for on_change).
313323 @returns True if pin's period expired, False otherwise.
314324*/
315325/* *********************************************************/
316- bool Wippersnapper_AnalogIO::timerExpired (long currentTime,
317- analogInputPin pin) {
318- if (currentTime - pin.prvPeriod > pin.period && pin.period != 0L )
326+ bool Wippersnapper_AnalogIO::timerExpired (long currentTime, analogInputPin pin,
327+ long periodOffset) {
328+ if (pin.period + periodOffset != 0L &&
329+ currentTime - pin.prvPeriod > (pin.period + periodOffset)) {
319330 return true ;
331+ }
320332 return false ;
321333}
322334
@@ -335,9 +347,8 @@ void Wippersnapper_AnalogIO::update() {
335347 if (_analog_input_pins[i].enabled == true ) {
336348
337349 // Does the pin execute on-period?
338- if ((long )millis () - _analog_input_pins[i].prvPeriod >
339- _analog_input_pins[i].period &&
340- _analog_input_pins[i].period != 0L ) {
350+ if (_analog_input_pins[i].period != 0L &&
351+ timerExpired (millis (), _analog_input_pins[i])) {
341352 WS_DEBUG_PRINT (" Executing periodic event on A" );
342353 WS_DEBUG_PRINTLN (_analog_input_pins[i].pinName );
343354
@@ -359,35 +370,61 @@ void Wippersnapper_AnalogIO::update() {
359370 encodePinEvent (_analog_input_pins[i].pinName ,
360371 _analog_input_pins[i].readMode , pinValRaw, pinValVolts);
361372
362- // IMPT - reset the digital pin
373+ // mark last execution time
363374 _analog_input_pins[i].prvPeriod = millis ();
364375 }
365376 // Does the pin execute on_change?
366377 else if (_analog_input_pins[i].period == 0L ) {
367378
379+ // not first run and timer not expired, skip
380+ if (_analog_input_pins[i].prvPeriod != 0L &&
381+ !timerExpired (millis (), _analog_input_pins[i], 500 )) {
382+ continue ;
383+ }
384+
368385 // note: on-change requires ADC DEFAULT_HYSTERISIS to check against prv
369386 // pin value
370387 uint16_t pinValRaw = getPinValue (_analog_input_pins[i].pinName );
371388
389+ // All boards ADC values scaled to 16bit, in future we may need to
390+ // adjust dynamically
391+ uint16_t maxDecimalValue = 65535 ;
392+
393+ // Calculate threshold values - using DEFAULT_HYSTERISIS for first third
394+ // (1/3) of the range, then 2x DEFAULT_HYSTERISIS for the middle 1/3,
395+ // and 4x DEFAULT_HYSTERISIS for the last 1/3. This should allow a more
396+ // wifi blip tolerant threshold for the both ends of the range.
397+ float CURRENT_HYSTERISIS;
398+ if (pinValRaw < maxDecimalValue / 3 ) {
399+ CURRENT_HYSTERISIS = maxDecimalValue * DEFAULT_HYSTERISIS;
400+ } else if (pinValRaw < (maxDecimalValue / 3 ) * 2 ) {
401+ CURRENT_HYSTERISIS = maxDecimalValue * DEFAULT_HYSTERISIS * 2 ;
402+ } else {
403+ CURRENT_HYSTERISIS = maxDecimalValue * DEFAULT_HYSTERISIS * 4 ;
404+ }
405+
406+ // get the threshold values for previous pin value
372407 uint16_t _pinValThreshHi =
373- _analog_input_pins[i].prvPinVal +
374- (_analog_input_pins[i].prvPinVal * DEFAULT_HYSTERISIS);
408+ _analog_input_pins[i].prvPinVal + CURRENT_HYSTERISIS;
375409 uint16_t _pinValThreshLow =
376- _analog_input_pins[i].prvPinVal -
377- (_analog_input_pins[i].prvPinVal * DEFAULT_HYSTERISIS);
410+ _analog_input_pins[i].prvPinVal - CURRENT_HYSTERISIS;
378411
379- if (pinValRaw > _pinValThreshHi || pinValRaw < _pinValThreshLow) {
412+ if (_analog_input_pins[i].prvPeriod == 0 ||
413+ pinValRaw > _pinValThreshHi || pinValRaw < _pinValThreshLow) {
380414 // Perform voltage conversion if we need to
381415 if (_analog_input_pins[i].readMode ==
382416 wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_ANALOG_READ_MODE_PIN_VOLTAGE) {
383- pinValVolts = pinValRaw * getAref () / 65536 ;
417+ pinValVolts = getPinValueVolts (_analog_input_pins[i]. pinName ) ;
384418 }
385419
386420 // Publish pin event to IO
387421 encodePinEvent (_analog_input_pins[i].pinName ,
388422 _analog_input_pins[i].readMode , pinValRaw,
389423 pinValVolts);
390424
425+ // mark last execution time
426+ _analog_input_pins[i].prvPeriod = millis ();
427+
391428 } else {
392429 // WS_DEBUG_PRINTLN("ADC has not changed enough, continue...");
393430 continue ;
0 commit comments