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

寝ても覚めてもPSoC

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

おもちゃの改造 その2

2010年04月05日 | PSoC
記事を投稿しようとしたら、なぜか認証画面になって本文が消えてしまったので簡単に書きます。

前回の電源ONはOpenDrainLowでうまくいきました。
ほぼPSoCで制御できるようになりました。
しかし、やっているうちに、いろいろ仕組みが入っている事がわかりました。
シンプルな回路と思ったけど、さすが商品ってところか。反省反省。
それに伴い、謎な事もでてきました。

改造版で遊ぶ前に、本体が壊れないことを祈る!

おもちゃの改造 その1

2010年03月30日 | PSoC
今、おもちゃの改造をしています\(^o^)/
おもちゃの電源は単一x3の4.5Vです。これをマイコン(5V)で制御したい。
制御すべきものは以下の3つ。
・電源ON(マイクロスイッチ)
・モーター3個
・電源OFF(フォトリフレクタ)
テスターで調べて、だいたいどこをつなぐとどうなるかがわかりました。
いやぁシンプルで助かったなぁ。これなら僕でも改造できそう。

まずはマイコンで電源をONにしよう!
おもちゃの仕組みは簡単。マイクロスイッチが押されると電源が入るw
VCC ------ SW ----- GND
となっているので、VCCとSWの間に配線したケーブルをGNDにつなげはいいよね。
ブレッドボード上でやると、なるほど確かに電源が入る!うほっ。
※実際にはスイッチが押されるのは瞬間なのでトリガーとしてしか使っていません。サイリスタみたいな機構があると思います。

で、これをマイコンで制御しようとすると....
どーしたらいいんでしょう?またまた基本的なことで悩んでしまう。

とりあえずトランジスタによるSWが思い浮かんだのですが、なんだかなぁ...
だいたいトランジスタって足が3つあるからあまり好きではないw
場所くうんだよね~


オープン・ドレイン・ドライブLowでポート直結は壊れるかな...

PSoCでMP3PLAYER[VS1011E] その2

2010年03月24日 | PSoC
仕事が忙しくなると更新が止まりますw
まぁ、趣味だからね。気楽にいこう

さて、mp3playerができました。
SDカードの操作やVS1011Eのデータシート日本語訳とか、いろいろ参考(パクりとも言う)にさせてもらいました。感謝、感謝です!

動画です。相変わらず音が小さいです...orz


実は完成してもまだ問題を抱えています。
mp3を再生していない待機中でも30mAほど消費しているのです。電池駆動ではなかなか厳しい数字ではないでしょうか。
ちなみに再生時は80mAぐらいになる時があります。平均70mAかな?
PastelMagicさんの掲示板にも同様な質問があり、SDにCMD15を送信するとほとんど0になるという書き込みがありましたが、怪しいwデータシートをみるとSPIモードでは使えないようです。試しに送信してみましたが変化無しでした。
もはや電源供給を絶つしかないのかなwwって事で、”そのうち”やってみようと思います。←僕にとっては難しいのです!

また、VS1011E制御の部分は少し最適化できそうです。というのは、VS1011Eには曲データ用の受信バッファがあり、32byteは連続送信できるようです(DREQを確認しなくても良いって事かな)。
これを実装すればマイコンの処理負荷を少し減らせるかも?微妙かも?

回路図です。
CY8C29466 mp3player(VS1011E)回路図
再生用PSoC+VS1011E+SDと制御用PSoCの構成です。
制御用とは言っても単なる通信なのでPC(ターミナル)からでも制御できます。
スピーカー配線がLRくっつけているので、このままではヤバイですね。僕はモノラルで使うのでLだけ配線しています。

デザイナ: 5.0 SP6
デバイス: CY8C29466 3.3V
コンパイラ:ImageCraft
PSoC_mp3player[VS1011E].lzh

PSoCでSDカードを使う[SD-CARD]

