goo blog サービス終了のお知らせ 

寝ても覚めてもPSoC

電子工作とマイコンをやりはじめました。
ど素人ですので配信する情報の取り扱いには十分注意してください。

【タンスの肥やし】嗚呼、悲しき部品たち...その1

2010年02月27日 | 電子工作
むしゃくしゃして買った。今は後悔している...
そんなパーツを晒します。

デジタルカラーセンサー(S9706)

浜松ホトニクスというメーカーのカラーセンサーです。12ビットのデジタル出力です。
購入した直後に少し遊んだだけでSLEEP(放置)モードに入りましたw
起こす時が来るとよいのですが...

圧電振動ジャイロモジュール(AE-GYRO-SMD)

村田製作所のジャイロスター(ENC-03RC/D)をモジュール化したものらしい。
サーボで遊んでた時に買ったんだよなぁ。
『ほほぅ?これが噂に聞くジャイロという奴か。ふーむ。』と、基板をしげしげと見ただけで、まだ電気を通したことは無いw
近いうちに使ってみたいとは思うのですが。

デジタルコンパスモジュール(RDCM-802)

方位を8方向で取得できます。3ビットのデジタル出力です。
使ってみたいんだけど、取り付けが簡単にできないので放置状態です。
いやほんと、使ってみたいですよ、これは。しかしモジュールのくせにここまで取り付けしにくいのは如何なものかと...

ソリッド・ステート・リレー

家電をマイコンで制御!夢の一つです
しかし、僕の知識では火事になりそうで... ←んなら買うなよ

■マイクロスイッチ(AV622264、D3M-01L1)

未開封新品!www
これはロボットの接触センサーとして使おう!と、買ったはいいけど、搭載する本体はいつできるのでしょう????

■リチウムイオンポリマー電池

小さな体で大きなパワー!これで小型軽量化ができるぅぅ!ひゃっほー!
と、何も考えずにポチッとしちゃったけど、後で大変危険な物体であることが判明。
爆発動画を観て、僕ならやりかねんな...という訳で、全部新品のままです


上記以外に、まだ眠っているパーツがありますw
今でこそヤバそうなのは事前に自分で扱えるか調べたり、今必要かを考えてから買うようにしていますが、まじで勢いで買っちゃってた時がありました
そのうち第二弾をやります!


SilentMoonSDKでネイティブアプリ 完成

2010年02月23日 | ColdFire
”TwitterおみくじBOT for ColdFire”が完成しました!

MakeColdfireBin.batとソースのユーザー名とパスワードを書き換えてビルドし、コンソールでExecUser(1)とすればBOTが起動します。[e]キーで中断しない限り、約2分毎に処理を繰り返します。
Twitterで@ユーザー名付きでメッセージに”おみくじ”と入れて送信すると、運勢を返信してきます。

ビルドの注意点として、文字コードをUTF-8にそろえるためソースファイルもUTF-8となっています。CodeWarriorではUTF-8の設定ができないため(設定する方法があればぜひ教えてください)、ソースの編集はTeraPadで行い、ビルドだけIDEで行います。決して、IDE上でソースの編集を行わないでください。
ColdFire基板単独で動作するので特に配線は必要ありませんが、AN0はどこにも接続しないでください。なぜならば、乱数生成にAN0を使用しているからです。未接続でA/D変換すると出鱈目な数値を返してくるのを(強引に)利用しています

今回SilentMoonSDKでTwitterBOTを作りましたが、作成時に起きた問題点をまとめると以下のようになります。

1.標準ライブラリが少ないので必要なものは自作する必要がある
2.GetNetLine関数は1行取得の使いやすい関数だが254文字までしか受け取れない。255文字以上の場合はカットされる。今回はサンプルのためこの関数を使用したが、長い文字列を取得する必要がある場合は、Read関数とGetReceiveBuffer関数で処理しなければならない。
3.GetNetLine関数に関連するバグに悩まされたが、結局は自分が余計なパラメータを送信していたのが原因だった。疑ってゴメンよ...
4.XMLパーサはまともに作ると大変なので、出力形式が固定であるので単なる文字列処理として簡略化した。出力フォーマットが変更されたら若干修正作業が発生するwww
5.日本語文字の出力は&#nnnnというHTML実体参照形式になる。nnnnはUnicode十進数らしく、これをUTF-8文字列に変換するには、
 code = atoi(nnnn);
 utf8[0] = (BYTE)(0xE0|(code>>12));
 utf8[1] = (BYTE)(0x80|(((code>>8)&0x0f)<<2)|(code>>6)&0x03);
 utf8[2] = (BYTE)(0x80|(code&0x3f));
 utf8[3] = 0;
