【2024 DigiKey创意大赛】基于Raspberry 5工业传感网关系统的设计-各项传感器数据采集
本帖最后由 JectXie 于 2024-10-21 23:03 编辑<p>本项目用到的各项传感器,<br />
1、FST红外温度传感器(主要用于无法安装接触式传感器测温场景)</p>
<p> </p>
<p>1.2 这是一个工业级Modbus红外测温传感器。下面是ESP32 驱动串口、写入接收Modbus数据,拿到温度数据的代码</p>
<pre>
<code class="language-cpp">#include <SoftwareSerial.h>
// 使用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 << 9) & 0xFFFFFFFF; // 将尾数左移以进行转换
// 将尾数的二进制转换为十进制小数
while (num > 0) {
result += ((num & 0x80000000) >> 31) * pow(0.5, countt);
countt++;
num = num << 1;
if (countt > 23) {
break; // 超过23位时退出
}
}
return result;
}
// 将IEEE 754格式的数据转换为十进制浮点数
float IEEE754_to_decimal(uint32_t source) {
uint8_t sign = (uint8_t)((source & 0x80000000) >> 31);// 符号位:第31位
uint8_t index = (uint8_t)((source & 0x7F800000) >> 23); // 指数部分:第23-30位
uint32_t mantissa = (source & 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 < 9; i++) {
data = mod.read();
Serial.print(data, HEX);
if (i < 8) Serial.print("/");
}
Serial.println();
// 检查返回的数据是否符合预期格式
if (data == 3 && data == 4) {
int val = 0;
char *pBuf = (char *)&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> </p>
<p> </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 下面是ESP32 读取SGP30监测到的有机化合物 (TVOC) 和二氧化碳当量 (CO₂eq) 浓度,氢气、乙醇的代码</p>
<pre>
<code class="language-cpp">#include <Wire.h>
#include <Adafruit_SGP30.h>
// SGP30 引脚连接到 ESP32:
// SGP30 VCC -> ESP32 3.3V
// SGP30 GND -> ESP32 GND
// SGP30 SDA -> ESP32 GPIO 21(或其他 SDA 引脚)
// SGP30 SCL -> 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> </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 <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME680.h>
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> </p>
<p>4、SHT40 这是一款高精度的温湿度传感器,可以读取温度和湿度。I2C协议,</p>
<p> </p>
<p>这是SHT30的升级款,代码也有改动。下面是示例代码</p>
<pre>
<code class="language-cpp">#include <Wire.h>
#include <Adafruit_SHT4x.h>
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(&humidity, &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> </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> </p>
<p>到这里,完成了ESP32 采集数据部分的功能。</p>
<p> </p>
<p>后续请看下一集,ESP32通过网络将数据传输到工业传感器网关</p>
<p>工业级的红外测温传感器,看着很高端啊 </p>
页:
[1]