利用红外实现两块Arduino简单通讯
本帖最后由 wasdpkj 于 2012-12-29 12:13 编辑这是前段时间做一个智能家居用到的思路,因为一块机子性能不够,所以用成本很低的红外传送状态和变量。
思路很简单,主机以红外方式发送数据,从机接收判断数据即可。
[*]这个例子上,主机上有一个18B20,将温度作为红外数据发送,完整的信号包括“信号头”-“数据”-“信号尾”
比如:
irsend.sendNEC(0x0929a, 32);
delay(20);
irsend.sendNEC(tem10, 32);
delay(20);
irsend.sendNEC(0x0929b, 32);
irrecv.enableIRIn(); //reset server
这里的0x0929a就是头,tem10是要传送的变量,0x0929b作为结尾,判断一个完整的数据组;
如果主机还有红外接收的任务,最后的 irrecv.enableIRIn(); 是必须的,否则红外接收会在发送一次后失灵。
[受此贴的帮助,感谢”贪婪“http://www.geek-workshop.com/forum.php?mod=viewthread&tid=2797]
[*]从机接收此数据,我自编自写了一个最简单的验证、查错代码。
利用loop的循环,在三个周期内完成对应数据的验证,大概思路:
获取开始值 开始 end
获取变量 判断开始值&&(赋值变量) end
获取结束 结束 有效 赋值 end
主机代码:
#include <IRremote.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float tem, tem10; //温度换算
int TIMETEM = 1; //设置温度刷新频率
int TIMEIR = 1;
int RECV_PIN = A0; //红外输入口
IRrecv irrecv(RECV_PIN);
decode_results results;
IRsend irsend;
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); //开始采集
}
void loop()
{
if (TIMETEM <= 6) //设置温度刷新频率
{
TIMETEM++;
}
else
{
sensors.requestTemperatures();
tem = sensors.getTempCByIndex(0); //温度--实际
tem10 = (sensors.getTempCByIndex(0) * 10);//温度*10
TIMETEM = 1;
}
if (TIMEIR <= 4) //设置红外刷新频率
{
TIMEIR++;
}
else
{
TIMEIR = 1;//发送红外数据
vosend();
}
}
void vosend()
{
irsend.sendNEC(0x0929a, 32);
delay(20);
irsend.sendNEC(tem10, 32);
delay(20);
irsend.sendNEC(0x0929b, 32);
irrecv.enableIRIn(); //reset server
}
从机:
#include <IRremote.h>
int RECV_PIN = A2;
IRrecv irrecv(RECV_PIN);
decode_results results;
/*=================0-初始化===================*/
int errnum4 = 0;
float tem,tem10;
boolean error4 = false;
boolean ir4start = false;
boolean ir4end = false;
float irnum4a,irnum4b;
void setup()
{
irrecv.enableIRIn(); // Start the receiver
Serial.begin(9600); //使用9600速率进行串口通讯
}
void loop()
{
tem=irnum4b/10;
tem10=irnum4b;
Serial.print("Tem:");
Serial.println(tem);
if (irrecv.decode(&results))
{
/*
Serial.print(results.value, HEX); //输出红外线解码结果(十六进制)
Serial.println("");
*/
unsigned long remote = results.value; //设红外信号为remote
/*=============查错=============*/
if(errnum4 <= 2) //检错(红外周期验证)
{
errnum4++;
}
else
{
errnum4 = 0;
}
if(remote == (-1)) //溢出时
{
Serial.print("irCode: ");
Serial.print(results.value, HEX); //输出红外线解码结果(十六进制)
Serial.print(",bits: ");
Serial.println(results.bits);
}
/*-------------函数irnum4-------------*/
else if (remote == 0x0929b)
{
ir4end = true;
}
if(ir4start == true && ir4end == false) //NO.2,赋值
{
irnum4a = remote;
}
if(ir4start == true && ir4end == true) //NO.3,检错&&执行
{
ir4start = false;
ir4end = false;
if(errnum4 == 2)//查错成功则赋值
{
irnum4b = irnum4a;
error4 = true;
}
else
{
error4 = false;
}
}
if (remote==0x0929a) //NO.1,判断开始
{
ir4start = true;
errnum4 = 0;
}
/*-----------End-函数irnum4-----------*/
irrecv.resume(); // 返回值
}
}
:funk:自己消灭零回复 我帮你消灭无人回复~最后的 irrecv.enableIRIn(); 是必须的,否则红外接收会在发送一次后失灵,我就是不知道这句干啥的! tgyfish 发表于 2012-12-30 23:19
我帮你消灭无人回复~最后的 irrecv.enableIRIn(); 是必须的,否则红外接收会在发送一次后失灵,我就是不知道 ...
没这句 就无法红外遥控主机了 请教电路连接,谢谢。
楼主这个程序是对的吗,我照着学习,可是看不到效果,难道是我的接线图错了吗???? :'(:'(:'(:'(:'(:'(:'(:'(:'(:'( cai_xiao_xiang 发表于 2013-9-6 17:13 static/image/common/back.gif
本帖是程序片段,我把当初的完整程序给你。好久以前写的自己都忘了,自行研究
不错不错
页:
[1]