Arduino 6) トラッキングセンサーを使ってみる。
2016.12.03
Arduino 5) タイマー処理を考える。
2016.11.28
タイマー処理は特定の周期でプログラムを実行させたいときにとても便利な機能です。
単純に待ち時間を設けたいだけならdelay()を指定するだけでいいのですのが、
プログラムが複雑になってくるとコードが汚くなるだけでなく、
正確なタイミングでコードを走らせることも難しくなっていきます。
そこでタイマーによるインタラプト処理を試してみました。
MsTimer2.zip
http://playground.arduino.cc/Main/MsTimer2
このコードを作るに当たって、ちょっと悩みました。
LCDの表示をtimercount()内に記述しても実行されないのです。
なぜかスルーされます。
loop()内に書くことで上手く表示されました。
追求すると沼にハマりそうなので、ここはそういう物という理解でいきます。
ただ、Windows系のプログラムに慣れてしまうと、これだけではちょっと物足りないですね。
できれば、タイマーを複数同時に走らせたいところ。
そこで調べてみると、複数同時に動かせるライブラリがあるようですね。
マルチタスクが実装されていないArduinoでどのように実現しているのでしょう?
Metro-Arduino-Wiring-master.zip
http://playground.arduino.cc/Code/Metro
2つ同時に動くタイマーを記述してみました。
どこまで正確に時を刻んでいるかは謎ですが、うまく機能しているようです。
でも、求めている物が微妙にちがう。
このライブラリは割り込みが起きたときのフラグを保持して
loop()内で判別して処理するというもの。
こうなるとloop()内に重い処理を書いてしまうと、
正確な時間を刻むことは難しい。
一長一短ですねぇ。
結局は最初に実験したMsTimer2.hを駆使し、
コーディングでなんとかするしか無さそうです。
先人のソースコードを沢山読み解けば
もっといい書き方があるのかもしれませんが・・・
単純に待ち時間を設けたいだけならdelay()を指定するだけでいいのですのが、
プログラムが複雑になってくるとコードが汚くなるだけでなく、
正確なタイミングでコードを走らせることも難しくなっていきます。
そこでタイマーによるインタラプト処理を試してみました。
MsTimer2.zip
http://playground.arduino.cc/Main/MsTimer2
このコードを作るに当たって、ちょっと悩みました。
LCDの表示をtimercount()内に記述しても実行されないのです。
なぜかスルーされます。
loop()内に書くことで上手く表示されました。
追求すると沼にハマりそうなので、ここはそういう物という理解でいきます。
ただ、Windows系のプログラムに慣れてしまうと、これだけではちょっと物足りないですね。
できれば、タイマーを複数同時に走らせたいところ。
そこで調べてみると、複数同時に動かせるライブラリがあるようですね。
マルチタスクが実装されていないArduinoでどのように実現しているのでしょう?
Metro-Arduino-Wiring-master.zip
http://playground.arduino.cc/Code/Metro
2つ同時に動くタイマーを記述してみました。
どこまで正確に時を刻んでいるかは謎ですが、うまく機能しているようです。
でも、求めている物が微妙にちがう。
このライブラリは割り込みが起きたときのフラグを保持して
loop()内で判別して処理するというもの。
こうなるとloop()内に重い処理を書いてしまうと、
正確な時間を刻むことは難しい。
一長一短ですねぇ。
結局は最初に実験したMsTimer2.hを駆使し、
コーディングでなんとかするしか無さそうです。
先人のソースコードを沢山読み解けば
もっといい書き方があるのかもしれませんが・・・
Arduino 4) LCD2004のケースを作った。
2016.11.27
机の上で煩雑に実験をしていると、
LCD2004の基盤がむき出しなのは危険なんじゃないかな
と思いましてケースを作成してみました。
いつも通りAutodesk Fusion360で設計します。
ABSで作るので、基板の周りに四方1mm程度の余裕もって作りました。
ネジ穴もABSの収縮でズレる可能性があるので、ドリルで後から開けることにします。
配線も抜けないようにガイドを付けようかとも考えたのですが、
テスト用のものなので抜き差しできないと逆に不便かと思い
横に切り欠きを付けるだけのシンプル構造にしてます。
これを3Dプリンターで印刷。
思いのほか綺麗に仕上がりました。
実はこれは2作目で、1作目はガラス面から剥離してしまい、
反りが発生してエライことになってしまいました。
2作目は収縮もほとんどなく、綺麗に仕上がっています。
基板を固定する穴は、基板を照らし合わせながら2.5mmのドリルで開けてます。
ネジは、廃品処理したノートパソコンから取り集めたネジを流用。
横から見た図。配線止めは上から押さえつける感じで作りました。
ABSの熱収縮で大きさが狂ったとしても、ヤスリ掛けで調整しやすいのでこの形をとってます。
ヤスリ掛け部分が見えたら格好悪いので、上蓋は配線止めの部分を少し覆うようにデザインしてます。
設計時、上蓋はドリルで固定穴を付け、ネジで固定するつもりでしたが、
頻繁に蓋を開けることがあるかもしれないと考え直し、落ち着くまでは両面テープで止めます。
これで完成です。
テーブルにコーヒーを置くことが多いのですが、
これで少しはショートさせることなく実験できる?( ´艸`)
LCD2004の基盤がむき出しなのは危険なんじゃないかな
と思いましてケースを作成してみました。
いつも通りAutodesk Fusion360で設計します。
ABSで作るので、基板の周りに四方1mm程度の余裕もって作りました。
ネジ穴もABSの収縮でズレる可能性があるので、ドリルで後から開けることにします。
配線も抜けないようにガイドを付けようかとも考えたのですが、
テスト用のものなので抜き差しできないと逆に不便かと思い
横に切り欠きを付けるだけのシンプル構造にしてます。
これを3Dプリンターで印刷。
思いのほか綺麗に仕上がりました。
実はこれは2作目で、1作目はガラス面から剥離してしまい、
反りが発生してエライことになってしまいました。
2作目は収縮もほとんどなく、綺麗に仕上がっています。
基板を固定する穴は、基板を照らし合わせながら2.5mmのドリルで開けてます。
ネジは、廃品処理したノートパソコンから取り集めたネジを流用。
横から見た図。配線止めは上から押さえつける感じで作りました。
ABSの熱収縮で大きさが狂ったとしても、ヤスリ掛けで調整しやすいのでこの形をとってます。
ヤスリ掛け部分が見えたら格好悪いので、上蓋は配線止めの部分を少し覆うようにデザインしてます。
設計時、上蓋はドリルで固定穴を付け、ネジで固定するつもりでしたが、
頻繁に蓋を開けることがあるかもしれないと考え直し、落ち着くまでは両面テープで止めます。
これで完成です。
テーブルにコーヒーを置くことが多いのですが、
これで少しはショートさせることなく実験できる?( ´艸`)
Arduino 3) 頻繁に起きる再起動を探る
2016.11.19
今使っているArduinoUNO R3
使い始めたころから、突然再起動がかかるのです。
なにぶん、何も知らないところからのスタートなので、
これも仕様通りなのだろうと思っていました。
例えば、
void setup(){} に試験的なコードを書き、
void loop(){} の部分を空欄にしておくと、
setupに記述した処理を終えた後
何も動かすコードがないので、一定時間過ぎた後再起動するのでは?
なんて無知ゆえ甘いことを考えていたのです。
ところがloopに、1秒ごとカウントするコードを書いて、
永遠に終わらない処理をさせてみたところ
不定期に再起動が起きることを確認しました。
つまりプログラム的なものではないな・・と
PCのUSBポートから給電させて動かしているのですが、
PC側のArduinoIDE又はドライバが定期的に再起動信号を送っているのか?
なんてことも考えたわけですが、事態は簡単に解決いたしました。
外部給電ソケット端子に、9V角形乾電池を接続すると症状は再現しませんでした。
あと、別のPCに接続してみても症状は再現しませんでした。
つまりは、私のPCのUSBで電力を十分に供給できていないということのようです。
結構デリケートなのね。LCDが思った以上に食うのかしら?
ではUSB接続しながら外部電源を接続した場合はどうなるのか?
ダブル電源カッケー!なんて中二病みたいな事にはならないようです。
外部電源端子に推奨されているのは7V~12V
7V以上外部から供給された時点でUSB給電を止め外部電源に切り替わるようだ。
外部から7V以上入れても、
三端子レギュレータで5Vに減圧されて使われるので問題ない。安定は9Vと言われているようで、多少熱はでるが12Vでも問題ないという話。
ということで手軽に実験するのであれば、
十分に電力を供給できるUSBポートを使うか、
9Vのアダプタ又は乾電池を使う必要がある。
使い始めたころから、突然再起動がかかるのです。
なにぶん、何も知らないところからのスタートなので、
これも仕様通りなのだろうと思っていました。
例えば、
void setup(){} に試験的なコードを書き、
void loop(){} の部分を空欄にしておくと、
setupに記述した処理を終えた後
何も動かすコードがないので、一定時間過ぎた後再起動するのでは?
なんて無知ゆえ甘いことを考えていたのです。
ところがloopに、1秒ごとカウントするコードを書いて、
永遠に終わらない処理をさせてみたところ
不定期に再起動が起きることを確認しました。
つまりプログラム的なものではないな・・と
PCのUSBポートから給電させて動かしているのですが、
PC側のArduinoIDE又はドライバが定期的に再起動信号を送っているのか?
なんてことも考えたわけですが、事態は簡単に解決いたしました。
外部給電ソケット端子に、9V角形乾電池を接続すると症状は再現しませんでした。
あと、別のPCに接続してみても症状は再現しませんでした。
つまりは、私のPCのUSBで電力を十分に供給できていないということのようです。
結構デリケートなのね。LCDが思った以上に食うのかしら?
ではUSB接続しながら外部電源を接続した場合はどうなるのか?
ダブル電源カッケー!なんて中二病みたいな事にはならないようです。
外部電源端子に推奨されているのは7V~12V
7V以上外部から供給された時点でUSB給電を止め外部電源に切り替わるようだ。
外部から7V以上入れても、
三端子レギュレータで5Vに減圧されて使われるので問題ない。安定は9Vと言われているようで、多少熱はでるが12Vでも問題ないという話。
ということで手軽に実験するのであれば、
十分に電力を供給できるUSBポートを使うか、
9Vのアダプタ又は乾電池を使う必要がある。
Arduino 2) 数値を文字として表示する
2016.11.17
プログラムを作っていると内部数値を
表に出したいことがよくあります。
バグの追跡などでは大活躍です。
Arduinoではセンサーの値を表示するなど頻繁に使うと思います。
私がよく使う言語ではinttostrのような数値を文字に変換する関数
を使ってから出力します。
ところが先日行ったLCD出力のコードを応用しますと、
lcd.print(65536);
このように実行しても問題なく表示されちゃうんですね・・・
ちょっと目からウロコw
int a;
a=65536;
lcd.print(a);
こうするとintの制限を受けて上手に表示されない。
ArduinoUNOのintは-32768から32767なのだ。
ArduinoDueなら-2147483648から2147483647までいけるらしい。
では以下のコードではどう示すか実験
int a,b;
a=32767;b=32767;
lcd.print(a+b);
結果 -2
int変数同士が足し算を行った場合は、
結果もintとして処理されてしまうようだ。
(正確には狂っているわけじゃなく2の補数計算されているだけですが)
負の値はいらないよ。って場合は、
unsigned int a,b;
a=32767;b=32767;
lcd.print(a+b);
結果 65534
正しい結果が導かれた。
unsigned intは整数のみを扱い、0~65535を扱えるっぽい。
チマチマしたことはどうでもいいって場合は
longを使うと-2,147,483,648から2,147,483,647まで扱える。
ではintとunsigned intの変数を足したらどういった結果になるのだろうか。
高級言語だと、型が合わないとか言ってコンパイラが弾くのだが・・
int a
unsigned int b
a=32767;b=32767;
lcd.print(a+b);
結果 65534
弾かないw 結果も正常。実に興味深いw
どうやら、サイズの大きい変数に合わせて計算されているようだ。
では、これではどうだろう。
int a
long b
a=32767;b=2000000000;
lcd.print(a+b);
結果 200003277
これも大きいサイズの変数に合わせて計算された。
強い物に巻かれろ主義( ´艸`)
こういったことは言語やCPUレジスタの特徴に大きく左右されるので、
一度実験しておくと今後悩まずにコードが書けるはず。
忘れっぽい私にはとても重要なことなのです。
表に出したいことがよくあります。
バグの追跡などでは大活躍です。
Arduinoではセンサーの値を表示するなど頻繁に使うと思います。
私がよく使う言語ではinttostrのような数値を文字に変換する関数
を使ってから出力します。
ところが先日行ったLCD出力のコードを応用しますと、
lcd.print(65536);
このように実行しても問題なく表示されちゃうんですね・・・
ちょっと目からウロコw
int a;
a=65536;
lcd.print(a);
こうするとintの制限を受けて上手に表示されない。
ArduinoUNOのintは-32768から32767なのだ。
ArduinoDueなら-2147483648から2147483647までいけるらしい。
では以下のコードではどう示すか実験
int a,b;
a=32767;b=32767;
lcd.print(a+b);
結果 -2
int変数同士が足し算を行った場合は、
結果もintとして処理されてしまうようだ。
(正確には狂っているわけじゃなく2の補数計算されているだけですが)
負の値はいらないよ。って場合は、
unsigned int a,b;
a=32767;b=32767;
lcd.print(a+b);
結果 65534
正しい結果が導かれた。
unsigned intは整数のみを扱い、0~65535を扱えるっぽい。
チマチマしたことはどうでもいいって場合は
longを使うと-2,147,483,648から2,147,483,647まで扱える。
ではintとunsigned intの変数を足したらどういった結果になるのだろうか。
高級言語だと、型が合わないとか言ってコンパイラが弾くのだが・・
int a
unsigned int b
a=32767;b=32767;
lcd.print(a+b);
結果 65534
弾かないw 結果も正常。実に興味深いw
どうやら、サイズの大きい変数に合わせて計算されているようだ。
では、これではどうだろう。
int a
long b
a=32767;b=2000000000;
lcd.print(a+b);
結果 200003277
これも大きいサイズの変数に合わせて計算された。
強い物に巻かれろ主義( ´艸`)
こういったことは言語やCPUレジスタの特徴に大きく左右されるので、
一度実験しておくと今後悩まずにコードが書けるはず。
忘れっぽい私にはとても重要なことなのです。