2017-03-09 34 views
2

私はArduino Uno/ESP8266を使用して、IRリモコンに代わるキャリア周波数(38KHz)の上にIR信号を生成しようとしています。Arduino/Esp8266赤外線リモコンキャリア周波数

最初にIRremote.hライブラリを使用しようとしましたが、 "irsend.sendNEC(0x8F4567A2,32)"を使用してコードを送信すると、実際に受信されたIRコードは8F4567A2(IRrecvDumpの例を使用)ではありません。だから私はオシロスコープを使ってArduino/Esp8266から生成された信号が何であるかを確認するために送信機ピンを使っていました。私は、キャリアパルスの持続時間が100us以上であることに気付きました(38KHzには〜26usが必要です)。

次に、私はyoutubeのチュートリアルで、IRremoteライブラリを使用しないで手動で信号を生成する方法を教えました。私はまだオシロスコープをトランスミッタ・ピンに接続し、キャリア・パルスの持続時間が26usではなく100usを超えていることを発見しました。スケッチでは26usに設定しましたが、方形パルスを設定しても平坦なパルス幅を見ることはできません。しかし、ループ()内に10個のパルスを "IRキャリア(260)"に入れ、ループ()内の他のコードをすべて削除すると、オシロスコープは5秒ごとに正しいパルス持続時間を示し、 。

ここで私のIRプロジェクトでは、テレビIRリモートを置き換えるためにarduino/esp8266を使用しようとしています。

#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

とにかく、受信したコードをチェックする方法としてIRremoteライブラリの "IRrecvDump"の例を使用すると、IR受信側は、2つの方法のいずれかを使用してスケッチ内の一致したIRコードセットを受け取ることができません。 –

+0

私はそれを試していませんが、[this post on esp8266.com](http://www.esp8266.com/viewtopic.php?f=24&t=832)では、変数とテーブルの参照を使ってgpioのパフォーマンスを説明しています。実際の値(たとえばHIGHの代わりに1)を使用して、実際の値を使用して速度が大幅に改善されていることを示します。彼はLuaを使っている。また、あなたのCPU速度は何に設定されていますか? – leetibbett

+0

[これは議論です](https:// github。com/esp8266/Arduino/issues/1536)、i2cのスピードについてはもっと速いタイミングを達成しており、コードを見ています – leetibbett

答えて

0

一般に、このようなタイミングの場合、私はポートに直接書き込みを行い、タイミングにタイマ割り込みを使用することをお勧めします。たとえば、遅くても遅いdigitalWrite()は、MCUの周波数に応じてより多くの時間を取るでしょう。

また、(定義された)F_CPUの値が、MCUが動作している周波数と同じであることも確認してください。

for(int i=0; i < (IRtimemicroseconds/26); i++) 

部門は、CPUサイクルの多くを取ることができますので、私は

for(int i=0; i < IRtimemicroseconds; i += 26) 

にそれを変更します。しかし、私は単に10用)(ループ内で "IRcarrier(260)" を置く場合パルス サイクルでループ内の他のコードをすべて削除すると、オシロスコープ は5秒ごとに正しいパルス持続時間を示し、パルスは予想通りに 平方パルスを示します。

正確に同じ機能が呼び出されてパルスが生成されるため、これは変です。

確かにBITtimeの正しい値はIRsendCode()ですか? (また、BITtimeは26の倍数ではありませんが、大きな違いはありません)

IRcarrier(9000);のパルスは何パルスですか?または、遅延機能と競合する可能性のある他のコードも実行していますか?