基于湿度和温度的 SGP41(原始)测量校正
概述(我如何开始这个项目)
首先我阅读了 Grove - 智能空气质量传感器(SGP41) 和 Grove - AHT20 I2C 工业级温湿度传感器 的文档。
根据 SGP41 数据手册(PDF) 第 3.2 节(原始信号测量),SGP41 测量依赖于湿度和温度,因此我们需要应用校正来获得一致的数据:从 AHT20(或其他传感器)读取相对湿度和温度,计算刻度值并将其传递给 sgp41_measure_raw_signals 函数。
理论测试
第 15 页的表 11(I2C 测量命令描述)描述了计算刻度值的公式:
RHticks = RH% × 65535 / 100
Tticks = (T°C + 45) × 65535 / 175
使用默认值 25°C 和 50% 相对湿度进行验证:
50 × 65535 / 100 = 32767.5 = 0x8000 (十六进制,向上取整)
(25 + 45) × 65535 / 175 = 26214 = 0x6666 (十六进制)
结果与Grove - 智能空气质量传感器 (SGP41)使用的程序中的常量相匹配,并在SGP41数据手册 (PDF)的表11中定义。
在c语言中相同:
int h_ticks = humi * 0xFFFF;
int t_ticks = (temp + 45) * 0xFFFF / 175;
注意程序中的 'humi' 是一个 0 到 1 之间的值,所以移除了除以 100 和之前的乘法运算。
硬件准备
我使用 Seeeduino Nano 作为控制板,并使用 Grove - 智能空气质量传感器 (SGP41) 和 Grove - AHT20 I2C 工业级温湿度传感器来实现这个功能。
Seeeduino Nano | Grove - AHT20 温湿度传感器 | Grove - 智能空气质量传感器 (SGP41) | Grove - 分支线缆 |
---|---|---|---|
![]() | ![]() | ![]() | ![]() |
软件准备
Arduino IDE |
---|
需要多个库文件,将在下一步中介绍。
开始使用
如果这是您第一次使用 Arduino,我们强烈建议您在开始之前先查看Arduino 入门指南。
1. 连接 Arduino Nano
请轻柔地插入 USB 线缆,否则可能会损坏端口。请使用内部有 4 根线的 USB 线缆,2 根线的线缆无法传输数据。如果您不确定手头的线缆规格,可以点击这里购买
-
步骤 1. 将 Grove 分支线缆连接到 Seeeduino Nano 的 I2C 端口。
-
步骤 2. 将 Grove 分支线缆插入 I2C Grove AHT20 传感器模块。
-
步骤 3. 将 Grove 分支线缆插入 I2C Grove SGP41 传感器模块。
-
步骤 4. 通过 USB 线缆将 Seeeduino 连接到 PC。
2. 下载所需库文件并添加到 Arduino
-
步骤 1. 从 Github 下载依赖库。
- arduino-core 库:
- arduino-i2c-sgp41 库:
- Seeed_Arduino_AHT20 库:
-
步骤 2. 参考如何安装库文件为 Arduino 安装库文件。
-
步骤 3. 正确下载并安装库文件后,您可以上传下面的代码,这是 SGP41 和 AHT20 软件的组合,并添加了介绍中描述的公式。
3. 上传代码并检查结果
- 步骤 1. 上传演示代码。如果您不知道如何上传代码,请查看如何上传代码。
// GROVE-AHT20+SGP41 的 ARDUINO 演示程序
//
#include <Wire.h>
#include "AHT20.h"
#include <Arduino.h>
#include <SensirionI2CSgp41.h>
SensirionI2CSgp41 sgp41;
// NOx 调节所需的时间(秒)
uint16_t conditioning_s = 10;
AHT20 AHT;
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(100);
}
Wire.begin();
uint16_t error;
char errorMessage[256];
sgp41.begin(Wire);
uint16_t serialNumber[3];
uint8_t serialNumberSize = 3;
error = sgp41.getSerialNumber(serialNumber, serialNumberSize);
if (error) {
Serial.print("尝试执行 getSerialNumber() 时出错: ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
} else {
Serial.print("序列号:");
Serial.print("0x");
for (size_t i = 0; i < serialNumberSize; i++) {
uint16_t value = serialNumber[i];
Serial.print(value < 4096 ? "0" : "");
Serial.print(value < 256 ? "0" : "");
Serial.print(value < 16 ? "0" : "");
Serial.print(value, HEX);
}
Serial.println();
}
uint16_t testResult;
error = sgp41.executeSelfTest(testResult);
if (error) {
Serial.print("尝试执行 executeSelfTest() 时出错: ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
} else if (testResult != 0xD400) {
Serial.print("executeSelfTest 失败,错误代码: ");
Serial.println(testResult);
}
AHT.begin();
}
uint16_t read_sgp41(uint16_t rh, uint16_t t) {
uint16_t error;
char errorMessage[256];
uint16_t srawVoc = 0;
uint16_t srawNox = 0;
delay(1000);
if (conditioning_s > 0) {
// 在 NOx 调节期间(10秒)SRAW NOx 将保持为 0
error = sgp41.executeConditioning(rh, t, srawVoc);
conditioning_s--;
} else {
// 读取测量值
error = sgp41.measureRawSignals(rh, t, srawVoc, srawNox);
}
if (error) {
Serial.print("尝试执行 measureRawSignals() 时出错: ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
} else {
Serial.print("RH ticks: ");
Serial.print(rh);
Serial.print("\t");
Serial.print("T ticks: ");
Serial.print(t);
Serial.print("\t");
Serial.print("SRAW_VOC: ");
Serial.print(srawVoc);
Serial.print("\t");
Serial.print("SRAW_NOx: ");
Serial.println(srawNox);
}
return error;
}
void loop()
{
float humi, temp;
int ret = AHT.getSensor(&humi, &temp);
if(ret) // 获取数据成功
{
Serial.print("湿度: ");
Serial.print(humi*100);
Serial.print("%\t 温度: ");
Serial.print(temp);
Serial.print("\t");
// T-ticks = (T/°C + 45) × 65535 / 175
// H-ticks = RH/% × 65535 / 100
int h_ticks = humi * 0xFFFF;
int t_ticks = (temp + 45) * 0xFFFF / 175;
read_sgp41(h_ticks, t_ticks);
}
else // 获取数据失败
{
Serial.println("从 AHT20 获取数据失败");
}
delay(100);
}
// 文件结束
- 步骤 2. 点击 工具-> 串口监视器 打开 Arduino IDE 的串口监视器。
请注意,由于调节过程,前十个 SRAW_NOx 值为零。
资源
✨ 贡献者项目
技术支持与产品讨论
感谢您选择我们的产品!我们在这里为您提供不同的支持,以确保您使用我们产品的体验尽可能顺畅。我们提供多种沟通渠道,以满足不同的偏好和需求。