2018年10月
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      

カテゴリー

ブログパーツ

無料ブログはココログ

« 2013年1月 | トップページ | 2013年3月 »

2013年2月

2013年2月27日 (水)

PIC24FにジャイロコンパスXG1300Lをつなぐ

花岡ちゃんのウィークエンド

今回はLEGO用のジャイロコンパスXG1300Lをつないでみます。もちろんI2Cです。
センサは以前実験済み。詳しくはこのページこのページこのページこのページ、を見てください。また、このセンサを応用した自動操縦カーの実験もしています。

今回のプロジェクトです。EEPROM、I2C液晶、HMC6352、XG1300L用のI2Cドライバが含まれますが、使っているのはI2C液晶とXG1300Lだけです。
「pic24f_test_4.zip」をダウンロード

プログラムを実行するとXG1300Lを読み出して液晶に表示します。リセットで0、右回りでプラス、左でマイナスになります。読み出し値は0.01度単位で±18000が計測範囲になります。

Dscn2532

ボタンを押すとその方位を0としてリセットします。

このセンサはLEGO用ですが、その他に同じメーカーからR1350Nという同じような1軸ジャイロコンパスが出ています。この写真の右側の部品です。
Dscn2531

XG1300Lをバラして見た訳ではないですが、大きさや性能から見て同じものが入っているようです。ただインターフェイスがロジックレベルのシリアル通信になっています。こちらはXG1300Lの1/3くらいのお値段ですので、シリアルでよければこちらが良さそうですね。


2013年2月25日 (月)

PIC24Fに電子コンパスHMC6352をつないでみる

花岡ちゃんのウィークエンド

今回は以前にテストしたI2C接続の磁気方位センサ、HMC6352を接続してみます。このデバイスについては、以前の投稿、これこれを見てください。

Dscn2528

このデバイスからは2バイト連続でデータを読み出すので、ACKを返すものとNACKを返すもの、二つの読み出し関数を用意しなければなりません。EEPROMの読み出しは1バイトだけだったので、いい加減に読み出してあとはストップコンディションでごまかしていますが、これはそうは行きません。ちゃんとした読み出し関数i2c_readとi2c_read_noackを作りました。後者はACKを返しません。

試作したのは、電子コンパスの情報を100ms周期でI2C液晶に表示するプログラムです。真北を0として3599まで、つまり方位角X10の数値を表示します。
HMC6352はPIC24FのSCK1とSDA1に接続します。この投稿の回路図を見てください。EEPROMは使ってないので取り付けなくてもかまいません。

詳細な中身はこのMPLAB Xプロジェクトを見てもらえばわかります。このプロジェクトにはEEPROM、I2C液晶、HMC6352用の関数が含まれています。
「pic24f_test_3.zip」をダウンロード

実をいうとI2Cには苦手意識があって、あまり使って来ませんでした。しかし、I2C接続のデバイスには魅力的なモノがおおく、この際苦手を克服しておきたいと思います。
これから面白そうなI2Cデバイスのドライバ関数を製作してみようかと思っています。

2013年2月24日 (日)

PIC24Fで秋月のI2C液晶を使ってみる

花岡ちゃんのウィークエンド

前回実験したPIC24FJ64GA002の実験回路に、秋月のI2C接続液晶ディスプレイを接続してみました。基本的なI2Cバスへのアクセスは出来ているので、こんなの簡単…のはずでしてたが、結局丸一日つぶれてしまいましたので、後進の方のために顛末を投稿します。

Dscn2527

まず、このディスプレイのI2Cアドレスは0x50(送信するアドレスバイトは1010000X)固定で、EEPROMのベースアドレスとバッティングしています。EEPのチップアドレスA0,A1,A2を000以外にすればいいのですが、なんでまたよく使うEEPと同じにするかなあという感じです。EEPを一つだけ使う場合は、一列に並んだアドレスピンをみんなGNDに落として、000にするのがいちばん簡単ですからね。

