在使用 ESP8266 进行开发时,我遇到了 I2C 通讯的问题。
具体来说,我需要使用两个 I2C 通讯接口,而默认的硬件 SDA 和 SCL 引脚(D1 和 D2)已经被占用。因此,我选择了 12 和 14 号引脚作为另一个设备的 SDA 和 SCL。
在开始时,如果我没有单独设置每个 I2C 设备的引脚,就会出现其中某个设备无法同时使用的情况。
后来我了解到,每次启用 I2C 都需要设置Wire.begin()才能让 I2C 正常工作。
以下是我的代码实现:
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <math.h>
#include <Wire.h>
#define ADDR 0b0100011 // I2C 设备地址
// 字符串用于存储光照数据
String str;
int i=1;
// I2C 引脚定义
int BH1750_SDA=12;
int BH1750_SCL=14;
int OLED_SDA=4;
int OLED_SCL=5;
int OLED_Txt_Size=2;
// 创建一个 SSD1306 对象,用于控制 OLED 显示
Adafruit_SSD1306 oled(128, 64, &Wire,-1);
void setup() {
// 初始化 OLED 显示
oled.begin(SSD1306_SWITCHCAPVCC,0x3C);
oled.setTextColor(WHITE);//设置文本颜色为白色
oled.clearDisplay();//清屏
oled.setTextSize(2); //设置字体大小
oled.setCursor(2, 5);//设置显示位置
oled.println("GY30:");//在 OLED 上显示 "GY30:"
// 更新 OLED 显示
oled.display();
Serial.begin(9600); // 设置串口波特率
while (!Serial) {;}
BH1750_Init();//初始化 BH1750 传感器
}
void loop() {
int val=0;
val=Read_BH1750();
/*输出光照数值*/
str="sample: "+String(i)+" "+String(val);
Serial.print("当前光照值: ");
Serial.println(str);
i++;
delay(100);
updateOLED(String(val)+ " lx");
}
void BH1750_Init(void){
// 初始化 I2C 通讯并指定 SDA 和 SCL 引脚
Wire.begin(BH1750_SDA,BH1750_SCL); // Wire.begin(SDA_PIN, SCL_PIN); Wire.begin(12,14);// 初始化 I2C 通信并指定 SDA 和 SCL 引脚
Wire.beginTransmission(ADDR);
Wire.write(0b00000001);
Wire.endTransmission();
}
int Read_BH1750(void){
int val = 0; //初始化光照值
Wire.begin(BH1750_SDA,BH1750_SCL);
Wire.beginTransmission(ADDR);
Wire.write(0b00000111);
Wire.endTransmission();
Wire.beginTransmission(ADDR);
Wire.write(0b00100000);
Wire.endTransmission();
delay(120);
/*计算光照*/
Wire.requestFrom(ADDR, 2); //每次 2byte
for (val = 0; Wire.available() >= 1; ) {
char c = Wire.read();
val = (val << 8) + (c & 0xFF);
}
val = val / 1.2;
return val;
}
void updateOLED(String data) {
Wire.begin(OLED_SDA,OLED_SCL);
oled.begin(SSD1306_SWITCHCAPVCC,0x3C);
// 清除 OLED 显示
oled.clearDisplay();//清屏
oled.setTextSize(1.5); //设置字体大小
oled.setCursor(2, 5);//设置显示位置
oled.println("Current Brightness:");
oled.setTextSize(OLED_Txt_Size); //设置字体大小
oled.setCursor(10, 35);//设置显示位置
// 显示新的数据
oled.println(data);
// 更新 OLED 显示
oled.display();
}
在这个示例中,我使用了两个 I2C 设备:BH1750 和 OLED。
我为每个设备单独设置了Wire.begin(),以确保它们可以同时工作。
然后,我通过Wire.write()和Wire.read()方法与设备进行通讯。