「PIC AVR 工作室」サイトの日記的なブログです。
サイトに挙げなかった他愛ないことを日記的に書き残してます。
PIC AVR 工作室 ブログ



昨日書いた以下の話。

>…1ミリ秒単位で指定できるのかな?指定できる
>範囲がどこからどこまでなのかがイマイチ判らない
>なぁ。あとでまた調べておこう…。

ライブラリの中身を覗いて見ました。判りました。

結論から言うと、最小単位1ミリ秒で正確に割り込みを
生じさせることが可能です。
しかもその時間はunsigned long int で定義されて
いるので、32ビット幅(ミリ秒単位)で時刻指定できる
ようです。
さすがにそんな長い周期で割り込みかける用途はないと
思うので、事実上どんな周期でも正確に設定可能と
考えて良さそうです。

(補記:内部では、1ミリ秒毎に毎回毎回割り込みが
 発生しているんですが、指定したミリ秒分だけ
 カウントをしていて、その回数に至って初めて
 関数の呼び出しが行われます。例えば500ミリ秒
 と指定した場合、内部では1ミリ秒毎に割り込み処理が
 発生しているんですが、それが500回繰り返されて
 初めて自作の関数がコールされることになります。
 内部ではそういう仕組みです。1回1回は1クロック単位
 で正確に1ミリ秒なので、500ミリ秒と設定して
 おけば、正確に500ミリ秒毎に関数が呼び出されます)


ライブラリの中身をのぞいていて違和感を感じた部分が一点。
↓こんな記述のところです。

 tcnt2 = 256 - (int)((float)F_CPU * 0.001 / prescaler);

この0.001という中途半端な数値で掛け算をしているところ。
1000で割り算をするのなら整数値だけで済むので正確な
答が出ると思うのですが、0.001は内部の2進数では
正確な表現は出来ないような…。丸め誤差出ませんか?
(いやまてよ、浮動少数だから内部では1.0×10^-3
 なんて表現になってるのかな?うーん、よくわからん)

一応、サンプルプログラムをフリーランさせていた範囲では
時計との誤差らしいモノは生じてないようなのですが…。
とにかく、整数値で計算したいのに0.001って、
なんだか気持ち悪いなぁ。


なお、このライブラリを眺めていたら、arduinoが
バージョンアップしてもなぜずっと16MHzなのかが
判ったような気がします。

もし20MHzにしちゃうと、timer0やtimer2の8ビット幅
(とプリスケーラ)では厳密に1ミリ秒という正確な
割り込みが出来なくなっちゃうからだろうと…。

timer0はmillis()関数でバリバリ使ってますからね。
8ビット幅ではミリ秒単位の割り込みが出来なくなるのは
timer2同様です。

まぁ、16MHzでも全然困らないのでこのままで充分満足です。
シンプルが一番でしょう。



コメント ( 0 )
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする




引き続き、arduinoのライブラリ関係を調査しています。

SPIを使いたかったんですが、Official Librariesは
おろかContributed Librariesにもそれっぽいもの無し。
先人のSPI関係のスケッチを探してみたんですが、
めぼしい感じのものがヒットせず。
(↓これはちょっと長すぎるよね…)
http://www.arduino.cc/en/Tutorial/SPIEEPROM


なので、I2C(TWI)i/fについて調べました。これも
SPI同様に「バスi/f」として簡単に使えるので。


I2C(TWI)については、Official Librariesで
しっかり対応されてました。
サンプルスケッチなどを眺めてみましたが、
使い方も超シンプル。I2C対応のICとなら、
取り交わすコマンド類さえ判れば簡単にスケッチ
が可能かと。


凝り性なもので、ライブラリの内部を眺めてみました。
特に気になっているのは通信速度のこと。
(ピン配置などは標準のピン以外に割り当てのしようが
 ないはずなので)

MEGA168の内部レジスタでは、プリスケーラとビットレート
を決めるのは、TWSRレジスタ内のTWPS1、TWPS0の
2ビットと、TWBRレジスタの全8ビット、計10ビット。
これらが内部でどう設定されてるのか、なのですが…