とりあえずI2Cバスに接続してプログラムを作りましたが、なにも表示されません。液晶の上段が薄く全点灯しているだけ、I2Cでない普通の液晶に電源をつないだだけの状態のように見えます。シンクロでI2Cバスの波形を見るとACKが返ってこないようです。なんだこりゃということで、いろいろ試してみましたが状況は変わりません。

もしかしたら壊れているのかも? と思って散歩がてら秋月までもう一つ買い出しに。残念ながら新しいものに変えても全く同じです。2個不良というのはまずありません。

そこで、おなじみのPIC16F887の基板で表示プログラム(ただしccscで)を作って試してみると素直に動きます。バスの波形を比べると下のような違いがあります。
Waveform
上がSDA(データ)下がSCL(クロック)です。16Fだとデータビットの真ん中にクロックが来てますが、24Fだとクロックの立ち下がりとデータの立ち下がりが同時です。ただ、I2Cではコレでもいいはず、data hold time(クロックの立ち下がりからデータ変更までの時間差)の最小値は0です。液晶のデータシートでもそうなってます。

同様の波形をソフトで作り、24Fで試してみるとうまく動きます。このせいなんでしょうか? でもなんか解せません。

さらに色々いじっているうちにようやく原因がつかめました。データを送信する時、送信とACKの受信が終了したことをTRSTATというフラグで見ているのですが、これで送信終了を判断した後、次のデータ送信までに10usほど時間をあけないといけないようです。EEPROMだと問題ないのですがI2C液晶はソフトで通信シーケンスを実装している関係で、データの取り込みに少々時間が必要なようです。波形を変えてうまく行ったのは、クロックの立ち下がり後に5usほどクロックLの時間を作ったことと、ソフトなので処理時間が少し増えたこと、これが相手の読み込み処理のマージンになったためだと思います。

最終的にはi2c_send関数の終了前にforループで遅延を入れることで、PIC24FのハードによるI2C通信でもきちんと働くようになりました。

I2C液晶表示を使った、100msごとカウントアップするタイマーのMPLAB Xプロジェクトを公開します。配線は前回の回路同様です。追試する方はEEPROMを外すか、チップアドレスを変更するのを忘れないでください。
「pic24f_test_2.zip」をダウンロード

2013年2月19日 (火)

pythonで作ったノードサンプルを実行する

ROSさんお手やわらかに:ROS入門編

前回作った発行のノードサンプルを実行してみる

なにはともあれ
make
でノードとして実行できるようにする。

あとはroscoreを実行後、別のターミナルを開いて

rosrun beginner_tutorials talker.py

で、実行できるはずだが・・ うまくいかない。beginner_tutorialsというスタックかパッケージはないと言われる。色々試してみると、開いたターミナルでsource myros(これ)を実行しないとmakeもroscdもうまくいかないようだ。turtlebotのテストではそんなことはなかったのに・・ 
と思ったらここに注意があった。なんかこれとも違うような感じだが、ともあれ新しいターミナルを開いたらsource myros(source ~/fuerte_workspace/setup.bash)をやっておいた方がよいようだ。

実行すると画面にメッセージが、こんな風にタイムスタンプ付きで表示され続ける。

[INFO] [WallTime: 1361203264.644360] hello world 1361203264.64
[INFO] [WallTime: 1361203265.646276] hello world 1361203265.65
[INFO] [WallTime: 1361203266.648367] hello world 1361203266.65
[INFO] [WallTime: 1361203267.650462] hello world 1361203267.65
[INFO] [WallTime: 1361203268.652513] hello world 1361203268.65
・・・・・・

ここまでできればとりあえずOKのようだ。

2013年2月17日 (日)

PIC24Fに手を出してみる

花岡ちゃんのウィークエンド

今回のウィークエンドはPICシリーズの16bitマイコン、PIC24FJ64GA002を試してみます。最近、PICの開発環境をMPLAB-Xに乗り換えたついでに、手を出してみることにしました。

Dscn2519

