极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 27695|回复: 1

Arduino使用I2C通讯案例

[复制链接]
发表于 2020-12-13 20:58:02 | 显示全部楼层 |阅读模式
尝试使用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 可以正常点亮,和熄灭。


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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

 楼主| 发表于 2020-12-14 18:53:54 | 显示全部楼层
没有人额,怎么感觉这么冷清啦
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-5-1 12:14 , Processed in 0.039367 second(s), 18 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表