127 lines
4.2 KiB
Markdown
127 lines
4.2 KiB
Markdown
---
|
|
title: "AnalogLevelSwitch Component"
|
|
description: "Analog Level Switch Component for multi-position switch detection via analog input"
|
|
keywords: ["analog", "level", "switch", "ESP32", "voltage divider", "multi-position"]
|
|
---
|
|
|
|
# AnalogLevelSwitch
|
|
|
|
**Path**: [`src/components/AnalogLevelSwitch.h`](../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
|
|
|
|
- [Component](../src/Component.h) - Base component class
|
|
- [ModbusTCP](../src/modbus/ModbusTCP.h) - Modbus TCP communication
|
|
- [ArduinoLog](https://github.com/thijse/Arduino-Log) - Logging functionality
|
|
|
|
```mermaid
|
|
graph TD
|
|
AnalogLevelSwitch --> Component
|
|
AnalogLevelSwitch --> ModbusTCP
|
|
AnalogLevelSwitch --> ArduinoLog
|
|
```
|
|
|
|
## BEHAVIOUR
|
|
|
|
```mermaid
|
|
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:
|
|
|
|
```cpp
|
|
#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}
|