// ============================================================================= // modbus_registers.h -- AR-Autopilot Modbus RTU register map // ============================================================================= // // AUTO-GENERATED. Do not edit by hand. // Source: firmware/ar_autopilot_v1/modbus_registers.yaml // Regenerate with: python tools/gen_modbus_registers.py // ============================================================================= #pragma once #include namespace arautopilot::protocols::modbus { constexpr const char* MAP_SCHEMA_VERSION = "0.1.0"; constexpr uint8_t SLAVE_ID = 1; constexpr uint32_t BAUDRATE = 38400; constexpr char PARITY = 'N'; constexpr uint8_t DATA_BITS = 8; constexpr uint8_t STOP_BITS = 1; // ----- Discrete inputs (read-only bits) ----- constexpr uint16_t DISCRETE_COUNT = 19; constexpr uint16_t DISCRETE_MAX_ADDR = 25; // 1 if the pilot is currently engaged (any mode other than STANDBY) constexpr uint16_t DISCRETE_PILOT_ENGAGED = 0; // Live state of the physical Engage/Disengage push-button constexpr uint16_t DISCRETE_DI_DISENGAGE_BUTTON = 1; // Port-side rudder mechanical end-stop reached constexpr uint16_t DISCRETE_DI_LIMIT_PORT = 2; // Starboard-side rudder mechanical end-stop reached constexpr uint16_t DISCRETE_DI_LIMIT_STBD = 3; // External critical alarm (VMS / genset) asserted constexpr uint16_t DISCRETE_DI_EXTERNAL_ALARM = 4; // Manual confirmation switch asserted (emergency override) constexpr uint16_t DISCRETE_DI_MANUAL_CONFIRM = 5; // Master actuator power relay (DO3) commanded ON constexpr uint16_t DISCRETE_ACTUATOR_POWER = 8; // Actuator direction output: driving to port constexpr uint16_t DISCRETE_ACTUATOR_DRIVING_PORT = 9; // Actuator direction output: driving to starboard constexpr uint16_t DISCRETE_ACTUATOR_DRIVING_STBD = 10; // Off-course warning active constexpr uint16_t DISCRETE_ALARM_OFF_COURSE = 16; // Severe off-course alarm (auto-disengage) constexpr uint16_t DISCRETE_ALARM_OFF_COURSE_SEVERE = 17; // Rudder command sent but no feedback motion constexpr uint16_t DISCRETE_ALARM_RUDDER_NOT_RESP = 18; // NMEA 2000 heading PGN not received >5 s constexpr uint16_t DISCRETE_ALARM_HEADING_LOST = 19; // Actuator current over threshold constexpr uint16_t DISCRETE_ALARM_ACTUATOR_OVERCURR = 20; // Supply voltage below safe threshold constexpr uint16_t DISCRETE_ALARM_VOLTAGE_LOW = 21; // Rudder reached mechanical end-stop constexpr uint16_t DISCRETE_ALARM_LIMIT_REACHED = 22; // Firmware watchdog fired -- controller reset constexpr uint16_t DISCRETE_ALARM_WATCHDOG_TRIPPED = 23; // VMS reported blackout or electrical fault constexpr uint16_t DISCRETE_ALARM_VMS_CRITICAL = 24; // OR of all alarm bits (convenience) constexpr uint16_t DISCRETE_ANY_ALARM_ACTIVE = 25; // ----- Coils (read-write bits) ----- constexpr uint16_t COIL_COUNT = 4; constexpr uint16_t COIL_MAX_ADDR = 3; // Rising edge requests pilot engagement (subject to interlocks) constexpr uint16_t COIL_CMD_ENGAGE_REQUEST = 0; // Rising edge forces pilot to STANDBY constexpr uint16_t COIL_CMD_DISENGAGE_REQUEST = 1; // Rising edge acknowledges every active alarm constexpr uint16_t COIL_CMD_ACK_ALL_ALARMS = 2; // Knob arming request (Sprint 7+) constexpr uint16_t COIL_CMD_KNOB_ARM = 3; // ----- Input registers (read-only words) ----- constexpr uint16_t INPUT_COUNT = 23; constexpr uint16_t INPUT_MAX_ADDR = 45; // Firmware major version constexpr uint16_t INPUT_FW_VERSION_MAJOR = 0; // Firmware minor version constexpr uint16_t INPUT_FW_VERSION_MINOR = 1; // Firmware patch version constexpr uint16_t INPUT_FW_VERSION_PATCH = 2; // Modbus map schema version (0=v0.1.0) constexpr uint16_t INPUT_SCHEMA_VERSION = 3; // Uptime seconds, low 16 bits // unit=s constexpr uint16_t INPUT_UPTIME_SECONDS_LO = 4; // Uptime seconds, high 16 bits // unit=s constexpr uint16_t INPUT_UPTIME_SECONDS_HI = 5; // Current AutopilotMode (0=STANDBY,1=HH,2=TC,3=TK,4=DODGE) constexpr uint16_t INPUT_CURRENT_MODE = 6; // Current free heap, KiB // unit=KiB constexpr uint16_t INPUT_FREE_HEAP_KB = 7; // Minimum free heap since boot // unit=KiB constexpr uint16_t INPUT_MIN_FREE_HEAP_KB = 8; // Filtered rudder angle, deg * 100 (-3500..+3500) // unit=deg, scale=0.01 constexpr uint16_t INPUT_RUDDER_ANGLE_DEG_X100 = 16; // Raw ADC reading after median filter (0..4095) // unit=counts constexpr uint16_t INPUT_RUDDER_RAW_ADC = 17; // 1 if median filter has filled (>=5 samples) constexpr uint16_t INPUT_RUDDER_VALID = 18; // Current heading from NMEA 2000 PGN 127250, deg*100 (0..35999) // unit=deg, scale=0.01 constexpr uint16_t INPUT_HEADING_DEG_X100 = 24; // Rate of turn from PGN 127251, deg/s*100 (signed int16) // unit=deg/s, scale=0.01 constexpr uint16_t INPUT_ROT_DPS_X100 = 25; // Milliseconds since the last heading update (0..60000) // unit=ms constexpr uint16_t INPUT_HEADING_AGE_MS = 26; // System battery voltage, V*100 // unit=V, scale=0.01 constexpr uint16_t INPUT_BATTERY_VOLTAGE_X100 = 32; // Actuator current, A*100 // unit=A, scale=0.01 constexpr uint16_t INPUT_ACTUATOR_CURRENT_X100 = 33; // Inner-loop rudder setpoint, deg*100 (signed int16) // unit=deg, scale=0.01 constexpr uint16_t INPUT_PID_INNER_SETPOINT_X100 = 40; // Last PID command, %*100 (signed int16, -10000..+10000) // unit=%, scale=0.01 constexpr uint16_t INPUT_PID_INNER_OUTPUT_X100 = 41; // Last PID error, deg*100 (signed int16) // unit=deg, scale=0.01 constexpr uint16_t INPUT_PID_INNER_ERROR_X100 = 42; // Inner-loop kp * 1000 (unsigned) // scale=0.001 constexpr uint16_t INPUT_PID_INNER_KP_X1000 = 43; // Inner-loop ki * 1000 (unsigned) // scale=0.001 constexpr uint16_t INPUT_PID_INNER_KI_X1000 = 44; // Inner-loop kd * 1000 (unsigned) // scale=0.001 constexpr uint16_t INPUT_PID_INNER_KD_X1000 = 45; // ----- Holding registers (read-write words) ----- constexpr uint16_t HOLDING_COUNT = 9; constexpr uint16_t HOLDING_MAX_ADDR = 19; // Mode requested by operator (0=STANDBY,1=HH,2=TC,3=TK,4=DODGE) constexpr uint16_t HOLDING_MODE_REQUEST = 0; // Desired heading, deg*100 // unit=deg, scale=0.01 constexpr uint16_t HOLDING_HEADING_SETPOINT_X100 = 1; // Display brightness 0..100 // unit=% constexpr uint16_t HOLDING_BRIGHTNESS_PCT = 2; // Alarm volume 0..100 // unit=% constexpr uint16_t HOLDING_ALARM_VOLUME_PCT = 3; // Dodge mode heading offset, deg*100 (signed int16) // unit=deg, scale=0.01 constexpr uint16_t HOLDING_DODGE_OFFSET_DEG_X100 = 8; // Requested inner-loop rudder setpoint, deg*100 (signed int16) // unit=deg, scale=0.01 constexpr uint16_t HOLDING_PID_INNER_SETPOINT_REQ_X100 = 16; // Requested inner-loop kp * 1000 (unsigned) // scale=0.001 constexpr uint16_t HOLDING_PID_INNER_KP_REQ_X1000 = 17; // Requested inner-loop ki * 1000 (unsigned) // scale=0.001 constexpr uint16_t HOLDING_PID_INNER_KI_REQ_X1000 = 18; // Requested inner-loop kd * 1000 (unsigned) // scale=0.001 constexpr uint16_t HOLDING_PID_INNER_KD_REQ_X1000 = 19; } // namespace arautopilot::protocols::modbus