我正在尝试使用Arduino Uno / ESP8266在载波频率(38KHz)之上生成IR信号,以取代IR遥控器。
首先,我试图使用IRremote.h库,但是当使用“irsend.sendNEC(0x8F4567A2,32)”发送代码时,实际收到的IR代码不是8F4567A2(使用IRrecvDump示例)。所以我用示波器连接发射器引脚来检查Arduino / Esp8266产生的信号是什么。我注意到载波脉冲持续时间超过100us(38KHz应该有~26us)。
然后,我发现youtube教程教导如何在不使用IRremote库的情况下手动生成信号,如下面的代码。我仍然用发射器引脚连接示波器,发现载波脉冲持续时间超过100us而不是26us,即使我把它设置为草图中的26us,我甚至看不到平坦的脉冲宽度,即使我设置了方波脉冲。但是,如果我只是简单地将“IRcarrier(260)”置于循环()中10个脉冲周期并移除循环中的所有其他代码(),则示波器每5秒显示正确的脉冲持续时间,并且脉冲显示有点像预期的方波脉冲
我有点困在我的IR项目,尝试使用arduino / esp8266来取代电视IR遥控器。
#define IRLEDpin 2 //the arduino pin connected to IR LED to ground. HIGH=LED ON
#define BITtime 562 //length of the carrier bit in microseconds
//put your own code here - 4 bytes (ADDR1 | ADDR2 | COMMAND1 | COMMAND2)
unsigned long IRcode=0b11000001110001111100000000111111;
// SOME CODES:
// Canon WL-D89 video remote START/STOP button = 0b11000001110001111100000000111111
void setup()
{
}
void IRsetup(void)
{
pinMode(IRLEDpin, OUTPUT);
digitalWrite(IRLEDpin, LOW); //turn off IR LED to start
}
// Ouput the 38KHz carrier frequency for the required time in microseconds
// This is timing critial and just do-able on an Arduino using the standard I/O functions.
// If you are using interrupts, ensure they disabled for the duration.
void IRcarrier(unsigned int IRtimemicroseconds)
{
for(int i=0; i < (IRtimemicroseconds / 26); i++)
{
digitalWrite(IRLEDpin, HIGH); //turn on the IR LED
//NOTE: digitalWrite takes about 3.5us to execute, so we need to factor that into the timing.
delayMicroseconds(9); //delay for 13us (9us + digitalWrite), half the carrier frequnecy
digitalWrite(IRLEDpin, LOW); //turn off the IR LED
delayMicroseconds(9); //delay for 13us (9us + digitalWrite), half the carrier frequnecy
}
}
//Sends the IR code in 4 byte NEC format
void IRsendCode(unsigned long code)
{
//send the leading pulse
IRcarrier(9000); //9ms of carrier
delayMicroseconds(4500); //4.5ms of silence
//send the user defined 4 byte/32bit code
for (int i=0; i<32; i++) //send all 4 bytes or 32 bits
{
IRcarrier(BITtime); //turn on the carrier for one bit time
if (code & 0x80000000) //get the current bit by masking all but the MSB
delayMicroseconds(3 * BITtime); //a HIGH is 3 bit time periods
else
delayMicroseconds(BITtime); //a LOW is only 1 bit time period
code<<=1; //shift to the next bit for this byte
}
IRcarrier(BITtime); //send a single STOP bit.
}
void loop() //some demo main code
{
IRsetup(); //Only need to call this once to setup
IRsendCode(IRcode);
delay(5000);
}
答案 0 :(得分:0)
一般来说,对于这样的时序,我更喜欢直接写入端口并使用定时器中断进行定时。例如digitalWrite()
,无论如何都很慢,取决于MCU的频率,会花费更多或更少的时间。
还要确保(已定义的)F_CPU
的值与MCU运行的频率相同。
for(int i=0; i < (IRtimemicroseconds / 26); i++)
分区可能需要很多CPU周期,因此我会将其更改为
for(int i=0; i < IRtimemicroseconds; i += 26)
但是,如果我只是简单地将“IRcarrier(260)”放入循环()中10脉冲 循环并删除环路(),示波器中的所有其他代码 每5秒显示正确的脉冲持续时间,脉搏显示有点 方波脉冲符合预期。
现在这很奇怪,因为调用完全相同的函数来生成脉冲。
您确定BITtime
内的IRsendCode()
仍然具有正确的值吗? (另外,BITtime
不是26的精确倍数,但这不会产生很大的影响)
IRcarrier(9000);
生成什么脉冲?或者你还有一些其他代码运行,可能会与延迟函数冲突?