お留守番ロボット RoboDuck

TYPE-1 dsPIC30F5011,XPort,C328,S9706,LM35DZ
TYPE-2 dsPIC33FJ256GP506,ENC28J60,MPL115A2,XBEE

2008/09/14
TYPE-1
dsPIC30F5011,XPort,C328,S9706,LM35DZ

dsPIC30F5011を使って、外出先から家の状況を携帯電話のメイルに報告する 「お留守番ロボット」をテーマにしてみます。

基本機能は、こんなことができたらいいなーというところです。

  • 気温、照度と画像を定期的にメイルで報告する
  • 人が近づいたらカメラで画像を写し、メイルで報告する
  • 気温、照度のログとカメラの画像をSDカードに保存する


LCDを外したところ

メイン基板

大容量コンデンサ,カメラコネクタ追加

右下にリレー追加

I/O接続

XPort

XPort開発用基板

JPEGカメラ

簡易I/O

焦電センサー

  回路図
   Main board
   I/O board
   C328 JPEG Camera ==>これはUARTに接続するだけです

秋月でPickit2が安く売っていたので、これを機会に購入しました。 6ピンソケットがヤワなので、基板に結束バンドで括り付けて、別の2列ピンヘッダーからフラットケーブルが引けるように改造しています。 その場合、Pickit2から基板に繋ぐ為のピンヘッダーは、少し加工が必要です。 2列のL字ピンヘッダーを使い、短い列側のピン両端をニッパーで切り落とします。 さらに、長い方の列側のピンをラジオペンチで一度まっすぐに伸ばして、根元から逆に90度曲げます。 高さが均一になるように曲げを調整してからPickit2に刺して、 高さ調整のために刺したまま基板に半田付けします。基板横から見た写真を参考にして下さい。 ピンヘッダーが基板から若干浮いているのがわかります。


Pickit2

基板に固定

基板を横から

開発風景


開発は、MPLAB上のCで行います。手順は以下のとおりです。
 1.メニューからProject/Project Wizardを選択
 2.Wellcom画面で次へ
 3.DeviceでdsPIC30F5011を選択し次へ
 4.Active ToolsuiteにMicorchipC 30 Toolsuiteを、Toolsuite ContentsにMPLAB C30 C Compiler(pic30-gcc.exe)を選択し次へ
 5.Create New Project Fileにプロジェクトのファイル名を入力して次へ
 6.ソースファイルがあればAddして右の画面にaddし次へ。後でAdd Fileも可能
 7.完了
 8.メニューのView/Projectで確認する。
 9.MPLAB C30/lib/libp30f5011-coff.aとMPLAB C30/support/gld/p30f5011.gldを追加する。

XPortは設定が必要です。 この企画の場合、シリアルとLANのやり取りだけなので、設定はさほど難しくありません。 抑えておくのは、DHCPを使うところとBaudrate、Flow制御を合わせるところでしょうか。

秋月から出ているデジタルカラーセンサー「S9706」も面白そうなので使ってみました。 夕方になると夕焼けの赤成分が多くなるのかなーと予想しています。 テストの結果、プログラムはこのようになりました。
GetColor
サンプリングの時間によって光の強度が決まってくるので、 一回目めは長めにサンプリング時間をとり、取得値が振り切れないようにサンプリング時間を短く何回かに区切って 繰り返すようにするのが良いです。

SMTPメイルの送信手順
yahoo メイルの場合の、POP before SMTPの例です。


プログラム
  test17.c
  lcd.h
  lcd.c
  common.h
  common.c
  base64.c

common.cの中には、EEPROMのread/writeルーチンとJPEGカメラC328のルーチンが含まれています。

一定時間(hour)ごとに、温度、照度、RGBレベルを取得して、メイル送信します。さらに、センサーに近づくとメイルを送信します。 今後、カメラによる画像を添付してメイルするルーチンの追加を予定しています。


まだ未解決なのが次の2点です。
  (1) JPEGカメラの通信が成立しない
  (2) SDカードへのファイル保存

(1)については、SYNCコマンドを発行するものの、ACKの6バイトが返らなければならないところ、5バイトしか返ってきません。 よって返信のSYNCコマンドも流れてこないのです。
SYNC(0xAA,0x0D,0x00,0x00,0x00,0x00) -> to JPEG camera
from JPEG camera -> ACK(0xAA,0x0E,0x0D,0x00,0x00) 以後データが返ってこない
もう一年以上も原因不明で調査中となってます。
Camera.c
レベルコンバータをかましてPCのハイパーターミナルで確認してみると、やはり連続5バイトまで送信、受信可能で、同じところで止まるのがわかりました。 データシートを熟読してみると、まず内部OSCの発振周波数設定が違うではないですか。dspic30f2011のソースを利用したので、そのまま7.37MHzになってました。 dspic30f5011は、PLL4、PLL8で8MHz、PLL16で7.5MHzとなってました。ここを修正しましたが、かえって通信不可になってしまいます。 7.3MHz_PLL8設定だと、Lantrex可、HyperTerminalは5バイトまで可、8MHz_PLL8だとHyperTerminal不可となり、泥沼状態です。 原因不明なので、dspic30f5011のUARTはクローズすることにしました。
==>後日、JpegCameraのアクセスは成功しました。C-21参照

