MENU

Arduino (ProMicro)で家用のマルチリモコンを作る  その2

 前回の続きです。

moutakusan.hatenablog.com

 ↓こういうデータがダンプできたわけですが、どういう規格になってるんでしょうか。

f:id:moutakusan:20200908223306p:plain
ダンプされたデータ

 規格についてはこちらのサイトやこちらのサイトが参考にさせていただきました。 あと、Arduinoを使用した解析についてはdok kozoさんの記事jumbleatさんのブログも参考にさせていただきました。
 ポイントは、

  • 赤外線規格には数種類ある
    • 出力結果のEncodingってとこですね。
  • いずれの規格も全体の流れはリーダー→データ→リピート→データ→リピート→… の流れ
    • 出力結果のTimingの"+3450, -1600"がリーダー、その後の"500, -300"と"+550, -1150"がデータ。数字には少しばらつきがある。
  • データはHi期間とLow期間の比であらわされる
    • 出力結果のTimingの"+"がHigh期間、"-"がLow機関に対応している。

の三点ですかね。
 加えて、EncodingのフォーマットがPanasonicの場合は、アドレスが信号に含まれるみたいです。
 ここでちゃんとEncodingフォーマットが表示されていて、上手くデコードできている場合は、IRRemoteライブラリを使えば簡単に送信側もできそうですね。先にそっちをちょっとやってみることにします。

テレビの赤外線送信部を作ってみる

 テレビの赤外線信号はIRRemoteライブラリをそのまま使えば上手くデコードできてたみたいなので、デコードしたデータを参考に赤外線送信部を作ってみます。
 とりあえず、下記にデコードした結果の一部を書いてみました。

リモコンキー デコード結果
電源 0x555A F148688B
1ch 0x555A F148724C
2ch 0x555A F148F244
録画 0x555A F148C9F7

 デコード結果の前半の0x555Aがアドレス、後半がデータです。では試しにこれらのデータをテレビに投げてみましょう。

回路

回路はこう。

f:id:moutakusan:20200917165515p:plain
送信部回路図、 ピン5の先は前回作った受光部の回路につながってる
 赤外LEDはコレを使いました。赤外LEDの順方向電圧はTyp. 1.35V、最大定格電流はPulse駆動の場合は1000mAなんで、
    RIR = (5-1.35)V/1A = 3.65 ohm
ということで、3.65ohm以上ならOK。実際にはUSBの供給電流は最大500mAなので、余裕をもって100mA (RIR=36.5 ohm)くらいで使うことにします。1000 mA流したければ、別電源いりますね。これに合わせてトランジスタ2SC1815を使うことにしました。150mAまで流せるやつです。
 注意点として、定電流のときのLEDの最大定格は100mAなので、前のスケッチが残っていたりしてD5ピンがHighになっている状態で回路の電源入れるとLEDが壊れます。スケッチを書き込んでからLEDを接続するようにするなどして対策してください。

コード

 コードはスケッチ例のIRSendDemo.inoを編集して、テレビのON/OFF信号を5秒に1回投げるようにしました。

#include <IRremote.h>

IRsend irsend;

void setup() {
    pinMode(LED_BUILTIN, OUTPUT);

    Serial.begin(115200);
    // Just to know which program is running on my Arduino
    Serial.println(F("START " __FILE__ " from " __DATE__));
    Serial.print(F("Ready to send IR signals at pin "));
    Serial.println(IR_SEND_PIN);  //IR_SEND_PIN=5
}

void loop() {
    unsigned long tAddress = 0x555a;  //TV address
    unsigned long tData = 0xf148688B;  //Power ON/OFF
    
    for (int i = 0; i < 3; i++) {
        irsend.sendPanasonic(tAddress, tData);
        Serial.print(F("sendPanasonic(0x"));
        Serial.print(tAddress,HEX);
        Serial.print(F(", 0x"));
        Serial.print(tData,HEX);
        Serial.println(F(")"));
        delay(40);
    }

    delay(5000); 
}

結果

 スケッチを回路に書き込むと赤外LEDがチカチカ(目視ではもちろん見えませんが、スマホのカメラ越しだと赤外LEDの光が見えます。)

f:id:moutakusan:20200917164434g:plain
赤外LEDチカチカ
 赤外LEDをテレビの方に向けると…ちゃんとテレビがON/OFFしてくれました!!ちなみに、テレビからどれくらい離れても届くか試したところ、だいたい4.5mくらいまでは反応してくれました。家の中で使う分には十分なので、回路はこのまま進めようと思います。

 次回はもう少しIRremoteライブラリをいじってみようかなぁ。


つづく

Arduino (ProMicro)で家用のマルチリモコンを作る  その1

こういうやつですね。

作ってみましょう。

仕様

 家にあるリモコンから赤外線を読み込んでデータを解析し、保存するモードと、保存したデータを送信するモードがあるといいですね。

手順

 下記順番で進めていこうと思います。

  1. 赤外線読み込み部を作る。
  2. データ保存部を作る。
  3. 赤外線送信部を作る。
  4. 全部組み合わせて動かす。

まずは、”1. 赤外線読み込み部を作る”からやっていきます。

1. 赤外線読み込み部を作る

 こちらの記事が参考になりそうですね。コードは記事中に載っているIRremote Arduino Libraryを使えば簡単にできそうです。こちらのライブラリはIDEからもインストールできるみたいですね。

f:id:moutakusan:20200907221021p:plain
IRremote LibraryはIDEからインストールできる
readmeのHintsの中に

Use the IRrecvDumpV2 example to dump out the IR timing. You can then reproduce/send this timing with the IRsendRawDemo example. For long codes like from air conditioners, you can change the length of the input buffer in IRremoteInt.h.

