Compare commits
6 Commits
project-re
...
bb25134b6c
| Author | SHA1 | Date | |
|---|---|---|---|
| bb25134b6c | |||
| 9f96384aa5 | |||
| b543579393 | |||
| 69cf7e9511 | |||
| 8df7aef51b | |||
| f6ee0a5122 |
@@ -38,6 +38,7 @@ 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)
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.20)
|
|
||||||
|
|
||||||
project(fwu)
|
|
||||||
|
|
||||||
target_sources(fwu PRIVATE src/fwu.c)
|
|
||||||
target_include_directories(fwu PUBLIC include)
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.20)
|
|
||||||
|
|
||||||
project(modbus_server)
|
|
||||||
|
|
||||||
target_sources(modbus_server PRIVATE src/modbus_server.c)
|
|
||||||
target_include_directories(modbus_server PUBLIC include)
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.20)
|
|
||||||
|
|
||||||
project(valve)
|
|
||||||
|
|
||||||
target_sources(valve PRIVATE src/valve.c)
|
|
||||||
target_include_directories(valve PUBLIC include)
|
|
||||||
@@ -1,9 +1,50 @@
|
|||||||
|
/ {
|
||||||
|
vnd7050aj: vnd7050aj {
|
||||||
|
compatible = "vnd7050aj-valve-controller";
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
|
// VND7050AJ GPIO pin definitions
|
||||||
|
in0-gpios = <&gpiob 7 GPIO_ACTIVE_HIGH>; // IN0 (PB7) - Input 0 control signal
|
||||||
|
in1-gpios = <&gpiob 9 GPIO_ACTIVE_HIGH>; // IN1 (PB9) - Input 1 control signal
|
||||||
|
rst-gpios = <&gpiob 3 GPIO_ACTIVE_HIGH>; // RST (PB3) - Reset pin for VND7050AJ
|
||||||
|
sen-gpios = <&gpiob 4 GPIO_ACTIVE_HIGH>; // SEN (PB4) - Sense Enable for current monitoring
|
||||||
|
s0-gpios = <&gpiob 6 GPIO_ACTIVE_HIGH>; // S0 (PB6) - Status/Select 0 output from VND7050AJ
|
||||||
|
s1-gpios = <&gpiob 5 GPIO_ACTIVE_HIGH>; // S1 (PB5) - Status/Select 1 output from VND7050AJ
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
&usart1 {
|
&usart1 {
|
||||||
modbus0 {
|
modbus0 {
|
||||||
compatible = "zephyr,modbus-serial";
|
compatible = "zephyr,modbus-serial";
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
status = "okay";
|
status = "okay";
|
||||||
pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>;
|
pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; // PA9=TX, PA10=RX for Modbus communication
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&adc1 { // ADC1 wird für PA0 verwendet
|
||||||
|
status = "okay"; // ADC1 aktivieren
|
||||||
|
pinctrl-0 = <&adc1_in1_pa0>; // Pinmux für PA0 als ADC1_IN1
|
||||||
|
pinctrl-names = "default";
|
||||||
|
st,adc-clock-source = "SYNC";
|
||||||
|
st,adc-prescaler = <4>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
// Definition des ADC-Kanals für MULTISENSE (PA0)
|
||||||
|
channel@1 { // ADC1_IN1 ist Kanal 1
|
||||||
|
reg = <1>; // Kanalnummer
|
||||||
|
zephyr,gain = "ADC_GAIN_1";
|
||||||
|
zephyr,reference = "ADC_REF_INTERNAL";
|
||||||
|
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
|
||||||
|
zephyr,resolution = <12>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&pinctrl {
|
||||||
|
// Pinmux für PA0 als ADC1_IN1 (Analogmodus)
|
||||||
|
adc1_in1_pa0: adc1_in1_pa0 {
|
||||||
|
pinmux = <STM32_PINMUX('A', 0, ANALOG)>; // PA0 in den Analogmodus setzen
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -8,3 +8,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&usart1 {
|
||||||
|
/delete-node/ modbus0;
|
||||||
|
};
|
||||||
@@ -6,42 +6,44 @@
|
|||||||
/**
|
/**
|
||||||
* @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,
|
||||||
/* Firmware Update */
|
REG_INPUT_SUPPLY_VOLTAGE_MV = 0x00F5,
|
||||||
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);
|
||||||
|
|||||||
@@ -2,8 +2,21 @@
|
|||||||
#define VALVE_H
|
#define VALVE_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <zephyr/drivers/gpio.h>
|
||||||
|
|
||||||
enum valve_state { VALVE_STATE_CLOSED, VALVE_STATE_OPEN };
|
struct valve_gpios {
|
||||||
|
const struct gpio_dt_spec in0;
|
||||||
|
const struct gpio_dt_spec in1;
|
||||||
|
const struct gpio_dt_spec rst;
|
||||||
|
const struct gpio_dt_spec sen;
|
||||||
|
const struct gpio_dt_spec s0;
|
||||||
|
const struct gpio_dt_spec s1;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum valve_state {
|
||||||
|
VALVE_STATE_CLOSED,
|
||||||
|
VALVE_STATE_OPEN,
|
||||||
|
};
|
||||||
enum valve_movement { VALVE_MOVEMENT_IDLE, VALVE_MOVEMENT_OPENING, VALVE_MOVEMENT_CLOSING, VALVE_MOVEMENT_ERROR };
|
enum valve_movement { VALVE_MOVEMENT_IDLE, VALVE_MOVEMENT_OPENING, VALVE_MOVEMENT_CLOSING, VALVE_MOVEMENT_ERROR };
|
||||||
|
|
||||||
void valve_init(void);
|
void valve_init(void);
|
||||||
|
|||||||
@@ -128,6 +128,9 @@ 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;
|
||||||
@@ -155,6 +158,17 @@ 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));
|
||||||
@@ -179,20 +193,37 @@ 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;
|
||||||
|
|||||||
@@ -1,10 +1,21 @@
|
|||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/settings/settings.h>
|
#include <zephyr/settings/settings.h>
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
|
#include <zephyr/device.h>
|
||||||
|
#include <zephyr/drivers/gpio.h>
|
||||||
#include <lib/valve.h>
|
#include <lib/valve.h>
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(valve, LOG_LEVEL_INF);
|
LOG_MODULE_REGISTER(valve, LOG_LEVEL_INF);
|
||||||
|
|
||||||
|
static const struct valve_gpios valve_gpios = {
|
||||||
|
.in0 = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj), in0_gpios),
|
||||||
|
.in1 = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj), in1_gpios),
|
||||||
|
.rst = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj), rst_gpios),
|
||||||
|
.sen = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj), sen_gpios),
|
||||||
|
.s0 = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj), s0_gpios),
|
||||||
|
.s1 = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj), s1_gpios),
|
||||||
|
};
|
||||||
|
|
||||||
static enum valve_state current_state = VALVE_STATE_CLOSED;
|
static enum valve_state current_state = VALVE_STATE_CLOSED;
|
||||||
static enum valve_movement current_movement = VALVE_MOVEMENT_IDLE;
|
static enum valve_movement current_movement = VALVE_MOVEMENT_IDLE;
|
||||||
static uint16_t max_opening_time_s = 60;
|
static uint16_t max_opening_time_s = 60;
|
||||||
@@ -13,11 +24,15 @@ static struct k_work_delayable valve_work;
|
|||||||
|
|
||||||
static void valve_work_handler(struct k_work *work)
|
static void valve_work_handler(struct k_work *work)
|
||||||
{
|
{
|
||||||
|
gpio_pin_set_dt(&valve_gpios.in0, 0);
|
||||||
|
gpio_pin_set_dt(&valve_gpios.in1, 0);
|
||||||
|
gpio_pin_set_dt(&valve_gpios.rst, 0);
|
||||||
|
|
||||||
if (current_movement == VALVE_MOVEMENT_OPENING) {
|
if (current_movement == VALVE_MOVEMENT_OPENING) {
|
||||||
LOG_INF("Virtual valve finished opening");
|
LOG_INF("Valve finished opening");
|
||||||
} else if (current_movement == VALVE_MOVEMENT_CLOSING) {
|
} else if (current_movement == VALVE_MOVEMENT_CLOSING) {
|
||||||
current_state = VALVE_STATE_CLOSED;
|
current_state = VALVE_STATE_CLOSED;
|
||||||
LOG_INF("Virtual valve finished closing");
|
LOG_INF("Valve finished closing");
|
||||||
}
|
}
|
||||||
current_movement = VALVE_MOVEMENT_IDLE;
|
current_movement = VALVE_MOVEMENT_IDLE;
|
||||||
}
|
}
|
||||||
@@ -27,22 +42,35 @@ void valve_init(void)
|
|||||||
k_work_init_delayable(&valve_work, valve_work_handler);
|
k_work_init_delayable(&valve_work, valve_work_handler);
|
||||||
settings_load_one("valve/max_open_time", &max_opening_time_s, sizeof(max_opening_time_s));
|
settings_load_one("valve/max_open_time", &max_opening_time_s, sizeof(max_opening_time_s));
|
||||||
settings_load_one("valve/max_close_time", &max_closing_time_s, sizeof(max_closing_time_s));
|
settings_load_one("valve/max_close_time", &max_closing_time_s, sizeof(max_closing_time_s));
|
||||||
|
|
||||||
|
gpio_pin_configure_dt(&valve_gpios.in0, GPIO_OUTPUT_INACTIVE);
|
||||||
|
gpio_pin_configure_dt(&valve_gpios.in1, GPIO_OUTPUT_INACTIVE);
|
||||||
|
gpio_pin_configure_dt(&valve_gpios.rst, GPIO_OUTPUT_INACTIVE);
|
||||||
|
gpio_pin_configure_dt(&valve_gpios.sen, GPIO_OUTPUT_INACTIVE);
|
||||||
|
gpio_pin_configure_dt(&valve_gpios.s0, GPIO_OUTPUT_INACTIVE);
|
||||||
|
gpio_pin_configure_dt(&valve_gpios.s1, GPIO_OUTPUT_INACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void valve_open(void)
|
void valve_open(void)
|
||||||
{
|
{
|
||||||
if (current_state == VALVE_STATE_CLOSED) {
|
if (current_state == VALVE_STATE_CLOSED) {
|
||||||
|
gpio_pin_set_dt(&valve_gpios.rst, 1);
|
||||||
|
gpio_pin_set_dt(&valve_gpios.in1, 0);
|
||||||
|
gpio_pin_set_dt(&valve_gpios.in0, 1);
|
||||||
current_state = VALVE_STATE_OPEN;
|
current_state = VALVE_STATE_OPEN;
|
||||||
current_movement = VALVE_MOVEMENT_OPENING;
|
current_movement = VALVE_MOVEMENT_OPENING;
|
||||||
k_work_schedule(&valve_work, K_SECONDS(max_opening_time_s));
|
k_work_schedule(&valve_work, K_MSEC(max_opening_time_s * 1000 * 0.9));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void valve_close(void)
|
void valve_close(void)
|
||||||
{
|
{
|
||||||
if (current_state == VALVE_STATE_OPEN) {
|
if (current_state == VALVE_STATE_OPEN) {
|
||||||
|
gpio_pin_set_dt(&valve_gpios.rst, 1);
|
||||||
|
gpio_pin_set_dt(&valve_gpios.in0, 0);
|
||||||
|
gpio_pin_set_dt(&valve_gpios.in1, 1);
|
||||||
current_movement = VALVE_MOVEMENT_CLOSING;
|
current_movement = VALVE_MOVEMENT_CLOSING;
|
||||||
k_work_schedule(&valve_work, K_SECONDS(max_closing_time_s));
|
k_work_schedule(&valve_work, K_MSEC(max_closing_time_s * 1000 * 0.9));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ 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
|
||||||
@@ -84,7 +85,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=5, slave=slave_id)
|
ir_sys = client.read_input_registers(REG_INPUT_FIRMWARE_VERSION_MAJOR_MINOR, count=6, 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)
|
||||||
@@ -109,9 +110,11 @@ 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
|
||||||
@@ -302,6 +305,7 @@ 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)
|
||||||
|
|||||||
Reference in New Issue
Block a user