2014年3月23日 星期日

Arduino : 用 Android 遙控藍芽科學魔法車

上回以「S4A」(Scratch for Arduino)在電腦上透過藍芽無線遙控科學魔法車,也試過別人寫的 Android App 來遙控同一臺車,其實如果有 Scratch 的設計經驗,可以試試具類似界面的「MIT App Inventor」來製作自己的 Android App。之前都沒有 App Inventor 使用經驗的我,算是第一次就上手,在 S4A firmware 傳輸資料的演算法弄清楚後,試著寫出了遙控 S4A 科學魔法車的 Android App 了,簡單、好玩!雖然仍然有 bugs,分享一下製作的心得。



車子的硬體部份和「雄 : Arduino : S4A 藍芽無線遙控科學魔法車」一文中的相同,Aruduino 靭體的部份用的是 S4A 官網中 1.5 版的靭體,Android App 開發工具則是「MIT App Inventor 2」。


新增了 Project 後,在 App Inventor 設計畫面中依序拖曳了以下的元件到 Screen1 裡:

  • Label:Label1 顯示連線狀態
  • ListPicker:ListPicker1 未連線時,按下去後顯示搜尋到的藍芽裝置清單供選取並連線;已連線則供切斷藍芽連線用。
  • Label:LabelPower:顯示目前馬達馬力的設定值。
  • Slider:Slider1 供設定馬達馬力的設定值。最大值 255,最小為值 0,初始值設為 128。
  • TableArrangement:TableArrangement1 供放置控制車子方向的按鈕,設為 3x5 格。
  • Button:拉五個 Button 至 TableArrangement1 內,分別命名為 ButtonFD (前進)、ButtonBK(後退)、ButtonRT(右轉)、ButtonLT(左轉)及 ButtonStop(停止)。
  • Label:在 TableArrangement1 加入一個名為 LabelStatus 的 Label,顯示按了哪一個按鈕。
  • Label:lblResult 顯示錯誤訊息、Arduino 傳來的 sessors 值或其它訊息用。
  • BluetoothClient:由 connectivity 中拉一個 BluetoothClient 到 Screen1 中,這樣就具有藍芽的功能了。
  • Clock:拖曳兩個 Clock 到 Screen1 中,Clock1 用來定時擷取 Arduino 傳來的資料,Clock2 則是定時傳 2 bytes 空字元給 Arduino ,讓它確認和 Android 的連線持續中。

Screen1 的畫面安排妥當,就可以點選 App Inventor 右上角的「Blocks」開始編寫程式,底下是程式的內容:

※ 新增兩個 global 變數分別用來儲存馬達的馬力設定值及連線中的藍芽網址。

※ 設定 ListPicker1 在沒被按下去前,抓搜尋到的藍芽裝置清單或只顯示中斷目前連線的選項。

※ 當使用者由 ListPicker1 選了選項後,進行藍芽連線或是中斷藍芽連線。

※ 當使用者調整了 Slider1 後,把值以無條件捨去取整數並設定給 power 這個變數,供之後設定 Arduino pin5、pin6 用。

※ 透過藍芽傳送指定腳位的值給 Arduino

根據 S4A 給 Arduino 用的 firmware 程式碼中觀察,它在傳送或接收資料時是以 2 Bytes 為單為,第一個 byte 必須大於 128 (最高 bit 為 1),最低的三個 bits 為腳位值大於 127 的部份,接著則為腳位序號。第二個 byte 必須小於等於 127 ,存放欲設定腳位值的最低 7 bits。簡單的利用下面的算式重組 pin (Arduino 腳位) 及 value (欲設定的值):

  • valueHighBit = floor(value/128)
  • 第一個 byte:pin * 8 + 128 + valueHighBit
  • 第二個 byte:value - 128 * valueHighBit (也可以用 modulo 直接取 value / 128 的餘數)。


※ 傳送控制兩顆馬達正轉或逆轉 Arduino 腳位的設定值:

