Arduino模块毗连多个I2C设置装备摆设_arduino模拟输
Arduino模块连接多个I2C设备
问题
你想连接多个I2C设备。
解决方案
以下示例使用一个空气质量传感器来测量每亿份中总挥发性有机化合物浓度(TVOC),并在四位数码LED显示器上显示它。你必须连接I2C上的空气质量传感器和LED显示控制器。图13-7显示了这两个I2C外设的连线,以及连接到LED控制器的四位数码LED段显示器
/
两个I2C设备示例
读取空气质量传感器并在LED显示器上显示VOC浓度。
/
#include
#include
#include
// 创建传感器和显示器的对象。
Adafruit_CCS811 s;
Adafruit_7segment matrix = Adafruit_7segment();
void setup()
{
Serial.begin(9600);
if (!s.begin())
{
Serial.println("Could not start sensor.");
hile (1) ; // 停止
}
hile (!s.available()) ; // 等待传感器准备就绪
matrix.begin(0x70); // 启动矩阵
}
void loop()
{
if (s.available())
{
if (!s.readData())
{
int tvoc = s.getTVOC(); // 获取VOC浓度
matrix.println(tvoc); // 写入值
matrix.riteDisplay(); // 更新显示器
}
}
delay(500);
}
讨论
解决方案使用了两个I2C组件ams CCS811空气质量传感器和Holtek HT16K33 LED控制器驱动器。它们都可以从多种来源的拆分板上获得。Adafruit将空气质量传感器作为部件号3566提供,将LED控制器作为部件号1427提供。SparkFun将空气质量传感器作为部件号SEN-14193提供。该解决方案使用了Adafruit板设计和Adafruit库(Adafruit CCS811库和Adafruit LED背包库)。您可以通过Arduino库管理器安装这两个库。
当连接多个I2C设备时,将所有SDA线连接在一起,所有SCL线连接在一起。每个设备都连接到电源,并且应该有0.1uF的去耦电容,除非它们被集成到拆分板中(检查拆分板的数据表或原理图),就像传感器和LED控制器驱动器一样。即使设备使用单独的电源(例如电池),GND线也必须连接在一起。
如果拆分板上包括所需的I2C线(SCL和SDA)上拉电阻,则您可能不需要在电路中包括它们(请参见食谱13.0)。Adafruit板确实包括这些内容,但如果您使用其他品牌,则应检查数据表或原理图。
该示例在setup中初始化了两个设备,并在循环内重复读取TVOC浓度,每次获得读数时在LED显示器上显示该值。您的LED显示器可能具有不同的引脚,请务必查阅数据表并相应地调整连线。
两个板子都支持5V电平,所以你可以与5V板子一起使用。如果你使用CCS811与一个3.3V板子一起使用,你必须使用3.3V来供电,否则其I2C引脚上的电压将会对你的板子来说过高。如果你想要将HT16K33与一个3.3V板子一起使用,情况会变得有些复杂,因为根据其规格,该板子需要至少4.5V才能运行。你可以使用一个电平转换器(参见第474页的“使用5V板子控制3.3V器件”)将其与你的3.3V Arduino兼容板连接作为低电压(LV)端,有些人报告说在3.3V电源下它也可以正常工作,所以你可以先尝试一下这个方法。
HT16K33期望的是一个公共阴极LED。Figure 13-7中的引脚分配是为了一个常见的4位7段数码管显示。HT16K33上的A0到A15用于控制七段数码管以及小数点。这个示例只使用A0到A7。如果你使用的是LED矩阵显示,你需要使用更多的引脚。引脚C0到C7选择要寻址的数字。HT16K33快速切换以显示每个数字,并依赖视觉暂留效应使其看起来所有四个数字点亮。
有些这样的显示器可以在每一对数字之间显示一个冒号,这在你想要创建一个数字时钟时非常有用。Adafruit LED Backpack库假定这个连接到C4(引脚4)。这个示例不使用它,所以引脚C4未使用。
在底层,Adafruit库使用Wire库与设备交互。例如,您可以使用matrix.setBrightness(1);将显示设置为最低亮度(15是最大值)。该库将发出以下命令来完成此操作(0x70是HT16K33的I2C地址)
#define HT16K33_CMD_BRIGHTNESS 0xE0
Wire.beginTransmission(0x70);
Wire.rite(HT16K33_CMD_BRIGHTNESS | 1);
Wire.endTransmission();
当该程序调用s.readData()然后调用s.getTVOC()时,驱动程序会执行类似以下的操作(0x5A是CCS811的I2C地址)。TVOC读数是通过将第三个和第四个字节(记住,C数组从零开始)组合成一个字值来形成的
uint8_t buf[8];
Wire.beginTransmission(0x5A);
Wire.rite(0x02); //写入寄存器0x02
Wire.endTransmission();
Wire.requestFrom(0x5A, 8); //从CCS811请求8个字节
for (int i = 0; i < 8; i++)
{
buf[i] = Wire.read();
}
int tvoc = ord(buf[2], buf[3]);