Compare commits
No commits in common. "bb25134b6c9a781a73ba376dde7c15b8a221f41b" and "69cf7e95117dae7bac257a74b82f44a83cb89b21" have entirely different histories.
bb25134b6c
...
69cf7e9511
|
|
@ -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. |
|
| **0x00F2** | `DEVICE_STATUS` | System | `0`=OK, `1`=Allgemeiner Fehler. |
|
||||||
| **0x00F3** | `UPTIME_SECONDS_LOW` | System | Untere 16 Bit der Uptime in Sekunden. |
|
| **0x00F3** | `UPTIME_SECONDS_LOW` | System | Untere 16 Bit der Uptime in Sekunden. |
|
||||||
| **0x00F4** | `UPTIME_SECONDS_HIGH` | System | Obere 16 Bit der Uptime. |
|
| **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. |
|
| **0x0100** | `FWU_LAST_CHUNK_CRC` | Firmware-Update | Enthält den CRC16 des zuletzt im Puffer empfangenen Daten-Chunks. |
|
||||||
|
|
||||||
## 3. Holding Registers (4xxxx, Read/Write)
|
## 3. Holding Registers (4xxxx, Read/Write)
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,4 @@
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
&usart1 {
|
|
||||||
/delete-node/ modbus0;
|
|
||||||
};
|
};
|
||||||
|
|
@ -6,44 +6,42 @@
|
||||||
/**
|
/**
|
||||||
* @brief Modbus Input Register Addresses.
|
* @brief Modbus Input Register Addresses.
|
||||||
*/
|
*/
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
/* Valve Control & Status */
|
/* Valve Control & Status */
|
||||||
REG_INPUT_VALVE_STATE_MOVEMENT = 0x0000,
|
REG_INPUT_VALVE_STATE_MOVEMENT = 0x0000,
|
||||||
REG_INPUT_MOTOR_CURRENT_MA = 0x0001,
|
REG_INPUT_MOTOR_CURRENT_MA = 0x0001,
|
||||||
/* Digital Inputs */
|
/* Digital Inputs */
|
||||||
REG_INPUT_DIGITAL_INPUTS_STATE = 0x0020,
|
REG_INPUT_DIGITAL_INPUTS_STATE = 0x0020,
|
||||||
REG_INPUT_BUTTON_EVENTS = 0x0021,
|
REG_INPUT_BUTTON_EVENTS = 0x0021,
|
||||||
/* System Config & Status */
|
/* System Config & Status */
|
||||||
REG_INPUT_FIRMWARE_VERSION_MAJOR_MINOR = 0x00F0,
|
REG_INPUT_FIRMWARE_VERSION_MAJOR_MINOR = 0x00F0,
|
||||||
REG_INPUT_FIRMWARE_VERSION_PATCH = 0x00F1,
|
REG_INPUT_FIRMWARE_VERSION_PATCH = 0x00F1,
|
||||||
REG_INPUT_DEVICE_STATUS = 0x00F2,
|
REG_INPUT_DEVICE_STATUS = 0x00F2,
|
||||||
REG_INPUT_UPTIME_SECONDS_LOW = 0x00F3,
|
REG_INPUT_UPTIME_SECONDS_LOW = 0x00F3,
|
||||||
REG_INPUT_UPTIME_SECONDS_HIGH = 0x00F4,
|
REG_INPUT_UPTIME_SECONDS_HIGH = 0x00F4,
|
||||||
REG_INPUT_SUPPLY_VOLTAGE_MV = 0x00F5,
|
/* Firmware Update */
|
||||||
REG_INPUT_FWU_LAST_CHUNK_CRC = 0x0100
|
REG_INPUT_FWU_LAST_CHUNK_CRC = 0x0100,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Modbus Holding Register Addresses.
|
* @brief Modbus Holding Register Addresses.
|
||||||
*/
|
*/
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
/* Valve Control */
|
/* Valve Control */
|
||||||
REG_HOLDING_VALVE_COMMAND = 0x0000,
|
REG_HOLDING_VALVE_COMMAND = 0x0000,
|
||||||
REG_HOLDING_MAX_OPENING_TIME_S = 0x0001,
|
REG_HOLDING_MAX_OPENING_TIME_S = 0x0001,
|
||||||
REG_HOLDING_MAX_CLOSING_TIME_S = 0x0002,
|
REG_HOLDING_MAX_CLOSING_TIME_S = 0x0002,
|
||||||
/* Digital Outputs */
|
/* Digital Outputs */
|
||||||
REG_HOLDING_DIGITAL_OUTPUTS_STATE = 0x0010,
|
REG_HOLDING_DIGITAL_OUTPUTS_STATE = 0x0010,
|
||||||
/* System Config */
|
/* System Config */
|
||||||
REG_HOLDING_WATCHDOG_TIMEOUT_S = 0x00F0,
|
REG_HOLDING_WATCHDOG_TIMEOUT_S = 0x00F0,
|
||||||
REG_HOLDING_DEVICE_RESET = 0x00F1,
|
REG_HOLDING_DEVICE_RESET = 0x00F1,
|
||||||
/* Firmware Update */
|
/* Firmware Update */
|
||||||
REG_HOLDING_FWU_COMMAND = 0x0100,
|
REG_HOLDING_FWU_COMMAND = 0x0100,
|
||||||
REG_HOLDING_FWU_CHUNK_OFFSET_LOW = 0x0101,
|
REG_HOLDING_FWU_CHUNK_OFFSET_LOW = 0x0101,
|
||||||
REG_HOLDING_FWU_CHUNK_OFFSET_HIGH = 0x0102,
|
REG_HOLDING_FWU_CHUNK_OFFSET_HIGH = 0x0102,
|
||||||
REG_HOLDING_FWU_CHUNK_SIZE = 0x0103,
|
REG_HOLDING_FWU_CHUNK_SIZE = 0x0103,
|
||||||
REG_HOLDING_FWU_DATA_BUFFER = 0x0180,
|
REG_HOLDING_FWU_DATA_BUFFER = 0x0180,
|
||||||
};
|
};
|
||||||
|
|
||||||
int modbus_server_init(void);
|
int modbus_server_init(void);
|
||||||
|
|
|
||||||
|
|
@ -128,9 +128,6 @@ static int input_reg_rd(uint16_t addr, uint16_t *reg)
|
||||||
case REG_INPUT_UPTIME_SECONDS_HIGH:
|
case REG_INPUT_UPTIME_SECONDS_HIGH:
|
||||||
*reg = (uint16_t)(uptime_s >> 16);
|
*reg = (uint16_t)(uptime_s >> 16);
|
||||||
break;
|
break;
|
||||||
case REG_INPUT_SUPPLY_VOLTAGE_MV:
|
|
||||||
*reg = 12300;
|
|
||||||
break;
|
|
||||||
case REG_INPUT_FWU_LAST_CHUNK_CRC:
|
case REG_INPUT_FWU_LAST_CHUNK_CRC:
|
||||||
*reg = fwu_get_last_chunk_crc();
|
*reg = fwu_get_last_chunk_crc();
|
||||||
break;
|
break;
|
||||||
|
|
@ -158,17 +155,6 @@ static struct modbus_user_callbacks mbs_cbs = {
|
||||||
int modbus_server_init(void)
|
int modbus_server_init(void)
|
||||||
{
|
{
|
||||||
k_timer_init(&watchdog_timer, watchdog_timer_handler, NULL);
|
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)};
|
const char iface_name[] = {DEVICE_DT_NAME(MODBUS_NODE)};
|
||||||
#if DT_NODE_HAS_COMPAT(DT_PARENT(MODBUS_NODE), zephyr_cdc_acm_uart)
|
#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));
|
const struct device *const dev = DEVICE_DT_GET(DT_PARENT(MODBUS_NODE));
|
||||||
|
|
@ -193,37 +179,20 @@ int modbus_server_init(void)
|
||||||
return modbus_iface;
|
return modbus_iface;
|
||||||
}
|
}
|
||||||
server_param.server.user_cb = &mbs_cbs;
|
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);
|
return modbus_init_server(modbus_iface, server_param);
|
||||||
}
|
}
|
||||||
|
|
||||||
int modbus_reconfigure(uint32_t baudrate, uint8_t unit_id)
|
int modbus_reconfigure(uint32_t baudrate, uint8_t unit_id)
|
||||||
{
|
{
|
||||||
// Update parameters
|
|
||||||
server_param.serial.baud = baudrate;
|
server_param.serial.baud = baudrate;
|
||||||
server_param.server.unit_id = unit_id;
|
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);
|
int ret = modbus_init_server(modbus_iface, server_param);
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
settings_save_one("modbus/baudrate", &baudrate, sizeof(baudrate));
|
settings_save_one("modbus/baudrate", &baudrate, sizeof(baudrate));
|
||||||
settings_save_one("modbus/unit_id", &unit_id, sizeof(unit_id));
|
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;
|
return ret;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ REG_INPUT_FIRMWARE_VERSION_PATCH = 0x00F1
|
||||||
REG_INPUT_DEVICE_STATUS = 0x00F2
|
REG_INPUT_DEVICE_STATUS = 0x00F2
|
||||||
REG_INPUT_UPTIME_SECONDS_LOW = 0x00F3
|
REG_INPUT_UPTIME_SECONDS_LOW = 0x00F3
|
||||||
REG_INPUT_UPTIME_SECONDS_HIGH = 0x00F4
|
REG_INPUT_UPTIME_SECONDS_HIGH = 0x00F4
|
||||||
REG_INPUT_SUPPLY_VOLTAGE_MV = 0x00F5
|
|
||||||
REG_INPUT_FWU_LAST_CHUNK_CRC = 0x0100
|
REG_INPUT_FWU_LAST_CHUNK_CRC = 0x0100
|
||||||
REG_HOLDING_VALVE_COMMAND = 0x0000
|
REG_HOLDING_VALVE_COMMAND = 0x0000
|
||||||
REG_HOLDING_MAX_OPENING_TIME_S = 0x0001
|
REG_HOLDING_MAX_OPENING_TIME_S = 0x0001
|
||||||
|
|
@ -85,7 +84,7 @@ def poll_status(slave_id, interval):
|
||||||
# If connected, try to read data
|
# If connected, try to read data
|
||||||
ir_valve = client.read_input_registers(REG_INPUT_VALVE_STATE_MOVEMENT, count=2, slave=slave_id)
|
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_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_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_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)
|
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_minor = ir_sys.registers[0] & 0xFF
|
||||||
fw_patch = ir_sys.registers[1]
|
fw_patch = ir_sys.registers[1]
|
||||||
uptime_seconds = (ir_sys.registers[4] << 16) | ir_sys.registers[3]
|
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["firmware"] = f"v{fw_major}.{fw_minor}.{fw_patch}"
|
||||||
new_data["device_status"] = "OK" if ir_sys.registers[2] == 0 else "ERROR"
|
new_data["device_status"] = "OK" if ir_sys.registers[2] == 0 else "ERROR"
|
||||||
new_data["uptime"] = format_uptime(uptime_seconds)
|
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["watchdog"] = f"{hr_sys.registers[0]}s"
|
||||||
new_data["error"] = None # Clear any previous error on successful read
|
new_data["error"] = None # Clear any previous error on successful read
|
||||||
reconnect_attempts = 0 # Reset attempts on successful communication
|
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(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(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(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)
|
stdscr.addstr(5, 0, "─" * (w - 1), normal)
|
||||||
for idx, row in enumerate(menu):
|
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)
|
draw_button(stdscr, h // 2 - len(menu) + (idx * 2), w // 2 - len(row) // 2, row, idx == current_row_idx)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue