firmware-base/docs/AnalogLevelSwitch.md

4.2 KiB

title description keywords
AnalogLevelSwitch Component Analog Level Switch Component for multi-position switch detection via analog input
analog
level
switch
ESP32
voltage divider
multi-position

AnalogLevelSwitch

Path: src/components/AnalogLevelSwitch.h

Revision History: Initial documentation

The AnalogLevelSwitch component interprets an analog voltage as a discrete position or slot. It enables reading an analog input as a multi-position switch by mapping voltage levels to specific slots or positions, with built-in smoothing and debouncing functionality.

REQUIREMENTS

Hardware

  • An analog input pin on the ESP32
  • A voltage divider circuit with different resistor values for each switch position
  • Pull-down resistor (typically 10kΩ) connected to the analog pin

Software

  • Arduino framework
  • ArduinoLog library
  • ModbusTCP support

FEATURES

  • Maps analog voltage readings to discrete positions (slots)
  • Configurable number of positions/slots (up to 32 positions)
  • Adjustable ADC step size per slot
  • Configurable ADC value offset for the first slot
  • Built-in signal smoothing using moving average or EMA
  • Debouncing algorithm to prevent spurious readings
  • Hysteresis to prevent jitter between adjacent positions
  • Modbus integration for industrial control systems
  • Customizable reading interval

DEPENDENCIES

graph TD
  AnalogLevelSwitch --> Component
  AnalogLevelSwitch --> ModbusTCP
  AnalogLevelSwitch --> ArduinoLog

BEHAVIOUR

stateDiagram-v2
  [*] --> Initialization
  Initialization --> ReadAnalogValue
  ReadAnalogValue --> SmoothValue
  SmoothValue --> DetermineSlot
  DetermineSlot --> CheckIfChanged
  CheckIfChanged --> ConfirmChange: Slot different
  CheckIfChanged --> ReadAnalogValue: Slot same
  ConfirmChange --> UpdateSlot: Confirmed
  ConfirmChange --> ReadAnalogValue: Not confirmed
  UpdateSlot --> NotifyStateChange
  NotifyStateChange --> ReadAnalogValue

TODOS

PERFORMANCE

  • Consider optimizing the moving average calculation for better performance
  • Evaluate if the current reading interval is optimal for the application
  • Investigate using hardware filtering in addition to software smoothing

SECURITY

  • Implement range checking for analog readings to prevent unexpected behavior
  • Add validation for Modbus register access

COMPLIANCE

  • Ensure compatibility with industrial standards for analog input processing
  • Verify noise immunity meets requirements for industrial environments

RECOMMENDATIONS

  • Use 1% tolerance resistors in the voltage divider circuit for better accuracy
  • Ensure the voltage divider resistance values create sufficient separation between positions
  • Keep the overall equivalent resistance of the voltage divider in the 1kΩ to 100kΩ range
  • Add appropriate ESD protection for the analog input pin in industrial environments
  • When using mechanical switches, consider adding hardware debouncing in addition to software debouncing

EXAMPLE

Here's an example of how to initialize and use the AnalogLevelSwitch component:

#ifdef PIN_ANALOG_LEVEL_SWITCH_0
  analogLevelSwitch_0 = new AnalogLevelSwitch(
      this,                       // owner
      PIN_ANALOG_LEVEL_SWITCH_0,  // analogPin
      ALS_0_NUM_LEVELS,           // numLevels
      ALS_0_ADC_STEP,             // levelStep
      ALS_0_ADC_OFFSET,           // adcValueOffset
      ID_ANALOG_LEVEL_SWITCH_0,   // id
      ALS_0_MB_ADDR               // modbusAddress
  );
  if (analogLevelSwitch_0) {
    components.push_back(analogLevelSwitch_0);
    Log.infoln(F("AnalogLevelSwitch_0 initialized. Pin:%d, Levels:%d, Step:%d, Offset:%d, ID:%d, MB:%d"),
               PIN_ANALOG_LEVEL_SWITCH_0, ALS_0_NUM_LEVELS, 
               ALS_0_ADC_STEP, ALS_0_ADC_OFFSET,
               ID_ANALOG_LEVEL_SWITCH_0, ALS_0_MB_ADDR);
  } else {
    Log.errorln(F("AnalogLevelSwitch_0 initialization failed."));
  }
#endif

References

${DOXYGEN_PLACEHOLDER}

${VENDOR_PLACEHOLDER}