PIC16シリーズは、マイコン一つで完結する小型の電子機器の製作には十分な性能があります。僕も公私ともPIC16で様々な機械を作ってきました。安定でコストが安いのも魅力です。反面、RAMが極端に少ない、シリアルポートが1本しかないなど、複数のマイコンを通信で結んだ、マルチプロセッサの機械の中核に使おうと思うと、さすがに力不足の感は否めません。そんなときにはSTM32やSH-Tinyを使えばよい訳ですが、DIPパッケージがないので「気楽」に始められる雰囲気がありません。その点、24Fシリーズは28pinDIPパッケージがあるので、思い立ったらすぐ、ブレットボードで実験が始められます。スピードではSTMなどには及ばないものの、PIC16よりははるかに高速ですし、数値演算やテキスト処理に何かと必要なRAMは8KBもあります。さらに、UARTとI2Cが2チャンネル搭載されており、マルチプロセッサのアプリケーションにも十分対応できそうです。

作成したのは下記の機能を持つテストプログラムです。

■Timer1の割り込みでLEDを周期1Hzで点滅(タイマーの使い方と出力ポートの確認)
■ボタンを押している間LEDがつきっぱなしに(入力ポートの確認)
■シリアルポートからのコマンド受け取り(シリアルポートの使い方の確認)
■I2Cバスに接続したEEPROMの読み書き(I2Cバスの使い方とEEPROMアクセスの確認)

MPLAB-XとXC16でのプロジェクトを参考までに公開します。全てmain.cに記述されているので、そこだけ見てもらえば、タイマー割り込み、割り込みでハンドルするUART通信、I2Cの制御とEEPROMの読み書きなどの実装方法がわかると思います。

「pic24f_test_1.X.zip」をダウンロード

実験した回路図はこれです。TX,RXはレベルコンバータを経由してパソコンのシリアルポートに接続します。

「pic24f.pdf」をダウンロード

テストプログラムをPICKIT3(2でも可能です)で実験機にダウンロードするとLEDが1秒周期で点滅を始めます。ボタンを押すとその間LEDがつきっぱなしになるはずです。
いったん電源を切り、レベルコンバータで実験機をパソコンのシリアルポートに接続、ターミナルソフトを起動してボーレートを9600bpsに、ローカルエコーをONにセットします。

電源を入れるとスタートアップメッセージとコマンドプロンプト">"が表示されます。コマンドはエコーバックするeコマンド、EEPROMに書き込むwコマンドと読み出すrコマンドが使えます。実行の様子は下記スクリーンショットを見てください。">"の右がPCに打ち込んだコマンドです。

Term

PIC16シリーズとはポート設定の方法がかなり違います。この辺は初心に戻ってきちんとデータシートを読むなり、参考書を買うなりした方が賢明です。特に下記には気をつけた方がよいと思います

・アナログ入力兼用のGPIOポートは初期状態では「アナログ入力」になっている。これを解除しないとデジタル入力ポートとして使えない。

・I2Cはマルチマスター対応なので、明示的にマスターとして設定できず、送信するまではスレーブとして動作する。そのため、使用するポートをまずGPIO出力として0に初期化し、その後これをI2Cとして設定するとプルアップで1になるのでスタートコンディションが入って受信中になることがある。これではクロックがこないので受信終了にならない。こうなると、その後、送信コマンドなどを一切受け付けなくなる。そのため、I2Cを先に設定し、その後GPIOの設定をしなければならない。

・シリアルRXを割り当てたポートはTRISで入力に設定する必要がある。

ともあれ、ひとまずPIC24のコードのひな形が出来ました。機会があれば何か作ってみたいと思います。


2013年2月 6日 (水)

pythonでノードを作る(パブリッシュ編)

ROSさんお手やわらかに:ROS入門編

pythonでノードを作る方法。チュートリアルのこのページ

beginner_tutorialsにscriptsというディレクトリをつくり、以降のファイルはそこに置く。

まずは発行(パブリッシュ)するノードtalker.pyを作る。僕はGUIのエディタで入力した。
ファイルが出来たら

chmod +x scripts/talker.py

で実行可能にしておく。

下記がtalker.pyの解説だ。ブログにコードを貼るとインデントが崩れてしまうが、pythonはインデントに意味があるので、もとページのコードを参照のこと。

