2017-03-09 15 views
2

Arduino Uno/ESP8266을 사용하여 IR 원격 제어를 대체 할 캐리어 주파수 (38KHz) 상단에 IR 신호를 생성하려고합니다.Arduino/Esp8266 적외선 원격 제어 캐리어 주파수

먼저 IRremote.h 라이브러리를 사용하려고했지만 "irsend.sendNEC (0x8F4567A2, 32)"를 사용하여 코드를 보내면 실제받은 IR 코드가 8F4567A2가 아니며 (IRrecvDump 예제 사용). 그래서 오실로스코프를 사용하여 Arduino/Esp8266에서 생성 된 신호가 무엇인지 확인하기 위해 송신기 핀을 사용했습니다. 캐리어 펄스 지속 시간이 100us (38KHz ~ 26us가되어야 함) 이상인 것으로 나타났습니다.

그런 다음 코드를 다음과 같이 IRremote 라이브러리를 사용하지 않고 수동으로 신호를 생성하는 방법을 설명하는 YouTube 튜토리얼을 발견했습니다. 나는 여전히 오실로스코프를 송신기 핀에 연결하고 캐리어 펄스 지속 시간이 26us 대신 100us 이상인 것을 발견했다. 심지어 스케치에서 26us로 설정 했더니 사각 펄스를 설정해도 평탄한 펄스 폭을 볼 수 없었다 . 하지만 루프()에 루프()를 넣고 루프의 다른 모든 코드를 제거하면 오실로스코프는 5 초마다 정확한 펄스 지속 시간을 보여 주며 펄스는 예상대로 정사각형 펄스를 표시합니다 .

저는 IR 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

어쨌든 수신 된 코드를 확인하는 방법으로 IRremote 라이브러리의 "IRrecvDump"예제를 사용하면 IR 수신자 측에서 두 가지 방법 중 하나를 사용하여 스케치에서 일치하는 IR 코드 세트를받을 수 없습니다. –

+0

아직 실험하지는 않았지만 [이 게시물은 esp8266.com] (http://www.esp8266.com/viewtopic.php?f=24&t=832)에서 변수 및 테이블 조회를 사용하여 gpio의 성능을 설명합니다 실제 값 (예 : HIGH 대신 1)을 사용하며 실제 값을 사용하여 속도가 크게 향상됩니다. 그는 루아를 사용하고 있습니다. 또한, 귀하의 CPU 속도는 무엇입니까? – leetibbett

+0

[여기 토론입니다] (https : // github.co.kr/esp8266/Arduino/issues/1536)에서 i2c 속도에 대한 정보를 얻고 훨씬 빠른 타이밍을 달성하고 코드를 살펴 봅니다. – leetibbett

답변

0

일반적으로 이러한 타이밍의 경우 포트에 직접 쓰고 타이밍을 위해 타이머 인터럽트를 사용하는 것이 좋습니다. 예를 들어 어쨌든 느린 digitalWrite()은 MCU 주파수에 따라 다소 시간이 걸릴 것입니다.

또한 정의 된 F_CPU의 값이 MCU가 실행되는 주파수와 동일한 지 확인하십시오.

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

부문은 CPU 사이클이 많이 걸릴 수 있습니다, 그래서 단지 10 루프()에서 "IRcarrier (260)"를 넣으면 내가

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

에 그 변경 그러나 것 펄스 사이클을 반복하고 loop()에서 다른 모든 코드를 제거하면 오실로스코프 은 5 초마다 정확한 펄스 지속 시간을 나타내며 펄스는 예상대로 평방 펄스를 표시합니다.

정확히 같은 기능이 펄스를 생성하기 위해 호출 되었기 때문에 이것은 이상합니다.

BITtime의 올바른 값은 IRsendCode()입니까? (또한 BITtime은 26의 정확한 배수가 아니지만 큰 차이는 아닙니다.)

IRcarrier(9000);의 펄스는 무엇입니까? 아니면 지연 기능과 충돌 할 수있는 다른 코드도 실행 중입니까?