mirror of
https://github.com/esphome/esphome.git
synced 2025-04-05 18:30:28 +01:00
add test for adc
This commit is contained in:
parent
df35ceea7b
commit
de236e7ea1
@ -19,7 +19,7 @@ ADC_MODE(ADC_VCC)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_ZEPHYR
|
#ifdef USE_ZEPHYR
|
||||||
static const struct adc_dt_spec adc_chan = ADC_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), 1);
|
#include "hal/nrf_saadc.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
@ -95,15 +95,14 @@ extern "C"
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_ZEPHYR
|
#ifdef USE_ZEPHYR
|
||||||
adc_chan_ = &adc_chan;
|
if (!adc_is_ready_dt(adc_channel_)) {
|
||||||
if (!adc_is_ready_dt(adc_chan_)) {
|
ESP_LOGE(TAG, "ADC controller device %s not ready", adc_channel_->dev->name);
|
||||||
ESP_LOGE(TAG, "ADC controller device %s not ready", adc_chan_->dev->name);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto err = adc_channel_setup_dt(adc_chan_);
|
auto err = adc_channel_setup_dt(adc_channel_);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
ESP_LOGE(TAG, "Could not setup channel %s (%d)", adc_chan_->dev->name, err);
|
ESP_LOGE(TAG, "Could not setup channel %s (%d)", adc_channel_->dev->name, err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -158,8 +157,110 @@ void ADCSensor::dump_config() {
|
|||||||
#endif // USE_RP2040
|
#endif // USE_RP2040
|
||||||
|
|
||||||
#ifdef USE_ZEPHYR
|
#ifdef USE_ZEPHYR
|
||||||
ESP_LOGCONFIG(TAG, " Name: %s, channel_id: %d, vref_mv: %d, resolution %d, oversampling %d", adc_chan_->dev->name,
|
ESP_LOGCONFIG(TAG, " Name: %s, channel_id: %d, vref_mv: %d, resolution %d, oversampling %d", adc_channel_->dev->name,
|
||||||
adc_chan_->channel_id, adc_chan_->vref_mv, adc_chan_->resolution, adc_chan_->oversampling);
|
adc_channel_->channel_id, adc_channel_->vref_mv, adc_channel_->resolution, adc_channel_->oversampling);
|
||||||
|
|
||||||
|
auto gain = [](enum adc_gain gain) {
|
||||||
|
switch (gain) {
|
||||||
|
case ADC_GAIN_1_6: /**< x 1/6. */
|
||||||
|
return "1/6";
|
||||||
|
case ADC_GAIN_1_5: /**< x 1/5. */
|
||||||
|
return "1/5";
|
||||||
|
case ADC_GAIN_1_4: /**< x 1/4. */
|
||||||
|
return "1/4";
|
||||||
|
case ADC_GAIN_1_3: /**< x 1/3. */
|
||||||
|
return "1/3";
|
||||||
|
case ADC_GAIN_2_5: /**< x 2/5. */
|
||||||
|
return "2/5";
|
||||||
|
case ADC_GAIN_1_2: /**< x 1/2. */
|
||||||
|
return "1/2";
|
||||||
|
case ADC_GAIN_2_3: /**< x 2/3. */
|
||||||
|
return "2/3";
|
||||||
|
case ADC_GAIN_4_5: /**< x 4/5. */
|
||||||
|
return "4/5";
|
||||||
|
case ADC_GAIN_1: /**< x 1. */
|
||||||
|
return "1";
|
||||||
|
case ADC_GAIN_2: /**< x 2. */
|
||||||
|
return "2";
|
||||||
|
case ADC_GAIN_3: /**< x 3. */
|
||||||
|
return "3";
|
||||||
|
case ADC_GAIN_4: /**< x 4. */
|
||||||
|
return "4";
|
||||||
|
case ADC_GAIN_6: /**< x 6. */
|
||||||
|
return "6";
|
||||||
|
case ADC_GAIN_8: /**< x 8. */
|
||||||
|
return "8";
|
||||||
|
case ADC_GAIN_12: /**< x 12. */
|
||||||
|
return "12";
|
||||||
|
case ADC_GAIN_16: /**< x 16. */
|
||||||
|
return "16";
|
||||||
|
case ADC_GAIN_24: /**< x 24. */
|
||||||
|
return "24";
|
||||||
|
case ADC_GAIN_32: /**< x 32. */
|
||||||
|
return "32";
|
||||||
|
case ADC_GAIN_64: /**< x 64. */
|
||||||
|
return "64";
|
||||||
|
case ADC_GAIN_128: /**< x 128. */
|
||||||
|
return "128";
|
||||||
|
}
|
||||||
|
return "undefined";
|
||||||
|
};
|
||||||
|
|
||||||
|
auto reference = [](enum adc_reference reference) {
|
||||||
|
switch (reference) {
|
||||||
|
case ADC_REF_VDD_1:
|
||||||
|
return "VDD";
|
||||||
|
case ADC_REF_VDD_1_2:
|
||||||
|
return "VDD/2";
|
||||||
|
case ADC_REF_VDD_1_3:
|
||||||
|
return "VDD/2";
|
||||||
|
case ADC_REF_VDD_1_4:
|
||||||
|
return "VDD/4";
|
||||||
|
case ADC_REF_INTERNAL:
|
||||||
|
return "INTERNAL";
|
||||||
|
case ADC_REF_EXTERNAL0:
|
||||||
|
return "External, input 0";
|
||||||
|
case ADC_REF_EXTERNAL1:
|
||||||
|
return "External, input 1";
|
||||||
|
}
|
||||||
|
return "undefined";
|
||||||
|
};
|
||||||
|
|
||||||
|
auto input = [](uint8_t input) {
|
||||||
|
switch (input) {
|
||||||
|
case NRF_SAADC_INPUT_AIN0:
|
||||||
|
return "AIN0";
|
||||||
|
case NRF_SAADC_INPUT_AIN1:
|
||||||
|
return "AIN1";
|
||||||
|
case NRF_SAADC_INPUT_AIN2:
|
||||||
|
return "AIN2";
|
||||||
|
case NRF_SAADC_INPUT_AIN3:
|
||||||
|
return "AIN3";
|
||||||
|
case NRF_SAADC_INPUT_AIN4:
|
||||||
|
return "AIN4";
|
||||||
|
case NRF_SAADC_INPUT_AIN5:
|
||||||
|
return "AIN5";
|
||||||
|
case NRF_SAADC_INPUT_AIN6:
|
||||||
|
return "AIN6";
|
||||||
|
case NRF_SAADC_INPUT_AIN7:
|
||||||
|
return "AIN7";
|
||||||
|
case NRF_SAADC_INPUT_VDD:
|
||||||
|
return "VDD";
|
||||||
|
case NRF_SAADC_INPUT_VDDHDIV5:
|
||||||
|
return "VDDHDIV5";
|
||||||
|
}
|
||||||
|
return "undefined";
|
||||||
|
};
|
||||||
|
|
||||||
|
ESP_LOGCONFIG(TAG, " Gain: %s, reference: %s, acquisition_time: %d, differential %s",
|
||||||
|
gain(adc_channel_->channel_cfg.gain), reference(adc_channel_->channel_cfg.reference),
|
||||||
|
adc_channel_->channel_cfg.acquisition_time, YESNO(adc_channel_->channel_cfg.differential));
|
||||||
|
if (adc_channel_->channel_cfg.differential) {
|
||||||
|
ESP_LOGCONFIG(TAG, " Input positive: %s, negative: %s", input(adc_channel_->channel_cfg.input_positive),
|
||||||
|
input(adc_channel_->channel_cfg.input_negative));
|
||||||
|
} else {
|
||||||
|
ESP_LOGCONFIG(TAG, " Input positive: %s", input(adc_channel_->channel_cfg.input_positive));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LOG_UPDATE_INTERVAL(this);
|
LOG_UPDATE_INTERVAL(this);
|
||||||
@ -331,11 +432,11 @@ float ADCSensor::sample() {
|
|||||||
};
|
};
|
||||||
int32_t val_mv;
|
int32_t val_mv;
|
||||||
|
|
||||||
adc_sequence_init_dt(adc_chan_, &sequence);
|
adc_sequence_init_dt(adc_channel_, &sequence);
|
||||||
|
|
||||||
auto err = adc_read(adc_chan_->dev, &sequence);
|
auto err = adc_read(adc_channel_->dev, &sequence);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
ESP_LOGE(TAG, "Could not read %s (%d)", adc_chan_->dev->name, err);
|
ESP_LOGE(TAG, "Could not read %s (%d)", adc_channel_->dev->name, err);
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +445,7 @@ float ADCSensor::sample() {
|
|||||||
* in the ADC sample buffer should be a signed 2's
|
* in the ADC sample buffer should be a signed 2's
|
||||||
* complement value.
|
* complement value.
|
||||||
*/
|
*/
|
||||||
if (adc_chan_->channel_cfg.differential) {
|
if (adc_channel_->channel_cfg.differential) {
|
||||||
val_mv = (int32_t) ((int16_t) buf);
|
val_mv = (int32_t) ((int16_t) buf);
|
||||||
} else {
|
} else {
|
||||||
val_mv = (int32_t) buf;
|
val_mv = (int32_t) buf;
|
||||||
@ -354,10 +455,10 @@ float ADCSensor::sample() {
|
|||||||
return val_mv;
|
return val_mv;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = adc_raw_to_millivolts_dt(adc_chan_, &val_mv);
|
err = adc_raw_to_millivolts_dt(adc_channel_, &val_mv);
|
||||||
/* conversion to mV may not be supported, skip if not */
|
/* conversion to mV may not be supported, skip if not */
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
ESP_LOGE(TAG, "Value in mV not available %s (%d)", adc_chan_->dev->name, err);
|
ESP_LOGE(TAG, "Value in mV not available %s (%d)", adc_channel_->dev->name, err);
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,8 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
|||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
#ifndef USE_ZEPHYR
|
#ifndef USE_ZEPHYR
|
||||||
void set_pin(InternalGPIOPin *pin) { this->pin_ = pin; }
|
void set_pin(InternalGPIOPin *pin) { this->pin_ = pin; }
|
||||||
|
#else
|
||||||
|
void set_adc_channel(const adc_dt_spec *adc_channel) { this->adc_channel_ = adc_channel; }
|
||||||
#endif
|
#endif
|
||||||
void set_output_raw(bool output_raw) { output_raw_ = output_raw; }
|
void set_output_raw(bool output_raw) { output_raw_ = output_raw; }
|
||||||
float sample() override;
|
float sample() override;
|
||||||
@ -58,7 +60,7 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
|||||||
#ifndef USE_ZEPHYR
|
#ifndef USE_ZEPHYR
|
||||||
InternalGPIOPin *pin_;
|
InternalGPIOPin *pin_;
|
||||||
#else
|
#else
|
||||||
const struct adc_dt_spec *adc_chan_;
|
const struct adc_dt_spec *adc_channel_ = nullptr;
|
||||||
#endif
|
#endif
|
||||||
bool output_raw_{false};
|
bool output_raw_{false};
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
from esphome.cpp_generator import MockObj
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
import esphome.final_validate as fv
|
import esphome.final_validate as fv
|
||||||
@ -56,6 +57,10 @@ ADCSensor = adc_ns.class_(
|
|||||||
"ADCSensor", sensor.Sensor, cg.PollingComponent, voltage_sampler.VoltageSampler
|
"ADCSensor", sensor.Sensor, cg.PollingComponent, voltage_sampler.VoltageSampler
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CONF_NRF_SAADC = "nrf_saadc"
|
||||||
|
|
||||||
|
adc_dt_spec = cg.global_ns.class_("adc_dt_spec").operator("const")
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.All(
|
CONFIG_SCHEMA = cv.All(
|
||||||
sensor.sensor_schema(
|
sensor.sensor_schema(
|
||||||
ADCSensor,
|
ADCSensor,
|
||||||
@ -71,6 +76,9 @@ CONFIG_SCHEMA = cv.All(
|
|||||||
cv.SplitDefault(CONF_ATTENUATION, esp32="0db"): cv.All(
|
cv.SplitDefault(CONF_ATTENUATION, esp32="0db"): cv.All(
|
||||||
cv.only_on_esp32, cv.enum(ATTENUATION_MODES, lower=True)
|
cv.only_on_esp32, cv.enum(ATTENUATION_MODES, lower=True)
|
||||||
),
|
),
|
||||||
|
cv.GenerateID(CONF_NRF_SAADC): cv.All(
|
||||||
|
cv.only_on_nrf52, cv.declare_id(adc_dt_spec)
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.extend(cv.polling_component_schema("60s")),
|
.extend(cv.polling_component_schema("60s")),
|
||||||
@ -91,48 +99,36 @@ async def to_code(config):
|
|||||||
cg.add(var.set_is_temperature())
|
cg.add(var.set_is_temperature())
|
||||||
elif CORE.using_zephyr:
|
elif CORE.using_zephyr:
|
||||||
zephyr_add_prj_conf("ADC", True)
|
zephyr_add_prj_conf("ADC", True)
|
||||||
|
nrf_saadc = config[CONF_NRF_SAADC]
|
||||||
|
channel_id = int(str(nrf_saadc)[str(nrf_saadc).find("_id") + 4 :] or "1") - 1
|
||||||
|
rhs = MockObj(f"ADC_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), {channel_id})")
|
||||||
|
adc = cg.new_Pvariable(nrf_saadc, rhs)
|
||||||
|
cg.add(var.set_adc_channel(adc))
|
||||||
|
gain = "ADC_GAIN_1_6"
|
||||||
zephyr_add_overlay(
|
zephyr_add_overlay(
|
||||||
"""
|
"""
|
||||||
/ {
|
/ {
|
||||||
zephyr,user {
|
zephyr,user {
|
||||||
io-channels = <&adc 0>, <&adc 1>, <&adc 7>;
|
io-channels = <&adc 0>, <&adc 1>, <&adc 2>;
|
||||||
};
|
};
|
||||||
};
|
};"""
|
||||||
|
)
|
||||||
&adc {
|
zephyr_add_overlay(
|
||||||
|
f"""
|
||||||
|
&adc {{
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
|
|
||||||
channel@0 {
|
channel@{channel_id} {{
|
||||||
reg = <0>;
|
reg = <{channel_id}>;
|
||||||
zephyr,gain = "ADC_GAIN_1_6";
|
zephyr,gain = "{gain}";
|
||||||
zephyr,reference = "ADC_REF_INTERNAL";
|
zephyr,reference = "ADC_REF_INTERNAL";
|
||||||
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
|
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
|
||||||
zephyr,input-positive = <NRF_SAADC_AIN1>; /* P0.03 */
|
zephyr,input-positive = <NRF_SAADC_{config[CONF_PIN][CONF_NUMBER]}>;
|
||||||
zephyr,resolution = <12>;
|
|
||||||
};
|
|
||||||
|
|
||||||
channel@1 {
|
|
||||||
reg = <1>;
|
|
||||||
zephyr,gain = "ADC_GAIN_1_6";
|
|
||||||
zephyr,reference = "ADC_REF_INTERNAL";
|
|
||||||
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
|
|
||||||
zephyr,input-positive = <NRF_SAADC_VDD>;
|
|
||||||
zephyr,resolution = <14>;
|
zephyr,resolution = <14>;
|
||||||
zephyr,oversampling = <8>;
|
zephyr,oversampling = <8>;
|
||||||
};
|
}};
|
||||||
|
}};
|
||||||
channel@7 {
|
|
||||||
reg = <7>;
|
|
||||||
zephyr,gain = "ADC_GAIN_1_5";
|
|
||||||
zephyr,reference = "ADC_REF_VDD_1_4";
|
|
||||||
zephyr,vref-mv = <750>;
|
|
||||||
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
|
|
||||||
zephyr,input-positive = <NRF_SAADC_AIN6>; /* P0.30 */
|
|
||||||
zephyr,input-negative = <NRF_SAADC_AIN7>; /* P0.31 */
|
|
||||||
zephyr,resolution = <12>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
@ -46,7 +46,7 @@ ADC_INPUTS = [
|
|||||||
"AIN6",
|
"AIN6",
|
||||||
"AIN7",
|
"AIN7",
|
||||||
"VDD",
|
"VDD",
|
||||||
"VDDH",
|
"VDDHDIV5",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class BLENUS : public Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BLENUS(size_t buffer_size = 1024);
|
BLENUS(size_t buffer_size = 2048);
|
||||||
void setup() override;
|
void setup() override;
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
void loop() override;
|
void loop() override;
|
||||||
|
18
tests/components/adc/test.nrf52-adafruit.yaml
Normal file
18
tests/components/adc/test.nrf52-adafruit.yaml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
sensor:
|
||||||
|
- platform: uptime
|
||||||
|
name: Uptime Sensor
|
||||||
|
update_interval: 5sec
|
||||||
|
- platform: adc
|
||||||
|
pin: VDDHDIV5
|
||||||
|
name: "VDDH Voltage"
|
||||||
|
update_interval: 5sec
|
||||||
|
filters:
|
||||||
|
- multiply: 5
|
||||||
|
- platform: adc
|
||||||
|
pin: VDD
|
||||||
|
name: "VDD Voltage"
|
||||||
|
update_interval: 5sec
|
||||||
|
- platform: adc
|
||||||
|
pin: AIN0
|
||||||
|
name: "AIN0 Voltage"
|
||||||
|
update_interval: 5sec
|
18
tests/components/adc/test.nrf52.yaml
Normal file
18
tests/components/adc/test.nrf52.yaml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
sensor:
|
||||||
|
- platform: uptime
|
||||||
|
name: Uptime Sensor
|
||||||
|
update_interval: 5sec
|
||||||
|
- platform: adc
|
||||||
|
pin: VDDHDIV5
|
||||||
|
name: "VDDH Voltage"
|
||||||
|
update_interval: 5sec
|
||||||
|
filters:
|
||||||
|
- multiply: 5
|
||||||
|
- platform: adc
|
||||||
|
pin: VDD
|
||||||
|
name: "VDD Voltage"
|
||||||
|
update_interval: 5sec
|
||||||
|
- platform: adc
|
||||||
|
pin: AIN0
|
||||||
|
name: "AIN0 Voltage"
|
||||||
|
update_interval: 5sec
|
1
tests/components/uptime/test.nrf52-adafruit.yaml
Normal file
1
tests/components/uptime/test.nrf52-adafruit.yaml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<<: !include common.yaml
|
1
tests/components/uptime/test.nrf52.yaml
Normal file
1
tests/components/uptime/test.nrf52.yaml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<<: !include common.yaml
|
@ -80,10 +80,15 @@ zephyr_debug:
|
|||||||
debug:
|
debug:
|
||||||
|
|
||||||
sensor:
|
sensor:
|
||||||
|
- platform: uptime
|
||||||
|
name: Uptime Sensor
|
||||||
|
update_interval: 5sec
|
||||||
- platform: adc
|
- platform: adc
|
||||||
pin: VDDH
|
pin: VDDHDIV5
|
||||||
name: "VDDH Voltage"
|
name: "VDDH Voltage"
|
||||||
update_interval: 5sec
|
update_interval: 5sec
|
||||||
|
filters:
|
||||||
|
- multiply: 5
|
||||||
- platform: adc
|
- platform: adc
|
||||||
pin: VDD
|
pin: VDD
|
||||||
name: "VDD Voltage"
|
name: "VDD Voltage"
|
||||||
|
@ -45,9 +45,21 @@ zephyr_debug:
|
|||||||
|
|
||||||
debug:
|
debug:
|
||||||
|
|
||||||
text_sensor:
|
sensor:
|
||||||
- platform: debug
|
- platform: uptime
|
||||||
device:
|
name: Uptime Sensor
|
||||||
name: "Device Info"
|
update_interval: 5sec
|
||||||
reset_reason:
|
- platform: adc
|
||||||
name: "Reset Reason"
|
pin: VDDHDIV5
|
||||||
|
name: "VDDH Voltage"
|
||||||
|
update_interval: 5sec
|
||||||
|
filters:
|
||||||
|
- multiply: 5
|
||||||
|
- platform: adc
|
||||||
|
pin: VDD
|
||||||
|
name: "VDD Voltage"
|
||||||
|
update_interval: 5sec
|
||||||
|
- platform: adc
|
||||||
|
pin: AIN0
|
||||||
|
name: "AIN0 Voltage"
|
||||||
|
update_interval: 5sec
|
||||||
|
Loading…
x
Reference in New Issue
Block a user