■ホビーロボット部品の製造・販売 
  モータコントローラ、センサ、音声、画像、無線モジュールなど、
■ホビーロボット制作記事のページ (各種マイコン、PCとの接続事例)
■特殊メイク、特殊材料の販売 ※特殊メイクのコーナーはこちらに移りました。
Top(お知らせ) 製品一覧 使い方とサンプルプログラムWebショップ リンク ブログ 会社案内
 Easy Robotics for all enthusiastic people!!!  ---HOBBY ROBOT PARTS SHOP ASAKUSAGIKEN---   Since 2003...


PICマイコンとAndroid端末をWiFiでつないでみる
 

<概要>

 ここではPICマイコンをWiMaster経由でAndroid端末につないでみます。今回は携帯機器を意識して、単三乾電池2本で動かしてみます。

 PICマイコンは浅草ギ研で販売しているPIC16F1936を搭載したPicoloを使いました。

<注意>

 ここでご紹介するプログラムはあくまでもサンプルプログラムとなります。個別のご質問などにはお答えできませんのでご了承下さい。

 機種やOSのバージョン違いや環境の違いなどにより動作しない可能性もあります。また、今後のiPhoneのOSバージョンアップなどに対しての動作も定かではありません。

 

紹介動画

 


<ブロック図>




 マイコンボードからは一定周期でセンサー読み取り値(8bit値)が送信されつづけます。マイコンボードが0x01を受信するとLEDを点灯、0x00で消灯します。





  

  


<接続図>


 PIC側接続詳細


■電源部

  ホビー用のマイコンボードは5V動作が多いので、WiMasterの電源入力は5Vになっています。実際にはWiMasterに供給された電源をU2(基板上の白い文字を参照)のレギュレータで3.3Vにし、内部は3.3V動作で動いています。無線部は”大体”3Vぐらいで動くように作られているので、単三乾電池2本直列で3Vをつくり、これを電源としても動きます。

 また、Picolo(PIC16F1936マイコンボード)は1.8〜5.5Vで動きますので、こちらも乾電池2本で問題ありません。

 WiMasterに直接3.3V(又は3Vぐらい)を入れる場合は、端子が出ていませんが、C2の部品の右側が内部電源+につながっているので、ここに3Vを供給します。PicoloのシリアルポートのVDDは電源+端子につながっているのでここから乾電池の+電圧が出ていますので、これをC2右につなぎます。

■LED

 LEDはアノードをRB7端子、カソードを電流制限抵抗経由でGNDにつないでいますので、RB7をHiにするとLEDが点灯し、Loにすると消灯します。

■センサー

 今回はセンサーダミーとしてスライドボリュームをつけてみました。電圧変化型のセンサーなら同じように値を読み取ることができます。



<PIC側プログラム説明>

 開発環境はMPLABv8.90、コンパイラはHI-TECH Cを使用しました。どちらも無償で入手できます。PIC側のプロジェクト全体を圧縮したものはこちら。

 WiMaster_test4.zip


 送信、受信、両方のデモを行うため、センサー値を送信し、受信した値によりLEDを点灯させるプログラムを作りました。

 

■初期設定

 初期設定部分は次のようになります。

//////////////////////////////////////
// define
// //////////////////////////////////////
#define LED PORTBbits.RB7
#define ON 1
#define OFF 0

//////////////////////////////////////
// initial setting //
//////////////////////////////////////
void init_IO(){
 //clock
  OSCCON = 0b11110000; //32MHz(4xPLL=enable FOSC=8MHz OSCSetting=CONFIGbit)
  //IO
  ANSELA = 0b00000000; //1:Analog, 0:Digital
  ANSELB = 0b00100000; //1:Analog, 0:Digital *RB5 is analog
  TRISB = 0b01111111; //0:output 1:input *TB7 is outout
  //UART
  SPBRG = 51; //9600bps (FOSC=8MHz (without PLLx4))
  TXEN = 1;
  SYNC = 0;
  SPEN = 1;
  CREN=1;
  RCIE=1; //RC intrrupt enable
  //ADC setting
  ADCON0 = 0b00110101; //AN13 select, DONE=0, ADON=1
  ADCON1 = 0b00100000; //Left, FOSC/2, VREF-=VSS, VREF+=AVDD
  //Intrrupt
  PEIE=1;
  GIE=1;
}

 内部8MHz駆動で、UARTは9600bps、LED用にRB7をデジタル出力へ設定、センサー用にRB5(AN13)をanalog入力ポートに設定しています。

 受信は割り込みで受けるので、割り込みも有効に設定しています。

 

■データ受信

