JectXie 发表于 2024-10-21 21:41

【2024 DigiKey创意大赛】基于Raspberry 5工业传感网关系统的设计-各项传感器数据采集

本帖最后由 JectXie 于 2024-10-21 23:03 编辑

<p>本项目用到的各项传感器,<br />
1、FST红外温度传感器(主要用于无法安装接触式传感器测温场景)</p>

<p> &nbsp;</p>

<p>1.2&nbsp;这是一个工业级Modbus红外测温传感器。下面是ESP32 驱动串口、写入接收Modbus数据,拿到温度数据的代码</p>

<pre>
<code class="language-cpp">#include &lt;SoftwareSerial.h&gt;

// 使用SoftwareSerial定义Modbus的RX和TX引脚
SoftwareSerial mod(16, 17); // RX = 16, TX = 17

// 读取FST传感器的Modbus命令
const uint8_t ModFstReadBuffer[] = {0x7B, 0x03, 0x00, 0x00, 0x00, 0x02, 0xCF, 0x91};

// 将尾数部分转换为小数
float tow_to_ten(uint32_t dat) {
    float result = 0.0;
    uint8_t countt = 1;
    uint32_t num = (dat &lt;&lt; 9) &amp; 0xFFFFFFFF; // 将尾数左移以进行转换

    // 将尾数的二进制转换为十进制小数
    while (num &gt; 0) {
      result += ((num &amp; 0x80000000) &gt;&gt; 31) * pow(0.5, countt);
      countt++;
      num = num &lt;&lt; 1;
      if (countt &gt; 23) {
            break; // 超过23位时退出
      }
    }
    return result;
}

// 将IEEE 754格式的数据转换为十进制浮点数
float IEEE754_to_decimal(uint32_t source) {
    uint8_t sign = (uint8_t)((source &amp; 0x80000000) &gt;&gt; 31);// 符号位:第31位
    uint8_t index = (uint8_t)((source &amp; 0x7F800000) &gt;&gt; 23); // 指数部分:第23-30位
    uint32_t mantissa = (source &amp; 0x007FFFFF);            // 尾数部分:第0-22位
    float decimal = tow_to_ten(mantissa);                   // 将尾数转换为小数

    // 根据IEEE 754公式计算十进制浮点数
    return pow(-1, sign) * (1 + decimal) * pow(2, (index - 127));
}

// 获取FST传感器的温度数据
void GetfstSenesorData() {
    float fstTemperature, FstTemperatureFahrenheit;

    Serial.println("state=2常规工作模式-------------菲尔斯特探头工作模式");
    unsigned int data; // 用于存储读取到的响应数据
    delay(10); // 等待传感器响应

    // 写入Modbus命令并检查是否成功发送了8个字节
    if (mod.write(ModFstReadBuffer, sizeof(ModFstReadBuffer)) == 8) {
      Serial.println("写入串口数据成功");
      Serial.println("----------1----------↓");

      // 读取传感器的Modbus响应数据
      for (int i = 0; i &lt; 9; i++) {
            data = mod.read();
            Serial.print(data, HEX);
            if (i &lt; 8) Serial.print("/");
      }
      Serial.println();

      // 检查返回的数据是否符合预期格式
      if (data == 3 &amp;&amp; data == 4) {
            int val = 0;
            char *pBuf = (char *)&amp;val;

            // 将四个字节的数据组合成一个32位的整数
            pBuf = data;
            pBuf = data;
            pBuf = data;
            pBuf = data;

            Serial.print("读取的原始整数值:");
            Serial.println(val);

            // 将读取到的数据转换为实际的温度值
            fstTemperature = IEEE754_to_decimal(val);
            FstTemperatureFahrenheit = (fstTemperature * 1.8) + 32.0f;

            // 输出温度值
            Serial.print("温度 (摄氏度): ");
            Serial.println(fstTemperature);
            Serial.print("温度 (华氏度): ");
            Serial.println(FstTemperatureFahrenheit);
      } else {
            Serial.println("接收到的Modbus响应数据无效。");
      }

      Serial.println("↑-----------1----------↑");
    } else {
      Serial.println("写入串口数据失败。");
    }
}

void setup() {
    // 初始化串口和Modbus通信
    Serial.begin(115200);
    mod.begin(9600);
}

void loop() {
    // 每2秒获取一次FST传感器数据
    GetfstSenesorData();
    delay(2000);
}
</code></pre>

<p>这一部分需要有一个TTL-RS485的芯片,附一个原理图供参考</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>2、SGP30 传感器<strong>(这是我的必选物料之一)</strong></p>

<p>SGP30 是一款多功能气体传感器,用于测量空气中的总挥发性有机化合物 (TVOC) 和二氧化碳当量 (CO₂eq) 浓度。SGP30 使用MEMS技术和气体传感技术。</p>

<p><img src="https://www.eeworld.com.cn/huodong/digikey_contest_2024/image/3709.png" /></p>

<p>2.2&nbsp; 下面是ESP32 读取SGP30监测到的有机化合物 (TVOC) 和二氧化碳当量 (CO₂eq) 浓度,氢气、乙醇的代码</p>

<pre>
<code class="language-cpp">#include &lt;Wire.h&gt;
#include &lt;Adafruit_SGP30.h&gt;

// SGP30 引脚连接到 ESP32:
// SGP30 VCC -&gt; ESP32 3.3V
// SGP30 GND -&gt; ESP32 GND
// SGP30 SDA -&gt; ESP32 GPIO 21(或其他 SDA 引脚)
// SGP30 SCL -&gt; ESP32 GPIO 22(或其他 SCL 引脚)

Adafruit_SGP30 sgp;

