卓上ロボット掃除機の改造 (6)
LuaridaとPIC Microbridge Cleanerプログラムが通信し、ロボットを動かすプログラムについて説明します。
テストプログラムは、最後に添付します。
tcp通信接続
sock.nlistenOpen()で60101ポートへの接続を10秒間待ちます。現状、PIC側よりも先に待たないと、うまく接続してくれないのですが、ここら辺が分からないところです。Microbridgeの勉強不足です。
--60101ポートへの接続を10秒間待つ local ret = sock.nlistenOpen( 1, 60101, 10 ) if( ret~=1 )then dialog( "adb接続に失敗しました", "終了します" , 1 ) system.exit() end --接続できたことを表示する print( "MicroBridgeと接続しました")
PICへのコマンド送信
PICにデータを送信するプログラムです。cmdに代入された2バイトデータをsock.nsend()で送信します。送信後、PICからの1バイト返信(Ack)を待ちます。返信(Ack)が返ってこない場合は、再度送信します。後は超適当に時間を待っています。
------------------------------------------ --コマンドを送信します -- 引数 送信コマンド, 動作時間 ------------------------------------------ function sendcmd( cmd, sec ) local txt, ret,psec while( true )do sock.nsend( 1, cmd, 2 ) if( cmd:sub(1,1)=="Q" )then break end txt, ret = sock.nrecv( 1 ) if( txt==cmd:sub(1,1) )then break end print( "コマンド送信に失敗しました" ) end psec=system.getSec() + sec -0.4 while psec>system.getSec() do end end
実際のコマンド送信
Luaではバイナリ配列を文字列として扱うことが出来ます。0x0も扱えます。文字列にバイナリコードを入れるには、string.char()を使います。
以下は前進コマンドの例です。例では cmd = "F"..string.char(p) と書いていますが、 このように、cmd = "F"..p:char() とも書けます。
local cmd local p = 40 --2sec 前進 cmd = "F"..string.char(p) sendcmd( cmd, 2 )
通信終了
通信の終了は、Qコマンドを送信して、ソケットをクローズします。Qコマンドが送信された場合は、PICマイコンをhalt状態にすればいいのかな。ここら辺は今後の課題です。
--終了 cmd = "Q"..string.char(p) sendcmd( cmd, 0.2 ) sock.nclose( 1 ) dialog( "テスト走行終了", "電源を切ってください" , 1 )
最後にLuaridaのテストプログラムと動画を添付しておきます。
------------------------------------------ -- Robot Test ------------------------------------------ --関数宣言-------------------------------- main={} --mainメソッド setTateGamen={} --縦向きに変更 print={} --スクロールするテキスト表示 sendcmd={} --コマンドを送信します --グローバル変数宣言---------------------- ------------------------------------------ mt={} mt.__newindex=function(mtt,mtn,mtv) dialog( "Error Message", "宣言していない変数 "..mtn.." に値を入れようとしています", 0 ) toast("画面タッチで実行を続けます", 1) touch(3) end mt.__index=function(mtt,mtn) dialog( "Error Message", "変数 "..mtn.." は宣言されていません", 0 ) toast("画面タッチで実行を続けます", 1) touch(3) end setmetatable(_G,mt) --------以下が実プログラム---------------- ------------------------------------------ --縦向きに変更 ------------------------------------------ function setTateGamen() system.setScreen(1) --内部グラフィック画面設定の変更 local w,h = canvas.getviewSize() canvas.setMainBmp( w, h ) end ------------------------------------------ --スクロールするテキスト表示 -- 文字, サイズ, 色, 背景色 ------------------------------------------ function print(...) local w, h = canvas.getviewSize() --画面サイズ取得 local t={...} local str = t[1] if( str==nil )then str = "" end local fontsize = t[2] if( fontsize==nil )then fontsize = 18 end local fcolor = t[3] if( fcolor==nil )then fcolor = color(0,0,0) end local bcolor = t[4] if( bcolor==nil )then bcolor = color(255,255,255) end --一度、見えないところにテキストを書いて、改行数を求める local sc = canvas.putTextBox( str, 0, h+1, fontsize, fcolor, w ) --画面の絵をワークエリアに取り込みます canvas.getg( 0, fontsize*sc, w-1, h-1, 0, fontsize*sc, w-1, h-1 ) --取り込んだ画面をスクロールさせて描きます canvas.putg( 0, 0, w-1, h-fontsize*sc-1, 0, fontsize*sc, w-1, h-1 ) --書き出す部分をバックカラーで塗り潰します canvas.putRect( 0, h-fontsize*sc-1, w, h, bcolor, 1 ) --スクロールしたところにテキストを書きます canvas.drawTextBox( str, 0, h-fontsize*sc, fontsize, fcolor, w ) end ------------------------------------------ --コマンドを送信します ------------------------------------------ function sendcmd( cmd, sec ) local txt, ret,psec while( true )do sock.nsend( 1, cmd, 2 ) if( cmd:sub(1,1)=="Q" )then break end txt, ret = sock.nrecv( 1 ) if( txt==cmd:sub(1,1) )then break end print( "コマンド送信に失敗しました" ) end psec=system.getSec() + sec -0.4 while psec>system.getSec() do end end ------------------------------------------ --メインプログラム ------------------------------------------ function main() --画面を縦向きに変更 setTateGamen() canvas.drawCls( color(255,255,255) ) --背景を白色に system.setSleep(0) --スリープしない --60101ポートへの接続を10秒間待つ local ret = sock.nlistenOpen( 1, 60101, 10 ) if( ret~=1 )then dialog( "adb接続に失敗しました", "終了します" , 1 ) system.exit() end --接続できたことを表示する print( "MicroBridgeと接続しました") local cmd local p = 40 --2sec 前進 cmd = "F"..string.char(p) sendcmd( cmd, 2 ) --2sec 後退 cmd = "B"..string.char(p) sendcmd( cmd, 2 ) --5sec 停止 cmd = "S"..string.char(p) sendcmd( cmd, 5 ) --2sec 右回転 cmd = "R"..string.char(p) sendcmd( cmd, 2 ) --2sec 左回転 cmd = "L"..string.char(p) sendcmd( cmd, 2 ) --終了 cmd = "Q"..string.char(p) sendcmd( cmd, 0.2 ) sock.nclose( 1 ) dialog( "テスト走行終了", "電源を切ってください" , 1 ) end main() system.exit()