艾克瑞特

 找回密码
 立即注册ICrobot论坛
查看: 13792|回复: 0

利用红外实现两块Arduino简单通讯

[复制链接]

2

主题

2

帖子

38

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
38
发表于 2020-12-27 12:50:52 | 显示全部楼层 |阅读模式
这是前段时间做一个智能家居用到的思路,因为一块机子性能不够,所以用成本很低的红外传送状态和变量。

思路很简单,主机以红外方式发送数据,从机接收判断数据即可。


  • 这个例子上,主机上有一个18B20,将温度作为红外数据发送,完整的信号包括“信号头”-“数据”-“信号尾”
比如:
  1. irsend.sendNEC(0x0929a, 32);
  2.   delay(20);
  3.   irsend.sendNEC(tem10, 32);
  4.   delay(20);
  5.   irsend.sendNEC(0x0929b, 32);

  6.   irrecv.enableIRIn();      //reset server
复制代码
这里的0x0929a就是头,tem10是要传送的变量,0x0929b作为结尾,判断一个完整的数据组;

如果主机还有红外接收的任务,最后的 irrecv.enableIRIn();必须的,否则红外接收会在发送一次后失灵。


  • 从机接收此数据,我自编自写了一个最简单的验证、查错代码。
利用loop的循环,在三个周期内完成对应数据的验证,大概思路:

获取开始值                开始                                end
获取变量                判断开始值&&(赋值变量)              end
获取结束                结束        有效        赋值                                        end


主机代码:
  1. #include <IRremote.h>
  2. #include <OneWire.h>
  3. #include <DallasTemperature.h>

  4. #define ONE_WIRE_BUS 2

  5. OneWire oneWire(ONE_WIRE_BUS);
  6. DallasTemperature sensors(&oneWire);

  7. float tem, tem10;        //温度换算

  8. int TIMETEM = 1;                //设置温度刷新频率
  9. int TIMEIR = 1;
  10. int RECV_PIN = A0;                //红外输入口


  11. IRrecv irrecv(RECV_PIN);
  12. decode_results results;

  13. IRsend irsend;

  14. void setup()
  15. {
  16.   Serial.begin(9600);

  17.   irrecv.enableIRIn();                                 //开始采集

  18. }


  19. void loop()

  20. {
  21.   
  22.   if (TIMETEM <= 6)                                //设置温度刷新频率
  23.   {
  24.     TIMETEM++;
  25.   }

  26.   else
  27.   {
  28.     sensors.requestTemperatures();
  29.     tem = sensors.getTempCByIndex(0);     //温度--实际
  30.     tem10 = (sensors.getTempCByIndex(0) * 10);//温度*10
  31.     TIMETEM = 1;
  32.   }

  33.   if (TIMEIR <= 4)                                //设置红外刷新频率
  34.   {
  35.     TIMEIR++;
  36.   }

  37.   else
  38.   {
  39.     TIMEIR = 1;  //发送红外数据
  40.     vosend();
  41.   }


  42. }


  43. void vosend()
  44. {
  45.   irsend.sendNEC(0x0929a, 32);
  46.   delay(20);
  47.   irsend.sendNEC(tem10, 32);
  48.   delay(20);
  49.   irsend.sendNEC(0x0929b, 32);

  50.   irrecv.enableIRIn();      //reset server
  51. }
复制代码
从机:
  1. #include <IRremote.h>

  2. int RECV_PIN = A2;
  3. IRrecv irrecv(RECV_PIN);
  4. decode_results results;
  5. /*=================0-初始化===================*/

  6. int errnum4 = 0;
  7. float tem,tem10;

  8. boolean error4 = false;
  9. boolean ir4start = false;
  10. boolean ir4end = false;

  11. float irnum4a,irnum4b;

  12. void setup()
  13. {
  14.   irrecv.enableIRIn(); // Start the receiver
  15.   Serial.begin(9600);         //使用9600速率进行串口通讯
  16. }



  17. void loop()
  18. {
  19.   tem=irnum4b/10;  
  20.   tem10=irnum4b;
  21.   
  22.   Serial.print("Tem:");
  23.   Serial.println(tem);

  24.   if (irrecv.decode(&results))
  25.   {
  26.     /*
  27.     Serial.print(results.value, HEX);   //输出红外线解码结果(十六进制)
  28.      Serial.println("");
  29.      */
  30.     unsigned long remote = results.value;                //设红外信号为remote

  31.     /*=============查错=============*/
  32.     if(errnum4 <= 2)                //检错(红外周期验证)
  33.     {
  34.       errnum4++;
  35.     }
  36.     else
  37.     {
  38.       errnum4 = 0;
  39.     }

  40.     if(remote == (-1))                //溢出时
  41.     {
  42.       Serial.print("irCode: ");
  43.       Serial.print(results.value, HEX);   //输出红外线解码结果(十六进制)
  44.       Serial.print(",  bits: ");
  45.       Serial.println(results.bits);
  46.     }

  47.     /*-------------函数irnum4-------------*/
  48.     else if (remote == 0x0929b)
  49.     {
  50.       ir4end = true;
  51.     }

  52.     if(ir4start == true && ir4end == false)                        //NO.2,赋值
  53.     {
  54.       irnum4a = remote;
  55.     }

  56.     if(ir4start == true && ir4end == true)                        //NO.3,检错&&执行
  57.     {
  58.       ir4start = false;
  59.       ir4end = false;
  60.       if(errnum4 == 2)  //查错成功则赋值
  61.       {
  62.         irnum4b = irnum4a;
  63.         error4 = true;
  64.       }
  65.       else
  66.       {
  67.         error4 = false;
  68.       }
  69.     }

  70.     if (remote==0x0929a)                  //NO.1,判断开始
  71.     {
  72.       ir4start = true;
  73.       errnum4 = 0;
  74.     }
  75.     /*-----------End-函数irnum4-----------*/

  76.     irrecv.resume();                 // 返回值
  77.   }

  78. }
复制代码



回复

使用道具 举报

本版积分规则

Archiver|手机版|小黑屋|艾克瑞特 ( 鲁ICP备08015066号-5 )

GMT+8, 2024-5-3 04:12 , Processed in 0.049499 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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