えーと・・・
Arduinoで行き詰っていたのですが・・・こういうときは気分を変えて・・・
Arduino UNO を触ってみました。
この UNO は、ロボカップ仲間が我が家に遊びに来てくれたときのお土産です。
(つまり、頂き物です。お土産に Arduino を持って来るところが、さすがロボカッパー!!)
せっかく、頂いた UNO ですが、ずっとお蔵入りしていました。
しかし、時は満ちた・・・今こそ封印を解く時・・・
ということで、PCに接続してみました。
Powerの緑LEDが点灯し、オレンジ色のLEDが点滅するのですが・・・
プログラムが転送できません。
ツールメニューのシリアルポートがグレーアウトされたままです。
デバイスマネージャーを開くと・・・
Arduino UNO にビックリマークが付いています。
これをどうにかしないとダメみたい。
FTDIのHPでドライバーをダウンロードします。
http://www.ftdichip.com/Drivers/VCP.htm
ダウンロードしたドライバプログラムを実行してみると・・・
「権限がない」と怒られます。
じゃあ、管理者として実行すると、あっさりプログラムは終了します。
でも、だめ
ググると・・・以下の操作が必要なことが判明しました。
チャームから「PCの設定変更」
↓
「保守と管理」
↓
「回復」
↓
「PCの起動をカスタマイズする」の項目にある「今すぐ再起動する」
↓
PC再起動処理開始
↓
「オプションの選択」の「トラブルシューティング」
↓
「トラブルシューティング」の「詳細オプション」
↓
「詳細オプション」の「スタートアップ設定」
↓
「スタートアップ設定」の「再起動」
↓
再起動途中でキーボードの「7」を押して署名無効モードで起動
↓
デスクトップ右下にテストモードで起動中であることを示す表示が付く
ということで、やってみたのですが・・・
う~ん、なんか変わったような気がしない・・・
ところが、コントロープパネルから、ドライバの更新を実施して、Arduino のIDEのディレクトリ配下にあるDriverディレクトリを指定したら、ドライバのインストールが進みました。
これで、やっと UNO が使えるようになりました。
なんか、関係ないところで、労力と時間を無駄にしてしまいました。
Windows8 恐るべし・・・
で、その UNO に R1350N とNXTを接続してみました。
別に、普通につながります。
そうすると、やっぱり簡易Arduinoじゃダメなのは、8MHzだから・・・なのかなぁ
結局、1チップだけの簡易Arduinoでは、R1350Nを制御できないことが分かりました。
どうも・・・その簡易Arduinoは内部発振のクロック8MHzなので、通信が追い付いてないのではないか・・・という想像です。
まあ、ハードのことは良く分からないのですが・・・もう、ここまできたら一気に行くしかない、と思って、16MHzのArduinoに挑戦です。
(実際には、大したことじゃないけど・・・)
クロックの端子に16MHzの水晶発信子を接続します。
そして、ブートローダの書き込みに ATmegaBOOT_168_diecimila.hex を指定します。
そして、FusesとLock Bits は以下の設定で・・・
Fuses : Extended 0xF8 High 0xDD Low 0xFF
Lock bits : 0xFF
さて、これで、16Mhzで動作する、Arduino Duemilanove もどきになりました。(ハズ)
この Arduino Duemilanove もどきに R1350N を接続します。
そして、I2CでNXTとも接続します。
結果は・・・
はい、動作しました。
ちゃんと、NXTとLCD上に、角度、加速度(X)、加速度(Y)が表示されました。
さらに・・・
今度は、XG1300LをNXTに接続してみます。
同じプログラムを実行してみると、同じように表示されます。
ということで・・・3分の1程度の値段でXG1300Lもどきを作ることができました。
う~ん・・・自己満足!
さて、R1350Nが使えて、NXTとのI2C接続ができたら・・・(復習しただけですけど・・・)
やりたかったのは、慣性センサーであるXG1300Lもどきを安価に作ることです。
現状で(個人輸入をせずに)普通に買えるのかは知りませんが、かつては10,000円程度していました。それを 1/3程度でできれば、大変リーズナブルなセンサーになるかと・・・
で、作業は結構簡単で、ちょっと前の2つの記事の内容を合体するだけです。
NXTとArduinoはI2C接続
ArduinoとR1350Nはシリアル接続
です。
XG1300Lに合わせて、NXTからのI2Cアドレスは 0x02 にしました。
その他も XG1300L に合わせて、角度を読む場合は 0x42 を指定します。
byte Wbuf[] = {0x02, 0x42 };
byte Rbuf[2];
int i=2;
I2CBytes(IN_1,Wbuf,i,Rbuf);
プログラムはこんな感じですね。
これで、Arduino から角度の数値 2byte を送付してもらいます。
Arduino 側では、アドレス 0x02 を監視していて、次の 1byte が 0x42 なら取得した角度の2byte を送り出します。
R1350Nからの読出しは良いとして、リセットはどうするのでしょうか・・・
本来であれば、シリアルでリセットコマンドを書き込むのが正しいようなのですが・・・私のプログラミング技術では無理なようなので、単純にRESET端子をOFF、ONにします。ONの立ち上がりの時にリセットがかかるようです。
まとめると
I2Cアドレス:0x02
角度の読み込み:0x42
加速度センサー(X軸):0x46
加速度センサー(Y軸):0x48
加速度センサー(Z軸):0x4A (使わないけど・・・)
リセット:0x60
これで、とりあえず XG1300L と似た動きができそうです。
プログラムを作って実行させると・・・
ちゃんとNXTにセンサーの値が表示されました。
ここまでは順調です。
Arduino NANO を使用しての実験は、とりあえず成功しました。
で・・・ここからが本題です。
ATMEGA168を使用した、簡易ArduinoでセンサーとNXTを接続してみます。
ブレッドボードに配線してNXTと接続します。
NXTのプログラムを実行すると ERROR になります。
なんで!?
いろいろ確認してみると・・・
単に、使用したブレッドボード用のケーブルの端子が(錆びていたのか)接触不良でした。
接触のよさそうなケーブルに変更して、実行してみると・・・
NXTに数字が表示されるのですが・・・おかしな値です。(4桁とか・・・)
センサーを回転させても、数字が変わったり変わらなかったり・・・ダメだ!!
そもそも、通信が遅いです。
いろいろやったけど、明確な原因は不明です。
いまのところの、想像では、8MHzのArduinoでは、シリアルの高速通信が追い付いていないのではないかと・・・
ということで、気が向いたら続きをやりたいと思います。
それでは、今度は Arduino から NXT にデータを送るサンプルです。
I2Cアドレスは 0x62 で、0x20 から 2バイトを読む、というようなプログラムです。
NXT側
#define I2C_PORT IN_1
int getData()
{
byte Wbuf[]={ 0x62,0x20 };
byte Rbuf[2];
int i=2;
int data;
I2CBytes(I2C_PORT, Wbuf, i , Rbuf);
data = Rbuf[0]+(Rbuf[1]<<8);
return (data);
}
task main()
{
SetSensorLowspeed(I2C_PORT);
ClearScreen();
NumOut(40,LCD_LINE6,getData());
Wait( 2000 );
}
Arduino側
#include < Wire.h >
#define I2C_SLAVE_ADDRESS 0x31
byte requestRegister, requestCommand;
void requestEvent()
{
byte d[2];
int j=-256;
if (requestRegister == 0x20)
{
d[0]=j & 0xff;
d[1]=j >> 8;
Wire.write(d,2);
}
}
void receiveEvent(int howMany)
{
requestRegister = Wire.read();
}
void setup()
{
Wire.begin(I2C_SLAVE_ADDRESS);
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
}
void loop() { }
これで、NXTとArduinoの双方の通信ができるようになりました。
上の例では、単純に-256という数値をArduinoがNXTに返します。
この部分を、Arduinoに接続したセンサーの値を返すようにすれば、沢山のセンサーを接続することができます。
ところで・・・
上の例では、NXT側は Arduino側から 2byte のデータを受け取ります。
NXT側ではあらかじめ
I2CBytes関数の第3パラメータに2を指定して2byteをうけとります。
勿論 Arduino側でも、2byteを送出します。
だから問題は無いのですが・・・
例えば、I2CBytes関数の第3パラメータで何byteを受け取るかは、Arduino側には渡るのでしょうか? 普通のI2Cセンサーの場合は、読み出すレジスタ番号と何byte読み出すかを指定すれば、連続で読みだすことができます。 これと同じことがArduinoではできるのでしょうか? それともできないのでしょうか?
例えば、NXT側は2byteを受け取る、Arduino側は4byteを送出する・・・このようにして通信してみても、特に問題は無いようです。
じゃあ、今度は、NXT側は4byteを受け取る、Arduino側は2byteを送出します。
そうすると、特にエラーや処理待ちにはならずに、2byteが正しく送られて、残りの2byteは0xFFが返されます。
そうすると、Arduino側からは多めにデータを送出しておけば良いってことなのかなぁ。
既に、何度か自分でも書いていますし、他のブログでも丁寧に解説されていますので、この記事は単なる自分の備忘録のつもりです。
Mindstorms NXT には入力ポートが4つしかありません。
ですので、普通に考えると4つのセンサーしか接続できません。
M&Yが RoboCupJunior に参加した頃の 2007年のレスキュー競技でも 4個のセンサーでは十分ではなかったと思います。それでも、重ね技とかを駆使して、みんな何とかしていました。(最近では、ポートスプリッタですね)
しかし、ある時、NXTにセンサーコントローラとして、AVRを接続することができることを知りました。(それ以前に、2007年のアトランタ世界大会で、すでにスペインのレスキューチーム「Complbot」が、それを実現していました。やっぱり、すげ~!)
それが、NicoSensor です。
このキットとの出会いが、その後の M&Y の活動に大きく影響しました。
この NicoSencor 自体は、自作用のセンサーを1個接続できるだけなので、ポート数の拡張には役に立たなかったのですが、このプログラムを解析してちょっと改造すれば、いくつでもセンサーを接続できることが分かりました。
で、その時には、直にAVRのプログラミングをして研究していたのですが・・・おかげで、私とYは AVR のプログラムがちょこっと書けるようになりました。
今は、同様のことが Arduino を使ってできますので、とっても手軽になりました。
はい、前置きが長くなりました。
ここからが本文です。
NXT と Arduino を接続して I2C で通信します。
(M&Yでは、I2Cを「あいすくえあどしー」と発音します。)
接続するのは4本の線です。
NXT(緑:VCC) - (VCC) Arduino
NXT(赤:GND) - (GND) Arduino
NXT(黄:SCL) - (A5) Arduino
NXT(青:SDA) - (A4) Arduino
さらに、A4、A5の2つは 100KΩの抵抗でプルアップします。
配線は、これだけです。
まずは、NXT からデータを Arduino に送るサンプルです。
Arduino の I2C アドレスを 0x62、書き込むアドレスを 0x42 にします。
ここに 0x11 を書き込むと LED を点灯し、0x10 を書き込むと LED を消灯するプログラムです。
NXC側
#define LED_ON 0x10
#define LED_OFF 0x11
#define I2C_PORT IN_1
void sendCom(const byte cmd)
{
byte Wbuf[3]={0x62,0x42,0x00};
byte Rbuf[];
int n=0;
Wbuf[2]=cmd;
I2CBytes(I2C_PORT, Wbuf, n, Rbuf);
}
task main()
{
SetSensorLowspeed(I2C_PORT);
while (TRUE)
{
sendCom(LED_ON);
Wait(200);
sendCom(LED_OFF);
Wait(800);
}
}
Arduino側
#include < Wire.h >
#define I2C_SLAVE_ADDRESS 0x31
#define LED_RED 13
#define RED_ON 0x10
#define RED_OFF 0x11
byte requestRegister, requestCommand;
void receiveEvent(int howMany) {
requestRegister = Wire.read();
if (Wire.available() > 0) {
requestCommand = Wire.read();
if (requestRegister == 0x42)
if (requestCommand == RED_ON)
digitalWrite(LED_RED, HIGH);
else if (requestCommand == RED_OFF)
digitalWrite(LED_RED, LOW);
}
}
void setup() {
pinMode(LED_RED, OUTPUT);
digitalWrite(LED_RED, LOW);
Wire.begin(I2C_SLAVE_ADDRESS);
Wire.onReceive(receiveEvent);
}
void loop() {
}
これを実行すると、NXT側の指示で Arduino の LED が1秒ごとに点滅します。
過去に実験したことをもう一度やっただけなので、すんなりいくはずだったのですが・・・
世の中そんなに甘くありません。
Arduino の A4、A5 には 10kΩ の抵抗が付いていたのですが・・・このままだと、なぜかデータが 1byte しか NXT に渡りません。2byte 目以降が 0xff になりました。
原因は良く分かりませんが、プルアップしていた 10kΩの抵抗を外すと、ちゃんとデータが渡せます。それで、NicoSensor の回路図を確認して、とりあえず 100kΩの抵抗を入れました。
それと、上のサンプルプログラムですが・・・これが正解なのかは知りません。
とりあえず、目的の動作はします。
・・・という程度のものです、悪しからず・・・
以前に購入した R1350N ですが・・・
サンプルプログラムが動作することを確認して、それ以降放置していました。
先日、「ハイテク、ロ-テク」の記事を書いた後に・・・
そういえば、M&Yも高価なジャイロセンサーを使っていたなぁ
というのを思い出して、その技術を安価に実現できないか研究をしてみようと考えました。
まず・・・M&Yのロボットに搭載していたジャイロセンサーは CruizCore® XG1300L というものです。発売当時は、結構話題になりました。日本でも普通に買えていたのですが・・・いつのまにか簡単には購入できなくなったようです。正確には購入できなくなったわけではなく「簡単に購入ができない」です。
XG1300L は MICROINFINITY という会社(韓国の会社!?)の製品ですが、日本支社をクローズしてしまったのが原因のようです。
で、今、普通に買うとしたら、本社(韓国!?)から個人輸入するしかなさそうです。
ここで購入すると、価格85USD+送料25USDで合計110USDなのですが・・・
今は円安なので、結構な値段ですよね。(以前は 9,000円位で購入したような記憶が・・・)
で・・・その XG1300L の中身と思われるモジュールも売られています。
それが、R1350Nです。
X1300Lに比べて、こちらの方が安いと思うのですが・・・価格は 170USD もします。
しかし・・・何故か・・・この R1350N は、スイッチサイエンスで 3,394円 で販売されています。
この価格のからくりが、良く分かりません。
でも、とにかく、私たちはスイッチサイエンスで購入しました。
ここまでで、長い前置きが終了です。(苦笑)
これまで、スイッチサイエンスのHPにあった(リンクされていた)記事のサンプルプログラムを動作させて「動いた、動いた」と満足していたのですが・・・そろそろ、ちゃんと動作を理解しようと重い腰を上げました。
R1350NとArduinoはシリアル通信で接続します。
接続は簡単で、R1350Nには、VCCとGND、そして TX を Arduino の RX0 に接続します。
つまり、電源とGND以外には、配線は1本だけです。
ただし、この1本が曲者で、この線(RX0に接続した線)を外さないと、Arduinoへの書き込みができません。
ですから、Arduinoへの書き込みの度に、RX0への配線を外します。(面倒くさい・・・です)
R1350Nは 115200bps のシリアル通信をします。
一組のデータは15バイトです。
1-2: 信号の始まり 0x00AA
3: インデックス
4-5: 角度(0.01度単位で100倍した値)
6-7: 角速度(0.01度/秒単位で100倍した値)
8-9: x軸加速度(1mg単位)
10-11: y軸加速度(1mg単位)
12-13: z軸加速度(1mg単位)
14: 予約
15: チェックサム(3-14バイトのデータの合計の下位バイト)
となります。
サンプルプログラムを解析(するほどでもないけど)した結果・・・
・シリアル通信で、データの受信を待ち
・最初の2バイトが 0xaa,0x00 であることを確認して
・残りの13バイトを取り込む
・最後にチェックサムを確認して取り込んだ13バイトが正しい場合に、LCDに値を表示する
単純に書くとこのような動きですね。
これを、自分なりに整理して簡略化したのが、以下のプログラムです。
#include < LiquidCrystal.h >
byte buffer[15];
LiquidCrystal lcd(6,7,8,9,10,11,12);
void setup() {
Serial.begin(115200);
lcd.begin(16, 2);
}
void loop() {
byte data;
int sum,i;
static int state = 0;
static int index = 0;
while(Serial.available() == 0);
data = Serial.read();
if(state == 0) {
if(data == 0xaa)
state++;
}
else if(state == 1) {
if (data == 0x00)
state++;
else {
state = 0;
index = 0;
}
}
else {
buffer[index++] = data;
if (index >= 13) {
sum = 0;
for (i = 0; i < 11; i++)
sum += buffer[i];
if ((sum & 0xff) == buffer[12]) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("A:");
lcd.print((buffer[2] << 8) | buffer[1],DEC);
delay(100);
Serial.flush();
}
state = 0;
index = 0;
}
}
}
これで、角度(×100の値)がLCDに表示されます。
ただし、上に書いたように、Arduinoへの書き込みの時には RX0 の配線を外して、書き込みが終わったら RX0 を接続します。その後に R1350N の電源を入れなおすと、やっと正しく動作します。
で、実際に動作しているところを見てみると・・・このセンサーは優秀ですよね。
普通のジャイロセンサーなら、見ていると少しづつ値がズレていきます。(ドリフトと言うのでしたっけ!?)
でも、R1350Nは、時間が経過しても、ほとんどズレません。
先日、部屋の片づけをしていたら、AVRへの書き込みを行う AVRISP mkII が出てきました。
そういえば、昔よく使っていたなぁ…
前は、直接AVRのプログラムを書いていたのですが・・・いつの間にかそれを使わなくなり、簡単な Arduino に移ってしまいました。(怠惰な人間は、安易な方向に流れる・・・笑)
ついでに、部品箱の中の AVR(ATMEGA) をいくつか見つけました。
おそらく、どれかはArduinoのブートローダーを書き込んでいると思うのですが・・・調べるのも面倒です。
そこで・・・
全部に Arduino のブートロ-ダを書き込んでしまおう!!
ということにしました。
まず・・・ブートローダーの書き込み方から忘れているので・・・
いつも参考にさせていただいているのがこちらです。
こちらのHPの内容を参考にさせてもらって、Arduinoのブートロ-ダーを書き込むのですが・・・
まず、AVR Studio をダウンロードしなければなりません。
ダウンロードするには、ユーザー登録をしなければなりません。
と・・・面倒なので、古いPCを持ち出して、そこに入っている AVR Studio を使いました。そのPCは Windows XP ですが・・・ネット接続しなけりゃ問題無いですよね・・・
もう、基本の操作も忘れているのですが・・・さっきのHPを確認しながら、1つ1つ書き込みました。
家にあったAVRは ATMEGA 168 と 328 と 88 です。
88 は(標準では!?)Arduinoにならないので、外しました。
168Pが7個、328Pが2個あったので・・・全部 Arduino にしちゃいました。
168と328は、書き込むブートロ-ダーのプログラムが違うし、Flash と Lock bits が異なります。以前に、Flash と Lock bits が違うことを知らずに、長い時間悩みました。
まあ、とにかく・・・
どれが Arduino で、どれが Arduino で無いか、悩まなくて済むようになりました。(笑)
ぜ~んぶ Arduino!!
I2C接続のセンサーは、同じ信号線に複数のセンサーを接続することができます。
ただし、異なるアドレスに変更しなければなりません。
だから、同じセンサーを2個使いたい場合は、片方のアドレスを変更します。
アドレスを変更した場合は、変更したアドレスを覚えておく(記録しておく)のですが・・・
これを忘れてしまうと、後々使えなくなってしまいます。
でも、そんなときに使うのがこれ・・・ i2c_scanner です。
これは、Arduinoに接続した、i2c機器のアドレスを調査してくれるプログラムのようです。
プログラムを動作させて、シリアルモニタを見ていると・・・
I2C Scanner
Scanning...
I2C device found at address 0x68 !
done
こんな感じで、アドレスを教えてくれます。
普通は2倍にするので、0xd0 ということですね。
いつも忘れるので、毎回調べるのが・・・
A4がSDA(データライン)
A5がSCL(クロックライン)
さて、GP2Y0E03 をアナログ出力で使うのは簡単です。
単に Vout の出力をアナログポートで読み出すだけです。
まあ、電源電圧が3.3Vなので、レギュレータなどで降圧する必要はありますが・・・
で、このセンサーの素晴らしいところは、計測した距離に対して、出力の電圧が線形になることです。
データシートのグラフはこのようになっています。
x=(long)analogRead(2)*5.0/1024;
y=-26.7*x+63.3;
こんな感じの変換式で、距離が分かります。
これまでの、シャープの測距モジュールは、アナログ出力が線形で無いため、いくつもの場合分けが必要でした。 さらに、出力のグラフが山形だったので、出力の電圧だけでは、計測した距離が、近いのか遠いのかが分からないというおまけ付きでした。
ちなみに、私は、この SHARPセンサー を PSD と呼んでいたのですが・・・
赤外線を受光する部分がPSDであり、赤外線を発する部分とPSDが組み合わされて、このSHARPセンサーが構成されている、というのが正しいようです。
ところで、一番の興味は、このめっちゃ小型の距離センサーが、超音波センサーの代りとして使えるのか・・・ということなんですが・・・
私が実験した限りでは、センサーとして性能(正確性)は超音波センサーの勝ちだと思います。
(出力の値が、けっこう振らつきます。 アナログだから仕方がないのかも・・・)
I2Cでの計測の実験をしていないので、まだ何とも言えませんが・・・
大きさや価格は、大変魅力的なのですがねぇ。
先日、秋月で赤外線式の距離センサーを買ってきました。
これもいわゆるシャープセンサーなんでしょうか!?
実物を手に取って、最初に驚いたのがその大きさ(小ささ)です。
17mm×11mmです。(単位はmmで合っています、cmじゃありません)
めっちゃ小さいです!!
LEGOと比べてみてください。 その大きさ(小ささ)が分かります。
もし、これが超音波センサーの代わりに使えれば・・・小型軽量化に役立つと思うのですが・・・
じゃあ、早速実験してみます。
電源は(5Vではなく)3V系のようなので、三端子レギュレータで3.3Vに降圧します。
さて、アプリケーションノートを参考に配線します。
①VDD
②GND
③Vout
ということで配線をして、Voutの値をArduinoの analogRead() で値を測るのですが・・・
なんだか数値が安定しないし、そもそも距離が測れているように見えません。
で・・・よく見たら・・・
アプリケーションノートの GP2Y0E02A の部分を見てました。
(つまり違うセンサーの端子の説明を見てました)
GP2Y0E03の端子は
①VDD
②Vout
③GND
と、先ほどのセンサーとは、②③が逆になっていました。
(同じ系列のセンサーなんだから、並びを統一しておけよ)
で、改めて配線をしなおすと、あっさりと計測ができました。
とっても簡単で、とっても面白いので
マイコン内蔵RGBを追加で買ってきて、8個のLEDを並べて表示してみました。
8個のLEDを1本の信号線で制御できるのが・・・すごいですね。
(あとは、5VとGNDの2本の合計3本だけ)
8個並べたLEDの光を右に流したり、左に流したり・・・
色を変えたり・・・
ソフトで制御できるのが「M&Y」向きです。
しかし・・・電源を入れた直後は、すべてのLEDが白く光ります。
(白く光るということは、赤、緑、青の3つの発行体が同時に光るということ)
そうすると、きっと結構な消費電力になりますね。
Arduinoのスタートアップが終わって、LEDの制御が始まればLEDが消灯するのですが・・・
電源を入れたら点灯ではなくて、電源を入れても消灯(したまんま)にできないでしょうか!?
せっかく、秋月電子で買ってきた マイコン内蔵RGB LED ですが・・・
自分で、制御プログラムを作れないか、いろいろとやってみましたが・・・
私の技術ではどうにもできないようです。
制御の仕組み自体は簡単で・・・「0」に当たる信号と「1」に当たる信号を1つのLEDに付き24ビット分送付するだけです。
しかも、その24ビットも単純にRGBのそれぞれに当たる明るさ(強さ)を送るだけです。
しかし、この「0」に当たる信号と「1」に当たる信号のタイミングが短すぎて、普通のArduinoの命令では実現が難しいようです。
(サンプルプログラムでは、アセンブラを利用しているようです)
最初は、ループとかで、短いタイミングのWaitを作れば良いのでは・・・とやってみたのですが、どうもうまくいきません。
ということで、独自で作ることはあきらめました。
ネットにある、サンプルのスケッチを使って、プログラミングをすることはできそうです。
例えば
#include Adafruit_NeoPixel TestLED = Adafruit_NeoPixel(4, 3, NEO_GRB + NEO_KHZ400);
void setup() {
TestLED.begin();
TestLED.show();
}
void loop() {
TestLED.setPixelColor(0, TestLED.Color(32,0,0));
TestLED.setPixelColor(1, TestLED.Color(0,32,0));
TestLED.setPixelColor(2, TestLED.Color(0,0,128));
TestLED.setPixelColor(3, TestLED.Color(32,32,32));
TestLED.show();
}
こんな感じです。
とにかく、信号線1本で、いくつものLEDを制御できるので・・・
なかなか便利です。
写真では、きれいに色が分かれていませんが・・・
ちゃんと、緑、赤、青、白に光ります。
同じパワーだと、青がちょっと暗いですかねぇ。
(というか、赤や緑が眩しすぎる・・・)
もちろん、フルカラーなので、中間色なども自由自在です。
秋月電子で、「マイコン内蔵RGB 5mmLED PL9823-F5」というLEDを買ってきました。
フルカラーのLEDですが、マイコンが内蔵されていて、色のコントロールは一本の信号線でできてしまうらしいです。
写真のように、LEDから足が4本出ています。
2本はVCCとGNDです。 そして残りの2本が制御用の信号線の IN と OUT です。
で・・・
秋月のHPには、「Arduinoのサンプルスケッチが使えます。」と書かれていたので、簡単に制御できるのかと思いきや・・・
まず、そのサンプルスケッチがどこにあるのかがわかりません。
散々さがして・・・
Adafruit_NeoPixel-master.zip
というファイルを見つけました。
さて、見つけたのは良いけど、これをどうすれば使えるのでしょうか!?
あーでもない、こーでもない、と散々苦労したあげく・・・
結論からすると・・・
解凍したファイルをディレクトリごと、Arduinoのツールの librariesというディレクトリに格納すれば良かったのです。
そして、examples のディレクトリ配下にある ino ファイルをArduinoで実行すれば、サンプル的な動作ができました。
あ~、たったこれだけのことに、どれだけ時間を費やしたか・・・
もう、本当に・・・最後は、自分で一から組むしか無いのかと、絶望しましたよ・・・
一応、データシートを見て、「なるほど、0と1を送り込んでやれば良いのね」なんて、安易に考えていたら・・・
0の時のON時間は0.35μs、OFF時間は1.36μsって・・・
そんな短い時間のWaitはどうやって、やるのでしょうか!?
と・・・サンプルプログラムを解析していったところで、途中でアセンブラのコードが出てきて頓挫です。(苦笑)
さて、届いたジャイロセンサーR1350N を使ってみました。
まず・・・
2mmという特殊なピッチの半穴の入出力端子をどうするか・・・ですが・・・
同時に、専用のピッチ変換基盤を買っておいたので、問題ありません。
変換基盤を重ねて(ずれないようにテープで止めてから)直接ハンダ付けしました。
そして、ヘッダーピンも付けました。
(歳だからか・・・ハンダ付け作業がすごく億劫です)
これで、ブレッドボードに挿せます。
実験ができる状態になりました。
それでは、早速やってみます。
といっても、参考にしたHPに何から何まで書かれているので、ほとんど苦労はしませんでした。
Arduinoとの接続は、3本の配線だけです。
R1350NのVCCを+5Vに
R1350NのGNDをGNDに
そして、R1350NのTXを ArduinoのRx0に、接続します。
プログラムは、そのHPに書かれているものをそのまま使ってみました。
実行してみようとすると・・・エラーになります。
どうも、転送エラーのようです。
う~ん
で、何が悪かったのかというと、Arduinoへの書き込みの時に、Rx0の配線を抜かないとダメなようです。
つまり、書き込みの時にRx0の配線を抜きます。
実行するときには、Rx0の配線を挿します。
面倒臭い・・・
まあ、とにかく、プログラムを書き込んで実行してみました。
はい、あっさり動きました。
LCDにA(回転角)、XYZ(それぞれの傾き)が表示されます。
やっぱり、なかなか正確です。
回転した角度を算出するために、ソフトで積分を繰り返さなければならない他の(普通の)ジャイロセンサーとは違いますねぇ。
R1350Nに、単純な Arduino を組み合わせて、NXT専用のジャイロセンサー(おまけに3次元加速度センサー付き)を作れば、コストパフォーマンスの良いセンサーができそうです。