なんていう記述もあり、やりたいことほぼそのまんまです。あと、エアコンはテレビなどに比べて長めの赤外線信号でやりとりしてるみたいなんで、それにも対応が必要らしいってことはわかってたんですが、そちらの問題もケアできそうです。これを参考に作っていきましょう。

 赤外線受光モジュールは秋月電子様のこちらを使います。データシートを見ると、回路例が載ってるのでこの通りに作っていきましょう。(For Noisy Power Supplyとあるので、Vsが安定してるならR2とC1は必要ないかも。)

f:id:moutakusan:20200906161859p:plain
赤外線受光モジュール回路例

材料

コーディング

 さっそく、IRremoteをインストールしたときについてきたスケッチ例の中の”IRrecvDumpV2.ino”を動かしてみましょう(こちらです)。ざっと見た感じ、受信用のピンだけ回路に合わせて変えれば動くのかな。まぁやってみましょう。

実行結果

f:id:moutakusan:20200908223215p:plain
ピッ

f:id:moutakusan:20200908223306p:plain
パッ

 動きましたー。よくわからない形式のデータがダンプされてますね。次回はここらへんの調査をしていきます。


つづく。

ProMicroで熱中症アラート付き温度計を作ってみた

 ProMicroを手に入れました。正確にはProMicroの互換品ですが。

 ProMicro自体もArduino Leonardoの互換品ということで、互換品の互換品になりますね。今回はProMicroと温度センサモジュールとキャラクLCDモジュールを使って温度計を作ってみましょう。
 どうせなら、熱中症の危険度がLEDの色で一目でわかるようにしてみましょう。

仕様

 温度計なので、LCDに温度を表示させるのは決まりです。LEDの色と閾値を決めなければいけません。
 こちらの環境省の資料によれば部屋の温度が28℃が最もよく、24℃以下では外気温との温度差が大きく体に負担とのことです。
 また、こちらの資料では、暑さ指数(WGBT)が

暑さ指数 危険度
28℃~31℃ 厳重警戒
31℃以上 危険

となっていますね。
 暑さ指数は実際には湿度によっても変わるんですが、今回は手元に湿度計がないので温度だけ見てアラートを出すことにします。湿度測定への拡張は作ってしまってからでも簡単にできますしね。
 ということで、LEDの色と閾値は下記の感じでいきましょう。

室温 危険度
24℃以下 黄色
24~28.5℃ 青色
28.5~31℃ 黄色
31℃以上 赤色

材料

回路

 こんな感じです。 f:id:moutakusan:20200905170158p:plain

 LEDの電流制限抵抗は赤が順方向電圧2.1V minで、最大定格50mAなので、
    RRED = (5-1.8)V/0.05A = 64 ohm
青と緑は順方向電圧2.9V minで、最大定格30mAなので、
    RBG = (5-2.9)V/0.03A = 70 ohm
って感じで、抵抗のMIN値だけ計算して、適当に決めました。

配線

こんなんになりました。配線多くて見た目はいまいちだなぁ。 f:id:moutakusan:20200905174246p:plain

こちらの記事とかだと、ユニバーサル基板にLCDモジュールを取り付けてきれいに配線してるなぁ。今後の課題です。

コード

基本的にはArduino IDEに収録されてるコードのコピペで作れてしまいます。今回は、

  • ファイル → スケッチ例 → Wire → master_reader
  • ファイル → スケッチ例 → LiquidCrystal → HelloWorld

の二つをベースに作りました。

#include <Wire.h>
#include <LiquidCrystal.h>

const int rs = 9, en = 10, d4 = 8, d5 = 7, d6 = 6, d7 = 5;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

const int rled=15, gled=14, bled = 16;

void setup() {
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
  Wire.beginTransmission(0x48);
  Wire.write(0x03);
  Wire.write(0x80); 
  Wire.endTransmission();
  delay(240);  

  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("temperature");  

  pinMode(rled,OUTPUT);
  pinMode(bled,OUTPUT);
  pinMode(gled,OUTPUT);
  digitalWrite(rled,LOW);
  digitalWrite(gled,LOW);
  digitalWrite(bled,LOW);  
  
}

void loop() {
  Wire.requestFrom(0x48, 2);    // request 6 bytes from slave device #8

  int byteData;
  int data=0;
  float temp;
  while (Wire.available()) { // slave may send less than requested
    byteData = (Wire.read()<<8) | Wire.read(); // receive a byte as character
    if(byteData & 0x8000){
      data = -((~byteData & 0x7fff) +1 );
    }
    else{
      data = byteData&0x7fff;
    }
  }
  temp = data*0.0078;

  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(temp);

  lcd.setCursor(6,1);
  lcd.print("degC");

  if(temp>31){
    digitalWrite(rled,HIGH);
    digitalWrite(gled,LOW);
    digitalWrite(bled,LOW);
  }
  else if (temp>28.5| temp<24){
    digitalWrite(rled,HIGH);
    digitalWrite(gled,HIGH);
    digitalWrite(bled,LOW);
    
  }
  else{
    digitalWrite(rled,LOW);
    digitalWrite(gled,LOW);
    digitalWrite(bled,HIGH);        
  }

  delay(500);
}

完成品

 室温が28℃以下の部屋で、温度センサー部を指で温めて動作を確認します。

f:id:moutakusan:20200905231410g:plain
28.5℃以下から28.5℃以上
f:id:moutakusan:20200905231518g:plain
31℃以下から31℃以上

 動きました!温度によってLEDの色も変化してくれていますね。ただ、黄色がただの赤と緑になってますね。フルカラーLEDを初めて使ったんですが、上手く色が混ざらないものなんでしょうか?拡散板とか使えばいいのかなぁ。もしくは輝度調整?また次の機会にそこらへんは見ていくことにしましょう。