Compare commits

..

No commits in common. "bb25134b6c9a781a73ba376dde7c15b8a221f41b" and "69cf7e95117dae7bac257a74b82f44a83cb89b21" have entirely different histories.

5 changed files with 24 additions and 66 deletions

View File

@ -38,7 +38,6 @@ Alle Register sind in einer einzigen, durchgehenden Liste pro Register-Typ (`Inp
| **0x00F2** | `DEVICE_STATUS` | System | `0`=OK, `1`=Allgemeiner Fehler. |
| **0x00F3** | `UPTIME_SECONDS_LOW` | System | Untere 16 Bit der Uptime in Sekunden. |
| **0x00F4** | `UPTIME_SECONDS_HIGH` | System | Obere 16 Bit der Uptime. |
| **0x00F5** | `SUPPLY_VOLTAGE_MV` | System | Aktuelle Versorgungsspannung in Millivolt (mV). |
| **0x0100** | `FWU_LAST_CHUNK_CRC` | Firmware-Update | Enthält den CRC16 des zuletzt im Puffer empfangenen Daten-Chunks. |
## 3. Holding Registers (4xxxx, Read/Write)

View File

@ -7,8 +7,4 @@
status = "okay";
};
};
};
&usart1 {
/delete-node/ modbus0;
};

View File

@ -6,44 +6,42 @@
/**
* @brief Modbus Input Register Addresses.
*/
enum
{
enum {
/* Valve Control & Status */
REG_INPUT_VALVE_STATE_MOVEMENT = 0x0000,
REG_INPUT_MOTOR_CURRENT_MA = 0x0001,
REG_INPUT_VALVE_STATE_MOVEMENT = 0x0000,
REG_INPUT_MOTOR_CURRENT_MA = 0x0001,
/* Digital Inputs */
REG_INPUT_DIGITAL_INPUTS_STATE = 0x0020,
REG_INPUT_BUTTON_EVENTS = 0x0021,
REG_INPUT_DIGITAL_INPUTS_STATE = 0x0020,
REG_INPUT_BUTTON_EVENTS = 0x0021,
/* System Config & Status */
REG_INPUT_FIRMWARE_VERSION_MAJOR_MINOR = 0x00F0,
REG_INPUT_FIRMWARE_VERSION_PATCH = 0x00F1,
REG_INPUT_DEVICE_STATUS = 0x00F2,
REG_INPUT_UPTIME_SECONDS_LOW = 0x00F3,
REG_INPUT_UPTIME_SECONDS_HIGH = 0x00F4,
REG_INPUT_SUPPLY_VOLTAGE_MV = 0x00F5,
REG_INPUT_FWU_LAST_CHUNK_CRC = 0x0100
REG_INPUT_FIRMWARE_VERSION_PATCH = 0x00F1,
REG_INPUT_DEVICE_STATUS = 0x00F2,
REG_INPUT_UPTIME_SECONDS_LOW = 0x00F3,
REG_INPUT_UPTIME_SECONDS_HIGH = 0x00F4,
/* Firmware Update */
REG_INPUT_FWU_LAST_CHUNK_CRC = 0x0100,
};
/**
* @brief Modbus Holding Register Addresses.
*/
enum
{
enum {
/* Valve Control */
REG_HOLDING_VALVE_COMMAND = 0x0000,
REG_HOLDING_MAX_OPENING_TIME_S = 0x0001,
REG_HOLDING_MAX_CLOSING_TIME_S = 0x0002,
REG_HOLDING_VALVE_COMMAND = 0x0000,
REG_HOLDING_MAX_OPENING_TIME_S = 0x0001,
REG_HOLDING_MAX_CLOSING_TIME_S = 0x0002,
/* Digital Outputs */
REG_HOLDING_DIGITAL_OUTPUTS_STATE = 0x0010,
REG_HOLDING_DIGITAL_OUTPUTS_STATE = 0x0010,
/* System Config */
REG_HOLDING_WATCHDOG_TIMEOUT_S = 0x00F0,
REG_HOLDING_DEVICE_RESET = 0x00F1,
REG_HOLDING_WATCHDOG_TIMEOUT_S = 0x00F0,
REG_HOLDING_DEVICE_RESET = 0x00F1,
/* Firmware Update */
REG_HOLDING_FWU_COMMAND = 0x0100,
REG_HOLDING_FWU_CHUNK_OFFSET_LOW = 0x0101,
REG_HOLDING_FWU_CHUNK_OFFSET_HIGH = 0x0102,
REG_HOLDING_FWU_CHUNK_SIZE = 0x0103,
REG_HOLDING_FWU_DATA_BUFFER = 0x0180,
REG_HOLDING_FWU_COMMAND = 0x0100,
REG_HOLDING_FWU_CHUNK_OFFSET_LOW = 0x0101,
REG_HOLDING_FWU_CHUNK_OFFSET_HIGH = 0x0102,
REG_HOLDING_FWU_CHUNK_SIZE = 0x0103,
REG_HOLDING_FWU_DATA_BUFFER = 0x0180,
};
int modbus_server_init(void);

View File

@ -128,9 +128,6 @@ static int input_reg_rd(uint16_t addr, uint16_t *reg)
case REG_INPUT_UPTIME_SECONDS_HIGH:
*reg = (uint16_t)(uptime_s >> 16);
break;
case REG_INPUT_SUPPLY_VOLTAGE_MV:
*reg = 12300;
break;
case REG_INPUT_FWU_LAST_CHUNK_CRC:
*reg = fwu_get_last_chunk_crc();
break;
@ -158,17 +155,6 @@ static struct modbus_user_callbacks mbs_cbs = {
int modbus_server_init(void)
{
k_timer_init(&watchdog_timer, watchdog_timer_handler, NULL);
// Load saved settings
uint32_t saved_baudrate = 19200;
uint8_t saved_unit_id = 1;
settings_load_one("modbus/baudrate", &saved_baudrate, sizeof(saved_baudrate));
settings_load_one("modbus/unit_id", &saved_unit_id, sizeof(saved_unit_id));
// Apply loaded settings
server_param.serial.baud = saved_baudrate;
server_param.server.unit_id = saved_unit_id;
const char iface_name[] = {DEVICE_DT_NAME(MODBUS_NODE)};
#if DT_NODE_HAS_COMPAT(DT_PARENT(MODBUS_NODE), zephyr_cdc_acm_uart)
const struct device *const dev = DEVICE_DT_GET(DT_PARENT(MODBUS_NODE));
@ -193,37 +179,20 @@ int modbus_server_init(void)
return modbus_iface;
}
server_param.server.user_cb = &mbs_cbs;
LOG_INF("Starting Modbus server: baudrate=%u, unit_id=%u", saved_baudrate, saved_unit_id);
return modbus_init_server(modbus_iface, server_param);
}
int modbus_reconfigure(uint32_t baudrate, uint8_t unit_id)
{
// Update parameters
server_param.serial.baud = baudrate;
server_param.server.unit_id = unit_id;
// Try to reinitialize - this should work for most cases
int ret = modbus_init_server(modbus_iface, server_param);
if (ret == 0)
{
settings_save_one("modbus/baudrate", &baudrate, sizeof(baudrate));
settings_save_one("modbus/unit_id", &unit_id, sizeof(unit_id));
LOG_INF("Modbus reconfigured: baudrate=%u, unit_id=%u", baudrate, unit_id);
}
else
{
LOG_ERR("Failed to reconfigure Modbus: %d", ret);
LOG_INF("Modbus reconfiguration requires restart to take effect");
// Save settings for next boot
settings_save_one("modbus/baudrate", &baudrate, sizeof(baudrate));
settings_save_one("modbus/unit_id", &unit_id, sizeof(unit_id));
LOG_INF("Settings saved. Type 'reset' to restart the device and apply the change.");
return 0; // Return success since settings are saved
}
return ret;

View File

@ -19,7 +19,6 @@ REG_INPUT_FIRMWARE_VERSION_PATCH = 0x00F1
REG_INPUT_DEVICE_STATUS = 0x00F2
REG_INPUT_UPTIME_SECONDS_LOW = 0x00F3
REG_INPUT_UPTIME_SECONDS_HIGH = 0x00F4
REG_INPUT_SUPPLY_VOLTAGE_MV = 0x00F5
REG_INPUT_FWU_LAST_CHUNK_CRC = 0x0100
REG_HOLDING_VALVE_COMMAND = 0x0000
REG_HOLDING_MAX_OPENING_TIME_S = 0x0001
@ -85,7 +84,7 @@ def poll_status(slave_id, interval):
# If connected, try to read data
ir_valve = client.read_input_registers(REG_INPUT_VALVE_STATE_MOVEMENT, count=2, slave=slave_id)
ir_dig = client.read_input_registers(REG_INPUT_DIGITAL_INPUTS_STATE, count=2, slave=slave_id)
ir_sys = client.read_input_registers(REG_INPUT_FIRMWARE_VERSION_MAJOR_MINOR, count=6, slave=slave_id)
ir_sys = client.read_input_registers(REG_INPUT_FIRMWARE_VERSION_MAJOR_MINOR, count=5, slave=slave_id)
hr_valve = client.read_holding_registers(REG_HOLDING_MAX_OPENING_TIME_S, count=2, slave=slave_id)
hr_dig = client.read_holding_registers(REG_HOLDING_DIGITAL_OUTPUTS_STATE, count=1, slave=slave_id)
hr_sys = client.read_holding_registers(REG_HOLDING_WATCHDOG_TIMEOUT_S, count=1, slave=slave_id)
@ -110,11 +109,9 @@ def poll_status(slave_id, interval):
fw_minor = ir_sys.registers[0] & 0xFF
fw_patch = ir_sys.registers[1]
uptime_seconds = (ir_sys.registers[4] << 16) | ir_sys.registers[3]
supply_voltage_mv = ir_sys.registers[5]
new_data["firmware"] = f"v{fw_major}.{fw_minor}.{fw_patch}"
new_data["device_status"] = "OK" if ir_sys.registers[2] == 0 else "ERROR"
new_data["uptime"] = format_uptime(uptime_seconds)
new_data["supply_voltage"] = f"{supply_voltage_mv / 1000.0:.2f} V"
new_data["watchdog"] = f"{hr_sys.registers[0]}s"
new_data["error"] = None # Clear any previous error on successful read
reconnect_attempts = 0 # Reset attempts on successful communication
@ -305,7 +302,6 @@ def main_menu(stdscr, slave_id):
stdscr.addstr(1, col4, "Firmware:", bold); stdscr.addstr(1, col4 + 14, str(current_data.get('firmware', 'N/A')), normal)
stdscr.addstr(2, col4, "Uptime:", bold); stdscr.addstr(2, col4 + 14, str(current_data.get('uptime', 'N/A')), normal)
stdscr.addstr(3, col4, "Dev. Status:", bold); stdscr.addstr(3, col4 + 14, str(current_data.get('device_status', 'N/A')), normal)
stdscr.addstr(4, col4, "Supply V:", bold); stdscr.addstr(4, col4 + 14, str(current_data.get('supply_voltage', 'N/A')), normal)
stdscr.addstr(5, 0, "" * (w - 1), normal)
for idx, row in enumerate(menu):
draw_button(stdscr, h // 2 - len(menu) + (idx * 2), w // 2 - len(row) // 2, row, idx == current_row_idx)