Just saving
This commit is contained in:
parent
222ffea568
commit
c1622bb01c
|
|
@ -1,23 +1,17 @@
|
|||
#include <zephyr/dt-bindings/gpio/gpio.h>
|
||||
|
||||
/ {
|
||||
/* VND7050AJ Sensor Multiplexer - Centralized configuration */
|
||||
vnd7050aj_mux: sensor-multiplexer {
|
||||
compatible = "vnd7050aj,sensor-mux";
|
||||
vnd7050aj: vnd7050aj {
|
||||
compatible = "vnd7050aj-valve-controller";
|
||||
status = "okay";
|
||||
|
||||
/* Shared ADC configuration */
|
||||
io-channels = <&adc1 1>; /* ADC1 channel 1 (PA0) */
|
||||
io-channel-names = "sensor-input";
|
||||
reference-mv = <3300>;
|
||||
|
||||
/* VND7050AJ GPIO pin definitions - shared by all sensors */
|
||||
sen-gpios = <&gpiob 4 GPIO_ACTIVE_HIGH>; /* SEN (PB4) - Sense Enable */
|
||||
s0-gpios = <&gpiob 6 GPIO_ACTIVE_HIGH>; /* S0 (PB6) - Mux select bit 0 */
|
||||
s1-gpios = <&gpiob 5 GPIO_ACTIVE_HIGH>; /* S1 (PB5) - Mux select bit 1 */
|
||||
|
||||
/* Valve control pins (separate from sensor mux) */
|
||||
in0-gpios = <&gpiob 7 GPIO_ACTIVE_HIGH>; /* IN0 (PB7) - Valve input 0 */
|
||||
in1-gpios = <&gpiob 9 GPIO_ACTIVE_HIGH>; /* IN1 (PB9) - Valve input 1 */
|
||||
rst-gpios = <&gpiob 3 GPIO_ACTIVE_HIGH>; /* RST (PB3) - Reset pin */
|
||||
// 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
|
||||
};
|
||||
|
||||
adc_sensors {
|
||||
|
|
@ -25,22 +19,49 @@
|
|||
|
||||
supply_voltage: supply-voltage {
|
||||
compatible = "custom,supply-voltage";
|
||||
sensor-mux = <&vnd7050aj_mux>; /* Reference to shared mux config */
|
||||
|
||||
/* Sensor-specific configuration */
|
||||
io-channels = <&adc1 1>; /* ADC1 channel 1 (PA0) */
|
||||
io-channel-names = "voltage";
|
||||
reference-mv = <3300>;
|
||||
voltage-divider-ratio = <4>; /* Adjust based on your voltage divider */
|
||||
mux-channel = <0>; /* Channel 0: s1=0, s0=0 */
|
||||
measurement-delay-ms = <5>; /* 5ms delay after GPIO setup */
|
||||
|
||||
/* GPIO control pins using VND7050AJ pins */
|
||||
sen-gpios = <&gpiob 4 GPIO_ACTIVE_HIGH>; /* SEN (PB4) - enable sensor */
|
||||
s0-gpios = <&gpiob 6 GPIO_ACTIVE_HIGH>; /* S0 (PB6) - mux select bit 0 */
|
||||
s1-gpios = <&gpiob 5 GPIO_ACTIVE_HIGH>; /* S1 (PB5) - mux select bit 1 */
|
||||
|
||||
measurement-delay-ms = <5>; /* 5ms delay after GPIO setup */
|
||||
};
|
||||
|
||||
motor_current: motor-current {
|
||||
motor_current_open: motor-current-open {
|
||||
compatible = "custom,motor-current";
|
||||
sensor-mux = <&vnd7050aj_mux>; /* Reference to shared mux config */
|
||||
io-channels = <&adc1 1>; /* Same ADC channel, different mux setting */
|
||||
io-channel-names = "current";
|
||||
reference-mv = <3300>;
|
||||
current-sense-resistor-mohm = <1500000>; /* 1.5kΩ sense resistor in mΩ */
|
||||
k-factor = <10>; /* Current sense amplification factor */
|
||||
|
||||
/* Sensor-specific configuration */
|
||||
current-sense-resistor-mohm = <100>; /* 100mΩ sense resistor */
|
||||
mux-channel = <1>; /* Channel 1: s1=0, s0=1 */
|
||||
measurement-delay-ms = <10>; /* 10ms delay for current settling */
|
||||
/* GPIO control pins using VND7050AJ pins */
|
||||
sen-gpios = <&gpiob 4 GPIO_ACTIVE_HIGH>; /* SEN (PB4) - enable sensor */
|
||||
s0-gpios = <&gpiob 6 GPIO_ACTIVE_HIGH>; /* S0 (PB6) - mux select bit 0 */
|
||||
s1-gpios = <&gpiob 5 GPIO_ACTIVE_HIGH>; /* S1 (PB5) - mux select bit 1 */
|
||||
|
||||
measurement-delay-ms = <10>; /* 10ms delay for current settling */
|
||||
};
|
||||
|
||||
motor_current_close: motor-current-close {
|
||||
compatible = "custom,motor-current";
|
||||
io-channels = <&adc1 1>; /* Same ADC channel, different mux setting */
|
||||
io-channel-names = "current";
|
||||
reference-mv = <3300>;
|
||||
current-sense-resistor-mohm = <1500000>; /* 1.5kΩ sense resistor in mΩ */
|
||||
k-factor = <10>; /* Current sense amplification factor */
|
||||
|
||||
/* GPIO control pins using VND7050AJ pins */
|
||||
sen-gpios = <&gpiob 4 GPIO_ACTIVE_HIGH>; /* SEN (PB4) - enable sensor */
|
||||
s0-gpios = <&gpiob 6 GPIO_ACTIVE_HIGH>; /* S0 (PB6) - mux select bit 0 */
|
||||
s1-gpios = <&gpiob 5 GPIO_ACTIVE_HIGH>; /* S1 (PB5) - mux select bit 1 */
|
||||
|
||||
measurement-delay-ms = <10>; /* 10ms delay for current settling */
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,78 @@
|
|||
#include <zephyr/dt-bindings/gpio/gpio.h>
|
||||
|
||||
/ {
|
||||
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
|
||||
};
|
||||
|
||||
adc_sensors {
|
||||
compatible = "adc-sensors";
|
||||
|
||||
supply_voltage: supply-voltage {
|
||||
compatible = "custom,supply-voltage";
|
||||
io-channels = <&adc1 1>; /* ADC1 channel 1 (PA0) */
|
||||
io-channel-names = "voltage";
|
||||
reference-mv = <3300>;
|
||||
voltage-divider-ratio = <4>; /* Adjust based on your voltage divider */
|
||||
sensor-mux = <&vnd7050aj>; /* Reference to VND7050AJ mux */
|
||||
mux-channel = <3>; /* VCC sense channel */
|
||||
measurement-delay-ms = <5>; /* 5ms delay after GPIO setup */
|
||||
};
|
||||
|
||||
motor_current_open: motor-current-open {
|
||||
compatible = "custom,motor-current";
|
||||
io-channels = <&adc1 1>; /* Same ADC channel, different mux setting */
|
||||
io-channel-names = "current";
|
||||
reference-mv = <3300>;
|
||||
current-sense-resistor-mohm = <1500000>; /* 1.5kΩ sense resistor in mΩ */
|
||||
k-factor = <10>; /* Current sense amplification factor */
|
||||
sen-gpios = <&gpiob 4 GPIO_ACTIVE_HIGH>; /* SEN (PB4) - enable sensor */
|
||||
s0-gpios = <&gpiob 6 GPIO_ACTIVE_HIGH>; /* S0 (PB6) - mux select bit 0 */
|
||||
s1-gpios = <&gpiob 5 GPIO_ACTIVE_HIGH>; /* S1 (PB5) - mux select bit 1 */
|
||||
measurement-delay-ms = <10>; /* 10ms delay for current settling */
|
||||
};
|
||||
|
||||
motor_current_close: motor-current-close {
|
||||
compatible = "custom,motor-current";
|
||||
io-channels = <&adc1 1>; /* Same ADC channel, different mux setting */
|
||||
io-channel-names = "current";
|
||||
reference-mv = <3300>;
|
||||
current-sense-resistor-mohm = <1500000>; /* 1.5kΩ sense resistor in mΩ */
|
||||
k-factor = <10>; /* Current sense amplification factor */
|
||||
sen-gpios = <&gpiob 4 GPIO_ACTIVE_HIGH>; /* SEN (PB4) - enable sensor */
|
||||
s0-gpios = <&gpiob 6 GPIO_ACTIVE_HIGH>; /* S0 (PB6) - mux select bit 0 */
|
||||
s1-gpios = <&gpiob 5 GPIO_ACTIVE_HIGH>; /* S1 (PB5) - mux select bit 1 */
|
||||
measurement-delay-ms = <10>; /* 10ms delay for current settling */
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&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>;
|
||||
};
|
||||
|
||||
&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
|
||||
};
|
||||
};
|
||||
|
||||
&zephyr_udc0 {
|
||||
cdc_acm_uart0: cdc_acm_uart0 {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
|
|
|
|||
|
|
@ -4,29 +4,48 @@ description: Motor current sensor using VND7050AJ multiplexer
|
|||
compatible: "custom,motor-current"
|
||||
|
||||
properties:
|
||||
sensor-mux:
|
||||
type: phandle
|
||||
io-channels:
|
||||
type: phandle-array
|
||||
required: true
|
||||
description: Reference to the VND7050AJ sensor multiplexer node
|
||||
description: ADC channel phandle and specifier
|
||||
|
||||
io-channel-names:
|
||||
type: string-array
|
||||
required: true
|
||||
description: Names for the ADC channels
|
||||
|
||||
reference-mv:
|
||||
type: int
|
||||
required: true
|
||||
description: ADC reference voltage in millivolts
|
||||
|
||||
current-sense-resistor-mohm:
|
||||
type: int
|
||||
required: true
|
||||
description: Current sense resistor value in milliohms
|
||||
|
||||
amplifier-gain:
|
||||
type: int
|
||||
required: false
|
||||
default: 1
|
||||
description: Current sense amplifier gain
|
||||
|
||||
mux-channel:
|
||||
k-factor:
|
||||
type: int
|
||||
required: true
|
||||
description: Multiplexer channel number (0-3) for this sensor
|
||||
description: Current sense amplification factor for VND7050AJ
|
||||
|
||||
sen-gpios:
|
||||
type: phandle-array
|
||||
required: true
|
||||
description: GPIO for sensor enable (SEN pin)
|
||||
|
||||
s0-gpios:
|
||||
type: phandle-array
|
||||
required: true
|
||||
description: GPIO for multiplexer select bit 0 (S0 pin)
|
||||
|
||||
s1-gpios:
|
||||
type: phandle-array
|
||||
required: true
|
||||
description: GPIO for multiplexer select bit 1 (S1 pin)
|
||||
|
||||
measurement-delay-ms:
|
||||
type: int
|
||||
required: false
|
||||
default: 10
|
||||
description: Delay in milliseconds after GPIO setup before measurement
|
||||
description: Delay in milliseconds after setting GPIO pins before reading ADC
|
||||
|
|
@ -4,6 +4,21 @@ description: Supply voltage sensor using VND7050AJ multiplexer
|
|||
compatible: "custom,supply-voltage"
|
||||
|
||||
properties:
|
||||
io-channels:
|
||||
type: phandle-array
|
||||
required: true
|
||||
description: ADC channel phandle and specifier
|
||||
|
||||
io-channel-names:
|
||||
type: string-array
|
||||
required: true
|
||||
description: Names for the ADC channels
|
||||
|
||||
reference-mv:
|
||||
type: int
|
||||
required: true
|
||||
description: ADC reference voltage in millivolts
|
||||
|
||||
sensor-mux:
|
||||
type: phandle
|
||||
required: true
|
||||
|
|
|
|||
|
|
@ -48,3 +48,13 @@ properties:
|
|||
type: phandle-array
|
||||
required: false
|
||||
description: GPIO for reset control (RST pin)
|
||||
|
||||
sense-resistor-ohm:
|
||||
type: int
|
||||
required: true
|
||||
description: Current sense resistor value in ohms
|
||||
|
||||
k-factor:
|
||||
type: int
|
||||
required: true
|
||||
description: Current sense ratio for VND7050AJ (typical ~1200:1)
|
||||
|
|
|
|||
|
|
@ -34,13 +34,34 @@ int adc_sensor_init(void);
|
|||
uint16_t adc_sensor_get_voltage_mv(void);
|
||||
|
||||
/**
|
||||
* @brief Gets the current motor current reading.
|
||||
* @brief Gets the current motor current reading (legacy function).
|
||||
*
|
||||
* This function reads the value from the motor driver's sense pin via ADC
|
||||
* and converts it to milliamps. This is used for end-stop detection.
|
||||
* This function reads the current from the opening channel (IN0).
|
||||
* For backward compatibility only. Use adc_sensor_get_current_open_ma()
|
||||
* instead.
|
||||
*
|
||||
* @return The motor current in milliamps (mA).
|
||||
*/
|
||||
uint16_t adc_sensor_get_current_ma(void);
|
||||
|
||||
/**
|
||||
* @brief Gets the motor opening current reading (IN0 current sense).
|
||||
*
|
||||
* This function reads the current from the VND7050AJ IN0 current sense channel.
|
||||
* Used for monitoring valve opening current.
|
||||
*
|
||||
* @return The motor opening current in milliamps (mA).
|
||||
*/
|
||||
uint16_t adc_sensor_get_current_open_ma(void);
|
||||
|
||||
/**
|
||||
* @brief Gets the motor closing current reading (IN1 current sense).
|
||||
*
|
||||
* This function reads the current from the VND7050AJ IN1 current sense channel.
|
||||
* Used for monitoring valve closing current.
|
||||
*
|
||||
* @return The motor closing current in milliamps (mA).
|
||||
*/
|
||||
uint16_t adc_sensor_get_current_close_ma(void);
|
||||
|
||||
#endif /* ADC_SENSOR_H */
|
||||
|
|
|
|||
|
|
@ -23,9 +23,13 @@ enum {
|
|||
*/
|
||||
REG_INPUT_VALVE_STATE_MOVEMENT = 0x0000,
|
||||
/**
|
||||
* @brief Aktueller Motorstrom in Milliampere (mA).
|
||||
* @brief Motorstrom beim Öffnen in Milliampere (mA) - IN0 current sense.
|
||||
*/
|
||||
REG_INPUT_MOTOR_CURRENT_MA = 0x0001,
|
||||
REG_INPUT_MOTOR_OPEN_CURRENT_MA = 0x0001,
|
||||
/**
|
||||
* @brief Motorstrom beim Schließen in Milliampere (mA) - IN1 current sense.
|
||||
*/
|
||||
REG_INPUT_MOTOR_CLOSE_CURRENT_MA = 0x0002,
|
||||
/**
|
||||
* @brief Bitmaske der digitalen Eingänge. Bit 0: Eingang 1, Bit 1: Eingang 2.
|
||||
* 1=Aktiv.
|
||||
|
|
|
|||
|
|
@ -22,30 +22,40 @@ LOG_MODULE_REGISTER(adc_sensor, LOG_LEVEL_INF);
|
|||
|
||||
// Devicetree node checks
|
||||
#define VOLTAGE_SENSOR_NODE DT_NODELABEL(supply_voltage)
|
||||
#define CURRENT_SENSOR_NODE DT_NODELABEL(motor_current)
|
||||
#define SENSOR_MUX_NODE DT_NODELABEL(vnd7050aj_mux)
|
||||
#define CURRENT_OPEN_SENSOR_NODE DT_NODELABEL(motor_current_open)
|
||||
#define CURRENT_CLOSE_SENSOR_NODE DT_NODELABEL(motor_current_close)
|
||||
#define VND7050AJ_NODE DT_NODELABEL(vnd7050aj)
|
||||
|
||||
#ifndef CONFIG_ADC_SENSOR_SIMULATED
|
||||
// ADC device reference from centralized mux node
|
||||
#if DT_NODE_EXISTS(SENSOR_MUX_NODE)
|
||||
#define ADC_NODE DT_PHANDLE(SENSOR_MUX_NODE, io_channels)
|
||||
#define ADC_CHANNEL DT_PHA(SENSOR_MUX_NODE, io_channels, input)
|
||||
#define ADC_RESOLUTION 12
|
||||
#define ADC_REFERENCE_MV DT_PROP(SENSOR_MUX_NODE, reference_mv)
|
||||
// ADC device reference from voltage sensor node (all sensors use same ADC)
|
||||
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
|
||||
#define ADC_NODE DT_PHANDLE(VOLTAGE_SENSOR_NODE, io_channels)
|
||||
#define ADC_REFERENCE_MV DT_PROP(VOLTAGE_SENSOR_NODE, reference_mv)
|
||||
#endif
|
||||
|
||||
#define ADC_CHANNEL 1 /* ADC1 channel 1 as defined in overlay */
|
||||
|
||||
// Sensor-specific properties
|
||||
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
|
||||
#define VOLTAGE_DIVIDER_RATIO \
|
||||
DT_PROP(VOLTAGE_SENSOR_NODE, voltage_divider_ratio)
|
||||
#define VOLTAGE_MUX_CHANNEL DT_PROP(VOLTAGE_SENSOR_NODE, mux_channel)
|
||||
#define VOLTAGE_DELAY_MS DT_PROP(VOLTAGE_SENSOR_NODE, measurement_delay_ms)
|
||||
#endif
|
||||
|
||||
#if DT_NODE_EXISTS(CURRENT_SENSOR_NODE)
|
||||
#define CURRENT_SENSE_RESISTOR_MOHM \
|
||||
DT_PROP(CURRENT_SENSOR_NODE, current_sense_resistor_mohm)
|
||||
#define CURRENT_MUX_CHANNEL DT_PROP(CURRENT_SENSOR_NODE, mux_channel)
|
||||
#define CURRENT_DELAY_MS DT_PROP(CURRENT_SENSOR_NODE, measurement_delay_ms)
|
||||
#if DT_NODE_EXISTS(CURRENT_OPEN_SENSOR_NODE)
|
||||
#define CURRENT_OPEN_SENSE_RESISTOR_MOHM \
|
||||
DT_PROP(CURRENT_OPEN_SENSOR_NODE, current_sense_resistor_mohm)
|
||||
#define CURRENT_OPEN_K_FACTOR DT_PROP(CURRENT_OPEN_SENSOR_NODE, k_factor)
|
||||
#define CURRENT_OPEN_DELAY_MS \
|
||||
DT_PROP(CURRENT_OPEN_SENSOR_NODE, measurement_delay_ms)
|
||||
#endif
|
||||
|
||||
#if DT_NODE_EXISTS(CURRENT_CLOSE_SENSOR_NODE)
|
||||
#define CURRENT_CLOSE_SENSE_RESISTOR_MOHM \
|
||||
DT_PROP(CURRENT_CLOSE_SENSOR_NODE, current_sense_resistor_mohm)
|
||||
#define CURRENT_CLOSE_K_FACTOR DT_PROP(CURRENT_CLOSE_SENSOR_NODE, k_factor)
|
||||
#define CURRENT_CLOSE_DELAY_MS \
|
||||
DT_PROP(CURRENT_CLOSE_SENSOR_NODE, measurement_delay_ms)
|
||||
#endif
|
||||
|
||||
static const struct device *adc_dev;
|
||||
|
|
@ -59,24 +69,23 @@ static struct adc_channel_cfg adc_channel_cfg = {
|
|||
static struct adc_sequence adc_sequence = {
|
||||
.channels = BIT(ADC_CHANNEL),
|
||||
.buffer_size = sizeof(uint16_t),
|
||||
.resolution = ADC_RESOLUTION,
|
||||
.resolution = 12,
|
||||
};
|
||||
|
||||
static uint16_t adc_buffer;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static bool initialized = false;
|
||||
|
||||
#ifndef CONFIG_ADC_SENSOR_SIMULATED
|
||||
// GPIO specs from centralized mux node
|
||||
#if DT_NODE_EXISTS(SENSOR_MUX_NODE)
|
||||
// GPIO specs from VND7050AJ node
|
||||
#if DT_NODE_EXISTS(VND7050AJ_NODE)
|
||||
static const struct gpio_dt_spec sen_gpio =
|
||||
GPIO_DT_SPEC_GET(SENSOR_MUX_NODE, sen_gpios);
|
||||
GPIO_DT_SPEC_GET(VND7050AJ_NODE, sen_gpios);
|
||||
static const struct gpio_dt_spec s0_gpio =
|
||||
GPIO_DT_SPEC_GET(SENSOR_MUX_NODE, s0_gpios);
|
||||
GPIO_DT_SPEC_GET(VND7050AJ_NODE, s0_gpios);
|
||||
static const struct gpio_dt_spec s1_gpio =
|
||||
GPIO_DT_SPEC_GET(SENSOR_MUX_NODE, s1_gpios);
|
||||
GPIO_DT_SPEC_GET(VND7050AJ_NODE, s1_gpios);
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
@ -85,7 +94,7 @@ static const struct gpio_dt_spec s1_gpio =
|
|||
static int configure_sensor_gpios(void) {
|
||||
int ret = 0;
|
||||
|
||||
#if DT_NODE_EXISTS(SENSOR_MUX_NODE)
|
||||
#if DT_NODE_EXISTS(VND7050AJ_NODE)
|
||||
// Configure sensor multiplexer GPIOs
|
||||
if (gpio_is_ready_dt(&sen_gpio)) {
|
||||
ret = gpio_pin_configure_dt(&sen_gpio, GPIO_OUTPUT_INACTIVE);
|
||||
|
|
@ -122,7 +131,7 @@ static int configure_sensor_gpios(void) {
|
|||
* @param delay_ms Delay after setting GPIOs
|
||||
*/
|
||||
static int set_mux_channel(bool enable, uint8_t channel, uint32_t delay_ms) {
|
||||
#if DT_NODE_EXISTS(SENSOR_MUX_NODE)
|
||||
#if DT_NODE_EXISTS(VND7050AJ_NODE)
|
||||
if (gpio_is_ready_dt(&sen_gpio)) {
|
||||
gpio_pin_set_dt(&sen_gpio, enable ? 1 : 0);
|
||||
}
|
||||
|
|
@ -148,7 +157,7 @@ static int set_mux_channel(bool enable, uint8_t channel, uint32_t delay_ms) {
|
|||
* @return ADC reading in millivolts, or 0 on error
|
||||
*/
|
||||
static uint16_t read_adc_voltage_mv(void) {
|
||||
#if DT_NODE_EXISTS(SENSOR_MUX_NODE) && DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
|
||||
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
|
||||
int ret = adc_read(adc_dev, &adc_sequence);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("ADC read failed: %d", ret);
|
||||
|
|
@ -172,11 +181,11 @@ static uint16_t read_adc_voltage_mv(void) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Read ADC value and convert to milliamps (for current sensor)
|
||||
* @brief Read ADC value and convert to milliamps for opening current
|
||||
* @return ADC reading in milliamps, or 0 on error
|
||||
*/
|
||||
static uint16_t read_adc_current_ma(void) {
|
||||
#if DT_NODE_EXISTS(SENSOR_MUX_NODE) && DT_NODE_EXISTS(CURRENT_SENSOR_NODE)
|
||||
static uint16_t read_adc_current_open_ma(void) {
|
||||
#if DT_NODE_EXISTS(CURRENT_OPEN_SENSOR_NODE)
|
||||
int ret = adc_read(adc_dev, &adc_sequence);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("ADC read failed: %d", ret);
|
||||
|
|
@ -187,12 +196,45 @@ static uint16_t read_adc_current_ma(void) {
|
|||
uint32_t adc_value = adc_buffer;
|
||||
uint32_t voltage_mv = (adc_value * ADC_REFERENCE_MV) / 4095;
|
||||
|
||||
// Convert voltage to current based on sense resistor
|
||||
// I = V / R, where R is in milliohms and V is in millivolts
|
||||
// VND7050AJ current calculation: I = V_sense * K / R_sense
|
||||
// Where: V_sense in mV, K is the current sense factor, R_sense in mΩ
|
||||
// Result is in milliamps
|
||||
uint32_t current_ma = (voltage_mv * 1000) / CURRENT_SENSE_RESISTOR_MOHM;
|
||||
uint32_t current_ma = (voltage_mv * CURRENT_OPEN_K_FACTOR * 1000) /
|
||||
CURRENT_OPEN_SENSE_RESISTOR_MOHM;
|
||||
|
||||
LOG_DBG("ADC raw: %u, current: %u mA", adc_value, (uint16_t)current_ma);
|
||||
LOG_DBG("Open current - ADC raw: %u, voltage: %u mV, current: %u mA",
|
||||
adc_value, voltage_mv, (uint16_t)current_ma);
|
||||
|
||||
return (uint16_t)current_ma;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read ADC value and convert to milliamps for closing current
|
||||
* @return ADC reading in milliamps, or 0 on error
|
||||
*/
|
||||
static uint16_t read_adc_current_close_ma(void) {
|
||||
#if DT_NODE_EXISTS(CURRENT_CLOSE_SENSOR_NODE)
|
||||
int ret = adc_read(adc_dev, &adc_sequence);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("ADC read failed: %d", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert ADC reading to millivolts first
|
||||
uint32_t adc_value = adc_buffer;
|
||||
uint32_t voltage_mv = (adc_value * ADC_REFERENCE_MV) / 4095;
|
||||
|
||||
// VND7050AJ current calculation: I = V_sense * K / R_sense
|
||||
// Where: V_sense in mV, K is the current sense factor, R_sense in mΩ
|
||||
// Result is in milliamps
|
||||
uint32_t current_ma = (voltage_mv * CURRENT_CLOSE_K_FACTOR * 1000) /
|
||||
CURRENT_CLOSE_SENSE_RESISTOR_MOHM;
|
||||
|
||||
LOG_DBG("Close current - ADC raw: %u, voltage: %u mV, current: %u mA",
|
||||
adc_value, voltage_mv, (uint16_t)current_ma);
|
||||
|
||||
return (uint16_t)current_ma;
|
||||
#else
|
||||
|
|
@ -219,7 +261,7 @@ int adc_sensor_init(void) {
|
|||
}
|
||||
|
||||
// Initialize ADC hardware
|
||||
#if DT_NODE_EXISTS(SENSOR_MUX_NODE)
|
||||
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
|
||||
adc_dev = DEVICE_DT_GET(ADC_NODE);
|
||||
if (!device_is_ready(adc_dev)) {
|
||||
LOG_ERR("ADC device not ready");
|
||||
|
|
@ -237,15 +279,18 @@ int adc_sensor_init(void) {
|
|||
LOG_INF("ADC device ready: %s", adc_dev->name);
|
||||
#endif
|
||||
|
||||
LOG_INF("ADC sensor initialized (real ADC mode with centralized mux)");
|
||||
LOG_INF("ADC sensor initialized (real ADC mode)");
|
||||
|
||||
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
|
||||
LOG_INF("Voltage sensor: channel %d, divider ratio %d", VOLTAGE_MUX_CHANNEL,
|
||||
VOLTAGE_DIVIDER_RATIO);
|
||||
LOG_INF("Voltage sensor: divider ratio %d", VOLTAGE_DIVIDER_RATIO);
|
||||
#endif
|
||||
#if DT_NODE_EXISTS(CURRENT_SENSOR_NODE)
|
||||
LOG_INF("Current sensor: channel %d, sense resistor %d mOhm",
|
||||
CURRENT_MUX_CHANNEL, CURRENT_SENSE_RESISTOR_MOHM);
|
||||
#if DT_NODE_EXISTS(CURRENT_OPEN_SENSOR_NODE)
|
||||
LOG_INF("Open current sensor: K-factor %d, sense resistor %d mΩ",
|
||||
CURRENT_OPEN_K_FACTOR, CURRENT_OPEN_SENSE_RESISTOR_MOHM);
|
||||
#endif
|
||||
#if DT_NODE_EXISTS(CURRENT_CLOSE_SENSOR_NODE)
|
||||
LOG_INF("Close current sensor: K-factor %d, sense resistor %d mΩ",
|
||||
CURRENT_CLOSE_K_FACTOR, CURRENT_CLOSE_SENSE_RESISTOR_MOHM);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
@ -262,9 +307,9 @@ uint16_t adc_sensor_get_voltage_mv(void) {
|
|||
#ifdef CONFIG_ADC_SENSOR_SIMULATED
|
||||
return SIMULATED_VOLTAGE_MV;
|
||||
#else
|
||||
// Set multiplexer to voltage channel
|
||||
// Set multiplexer to voltage channel (channel 3: VCC sense)
|
||||
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
|
||||
set_mux_channel(true, VOLTAGE_MUX_CHANNEL, VOLTAGE_DELAY_MS);
|
||||
set_mux_channel(true, 3, VOLTAGE_DELAY_MS);
|
||||
|
||||
// Read real ADC value for voltage
|
||||
uint16_t voltage = read_adc_voltage_mv();
|
||||
|
|
@ -280,6 +325,11 @@ uint16_t adc_sensor_get_voltage_mv(void) {
|
|||
}
|
||||
|
||||
uint16_t adc_sensor_get_current_ma(void) {
|
||||
// Legacy function - redirect to opening current for backward compatibility
|
||||
return adc_sensor_get_current_open_ma();
|
||||
}
|
||||
|
||||
uint16_t adc_sensor_get_current_open_ma(void) {
|
||||
if (!initialized) {
|
||||
LOG_WRN("ADC sensor not initialized, calling adc_sensor_init()");
|
||||
adc_sensor_init();
|
||||
|
|
@ -288,12 +338,38 @@ uint16_t adc_sensor_get_current_ma(void) {
|
|||
#ifdef CONFIG_ADC_SENSOR_SIMULATED
|
||||
return SIMULATED_CURRENT_MA;
|
||||
#else
|
||||
// Set multiplexer to current channel
|
||||
#if DT_NODE_EXISTS(CURRENT_SENSOR_NODE)
|
||||
set_mux_channel(true, CURRENT_MUX_CHANNEL, CURRENT_DELAY_MS);
|
||||
// Set multiplexer to IN0 current sense channel (channel 0)
|
||||
#if DT_NODE_EXISTS(CURRENT_OPEN_SENSOR_NODE)
|
||||
set_mux_channel(true, 0, CURRENT_OPEN_DELAY_MS);
|
||||
|
||||
// Read real ADC value for current
|
||||
uint16_t current = read_adc_current_ma();
|
||||
uint16_t current = read_adc_current_open_ma();
|
||||
|
||||
// Disable sensor after measurement to save power
|
||||
set_mux_channel(false, 0, 0);
|
||||
|
||||
return current;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t adc_sensor_get_current_close_ma(void) {
|
||||
if (!initialized) {
|
||||
LOG_WRN("ADC sensor not initialized, calling adc_sensor_init()");
|
||||
adc_sensor_init();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ADC_SENSOR_SIMULATED
|
||||
return SIMULATED_CURRENT_MA;
|
||||
#else
|
||||
// Set multiplexer to IN1 current sense channel (channel 1)
|
||||
#if DT_NODE_EXISTS(CURRENT_CLOSE_SENSOR_NODE)
|
||||
set_mux_channel(true, 1, CURRENT_CLOSE_DELAY_MS);
|
||||
|
||||
// Read real ADC value for current
|
||||
uint16_t current = read_adc_current_close_ma();
|
||||
|
||||
// Disable sensor after measurement to save power
|
||||
set_mux_channel(false, 0, 0);
|
||||
|
|
|
|||
|
|
@ -147,8 +147,11 @@ static int input_reg_rd(uint16_t addr, uint16_t *reg) {
|
|||
case REG_INPUT_VALVE_STATE_MOVEMENT:
|
||||
*reg = (valve_get_movement() << 8) | (valve_get_state() & 0xFF);
|
||||
break;
|
||||
case REG_INPUT_MOTOR_CURRENT_MA:
|
||||
*reg = adc_sensor_get_current_ma();
|
||||
case REG_INPUT_MOTOR_OPEN_CURRENT_MA:
|
||||
*reg = adc_sensor_get_current_open_ma();
|
||||
break;
|
||||
case REG_INPUT_MOTOR_CLOSE_CURRENT_MA:
|
||||
*reg = adc_sensor_get_current_close_ma();
|
||||
break;
|
||||
case REG_INPUT_UPTIME_SECONDS_LOW:
|
||||
*reg = (uint16_t)(uptime_s & 0xFFFF);
|
||||
|
|
|
|||
|
|
@ -17,12 +17,12 @@
|
|||
LOG_MODULE_REGISTER(valve, LOG_LEVEL_INF);
|
||||
|
||||
static const struct valve_gpios valve_gpios = {
|
||||
.in0 = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj_mux), in0_gpios),
|
||||
.in1 = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj_mux), in1_gpios),
|
||||
.rst = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj_mux), rst_gpios),
|
||||
.sen = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj_mux), sen_gpios),
|
||||
.s0 = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj_mux), s0_gpios),
|
||||
.s1 = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj_mux), s1_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;
|
||||
|
|
@ -78,8 +78,8 @@ void valve_init(void) {
|
|||
void valve_open(void) {
|
||||
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);
|
||||
gpio_pin_set_dt(&valve_gpios.in1, 0);
|
||||
current_state = VALVE_STATE_OPEN;
|
||||
current_movement = VALVE_MOVEMENT_OPENING;
|
||||
k_work_schedule(&valve_work, K_MSEC(max_opening_time_s * 1000 * 0.9));
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ from pymodbus.exceptions import ModbusException
|
|||
# --- Register Definitions ---
|
||||
# (omitted for brevity, no changes here)
|
||||
REG_INPUT_VALVE_STATE_MOVEMENT = 0x0000
|
||||
REG_INPUT_MOTOR_CURRENT_MA = 0x0001
|
||||
REG_INPUT_MOTOR_OPEN_CURRENT_MA = 0x0001
|
||||
REG_INPUT_MOTOR_CLOSE_CURRENT_MA = 0x0002
|
||||
REG_INPUT_DIGITAL_INPUTS_STATE = 0x0020
|
||||
REG_INPUT_BUTTON_EVENTS = 0x0021
|
||||
REG_INPUT_FIRMWARE_VERSION_MAJOR_MINOR = 0x00F0
|
||||
|
|
@ -83,14 +84,15 @@ def poll_status(slave_id, interval):
|
|||
continue
|
||||
|
||||
# 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=1, slave=slave_id)
|
||||
ir_current = client.read_input_registers(REG_INPUT_MOTOR_OPEN_CURRENT_MA, 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)
|
||||
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)
|
||||
|
||||
for res in [ir_valve, ir_dig, ir_sys, hr_valve, hr_dig, hr_sys]:
|
||||
for res in [ir_valve, ir_current, ir_dig, ir_sys, hr_valve, hr_dig, hr_sys]:
|
||||
if res.isError():
|
||||
raise ModbusException(str(res))
|
||||
|
||||
|
|
@ -99,7 +101,8 @@ def poll_status(slave_id, interval):
|
|||
state_map = {0: "Closed", 1: "Open"}
|
||||
new_data["movement"] = movement_map.get(valve_state_raw >> 8, 'Unknown')
|
||||
new_data["state"] = state_map.get(valve_state_raw & 0xFF, 'Unknown')
|
||||
new_data["motor_current"] = f"{ir_valve.registers[1]} mA"
|
||||
new_data["motor_current_open"] = f"{ir_current.registers[0]} mA"
|
||||
new_data["motor_current_close"] = f"{ir_current.registers[1]} mA"
|
||||
new_data["open_time"] = f"{hr_valve.registers[0]}s"
|
||||
new_data["close_time"] = f"{hr_valve.registers[1]}s"
|
||||
new_data["digital_inputs"] = f"0x{ir_dig.registers[0]:04X}"
|
||||
|
|
@ -295,7 +298,8 @@ def main_menu(stdscr, slave_id):
|
|||
col1, col2, col3, col4 = 2, 30, 58, 88
|
||||
stdscr.addstr(1, col1, "State:", bold); stdscr.addstr(1, col1 + 18, str(current_data.get('state', 'N/A')), normal)
|
||||
stdscr.addstr(2, col1, "Movement:", bold); stdscr.addstr(2, col1 + 18, str(current_data.get('movement', 'N/A')), normal)
|
||||
stdscr.addstr(3, col1, "Motor Current:", bold); stdscr.addstr(3, col1 + 18, str(current_data.get('motor_current', 'N/A')), normal)
|
||||
stdscr.addstr(3, col1, "Open Current:", bold); stdscr.addstr(3, col1 + 18, str(current_data.get('motor_current_open', 'N/A')), normal)
|
||||
stdscr.addstr(4, col1, "Close Current:", bold); stdscr.addstr(4, col1 + 18, str(current_data.get('motor_current_close', 'N/A')), normal)
|
||||
stdscr.addstr(1, col2, "Digital Inputs:", bold); stdscr.addstr(1, col2 + 18, str(current_data.get('digital_inputs', 'N/A')), normal)
|
||||
stdscr.addstr(2, col2, "Digital Outputs:", bold); stdscr.addstr(2, col2 + 18, str(current_data.get('digital_outputs', 'N/A')), normal)
|
||||
stdscr.addstr(3, col2, "Button Events:", bold); stdscr.addstr(3, col2 + 18, str(current_data.get('button_events', 'N/A')), normal)
|
||||
|
|
@ -306,7 +310,7 @@ def main_menu(stdscr, slave_id):
|
|||
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)
|
||||
stdscr.addstr(6, 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)
|
||||
if time.time() - message_time < 2.0: stdscr.addstr(h - 2, 0, message.ljust(w - 1), curses.color_pair(1) | curses.A_BOLD)
|
||||
|
|
|
|||
Loading…
Reference in New Issue