bluetooth控制Arduino单片机的红外发射装置(一)——Arduino部分

开学初,听到某同学在台湾留学时候,成功使用Android手机通过bluetooth设备控制Arduino单片机来实现对宿舍空调的遥控。当时就觉得蛮有趣的,但是他的Android手机程序是通过Appinventor写的,我就想是否自己能够通过Eclipse来重新实现这一过程,也就是用Android手机通过Bluetooth控制Arduino单片机来遥控空调。但是宿舍空调离我的实验室比较远,所以先用Nikon D3300来试试手。

 

今天先Arduino遥控nikon d3300的心酸历程。

 

废话不多讲,接下来我们进入正题。首先我们来看一下总的思路

 bluetooth控制Arduino单片机的红外发射装置(一)——Arduino部分_第1张图片

相信上图显示的流程大家都不难理解。接下来就是各个部分的详细情况。

 

首先我们知道,要通过Arduino来遥控红外设备,就得知道Arduino单片机需要传送给红外发射二极管什么码型或者什么波形。我参考了《Arduino互动设计入门》以及网上各大Arduino资料,基本上都是使用IRremote这个开源的库来读取码型IRremote库下载地址:点击打开链接

bluetooth控制Arduino单片机的红外发射装置(一)——Arduino部分_第2张图片

当然,我也会去尝试。将1838一体化红外接收头连接好Arduino单片机(1838VCCGND和信号脚分别接ArduinoVCCGND11脚),Arduino单片机通过串口连接电脑,电脑打开Arduino,并打开IRrecvDump这一例程,选择好Arduino单片机型号和串口(我的是Arduino MEGA 2560),并打开Serial Monitor,如图。

 bluetooth控制Arduino单片机的红外发射装置(一)——Arduino部分_第3张图片

nikon自带遥控器对着1838按一下,就可以在Serial Monitor读到如图的Raw码。

 

首先我是不知道这些Raw码是什么意思,先留着。各种参考资料说就获得的Raw做以下操作:

1、去掉第一个数字;2、全部数字取绝对值;3、将空格改为逗号(英文状态)。并存储为以下数组,比如


unsigned int test[]={550,1350,550,3350,500}。


为什么要这么操作,一开始我也是不知道。后面通过查看下载的IRremote库的IRremot.hIRremote.cpp代码终于明白了,下文会提及到

 bluetooth控制Arduino单片机的红外发射装置(一)——Arduino部分_第4张图片

将上图的电路连接好了之后(红外发送二极管接330欧姆电阻接ArduinoPWM脚,即3号脚),通过Arduino编写如下代码发送刚刚获取的Raw码。

unsigned int test[]={550,1350,550,3250,500};
irsend.sendRaw(test,5,38);
delay(100);
irsend.sendRaw(test,5,38);


 

其实我也不知道两次码型传输之间的间隔是多少,所以就试了100ms(这并不重要)。

 

照理来说,这时候应该是可行了吧。

但是但是,冥冥注定,这篇文照会有所不同,所以我还未能通过Arduino来操控nikon d3300

 

一开始很灰心,因为明明按照参考书来操作的,怎么就跟剧本发展不同呢。接下来就是本文的重点了。

 

我从实验室找来了一台示波器(型号:Agilent Technologies InfiniiViision DSO-X 3034A),来记录遥控器和Arduino发送的波形有什么区别。

 

 

上图为接收到的遥控器的波形。

 

 

上图为Arduino单片机通过test发送的Raw码接收到的波形。对比遥控器的波形,很明显我们可以看出,Arduino发送的波形少了前面一小段,那么只要我们增加前面的一小段信号,那么就可以用Arduino来遥控单反了。现在问题来了,前面一小段波形怎么添加呢?

 

通过查看IRremote.cpp里面的IRsendRaw函数,我们就可以知道IRsendRaw这个函数是做了什么事情。

void IRsend::sendRaw(unsigned int buf[], int len, int hz)
{
  enableIROut(hz);
  for (int i = 0; i < len; i++) {
    if (i & 1) {
      space(buf[i]);
    } 
    else {
      mark(buf[i]);
    }
  }
  space(0); // Just to be sure
}
 
 
void IRsend::mark(int time) {
  // Sends an IR mark for the specified number of microseconds.
  // The mark output is modulated at the PWM frequency.
  TIMER_ENABLE_PWM; // Enable pin 3 PWM output
  delayMicroseconds(time);
}
 
void IRsend::space(int time) {
  // Sends an IR space for the specified number of microseconds.
  // A space is no output, so the PWM output is disabled.
  TIMER_DISABLE_PWM; // Disable pin 3 PWM output
  delayMicroseconds(time);
}


来到这里,我们就可以比较清IRsendRaw这个函数就是用来改变PWM3号脚)的高低值(01),test数组内的数字是用来延时的(单位:微秒),这也就是要讲读取到的数组内的数字全部取绝对值的原因。一旦我们读取出遥控器发送的信号波形的时间参数,再重新定义一个test2[]数组,让Arduino发送这个test2[数组,我们就可以让Arduino发送的波形和遥控器发送的波形一模一样,也就可以来遥控单反了

 

通过测量遥控器发送波形的时间参数,我们重新定义了

unsigned int test1[]={2086,27038,556,1372,532,3384,516};
irsend.sendRaw2(test1,7,38);
delay(67);
irsend.sendRaw2(test1,7,38);


  and 

 

上左图为Arduino重新发送的波形,上右图是遥控器发送的波形。基本上信号(两段)是一样的(PS:两段信号之间的时间间隔影响不大)。到这里,我他喵的终于成功了。


细心的同学可能会发现我使用的是irsend.sendRaw2(test1,7,38)函数而非irsend.sendRaw(test1,7,38)函数。这是涉及到溢出问题,可参考http://www.geek-workshop.com/archiver/tid-9763.html

这篇文章写得很好,我也是按照里面去IRremote.hIRremote.cpp添加sendRaw2()mark2()space2()函数的。

 

接下来,我会更新如何使用Eclipse来编程Android连接Bluetooth模块的。

 

 

你可能感兴趣的:(bluetooth控制Arduino单片机的红外发射装置(一)——Arduino部分)