OHMの照明リモコンスイッチのリモコン壊れたので作りました。

OHMの天井照明用のリモコンスイッチを2か所で使っているのですが、2つとも手元のリモコンだけが壊れて仕方なく1セット買ったのですが、また壊れそうなので作りました。111

どうも赤外線リモコンの方式は独自のようです。

秋月で買った赤外線受信モジュールSPS-440-1でリモコンを受信してみると図のような波形でした。一般的なNEC方式とかではないです。このパターンを出力するリモコンをPIC16F1827で作ります。

回路図

万能基板 3Dプリンタで製作

PICのソフト

電池で動かすので普段はSLEEP状態にしておいて、ボタンを押すと割り込みでSLEEP解除され、送信します。SLEEP時の電流は20μAほどでした。

 

//
//2021_1130 OHM REMOCON
//
#include <xc.h>

#define _XTAL_FREQ 32000000    //  delay用に必要(クロック32MHzを指定)

#pragma config CPD = OFF
#pragma config BOREN = OFF
#pragma config IESO = OFF
#pragma config FOSC =INTOSC 
#pragma config FCMEN = OFF
#pragma config MCLRE = OFF
#pragma config WDTE = OFF 
#pragma config CP = OFF
#pragma config LVP = OFF
#pragma config PWRTE = ON

//********************************************************

void sync(void);
void stop(void);
void data(unsigned char);
void send_data(unsigned char);

void main(void) {
    //最高速32MHz
    OSCCONbits.SPLLEN = 1; //×4 PLL
    OSCCONbits.IRCF = 14; //8MHz 14

    ANSELA = 0; // アナログ入力を無効
    ANSELB = 0; // アナログ入力を無効

    PORTA = 0; //PORT CLR
    PORTB = 0;
    TRISA = 0; //PORTA OUTPUT
    TRISB = 0b111111; //PORTB 0-5 INUPT

    OPTION_REGbits.nWPUEN = 0; //0:有効

    IOCBNbits.IOCBN2 = 1; //RB2立下り割り込み許可
    IOCBNbits.IOCBN3 = 1; //RB3立下り割り込み許可
    INTCONbits.IOCIE = 1; //RB割り込み許可
    GIE = 1; // 割り込み許可

    __delay_ms(10); // 10msec

    unsigned char c = 0;

#define ON  0b00011110
#define OFF 0b00101101    

    while (1) {
        //ONが押された
        if (RB2 == 0) {
            send_data(ON);
        }

        //OFFが押された
        if (RB3 == 0) {
            send_data(OFF);
        }
        //3回まわったらスリープ
        if (c++ > 3) {
            SLEEP();
            c = 0;
        }

        __delay_ms(54); //連続送信の間隔は54ms

    }

}

void send_data(unsigned char d) {
    unsigned char p;

    sync(); //SYNC

    //データ送信
    for (p = 0b10000000; p != 0; p >>= 1) {
        //pとdの同じビット位置のANDが1なら1、0なら0を送信 pを右シフト
        data(d & p);
    }

    stop(); //STOP
}

void sync() {
    int n;
    //赤外線ON(デューティ比は1/3)26μs
    for (n = 0; n < 95; n++) {//2.6ms
        RA1 = 1;
        __delay_us(9);
        RA1 = 0;
        __delay_us(17);
    }
    //OFF 2.6ms    
    __delay_ms(2);
    __delay_us(600);
}

void stop() {
    int n;
    //赤外線ON(デューティ比は1/3)26μs
    for (n = 0; n < 30; n++) {//0.9ms
        RA1 = 1;
        __delay_us(9);
        RA1 = 0;
        __delay_us(17);
    }

}

void data(unsigned char d) {
    int n;
    //赤外線ON(デューティ比は1/3)26μs
    for (n = 0; n < 30; n++) {//0.9ms
        RA1 = 1;
        __delay_us(9);
        RA1 = 0;
        __delay_us(17);
    }

    //OFF    
    if (d == 0) {
        __delay_us(800); //dが0で800ms
    } else {
        __delay_ms(1); //dが0以外で1.8ms
        __delay_us(800);
    }

}

void __interrupt() ISR_ExtInt(void) {
    //ボタンがどちらか押されると割り込み発生しSLEEP解除
    IOCBFbits.IOCBF = 0; //INTフラグクリア

    RA0 = 1; //確認用LED ON

    __delay_ms(10);

    RA0 = 0; //確認用LED OFF

}