2011年3月2日水曜日

IR受信のプログラムを整理


サンプルプログラムを整理した。

display_xxxx() という下請け関数が3つあるが、処理の本質には関係ないので、
基本的には、byteの配列でバッファをつくって、receive()を呼ぶ。

receive() は 受信ステータスが立つのを待って ir_rx.getData()で
データを取り出す。

LCD には 上段にフォーマットとステータス。
下段に 受信データが表示される。

リモコンのボタンをいろいろ押すと、受信データが変わるので、
この値を比較して、対応する処理を呼び出すようにすると、
リモコンでコントロール出来る車ができたりする。

ややこしくなるので、このプログラムでは対応処理を呼び出す部分を書いていないが、
ボタンとコードの対応を調べるために、とっておくと良い。


#include

#include "ReceiverIR.h"
#include "TextLCD.h"


ReceiverIR ir_rx(p10); //GEMMY IR RECEIVER

TextLCD lcd(p11, p12, p27, p28, p29, p30); // rs, e, d4-d7


/**
* Receive.
*
* @param format Pointer to a format.
* @param buf Pointer to a buffer.
* @param bufsiz Size of the buffer.
*
* @return Bit length of the received data.
*/
int receive(RemoteIR::Format *format, uint8_t *buf, int bufsiz, int timeout = 100) {
int cnt = 0;
while (ir_rx.getState() != ReceiverIR::Received) {
cnt++;
if (timeout < cnt) {
return -1;
}
}
return ir_rx.getData(format, buf, bufsiz * 8);
}

/**
* Display a current status.
*/
void display_status(char *status, int bitlength) {
lcd.locate(8, 0);
lcd.printf("%-5.5s:%02d", status, bitlength);
}

/**
* Display a format of a data.
*/
void display_format(RemoteIR::Format format) {
lcd.locate(0, 0);
switch (format) {
case RemoteIR::UNKNOWN:
lcd.printf("????????");
break;
case RemoteIR::NEC:
lcd.printf("NEC ");
break;
case RemoteIR::NEC_REPEAT:
lcd.printf("NEC (R)");
break;
case RemoteIR::AEHA:
lcd.printf("AEHA ");
break;
case RemoteIR::AEHA_REPEAT:
lcd.printf("AEHA (R)");
break;
case RemoteIR::SONY:
lcd.printf("SONY ");
break;
}
}

int bit2CharLen(int bitlen) {
return bitlen / 8 + (((bitlen % 8) != 0) ? 1 : 0);
}


/**
* Display a data.
*
* @param buf Pointer to a buffer.
* @param bitlength Bit length of a data.
*/
void display_data(uint8_t *buf, int bitlength) {
lcd.locate(0, 1);

const int n = bit2CharLen(bitlength);

for (int i = 0; i < n; i++) {
lcd.printf("%02X", buf[i]);
}
for (int i = 0; i < 8 - n; i++) {
lcd.printf("--");
}
}



//void getStr(uint8_t *buf, int bitlength)


/**
* Entry point.
*/
int main(void) {


lcd.cls();
lcd.printf("IR RECEIVE TEST.");

/*
* Execute.
*/
while (1) {
uint8_t buf1[32];
memset(buf1, 0x00, sizeof(buf1));

RemoteIR::Format format;

int bitlen = receive(&format, buf1, sizeof(buf1));

if (bitlen < 0) {
continue;
}


display_status("RECV", bitlen);
display_data(buf1, bitlen);
display_format(format);

}
}