确认模块型号
SGP30 应扫到 0x58。若是 SGP40/SGP41,地址和输出逻辑不同,不要混用代码。
Important Specs
这里把“芯片本体”和“模块板”分开写,避免客户直接按裸芯片参数或 5V 模块参数误判。
| 项目 | 说明 | 排查意义 |
|---|---|---|
| 通信接口 | I2C | 不是 UART、SPI,也不是模拟输出 |
| 7 位地址 | 0x58 | Arduino / ESP32 / MicroPython 通常直接用 0x58 |
| STM32 HAL 写地址 | 0x58 << 1 = 0xB0 | 逻辑分析仪看到 0xB0 通常是对的 |
| STM32 HAL 读地址 | (0x58 << 1) | 1 = 0xB1 | 这是 7 位地址左移后的读方向 |
| I2C 速度 | 最高 400 kHz;排查先用 100 kHz | 长线、杜邦线、上拉弱时先降速 |
| 芯片本体供电 | SGP30 芯片本体不是 5V 芯片 | 不要把裸芯片当 5V 传感器接 |
| 模块供电 | 以 U54 模块板说明和实物为准 | 模块可能带稳压/电平转换/上拉电阻 |
Wiring
常见模块只需要 VCC、GND、SDA、SCL 四根线。5V 主控能不能直接接,要以当前模块是否带稳压和电平转换为准。
| SGP30 模块 | Arduino UNO / Nano | ESP32 常用接法 | 说明 |
|---|---|---|---|
| VCC / VIN | 5V 或 3.3V | 3.3V 优先 | 以 U54 模块说明为准;裸芯片板不要直接按 5V 处理 |
| GND | GND | GND | 必须共地 |
| SDA | A4 | GPIO21 | I2C 数据线 |
| SCL | A5 | GPIO22 | I2C 时钟线 |
Power
SGP30 芯片本体不是普通 5V 芯片。淘宝/1688 上销售的一般是模块板,板上可能已经加了稳压、电平转换、I2C 上拉电阻或 VIN 输入保护。
| 情况 | 建议 |
|---|---|
| 裸 SGP30 芯片 | 不能直接接 3.3V / 5V,需要按官方电源设计 |
| 带 VIN 引脚的 SGP30 模块 | 按模块说明接 VIN,常见可能支持 3.3V 或 5V |
| 模块标注只支持 3.3V | 不要接 5V |
| 模块标注支持 5V VIN | 可以用 5V 接 VIN,但仍要确认 SDA/SCL 电平是否适合主控 |
Troubleshooting
SGP30 应扫到 0x58。若是 SGP40/SGP41,地址和输出逻辑不同,不要混用代码。
先把 OLED、其它传感器全部拔掉,只保留 SGP30,排除地址冲突和总线拖死。
VCC、GND、SDA、SCL 不要反接;UNO/Nano 是 A4/A5,不是 D4/D5。
先用 100 kHz,线尽量短。杜邦线接触不良时,I2C 扫描会间歇失败。
5V Arduino 要确认模块板带电平转换;裸芯片转接板不能直接承受 5V I2C。
排针虚焊、SDA/SCL 焊盘连锡、GND 没焊牢,都会导致无应答。
ACK / Address
很多 STM32 客户会把地址格式看混。`0x58` 是 7 位地址;`0xB0` 是左移一位后的写地址。地址对了,不代表模块已经应答,还要看 ACK 位。
| 现象 | 判断 |
|---|---|
扫描到 0x58 | I2C 通信基本正常 |
Write to 0xB0 + ACK | STM32 地址和硬件通信正常 |
Write to 0xB0 + Missing ACK / NAK | 主控发出了 SGP30 地址,但模块没有应答 |
| SCL 没波形 | 主控 I2C 没运行或引脚配置错 |
| SDA/SCL 一直低 | 总线被拉死,可能短路、接反、模块异常 |
| SDA/SCL 空闲不是高电平 | 上拉、电平或供电异常 |
#define SGP30_ADDR_7BIT 0x58
#define SGP30_ADDR_HAL (SGP30_ADDR_7BIT << 1) // 0xB0
if (HAL_I2C_IsDeviceReady(&hi2c1, SGP30_ADDR_HAL, 3, 100) == HAL_OK) {
// SGP30 found
} else {
// No ACK
}
Arduino Test
Arduino IDE 库管理器安装 Adafruit SGP30 和 Adafruit BusIO。代码先扫描 I2C,再初始化 SGP30。
#include <Wire.h>
#include "Adafruit_SGP30.h"
Adafruit_SGP30 sgp;
void setup() {
Serial.begin(115200);
Wire.begin(); // UNO/Nano: SDA=A4, SCL=A5
Wire.setClock(100000); // 排查阶段先用 100kHz
if (!sgp.begin()) {
Serial.println("SGP30 not found. Check 0x58 / wiring.");
while (1) delay(1000);
}
Serial.println("SGP30 found.");
}
void loop() {
if (sgp.IAQmeasure()) {
Serial.print("TVOC "); Serial.print(sgp.TVOC); Serial.print(" ppb\t");
Serial.print("eCO2 "); Serial.print(sgp.eCO2); Serial.println(" ppm");
}
delay(1000);
}
Customer Reply
References