Implement real ADC readings with VND7050AJ sensor multiplexing
- Switch from simulated to real ADC readings in adc_sensor library - Add GPIO control for VND7050AJ sensor selection (sen, s0, s1 pins) - Implement proper ADC device and channel setup for voltage/current measurements - Enable ADC driver in prj.conf (CONFIG_ADC=y) - Disable simulation mode (CONFIG_ADC_SENSOR_SIMULATED=n) - Add devicetree bindings for custom supply voltage and motor current sensors - Update overlay with adc_sensors nodes using PB4, PB5, PB6 pins - Integrate real ADC readings into Modbus server registers - Support HSE/HSI clock source toggling in overlay configuration
This commit is contained in:
parent
b11f844415
commit
a9a0626913
|
|
@ -22,4 +22,5 @@ CONFIG_MODBUS_BUFFER_SIZE=256
|
|||
|
||||
# ADC Sensor Configuration - Use real ADC readings
|
||||
CONFIG_ADC_SENSOR_SIMULATED=n
|
||||
CONFIG_ADC=y
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,34 @@ LOG_MODULE_REGISTER(adc_sensor, LOG_LEVEL_INF);
|
|||
#define VOLTAGE_SENSOR_NODE DT_NODELABEL(supply_voltage)
|
||||
#define CURRENT_SENSOR_NODE DT_NODELABEL(motor_current)
|
||||
|
||||
#ifndef CONFIG_ADC_SENSOR_SIMULATED
|
||||
// ADC device reference
|
||||
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
|
||||
#define ADC_NODE DT_PHANDLE(VOLTAGE_SENSOR_NODE, io_channels)
|
||||
#define ADC_CHANNEL DT_PHA(VOLTAGE_SENSOR_NODE, io_channels, input)
|
||||
#define ADC_RESOLUTION 12
|
||||
#define ADC_REFERENCE_MV DT_PROP(VOLTAGE_SENSOR_NODE, reference_mv)
|
||||
#define VOLTAGE_DIVIDER_RATIO \
|
||||
DT_PROP(VOLTAGE_SENSOR_NODE, voltage_divider_ratio)
|
||||
|
||||
static const struct device *adc_dev;
|
||||
static struct adc_channel_cfg adc_channel_cfg = {
|
||||
.gain = ADC_GAIN_1,
|
||||
.reference = ADC_REF_INTERNAL,
|
||||
.acquisition_time = ADC_ACQ_TIME_DEFAULT,
|
||||
.channel_id = ADC_CHANNEL,
|
||||
.differential = 0};
|
||||
|
||||
static struct adc_sequence adc_sequence = {
|
||||
.channels = BIT(ADC_CHANNEL),
|
||||
.buffer_size = sizeof(uint16_t),
|
||||
.resolution = ADC_RESOLUTION,
|
||||
};
|
||||
|
||||
static uint16_t adc_buffer;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static bool initialized = false;
|
||||
|
||||
#ifndef CONFIG_ADC_SENSOR_SIMULATED
|
||||
|
|
@ -165,6 +193,65 @@ static int set_current_sensor_gpios(bool enable, bool s0_state, bool s1_state) {
|
|||
}
|
||||
#endif /* !CONFIG_ADC_SENSOR_SIMULATED */
|
||||
|
||||
#ifndef CONFIG_ADC_SENSOR_SIMULATED
|
||||
/**
|
||||
* @brief Read ADC value and convert to millivolts
|
||||
* @return ADC reading in millivolts, or 0 on error
|
||||
*/
|
||||
static uint16_t read_adc_voltage_mv(void) {
|
||||
#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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert ADC reading to millivolts
|
||||
// ADC reading is 12-bit (0-4095) representing 0 to ADC_REFERENCE_MV
|
||||
uint32_t adc_value = adc_buffer;
|
||||
uint32_t voltage_mv = (adc_value * ADC_REFERENCE_MV) / 4095;
|
||||
|
||||
// Apply voltage divider scaling
|
||||
voltage_mv *= VOLTAGE_DIVIDER_RATIO;
|
||||
|
||||
LOG_DBG("ADC raw: %u, voltage: %u mV", adc_value, (uint16_t)voltage_mv);
|
||||
|
||||
return (uint16_t)voltage_mv;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read ADC value and convert to milliamps (for current sensor)
|
||||
* @return ADC reading in milliamps, or 0 on error
|
||||
*/
|
||||
static uint16_t read_adc_current_ma(void) {
|
||||
#if DT_NODE_EXISTS(CURRENT_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;
|
||||
|
||||
// Convert voltage to current based on current sensor characteristics
|
||||
// Assuming a linear current sensor with specific mV/mA ratio
|
||||
// This will need to be calibrated for your specific current sensor
|
||||
uint32_t current_ma = voltage_mv / 10; // Example: 10mV per mA
|
||||
|
||||
LOG_DBG("ADC raw: %u, current: %u mA", adc_value, (uint16_t)current_ma);
|
||||
|
||||
return (uint16_t)current_ma;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
int adc_sensor_init(void) {
|
||||
if (initialized) {
|
||||
return 0;
|
||||
|
|
@ -182,7 +269,25 @@ int adc_sensor_init(void) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
// TODO: Initialize real ADC hardware
|
||||
// Initialize ADC hardware
|
||||
#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");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
adc_sequence.buffer = &adc_buffer;
|
||||
|
||||
ret = adc_channel_setup(adc_dev, &adc_channel_cfg);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to setup ADC channel: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LOG_INF("ADC device ready: %s", adc_dev->name);
|
||||
#endif
|
||||
|
||||
LOG_INF("ADC sensor initialized (real ADC mode with GPIO control)");
|
||||
|
||||
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
|
||||
|
|
@ -209,9 +314,8 @@ uint16_t adc_sensor_get_voltage_mv(void) {
|
|||
// Set GPIOs for voltage measurement (example: s0=0, s1=0 for channel 0)
|
||||
set_voltage_sensor_gpios(true, false, false);
|
||||
|
||||
// TODO: Read real ADC value for voltage
|
||||
// For now return simulated value
|
||||
uint16_t voltage = SIMULATED_VOLTAGE_MV;
|
||||
// Read real ADC value for voltage
|
||||
uint16_t voltage = read_adc_voltage_mv();
|
||||
|
||||
// Disable sensor after measurement to save power
|
||||
set_voltage_sensor_gpios(false, false, false);
|
||||
|
|
@ -232,9 +336,8 @@ uint16_t adc_sensor_get_current_ma(void) {
|
|||
// Set GPIOs for current measurement (example: s0=1, s1=0 for channel 1)
|
||||
set_current_sensor_gpios(true, true, false);
|
||||
|
||||
// TODO: Read real ADC value for current
|
||||
// For now return simulated value
|
||||
uint16_t current = SIMULATED_CURRENT_MA;
|
||||
// Read real ADC value for current
|
||||
uint16_t current = read_adc_current_ma();
|
||||
|
||||
// Disable sensor after measurement to save power
|
||||
set_current_sensor_gpios(false, false, false);
|
||||
|
|
|
|||
Loading…
Reference in New Issue