NetduinoでI2Cの続きになります。
前回は秋月のリアルタイムクロックモジュールRTC8564NBを使った液晶時計をNetduinoで作ってみました。
今回は、ほぼ同じ機能をもつ液晶時計をArduinoに移植してみました。
一部違うのは、Netduinoでは、1秒割り込みを使って、1秒毎に時刻を拾いにいって表示していましたが、Arduino版では無条件に100ミリ秒毎に時刻を拾いにいっていることです。Arduinoでもピン割り込みの機能はあるのですが、ちょうどキャラクタLCDのピンとぶつかっていて使うことができませんでした。
RTC8564NBのCLKOUT出力(1秒割り込み)は、ArduinoのD7につないで、読み取ってLED(D13)でモニターできるようにしています。
RTC8564NBをArduinoから使うには、なんでも作っちゃう、かも。さんのRTC8564ライブラリ(記事)を使うのが便利でいいのですが、今回は比較の意味もこめて、全部自分で書いています。
ArduinoでI2Cを使うにはWireというライブラリを使います。仕様からすると、マルチマスタは考えられていないようですが、その分、.Net Microframeworkより使い方が簡単になっています。WireライブラリのマニュアルはArduino 日本語リファレンスにあります。
ソースコードです。
思いつきで、同じものをNetduinoとArduinoの両方に実現してみました。VS2010の補完機能になれてしまうと、全部キータイプしないといけないArduinoが不安になってきます(笑)。このくらいのものだと、何で作ってもそうたいした違いはないですが、やはりデバッグ機能のあるNetduinoが安心して作れると思いました。
前回は秋月のリアルタイムクロックモジュールRTC8564NBを使った液晶時計をNetduinoで作ってみました。
今回は、ほぼ同じ機能をもつ液晶時計をArduinoに移植してみました。
一部違うのは、Netduinoでは、1秒割り込みを使って、1秒毎に時刻を拾いにいって表示していましたが、Arduino版では無条件に100ミリ秒毎に時刻を拾いにいっていることです。Arduinoでもピン割り込みの機能はあるのですが、ちょうどキャラクタLCDのピンとぶつかっていて使うことができませんでした。
RTC8564NBのCLKOUT出力(1秒割り込み)は、ArduinoのD7につないで、読み取ってLED(D13)でモニターできるようにしています。
RTC8564NBをArduinoから使うには、なんでも作っちゃう、かも。さんのRTC8564ライブラリ(記事)を使うのが便利でいいのですが、今回は比較の意味もこめて、全部自分で書いています。
ArduinoでI2Cを使うにはWireというライブラリを使います。仕様からすると、マルチマスタは考えられていないようですが、その分、.Net Microframeworkより使い方が簡単になっています。WireライブラリのマニュアルはArduino 日本語リファレンスにあります。
ソースコードです。
#include <LiquidCrystal.h> #include <Wire.h> #define RTC 0x51 LiquidCrystal lcd(12, 11, 5, 4, 3, 2); uint8_t year, month, day, wday, hour, minute, second; const char *weekday[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; // RTC-8564NB // 1pin CLKOE - open // 2pin CLKOUT - Arduino D7 // 3pin INT - open // 4pin Vss - Arduino GND // 5pin SDA - Arduino A4 // 6pin SCL - Arduino A5 // 7pin NC - open // 8pin Vdd - Arduino 5V <<< void setup(){ lcd.begin(16, 2); Wire.begin(); // init as master sendcmd(0x00, 0x20); // stop sendcmd(0x01, 0x00); // Control2 sendcmd(0x0e, 0x00); // Timer Control sendcmd(0x0d, 0x83); // CLKOUT frequency sendcmd(0x02, 0x00); // sec sendcmd(0x03, 0x05); // min sendcmd(0x04, 0x23); // hour sendcmd(0x05, 0x05); // day sendcmd(0x06, 0); // weekday 0:Sun sendcmd(0x07, 0x09); // month sendcmd(0x08, 0x10); // year low sendcmd(0x00, 0x00); // start pinMode(13, OUTPUT); pinMode(7, INPUT); } void loop(){ digitalWrite(13, digitalRead(7)); readTime(); lcd.home(); hex2(0x20); // year high hex2(year); lcd.write('/'); hex2(month); lcd.write('/'); hex2(day); lcd.write(' '); lcd.print(weekday[wday]); lcd.setCursor(0, 1); hex2(hour); lcd.write(':'); hex2(minute); lcd.write(':'); hex2(second); delay(100); } void readTime(void) { Wire.beginTransmission(RTC); Wire.send(0x02); Wire.endTransmission(); Wire.requestFrom(RTC, 7); second = Wire.receive() & 0x7f; minute = Wire.receive() & 0x7f; hour = Wire.receive() & 0x3f; day = Wire.receive() & 0x3f; wday = Wire.receive() & 0x07; month = Wire.receive() & 0x1f; year = Wire.receive(); } void sendcmd(uint8_t addr, uint8_t data) { Wire.beginTransmission(RTC); Wire.send(addr); Wire.send(data); Wire.endTransmission(); } char hexchar[] = "0123456789abcdef"; void hex2(uint8_t x) { lcd.write(hexchar[x >> 4]); lcd.write(hexchar[x & 15]); }
思いつきで、同じものをNetduinoとArduinoの両方に実現してみました。VS2010の補完機能になれてしまうと、全部キータイプしないといけないArduinoが不安になってきます(笑)。このくらいのものだと、何で作ってもそうたいした違いはないですが、やはりデバッグ機能のあるNetduinoが安心して作れると思いました。
ええ、思わずひいちゃうところがありますね。そこを隠すのがライブラリというのは、そのとおりだと思います。
思いつきもしなかった時点で、まだまだ修行が足りないです><。
遠慮せずにどんどんやっちゃっていいのではと思います。
スケッチで直接割込みハンドラを書くと「Arduinoらしくない、、、」なんて事を思っちゃいますが、でもこれをライブラリ化してみんなに公開すれば、「さすがArduino!、やっぱりArduino」なんて評価に変わりますからね(笑)。
ArduinoのD2はPD2(INT0)に、D3はPD3(INT1)につながっているので、attachInterrupt()は外部割込み(INT0, INT1)を使っているみたいです。
他に使えそうなのは、PCINT(pin change interrupt)ですが、Arduinoはサポートしてないみたいです。
直接AVRをたたくみたいなコードを書く必要がありそうですね。