这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 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生态的传感器就非常方便连接了. 比如说同样来自SipeedSGP30, 空气质量传感器和光照传感器.

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接地. SCLSDA连接开发板的SCLSDA即可.



image.png

推荐的应用电路

 


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


image.png


测量命令图


 

image.png

I2C命令和通讯时序

 

我们可以着重关注 init的命令和触发测量measure_iaq的命令. 由于采用的i2C通讯, 所以在传输命令时需要分MSBLSB进行两次发送. 如果发送的是测量命令measure_iaq 那么, 它将会返回6个字节. 由于是TVOCCo2的数据, 所有带上CRC校验数据, 一共是6个字节. 顺序为CO₂eq2Bytes + CRC + TVOC2Bbytes + 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 跳转至

回复

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