2010年03月10日 | PSoC
PSoC Designer Ver 5.5 SP6では、そのままではSDCARDモジュールが選択できません。
なのでVer4.4でプロジェクトを作成し、5.5 SP6用のプロジェクトにしました。
モジュールはSDCARDしか配置していませんので雛形として使えます。DEVICEを換えたい等はCloneしてください。

PSoC_SdcardTemplate.lzh

現在、懲りずにVS1011Eでmp3再生をやってます
今回は基板にPSoCをくっつけたので前回よりケーブルが少なく済んでますw
前回はスパゲッティ状態だったもんなぁ... orz



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

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


PSoCで温度送信機 その後[LM60 24C512]

2010年01月25日 | PSoC
電池電圧を測定してみました~!

室温と車内で計測し、グラフにしてみました。
・電源は単四エボルタx3
・回路の消費電流は18mA
・計測期間は約18時間(1分間隔)

まずは室内です。(AM2:00計測開始。電池フル充電)


次に車内です。(AM1:00計測開始。電池フル充電から2日放置状態)


えー、どんどん温度が下がって、日中は17℃ぐらいまで上がって、その後は徐々に温度が低下。
電圧については、朝方の0℃付近から10℃ぐらいになったとき、若干電圧が回復しています(10mV程度)。
やっぱ低温音は電池は弱くなる!?いや、エボルタ君すげ~!のか!?
次はアルカリ電池でやってみよっかなぁ。

回路図です。

※2/5追記 回路図のレギュレータ部分が間違っていたので修正しました。

回路図では6Vになっていますが実際は違います。フル充電直後なので1.4Vx3で4.2Vです。
TA48M033Fの必要電位差0.65Vって事は最低4Vは必要なのに...出力はちゃんと3.3V出てたのかな。特に車内の方は最初から4V切ってるし
あと電池電圧を分圧して3.3V内に収めていますが、100KΩはちょっと大きすぎるかな~とか。よくわかりません。
データの記録は秋月で売ってるシリアルI2C EEPROM 24C512を使いました。
64KBで小さい(?)ですが、ログ記録としては便利ですよね。

うーむ、今回...俺は...何を...やってんだろ orz
って感じですが、電池の電圧が監視できるようになったのは嬉しいなぁ\(^o^)/
目指せ!はやぶさ探査機だ!
『ほら来た。(キリッ)』って言ってみてぇーーーwwww

PSoCで温度送信機 成功[LM60 XBee]

2010年01月16日 | PSoC
計測に成功しました!

[2日目]
天気:雪
最低気温:-2.6
電源:単三6本

[3日目]
天気:曇
最低気温:-3.5
電源:単四3本

両日凍てつく寒さだった事がわかります。

消費電流を測ってみると、
計測時:79.6mA
スリープ時:4.3mA
でした。(20℃、レギュレータOUT端子の直後)
XBeeだけでも50mA程度使うらしい。
ちなみにGlobalResourceのAnalogPower、Op-Amp Bias、A_Buff_Powerを Low にすると、スリープ時は 0.4mA になりましたが、High の時と比べて温度が2℃近く差が出ました。
うーむ、回路が悪いのかな
まぁとにかく、今回は過酷な環境下で長時間稼働させる難しさを実感しました。(といっても電池で一晩だけどw)


■センサー側(PSoC XBee LM60)回路図

PSoC XBee LM60回路図


■受信側(XBee AE-UM232R(FT232RL))回路図

XBee AE-UM232R(FT232RL)回路図


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


低温時のバッテリー電圧の変化が知りたくなった!次はこれを作ってみようかな!

※3.3V版のMiniProgが欲しいと思う。間違えてPowerCycleで書き込んでしまい、あやうくXBeeを壊すところだった...orz


PSoCで温度送信機 失敗[LM60 XBee]

2010年01月13日 | PSoC
寒い。寒いぞ!
しかも冬将軍が来ているらしい。厄介なことに雪が降るというのだ。
こりゃ氷点下になるな...

おっ!?
そういえば氷点下の温度もお手軽に測れる温度センサを買ったのを思い出した。
秋月で売っているLM60です。