でOKだった。ここに変換の図が載っています。トン!
6.Twitterメッセージのidが大きすぐる!w 今後どーすんだろ?とりあえず今回は2分割しましたが...

とにかく他のプラットフォームのように文字列関数や数値関数が充実してたり、漢字コード変換も関数一発とはいかないのでこういうのは苦労しますね。とくに僕のようなメモリ大量、高速CPUになれた”ゆとり君”には。変換サーバを通せば楽なんだけど、それじゃー意味ないしなぁ...
あ、ちなみに長時間稼動させた事はないので安定度は未知数です


続いてTwitterBOTの仕組みです。これが正しいとかではなく、”この方法でできました”です。つまり俺流ですので、ご了承ください。

1.誰かから @BOTユーザー名 メッセージ としてリクエストしてもらいます。
2.BOTは mentions API で返信メッセージの一覧を取得します。
  ※通常は最新の返信メッセージを受け取るため、 since_id パラメータでidを指定します。
3.いろんな(余計な)データが取得できますが、最低限必要なパラメータは、
 status.id....メッセージのid
 status.text...メッセージ本文
 status.user.screen_name...返信ユーザー名
 です。出力データを見れば構造はすぐわかります。
4.受け取ったメッセージ本文の中にキーワード(今回は”おみくじ”)が存在したら、@返信ユーザー名 ほにゃららら~ と、 update API でつぶやきます。
5.取得したリスト分繰り返します。
6.API制限のため数分待機して2.に戻る。

このBOTでは mentions API のpage制御をしていません。巡回時に2page以上も返信リクエストがある場合はちゃんと処理する必要があります。そんな人気なBOTを作ってみたいですがw
とりあえずは countパラメータで 200 としておけば良いのではないでしょうか
くれぐれもスパムBOTにならないように気をつけないといけないですね。


いろいろ難がありましたが、ColdFire+SilentMoonSDKでのネイティブアプリ開発は、所詮はマイコンなので大きなものを対象としなければ非常に有効な手段だと思いました。(もう少しライブラリを整備する必要はありますが...)
現状PSoCではTCP/IPが使えないので、I2CやUARTでやりとりしたりして組み合わせると...夢広がりますwww

プロジェクトです。
ColdFire_Twitter_omikujiBOT.lzh
※twbot.cで定義されているUSERNAMEとUSERPWを自分の情報に書き換えてください。
※MakeColdfireBin.batのIPアドレスを自分の環境に書き換えてください。


※現在はBASIC認証が廃止されているため、そのままでは動作しません。

SilentMoonSDKでネイティブアプリ

2010年02月17日 | ColdFire
久々にInterface付録基板のColdFireをやっています。(...っていうか、まだ他に誰かこの基板を使っている人がいるのかなw)
今回はSilentCではなくて、SilentMoonSDKを使用したネイティブアプリをC言語で作成しています。IDEはCodeWarriorです。
とりあえずTwitterにつぶやくのはできたので、Twitter-BOTでも作るかぁと。
手始めにPCアプリで@ネームでメッセージをもらうと、その相手に運勢を返すのはできた。
カスタマイズ性を持たせてNTサービスにして配布しようかと考えたけど、PCよりも単体で動くColdFireの方が面白いよね!

って事で作り始めましたが....
なかなか難航しておりますww
ここ4日間ほど睨めっこ状態です

長期化は好ましくないので、なんとかケリをつけなくては....

JPEGカメラで撮影しGLCDで表示[C328-7640]

2010年02月05日 | PSoC
かなり前にJPEGカメラ(C328-7640)で撮影したファイルをSDカードに保存するプロジェクトを作成しました。
今回はコンパイラをImageCraft用に変更したついでに、いつものSG12864Aに表示するようにしてみました。
JPEGデコードはPSoCではかなり厳しいので、80x60ドットの8bitGrayScaleで撮影しています どうせLCDもモノクロだし...
80x60の8bitのため、データサイズは4800バイトになります。この領域を確保するのは、やはりPSoCでは厳しいのでEEPROMにデータを保存しています。

