Skip to content

Commit 0d4c7ef

Browse files
committed
Switch Analog Voltage on esp32 to use analogReadMilliVolts and tweak hysteresis
1 parent 270344d commit 0d4c7ef

File tree

2 files changed

+55
-17
lines changed

2 files changed

+55
-17
lines changed

src/components/analogIO/Wippersnapper_AnalogIO.cpp

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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
/**********************************************************/
234238
float 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;

src/components/analogIO/Wippersnapper_AnalogIO.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ 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,
67+
long periodOffset = 0);
6768

6869
void update();
6970
bool encodePinEvent(

0 commit comments

Comments
 (0)