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
|
||||
|
||||
#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
|
||||
|
||||
namespace esphome {
|
||||
@ -95,15 +95,14 @@ extern "C"
|
||||
#endif
|
||||
|
||||
#ifdef USE_ZEPHYR
|
||||
adc_chan_ = &adc_chan;
|
||||
if (!adc_is_ready_dt(adc_chan_)) {
|
||||
ESP_LOGE(TAG, "ADC controller device %s not ready", adc_chan_->dev->name);
|
||||
if (!adc_is_ready_dt(adc_channel_)) {
|
||||
ESP_LOGE(TAG, "ADC controller device %s not ready", adc_channel_->dev->name);
|
||||
return;
|
||||
}
|
||||
|
||||
auto err = adc_channel_setup_dt(adc_chan_);
|
||||
auto err = adc_channel_setup_dt(adc_channel_);
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
@ -158,8 +157,110 @@ void ADCSensor::dump_config() {
|
||||
#endif // USE_RP2040
|
||||
|
||||
#ifdef USE_ZEPHYR
|
||||
ESP_LOGCONFIG(TAG, " Name: %s, channel_id: %d, vref_mv: %d, resolution %d, oversampling %d", adc_chan_->dev->name,
|
||||
adc_chan_->channel_id, adc_chan_->vref_mv, adc_chan_->resolution, adc_chan_->oversampling);
|
||||
ESP_LOGCONFIG(TAG, " Name: %s, channel_id: %d, vref_mv: %d, resolution %d, oversampling %d", adc_channel_->dev->name,
|
||||
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
|
||||
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
@ -331,11 +432,11 @@ float ADCSensor::sample() {
|
||||
};
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -344,7 +445,7 @@ float ADCSensor::sample() {
|
||||
* in the ADC sample buffer should be a signed 2's
|
||||
* complement value.
|
||||
*/
|
||||
if (adc_chan_->channel_cfg.differential) {
|
||||
if (adc_channel_->channel_cfg.differential) {
|
||||
val_mv = (int32_t) ((int16_t) buf);
|
||||
} else {
|
||||
val_mv = (int32_t) buf;
|
||||
@ -354,10 +455,10 @@ float ADCSensor::sample() {
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,8 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
||||
float get_setup_priority() const override;
|
||||
#ifndef USE_ZEPHYR
|
||||
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
|
||||
void set_output_raw(bool output_raw) { output_raw_ = output_raw; }
|
||||
float sample() override;
|
||||
@ -58,7 +60,7 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
||||
#ifndef USE_ZEPHYR
|
||||
InternalGPIOPin *pin_;
|
||||
#else
|
||||
const struct adc_dt_spec *adc_chan_;
|
||||
const struct adc_dt_spec *adc_channel_ = nullptr;
|
||||
#endif
|
||||
bool output_raw_{false};
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
from esphome.cpp_generator import MockObj
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
import esphome.final_validate as fv
|
||||
@ -56,6 +57,10 @@ ADCSensor = adc_ns.class_(
|
||||
"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(
|
||||
sensor.sensor_schema(
|
||||
ADCSensor,
|
||||
@ -71,6 +76,9 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.SplitDefault(CONF_ATTENUATION, esp32="0db"): cv.All(
|
||||
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")),
|
||||
@ -91,48 +99,36 @@ async def to_code(config):
|
||||
cg.add(var.set_is_temperature())
|
||||
elif CORE.using_zephyr:
|
||||
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,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>;
|
||||
#size-cells = <0>;
|
||||
|
||||
channel@0 {
|
||||
reg = <0>;
|
||||
zephyr,gain = "ADC_GAIN_1_6";
|
||||
channel@{channel_id} {{
|
||||
reg = <{channel_id}>;
|
||||
zephyr,gain = "{gain}";
|
||||
zephyr,reference = "ADC_REF_INTERNAL";
|
||||
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
|
||||
zephyr,input-positive = <NRF_SAADC_AIN1>; /* P0.03 */
|
||||
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,input-positive = <NRF_SAADC_{config[CONF_PIN][CONF_NUMBER]}>;
|
||||
zephyr,resolution = <14>;
|
||||
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:
|
||||
|
@ -46,7 +46,7 @@ ADC_INPUTS = [
|
||||
"AIN6",
|
||||
"AIN7",
|
||||
"VDD",
|
||||
"VDDH",
|
||||
"VDDHDIV5",
|
||||
]
|
||||
|
||||
|
||||
|
@ -16,7 +16,7 @@ class BLENUS : public Component {
|
||||
};
|
||||
|
||||
public:
|
||||
BLENUS(size_t buffer_size = 1024);
|
||||
BLENUS(size_t buffer_size = 2048);
|
||||
void setup() override;
|
||||
void dump_config() 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:
|
||||
|
||||
sensor:
|
||||
- platform: uptime
|
||||
name: Uptime Sensor
|
||||
update_interval: 5sec
|
||||
- platform: adc
|
||||
pin: VDDH
|
||||
pin: VDDHDIV5
|
||||
name: "VDDH Voltage"
|
||||
update_interval: 5sec
|
||||
filters:
|
||||
- multiply: 5
|
||||
- platform: adc
|
||||
pin: VDD
|
||||
name: "VDD Voltage"
|
||||
|
@ -45,9 +45,21 @@ zephyr_debug:
|
||||
|
||||
debug:
|
||||
|
||||
text_sensor:
|
||||
- platform: debug
|
||||
device:
|
||||
name: "Device Info"
|
||||
reset_reason:
|
||||
name: "Reset Reason"
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user