残念ながら、ざっと眺めた程度ではこれらのレジスタに
設定している処理までは追いきれませんでした…。
ただ、Wire.cpp 内のbegin()関数から呼び出される
twi.h 内のtwi_init() 関数の中で、

   #define TWI_FREQ 100000L

と言う具合にTWIの周波数を100KHzに設定している
ところがあり、それ以外の周波数に設定している
所はないようなので、多分100KHz(=低速モード)
に固定で設定されていると考えて間違えないでしょう。

きっと、下手に速い速度で固定すると古い周辺IC
とかでは対応されない場合があるから遅い方に
あわせてあるのでしょう。
逆に受信速度自体はMEGA168ならもともと400KHz対応だし。


どちらかというと、速い通信速度(400KHz)固定の
ほうが個人的には困ってしまうところなので、
100KHzは歓迎です。

その他興味をひいたライブラリとしてはグラフィックLCD
の表示ライブラリとか、PS2キーボードライブラリとか、
サーボモーターライブラリあたりですね。
この辺はあとで時間があるときにでもじっくり見て
みたいと思います。



コメント ( 0 )
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする




makeのブログ経由で、
http://www.instructables.com/id/DIY-3D-Controller/

こんなシンプルな3D入力デバイスの記事を知りました。
抵抗数本、アルミ箔、配線、そしてarduino。
それだけ。

すごいねぇ!

多分arduinoはこのアルミ箔の静電容量をもとに
充電時間を計って距離を求め、それをPCに
送信、PC側で3Dグラフィック(Direct-Xか
open-GLか多分どっちか)でスクリーンに
描き出している様子。

Chanさんのサイトなどでも、PCBの
銅箔と人体の間の静電容量をつかったタッチセンサー
が公開されてましたが、それにしてもアルミ箔
からこんなに離れていてもちゃんと計れるんですねぇ。

どういう計算するとこういうものが設計できる
のかなぁ?

ムービーを見ていると、カーソル(?)の移動速度が
比較的ゆったりなので、速い動きには追従が難しい
のかな?

それにしても、これはいいなぁ。
今後、何か製品とかにも応用されたりするんじゃ
ないかなぁ。


そういえば、1つだけ難点が。

ポインティングデバイスとして使うのであれば、
位置情報だけでなく、マウスで言うところの
クリックが必要になるはず。

静電容量を使った距離計測機能のほかに、
「クリック」に相当する操作が出来ないと
応用範囲が限られるかな。



コメント ( 0 )
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする




さて、arduinoのtimer機能ばかりズラズラッと
書いてきましたが、もう一つだけ。

なぜ、arduino用のスケッチやライブラリでは
timer0やtimer1ではなくtimer2を使うものが
多いのかについてです。

arduinoの各timerがどのように使われているか
について検索してみました。
こちらがとっても纏まった情報になってます。↓
http://www.uchobby.com/index.php/2007/11/24/arduino-interrupts/

このページの上から1/4くらいのところ。
「Timers on the Arduino」というタイトル部分
のところに書いてあることを簡単に和訳してみますと…

・timer0:
 millis()関数、及びデジタル5ピン6ピンへの
 PWM出力用として使います。
・timer1:
 デジタル9ピン10ピンへのPWM出力として使います。
・timer2:
 デジタル3ピン11ピンへのPWM出力として使います。

ということらしいです。(ちなみにPWM出力って
いうのはarduinoでいうanalogWrite関数のこと)
そして、

・(システムが)使用しているタイマー機能はすべて
 timer0にアサインされているので、timer1とtimer2は
 乗っ取ることができます。(筆者注:もちろんtimer1,2を
 PWMでも使ってない場合ですよ)

と書かれています。


それに加え、timer1は16ビットカウンターなので、
8ビットで済んじゃう程度ならtimer2を使えば
いいんでしょ!ということだろうと思います。
(そう理解しました)

あと、タイマー割り込み機能として使うだけなら
カウンターのビット幅だけで考えても良いんですが、
PWMとして使う場合は出力端子が各タイマー毎に固定
されているので、その点も考慮して選ぶ必要があるかと
思います。

