「ロボット・電子工作・マイコン」カテゴリーアーカイブ
Arduino+方位センサー(その2) うまくいきました!
前回、動かすたびに同じ方位でも値が異なり、うまくいきませんでしたが、
Arduino側でキャリブレーションするようにしたところ、比較的正確に方位を取得できるようになりました。
キャリブレーションといっても以下のような簡単な方法です。
OUT1とOUT2それぞれについて最大値、最小値を測定し、最小値~最大値の範囲で正規化します。
起動後にゆっくり2回転ほどさせると、正確な方位がとれるようになりました。
I2C版のHMC6352もキャリブレーション機能があるので、キャリブレーションは必須ということなのでしょう。
また、効果があるか良く分からないのですが、値の取得前にSET/RESET端子にパルスを入れるようにしています。
ArduinoのDIGITAL2をSET/RESET端子に接続します(10KΩの抵抗でプルダウン)。
■Arduinoスケッチ
// Calibration 初期値は安全な値を適当に設定 int cal_min1 = 488; int cal_max1 = 515; int cal_min2 = 463; int cal_max2 = 489; void setup() { pinMode(2, OUTPUT); Serial.begin(9600); } void loop() { // SET/RESET PULSE digitalWrite(2, LOW); delay(10); digitalWrite(2, HIGH); delay(10); digitalWrite(2, LOW); delay(10); // 読み取り int val1 = analogRead(0); int val2 = analogRead(1); // キャリブレーション if (val1<cal_min1) cal_min1 = val1; if (val2<cal_min2) cal_min2 = val2; if (val1>cal_max1) cal_max1 = val1; if (val2>cal_max2) cal_max2 = val2; int div1 = (cal_max1 - cal_min1 + 1); int div2 = (cal_max2 - cal_min2 + 1); float fval1 = (val1 - cal_min1 - div1 / 2.0) / div1; float fval2 = (val2 - cal_min2 - div2 / 2.0) / div2; // 角度(方位)を0~255に変換 int at = (atan2(fval1, fval2) + PI ) * 255 / (2*PI); Serial.print(at, BYTE); delay(100); }
■Processingスケッチ
import processing.serial.*; Serial myPort; int val; void setup() { size(200, 200); myPort = new Serial(this, "COM9", 9600); PFont font = createFont("Arial", 12); textFont(font); } void draw() { if ( myPort.available() > 0) { val = myPort.read(); } background(0); text(str(val), 1, 10); translate(width/2, height/2); rotate(val * 2 * PI/255); triangle(-10, -40, 10, -40, 0, 40); }
Arduino+方位センサー
2軸磁気センサーの実験をしました。
HMC1052Lは2軸の磁気センサーで、atan2をとることによって方位を知ることができます。
1年ほど前にストロベリー・リナックスにて¥3,480にて購入しました。
スイッチサイエンスでは¥2,000だったようですが、メーカー廃番で販売終了となっているようです。センサー部分のみでOPアンプなどが付いていないものが¥1,495で販売されています。こちらの方が安くてよいかも。
【接続】
HMC1052L | Arduino |
---|---|
OUT1 | AN0 |
OUT2 | AN1 |
GND | GND |
VCC | 5V |
出力が発振してしまうことがあったので、
HMC1052LのGNDとVCC間にコンデンサ(47μF+0.1μF)を入れたところ安定しました。
値は取れるようでしたので、Arduino側で方位を求め、PCにシリアルで送り、
PC側で簡単なアプリ(processingで作成)で方向を表示するようにしてみました。
ここで問題が!!
動かすたびに、同じ方向でも少し値が違って来るため、正確な方位が求められません。
Set/Reset端子というのがあり、パルスを入れると調整できるようなのですが、使い方がわかりません。。。(泣)
パルスを入れても入れなくても結果は変わらず。
I2CでコントロールできるHMC6352の方が良いかもしれません。
現時点でスイッチサイエンスにて¥3,495で販売されています。
Arduino+加速度センサ
Arduinoで秋月の3軸加速度センサー(KXM52-1050)を使ってみました。
↓を参考にしました。というかそのままです。
http://kousaku-kousaku.blogspot.com/2008/06/arduino_16.html
今日はシリアルで値がとれるところまで確認しました。
今後、①自作Arduino, ②XBeeで無線化して、無線コントローラーにする予定です。
Arduino+ダイセンモータードライバ
Arduinoでダイセン電子工業のモータードライバを動かす実験です。
結果から言うとうまくいきませんでした。
このモータードライバは6つのモーターを駆動でき、小型のモーターであれば十二分に動かせるパワーもあります。
価格も高くなくコストパフォーマンスに優れたボードだと思います。
ロボカップジュニア(サッカー)ではおなじみのボードで、うちの子供も使っています。
I2Cでコントロールできるので、Arduinoから簡単に動かせると考えました。
ダイセン電子工業のサイト
http://www.daisendenshi.com/detail/ddkit_0601.html
【接続】
- Arduinoの5VとGNDをモータードライバのI2C端子の5VとGNDへ接続。
- Arduinoのアナログ4pinをSDAへ接続、アナログ5pinをSCLへ接続、各々3KΩの抵抗を介してプルアップ。
【スケッチ(プログラム)】
プログラムは上記のURLからダウンロードできるマニュアルを参考に作成しました。
#include <Wire.h> #define TJ3M_ADDR 0x14 int ret; byte b[6]; void setup() { Wire.begin(); delay(100); } void loop() { Wire.beginTransmission(TJ3M_ADDR); b[0] = 50; b[1] = 50; b[2] = 0; b[3] = 0; b[4] = 0; b[5] = 0; Wire.send(b, 6); ret=Wire.endTransmission(); delay(100); }
結果は冒頭の通りうまくいかなかったのですが、ごく稀に(10回に1回ぐらい?)動くこともありますので、タイミングの問題でしょうかね?よくわかりません。
なお、ArduinoのI2Cは100KHzで動いているようです。モータードライバのマニュアルによれば100KHzでも大丈夫なようです。
ArduinoのI2Cの使い方としては温度センサのLM73ではうまく動いたので、問題はないと思うのですが。