void setup() {
Serial.begin(115200);

// 初始化 SGP30
if (!sgp.begin()) {
    Serial.println("Failed to find SGP30 chip");
    while (1) {
      delay(10); // 避免无限循环时占用过多CPU
    }
}

// 初始化 IAQ(Indoor Air Quality)
sgp.IAQinit();
}

void loop() {
// 读取 eCO₂ 和 TVOC 数据
if (sgp.IAQmeasure()) {
    Serial.print("eCO2 = ");
    Serial.print(sgp.eCO2);
    Serial.println(" ppm");

    Serial.print("TVOC = ");
    Serial.print(sgp.TVOC);
    Serial.println(" ppb");

    Serial.print("Raw H2: ");
    Serial.print(sgp.rawH2);
    Serial.print("   Raw Ethanol: ");
    Serial.println(sgp.rawEthanol);

    Serial.println("-----------------");
} else {
    Serial.println("Measurement failed");
}

delay(3000); // 每3秒读取一次数据
}
</code></pre>

<p>&nbsp;</p>

<p>3、BME680模组 (这是我的第二个必选模组)</p>

<p><img src="https://www.eeworld.com.cn/huodong/digikey_contest_2024/image/3660.png" /></p>

<p>BME680 是一款由 Bosch Sensortec 生产的多合一环境传感器,可以测量<strong>温度、湿度、气压、气体</strong></p>

<p><strong>下面是ESP32 读取这些参数的代码</strong></p>

<pre>
<code class="language-cpp">#include &lt;Wire.h&gt;
#include &lt;Adafruit_Sensor.h&gt;
#include &lt;Adafruit_BME680.h&gt;

Adafruit_BME680 bme; // I2C

void setup() {
Serial.begin(115200);
if (!bme.begin(0x77)) {// 根据你的模块地址设置
    Serial.println("BME680 not found");
    while (1);
}
}

void loop() {
if (bme.performReading()) {
    Serial.print("Temperature = ");
    Serial.print(bme.temperature);
    Serial.println(" *C");
   
    Serial.print("Humidity = ");
    Serial.print(bme.humidity);
    Serial.println(" %");
   
    Serial.print("Pressure = ");
    Serial.print(bme.pressure / 100.0);
    Serial.println(" hPa");
   
    Serial.print("Gas Resistance = ");
    Serial.print(bme.gas_resistance);
    Serial.println(" ohms");
} else {
    Serial.println("Failed to perform reading");
}

delay(3000); // 每3秒读取一次数据
}
</code></pre>

<p>&nbsp;</p>

<p>4、SHT40 这是一款高精度的温湿度传感器,可以读取温度和湿度。I2C协议,</p>

<p> &nbsp;</p>

<p>这是SHT30的升级款,代码也有改动。下面是示例代码</p>

<pre>
<code class="language-cpp">#include &lt;Wire.h&gt;
#include &lt;Adafruit_SHT4x.h&gt;

Adafruit_SHT4x sht4x;

void setup() {
Serial.begin(115200);

// 初始化 SHT40
if (!sht4x.begin()) {
    Serial.println("SHT40 not found");
    while (1) delay(10);
}

// 可以设置传感器精度
sht4x.setPrecision(SHT4X_HIGH_PRECISION);
}

void loop() {
sensors_event_t humidity, temperature;

// 读取温湿度数据
if (sht4x.getEvent(&amp;humidity, &amp;temperature)) {
    Serial.print("Temperature: ");
    Serial.print(temperature.temperature);
    Serial.println(" °C");

    Serial.print("Humidity: ");
    Serial.print(humidity.relative_humidity);
    Serial.println(" %");
} else {
    Serial.println("Failed to read data from SHT40");
}

delay(2000); // 每2秒读取一次数据
}
</code></pre>

<p>5、LTR329 这是一个光传感器,可以测量可见光和红外光。在项目中用于监测车间内光照强度是否达标。对员工视力是否影响。</p>

<p> &nbsp;</p>

<p>下面是ESP32 读取LTR-329的代码</p>

<pre>
<code class="language-cpp">#include "Adafruit_LTR329_LTR303.h"

Adafruit_LTR329 ltr = Adafruit_LTR329();

void setup() {
Serial.begin(115200);
Serial.println("Adafruit LTR-329 light sensor test");

if (!ltr.begin()) {
Serial.println("Couldn't find LTR sensor!");
while (1) delay(10);
}
Serial.println("Found LTR sensor!");

// 设置默认增益、积分时间和测量速率
ltr.setGain(LTR3XX_GAIN_2); // 默认增益
ltr.setIntegrationTime(LTR3XX_INTEGTIME_100); // 默认积分时间
ltr.setMeasurementRate(LTR3XX_MEASRATE_200); // 默认测量速率
}

void loop() {
if (ltr.newDataAvailable()) {
uint16_t visible_plus_ir, infrared;
bool valid = ltr.readBothChannels(visible_plus_ir, infrared);
if (valid) {
Serial.print("CH0 Visible + IR: ");//可见光
Serial.print(visible_plus_ir);
Serial.print("\t\tCH1 Infrared: ");//红外光
Serial.println(infrared);
}
}

delay(2000); // 延时以避免数据更新过于频繁
}
</code></pre>

<p>&nbsp;</p>

<p>到这里,完成了ESP32 采集数据部分的功能。</p>

<p>&nbsp;</p>

<p>后续请看下一集,ESP32通过网络将数据传输到工业传感器网关</p>

秦天qintian0303 发表于 2024-10-22 09:08

<p>工业级的红外测温传感器,看着很高端啊&nbsp;</p>
页: [1]
查看完整版本: 【2024 DigiKey创意大赛】基于Raspberry 5工业传感网关系统的设计-各项传感器数据采集