//////////////////////////////////////
// interrupt //
//////////////////////////////////////
static void interrupt
isr(void){
  //受信割り込み
  if(RCIF == 1){
   unsigned char getData;
   RCIF = 0;
   getData = RCREG;
   //LED判定
   if(getData==0x01){
    LED=ON;
   }else if(getData==0x00){
    LED=OFF;
   }
  }
}

 受信は割り込みで受けて、0x01ならLEDをON、0x00ならオフしています。HI-TECH Cの場合、割り込み後にどのフラグが立ったかで何の割り込みかを判定しています。UARTの受信割り込み発生時にはRCIFフラグがたちます。このフラグはRCIF = 0;のようにプログラムでリセットする必要があります。

 

■メイン(一定周期でセンサーデータを読んで送信)

//////////////////////////////////////
// main //
//////////////////////////////////////
void main(){

  //初期設定
  init_IO();

  //300mSごとにセンサーデータを送る。受信は割り込みで処理。
  while(1){
   TXREG=readADC();
   wait_ms(100);
  }
}

 readADC( )はADCで読んだ値を返す関数です。 wait_ms( )は引数mS間ウェイトする関数です。中身はソースを参照願います。TXREGに値をセットすると自動で送信されます。

 メインループでは一定周期でセンサーデータを送っているだけです。受信は先の割り込みルーチンで処理されます。

 


<Android側プログラム説明>


 ここでは、Android端末とWiMasterはすでにアソシエーションまで済んでいるとします。この操作についてはWiMasterの説明ページの<動作説明>の部分を参照願います。


 通信はSocket通信で行います。
 Androidndの場合、Socket
クラスがあるのでこれを使います。

 Eclipse上で作成したAndroidのJavaアプリを圧縮したものがこちらになります。

 WiMaster_test_Android4.zip



 画面イメージ

 


 画面レイアウトはXMLで記述しています。詳細はソースを参照願います。センサーデータは一番上に表示され、「LED ON」ボタンを押すと0x01が送信、「LED OFF」ボタンを押すと0x00が送信されます。

 

■画面部


 起動時に画面を構成しているところが次の部分です。


 

■Socket開通部

 次に今回のポイントである、ソケット通信の部分を説明します。


 画面が表示されるとき(onResume)にソケットを開き、画面が閉じたらソケットを閉じています。ソケットを開く部分は別スレッドで実行します。実際の接続処理はconnectメソッドで行っています。






 connectメソッドの中身はこのようになっています。

 Socketクラスのインスタンスsocketにsocket=new Socket(ip,port);でソケットを開いています。ipはString型で、WiMaster購入時についてくる紙に書かれたIPを指定します。"0.0.0.0"のように指定します。portも購入時の紙に書いてあるポート番号を指定します。


 その後、ソケット開通をisConnected()で確認し、受信ループを作っています。この受信ループは、先のonResume内で別スレッドで構成されていますので、メインスレッドとは別にこのループが動きます。受信ループ内では、ループ毎に受信バッファから読み込み、読み込みバイト数が0以下でなかったら(なにか受信されてたら)データをイベントハンドラに渡します。このとき、何のイベントかを識別するためにWiFiComWhat定数をセットしています。

 

■受信

 イベントハンドラ部では、来たイベントがWiFiComWhatであったら、画面に表示させています。画面表示部はchkRcvData( )で処理させています。

 

 chkRcvData( )では、来たデータの先頭1バイトを符号なしintに変換し、TextViewのインスタンスであるsensorTextに表示させています。

 


 

■送信

 ボタンを押してデータを送る部分を説明します。

 まず、ボタンを押すと、ボタンクリックのイベントが動きます。



 それぞれのボタンを識別して0x01か0x00を送っています。




 送信は、byte[]配列を、outputStreamのインスタンスoutに、writeメソッドを使って渡しているだけです。これでデータが送信されます。

 

 iPhoneでも同じようにソケット通信で、同じハードウェアを動かすことができます。WiMasterのページのサンプルプログラムの節、他のデバイスでの例を掲載しています。

 


<動作時間>


 このWiFiモジュールはBluetoothなみの低消費電力で動きます。電波を発射するので、送信の方が受信よりも電力を使います。

 今回の例では100mS毎にセンサーデータを送信していますが、これを1秒間隔で送信に変更し、実験したところ、乾電池2本で連続で33時間駆動できました。携帯機器の性能としてはまあまあだと思います。電池部を充電可能なものにしたり、大きなバッテリで動くものに搭載して一定周期でセンサーデータを送る、などもできると思います。




以上







(C)Copylight 2003. 有限会社浅草ギ研 | 通信販売の法規(訪問販売法第8条)に基づく通信販売業者の表示