此部份和在 Srcatch 中一樣:

  • 右側馬達由 pin 5 控制轉速(0~255),pin 10 Off + pin 11 On 逆時轉(前進),反之 pin 10 On + pin 11 Off 順時轉(後退)。
  • 左側馬達由 pin 6 控制轉速(0~255),pin 12 Off + pin 13 On 逆時轉(前進),反之 pin 12 On + pin 13 Off 順時轉(後退)。

因為 pin 10, 11 值相反,而 pin 12, 13 相反,因此用前者的值加 1 後取除以 2 的餘數即可 0 變 1,1 變 0 。


※ 控制車子運行方向的五個按鈕
前、後、左、右
停止

※ 維持「上線狀態」(設定每 750ms 執行一次)

照說,有了前面的程式,應該可以透過 Android App 來控制載有 Arduino + S4A firmware 的科學魔法車,測試的結果卻很奇怪,車子跑一下就「熄火」停下來,得再度按按鈕才能再動一下,這部份和在 Scratch 中的執行結果完全不同。追了一下 S4A 的靭體,它如果沒有從 Serial port 中讀到 2 bytes 資料,一秒鐘後呼叫「checkScratchDisconnection()」,而它會將 Arduino pin 12 以下的其它腳位值設為 0,這樣就「熄火」了!為了避免這種情形發生,利用 Clock2 中的程式碼,每隔 750 ms 送 2 bytes 空資料給 Arduino ,讓它知道 Android 還在線。

※ 顯示錯誤訊息或其它訊息


※ 接收 Arduino 傳來的感應器值
2014.04.05 更新過後的 S4A Arduino 資料接收程序


以上為目前第一版的程式,大致上可以遙控安裝 S4A firmware 的 Arduino 了,不過尚有一隻大臭蟲不知問題在哪裡(2014.03.30 找到bug了,Arduino傳來的資料未接收,資料塞到爆掉),這個 App 玩太久,藍芽會掛掉,得將 App 強制關閉,嚴重時,藍芽必須關閉,重新啟用才能繼續用。而且 Android 機器愈新愈快的,掛掉的愈快,我爛爛的 Android 2.3 手機就可以撐很久不掛掉。在猜想,可能是 App Inventor 程式中,藍芽傳輸時的流量管控有問題。有空再用 Java 重寫,比較看看。


後記

用過別人買的藍芽模組 HC-06 後,發現 HC-06 可以很正常的運作,而 HC-05 會掛掉,App 掛掉的原因應該是找到了,我的 HC-05 實在太弱了,180 元買的,錢花得比人少,穏定性也比較差,一分錢一分貨啦!

2014.03.30 HC-05 掛掉的原因可能是處理 Arduino 送來的資料來不及的關係,所以「接收 Arduino 傳來的感應器值」的 block 應該要改為:每隔0.5秒鐘,利用「ReceiveUnisignedBytes NumberOfBytes」及「BytesAvailableToReceive」把送來的資料一次取走,HC-05 就不再掛掉了。滿納悶的,為什麼 HC-06 不會這樣?

接收資料的程序最佳化:只分析最後收到的 16 bytes ( A0~A5 + D2 + D3,每個 Arduino 的 output 2 bytes)。

如果想要彈性大一點的遙控 App,建議參考「雄 : Android : S4A_Bluetooth 藍芽遙控 App」文中的第二支程式,它可以自訂每個按鈕要發送的資料。


檔案下載




相關文章