とりあえず動画です。


プロジェクトと回路図は後日UPします。
そのかわりに、カメラ(C328-7640)について書きます。
かつてない程の長文となりましたwwwww


C328-7640は、非力なマイコンでもJPEG画像が取得できる便利なカメラです。
値段は5000円ぐらいと、ちょっと高いなぁと思いますが、SDカードやXBee等の無線装置と組み合わせると簡単に定点観測やスパイカメラwが作れます。
解像度は低いですが、非圧縮形式でも画像(グレースケール、16bitカラー)を取得できるため、ロボットの目としても使えそうです。
カメラとのインターフェイスもUARTで制御できるため比較的簡単ではないかと思います。
しかし、簡単とは言え、やはりそれなりの手順は必要となります。
今回は備忘録として、JPEG画像の取得と8bitグレースケール画像の取得についてまとめてみました。
短時間でまとめたため読みにくい部分があるかと思いますが、そこは脳内補間とグーグル先生で自己解決してくださいw

それから僕の書く記事の大前提ですが、内容は保証するものではありません。
必ずデータシートを読んで、自分で確認してください。

【C328-7640仕様】
動作電圧: 3.0V~3.6V
消費電流: 60mA~
通信: UART
通信速度: 7200, 9600, 14400, 19200, 28800, 38400, 57600, 115200bps
色数: Gray Scale(2bit, 4bit, 8bit)[YCbCrのY(輝度)のみ]、Color(12bit[444:RGB], 16bit[565:RGB])、JPEG
解像度: 80x60, 160x120
JPEG解像度: 80x64, 160x128, 320x240, 640x480
SLEEP: 有り(100μA)


【C328-7640のコマンド送受信】
[1] C328とは基本的に専用のコマンドを使用してやりとりします
やりとりのコマンドはコマンドIDとオプションパラメータが4つの計6バイトが1セットになります。
例えばSYNCコマンドの場合、
0xAA 0x0D 0x00  0x00  0x00  0x00
(ID Number Param1 Param2 Param3 Param4)
と、先頭から順に送信します。
void sendSyncCmd()
{
 C328TX_putByte( 0xAA );
 C328TX_putByte( 0x0D );
 C328TX_putByte( 0x00 );
 C328TX_putByte( 0x00 );
 C328TX_putByte( 0x00 );
 C328TX_putByte( 0x00 );
}
って感じです。
UART送受信はバイナリモードで行う必要があります。テキストモードでは制御できません。
※C328TX_putByte()は、C328カメラに1バイト送信する関数です。


[2] コマンドを送信し、カメラ側が受領するとACKコマンドを返してきます
つまり、コマンド送信→ACK受け取り→次のコマンド送信→ACK受け取り‥‥‥
という感じです。
ACK送出はカメラ側だけではなく、マイコン側から送信する場合もあります。
カメラから送られてくるACKはパラメータで必要なもの(SYNCとか画像サイズ等)以外は、とりあえず6バイト読み込むだけでパラメータの内容は考慮しなくても良さそうです。
void getACK( void )
{
 for( i = 0; i < 6; i++ ) C328RX_getByte();
}
って感じ。


[3] コマンドの送信は速すぎると失敗する場合があります
その場合はコマンド送信前に適度(20msぐらい)のwaitを入れてあげるとうまくいく場合があります。


【JPEG画像を取得する方法】
[1] SYNCコマンドを送信してカメラとの接続を確立する
通信速度をカメラ側がスキャンして自動的に認識するため、何回か送信してやる必要があります。
データシートには、だいたい25回ぐらいで確立できると書いてあります。
60回送信しても応答がなければ何らかの問題が発生していると考えられます。
一回接続が確立するとボーレート変更コマンドで指定しないかぎり通信速度は維持されます。
カメラ側からACKコマンドを受信したらマイコン側からもACKコマンドを送信し、手続きを完了します。
この時、Param1にはSYNCコマンドのACKである事を示す0x0Dを入れ、Param2には受信したACKと同じParam2の値を入れます。

