You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

新手求助:如何为Arduino Nano RP2040 Connect软件模拟I2C连接多台AM2320?

解决相同地址AM2320多传感器读取方案(基于SoftwareWire)

核心思路

因为硬件I2C总线只能区分不同地址的设备,而你的AM2320地址无法修改,所以给每个传感器分配一组独立的软件模拟I2C引脚,用SoftwareWire库分别创建I2C总线实例,实现独立通信。

步骤1:安装SoftwareWire库

在Arduino IDE中打开「库管理器」,搜索SoftwareWire,找到并安装该库。

步骤2:硬件接线

给四个AM2320分别分配不同的数字引脚对(SDA/SCL),比如:

  • 传感器1:SDA=D2,SCL=D3
  • 传感器2:SDA=D4,SCL=D5
  • 传感器3:SDA=D6,SCL=D7
  • 传感器4:SDA=D8,SCL=D9
    每个传感器的VCC接3.3V(AM2320兼容3.3V/5V,Nano RP2040的IO是3.3V,建议用3.3V),GND接开发板GND,注意每个I2C总线建议加10kΩ上拉电阻(如果传感器自带可以不加)。

步骤3:完整代码示例

#include <SoftwareWire.h>

// 为每个传感器创建独立的SoftwareWire实例
SoftwareWire wire1(2, 3);  // SDA=2, SCL=3
SoftwareWire wire2(4, 5);  // SDA=4, SCL=5
SoftwareWire wire3(6, 7);  // SDA=6, SCL=7
SoftwareWire wire4(8, 9);  // SDA=8, SCL=9

// AM2320的I2C地址(固定0x5C)
#define AM2320_ADDR 0x5C

void setup() {
  Serial.begin(115200);
  // 初始化所有软件I2C总线
  wire1.begin();
  wire2.begin();
  wire3.begin();
  wire4.begin();
  delay(1000);
}

// 封装AM2320读取函数,接收SoftwareWire实例作为参数
bool readAM2320(SoftwareWire &wire, float &temp, float &hum) {
  // 第一步:唤醒传感器(AM2320默认休眠,需先发送空数据唤醒)
  wire.beginTransmission(AM2320_ADDR);
  wire.endTransmission();
  delay(10);  // 等待传感器唤醒

  // 第二步:发送读取命令(读取4字节数据:湿度高、低,温度高、低)
  wire.beginTransmission(AM2320_ADDR);
  wire.write(0x03);  // 读取寄存器命令
  wire.write(0x00);  // 起始寄存器地址
  wire.write(0x04);  // 读取字节数
  int ack = wire.endTransmission(false);  // 发送后不释放总线
  if (ack != 0) {
    Serial.println("传感器无响应");
    return false;
  }

  // 第三步:读取传感器返回的数据
  wire.requestFrom(AM2320_ADDR, 6);  // 共返回6字节:命令码、字节数、湿度2字节、温度2字节、校验码
  if (wire.available() != 6) {
    Serial.println("数据长度错误");
    return false;
  }

  // 解析数据
  byte cmd = wire.read();
  byte len = wire.read();
  byte humHigh = wire.read();
  byte humLow = wire.read();
  byte tempHigh = wire.read();
  byte tempLow = wire.read();
  byte checksum = wire.read();

  // 校验数据
  byte calcChecksum = cmd + len + humHigh + humLow + tempHigh + tempLow;
  if (calcChecksum != checksum) {
    Serial.println("数据校验失败");
    return false;
  }

  // 转换为实际数值
  hum = (humHigh << 8 | humLow) / 10.0;
  temp = ((tempHigh & 0x7F) << 8 | tempLow) / 10.0;
  if (tempHigh & 0x80) {  // 温度为负
    temp = -temp;
  }

  return true;
}

void loop() {
  float temp1, hum1;
  float temp2, hum2;
  float temp3, hum3;
  float temp4, hum4;

  // 依次读取四个传感器
  Serial.println("=== 传感器1数据 ===");
  if (readAM2320(wire1, temp1, hum1)) {
    Serial.print("湿度: ");
    Serial.print(hum1);
    Serial.print("%  温度: ");
    Serial.print(temp1);
    Serial.println("℃");
  }

  Serial.println("=== 传感器2数据 ===");
  if (readAM2320(wire2, temp2, hum2)) {
    Serial.print("湿度: ");
    Serial.print(hum2);
    Serial.print("%  温度: ");
    Serial.print(temp2);
    Serial.println("℃");
  }

  Serial.println("=== 传感器3数据 ===");
  if (readAM2320(wire3, temp3, hum3)) {
    Serial.print("湿度: ");
    Serial.print(hum3);
    Serial.print("%  温度: ");
    Serial.print(temp3);
    Serial.println("℃");
  }

  Serial.println("=== 传感器4数据 ===");
  if (readAM2320(wire4, temp4, hum4)) {
    Serial.print("湿度: ");
    Serial.print(hum4);
    Serial.print("%  温度: ");
    Serial.print(temp4);
    Serial.println("℃");
  }

  Serial.println("------------------------");
  delay(2000);  // 每2秒读取一次
}

关键代码解释

  • SoftwareWire实例化:每个SoftwareWire wireX(sdaPin, sclPin)对应一组独立的模拟I2C总线,引脚可以选任意可用的数字引脚。
  • AM2320读取逻辑:AM2320需要先唤醒(发送空传输),再发送读取命令,最后解析返回数据并校验。把读取逻辑封装成函数,传入不同的SoftwareWire实例即可复用。
  • 数据校验:必须校验返回的校验码,避免读取到错误数据。

常见问题排查

  • 如果传感器无响应:检查接线是否正确,上拉电阻是否添加,引脚是否接反。
  • 如果数据校验失败:可能是通信干扰,尝试增加延迟,或者检查电源稳定性。
  • 引脚冲突:确保所选数字引脚没有被其他功能占用(比如串口、SPI引脚)。

内容的提问来源于stack exchange,提问作者Kristóf Varga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 13:25:23