リモコン受信を判定するプログラム。 秋月のオプトサプライ赤外線リモコンに対応。

Dependencies:   mbed

main.cpp

Committer:
gitakichi
Date:
2020-02-13
Revision:
8:9c0161fd67e2
Parent:
7:47e8eccc7a01

File content as of revision 8:9c0161fd67e2:

//reference from
//https://www.hiramine.com/physicalcomputing/mbed/irreceiver.html
//http://elm-chan.org/docs/ir_format.html
#include "mbed.h"

//compatible
//http://akizukidenshi.com/catalog/g/gM-07245/

//{customer code 16bit,data 8bit data_n 8bit,none 1bit}
#define OPT_PWR     "000010001111011100011011111001001"
#define OPT_A       "000010001111011100011111111000001"
#define OPT_B       "000010001111011100011110111000011"
#define OPT_C       "000010001111011100011010111001011"
#define OPT_CENTRE  "000010001111011100000100111110111"
#define OPT_TOP     "000010001111011100000101111110101"
#define OPT_UNDER   "000010001111011100000000111111111"
#define OPT_LEFT    "000010001111011100001000111101111"
#define OPT_RIGHT   "000010001111011100000001111111101"

#define DARK    1
#define BRIGHT  0

DigitalIn ir_in(D2);
Serial pc(USBTX, USBRX);
DigitalOut myled(LED1);
DigitalOut ir_out(D3);

Timer timer;

int IR_transmitte(char tx_data[])
{
    timer.start();

    //flame
    int t_start = timer.read_us();
    ir_out = 1;
    while( timer.read_us() - t_start < 625*16 );//16T
    t_start = timer.read_us();
    ir_out = 0;
    while( timer.read_us() - t_start < 625*8 );//8T

    //data
    for(int i=0; tx_data[i] != '\0'; i++ ) {
        t_start = timer.read_us();
        while( timer.read_us() - t_start < 625 )   ir_out = 1;
        t_start = timer.read_us();
        ir_out = 0;
        if( tx_data[i] == '1') {
            while( timer.read_us() - t_start < 625 );//1T
        } else {
            while( timer.read_us() - t_start < 625*3 );//3T
        }
    }
    return 0;
}

int IR_receive(char rx_data[])
{
    int t_negedge,t_posedge,t_delta,iState;
    int iState_prev = 1;
    int busy = 0;
    int data_en = 0;

    timer.start();
    memset(rx_data, '\0', sizeof(rx_data));

    while(busy == 0) {
        iState = ir_in;
        if(iState_prev == DARK && iState == BRIGHT) {//detect negedge
            t_negedge = timer.read_us();//start(detect negedge
            t_delta = t_negedge - t_posedge;

            if(data_en == 1) {
                data_en = 0;
                if(t_delta > 1523)    strcat(rx_data, "1");//625*2.5
                else                  strcat(rx_data, "0");

                if(strlen(rx_data) == 33) {
                    busy = 1;
                }
            }
        } else if(iState_prev == BRIGHT && iState == DARK) {//detect posedge
            t_posedge = timer.read_us();
            t_delta = t_posedge - t_negedge;
            if(t_delta > 500 && t_delta < 750) {//16T
                data_en = 1; //This is flame
            }
        }
        iState_prev = iState;
    }
    return busy;
}


int main()
{
    char rx_data[64],tx_data[64];
    int busy = 0;
    int tx_delay,tx_en;

    pc.baud(115200);

    while(1) {
        if(busy == 1) {
            pc.printf("%s\r\n",rx_data);

            if (strcmp(rx_data,OPT_PWR) == 0) {
                tx_delay = 5;
                tx_en = 1;
                strcpy(tx_data, OPT_PWR);//enter Arbitrary Values
            } else {
                tx_delay = 0;
                tx_en = 0;
            }
            myled = 1;
            for(int i=0; i<tx_delay; i++) {
                wait_ms(1000);
            }
            //tx IR
            if(tx_en == 1)  IR_transmitte(tx_data);
            tx_en = 0;
            myled = 0;
            busy = 0;
        } else {
            busy = IR_receive(rx_data);
        }
    }
}