(2)は、後日カードに書き込むことに成功しました。テストで使ったソースはこちらです。
SD_Card.c


2011/10/29
TYPE-2
dsPIC33FJ256GP506,ENC28J60,MPL115A2,XBEE

まずは、xBeeを2つ買ってきました。xBeeは幾つかグレードがあって、どれを使ったら良いのかわかりません。 とりあえず通信距離は短くてもいいという事で、一番安いチップアンテナ内臓の物を選びました。


ピン幅は2mm規格なので、いつもの2.45にどうやって挿すか迷いました。 すべてのピンを使うわけではないので、いらなさそうなピンを90度曲げて穴に挿さない=使わないことにしました。 4pin,8pin,14pin,15pin,18pinを犠牲にしました。残りは多少斜めにすると半田付け可能です。

最初に、Digi InternationalからX-CTUのプログラムをダウンロードしてxBeeのコンフィグ設定を行います。
xBeeの設定を読み込んでみると、モデムタイプがXB24と思っていたのにXB-24ZBと表示されます。 ZBEE 802.15.4で相互アドレスを設定して1対1で通信させようと思ってましたが、予定が違くなりそうです。 またまたマニュアルの熟読です。 強制的にタイプをXB24-Bと書き込む事が可能と、いろいろ実験してわかりました。 ネットワークノードを構成するには、唯一のコーディネータが必要で、残りはルーターかエンドデバイスです。 なので、一つはコーディネータとしてwrite、もう一つはリモート側としてエンドデバイスに設定してwriteします。
データ書き込み中にxBeeとの結線がゆるくなって切れてしまい、二度と反応しなくなりました。もう一つxBeeを買いに秋葉に走りました。

まずは、ホスト側のハードを作ります。 基板は2段重ね、グラフィックディスプレイを加えると3段重ねになりました。1階にはメインのコントローラと LAN制御用にENC28J60、無線LAN用にXBee、気圧センサーのMPL115A2、クロックに時計用の32.768kHz水晶、 なぜか余っていたので10MHzのセラロック、プルアップ抵抗は面倒なので集合抵抗に、タクトスイッチを少々、 パスコンは基板半田面にチップでリード線無しで半田付けしています。 2階は、SDカードのコントロールとグラフィックディスプレイのコネクタ、そしてLCDドライブ用の3.3V→5Vインバータしか乗せていません。 ピン数の関係で、SDカードのライトプロテクト線はフローティング状態です。 プログラムのためのISPは、XBee基板の下にピンソケットを忍ばせました。

xBeeの前に、気圧温度センサーからのデータ取得と、SDカードにアクセスしてデータを記録する部分、 さらにTCP/IPでNTPサーバーから時間を取得してクロック同期し、SMTPメイル送信ができるところまでを完成させました。 定期的に気圧と温度を読み取ってSDカードに保存、さらにxBee接続のリモート機から温度などのデータ値を取得、 リモートにシリアルカメラを接続して画像も記録しホストに転送、結果をメイルで送るという作戦です。

何度か使ったことがあるdsPIC33FJ256にしましたが、ここでヒューズの設定を一から見直すことにしました。 この時点では、思った周波数で動いているか不明です。実験なので、外部10MHz、内部OSC、32,768kHzのパターンで動かしてみました。 さすがに32.768kHzでは遅すぎてまともに機能しませんでした。 気圧センサーの計算は、変数のサイズが重要です。 はじめは何も考えずにlongとintなどが入り混じって計算してみましたが、答えがとんでもない値になるので一つ一つデバッグしてみると、 マイナス値でintからlongに変換がかかると上位16bitにゼロが入ってることがわかりました。ここは補数になる必要があります。 SDカードはchanさんのサブルーチンを使わせてもらいました。 SDカードのみでプログラムすると、コードページを日本語932にしても問題なく動作しました。 しかしTCPIPスタックを積んでみると、プログラム領域が大きくなりコンパイルが通りません。 932Tinyでも駄目です。 どちらのコードページも単体でコンパイルするとコンパイルできるようです。 2つのサイズを合わせてもdsPIC33FJ256の半分ちょっとしか使わないはずなのですが、フリーバージョンのMPLABでは制限を掛けているので コンパイルエラーとなります。仕方ないのでコードページを英語の437に設定しました。 いずれにしても、ファイル名の取り扱いだけの問題なので、ファイルの中身のデータにコードページは関係ありません。 TCPIPコンフィグは、メイル送信できるようにSMTP、ARPでIPとMACアドレスがネットワーク上に現れるか確認するのでICMP、 自動でIPをふるようにDHCP、名前解決のDNS、自力でIPを獲得できるようにAUTO_IP、 ホスト名が認識できるようにNBNS、と必要最小限にしました。 よくわかりませんがNBNSだけは機能してない感じです。プログラム領域も問題ないのでNBNS=onにしておきます。 時計用にTimer1を割り当てました。が、TCPIPスタックでもTimer1を使っていてコンフリクトを起こしてしまいました。 なのでTCPIPスタックをTimer2に避けています。

時間合わせのためにNTPサーバーを利用するようにしました。1970/1/1からの秒数が取得できますが、 100で割り切れる年は閏年でない、しかし400で割り切れる年は閏年と例外式を計算にまともに入れても、 これが有効になるのは次回約100年後であり、このハードが有効に動いているとは思えない。 無駄なことは止めて、2001/01/01からの秒数に変換して通常4年ごとの閏年を考慮した計算式に簡略化しました。 まずは、取得した秒数から978307200ullを引きます。さらにGMTをJSTに変換するので32400ullを足します。 何か変な日付を表示してしまいます。 マイクロチップが準備している関数 DWORD SNTPGetUTCSeconds(void) を使ったのですが、時間が合いません。 ソースを良く見ると、StuckTaskの中からNTPClientを常時呼び出していて、 NTPサーバーに時間を読みに行き、アクセスできなければ8秒おいて再接続、 アクセスできれば10分後に時間再読み込み、その間は内部時計のTick.cを基準に時間カウントしていました。 内部のTickカウントがどうやら正確に1秒を刻んでいないようです。 OSCの基本から見直しましたがどうしても2倍ぐらいの速さになってしまいます。 よくわからないので、SNTPGetUTCSeconds をあきらめて手っ取り早く別関数を作ってしまいました。 電源投入でNTPサーバーにアクセスし、アクセスできなければ10分おいて再接続、 アクセスできれば1時間ごとに時間合わせします。その間は、別タイマーで時間カウントです。

xBeeの設定です。次のような回路で、PCからシリアルポート経由でxBeeを設定します。
2つのxBee設定のポイントは、お互いにDestinatiion address(マックアドレス)をたすき掛けにする事です。それとPAN-IDはゼロ以外で、どちらも同じ値に設定します。 何かあって設定できなくなると困るので、通信速度は9600bpsのままにしておきました。

次に、xBeeで通信可能となるか、ホスト機からデータを送ってみてPCで受信できるか、次の回路とプログラムで実験します。(ホスト側の回路図はPICのみ表示)

    プログラム
    Version06 (05の変更部分のみ)
ホスト機のSW2を押している間、PCのターミナルソフトにDuckを送信し続けます。 PCは9600bpsと分かっているので、それに合わせてホスト機のクロックタイミングを確かめていきます。 実験していると、クロック周りの設定が違っているのがわかりました。 UARTシリアル用に訂正して、さらに時計クロックTimer周りも修正です。

問題なければ、間にxBeeをかましてみます。

ひとまずxBeeが機能してるのがわかり、無線通信できていると感動します。

次は、リモート機です。シリアルカメラも付けるかもしれないので、UARTが2つ欲しいところです。 これだけの機能の割にはオーバースペックですが、そんなに高価でもないのでPIC24FJ64GA002を選びました。 LEDは動作確認用です。とりあえずSecondOSCも付けてみました。

リモート側もシリアル系が機能するように、PCと通信してみます。以下の回路とプログラムで実験です。(リモート側の回路図はPICのみ表示)
このプログラムは、PCのターミナルソフトからコマンドを送ると文字を返す、またはコマンドによりLEDを点灯消灯させるスタブです。

うまくいったら、xBeeに置き換えてみます。

最後に、ホスト機からコマンドを出してリモート機から文字を返してもらって、ホスト機で受信した文字を表示するというテストをします。

これが完成すれば、第一関門突破というところです。ところが、ホスト機で送信はできるが受信できないという現象にはまってしまいました。 簡単なプログラムを作って、uart1に変えてみると受信OKです。uart2に戻すと受信NGです。I/Oポートにコンフィグを変えてみると、正しくI/O出力できました。 同じピンがI2Cと共用してるので、I2Cはdisableになってるのも確認です。 picのデータシートを見たりインターネット上に上がっている情報を探しましたが、原因となるような情報はありません。

picのハード・バグではないかと考えてます。(←なんと強気な)

<現在、ここで止まってしまいました>





Copyright © 2006- DuckFactory All rights reserved.