先日の↓
http://brown.ap.teacup.com/nekosan0/210.html
「外部リファレンスの参照も対応していたんですね。」
で書いたことについて、もうちょっと調べてみました。
通常のmega168(やmega88、mega48)を電源オン
した時と、arduinoでコンパイルしたプログラムを
実行した時、デフォルトでそれぞれ内部レジスタが
どのように設定されるかについてです。
arduinoについては以前書いたように、DEFAULT
として内蔵5Vが参照電圧として適用されますが、
mega168のデータシートを読むと、デフォルトは
AREF端子入力からの参照電圧となっています。
通常mega168で独自のプログラムを組む場合、
AREF電圧では無く内蔵参照電圧を使う場合には
明示的にレジスタを設定しないとならない
のですが、arduinoの場合は「簡単に使える」
ということが優先されたのか、DEFAULTで
内蔵参照に設定されてしまっています。
このことが厄介を呼んでいるようですね。
ちなみに、データシートをちゃんと読むと、
251ページの「23.5.2 ADC Voltage Reference」
の項目に
・AREFに外部参照用の機器を繋いでいる時は、
ショートしちゃうので他の参照用オプションは
使用できません。
と書いてありました。ちゃんとデータシート
読まないといけませんね(´o`)。
ちなみに、AREF端子がわざわざこういう特殊な
繋ぎ方になっているのは、1.1Vや5Vの内蔵参照電圧
を使うときにでも、AREF端子とGNDの間にパスコンを
入れることで参照電圧からノイズを取り除く事が
出来るようにという配慮みたいです。
それにしてもarduino。
一切外部参照電圧を使うことは出来ない仕様と
考えるのが自然でしょう。
なぜそういう方針にしたんだろう???
|
せっかくサーボモーターが発掘されたので、
arduinoでサーボモーターを使って遊んでみました。
まずは、私の愛機reduino-nanoのメーカー、
マイクロファンのサイトで公開されている↓これ。
http://www.microfan.jp/?cat=78
手元のサーボモーターもフタバ互換のピン配置
だったので、例に習ってCN3にそのままジャックを
差し込みます。
スケッチも特に修正不要。このまま動きます。
2つのボタン(リセットじゃないヤツ)を押すと、
サーボモーターがグリグリ動きました。
よし、よし。
ちなみに、動作風景はこんな感じ。
![](https://blogimg.goo.ne.jp/user_image/53/77/d87d9b7531c3f4affab4335448fb8101.jpg)
次、ライブラリその1。「Servo」を使ってみます。
例によってライブラリのzipファイルをダウンロード
したら、解凍して\hardware\librariesのフォルダに
放り込み、arduino-IDEを起動します。
そして以下のようにスケッチを入力。(サンプル
はサーボを2つ繋ぐようなものだったので、1個だけ
繋ぐように修正しました)
#include <Servo.h>
Servo servo1;
int servoPin = 10;
void setup(){
servo1.attach(servoPin);
//servo1.setMaximumPuls(2000);
Serial.begin(9600);
Serial.print("Ready");
}
void loop(){
static int v = 0;
if ( Serial.available()) {
char ch = Serial.read();
switch(ch) {
case '0'...'9':
v = v * 10 + ch - '0';
break;
case 's':
servo1.write(v);
v = 0;
break;
}
}
Servo::refresh();
}
(例によって、#include文には半角不等号の
代わりに全角不等号を入れてあります。
適宜直して使ってください)
これといって難しいところは無いんですが、
マイクロファンのサンプルプログラムが
直接ミリ秒指定で制御していたのに対し、
このライブラリを使用すると「角度」で
指定できるようです。PC側からシリアル
通信でコマンドを送ることで角度を変更
出来るスケッチです。
例えば、「90s」と打てば90°に設定されます。
ただこのライブラリ、setMaximumPulsメソッド等で
可動範囲を指定しておく必要があるようです。
(製品の仕様差をここで吸収しているんでしょう)
サーボを繋ぐピンはデジタルピンならどこでも
良いみたいですが、一点注意が必要。
少なくとも50m秒以内に1回、Servo::refresh()を
呼び出ししないといけないようです。
ライブラリの中身を覗いてないので何故かは
よく解ってません。まあ、サンプルスケッチに
従ってそのようにしてみます。
うん。動きました。
次、ライブラリその2。「Servotimer1」です。
avrのtimer1を占有してしまいますが、ハードウェア
処理で制御されるようです。
先ほどのライブラリと違って、Servo::refresh()を
定期的に呼び出す必要は無いという点と、
利用可能なピンが固定されてしまうという点
について注意が必要です。
さて、スケッチはこんな感じ。
#include <ServoTimer1.h>
ServoTimer1 servo1;
void setup()
{
pinMode(1,OUTPUT);
servo1.attach(10);
servo1.setMinimumPulse(750);
// not "setMinimumPulseWidth"
servo1.setMaximumPulse(2300);
// not "setMaximumPulseWidth"
Serial.begin(9600);
Serial.println("Ready");
}
void loop()
{
static int v = 0;
if ( Serial.available()) {
char ch = Serial.read();
switch(ch) {
case '0'...'9':
v = v * 10 + ch - '0';
break;
case 's':
servo1.write(v);
v = 0;
break;
}
}
// Notice that no ServoTimer1::refresh() is needed.
}
ライブラリの解説サイトに間違い発見!
上記のスケッチにコメントでも記入してますが、
0度、180度におけるパルスの長さはそれぞれ
setMinimumPulseWidth、setMaximumPulseWidth
で指定するように書かれていますが、コンパイル
エラーになっちゃいます。
ライブラリの中身を見るとすぐ判りますが、
正しくはsetMinimumPulse、setMaximumPulse
です。
なお、接続するサーボモーターによっては
大量の電流を使用してしまいます。
でもUSBは500mAまでしか取れません。
大型のサーボを使用する場合は別途電源が必要
です。
ちなみにreduino-nanoであればポリスイッチで
500mA以上流れたら遮断されるので、あまり
神経質になる必要はないと思います。
(突如遮断されるので、USB-シリアル変換機能
も切れてしまうので、windowsアプリ側から
見たら突如シリアルポートが無くなるという
状態になるので、変なことにはなると思いますが、
PCやreduino-nanoが壊れることはないでしょう)
個人的には、ライブラリその1としてご紹介した
「Servo」のライブラリが気に入りました。
接続するピンがどこでも言いという点と、
デジタルピンがあいている限り幾つでもサーボを
繋ぐことが可能だということ。
応用範囲が一番広いのはこれでしょう。
あとでサイト上にもう少しちゃんとまとめておきたい
と思います。
(追記:サイトのほうに情報を纏めました↓)
http://nekosan0.bake-neko.net/library_servo.html
![](/images/clear.gif)
![](/images/clear.gif)
![](/images/clear.gif)
|
![](/images/clear.gif) |
|
|
|
|