27 則留言:

  1. 雄大你好~
    小弟對arduino很感興趣,但完全是個外行,已經買了一本書,也慢慢開始翻閱,但還是不知道如何下手,目前有個問題想請教一下,也跟我工作有關,利用藍芽來傳輸動作收話及發話,簡單說要像無線電的動作一樣,按下去發話,放開收話不知能否做到這樣,要如何準備例如該買哪腫模組來搭配,我只知道藍芽模組,但主板不知道應該買哪一種,網路上也沒找到相關課程,剛好經貴過站,請雄大不吝賜教

    回覆刪除
    回覆
    1. 您好:
      哈~我跟您一樣,只是有興趣,但外行的人,純屬玩一玩而已。
      文章中提到的是我現有的經驗, 至於您提的問題, 已超出我所知的,實在沒什麼經驗可以跟您分享吔,真是抱歉。

      刪除
    2. 您好,我這有個例子,在arduino ide裏面灌入,效果是手機按下去,一個pin持續供電(可以是繼電器、LED),鬆手斷電。
      (配合手機藍牙發射APP,發送單字節1為高電平,2低電平)

      void setup() {
      pinMode(13, OUTPUT);
      Serial.begin(9600);
      }
      void loop() {
      while(Serial.available() )
      if(Serial.read() == '1')
      digitalWrite(13, HIGH);
      if(Serial.read() == '2')
      digitalWrite(13, LOW);
      }

      刪除
  2. 雄老師您好:
    小弟是剛入門的初學者,我已照著這篇的教學文做好了APP
    只是在要輸入ARDUINO的程式部分尚未對S4A十分明瞭,想問說是否S4A安裝到ARDUINO後,此APP就可以直接控制呢?還是程式部分還要另外再加更改?謝謝: )

    回覆刪除
    回覆
    1. 您好:
      如果您的 Arduino 有安裝 S4A 的靭體,照說就可以控制。不過,這支程式後來我有再調整過,圖沒再更新。比較建議您參考我今天貼的文章,這支最新的程式較沒 bugs,文中也附了 source。

      刪除
  3. 恩恩,非常感謝喔: )

    回覆刪除
  4. 可以請教一下嗎?
    我想學如何使用藍芽去控制電源供給跟調整時間!!

    回覆刪除
    回覆
    1. Jacky 您好:
      不是很懂您的意思, 以我文章中的架溝, 藍芽只是幫忙傳指令(文字)給 Arduino , 而那些指令(文字)代表什麼, 就得看您在 Arduino 中怎麼解譯並執行,決定權在您自己寫的程式收到文字後要做什麼,您想讓它做什麼它就做什麼。

      刪除
  5. 可以請教一下,我有下載android bt on s4a,紅綠燈還有音響是ok的,但只要

    一用到motor4或motor7的左右輪正轉逆轉前進之類的,就沒法動,之後連紅綠燈也沒法用一整個當掉,要怎麼調整?

    回覆刪除
    回覆
    1. 阿傑您好:
      很抱歉,對於您的東西一點概念都沒有,不知要從何除錯起吔!您的電子元件接在 Arduino 的哪些腳位?如何接會影響遙控的結果。
      「android bt on s4a」並不是我的作品,據我了解,motor4 / motor7 的每個按鈕會送出固定的資料給 Arduino pin 4, ping 7,詳細的資料我並不清楚。

      刪除
  6. 雄老師您好:
    我想請教您,就是我用手機app通過藍芽控制馬達轉動,沒有用 到Arduino,
    但我想請較藍芽角為開關應該怎麼設定?因為我有八個output,我只用其中兩個output,我只是想利用手機APP按鈕來開與關馬達就好,我要開通的腳位是pin25和pin29,我藍芽參數為115200(串列傳輸速率),我現在目前問題就是藍芽連接那些都行,就是腳位的開通不知道如何開通。謝謝您的回覆

    回覆刪除
    回覆
    1. 我的架構是由 Arduino 進行訊息處理及控制, 藍芽只是負責接收由手機傳來的訊息, 對藍芽而言,不會去影響電路上的其它元件, 開關的控制是由 Arduino 來完成的, 馬達無法直接和藍芽通訊, 藍芽無法直接控制開關。
      照您的描述, 您沒有使用 Arduino 當控制器, 應該有替代的元件, 實在不知您有的是什麼, 無從回答起吔~不過, 哈!我也只玩過 Arduino XD

      刪除
  7. 請問一下...我是第一次用arduino,請問要怎麼用手機透過xbee控制馬達的轉速...?
    目前卡在手機app無從做起,還有怎麼連結控制也是一頭霧水><

    回覆刪除
    回覆
    1. 胡凱迪您好:
      抱歉, 沒玩過 xbee, 至於如何控制馬達的轉速, 用 google 找一下, 應該可以找到很多做法,祝您順利找到您要的資料。

      刪除
  8. 您好
    想請問一下 我使用Arduino 接BT與手機溝通 我手邊有一個溫度傳感器,Arduino端要怎麼寫才能將溫度的值丟給手機APP去接收

    回覆刪除
    回覆
    1. 阿勝您好:
      我想,您需要 Google 的關鍵字是「arduino 溫度傳感器 android」

      刪除
  9. 不好意思 想請教一下
    我是用Motoduino(Arduino + L293D)這塊來做
    在腳位上有些不同
    研究您的APK程式後,我是直接把左右轉角位改成5 6 7 8
    5 8腳位為一組 5腳位控制PWM 8腳位控制正反轉(0正轉與1反轉)
    6 7腳位為一組 6腳位控制PWM 7腳位控制正反轉(0正轉與1反轉)
    而S4A firmware15 的部分我則參考網路上的 已把腳位設定與Motoduino 相同,也用S4A測試過,腳位修改成功但APK修改完後安裝,藍芽有連接到,但按鍵皆無反應,想請教一下是哪方面有問題

    我之前用Motoduino附贈的APK測試軟體也有過一樣的問題,後來是靠修改ardunio韌體的藍芽傳輸鮑率(57600)才會有動作,不知是否為一樣問題??
    如為一樣問題,想請教一下S4A firmware15的藍芽傳輸要如何修改?

    回覆刪除
    回覆
    1. 如果是要和 S4A 連線,只能將速率設定為 38400,它的 Scratch 改過的,預設用 38400 在通訊,因此,Arduino 及藍牙模組都只好用這個數。

      刪除
  10. APP如何用x.y.z三軸加速度達到馬達條訴的功能啊??
    那用字元的方式傳送到藍芽達到調速,按一次讀X的值,按第二次讀X+1的值一直到X+4的值=255,要怎麼設計啊?

    回覆刪除
  11. 請問有辦法用這個程式藍芽控制我電腦S4A做的遊戲嗎

    回覆刪除
    回覆
    1. 您好:
      這支程式是用來控制 Arduino, 它並不和電腦通訊, 如果您是要和電腦中的 S4A (Sracth) 通訊, 應該是不行。Scratch 有提供 "Remote sensor Connections " 的功能, 可能要朝這個方向去試:
      http://wiki.scratch.mit.edu/wiki/Remote_Sensor_Connections

      刪除
  12. 你好 請問 距離回傳值 跟 控制動作 要如何整合在一起?
    現在 分開來做 距離回傳 正常 控制動作 正常 但是 整合在一起 可以正常動作 但是 距離回傳值卻 回傳錯誤訊息

    回覆刪除
  13. 雄老師你好
    想請教您
    我有一塊UNO板子還有藍芽與相機模組
    有沒有辦法用AI2設計出 手機可以接收相機的畫面呢

    回覆刪除
    回覆
    1. 您好:
      個人對 AI2 並沒有那麼熟啦!
      看您的需求是想由 Arduino 拍照,再由 AI2 中顯示,建議您查一下 AI2 有關影音的說明:
      http://appinventor.mit.edu/explore/ai2/concepts/images-and-sounds.html

      手機可以連網路,如果 Arduino 也搭配網路並讓手機可以連到,應該是有機會的。至於純用藍牙透過 txd/rxd 來傳輸,速度應該有限(純想像而已)。以上, 您可能要自己試試。

      刪除
  14. 雄老師您好:

    想請問一下,我們按前進的時候,Arduino會發出BB的聲音,而且沒有辦法移動。

    回覆刪除
    回覆
    1. 您好:
      會不會是電力不足的關係?

      刪除
  15. 請問藍芽接收器是要買? 哪裡購買比較快呢

    回覆刪除

 
© 2009. Design by Pocket