PIC16F1938でDMX512を受信してLEDを制御してみる【DMX受信編】

この記事では、
DMX512の簡易的な受信器を作成したので、
その回路図やコードを解説しています。

はじめに

前回の記事(PIC16F1938でDMX送信に挑戦)では、
DMX512信号の送信に成功しました。
今回の記事では、DMX512信号の受信に挑戦しました。

今回の回路

前前回のPIC16F1938でRS485通信(送信・受信)をやってみる
使用したものをそのまま流用しています。
今回は、RA1に繋いだLEDが活躍しています。

今回も前回のDMX送信の時と同様、
DMX送信器は別で用意するため、
1つ用意しました。

また、今回は完全に送信機として使用するため、
DEと/REをショートさせて、
RA2でLowとしています。

実際のコード

初期設定

ピンの初期設定やUSARTの初期設定は
前回とほぼ同じ内容です。

c

void Pin_Init(void) {
    ANSELA = 0x00;           //デジタルにセット
    ANSELB = 0x00;           //デジタルにセット

    TRISAbits.TRISA1 = 0;    //RA1を送信にセット
    TRISAbits.TRISA2 = 0;    //RA2を送信にセット
    LATAbits.LATA2 = 0;      //RA2をhigh(受信モード)

    TRISCbits.TRISC6 = 1;    //USART使用時はRC6はUSARTに制御される
    TRISCbits.TRISC7 = 1;    //RC7(RX)を受信にセット

}

void USART_Init(void) {
    TXSTAbits.SYNC = 0;       //EUSARTモード選択 0:非同期  1:同期
    TXSTAbits.BRGH = 1;       //高baudレート選択 1:非同期高速モード
    BAUDCONbits.BRG16 = 1;    //0:8ビットbaudレート 1:16ビットbaudレート

    SPBRG = 7;                //baudレートを250,000
    SPBRGH = 0;
    
    RCSTAbits.SPEN = 1;       //シリアルポート有効
    RCSTAbits.CREN = 1;       //受信イネーブル
}

DMX受信も送信と同様、
Baudレートを250,000にする必要があります。
そのため、今回も前回の記事と同様、
SPBRG = 7
となります。

DMX信号の受信

c

void dmx_receive(void) {

/************DMX信号受信無しの処理***********/
    if (!PIR1bits.RCIF) {
        return;
    }

/************Breakを検出するための処理**********/
    if (RCSTAbits.FERR) {
        dummy = RCREG;
        dmx_count = 0;
        // LATAbits.LATA1 = !LATAbits.LATA1;      ・・・①
        return;
    }

/**********USARTのデータを読み込む処理**********/
    unsigned char data = RCREG;

    /****スタートコードの処理****/
    if (dmx_count == 0) {
        
        start_code = data;
        //        if(start_code == 0x00){
        //            LATAbits.LATA1 = 1;
        //        }else {
        //            LATAbits.LATA1 = 0;
        //        }                                ・・・②
        
    } 
    /****DMX1ch目のみの処理****/
    //    else if (dmx_count == 1) {
    //            if (data > 127) {
    //                LATAbits.LATA1 = 1;
    //            } else {
    //                LATAbits.LATA1 = 0;
    //            }
    //     }                                       ・・・③

    /****DMXチャンネルデータの処理****/
    else if (dmx_count <= 512) {
        for (unsigned char i = 0; i < 4; i++) {
            if (dmx_count == my_address[i]) {
                dimmer[i] = data;
            }
        }

    }

    dmx_count++;

}

前回の送信の時も解説しましたが、
ここでも少し触れておきます。
DMX512の信号は、
次のような構成となっています。

  1. Break (>88μs)
  2. MAB (>8μs)
  3. Start code
  4. 1ch – 512ch data code

今回の受信に関しては、
DMX信号の最大の特徴である
“長~いBreak”
を読み取って、
DMX信号のスタートであることを判断させています。

受信側がUSARTの信号受信モードの場合は、
Breakのような Stop bit が
88μsも存在しない信号を受け取ると、
FERR(フレーミングエラー)フラグが立ちます。
つまり、
『これはおかしな信号が来ているよ!』
と教えてくれる旗印なわけです。

これを読み込むことで、
その次にくる正常な信号を
0番目(スタートコード)として読み込ませることができます。

なおスタートコードは、
通常のDMX信号では0x00が送信されます。
RDMでは、0xCCが使用されます。

それ以降の信号は、
512ch以下のDMXのチャンネルのデータとなり、
次々と送られてきます。

結果と考察

上の”DMX信号の受信”コード上に
コメントアウト部分で①②③を付けています。
今回は、この順番にコメントアウトを外し、
DMXがちゃんと受信できているかの確認をしました。

①の結果

①の1行だけをコメントアウトを外し、
書き込みました。
それから、DMXの操作卓を繋ぎました。
結果、RA1のLEDがチラチラしたり、
光り方が少し弱くなっていることが確認出来ました。
つまり、Breakの度にLEDが反転しているので、
このような挙動となるので、
しっかりとBreakを判定できているものと
判断しました。

②の結果

①をコメントアウトし、
②の5行のコメントアウトを外し書き込みました。
①と同様、DMX卓を繋ぎ、
RA1に接続しているLEDを確認したところ、
①とは異なり、LEDが煌々と灯っていました。
つまり、DMXのスタートコードである
0x00を受信している証拠です。

③の結果

次は②の5行をコメントアウト、
③の7行のコメントアウトを外し、書き込みました。
DMX卓を繋ぐと、LEDは消えたまま。
そして、チャンネル1が割り当てられている
フェーダを上げていくと、
50%ぐらいで、LEDがフル点灯。
逆に下げていくと、
50%ぐらいで、LEDの消灯を確認することが
できました。

これら3つの結果を受けて、
しっかりとDMX信号を受信できていると、
確認することができました。

次回予告

今回、DMX信号をしっかりと受信していることが分かりましたので、
次は、受信したDMX信号の値に応じて、
PWMのデューティ比を変え
LEDを光らせたいと思います。

シリーズ一覧

STEP1 UART
STEP2 RS485
STEP3 DMX送信
STEP4 DMX理解
▶ STEP5 DMX受信
STEP6 DMX→PWM(今回)
STEP7 現場仕様化

コメント

タイトルとURLをコピーしました