車子的硬體部份和「雄 : 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 了,
後記
用過別人買的藍芽模組 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」文中的第二支程式,它可以自訂每個按鈕要發送的資料。
檔案下載
相關文章
雄大你好~
回覆刪除小弟對arduino很感興趣,但完全是個外行,已經買了一本書,也慢慢開始翻閱,但還是不知道如何下手,目前有個問題想請教一下,也跟我工作有關,利用藍芽來傳輸動作收話及發話,簡單說要像無線電的動作一樣,按下去發話,放開收話不知能否做到這樣,要如何準備例如該買哪腫模組來搭配,我只知道藍芽模組,但主板不知道應該買哪一種,網路上也沒找到相關課程,剛好經貴過站,請雄大不吝賜教
您好:
刪除哈~我跟您一樣,只是有興趣,但外行的人,純屬玩一玩而已。
文章中提到的是我現有的經驗, 至於您提的問題, 已超出我所知的,實在沒什麼經驗可以跟您分享吔,真是抱歉。
您好,我這有個例子,在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);
}
雄老師您好:
回覆刪除小弟是剛入門的初學者,我已照著這篇的教學文做好了APP
只是在要輸入ARDUINO的程式部分尚未對S4A十分明瞭,想問說是否S4A安裝到ARDUINO後,此APP就可以直接控制呢?還是程式部分還要另外再加更改?謝謝: )
您好:
刪除如果您的 Arduino 有安裝 S4A 的靭體,照說就可以控制。不過,這支程式後來我有再調整過,圖沒再更新。比較建議您參考我今天貼的文章,這支最新的程式較沒 bugs,文中也附了 source。
恩恩,非常感謝喔: )
回覆刪除可以請教一下嗎?
回覆刪除我想學如何使用藍芽去控制電源供給跟調整時間!!
Jacky 您好:
刪除不是很懂您的意思, 以我文章中的架溝, 藍芽只是幫忙傳指令(文字)給 Arduino , 而那些指令(文字)代表什麼, 就得看您在 Arduino 中怎麼解譯並執行,決定權在您自己寫的程式收到文字後要做什麼,您想讓它做什麼它就做什麼。
可以請教一下,我有下載android bt on s4a,紅綠燈還有音響是ok的,但只要
回覆刪除一用到motor4或motor7的左右輪正轉逆轉前進之類的,就沒法動,之後連紅綠燈也沒法用一整個當掉,要怎麼調整?
阿傑您好:
刪除很抱歉,對於您的東西一點概念都沒有,不知要從何除錯起吔!您的電子元件接在 Arduino 的哪些腳位?如何接會影響遙控的結果。
「android bt on s4a」並不是我的作品,據我了解,motor4 / motor7 的每個按鈕會送出固定的資料給 Arduino pin 4, ping 7,詳細的資料我並不清楚。
雄老師您好:
回覆刪除我想請教您,就是我用手機app通過藍芽控制馬達轉動,沒有用 到Arduino,
但我想請較藍芽角為開關應該怎麼設定?因為我有八個output,我只用其中兩個output,我只是想利用手機APP按鈕來開與關馬達就好,我要開通的腳位是pin25和pin29,我藍芽參數為115200(串列傳輸速率),我現在目前問題就是藍芽連接那些都行,就是腳位的開通不知道如何開通。謝謝您的回覆
我的架構是由 Arduino 進行訊息處理及控制, 藍芽只是負責接收由手機傳來的訊息, 對藍芽而言,不會去影響電路上的其它元件, 開關的控制是由 Arduino 來完成的, 馬達無法直接和藍芽通訊, 藍芽無法直接控制開關。
刪除照您的描述, 您沒有使用 Arduino 當控制器, 應該有替代的元件, 實在不知您有的是什麼, 無從回答起吔~不過, 哈!我也只玩過 Arduino XD
請問一下...我是第一次用arduino,請問要怎麼用手機透過xbee控制馬達的轉速...?
回覆刪除目前卡在手機app無從做起,還有怎麼連結控制也是一頭霧水><
胡凱迪您好:
刪除抱歉, 沒玩過 xbee, 至於如何控制馬達的轉速, 用 google 找一下, 應該可以找到很多做法,祝您順利找到您要的資料。
您好
回覆刪除想請問一下 我使用Arduino 接BT與手機溝通 我手邊有一個溫度傳感器,Arduino端要怎麼寫才能將溫度的值丟給手機APP去接收
阿勝您好:
刪除我想,您需要 Google 的關鍵字是「arduino 溫度傳感器 android」
不好意思 想請教一下
回覆刪除我是用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的藍芽傳輸要如何修改?
如果是要和 S4A 連線,只能將速率設定為 38400,它的 Scratch 改過的,預設用 38400 在通訊,因此,Arduino 及藍牙模組都只好用這個數。
刪除APP如何用x.y.z三軸加速度達到馬達條訴的功能啊??
回覆刪除那用字元的方式傳送到藍芽達到調速,按一次讀X的值,按第二次讀X+1的值一直到X+4的值=255,要怎麼設計啊?
請問有辦法用這個程式藍芽控制我電腦S4A做的遊戲嗎
回覆刪除您好:
刪除這支程式是用來控制 Arduino, 它並不和電腦通訊, 如果您是要和電腦中的 S4A (Sracth) 通訊, 應該是不行。Scratch 有提供 "Remote sensor Connections " 的功能, 可能要朝這個方向去試:
http://wiki.scratch.mit.edu/wiki/Remote_Sensor_Connections
你好 請問 距離回傳值 跟 控制動作 要如何整合在一起?
回覆刪除現在 分開來做 距離回傳 正常 控制動作 正常 但是 整合在一起 可以正常動作 但是 距離回傳值卻 回傳錯誤訊息
雄老師你好
回覆刪除想請教您
我有一塊UNO板子還有藍芽與相機模組
有沒有辦法用AI2設計出 手機可以接收相機的畫面呢
您好:
刪除個人對 AI2 並沒有那麼熟啦!
看您的需求是想由 Arduino 拍照,再由 AI2 中顯示,建議您查一下 AI2 有關影音的說明:
http://appinventor.mit.edu/explore/ai2/concepts/images-and-sounds.html
手機可以連網路,如果 Arduino 也搭配網路並讓手機可以連到,應該是有機會的。至於純用藍牙透過 txd/rxd 來傳輸,速度應該有限(純想像而已)。以上, 您可能要自己試試。
雄老師您好:
回覆刪除想請問一下,我們按前進的時候,Arduino會發出BB的聲音,而且沒有辦法移動。
您好:
刪除會不會是電力不足的關係?
請問藍芽接收器是要買? 哪裡購買比較快呢
回覆刪除不好意思 我想請教一下 App Inventor的Blocks 圖四 pin value 是怎麼出現在紫色方塊裡的 因為我找不到您的信箱 所以我就在這留言給您
回覆刪除您好, 紫色的是「Built-in」 中的「Procedures」新增完, 只要按一下積木左上角的設定圖示(齒輪)就可以增加要傳入的變數(將 input 拉到右邊 的 inputs 積木)。
刪除