1 #!/usr/bin/env python
2 import roslib; roslib.load_manifest('beginner_tutorials')
最初の行はおまじない。pythonで書くときは必ずつける。2行目は、このノードはパッケージbeginner_tutorialsに属し、そのマニュフェストを参照する設定らしい。良くわからないが、こういうものだということで先に進む。

3 import rospy
4 from std_msgs.msg import String
3行目、ノードをpythonで書くときはこれが必要。これもおまじないの一種だな。4行目はstd_msg.msgオブジェクト(?)からStringクラス(?)を読み込む。以降Stringと表記されるのはstd_msg.msg.Stringクラスのことを意味するようになる。

7 def talker():
8 pub = rospy.Publisher('chatter', String)
9 rospy.init_node('talker')
7行目はtalkerというノードを定義する。8行目はchatterというトピックにStringというメッセージタイプを発行(パブリッシュ)する定義。
9行目、これでノードを初期化する。原文に「重要」とある。名前はベースネーム、つまり/とか~とか入らないものということらしい。普通に名前付けすればいいようだ。

10 while not rospy.is_shutdown():
11 str = "hello world %s" % rospy.get_time()
12 rospy.loginfo(str)
13 pub.publish(String(str))
14 rospy.sleep(1.0)
ここが本体の実行ループだ。このプロセスがCTRL+cなどでシャットダウンされるまで一秒おきにhello worldに時刻をつけてパブリッシュ(発行)する。ちなみにブログに張るとインデントが崩れてしまうが、これはpython、インデントが実行単位になっているので要注意。言うまでもないが14行目は一秒待つという意味。

もっと複雑なタイプを発行するにはどうするのかが書いてある。「一般に、コンストラクタの引数が.msgファイルの順番に並んでいること」だそうだ。つまりここ【4項目め】でやったmsgファイルでの構造体の定義順ということか。並びはカンマで切るのかな?
それからString(str)はこんな風に書くことも出来る。(それで?)

msg = String()
msg.data = str

あるいは

String(data=str)


17 if __name__ == '__main__':
18 try:
19 talker()
20 except rospy.ROSInterruptException:
21 pass
ここで前で定義したtalker()を実行する。tryでつかまえる例外がrospy.ROSInterruptException。この例外はsleep()中にCTRL+cなどのシャットダウンイベントで発生、これを感知したら直ちにプログラムを終了させるため。このtalker()ではsleep()のあとに何もコードがないから関係ないが、sleep()の後に何かしらのコードがあると、シャットダウンを受け付けた後にそれを実行してしまうから。

こういう形が発行(パブリッシュ)の雛形のようだ。

2013年2月 2日 (土)

PICとXBeeでツィートしてみる(拾遺)

花岡ちゃんのウィークエンド:ツィートガジェットの実験

実験で気づいたことなどをまとめて。

■XBee WiFiの電源
以前の投稿では電源にコンデンサをおごらねばなどと実験結果を書いてましたが、ちゃんとデータシートに書いてありました。下図がデータシートにあるスタートアップ時の経過電流です。

Imagepqgzrw

横軸はサンプル数で、サンプリング周期は(たぶん)5us。つまり定常電流になるまで800*5usで約4msということになり、その間最大0.75Aのパルス電流が3回発生しているのが分かります。
そのため、データシートには電源ラインに500uFのコンデンサを入れるよう書いてあります。今回の試作品はこれに倣って470uFの電解を入れました。

ただ、これだけの容量のコンデンサを起動時に充電しなければならないので、電源レギュレータの電流容量が小さいと、電圧の立ち上がりが悪くなってXBeeやマイコンのリセットがかかりにくくなることもあります。僕も経験がありますが、電源を入れても一発では動作しなくて、何回かON/OFFしているうちに動くようになる場合は、その辺を疑って見るのがいいかとおもいます。ON/OFFを繰り返すことで、コンデンサに電荷が少しずつ溜まって立ち上がりが良くなるため、このような現象が起こるようです。

その他にもスイッチング電源を使う際の注意などが具体的に書いてありますので、一度目を通しておくことをおすすめします。

