初心者が Arduino ボードを触ってみた
電子工作すらまともにやったことのない私ですが、 Arduino ボードを購入して触ってみました。
Arduino ボードは、ATmega をベースに作られたマイコンボードです。 最近、Arduino 互換の製品が増えてきていることもあり、試してみることにしました。
Arduino ボードは種類がいくつもありますが、今回は、一番メジャーなArduino UNO
を使用します。
Arduino UNO は、公式サイトに以下のとおり記載されています。
Microcontroller | ATmega328P |
---|---|
Operating Voltage | 5V |
Input Voltage (recommended) | 7-12V |
Input Voltage (limit) | 6-20V |
Digital I/O Pins | 14 (of which 6 provide PWM output) |
PWM Digital I/O Pins | 6 |
Analog Input Pins | 6 |
DC Current per I/O Pin | 20 mA |
DC Current for 3.3V Pin | 50 mA |
Flash Memory | 32 KB (ATmega328P)of which 0.5 KB used by bootloader |
SRAM | 2 KB (ATmega328P) |
EEPROM | 1 KB (ATmega328P) |
Clock Speed | 16 MHz |
Length | 68.6 mm |
Width | 53.4 mm |
Weight | 25 g |
今回はIRレシーバを使用し、リモコンを受信テストをしてみます。
配線
配線は、いろいろネットで調べたり、試したりしながら、以下のようにしました。
コーディング
Arduino 公式アプリを使用して、以下の通りコーディングを行いました。
IR受信には、別途ライブラリが必要とのことで、以下のサイトからダウンロードして、配置してます。
https://github.com/z3t0/Arduino-IRremote
#include <IRremote.h> int RECV_PIN = 11; int LED_PIN = 3; IRrecv irrecv(RECV_PIN); IRsend irsend; decode_results results; void setup() { Serial.begin(9600); irrecv.enableIRIn(); pinMode(LED_PIN, OUTPUT); } void storeCode(decode_results *results) { String rcvCode = String(results->value,HEX); Serial.print("0x" + rcvCode + ": "); switch(results->value) { case 0xe730e916: Serial.println("ON!"); digitalWrite(LED_PIN, HIGH); delay(300); digitalWrite(LED_PIN, LOW); break; case 0xe730d12e: Serial.println("OFF!"); digitalWrite(LED_PIN, HIGH); delay(300); digitalWrite(LED_PIN, LOW); break; default: Serial.println("OTHERS.."); } } void loop() { if (irrecv.decode(&results)) { storeCode(&results); irrecv.resume(); } }
アプリから検証とアップロードを行えば、使用可能となります。
テスト
早速試してみると、リモコンを操作したタイミングで、無事にLEDが付きました。
シリアルモニタを開くと、以下の通り、16進数の受信コードと
押したボタンごとの状態表示(ON
・OFF
・OTHERS
の文字列)が表示されることも確認できました。
所感
若干、電圧とか気になりますが、動作したので、一旦気にしない〜
やっていて感じましたが、ITのシステム構築と似てますね。
H/W(各電子パーツ)を購入して、LAN(銅線)引いて、アプリ開発(コーディング)..w
次回は、乾電池使ったりとか、DCモータの制御とか、やろうかなぁ..
余談
ちなみにライブラリに付属してるサンプルアプリで2進数でコードが見れます。
このあたりの記事を見ましたが...電子工作が嫌いになりそうだったので見るのやめましたw
http://cranberrytree.blogspot.jp/2012/11/arduino2.html
http://elm-chan.org/docs/ir_format.html
最終的にコード解析は、ライブラリ付属のIRrecordを使用しました。
/* * IRrecord: record and play back IR signals as a minimal * An IR detector/demodulator must be connected to the input RECV_PIN. * An IR LED must be connected to the output PWM pin 3. * A button must be connected to the input BUTTON_PIN; this is the * send button. * A visible LED can be connected to STATUS_PIN to provide status. * * The logic is: * If the button is pressed, send the IR code. * If an IR code is received, record it. * * Version 0.11 September, 2009 * Copyright 2009 Ken Shirriff * http://arcfn.com */ #include <IRremote.h> int RECV_PIN = 11; int BUTTON_PIN = 12; int STATUS_PIN = 13; IRrecv irrecv(RECV_PIN); IRsend irsend; decode_results results; void setup() { Serial.begin(9600); irrecv.enableIRIn(); // Start the receiver pinMode(BUTTON_PIN, INPUT); pinMode(STATUS_PIN, OUTPUT); } // Storage for the recorded code int codeType = -1; // The type of code unsigned long codeValue; // The code value if not raw unsigned int rawCodes[RAWBUF]; // The durations if raw int codeLen; // The length of the code int toggle = 0; // The RC5/6 toggle state // Stores the code for later playback // Most of this code is just logging void storeCode(decode_results *results) { codeType = results->decode_type; int count = results->rawlen; if (codeType == UNKNOWN) { Serial.println("Received unknown code, saving as raw"); codeLen = results->rawlen - 1; // To store raw codes: // Drop first value (gap) // Convert from ticks to microseconds // Tweak marks shorter, and spaces longer to cancel out IR receiver distortion for (int i = 1; i <= codeLen; i++) { if (i % 2) { // Mark rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS; Serial.print(" m"); } else { // Space rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS; Serial.print(" s"); } Serial.print(rawCodes[i - 1], DEC); } Serial.println(""); } else { if (codeType == NEC) { Serial.print("Received NEC: "); if (results->value == REPEAT) { // Don't record a NEC repeat value as that's useless. Serial.println("repeat; ignoring."); return; } } else if (codeType == SONY) { Serial.print("Received SONY: "); } else if (codeType == RC5) { Serial.print("Received RC5: "); } else if (codeType == RC6) { Serial.print("Received RC6: "); } else { Serial.print("Unexpected codeType "); Serial.print(codeType, DEC); Serial.println(""); } Serial.println(results->value, HEX); codeValue = results->value; codeLen = results->bits; } } void sendCode(int repeat) { if (codeType == NEC) { if (repeat) { irsend.sendNEC(REPEAT, codeLen); Serial.println("Sent NEC repeat"); } else { irsend.sendNEC(codeValue, codeLen); Serial.print("Sent NEC "); Serial.println(codeValue, HEX); } } else if (codeType == SONY) { irsend.sendSony(codeValue, codeLen); Serial.print("Sent Sony "); Serial.println(codeValue, HEX); } else if (codeType == RC5 || codeType == RC6) { if (!repeat) { // Flip the toggle bit for a new button press toggle = 1 - toggle; } // Put the toggle bit into the code to send codeValue = codeValue & ~(1 << (codeLen - 1)); codeValue = codeValue | (toggle << (codeLen - 1)); if (codeType == RC5) { Serial.print("Sent RC5 "); Serial.println(codeValue, HEX); irsend.sendRC5(codeValue, codeLen); } else { irsend.sendRC6(codeValue, codeLen); Serial.print("Sent RC6 "); Serial.println(codeValue, HEX);a } } else if (codeType == UNKNOWN /* i.e. raw */) { // Assume 38 KHza irsend.sendRaw(rawCodes, codeLen, 38); Serial.println("Sent raw"); } } int lastButtonState; void loop() { // If button pressed, send the code. int buttonState = digitalRead(BUTTON_PIN); if (lastButtonState == HIGH && buttonState == LOW) { Serial.println("Released"); irrecv.enableIRIn(); // Re-enable receiver } if (buttonState) { Serial.println("Pressed, sending"); digitalWrite(STATUS_PIN, HIGH); sendCode(lastButtonState == buttonState); digitalWrite(STATUS_PIN, LOW); delay(50); // Wait a bit between retransmissions } else if (irrecv.decode(&results)) { digitalWrite(STATUS_PIN, HIGH); storeCode(&results); irrecv.resume(); // resume receiver digitalWrite(STATUS_PIN, LOW); } lastButtonState = buttonState; }