xiao_y 发表于 2020-12-13 20:58:02

Arduino使用I2C通讯案例

尝试使用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;            // 建立光带leds
CRGB leds_B;            // 建立光带leds
CRGB 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;
// CRGB 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为第一个灯珠,leds为第二个灯珠
            //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为第一个灯珠,leds为第二个灯珠
            //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为第一个灯珠,leds为第二个灯珠
                //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;
CRGB 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 可以正常点亮,和熄灭。


接线反复检查了,没有问题,板子也换了新的测试 也不成功。排除板子原因。
剩下的就不知道是哪里问题?请各位大神帮忙看看,解惑一下,不胜感激。。。

xiao_y 发表于 2020-12-14 18:53:54

没有人额,怎么感觉这么冷清啦
页: [1]
查看完整版本: Arduino使用I2C通讯案例