这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【e起DIY】低功耗蓝牙温湿度计-过程篇

共1条 1/1 1 跳转至

【e起DIY】低功耗蓝牙温湿度计-过程篇

工程师
2026-06-11 19:12:41     打赏

【e起DIY】低功耗蓝牙温湿度计-过程篇

板卡实物图

9a12532c-e5ea-45a0-87fe-78faa68bd061.jpg

接下来接到了重头戏部分

    SHT30 传感器驱动开发
• 完成 NXP FRDM-MCXW71 开发板与 SHT30 传感器的 I2C 物理连接
• 实现温度与湿度数据读取函数, 在串口终端打印原始数据与解析后的温湿度值,格式为:Temperature: 23.5°C, Humidity: 45.2%RH

上述任务说明写的是通过I2C总线连接SHT30传感器模块

可通过活动详情页https://www.eepw.com.cn/event/action/element14_diy/index.html#flow1

点击之后看到的是模拟接口的SHT30

https://www.element14.cn/dfrobot/dfr0588/sensor-module-temperature-humidity/dp/3974111

当时没注意,已经下单到手了,本着既来之则安之的心态,一样可以启动起来

结合ai工具,告诉ai,我们想通过frdm-mcxw71连接模拟输出的sht30并运行zephyr操作系统

可根据ai指导完成工程配置

首先是硬件连接

DFR0588 引脚FRDM-MCXW71(J2 Arduino)说明




VCC3.3V模块供电,严禁 5V
GNDGND共地
TEMPA0(PTB0/ADC0_CH0)温度模拟电压输出→ADC0 通道 0
HUMA1(PTB1/ADC0_CH1)湿度模拟电压输出→ADC0 通道 1
DFR0588 电压换算规则(官方 Gravity 模拟 SHT30):
  • 温度:Vtemp ∈ 0~3.3V → T = -40 + (165 × Vtemp / 3.3) ℃(-40~+125℃线性)

  • 湿度:Vhum ∈ 0~3.3V → RH = 0 + (100 × Vhum / 3.3) % RH(0~100% RH 线性)

实物接线图

mcxw71-temp.jpg

接下来上设备树

/*
 * Copyright 2024 NXP
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/dt-bindings/adc/adc.h>
#include <zephyr/dt-bindings/adc/mcux-lpadc.h>

/ {
	zephyr,user {
		io-channels = <&adc0 0>, <&adc0 1>;
	};
};

&adc0 {
	#address-cells = <1>;
	#size-cells = <0>;

	/* voltage-ref = <0> 表示使用 Alt1,即 VREFH/3.3V(而非默认 1.8V) */  
    voltage-ref = <0>;  
    /* 告诉驱动 VREFH=3300mV,用于计算实际电压值 */  
    nxp,references = <&vref 3300>;  

	channel@0 {
		reg = <0>;
		zephyr,gain = "ADC_GAIN_1";
		zephyr,reference = "ADC_REF_EXTERNAL0";
		zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
		zephyr,resolution = <12>;
		zephyr,vref-mv = <3300>;

		/* channel 0 ptd1 adc0_b5 MCUX_LPADC_CH1B */
		zephyr,input-positive = <MCUX_LPADC_CH1B>;
	};

	channel@1 {
		reg = <1>;
		zephyr,gain = "ADC_GAIN_1";
		zephyr,reference = "ADC_REF_EXTERNAL0";
		zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
		zephyr,resolution = <12>;
		zephyr,vref-mv = <3300>;

        /* channel 1 ptd2 adc0_a6 MCUX_LPADC_CH2A */
		zephyr,input-positive = <MCUX_LPADC_CH2A>;
	};
};

程序代码

/*
 * Copyright (c) 2020 Libre Solar Technologies GmbH
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>

#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/util.h>

#if !DT_NODE_EXISTS(DT_PATH(zephyr_user)) || \
    !DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels)
#error "No suitable devicetree overlay specified"
#endif

#define DT_SPEC_AND_COMMA_FOR_INPUTS(node_id, prop, idx) \
    COND_CODE_1(DT_PHA_HAS_CELL_AT_IDX(node_id, prop, idx, input), \
            (ADC_DT_SPEC_GET_BY_IDX(node_id, idx),), ())

/* Data of ADC io-channels specified in devicetree. */
static const struct adc_dt_spec adc_channels[] = {
    DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), io_channels,
                 DT_SPEC_AND_COMMA_FOR_INPUTS)
};

float get_temp_by_volatge(uint32_t value)
{
    float tempValue = 0.0;

    tempValue = -66.875f + 72.917f * ((float)value / 1000.0f);

    return tempValue;
}

float get_humi_by_volatge(uint32_t value)
{
    float humiValue = 0.0;

    humiValue = -12.5f  + 41.667f * ((float)value / 1000.0f);

    return humiValue;
}

int main(void)
{
    int err;
    uint32_t count = 0;
    uint32_t buf = 0;
    struct adc_sequence sequence = {
        .buffer = &buf,
        /* buffer size in bytes, not number of samples */
        .buffer_size = sizeof(buf),
#if CONFIG_SAMPLE_ADC_CALIBRATE_REQUIRED
        .calibrate = true,
#endif
    };

    float temp, humi;

    /* Configure channels individually prior to sampling. */
    for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
        if (!adc_is_ready_dt(&adc_channels[i])) {
            printk("ADC controller device %s not ready\n", adc_channels[i].dev->name);
            return 0;
        }

        err = adc_channel_setup_dt(&adc_channels[i]);
        if (err < 0) {
            printk("Could not setup channel #%d (%d)\n", i, err);
            return 0;
        }
    }

#ifndef CONFIG_COVERAGE
    while (1) {
#else
    for (int k = 0; k < 10; k++) {
#endif
        printk("ADC reading[%u]:\n", count++);
        for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
            int32_t val_mv;

            /*
             * Clear buffer before reading.  This ensures the upper 16-bits will be zero
             * when the adc uses a 16-bit buffer size.
             */
            buf = 0;

            printk("- %s, channel %d: ",
                   adc_channels[i].dev->name,
                   adc_channels[i].channel_id);

            (void)adc_sequence_init_dt(&adc_channels[i], &sequence);

            err = adc_read_dt(&adc_channels[i], &sequence);
            if (err < 0) {
                printk("Could not read (%d)\n", err);
                continue;
            }

            /*
             * If using differential mode, the 16 bit value
             * in the ADC sample buffer should be a signed 2's
             * complement value.
             */
            if (adc_channels[i].channel_cfg.differential) {
                val_mv = (int32_t)((int16_t)buf);
            } else {
                val_mv = (int32_t)buf;
            }
            printk("%"PRId32, val_mv);
            err = adc_raw_to_millivolts_dt(&adc_channels[i],
                               &val_mv);
            /* conversion to mV may not be supported, skip if not */
            if (err < 0) {
                printk(" (value in mV not available)\n");
            } else {
                printk(" = %"PRId32" mV\n", val_mv);
            }

            if (i)
            {
                humi = get_humi_by_volatge(val_mv);

                printk("--- humi == %f % ---\n", (double)humi);
            }
            else
            {
                temp = get_temp_by_volatge(val_mv);

                printk("--- temp == %f °C ---\n", (double)temp);
            }
        }

        k_sleep(K_MSEC(3000));
    }
    return 0;
}

prj.conf

CONFIG_ADC=y
CONFIG_REQUIRES_FLOAT_PRINTF=y
CONFIG_CBPRINTF_FP_SUPPORT=y

这样之后直接编译就行

企业微信截图_17811761162616.png

接下来烧录程序

企业微信截图_17811761646263.png

串口输出样式

企业微信截图_1781176204453.png

到这里,过程贴就算完成了


过程中有参考课程老师的帖子

https://forum.eepw.com.cn/thread/399659/1


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]