HonestQiao 发表于 2024-2-18 17:49

【ST NUCLEO-C031C6开发板测评】I2C获取温湿度传感器SHT30数据

<div class='showpostmsg'><p><strong>一、硬件了解</strong></p>

<p>从手册可以得知,PB8、PB9可以用作I2C1接口:</p>

<p> &nbsp;</p>

<p>对应开发板上,可以用如下位置的接口:</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p><strong>二、SHT30温湿度传感器</strong></p>

<p>我手头有一个标准的最简化的SHT30温湿度传感器,具体如下:</p>

<p> &nbsp;</p>

<p>这个SHT30用3.3V供电,I2C接口通讯。</p>

<p>&nbsp;</p>

<p>连接到开发板:</p>

<p> &nbsp;</p>

<p><strong>三、zephyr配置</strong></p>

<p>在 zephyr中,有一个示例samples/sensor/sht3xd,展示了从sht3xd读取数据,要在STM32C0的开发板上使用,需要做一些配置。</p>

<p>&nbsp;</p>

<p>首先,从zephyr/boards/arm/nucleo_c031c6/nucleo_c031c6.dts中,查看i2c的dts配置:</p>

<pre>
<code class="language-javascript">&amp;i2c1 {
      pinctrl-0 = &lt;&amp;i2c1_scl_pb8 &amp;i2c1_sda_pb9&gt;;
      pinctrl-names = "default";
      status = "okay";
      clock-frequency = &lt;I2C_BITRATE_FAST&gt;;
};</code></pre>

<p>从上述配置,可以看到,i2c使用了pb8、pb9。</p>

<p>另外,配置中定义了i2c通讯速率I2C_BITRATE_FAST,其具体的定义在 zephyr/include/zephyr/dt-bindings/i2c/i2c.h 文件中:</p>

<pre>
<code class="language-json">#define I2C_BITRATE_STANDARD    100000/* 100 Kbit/s */
#define I2C_BITRATE_FAST      400000/* 400 Kbit/s */
#define I2C_BITRATE_FAST_PLUS   1000000 /* 1 Mbit/s */
#define I2C_BITRATE_HIGH      3400000 /* 3.4 Mbit/s */
#define I2C_BITRATE_ULTRA       5000000 /* 5 Mbit/s */</code></pre>

<p>所以,对应的速率为400 Kbits/s。</p>

<p>&nbsp;</p>

<p>另外,还需要编写 zephyr/samples/sensor/sht3xd/boards/nucleo_c031c6.overlay,用于定义sht3xd传感器:</p>

<pre>
<code class="language-cpp">&amp;i2c1 { /* SDA CN5.9=PB9, SCL CN5.10=PB8, ALERT CN5.1=D8=PA9 */
/* &amp;i2c3 { * SDA CN7.36=PC1, SCL CN7.38=PC0, ALERT CN7.34=PB0 */
        sht3xd@44 {
                compatible = "sensirion,sht3xd";
                reg = &lt;0x44&gt;;
        };
};</code></pre>

<p>上述配置中,设置了传感器的具体类型,对应:zephyr/dts/bindings/sensor/sensirion,sht3xd.yaml</p>

<pre>
<code class="language-ini"># Copyright (c) 2018, Peter Bigot Consulting, LLC
# SPDX-License-Identifier: Apache-2.0

description: Sensirion Humidity SHT3x-DIS humidity and temperature sensor

compatible: "sensirion,sht3xd"

include:

properties:
alert-gpios:
    type: phandle-array
    description: |
      ALERT pin.

      This pin signals active high when produced by the sensor.The
      property value should ensure the flags properly describe the
      signal that is presented to the driver.</code></pre>

<p>其对应的驱动位置:./drivers/sensor/sht3xd</p>

<pre>
<code class="language-bash">./drivers/sensor/sht3xd
├── CMakeLists.txt
├── Kconfig
├── sht3xd.c
├── sht3xd.h
└── sht3xd_trigger.c</code></pre>

<p>做完上述配置,就可以编写具体程序了。</p>

<p>&nbsp;</p>

<p><strong>四、代码编写</strong></p>

<p>参考&nbsp;samples/sensor/sht3xd/src/main.c,编写如下的代码:</p>

<pre>
<code class="language-cpp">#include &lt;zephyr/kernel.h&gt;
#include &lt;zephyr/device.h&gt;
#include &lt;zephyr/drivers/sensor.h&gt;
#include &lt;stdio.h&gt;

const struct device *const dev = DEVICE_DT_GET_ONE(sensirion_sht3xd);

int main(void)
{
        int rc;

        if (!device_is_ready(dev)) {
                printf("Device %s is not ready\n", dev-&gt;name);
                return 0;
        }

        while (true) {
                struct sensor_value temp, hum;

                rc = sensor_sample_fetch(dev);
                if (rc == 0) {
                        rc = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP,
                                                &amp;temp);
                }
                if (rc == 0) {
                        rc = sensor_channel_get(dev, SENSOR_CHAN_HUMIDITY,
                                                &amp;hum);
                }
                if (rc != 0) {
                        printf("SHT3XD: failed: %d\n", rc);
                        break;
                }

                printf("SHT3XD: %d.%d=%.2f Cel ; %d.%d=%0.2f %%RH\n",
                                temp.val1,temp.val2,
                     sensor_value_to_double(&amp;temp),
                                hum.val1,hum.val2,
                     sensor_value_to_double(&amp;hum));

                k_sleep(K_MSEC(2000));
        }
        return 0;
}
</code></pre>

<p>在上述代码中,通过别名&nbsp;sensirion_sht3xd 来获得dts配置的设备,然后通过device_is_ready()检查设备是否准备去就绪。</p>

<p>因为前面做了dts配置,所以一旦系统启动,就会自动做好准备,提供服务。</p>

<p>&nbsp;</p>

<p>然后,调用sensor_sample_fetch()进行数据采样,采样后,就可以调用sensor_channel_get()来获取数据了。</p>

<p>在 zephyr/include/zephyr/drivers/sensor.h 中,定义了传感器数据读取的结构,以及对应的数据通道:</p>

<pre>
<code class="language-cpp">struct sensor_value {
      int32_t val1;
      int32_t val2;
};

enum sensor_channel {
      SENSOR_CHAN_ACCEL_X,
      SENSOR_CHAN_ACCEL_Y,
      SENSOR_CHAN_ACCEL_Z,
      SENSOR_CHAN_ACCEL_XYZ,
      SENSOR_CHAN_GYRO_X,
      SENSOR_CHAN_GYRO_Y,
      SENSOR_CHAN_GYRO_Z,
      SENSOR_CHAN_GYRO_XYZ,
      SENSOR_CHAN_MAGN_X,
      SENSOR_CHAN_MAGN_Y,
      SENSOR_CHAN_MAGN_Z,
      SENSOR_CHAN_MAGN_XYZ,
      SENSOR_CHAN_DIE_TEMP,
      SENSOR_CHAN_AMBIENT_TEMP,
      SENSOR_CHAN_PRESS,
      SENSOR_CHAN_PROX,
      SENSOR_CHAN_HUMIDITY,
      SENSOR_CHAN_LIGHT,
      SENSOR_CHAN_IR,
      SENSOR_CHAN_RED,
      SENSOR_CHAN_GREEN,
      SENSOR_CHAN_BLUE,
      SENSOR_CHAN_ALTITUDE,

      SENSOR_CHAN_PM_1_0,
      SENSOR_CHAN_PM_2_5,
      SENSOR_CHAN_PM_10,
      SENSOR_CHAN_DISTANCE,

      SENSOR_CHAN_CO2,
      SENSOR_CHAN_VOC,
      SENSOR_CHAN_GAS_RES,