私の持ってるボード”reduino-nano”の場合は
ラッキーなことにデジタル3ピンがLEDに
繋がっているので、LEDにアナログ出力
(PWMで)するにはもってこい。実験に最適。

ノーマルなarduinoなら13ピンにLEDが
ついてますが、13ピンにアナログ出力
するタイマーは無いですからね。残念でした。
外付けのLEDと抵抗を用意しましょう。


一方、タイマー機能とPWMを混在させて使う
としたら、ライブラリーの標準機能では
難しいんじゃないかな?
(そもそもPWM出力させながらCTCで割り込み
 かけることって出来たんだったっけ???
 山根さん本を読んでみる…特に出来ない
 理由は見当たらないな…多分可能でしょう)

いずれにしても上記のリンクサイト。
全部目を通したわけじゃありませんが、AVRの
割り込み関係についてarduinoも絡めて
超詳しく書いてあるので、ご興味のある方は
是非ご一読を。


(後日追記:タイマー割り込み関係の話を
 文章に纏めてサイトにアップしておきました。
 ↓こちら)
http://nekosan0.bake-neko.net/library_timer.html



コメント ( 0 )
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする




timer割り込みの話です。arduinoのサイトの
libraryのページ
http://www.arduino.cc/en/Reference/Libraries
に置かれていたtimer用のライブラリ、
   ”MsTimer2”
を使ってみたので、その話をします。超かんたんだー!

まずはダウンロードしたzipファイルを解凍します。
で、出てきたフォルダを丸ごとコピーします。
コピー先は…
arduino-0011\hardware\libraries
↑ここ。
ちなみにarduino-0011の部分は、arduinoIDEをどこに
インストールしているかによって当然変わりますので
適宜読み替えてください。

コピーしてからarduinoIDEを起動すると、メニューの
sketch - import libraryで「MsTimer2」が選べるように
なります。

そしたら以下のスケッチを入力します。

入力といっても、ダウンロードしたフォルダの中に
exampleフォルダというのが含まれていて、
そのスケッチを殆どそのまま使っています。

#include <MsTimer2.h>

// Switch on LED on pin 13 each second


void flash() {
static boolean output = HIGH;

digitalWrite(3, output);
output = !output;
}

void setup() {
pinMode(3, OUTPUT);

MsTimer2::set(500, flash); // 500ms period
MsTimer2::start();
}

void loop() {
}


変えたのは2箇所:digitalWriteとpinModeのところ。
reduino-nanoは3ピンにLEDが繋がっているので、
13ピンから3ピンに変更しました。
(あと、#include文のところは不等号を全角文字に
 しておきました。半角に書き換えて使うか、
 ライブラリのzipファイルを解凍したフォルダ
 からサンプルソースを取り出して使ってください)

書き込むと、LEDが1秒に1回点滅します。
いやぁ! それにしても短くなりましたなぁ!!!!

内部レジスタ類を触らなくて良いっていうのが
ラクチンでサイコーです。(≧v≦)σ
まぁ、シリアルポート出力とかの処理がない分
短いってのもありますが。

このライブラリ、Official Librariesに組み込まれない
かなぁ?使いやすくていい!
PWM機能(とうか、analogWrite関数という方が
arduino的には正しいかな?)も3つの各タイマー
機能を使用しているので、そこらへんとの整合性確保
とか、あとはタイマー関係の機能ってこれで十分
なのかなどという機能定義に関する議論などがあるんで
しょうね。きっと。
もしかしたら今後機能変更が入る可能性もありますね。


ま、いずれにしても1ミリ秒単位で割り込み周期を
指定して、正確で定期的な処理をするのが簡単に
できそうです。
カスタム機能満載の超多機能時計なんかも簡単に
できちゃいそう。

…1ミリ秒単位で指定できるのかな?指定できる
範囲がどこからどこまでなのかがイマイチ判らない
なぁ。あとでまた調べておこう…。
この辺は、内部レジスタを直接触らなくてもいい
という便利さとのトレードオフだな。


さて、ひとまず簡単にタイマー割り込みが使えるように
なったところで、arduino用スケッチではなぜtimer2ばかり
多用されているのかについて調べたので、別途まとめて
記載します。しばしおまちを。



コメント ( 0 )
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする