コンピュータを楽しもう!!

今、自分が面白くていろいろやってみたことを書き綴りたいと思います。連絡先はtarosa.yでgmail.comです。

卓上ロボット掃除機の改造 (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()