@@ -87,16 +87,20 @@ void Wippersnapper_AnalogIO::setADCResolution(int resolution) {
87
87
analogReadResolution (16 );
88
88
_nativeResolution = 12 ;
89
89
#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
92
97
#elif defined(ARDUINO_ARCH_RP2040)
93
98
scaleAnalogRead = true ;
94
99
_nativeResolution = 10 ;
95
100
#else
96
101
scaleAnalogRead = true ;
97
102
_nativeResolution = 10 ;
98
103
#endif
99
-
100
104
_adcResolution = resolution;
101
105
}
102
106
@@ -232,8 +236,12 @@ uint16_t Wippersnapper_AnalogIO::getPinValue(int pin) {
232
236
*/
233
237
/* *********************************************************/
234
238
float Wippersnapper_AnalogIO::getPinValueVolts (int pin) {
239
+ #ifdef ARDUINO_ARCH_ESP32
240
+ return analogReadMilliVolts (pin) / 1000.0 ;
241
+ #else
235
242
uint16_t rawValue = getPinValue (pin);
236
243
return rawValue * getAref () / 65536 ;
244
+ #endif
237
245
}
238
246
239
247
/* *****************************************************************/
@@ -310,13 +318,17 @@ bool Wippersnapper_AnalogIO::encodePinEvent(
310
318
The current software timer value.
311
319
@param pin
312
320
The desired analog pin to check
321
+ @param periodOffset
322
+ Offset to add to the pin's period (used for on_change).
313
323
@returns True if pin's period expired, False otherwise.
314
324
*/
315
325
/* *********************************************************/
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)) {
319
330
return true ;
331
+ }
320
332
return false ;
321
333
}
322
334
@@ -335,9 +347,8 @@ void Wippersnapper_AnalogIO::update() {
335
347
if (_analog_input_pins[i].enabled == true ) {
336
348
337
349
// 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])) {
341
352
WS_DEBUG_PRINT (" Executing periodic event on A" );
342
353
WS_DEBUG_PRINTLN (_analog_input_pins[i].pinName );
343
354
@@ -359,35 +370,61 @@ void Wippersnapper_AnalogIO::update() {
359
370
encodePinEvent (_analog_input_pins[i].pinName ,
360
371
_analog_input_pins[i].readMode , pinValRaw, pinValVolts);
361
372
362
- // IMPT - reset the digital pin
373
+ // mark last execution time
363
374
_analog_input_pins[i].prvPeriod = millis ();
364
375
}
365
376
// Does the pin execute on_change?
366
377
else if (_analog_input_pins[i].period == 0L ) {
367
378
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
+
368
385
// note: on-change requires ADC DEFAULT_HYSTERISIS to check against prv
369
386
// pin value
370
387
uint16_t pinValRaw = getPinValue (_analog_input_pins[i].pinName );
371
388
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
372
407
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;
375
409
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;
378
411
379
- if (pinValRaw > _pinValThreshHi || pinValRaw < _pinValThreshLow) {
412
+ if (_analog_input_pins[i].prvPeriod == 0 ||
413
+ pinValRaw > _pinValThreshHi || pinValRaw < _pinValThreshLow) {
380
414
// Perform voltage conversion if we need to
381
415
if (_analog_input_pins[i].readMode ==
382
416
wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_ANALOG_READ_MODE_PIN_VOLTAGE) {
383
- pinValVolts = pinValRaw * getAref () / 65536 ;
417
+ pinValVolts = getPinValueVolts (_analog_input_pins[i]. pinName ) ;
384
418
}
385
419
386
420
// Publish pin event to IO
387
421
encodePinEvent (_analog_input_pins[i].pinName ,
388
422
_analog_input_pins[i].readMode , pinValRaw,
389
423
pinValVolts);
390
424
425
+ // mark last execution time
426
+ _analog_input_pins[i].prvPeriod = millis ();
427
+
391
428
} else {
392
429
// WS_DEBUG_PRINTLN("ADC has not changed enough, continue...");
393
430
continue ;
0 commit comments