2014年10月14日火曜日

Arduinoでエアコン制御 2-3 (受信編)

Arduinoでエアコン制御 2-2の続き
ここでやっと信号の受信とそのフォーマットの解析までできた。

シリアル通信速度と"digitalRead"の有無の比較

下画像は上から115200、9600、38400 [bps]、左がスケッチ内で"digitalRead"を使わなかった場合、右は使った場合。
それぞれ5回ずつ受信テストを行った(一部略。計(3*2-1)*5回テストを行った)。
なお"max"、"min"欄は5回の内の最大値(最小値)と平均値の比であり、その比が30%を超えた場合、右隣に"×"が入るようにしている。
9600[bps]を一般値なんだとして選択していたが、"digitalRead"を入れた途端、データ数が揃わない。当然ながら歯抜けの為"×"が沢山入る。そしてなにより(115200[bps]と比較して)相当情報が欠落している。
38400[bps]でもガタガタで、やはり全てのデータを受信できていない。

受信がうまく完了していない原因は"digitalRead"にあるのではないかと予想を立てたが、影響はしているものの根本ではなかった。
つまり根本原因はシリアル通信のビットレートの低さにあったと言える。

考えてみれば当然とも言える結果だが、山(あるいは谷)1つ分で1[bit]、9600[bps]は9600[Hz]でその1[bit]を送っている。
赤外線通信の家電協フォーマットは0.4[ms]=2500[Hz]を1単位とした山(あるいは谷)である。
9600[bps]ではたった3.84倍でしかない。
38400[bps]は15.36倍あるのだが、それでも充分ではなかったようだ。

ただし「影響はしているものの…」としたのは、115200[bps]で"digitalRead"を使った場合に測定値のぶれが大きくなった為である。("×"が数個出た)
確かにその処理は重いらしい。

というか…一旦Arduinoにメモリさせて、まとめてシリアル通信に乗せればいいのか。
送受信機を考える段になってから検討する(かも)。

なお28800[bps]に設定して受信した際、Arduino IDEのシリアルモニタには下のように文字化け(?)したようなものが表示された。
ちらとググってみたが理由がわからなかった。
9600の4倍、12倍だった場合はうまくいったが、3倍だった場合はうまくいかなかった…というようなあたりに理由がありそうだが、また深入りすると一向に進められない為とりあえずこの件は見なかった事にする。

115200[bps]での受信テスト結果

115200[bps]で受信した時、そのデータ数は291+1+291=583あった。
リピートコードを挟み同数となっている為、おそらく欠落無く受信できたのだろう。
下は115200[bps]、"digitalRead"使用で5回テストを行った平均値を1~291までと、292~583[個]までで分けてグラフ化したものである。
なお正数はHigh(0)、負数はLow(1)で、縦軸は[μs]横軸は[個]になっている。
ちゃんと一致している。
あとは各ボタンを押した時のデータを収集比較するだけである。
とはいえ相当面倒臭い…

成功 スケッチ

const int irm = 2;
unsigned long time = 0;
unsigned long time_o =0;
volatile int itpt_st = 0;  //割込み確認フラグ

void setup() {
  pinMode(irm,INPUT);
  Serial.begin(115200); //Serial.print用
  attachInterrupt(0 ,rcv ,CHANGE);
}

void loop() {
  if (itpt_st == 1){
    if (digitalRead(irm) == HIGH) {
      Serial.print("-");
    }
    Serial.println(time-time_o);
    itpt_st = 0;  //フラグ初期化
  }
}

void rcv() {
  time_o = time;
  time = micros();
  itpt_st = 1;
}

フォーマットの確定(途中)

大分類 小分類 具体値 長さ 備考
Reader (1) 8T
(0) 4T
Customer BIN:1 0010 0110 1100 1011 0010 0011
(DEC:19,319,587)
(HEX:126 CB23)
45bit MITSUBISHI
霧ヶ峰
MSZ-GV223
Data 電源 0 off / 1 on 1bit
余白 5bit
運転モード BIN:11 冷房 / 10 除湿 / 01 暖房 2bit
余白 3bit
温度 BIN:0000 ~ 1111
冷房時16 ~ 31℃
4bit
余白 5bit
運転モード BIN:11 冷房 / 01 除湿 / 00 暖房 2bit 何故2ヶ所…???
共通 BIN:110 3bit 多分共通…
余白 2bit
風速 BIN:00 ~ 11
00 自動 / 01 風速1 ~ 11 風速3
2bit
余白 1bit
風向 BIN:000 ~ 111
000 自動 / 001 最上 ~ 111 最下
3bit
不明 2bit わからん…
余白 8bit
タイマ(切)時間 BIN:0000011 ~ 1001000
(DEC:3 ~ 72)
0.5h ~ 12h
3ずつ飛びとびの値を取る
10進数では*0.5/3する事になる
7bit
余白 1bit
タイマ(入)時間 BIN:000011 ~ 100100
(DEC:3 ~ 36)
0.5h ~ 6h
規則は(切)と同
6bit
余白 2bit
タイマーモード BIN:000 , 011 , 101
000 通常モード / 011 タイマ(切) / 101 タイマ(入)
3bit
余白 7bit
内部クリーン 0 off / 1 on 1bit
余白 9bit
パワフル運転 1bit
余白 11bit
Check sum Customer codeからCheck sum直前まで136bitを8bitずつ足した
下位8bit。
(8bitずつで切り出してそれらの合計を出し256でmodする)
8bit
Stop bit (1) 1T
Repeat (0) 33T
以降Reader codeからStop bitまでを1度繰返す
なお(1)はアクティブ…受信モジュールがLow、(0)はインアクティブ…受信モジュールがHighである事を示す。
Tは400[μs]を表す。
(括弧無しの)0は(1)-1T、(0)-1Tの組み合わせを示す(1bitは2Tの長さになる)。
1は(1)-1T、(0)-3Tの組み合わせを示す(1bitは4Tの長さになる)。

Customer codeは25bitしか記載していないが、上位ビットに(信号の後半に)20bit分の余白(0を示すbit)がきている。
また勝手に45bit分はCustomer codeだと書いているが、25bitかもしれないしその中間の長さかもしれない。Data codeが4、8、16等の区切りになっていなさそうなので確定できない。
送信の段になってから都合のいい切り方を考える(かもしれない)。

無意識に「後からきた信号は上位ビットに積まれていく」として考えていたが、たまたまそれが合っていたようである。
そこを間違えていたらCheck sumがどうなっているのか判断できなかったかもしれない。

0 件のコメント :

コメントを投稿