这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » [物联网系列][Aduino]使用Wioterminal读取SGP30空气质量传

共1条 1/1 1 跳转至页

[物联网系列][Aduino]使用Wioterminal读取SGP30空气质量传感器

高工
2025-05-20 15:04:40     打赏

简介

Sipeed有很多有趣且高质量的传感器, 其所有的传感器都是采用的Grove 接口. 随着Grove生态的发展, 现在很多不同公司的开发板都开始支持Grove接口. 比如说瑞萨的RA6M5开发板. 更或者是Sipeed的官方开发板. 比如说WIO terminal 同样集成了两个Grove接口.



image.png

上图为瑞萨RA6M5开发板

 

image.png

Wio terminal 背面

 

image.png

Wio terminal 的Grove接口


所以对Grove生态的传感器就非常方便连接了. 比如说同样来自Sipeed的SGP30, 空气质量传感器和光照传感器.

image.png



SGP30简介


SGP30是瑞士Sensirion公司推出的一款微型智能气体传感器,采用I2C数字接口,工作电压仅需1.8V。它能精准检测室内空气中的TVOC(总挥发性有机物)和CO₂等效浓度,主要被应用在了和空气净化器、新风系统等产品中来实现真正感知环境质量。这款传感器集高灵敏度、低功耗和小尺寸于一身,无需复杂校准即可输出可靠数据.


image.png

上图为Sipeed的SGP30传感器


image.png

Gas Sensing Performance

 


image.png

空气信号质量规格表


对应的PINOUT也比较简单, 唯一需要注意的就是这个传感器的驱动电压只有1.8V, 不能将这个传感器直接接到3.3v上的, 如果需要使用这个传感器, 那么在设计中最好需要包含一个降压电路.


image.png


VDDH可以直接和VDD连接在一起, VSS 和 R接地. SCL和SDA连接开发板的SCL和SDA即可.



image.png

推荐的应用电路

 


驱动测量的步骤也比较简单, 首先初始化SGP30传感器, 然后选择是否要校准绝对湿度、 和是否校准baseline. 之后便可以发送测量命令给SGP30, 等待一秒后将会返还测量的结果.


image.png


测量命令图


 

image.png

I2C命令和通讯时序

 

我们可以着重关注 init的命令和触发测量measure_iaq的命令. 由于采用的i2C通讯, 所以在传输命令时需要分MSB和LSB进行两次发送. 如果发送的是测量命令measure_iaq 那么, 它将会返回6个字节. 由于是TVOC和Co2的数据, 所有带上CRC校验数据, 一共是6个字节. 顺序为CO₂eq(2Bytes + CRC) + TVOC(2Bbytes + CRC)

 

对于传感器的驱动, 官方也提供了详细的驱动库.  其驱动库是C语言编写的, 因此非常容易进行移植.


image.png


如果使用的是Wio terminal进行驱动的话(Arduino环境), 将会变的更加简单.

 

1-      首先在库管理器中搜索sgp30 并且下载

2-      固定的初始化代码对传感器进行初始化

void initSGP30() {
    s16 err;
    u16 scaled_ethanol_signal, scaled_h2_signal;

    /* Init SGP30 module */
    while (sgp_probe() != STATUS_OK) {
        Serial.println("SGP failed");
        tft.drawString("SGP30 Init Failed!", 10, TITLE_Y);
        delay(1000);
    }
    
    /* Read H2 and Ethanol signal */
    err = sgp_measure_signals_blocking_read(&scaled_ethanol_signal, &scaled_h2_signal);
    if (err == STATUS_OK) {
        Serial.println("get ram signal!");
    } else {
        Serial.println("error reading signals");
    }
    
    err = sgp_iaq_init();
}


3- 测量和读取

// 读取空气质量数据
        s16 err;
        u16 tvoc_ppb, co2_eq_ppm;
        err = sgp_measure_iaq_blocking_read(&tvoc_ppb, &co2_eq_ppm);
        
        if (err != STATUS_OK) {
            Serial.println("error reading IAQ values");
            return;
        }