      SENSOR_CHAN_VOLTAGE,

      SENSOR_CHAN_VSHUNT,

      SENSOR_CHAN_CURRENT,
      SENSOR_CHAN_POWER,

      SENSOR_CHAN_RESISTANCE,

      SENSOR_CHAN_ROTATION,

      SENSOR_CHAN_POS_DX,
      SENSOR_CHAN_POS_DY,
      SENSOR_CHAN_POS_DZ,

      SENSOR_CHAN_RPM,

      SENSOR_CHAN_GAUGE_VOLTAGE,
      SENSOR_CHAN_GAUGE_AVG_CURRENT,
      SENSOR_CHAN_GAUGE_STDBY_CURRENT,
      SENSOR_CHAN_GAUGE_MAX_LOAD_CURRENT,
      SENSOR_CHAN_GAUGE_TEMP,
      SENSOR_CHAN_GAUGE_STATE_OF_CHARGE,
      SENSOR_CHAN_GAUGE_FULL_CHARGE_CAPACITY,
      SENSOR_CHAN_GAUGE_REMAINING_CHARGE_CAPACITY,
      SENSOR_CHAN_GAUGE_NOM_AVAIL_CAPACITY,
      SENSOR_CHAN_GAUGE_FULL_AVAIL_CAPACITY,
      SENSOR_CHAN_GAUGE_AVG_POWER,
      SENSOR_CHAN_GAUGE_STATE_OF_HEALTH,
      SENSOR_CHAN_GAUGE_TIME_TO_EMPTY,
      SENSOR_CHAN_GAUGE_TIME_TO_FULL,
      SENSOR_CHAN_GAUGE_CYCLE_COUNT,
      SENSOR_CHAN_GAUGE_DESIGN_VOLTAGE,
      SENSOR_CHAN_GAUGE_DESIRED_VOLTAGE,
      SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT,

      SENSOR_CHAN_ALL,

      SENSOR_CHAN_COMMON_COUNT,

      SENSOR_CHAN_PRIV_START = SENSOR_CHAN_COMMON_COUNT,

      SENSOR_CHAN_MAX = INT16_MAX,
};</code></pre>

<p>温度对应的通道为&nbsp;SENSOR_CHAN_AMBIENT_TEMP,湿度对应的通道为SENSOR_CHAN_HUMIDITY,所以读取温湿度信息,使用如下代码:</p>

<pre>
<code class="language-cpp">                rc = sensor_sample_fetch(dev);
                if (rc == 0) {
                        rc = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP,
                                                &amp;temp);
                }
                if (rc == 0) {
                        rc = sensor_channel_get(dev, SENSOR_CHAN_HUMIDITY,
                                                &amp;hum);
                }</code></pre>

<p>数据读取成功后,可以调用&nbsp;sensor_value_to_double()将结构化数据转换为double浮点数据。</p>

<p>&nbsp;</p>

<p><strong>五、输出结果</strong></p>

<p>将上述代码编译下载到开发板,运行后,即可输出温湿度信息:</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>用手捏住SHT30的传感器部分,温度就会上升。</p>

<p>对着它哈气,湿度就会上升了。</p>

<p>&nbsp;</p>

<p>&nbsp;</p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

Maker_kun 发表于 2024-2-19 08:53

<p>捏住传感器会不会污染传感器,影响后期传感器检测精度</p><br/>

HonestQiao 发表于 2024-2-19 09:23

Maker_kun 发表于 2024-2-19 08:53
捏住传感器会不会污染传感器,影响后期传感器检测精度

<p>先沐浴焚香净身<img height="52" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/titter.gif" width="48" /></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

LitchiCheng 发表于 2024-2-19 09:33

<p>这个zephyr和linux一样的开发路线了,用起来应该很熟悉</p>
页: [1]
查看完整版本: 【ST NUCLEO-C031C6开发板测评】I2C获取温湿度传感器SHT30数据