#contents 2014/02/02からのアクセス回数 &counter; 来週のArduino勉強会に備えて、mbedライクなクラスライブラリlbedをArduinoに移植してみました。 今回移植したクラスは、以下の通りです。((移植と言ってもほとんどArduinoのAPIのラッパーです)) - DigitalOut: LEDなどのデジタル出力ピンクラス - DigitalIn: タクトスイッチなどのデジタル入力ピンクラス - AnalogIn: 可変抵抗などのアナログ電圧を入力ピンクラス - BusOut: LCDデータ出力等のバス出力を行うクラス - Tone: Arduinoのtoneをクラスにしたもの(lbed互換のために追加) - PwmOut: LEDの明るさを変えたり、モータを制御するためのPWM制御クラス(周波数固定版) - I2C: I2Cインタフェースを使って制御を行うためのクラス(一部のみの実装) また、ユーザクラスの例として、以下の2つをlbed版から移植してみました。 - LM73: 温度センサーLM73のクラスを移植(setup対応のみ) - I2cLCD: 勝純一さんが作られたmbed用の [[I2C低電圧キャラクタ液晶モジュール>http://strawberry-linux.com/catalog/items?code=27001]] クラスの移植(setup対応のみ) ** インストール方法 [#e713aa3f] 以下のZIPファイルをダウンロードして、解凍して作成されたlbedフォルダーをArduinoのユーザ用 ディレクトリ(Macの場合には、Document(文書)/Arduino/libraries/に入れる - &ref(Lbed.zip); ** ライブラリの使い方 [#p7189f43] まずは、ライブラリの例題を動かしながら、ライブラリの使い方を説明します。 Arduino IDEを起動し、スケッチの例→Lbed→BlinkLEDを選択します。 以下のようなスケッチが表示されます。 #pre{{ /* Blink Turns on an LED on for one second, then off for one second, repeatedly. This example code is in the public domain. */ #include "lbed.h" // #A // Pin 13 has an LED connected on most Arduino boards. DigitalOut led(13); // #B // the setup routine runs once when you press reset: void setup() { } // the loop routine runs over and over again forever: void loop() { led = ~led; // #C wait_ms(1000); // #D } }} - #A: 最初にlbed.hをインクルードします - #B: DigitalOutのledをピン番号13に作成します - #C: ledの値を逆の値を代入します(1なら0に、0なら1になります) - #D: 1秒待ちます 次にファイルメニュー→マイコンボードに書き込むを選択して、スケッチをArduinoに書き込みます。 ArduinoのLEDが1秒間隔で点滅すれば成功です。 このようにmbedのDigitalOutクラスを使うと直感に合ったプログラムを書くことができます。 ** lbedの例題を動かしてみる [#x9ea6233] 次に、 [[Protosnap Pro Mini>http://www.switch-science.com/catalog/986/]] を使ってLbedに付属のサンプルを動かしてみます。 &ref(ProtoSnap_Pro_Mini.png); 部品とArduino Pro Miniのピンの接続は以下のようになっています。 | 部品のピン | Arduino Pro Miniのピン |h | ボタン | 7 | | 光センサー | A0 | | 緑のLED | 5 | | 青のLED | 6 | | 赤のLED | 3 | | ブザー | 2 | *** ボタンスイッチの例 [#t845b60a] 次の例は、ボタンスイッチを押したときにArduinoのLEDを点灯させる例です。 Protosnap Pro Miniがなくてもブレッドボードでタクトスイッチを使って以下の様に 回路を組み立てれば、簡単に動かすことができます。抵抗には10KΩを使って下さい。 &ref(ButtonSwitch_bread.png); スケッチは、同様にスケッチの例→Lbed→ButtonSwitchを選択します。 #pre{{ /* ButtonSwitch Turns on an LED on when button pushed. This example code is in the public domain. */ #include "lbed.h" // Pin 13 has an LED connected on most Arduino boards. DigitalOut led(13); // Pin 7 has an tact switch on Protosanap Pro Mini. DigitalIn sw(7); // #A // the setup routine runs once when you press reset: void setup() { } // the loop routine runs over and over again forever: void loop() { led = !sw; // #B wait_ms(200); // wait for 200 mili seconds. } }} - #A: 最初のBlinkLEDに変数に加えて、DigitalInのスイッチswをピン7に作成します - #B: swの値はスイッチを押したときに0になりますので、!を付けて逆の値をledに代入します *** 光センサーの例 [#a6427c2f] 光センサーの例題を試してみましょう。 この例題は、AnalogInで光センサーの電圧を取得し、その値でLEDを調整します。 Protosnap Pro Miniを灯りに近づけるとLEDが点灯し、影を作って暗くするとLEDが消灯します。 光センサーが無い場合には、可変抵抗で代用して実験して下さい。 #pre{{ /* LightSensor Turns on an LED on when light sensor > 0.5V(0.1). This example code is in the public domain. */ #include "lbed.h" // Pin 13 has an LED connected on most Arduino boards. DigitalOut led(13); // Pin A0 has a light sensor on Protosanap Pro Mini. AnalogIn sensor(A0); // #A // the setup routine runs once when you press reset: void setup() { } // the loop routine runs over and over again forever: void loop() { if (sensor > 0.1) // #B led = 1; else led = 0; wait_ms(200); // wait for 200 mili seconds. } }} - #A: スイッチの代わりに、AnalogInの光センサーsensorをピンA0に作成します - #B: 電圧が供給電圧の0.1(0.5V)より高い場合には、LEDを点灯し、低い場合は消灯します *** ブザーの例 [#z91a02f5] 次は音の実験です。 Protosnap Pro Miniが無い場合には、圧電ブザーとボタンスイッチ以下の様に接続して実験してください。 &ref(Buzzer_bread.png); 例題には、スケッチの例→Lbed→Buzzerを選択します。 #pre{{ /* Buzzer Sound on an buzzer on when button pressed. This example code is in the public domain. */ #include "lbed.h" int duration = 500; // Pin 7 has an tact switch on Protosanap Pro Mini. DigitalIn sw(7); // Pin 2 has a buzzer on Protosanap Pro Mini. Tone buzzer(2); // #A // the setup routine runs once when you press reset: void setup() { } // the loop routine runs over and over again forever: void loop() { if (!sw) { // #B buzzer.tone(262, duration); // ド, 500 msec wait_ms(500); buzzer.tone(294, duration); // レ, 500 msec wait_ms(500); buzzer.tone(330, duration); // ミ, 500 msec } } }} - #A: LEDの代わりに、Toneのbuzzerをピン番号2に作成します - #B: swが押された(値が0なので、!を付けて真にしています)時にbuzzerのtoneでブザーを鳴らします。~ toneの最初の引数が音の周波数、次がブザーを鳴らす時間をミリ秒で指定します。 ** mbed用のユーザーライブラリーをArduinoで動かす [#w21526d1] Aruino版lbedの目的は、mbed用に作成された多くのユーザーライブラリーをArduinoでも使えるようにすることです。 I2Cを使った以下の2例について、Arduino版への移植方法を説明します。 - LM73温度センサー(lbedで私がI2Cの動作確認に使用する例題) - I2cLCD: mbedで著名な勝純一さんの作成された [[I2C低電圧キャラクタ液晶モジュール>http://strawberry-linux.com/catalog/items?code=27001]] の移植方法 *** ArduinoのI2Cについて [#g5ae1203] 当初、ArduinoのI2Cのピン番号が分からなかったのですが、以下のサイトで、ArduinoのI2C/TWI端子はSCL(アナログ5番ピン)・SDA(アナログ4番ピン)となっていることをしりました。 - http://www.geocities.jp/zattouka/GarageHouse/micon/Arduino/RTC/RTC.htm *** I2Cの移植の注意 [#bd261956] Arduinoでは、I2C用のWireクラスのsetup後でないとI2Cの初期化ができないので、mbedのI2Cを使った ライブラリーをArduinoに移植する場合には、クラスのコンストラクターの処理をsetupメソッドにまとめ、 スケッチのsetupからユーザライブラリーのsetupをコールするようにします。 *** LM73の場合 [#r91016bc] LM73の場合、publicにsetupメソッドを以下の様に追加しました。 LM73.hの変更 #pre{{ class LM73 { public: LM73(PinName sda, PinName scl); /* Arduino 固有のメソッド */ void setup(); }} LM73.cppのLM73での初期設定をsetupに移します。 #pre{{ LM73::LM73(PinName sda, PinName scl) : i2c(sda, scl) { // setup(); } void LM73::setup() { i2c.setup(); char cmd[2]; // LM73設定 cmd[0] = 0x04; // register 4 cmd[1] = 0x60; // 14bit resolution i2c.write( LM73_ADDR, cmd, 2); // ポインタを0にしておく(readするだけで温度が読めるようになる) cmd[0] = 0x00; i2c.write( LM73_ADDR, cmd, 1); } }} 例題にあるスケッチは、以下の通りです。I2Cを使う例では、Wire.hのインクルードが必要になります。 #pre{{ #include "lbed.h" #include "Wire.h" #include "LM73.h" DigitalOut led(13); LM73 lm73(A4, A5); void setup() { Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } Serial.println("Hello World"); lm73.setup(); } void loop() { led = ~ led; float t = lm73.read(); Serial.print("Temp="); Serial.println(t); wait_ms(1000); } }} シリアルモニターの出力例 &ref(LM73-SerialMonitor.png); *** I2cLCDの場合 [#g2750981] 勝さんのI2cLCDも同様に移植しました。 I2cLCD.hの変更 #pre{{ class I2cLCD : public Print { public: I2cLCD(PinName sda, PinName scl, PinName rp); // Arduino用に追加 void setup(); 途中省略 protected: // 追加 Takemoto virtual size_t write(uint8_t c) { _putc(c); return 1; } }} I2cLCD.cppの変更 #pre{{ I2cLCD::I2cLCD(PinName sda, PinName scl, PinName rp) : _i2c( sda , scl ), _rs( rp ) { //setup(); } void I2cLCD::setup() { // このタイミングでセットアップする _i2c.setup(); // コンストラクターの処理を以下に移動 contrast = CNTR_DEF; icon = 0; wait_ms(15); //wait(0.015); // reset LOW->HIGH _rs = 0; wait_ms(10); //wait(0.01); _rs = 1; wait_ms(50); //wait(0.05); writeCommand(FUNC_SET1); writeCommand(FUNC_SET2); writeCommand(INT_OSC); writeCommand(0x70 | (contrast & 0xF)); writeCommand(0x5C | ((contrast >> 4) & 0x3)); writeCommand(0x6C); wait_ms(300); //wait(0.3); writeCommand(0x38); // function set writeCommand(0x0C); // Display On cls(); // Clear Display } }} 勝さんの作られたサンプルmainを元に以下のスケッチで動作を確認しました。 #pre{{ // I2cLCD テストスケッチ 勝さんのサンプルプログラムから移植 #include "lbed.h" #include "I2cLCD.h" #include "Wire.h" I2cLCD lcd(A4, A5, 2); // sda, scl, reset void setup() { lcd.setup(); // print TEXT lcd.print("Dsp test"); lcd.locate(0, 1); lcd.print("Hello World!"); // print ICON lcd.seticon( I2cLCD::Mark ); lcd.seticon( I2cLCD::Battery_1 ); lcd.seticon( I2cLCD::Battery_2 ); lcd.seticon( I2cLCD::Battery_3 ); lcd.seticon( I2cLCD::Battery_4 ); lcd.seticon( I2cLCD::NoSound ); lcd.seticon( I2cLCD::Lock ); lcd.seticon( I2cLCD::ArrowDown ); lcd.seticon( I2cLCD::ArrowUp ); lcd.seticon( I2cLCD::Input ); lcd.seticon( I2cLCD::Alarm ); lcd.seticon( I2cLCD::Tell ); lcd.seticon( I2cLCD::Antenna ); } void loop() { lcd.clearicon( I2cLCD::Antenna ); wait_ms(500); //wait(0.5); lcd.seticon( I2cLCD::Antenna ); wait_ms(500); //wait(0.5); } }} I2cLCDへの電源は、3.3Vを接続してください。 &ref(I2cLCD.png); ** おわりに [#ba2b0368] とても簡単にmbedのユーザーライブラリーをArduinoに移植できることがお分かり頂けたのではないかと思います。 是非、Arduino版lbedをお試し下さい。 ** コメント [#of0e8249] #vote(おもしろかった[1],そうでもない[0],わかりずらい[0]) #vote(おもしろかった[2],そうでもない[0],わかりずらい[0]) 皆様のご意見、ご希望をお待ちしております。 #comment_kcaptcha