尝试使用3个uno(1主机+2从机)来实践I2C通讯。
从机1成功了,但是从机2失败,不知道为什么信号传输失败了,哪位大神可以解惑?
主机程序:
/*主机向从机循环发送字符串"light is "和字节x,x为1或0
从机接受到主机发来的数据后,当主机通知从机向它上传数据时
会把x值再上传回主机,然后赋值给变量c。
当主机程序判断c为1,则点亮LED,否则熄灭LED。*/
#include <Wire.h>//声明I2C库文件
#include "FastLED.h"
//#define LED 13
#define DATA_PIN_A 11
#define DATA_PIN_B 12
#define DATA_PIN_C 13
#define NUM_LEDS_A 12 // LED灯珠数量
#define NUM_LEDS_B 12 // LED灯珠数量
#define NUM_LEDS_C 12 // LED灯珠数量
#define LED_TYPE WS2812 // LED灯带型号
#define COLOR_ORDER GRB // RGB灯珠中红色、绿色、蓝色LED的排列顺序
uint8_t max_bright = 50; // LED亮度控制变量,可使用数值为 0 ~ 255, 数值越大则光带亮度越高
CRGB leds_A[NUM_LEDS_A]; // 建立光带leds
CRGB leds_B[NUM_LEDS_B]; // 建立光带leds
CRGB leds_C[NUM_LEDS_C]; // 建立光带leds
char getstr;
char zx;
char gbzx;
int i;
// static int i=0;
// 按键的管脚定义
int buttonPin_1 = 2;
int buttonPin_2 = 3;
int buttonPin_3 = 4;
int buttonPin_4 = 5;
//初始化
void setup()
{
Wire.begin(); // 加入 i2c 总线,作为主机
// pinMode(LED, OUTPUT); //设置数字端口13为输出
Serial.begin(9600);
delay(1000); // 稳定性等待
LEDS.addLeds<LED_TYPE, DATA_PIN_A, COLOR_ORDER>(leds_A, NUM_LEDS_A); // 初始化光带
LEDS.addLeds<LED_TYPE, DATA_PIN_B, COLOR_ORDER>(leds_B, NUM_LEDS_B); // 初始化光带
LEDS.addLeds<LED_TYPE, DATA_PIN_C, COLOR_ORDER>(leds_C, NUM_LEDS_C); // 初始化光带
FastLED.setBrightness(max_bright); // 设置光带亮度
pinMode(DATA_PIN_A,OUTPUT);
pinMode(DATA_PIN_B,OUTPUT);
pinMode(DATA_PIN_C,OUTPUT);
//设置按键管脚上拉输入模式
pinMode(buttonPin_1, INPUT_PULLUP);
pinMode(buttonPin_2, INPUT_PULLUP);
pinMode(buttonPin_3, INPUT_PULLUP);
pinMode(buttonPin_4, INPUT_PULLUP);
}
void loop()
{
if (digitalRead(buttonPin_1) == LOW) // 若按键被按下
{
delay(80); //等待跳过按键抖动的不稳定过程
if (digitalRead(buttonPin_1) == LOW ) // 若按键被按下
{
Wire.beginTransmission(4); //发送数据到设备号为4的从机
// Wire.write("X is "); // 发送字符串"X is "
Wire.write(1); // 发送变量x中的一个字节
Wire.endTransmission(); // 停止发送
Serial.println("ls ok!");
delay(50);
// while (digitalRead(buttonPin_1) == LOW) //判断按钮状态,如果仍然按下的话,等待松开
// {
// delay(1);
// }
}
if (digitalRead(buttonPin_1) == HIGH)
{
Wire.beginTransmission(4); //发送数据到设备号为4的从机
// Wire.write("light is "); // 发送字符串"light is "
Wire.write(0); // 发送变量x中的一个字节
Wire.endTransmission(); // 停止发送
Serial.println("gbls ok!");
delay(50);
// while (digitalRead(buttonPin_1) == HIGH) //判断按钮状态,如果仍然按下的话,等待松开
// {
// delay(1);
// }
}
}
if (digitalRead(buttonPin_2) == LOW) // 若按键被按下
{
delay(80); //等待跳过按键抖动的不稳定过程
if (digitalRead(buttonPin_2) == LOW) // 若按键被按下
{
Wire.beginTransmission(3); //发送数据到设备号为4的从机
// Wire.write("light is "); // 发送字符串"light is "
Wire.write(3); // 发送变量x中的一个字节
Wire.endTransmission(); // 停止发送
Serial.println("xc ok!");
delay(50);
// while (digitalRead(buttonPin_2) == LOW) //判断按钮状态,如果仍然按下的话,等待松开
// {
// delay(1);
// }
}
if (digitalRead(buttonPin_2) == HIGH)
{
Wire.beginTransmission(3); //发送数据到设备号为4的从机
// Wire.write("light is "); // 发送字符串"light is "
Wire.write(2); // 发送变量x中的一个字节
Wire.endTransmission(); // 停止发送
Serial.println("gbxc ok!");
delay(50);
// while (digitalRead(buttonPin_2) == HIGH) //判断按钮状态,如果仍然按下的话,等待松开
// {
// delay(1);
// }
}
}
if (digitalRead(buttonPin_3) == LOW) // 若按键被按下
{
delay(80); //等待跳过按键抖动的不稳定过程
if (digitalRead(buttonPin_3) == LOW) // 若按键被按下
{
Wire.beginTransmission(3); //发送数据到设备号为4的从机
// Wire.write("light is "); // 发送字符串"light is "
Wire.write(5); // 发送变量x中的一个字节
Wire.endTransmission(); // 停止发送
Serial.println("jg ok!");
delay(50);
}
if (digitalRead(buttonPin_3) == HIGH) // 若按键被按下
{
Wire.beginTransmission(3); //发送数据到设备号为4的从机
// Wire.write("light is "); // 发送字符串"light is "
Wire.write(4); // 发送变量x中的一个字节
Wire.endTransmission(); // 停止发送
Serial.println("gbjg ok!");
delay(50);
}
}
}
// if (digitalRead(buttonPin_4) == LOW) // 若按键被按下
// {
// delay(80); //等待跳过按键抖动的不稳定过程
// if (digitalRead(buttonPin_4) == LOW) // 若按键被按下
// {
// yg();
// //Serial.println("yg ok!");
// delay(50);
// }
//
// else {
// gbyg();
// //Serial.println("gbyg ok!");
// delay(50);
// }
// }
// }
//
//
//void xc()
// {
// fill_solid(leds_A, 30, CRGB::White);
// FastLED.show();
// delay(25);
//
// }
//void gbxc()
// {
// fill_solid(leds_A, 30, CRGB::Black);
// FastLED.show();
// delay(25);
// }
//void jg()
// {
// fill_solid(leds_B, 30, CRGB::Blue);
// FastLED.show();
// delay(25);
// }
//void gbjg()
// {
// fill_solid(leds_B, 30, CRGB::Black);
// FastLED.show();
// delay(25);
// }
//void yg()
// {
// fill_solid(leds_C, 30, CRGB::White);
// FastLED.show();
// delay(25);
// }
//void gbyg()
// {
// fill_solid(leds_C, 30, CRGB::Black);
// FastLED.show();
// delay(25);
// }
从机1程序:
#include <Wire.h>//声明I2C库文件
#include "FastLED.h"
#define NUM_LEDS_A 12
// #define NUM_LEDS_B 12
#define DATA_PIN_A 9
//#define DATA_PIN_B 10
#define LED_TYPE WS2812
#define COLOR_ORDER GRB
uint8_t max_bright = 255;
uint8_t min_bright = 50;
CRGB leds_A[NUM_LEDS_A];
// CRGB leds_B[NUM_LEDS_B];
char getstr;
int x;//变量x值决定主机的LED是否点亮
//初始化
void setup()
{
Wire.begin(4); // 加入 i2c 总线,设置从机地址为 #4
Wire.onReceive(receiveEvent); //注册接受到主机字符的事件
// Wire.onRequest(requestEvent); // 注册主机通知从机上传数据的事件
Serial.begin(9600); //设置串口波特率
delay(10);
pinMode(9, OUTPUT);
//pinMode(10, OUTPUT);
LEDS.addLeds<LED_TYPE, DATA_PIN_A, COLOR_ORDER>(leds_A, NUM_LEDS_A);
// LEDS.addLeds<LED_TYPE, DATA_PIN_B, COLOR_ORDER>(leds_B, NUM_LEDS_B);
FastLED.setBrightness(min_bright);
}
//主程序
void loop()
{
delay(1000);//延时
if(x==1)
{
Serial.println("zx!");
zx();
}
if(x==0)
{
Serial.println("gbzx!");
gbzx();
}
}
// 当从机接受到主机字符,执行该事件
void receiveEvent(int howMany)
{
while( Wire.available()>1) // 循环执行,直到数据包只剩下最后一个字符
{
char getstr = Wire.read(); // 作为字符接受字节
Serial.print(getstr); // 把字符打印到串口监视器中
}
//接受主机发送的数据包中的最后一个字节
x = Wire.read(); // 作为整数接受字节
//Serial.println(x); //把整数打印到串口监视器中,并回车
}
void zx()
{
for (int i=0;i<=11;i++)
{
leds_A = CRGB::Yellow; // 设置光带中第一个灯珠颜色为红色,leds[0]为第一个灯珠,leds[1]为第二个灯珠
//leds_B = CRGB::Yellow;
FastLED.show(); // 更新LED色彩
delay(50); // 等待100毫秒
Serial.println("dianliang");
}
for (int i=0;i<=11;i++)
{
leds_A = CRGB::Black; // 设置光带中第一个灯珠颜色为红色,leds[0]为第一个灯珠,leds[1]为第二个灯珠
//leds_B = CRGB::Black;
FastLED.show(); // 更新LED色彩
delay(50); // 等待100毫秒
Serial.println("guanbi");
}
}
void gbzx()
{
for (int i=0;i<=11;i++)
{
leds_A = CRGB::Black; // 设置光带中第一个灯珠颜色为红色,leds[0]为第一个灯珠,leds[1]为第二个灯珠
//leds_B = CRGB::Black;
FastLED.show(); // 更新LED色彩
delay(10); // 等待100毫秒
Serial.println("guanbi");
}
}
从机2程序:(传输失败程序)
#include <Wire.h>//声明I2C库文件
#include "FastLED.h"
#define NUM_LEDS_A 12
#define NUM_LEDS_B 12
#define DATA_PIN_A 9
#define DATA_PIN_B 10
#define LED_TYPE WS2812
#define COLOR_ORDER GRB
uint8_t max_bright = 255;
uint8_t min_bright = 50;
CRGB leds_A[NUM_LEDS_A];
CRGB leds_B[NUM_LEDS_B];
char getstr;
int y;
//初始化
void setup()
{
Wire.begin(3); // 加入 i2c 总线,设置从机地址为 #4
Wire.onReceive(receiveEvent); //注册接受到主机字符的事件
// Wire.onRequest(requestEvent); // 注册主机通知从机上传数据的事件
Serial.begin(9600); //设置串口波特率
delay(10);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
LEDS.addLeds<LED_TYPE, DATA_PIN_A, COLOR_ORDER>(leds_A, NUM_LEDS_A);
LEDS.addLeds<LED_TYPE, DATA_PIN_B, COLOR_ORDER>(leds_B, NUM_LEDS_B);
FastLED.setBrightness(min_bright);
}
//主程序
void loop()
{
delay(1000);//延时
if(y==3)
{
Serial.println("xc!");
xc();
}
if(y==2)
{
Serial.println("gbxc!");
gbxc();
}
// if(y==5)
// {
// Serial.println("jg!");
// jg();
// }
// if(y==4)
// {
// Serial.println("gbjg!");
// gbjg();
// }
}
// 当从机接受到主机字符,执行该事件
void receiveEvent(int howMany)
{
while( Wire.available()>1) // 循环执行,直到数据包只剩下最后一个字符
{
char getstr = Wire.read(); // 作为字符接受字节
Serial.print(getstr); // 把字符打印到串口监视器中
}
//接受主机发送的数据包中的最后一个字节
y = Wire.read(); // 作为整数接受字节
//Serial.println(x); //把整数打印到串口监视器中,并回车
}
void xc()
{
fill_solid(leds_A, 30, CRGB::White);
FastLED.show();
delay(25);
Serial.println("xc ...");
}
void gbxc()
{
fill_solid(leds_A, 30, CRGB::Black);
FastLED.show();
delay(25);
Serial.println("gbxc ...");
}
void jg()
{
fill_solid(leds_B, 30, CRGB::Blue);
FastLED.show();
delay(25);
}
void gbjg()
{
fill_solid(leds_B, 30, CRGB::Black);
FastLED.show();
delay(25);
}
//void yg()
// {
// fill_solid(leds_C, 30, CRGB::White);
// FastLED.show();
// delay(25);
// }
//void gbyg()
// {
// fill_solid(leds_C, 30, CRGB::Black);
// FastLED.show();
// delay(25);
// }
串口能读到以下信息:
xc!
xc ...
xc!
xc ...�
灯能点亮,但是不能遥控熄灭。。
从机1 可以正常点亮,和熄灭。
接线反复检查了,没有问题,板子也换了新的测试 也不成功。排除板子原因。
剩下的就不知道是哪里问题?请各位大神帮忙看看,解惑一下,不胜感激。。。 |