■CTSによるフロー制御
XBee WiFiではシリアル受信バッファ(つまり無線LANへの送信データのバッファ)のスレショルドが設定できるようになっています。デフォルトは0x7F3、つまりシリアル受信バッファの容量が0x7F3(2035)バイトになったらCTSを1にして相手からの送信禁止を要求します。ですから無線LANへ送信するデータがこれ以下なら、フロー制御はいりません。今回のデータはヘッダをいれてもせいぜい1Kバイトくらいですから、フロー制御なしでやっています。ただ、画像データのように数十キロバイトもあるデータを送るにはこちらで試したようにフロー制御が必要です。

■日本語文字コードには要注意
今回の実験でてこずったのは、なんと日本語文字コードです。日本語で投稿する場合、ツィッターのAPIは投稿がUTF-8で記述されてないと受け付けません。手動でいろいろ試しているとき、英文だと投稿できるのに日本語にすると投稿できなくなってしまい、原因を発見するのに2時間近くかかってしまいました。いろいろな要因が重なってのことではありますが、結果的には、いつの間にかテキストを編集していたエディタの文字コードがS-JISになっていたというつまらない理由でした。
PICのプログラムには投稿する文章を文字定数で組み込んであります。プロジェクトの文字コードをUTF-8にしてあるのでそのまま変更して使う分には問題ないと思いますが、新たにプロジェクトを作ろうと思っている方は、注意が必要です。日本語コードが何種類もあるので、こういうことになるのですね。日本語の詩歌の美しさは世界に誇れると思っている僕でも、こんなときはアルファベットで事足りる英語圏の人がうらやましくなります。

2013年2月 1日 (金)

PICとXBee WiFiでツィートしてみる(おしまい)

花岡ちゃんのウィークエンド:ツィートガジェットの実験

最後にPICを使った実験機を作ってツィートしてみましょう。(その1)に投稿したように、このガジェットは0から999までの数字を一つ生成し、「ラッキーナンバーは123だよ 」などとツィートします。毎回ラッキーナンバーが変わる他に、語尾が「だよ 」「だぜぇ」など4種類に変化します。

PICは16F887を使っています。これはたまたまマイコンボードを持ってたためで、シリアルポートがあればもっと小さなPICでもかまいません。このソースコードをベースにするなら16F886あたりがお勧めです。回路図はこれです。


Xbeeeifi

実験機の写真です。奥に見える電源レギュレータに大げさな放熱器がついていますが、電源が単三4本なら、その必要はありません。

Dscn2510

ソフトの開発にはMPLAB XとXC8コンパイラ(無償版)を使いました。初めて使いましたが、ccs-cに比べるとかなり本格的なcの処理系だと思います。本機のプロジェクトファイルを公開します。「取り急ぎ」で製作したのであまりよいプログラムではありませんが、処理のシーケンスはわかりやすいと思います。ポインタを使えばもっとエレガントなコードになるでしょう。

「twTest.X.zip」をダウンロード

試してみるには、下記の作業が必要です。

■XBee WiFiが自分のドメインにアクセスできるように設定(こちらを見てください)
■XBee WiFiのシリアルポートの通信速度は38400bpsに設定
■main.c 21行目のexample.comを自分のドメイン名に書き換え
■main.c 27行目の"17"をhedder02の文字定数の文字数に書き換え

プロジェトをビルドし、Pickit2や3などでダウンロードします。
起動すると、LEDが点灯します。これがREADY状態で、ボタンを押すといったんLEDが消え、再度点灯します。この間に「ラッキーナンバー」をツィートしています。こんな感じです。

Photo

これで簡単なマイコンからでもツィッターに投稿できる機械ができました。誰かが来た、雨が降り出した、猫がえさを食べにきたなどなど、センサーとの組み合わせで面白いツィートガジェットが出来そうですね。

なお、今回の実験機ではサーバからのメッセージは全て無視しています。エラーがあっても何もしません。ルーターが落ちていてもわかりません。ちゃんと使うにはこういったエラーハンドリングをきちんとする必要があります。

« 2013年1月 | トップページ | 2013年3月 »