前回、動かすたびに同じ方位でも値が異なり、うまくいきませんでしたが、
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);
}
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でダイセン電子工業のモータードライバを動かす実験です。
結果から言うとうまくいきませんでした。
このモータードライバは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ではうまく動いたので、問題はないと思うのですが。
今日と明日の天気予報を表示する装置を作ってみました。
フルカラーLEDの色で天気をあらわします。(天気は赤、雨は暗い青など)
.
.
.
といっても、PCにつなぐ必要があります。PCでインターネットから天気予報の情報を取得する、なんちゃって装置です。
+GAINER(オーム社)の記事を参考にしました。
天気の情報は↓からXMLを取得します。
http://weather.livedoor.com/weather_hacks/
マイコンはトランジスタ技術2008年8月号の付録基盤のNECエレクトロニクス社製78K0マイコンを使用しています。このマイコンはアナログ入力ポートが無いのが痛いですね。。。
マイコン側ではPCから受け取った情報を元にPWMでフルカラーLEDの色を制御します。
このマイコンはLEDを駆動できるパワーが無いのでバッファをかませています。(左上のICです。)
PC側のプログラムはJAVAで組みました。XMLのパーサーはSAXを使用しています。
マイコンとの通信にはRXTXcommを使っています。
ぴよ将棋やその他アプリの開発・お知らせ、ロボット・電子工作