#最終目標
Arduinoでシーリングライト・エアコンを支配する。<-前回の続き
Wifiを用いて外部から操作できるようにする。<-機材届いてないのであとで
##エアコンの赤外線リモコンを解析する。
前回同様エアコンのリモコンを解析しよう。そうしよう。
(この時、苦労することなんて知るよしもなかった......)
###機材
-
Arduino uno R3<- WiFiモジュールの回路めんどくさくてESPDuino-32に変更した
(機材変更のためpinの設定が変わるがここでは省略) - 赤外線リモコン受信モジュール
- Panasonic Eolia リモコン
###ソースコード
前回同様IRremoteのSampleCode(IRrecvDumpV2)を用いて解析しようと思う。
//------------------------------------------------------------------------------
// Include the IRremote library header
//
#include <IRremote.h>
//------------------------------------------------------------------------------
// Tell IRremote which Arduino pin is connected to the IR Receiver (TSOP4838)
//
int recvPin = 11;
IRrecv irrecv(recvPin);
//+=============================================================================
// Configure the Arduino
//
void setup ( )
{
Serial.begin(9600); // Status message will be sent to PC at 9600 baud
irrecv.enableIRIn(); // Start the receiver
}
//+=============================================================================
// Display IR code
//
void ircode (decode_results *results)
{
// Panasonic has an Address
if (results->decode_type == PANASONIC) {
Serial.print(results->address, HEX);
Serial.print(":");
}
// Print Code
Serial.print(results->value, HEX);
}
//+=============================================================================
// Display encoding type
//
void encoding (decode_results *results)
{
switch (results->decode_type) {
default:
case UNKNOWN: Serial.print("UNKNOWN"); break ;
case NEC: Serial.print("NEC"); break ;
case SONY: Serial.print("SONY"); break ;
case RC5: Serial.print("RC5"); break ;
case RC6: Serial.print("RC6"); break ;
case DISH: Serial.print("DISH"); break ;
case SHARP: Serial.print("SHARP"); break ;
case JVC: Serial.print("JVC"); break ;
case SANYO: Serial.print("SANYO"); break ;
case MITSUBISHI: Serial.print("MITSUBISHI"); break ;
case SAMSUNG: Serial.print("SAMSUNG"); break ;
case LG: Serial.print("LG"); break ;
case WHYNTER: Serial.print("WHYNTER"); break ;
case AIWA_RC_T501: Serial.print("AIWA_RC_T501"); break ;
case PANASONIC: Serial.print("PANASONIC"); break ;
case DENON: Serial.print("Denon"); break ;
}
}
//+=============================================================================
// Dump out the decode_results structure.
//
void dumpInfo (decode_results *results)
{
// Check if the buffer overflowed
if (results->overflow) {
Serial.println("IR code too long. Edit IRremoteInt.h and increase RAWBUF");
return;
}
// Show Encoding standard
Serial.print("Encoding : ");
encoding(results);
Serial.println("");
// Show Code & length
Serial.print("Code : ");
ircode(results);
Serial.print(" (");
Serial.print(results->bits, DEC);
Serial.println(" bits)");
}
//+=============================================================================
// Dump out the decode_results structure.
//
void dumpRaw (decode_results *results)
{
// Print Raw data
Serial.print("Timing[");
Serial.print(results->rawlen-1, DEC);
Serial.println("]: ");
for (int i = 1; i < results->rawlen; i++) {
unsigned long x = results->rawbuf[i] * USECPERTICK;
if (!(i & 1)) { // even
Serial.print("-");
if (x < 1000) Serial.print(" ") ;
if (x < 100) Serial.print(" ") ;
Serial.print(x, DEC);
} else { // odd
Serial.print(" ");
Serial.print("+");
if (x < 1000) Serial.print(" ") ;
if (x < 100) Serial.print(" ") ;
Serial.print(x, DEC);
if (i < results->rawlen-1) Serial.print(", "); //',' not needed for last one
}
if (!(i % 8)) Serial.println("");
}
Serial.println(""); // Newline
}
//+=============================================================================
// Dump out the decode_results structure.
//
void dumpCode (decode_results *results)
{
// Start declaration
Serial.print("unsigned int "); // variable type
Serial.print("rawData["); // array name
Serial.print(results->rawlen - 1, DEC); // array size
Serial.print("] = {"); // Start declaration
// Dump data
for (int i = 1; i < results->rawlen; i++) {
Serial.print(results->rawbuf[i] * USECPERTICK, DEC);
if ( i < results->rawlen-1 ) Serial.print(","); // ',' not needed on last one
if (!(i & 1)) Serial.print(" ");
}
// End declaration
Serial.print("};"); //
// Comment
Serial.print(" // ");
encoding(results);
Serial.print(" ");
ircode(results);
// Newline
Serial.println("");
// Now dump "known" codes
if (results->decode_type != UNKNOWN) {
// Some protocols have an address
if (results->decode_type == PANASONIC) {
Serial.print("unsigned int addr = 0x");
Serial.print(results->address, HEX);
Serial.println(";");
}
// All protocols have data
Serial.print("unsigned int data = 0x");
Serial.print(results->value, HEX);
Serial.println(";");
}
}
//+=============================================================================
// The repeating section of the code
//
void loop ( )
{
decode_results results; // Somewhere to store the results
if (irrecv.decode(&results)) { // Grab an IR code
dumpInfo(&results); // Output the results
dumpRaw(&results); // Output the results in RAW format
dumpCode(&results); // Output the results as source code
Serial.println(""); // Blank line between entries
irrecv.resume(); // Prepare for the next value
}
}
###結果
IR code too long. Edit IRremoteInt.h and increase RAWBUF
Timing[100]:
+3450, -1700 + 450, - 400 + 450, -1250 + 500, - 400
+ 450, - 400 + 450, - 400 + 500, - 350 + 500, - 400
+ 450, - 400 + 450, - 400 + 450, - 400 + 500, - 400
+ 450, - 400 + 450, - 400 + 500, -1250 + 450, - 400
+ 450, - 400 + 450, - 450 + 450, - 400 + 450, - 400
+ 450, - 400 + 500, - 400 + 450, -1250 + 450, -1300
+ 450, -1250 + 450, - 400 + 500, - 400 + 450, -1250
+ 450, - 400 + 500, - 400 + 450, - 400 + 450, - 400
+ 450, - 400 + 500, - 400 + 450, - 400 + 450, - 400
+ 450, - 400 + 500, - 400 + 450, - 400 + 450, - 400
+ 450, - 400 + 500, - 400 + 450, - 400 + 450, - 400
+ 450, - 400 + 500, - 400 + 450, - 400 + 450, - 400
+ 450, - 400 + 500, - 400
unsigned int rawData[100] = {3450,1700, 450,400, 450,1250, 500,400, 450,400,
450,400, 500,350, 500,400, 450,400, 450,400, 450,400, 500,400, 450,400, 450,400,
500,1250, 450,400, 450,400, 450,450, 450,400, 450,400, 450,400, 500,400,
450,1250, 450,1300, 450,1250, 450,400, 500,400, 450,1250, 450,400, 500,400,
450,400, 450,400, 450,400, 500,400, 450,400, 450,400, 450,400, 500,400, 450,400,
450,400, 450,400, 500,400, 450,400, 450,400, 450,400, 500,400, 450,400, 450,400,
450,400, 500,400 }; // UNKNOWN 68D13F41
????????????????
さっぱりわからん物が出てきた。
上の英語を読む限り赤外線で送られた情報が長すぎて解析できないような模様。
IRremoteInt.hを編集してRAWBUFを増やせ!!って行ってますね。
#define RAWBUF 101 // Maximum length of raw duration buffer
こんなんになってたのでこうしてやった。
#define RAWBUF 256 // Maximum length of raw duration buffer
コレで受け取れるだろう...多分......
Encoding : UNKNOWN
Code : 9DCF5C22 (32 bits)
Timing[131]:
+3450, -1750 + 400, - 450 + 400, -1300 + 450, - 450
+ 400, - 450 + 400, - 450 + 450, - 450 + 400, - 450
+ 400, - 450 + 400, - 450 + 450, - 450 + 400, - 450
+ 400, - 450 + 400, - 450 + 450, -1300 + 400, - 450
+ 400, - 450 + 450, - 450 + 400, - 450 + 400, - 450
+ 400, - 500 + 400, - 450 + 400, -1300 + 450, -1300
+ 400, -1300 + 450, - 450 + 400, - 450 + 400, -1300
+ 450, - 450 + 400, - 450 + 400, - 450 + 400, - 500
+ 400, - 450 + 400, - 450 + 400, - 450 + 450, - 450
+ 400, - 450 + 400, - 450 + 400, - 450 + 450, - 450
+ 400, - 450 + 400, - 450 + 400, - 450 + 450, - 450
+ 400, - 450 + 400, - 450 + 400, - 450 + 450, - 450
+ 400, - 450 + 400, - 450 + 400, - 500 + 400, - 450
+ 400, - 450 + 400, - 450 + 450, - 450 + 400, - 450
+ 400, - 450 + 400, - 450 + 450, -1300 + 400, -1300
+ 450, - 450 + 400, - 450 + 400, - 450 + 400, - 500
+ 400, - 450 + 400
unsigned int rawData[131] = {3450,1750, 400,450, 400,1300, 450,450, 400,450,
400,450, 450,450, 400,450, 400,450, 400,450, 450,450, 400,450, 400,450, 400,450,
450,1300, 400,450, 400,450, 450,450, 400,450, 400,450, 400,500, 400,450,
400,1300, 450,1300, 400,1300, 450,450, 400,450, 400,1300, 450,450, 400,450,
400,450, 400,500, 400,450, 400,450, 400,450, 450,450, 400,450, 400,450, 400,450,
450,450, 400,450, 400,450, 400,450, 450,450, 400,450, 400,450, 400,450, 450,450,
400,450, 400,450, 400,500, 400,450, 400,450, 400,450, 450,450, 400,450, 400,450,
400,450, 450,1300, 400,1300, 450,450, 400,450, 400,450, 400,500, 400,450, 400};
// UNKNOWN 9DCF5C22
んーー、結局わからんかった......
いろいろ調べてみるとコレでも全部は受け取れてないっぽい.....
ただ最大値256にしたのに131しか受け取れてないってのもわからんが赤外線のこととかこのライブラリにもそれほど詳しくないのでわかりませんでした。
###対策
新たな自分では一からコーディングできそうにもない(えー、ぶっちゃけ勉強するのめんどいし)ライブラリを探してgithubへ......。
##Panasonic製エアコンをArduinoの支配下に置く
ここでいいライブラリを発見!!
ToniAさんのarduino-heatpumpir
どうやらMitsubishi,Toshiba,Panasonicなどのエアコンの赤外線を送れる模様。
早速使ってみる。
###機材
* Arduino uno R3
* IRLED
* タクトスイッチ×3
* 抵抗100Ω
###回路
環境とかモジュールによって回路はことなるので自分で調べてね。
###ソースコード
#include <Arduino.h>
#include <PanasonicHeatpumpIR.h>
#define cool_button 7
#define hot_button 4
#define stop_button 2
void setup(){
// setting button pin mode
pinMode(cool_button,INPUT);
pinMode(hot_button,INPUT);
pinMode(stop_button,INPUT);
// Serial begin speed = 115200
Serial.begin(115200);
}
void loop(){
IRSenderPWM irSender(3); // irSender(IRLEDpinNum);
PanasonicDKEHeatpumpIR *heatpumpIR;
// read button state
unsigned int air_cool_on_status = digitalRead(cool_button);
unsigned int air_hot_on_status = digitalRead(hot_button);
unsigned int air_off_status = digitalRead(stop_button);
//
if(air_off_status == LOW){ // air conditioner off
Serial.println("air off");
heatpumpIR = new PanasonicDKEHeatpumpIR();
heatpumpIR->send(irSender, POWER_OFF, MODE_COOL, FAN_AUTO, 26, VDIR_AUTO, HDIR_AUTO);
//send(irSender,スイッチON,OFF,冷暖房とか除湿,風量,温度,風向(上下),風向(右左));
}else if(air_cool_on_status == LOW){ // air conditioner mode cool
Serial.println("cool on");
heatpumpIR = new PanasonicDKEHeatpumpIR();
heatpumpIR->send(irSender, POWER_ON, MODE_COOL, FAN_AUTO, 26, VDIR_AUTO, HDIR_AUTO);
}else if(air_hot_on_status == LOW){ // air conditioner mode hot
Serial.println("hot on");
heatpumpIR = new PanasonicDKEHeatpumpIR();
heatpumpIR->send(irSender, POWER_ON, MODE_HEAT, FAN_AUTO, 22, VDIR_AUTO, HDIR_AUTO);
}
//delay time between this loop and next loop
delay(500);
}
とりあえず設定に使うやつ書き出しときます。
- POWER (電源)
- POWER_ON (on)
- POWER_OFF (off)
- MODE (モード)
- MODE_AUTO (自動)
- MODE_COOL (冷房)
- MODE_HEAT (暖房)
- MODE_DRY (除湿)
- MODE_ON (自分には不明)
- MODE_OFF (自分には不明)
- FAN (風量)
- FAN1
- FAN2
- FAN3
- FAN4
- FAN5
- FAN_AUTO
- VDIR (風向高さ)
- VDIR_AUTO
- VDIR_UP
- VDIR_MUP
- VDIR_MIDDLE
- VDIR_MDOWN
- VDIR_DOWN
- HDIR (風向左右)
- HDIR_AUTO
- HDIR_LEFT
- HDIR_MLEFT
- HDIR_MIDDLE
- HDIR_MRIGHT
- HDIR_RIGHT
多分使えるはず......
###結果
ちゃんと動いた。
解析せずにACを操作できるなんてマジ便利。
温度とか操作するボタンを実装させれば温度を変化できるけど、温度をほとんどいじらない自分には必要ないので実装はしない。
#次回
ESP8266モジュールがと届いたらAndroidからのWebPostで操作を可能にします。