いつも使っているLM35DZは、0℃までしか測れない。
しかし、こいつならマイナス温度を測れる!いいぞ、フラウボウ、否、LM60!
LM60は424mVのオフセット電圧があり、そこが0℃を示すらしい。
あとは6.25mV/℃でリニアに変化するのでLM35DZのように簡単に扱えそうだ。
ブレッドボードで作成すると、LM35が示す温度と多少違うけど、ICの特性という事でとりあえず了解w

さて、これを外に...と思ったけど、2つの問題点が発生。
1.結露が怖い
2.現在の気温が知りたいけど、外に出て確認するのは寒くて嫌だ

1は、やっぱ素人なので状況を予測できない。ケースってどれぐらいの密閉度があるんだろう。
という訳で、ヘタレな僕は車の中に入れることにした。
2は、これまた衝動買いしたXBeeモジュールを使って通信させる。これで家の中から計測値を取得することができる。通信距離は、まぁ大丈夫だろう。
念のため、最低温度をE2PROMモジュールを使用して記録するようにしておいた。

センサー側は、
・PSoC: CY8C29466
・温度センサ: LM60
・通信: XBee
・電源: 単四エボルタx3 TA48M033F
・備考: 5秒間間隔で計測し、計測時以外はモジュールをストップさせ、PSoCをSLEEP。XBeeも同様にSLEEP。

XBeeが3.3VなのでPSoCも3.3Vにして統一。
そうそう、LM60がLM35DZより優れているのは3.3Vでも動作可能って所もありりますね。(しかし、以前ColdFireでやったときは3.3VでLM35DZをむりやり使ってましたが...)

クライアントは、とりあえずPCを使う事にして、
・ターミナル: TeraTerm
・シリアル: FT232RL USBシリアル変換モジュール
・通信: XBee
・電源: USB
としました。
FT232RLモジュールは3.3Vを出力(PIN17)してくれるので、こいつをXBeeの電源へ。
TXRXはレベルシフトが必要だけど、XBeeからFT232RLへは直結。FT232RLからXBeeへは5.1Kと10Kの抵抗分圧にしました。
実はFT232RLのJP1を切り替えることで、IOの電圧を5Vと3.3Vの切り替えができます。ナイス!ですね。しかし、ここは男は黙って抵抗分圧(勉強のため)。

LM60 XBee
10cm程度の距離で通信確認をして、センサーブレッドボードを車内へ。うーさぶっ!
家に戻り、ターミナルを見ると(車内)温度が送信されてきている。
20℃程度から10℃ぐらいの場所へ一気に移動させたけど、温度の変化は思ったより緩やかですね。
これで、朝方にマイナス温度を記録するだろう。果たして、マイナス何℃なのか!?


が、計測は失敗に終わった。
最後に計測した温度は0.9℃だった。外は大雪。そんなはずは...
むむむ、一生懸命作った温度計が動作しないのは、何故だ!?
『坊やだからさ...』
ガルマが死んだのはそうかもしれないが、どうも解せない。
PSoCもXBeeもエボルタも氷点下でも稼動すると書いてある。
何故だ!

原因は....たぶん電池 (まぁ実際、車の中では氷点下にならないかもしれないけど)。
低温時は思った以上に消耗するらしい(電圧がかなり落ちる?)。
エボルタの説明には
----------------------------------------------------------------
●寒い場所での使用に強い!!
幅広い使用温度に対応。特に低温に強く、-20℃でもご使用いただけます。
(ただし、常温使用に比べると 電池の使用時間は短くなります。)
----------------------------------------------------------------
と書いてあるけど、零度近くから減りが極端に早くなってたりして。


明日は最低気温-4℃で雪のようだし、フル充電の単三エボルタ6本と計測1分間隔にしてやってみよう。車の窓も少し開けておくか。
なんとしても氷点下表示をキシリア様にお届けしたいのだ!

いやしかし、たかが温度計なのに思ったより大事(おおごと)になってるな~。
されど温度計ってことか...反省。

君は、氷点下を見る事ができるか!?


※プロジェクトファイル、回路図等は後日にします。