--- title: 3-Position Analog Switch Component description: Documentation for the Pos3Analog component that provides a 3-position switch interface with local and remote control modes keywords: [Pos3Analog, 3-position switch, modbus, esp32, analog input] --- ## Pos3Analog **Path**: [src/Pos3Analog.h](../../src/Pos3Analog.h) **Revision History**: Initial documentation The Pos3Analog component provides functionality for a 3-position analog switch interface, supporting both local (hardware) and remote (Modbus) control. It reads the state of a physical switch through analog inputs and exposes the switch state via Modbus. The component can be configured to operate in local mode (reading physical inputs) or remote mode (controlled via Modbus). ## REQUIREMENTS - **Hardware**: - Two analog input pins (upPin and downPin) - ESP-32 microcontroller - **Software**: - Platform.io build environment - C++17 compatible compiler ## FEATURES - Reads a 3-position switch (UP, MIDDLE, DOWN) using two analog inputs - Supports two control modes: LOCAL (hardware) and REMOTE (Modbus) - Provides Modbus register interface for reading the current position - Allows remote control of the switch position - Configurable Modbus address for integration with industrial systems - Debounced analog input reading with configurable interval ## DEPENDENCIES - [ArduinoLog](https://github.com/thijse/Arduino-Log) - For logging functionality - [Component](../../src/Component.h) - Base component class - [xmath](../../src/xmath.h) - For range checking and math utilities - [ModbusTCP](../../src/modbus/ModbusTCP.h) - For Modbus communication - [config.h](../../src/config.h) - For configuration constants - [config-modbus.h](../../src/config-modbus.h) - For Modbus-specific configurations - [enums.h](../../src/enums.h) - For enumerations used by the component ```mermaid graph TD Pos3Analog --> Component Pos3Analog --> xmath Pos3Analog --> ModbusTCP Pos3Analog --> ArduinoLog Component --> ArduinoLog ``` ## BEHAVIOUR ```mermaid stateDiagram-v2 [*] --> Setup Setup --> Idle Idle --> ReadLocal: If ControlMode==LOCAL Idle --> ReadRemote: If ControlMode==REMOTE ReadLocal --> UpdateState: If position changed ReadRemote --> UpdateState: If position changed UpdateState --> NotifyChange NotifyChange --> Idle Idle --> ProcessModbus: ModbusRequest ProcessModbus --> ChangeMode: Write to Mode Register ProcessModbus --> ChangeRemoteValue: Write to RemoteValue Register ProcessModbus --> ReturnCurrentValue: Read from Value Register ChangeMode --> Idle ChangeRemoteValue --> UpdateState: If Remote Mode & value changed ReturnCurrentValue --> Idle ``` ## TODOS ### PERFORMANCE - Consider implementing hysteresis for analog readings to prevent flickering between states - Optimize the loop interval for different application scenarios to balance responsiveness and CPU usage ### SECURITY - Add bounds checking on Modbus register access to prevent potential overflows - Consider adding a validation mechanism for state changes to prevent rapid oscillations ### COMPLIANCE - Ensure compliance with industrial Modbus protocol standards for wider compatibility - Document conformance to RS-485 electrical standards if used in that context ### RECOMMENDATIONS - Use pull-up/pull-down resistors on the analog input pins for more reliable readings - Configure appropriate thresholds in config.h for the specific analog sensors being used - Implement error handling for the case of both UP and DOWN inputs being active - Consider adding a debounce mechanism for the switch position to prevent oscillation ## EXAMPLE This example demonstrates how to initialize and add a Pos3Analog component to your application: ```cpp #ifdef PIN_POS3_ANALOG_0_UP pos3Analog_0 = new Pos3Analog( this, // owner PIN_POS3_ANALOG_0_UP, // upPin PIN_POS3_ANALOG_0_DOWN,// downPin ID_POS3_ANALOG_0, // id POS3_ANALOG_0_MB_ADDR // modbusAddress ); if (pos3Analog_0) { components.push_back(pos3Analog_0); Log.infoln(F("Pos3Analog_0 initialized. UpPin:%d, DownPin:%d, ID:%d, MB:%d"), PIN_POS3_ANALOG_0_UP, PIN_POS3_ANALOG_0_DOWN, ID_POS3_ANALOG_0, POS3_ANALOG_0_MB_ADDR); } else { Log.errorln(F("Pos3Analog_0 initialization failed.")); } #endif ``` ### References