また、接続確立直後はカメラの輝度が安定しないため、1~2秒待つか、高解像度で撮影を行う前に低解像度で撮影すると安定するそうです。

1.SYNC(0xAA 0x0D 0x00 0x00 0x00 0x00)を送信
 ※適当に待ち時間を挟みながら最大60回送信する。それでも反応がなければエラー。
2.ACK(0xAA 0x0E 0x0D nnn 0x00 0x00)を受信
3.ACK(0xAA 0x0E 0x0D nnn 0x00 0x00)を送信
 ※2.のACKで受け取った値(nnn)を入れる


[2] Initialコマンドを送信する
ここでカラータイプや解像度を指定します。
例えば、カラータイプをJPEG(0x07)、プレビュー解像度を80x60(0x01)、JPEG解像度を640x480(0x07)にする場合は、以下のコマンドを送信します。

1.Initial(0xAA 0x01 0x00 0x07 0x01 0x07)を送信
2.ACK(0xAA 0x0E 0x01 0x00 0x00 0x00)を受信


[3] SetPackageSizeコマンドを送信する
JPEGデータはパッケージという単位でデータを受け取るため、そのサイズを指定します。
パッケージサイズが大きいほど効率よく転送できますが、非力なマイコンでは用意できるバッファサイズが限定されると思いますので適当に調整します。
尚、サイズはデフォルトは64バイトで最大512バイトまでです。
仮にパッケージサイズを256バイトに設定してもヘッダーとフッターが付く(6バイト)ため、実際に取得できる画像データは250バイトになります。

1.SetPackageSize(0xAA 0x06 0x08 LB HB 0x00)を送信
2.ACK(0xAA 0x0E 0x06 0x00 0x00 0x00)を受信

LBとHBはバッケージサイズのLowByteとHighByteを入れます。(WORD型を上位バイト、下位バイトに分解)
サイズを変数BUFFSIZEに指定したとすると、
LBは BUFFSIZE&0xFF
HBは BUFFSIZE/256
となります。


[4] Snapshotコマンドを送信し、画像を撮影する
JPEGは圧縮してデータをもらうため、Compressed Picture(0x00)を指定します。

1.Snapshot(0xAA 0x05 0x00 0x00 0x00 0x00)を送信
2.ACK(0xAA 0x0E 0x05 0x00 0x00 0x00)を受信


[5] GetPictureコマンドを送信し、データを受け取る準備をする
PictureTypeはSnapshotPicture(0x01)を指定します。
GetPictureコマンドを送信すると、カメラ側からACKコマンドに続いて最初のDataコマンドが送信されてきます。
この中には撮影画像のデータサイズが入っていますので取得しておきます。

1.GetPicture(0xAA 0x04 0x01 0x00 0x00 0x00)を送信
2.ACK(0xAA 0x0E 0x04 0x00 0x00 0x00)を受信
3.Data(0xAA 0x0A 0x01 LB HB 0x00)を受信

LBとHBは画像データサイズのLowByteとHighByteが入っていますので、以下のように変換してサイズを取得します。
JPEGFILESIZE = HB*256+LB


[6] 全てのデータを受信するまでACKコマンドを送信する
マイコン側がACKを送信すると、カメラ側は1パッケージを送信してきます。
送信するACKにはパッケージIDを指定します。
受信するパッケージの構造は、
ID(2bytes) ............ パッケージID
DataSize(2bytes) ...... パッケージ内に含まれるデータサイズ
ImageData(DataSize) ... イメージデータ
VerifyCode(2bytes) .... チェックサム
です。
基本的に指定したパッケージサイズ分が返ってきますが、最後のパッケージは指定サイズよりも少ない可能性があります。

1.パッケージID、受信サイズを初期化 pid=0 total=0
2.ACK(0xAA 0x0E 0x00 0x00 LB HB)をカメラへ送信
 LBとHBはパッケージIDのLowByteとHighByteを入れます。
 具体的には 0xAA 0x0E 0x00 0x00 pid&0xFF pid/256 となります。