简单的画了一个界面使其可以将空气的数据显示在屏幕上. 

#include <Arduino.h>
#include "TFT_eSPI.h"
#include "Free_Fonts.h"
#include "sensirion_common.h"
#include "sgp30.h"

TFT_eSPI tft;

// 定义颜色
#define BACKGROUND_COLOR TFT_BLACK
#define TITLE_COLOR TFT_CYAN
#define VALUE_COLOR TFT_GREEN
#define UNIT_COLOR TFT_YELLOW
#define BORDER_COLOR TFT_NAVY

// 定义UI布局
#define TITLE_Y 10
#define TVOC_Y 100
#define CO2_Y 150
#define VALUE_X 160
#define UNIT_X 220
#define DIVIDER_HEIGHT 3

void initSGP30() {
    s16 err;
    u16 scaled_ethanol_signal, scaled_h2_signal;

    while (sgp_probe() != STATUS_OK) {
        Serial.println("SGP failed");
        tft.drawString("SGP30 Init Failed!", 10, TITLE_Y);
        delay(1000);
    }

    err = sgp_measure_signals_blocking_read(&scaled_ethanol_signal, &scaled_h2_signal);
    if (err == STATUS_OK) {
        Serial.println("get ram signal!");
    } else {
        Serial.println("error reading signals");
    }

    err = sgp_iaq_init();
}

void drawUI() {
    tft.fillScreen(BACKGROUND_COLOR);

    // 绘制标题
    tft.setTextColor(TITLE_COLOR, BACKGROUND_COLOR);
    tft.setFreeFont(FSB12);
    tft.drawString("Air Quality Monitor", 10, TITLE_Y);

    // 绘制分隔线
    tft.fillRect(0, 40, tft.width(), DIVIDER_HEIGHT, BORDER_COLOR);

    // 绘制TVOC标签
    tft.setFreeFont(FSB9);
    tft.setTextColor(TITLE_COLOR, BACKGROUND_COLOR);
    tft.drawString("TVOC:", 10, TVOC_Y);

    // 绘制CO2标签
    tft.drawString("CO2:", 10, CO2_Y);

    // 绘制单位
    tft.setTextColor(UNIT_COLOR, BACKGROUND_COLOR);
    tft.setFreeFont(FS9);
    tft.drawString("ppb", UNIT_X, TVOC_Y);
    tft.drawString("ppm", UNIT_X, CO2_Y);
}

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

    tft.begin();
    tft.setRotation(3);
    drawUI();
    initSGP30();
}

void loop() {
    static uint32_t lastUpdate = 0;
    static u16 last_tvoc = 0, last_co2 = 0;

    if (millis() - lastUpdate >= 500) {
        lastUpdate = millis();

        s16 err;
        u16 tvoc_ppb, co2_eq_ppm;
        err = sgp_measure_iaq_blocking_read(&tvoc_ppb, &co2_eq_ppm);

        if (err != STATUS_OK) {
            Serial.println("error reading IAQ values");
            return;
        }

        if (tvoc_ppb != last_tvoc) {
            tft.setTextColor(VALUE_COLOR, BACKGROUND_COLOR);
            tft.setFreeFont(FSB9);
            tft.drawNumber(tvoc_ppb, VALUE_X, TVOC_Y);
            last_tvoc = tvoc_ppb;
        }

        if (co2_eq_ppm != last_co2) {
            tft.setTextColor(VALUE_COLOR, BACKGROUND_COLOR);
            tft.setFreeFont(FSB9);
            tft.drawNumber(co2_eq_ppm, VALUE_X, CO2_Y);
            last_co2 = co2_eq_ppm;
        }

        Serial.print("TVOC: ");
        Serial.print(tvoc_ppb);
        Serial.print("ppb | CO2eq: ");
        Serial.print(co2_eq_ppm);
        Serial.println("ppm");
    }

    delay(100);
}



实验效果

image.png

附件

SGP30.zip

Sensirion_Gas_Sensors_Datasheet_SGP30.pdf




关键词: SGP32     Grove     wio termina    

共1条 1/1 1 跳转至页

回复

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