3.パッケージを受信する
 id = C328RX_getByte()+C328RX_getByte()*256;
 ds = C328RX_getByte()+C328RX_getByte()*256;
 for( i = 0; i < ds; i++ ){
  data[i] = C328RX_getByte();
 }
 verify = C328RX_getByte()+C328RX_getByte()*256;
 total += ds;
 pid++;
 ここで受け取ったデータ(data)をSDカードに保存する等の処理を行います。
 もし、チェックサムと合わなければ受信エラーとして同じパッケージIDを指定して再送してもらう事もできると思います。
 ※C328RX_getByte()はC328カメラから1バイト受信する関数
4.全て受信していなければ(total < JPEGFILESIZE)、2.へ戻る


[7] 全て受信したら受信完了ACKを送信する
1.ACK(0xAA 0x0E 0x00 0x00 0xF0 0xF0)を送信

[8] PowerOffコマンドを送信してカメラをスリープさせる(必要に応じて)
スリープした後に再び撮影する場合は、SYNCコマンドでカメラを起こす必要があります。
1.PowerOff(0xAA 0x09 0x00 0x00 0x00 0x00)を送信
2.ACK(0xAA 0x0E 0x09 0x00 0x00 0x00)を受信

これで完了です


【8-bitGrayScale画像を取得する方法】
[1] SYNCコマンドを送信してカメラとの接続を確立する
JPEGと手順は同じです。


[2] Initialコマンドを送信する
例えば、カラータイプを8-bitGrayScale(0x03)、プレビュー解像度を80x60(0x01)にする場合は、以下のコマンドを送信します。

1.Initial(0xAA 0x01 0x00 0x03 0x01 0x00)を送信
2.ACK(0xAA 0x0E 0x01 0x00 0x00 0x00)を受信


[3] Snapshotコマンドを送信し、画像を撮影する
非圧縮で画像データをもらうため、Uncompressed Picture(0x01)を指定します。

1.Snapshot(0xAA 0x05 0x01 0x00 0x00 0x00)を送信
2.ACK(0xAA 0x0E 0x05 0x00 0x00 0x00)を受信

※非圧縮ではパッケージ単位でやりとりしないため、SetPackageSizeコマンドは必要ありません。


[4] GetPictureコマンドを送信し、画像データを受け取る準備をする
JPEGと手順は同じです。
データサイズは非圧縮のため取得しても計算(80x60=4800)しても同じです。
Dataコマンドを受信した直後に画像データが一気に送信されてきます!


[5] 全ての画像データを受信する
JPEGと違い、非圧縮の生データがデータサイズ分だけ連続で送信されてきます。
パッケージ単位ではありません!

for( i = 0; i < 80x60; i++ ){
  data[i] = C328RX_getByte();
}
※2/8追記 コードを追加しました。

注意しなければならないのは、低速(9600bps以下)で通信する場合や受信バッファが十分に取れるマイコン環境なら問題ありませんが、バッファが少ない環境では、連続してデータが送信されくるため、データを外部メモリ(SDやEEPROM)に記録している間に受信バッファが満杯になり、取りこぼしが発生する可能性があります。
このあたりは上手に設計する必要がありそうです。JPEGと同じようにパッケージ単位の手法も用意してほしかった。
JPEGのパッケージ単位でやりとりの場合は、次の取得データのタイミングをマイコン側で制御できるため、最高速で通信が可能です。


[6] 全て受信したら受信完了ACKを送信する
1.ACK(0xAA 0x0E 0x0A 0x00 0x00 0x00)を送信


これで完了です

PSoCでCPUモニターを作ってみた[SG12864A]

2010年02月01日 | PSoC
グラフィックLCD(SG12864A)を使ってパソコンのCPUモニターを作ってみました。
なぜかSG12864Aで少しまともに表示したものを作りたくなったのです
なんでCPUモニターかというと、なんとなくw
ソレっぽさが出せそうだったからかなぁ。

デモ動画※グラフはGoogle Earthのツアーを実行した時の様子です。


回路図です。同じ基板を使っているので毎回同じです
一つ追加があり、通信(RX)のため P2[0] をシリアルへつなぎます。


PC側アプリです。
※詳しくはReadme.txtを参照してください
Pm2Serial100.lzh

PSoCプロジェクトです。
デザイナ: 5.0 SP6
デバイス: CY8C29466
コンパイラ:ImageCraft
PSoC_Pm2Serial29466.lzh

今回使用したフォントデータです。