HC-05藍牙模組補充說明(五):透過藍牙上傳Arduino程式碼

最近參考了Make雜誌的「自製Arduino藍牙程式編寫擴充板」文章,簡化電路之後,組裝一個藍牙無線上傳Arduino程式碼的電路板,並且用行動電源供電。假如你製作一個Arduino藍牙遙控車,需要經常修改、上傳程式碼,那麼,藍牙上傳程式碼很便利;但大多數情況,其實USB連線也很好用 😛

採用行動電源供電,藍牙上傳Arduino程式的模組。

實驗材料:

  • HC-05序列模組,一個。
  • 1KΩ~4.7KΩ電阻,一個。
  • 1μF~10μF電容,一個。
  • (選擇性的)Arduino原型擴充板,一片。

實驗電路:

本單元電路將取代Arduino的USB有線序列埠,因此HC-05模組接在Arduino的數位0與1腳

藍牙上傳Arduino程式的電路圖

電路說明:

Arduino編輯器在上傳(燒寫)程式之前,會先重置(reset)Arduino板,接著以115200bps57600bps鮑率傳遞程式碼。只要序列埠的電路符合這兩個條件,就能上傳程式碼。

若把Arduino微控器的Reset腳接低電位,它將會重置。因此,Arduino控制板預設把Reset腳透過10KΩ電阻連接到高電位。

透過電容自動重置Arduino控制板

若在Reset腳銜接一個1μF電容再接地,Arduino一開始將會處於「重置」狀態,經過約10ms之後,Arduino才會開始運作(註:電容充滿約70%所需的時間為一個時間常數τ,也就是R×C,10KΩ×1μF=10ms)。

HC-05藍牙序列模組具有可程式化輸出∕輸入(Programmable I/O)介面,並可透過AT命令設置介面的工作模式。如果能在藍牙模組開始連線時,讓它的某個接腳輸出低電位,連接到1μF電容,即可重置Arduino控制板。

設定HC-05藍牙序列通訊模組的AT命令

HC-05模組正好有個AT+POLAR命令,它原本的作用是切換連接在模組PIO9與PIO8(實際對應到32和33腳)的LED狀態燈訊號。如果對HC-05下達此AT命令:

AT+POLAR=1,0

可令HC-05在藍牙連線成功時,於PIO9(模組的32腳)輸出低電位(註:這道命令的第一個參數1,代表「當PIO8輸出高電位時,點亮LED」,第二個參數0代表「連線成功時,PIO9腳輸出低電位」)。

HC-05藍牙模組的PIO9接腳

我購買的HC-05模組的PIO9腳,連接到標示為STATE的接腳,因此不需要額外焊接;否則,請自行焊一條連接PIO9(32腳)與電容負極的導線。接下來,只要將藍牙模組的傳輸速率改成底下的數值即可:

  • 115200bps:用於連接UNO板。
  • 57600bps:連接Duemilanove、自製的Arduino、Leonardo…等控制板。

若要查閱上傳程式碼的傳輸速率,可開啟Arduino軟體安裝資料夾, “hardware\arduino\avr”路徑裡的boards.txt檔。這個文字檔包含Arduino控制板的燒錄參數,查閱“speed”,即可找到上傳程式碼的速率:

從boards.txt檔查詢Arduino燒錄的傳輸速率

請依照「HC-05與HC-06藍牙模組補充說明(三):使用Arduino設定AT命令」或「執行AT命令(AT-command)修改藍牙模組的資料傳輸速率」說明,進入HC-05模組的AT命令模式,並依序輸入下列AT命令(井號以及後面的文字是註解,請勿輸入):

AT+ORGL             # 將藍牙模組回復成原廠設定(此步驟可省略)
AT+ROLE=0           # 將HC-05設置為「從機」
AT+POLAR=1,0        # 藍牙連線成功時,在PIO 9輸出低電位。
AT+UART=115200,0,0  # 設定傳輸速率115200、一個停止位元、沒有同位位元
AT+INIT             # 初始化藍牙模組(此步驟可省略)

設定AT命令後,再將此HC-05藍牙模組依照上文的電路接好。

實際測試藍牙上傳Arduino程式碼

先讓電腦與藍牙模組配對,並確認其通訊埠號(COM編號)之後,再開啟Arduino(我用行動電源接電給Arduino)。接著就和往常一樣,選擇連接到電腦的藍牙序列埠(在我的電腦上是COM13),即可上傳程式碼。

選擇藍牙COM埠

藍牙上傳程式所需時間,跟使用USB連線差不多;若出現如下的錯誤訊息,請確認COM埠編號是否正確

avrdude: ser_open(): can’t open device “\\.\COM13”: 信號等待逾時。

若耗時過久,並且出現底下的錯誤訊息,請確認HC-05模組設置的傳輸速率是否正確

avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x74

非正廠Arduino UNO控制板的問題

我在三個不同的Arduino控制板測試藍牙上傳程式碼的電路:

  • 義大利原裝Arduino UNO:成功
  • 非原廠(中國製)Arduino UNO:失敗!
  • 非原廠(中國製)Arduino Duemilanove:成功(傳輸率:57600bps)

在副廠UNO板子上未能成功,我反覆檢查接線、使用不同傳輸速率,就是無法順利上傳程式碼。所以,如果用本文的方法無法上傳程式碼…請更換Arduino板。

這是原廠和副廠UNO板的正面外觀(下方副廠),副廠的顏色比較深、Arduino商標字體比較模糊、腳位編號字體也不同,但它們都標示“Made in Italy” 😛 詳細的分辨方式,請參閱Arduino官網的“How to spot a counterfeit Arduino”。

原廠和盜版的Arduino板比較

使用「原型實驗擴充板」製作藍牙上傳程式模組

我買了一個「原型實驗擴充板」空板,它的數位0腳外側多了用於連接藍牙模組的6個接點,其TXD和RXD接點分別與數位0和1腳直接相連,正好符合本文的電路需求。

我用美工刀切斷原本連接藍牙RXD和數位1腳的接線

Arduino原型實驗擴充板

在它們之間焊接一個2.2KΩ(紅紅紅)電阻:

焊接電阻

然後在藍牙STATE(PIO9)腳與Arduino的RESET接腳之間,焊接一個電解電容:

焊接電容

我手邊的1μF電容耐壓50V,體積比較大;實際焊接的是10μF電容

測試藍牙開關LED程式碼

同樣以開、關數位13腳的LED為例,請上傳底下的程式碼:

const byte LED = 13;
char val;     // 儲存接收資料的變數,採字元類型
void setup() {
  pinMode(LED, OUTPUT);

  // 序列傳輸速率依照藍牙模組的設定
  // 115200bps或57600bps
  Serial.begin(57600);
  Serial.println("Welcome to Arduino!");
}

void loop() {
  if( Serial.available() ) {
    val = Serial.read();
    switch (val) {
    case '0' :
      digitalWrite(LED, LOW);
      Serial.println("LED OFF");
      break;
    case '1' :
      digitalWrite(LED, HIGH);
      Serial.println("LED ON");
      break;
    }
  }
}

上傳之後,使用Arduino的序列埠監控視窗,或者其他序列通訊程式(如:AccessPort),連線到藍牙模組的COM埠,傳入‘1’或‘0’,即可開或關LED。

Posts created 467

49 thoughts on “HC-05藍牙模組補充說明(五):透過藍牙上傳Arduino程式碼

  1. 趙老師好久不見,最近在研究寫android APP,很興奮發覺了用adobe flash CS5以上版本都可開發,用flash做APP覺得自己比較上手,畢竟flash程式語言都是在老師書籍上學習而來,最近在研究Android結合Arduino做影像辨識玩具小車,網蒐發現openCV這強大的影像辨識庫,但是找遍網路資料找不到adobe AIR有支援openCV,特來求助老師哪裡能找到有關這方面的教學?

  2. 老師你好,想請問如果想用電腦上接受到的藍牙訊號去控制裝置的輸出電壓,用arduino來轉換是可行的嗎?再請教一個問題,arduino上的和電腦的usb連接槽是可以作為類比訊號的輸入端嗎?

    1. 1. 可行
      2. USB是數位訊號,類比訊號可以透過Arduino轉成數位之後,再透過USB傳給電腦。

      thanks,
      jeffrey

  3. 老師您好
    請問您在文中所說:hc-05若無焊接針腳則,請自行焊一條連接PIO9(32腳)與電容負極的導線。
    我手邊有一個hc-06的四腳藍芽模組,請問hc-06也是以相同方式焊接嗎?請問為什麼要與電容負極焊接呢?
    希望老師能回覆我的問題,謝謝

    1. hi hsinTing:

      本文的方法只適用於HC-05模組,與電容負極焊接,請參閱上文的「電路說明」,當HC-05輸出低電位,將讓電容開始充電。

      thanks,
      jeffrey

  4. 感謝您的回應 🙂 在此想另外請教一件事,請問HC-06的藍芽有方法可以得知是否配對嗎?
    因為在arduino的程式中BTSerial.avaliable()似乎是得知是否接收到訊息,而非表示是否配對,所以想請問您HC-06是否有腳位以及functino可以得知有無配對的情況。
    希望您能回覆我的問題,謝謝。

    1. 沒有這種指令,不過,藍牙模組上面有個代表配對狀態的LED,你可以觀察它的閃爍情況。若快速閃爍,代表沒有連線。

      有些藍牙模組把連線狀態腳位接出來(叫做state),你可以嘗試用程式判讀與計數閃爍的頻率,得知該模組是否處於連線狀態。

      thanks,
      jeffrey

  5. 請問如何讓Arduino程式一開始為靜止,再透過Android的Button讓程式開始動作?

    1. hi jason:

      並不是讓程式靜止,而是讓它持續偵測是否有訊號輸入(如:藍牙序列資料),再決定下一個動作。詳細請參閱第十四章「手機藍牙遙控機器人製作」說明。

      thanks,
      jeffrey

  6. 老師您好:
    所以其他Arduino板子可以按照此方式試試看囉!剛剛試著使用HC-05藍芽模組用在(非原廠)UNO上面是無法使用!感謝老師提出藍芽無線上傳程式碼方案!
    謝謝!這在8051時候想過!怎麼沒有無線方式燒入到單晶片!!

  7. 你好,
    我的也是非原廠的UNO,
    當使用藍牙上傳時也遇到avrdude: stk500_recv(): programmer is not responding,看來也沒辦法了吧?
    不過網路找了很久,就是你的教程比較詳細,
    繼續學習

  8. 趙老師,你好,我按照你的教程,但是最後IDE都會出來錯誤訊息如下,但是我確認過可以上傳程式,而且Nano執行功能看起來沒問題,我Rx用1K歐姆跟10K歐姆,Reset用10μF電容(手頭上沒有1μF),可以請教這可能是什麼問題嗎? 這會有後遺症嗎?

    avrdude: stk500_paged_load(): (a) protocol error, expect=0x10, resp=0x94
    avrdude: stk500_cmd(): programmer is out of sync
    上傳到板子時發生問題。可行建議請見http://www.arduino.cc/en/Guide/Troubleshooting#upload。

  9. 你好!
    目前使用hc-05、原廠micro板和彎曲感測器來做滑鼠移動
    我目前遇到的問題在於使用usb連接電腦燒錄,滑鼠移動一切正常,
    但換成無線傳輸時卻無法動作;COM的位子也有調整到HC-05的COM位,打開序列埠視窗也無法動作,
    我的程式如下:
    #include
    const int flex_pin = A4;
    int responseDelay = 1000;
    void setup()
    {
    pinMode(flex_pin,INPUT);
    Mouse.begin();
    Mouse.move(512,512, 0);
    }
    void loop()
    {
    if (410 < analogRead(flex_pin)&&analogRead(flex_pin)<560)
    {
    Mouse.move(( 568- analogRead(flex_pin)) / 10,0 , 0);
    }
    else if(575<analogRead(flex_pin)&&analogRead(flex_pin)<600)
    {
    Mouse.move(( 568- analogRead(flex_pin)) / 10,0 , 0);
    }

    }
    請問是否為程式問題還是設定上有甚麼需要改進或增加的呢?

    1. hi daze:

      問題不在程式,而是在HC-05「序列通訊」藍牙模組身上。

      藍牙有不同的規範(profile),例如:序列通訊(SPP)、人機介面(HID)、立體音訊(A2DP)…等等。

      要製作藍牙滑鼠、鍵盤、搖桿等週邊,你需要採用支援HID規範的藍牙模組,其實有些SPP和HID規範的藍牙晶片是一樣的,只是廠商在出貨之前,事先替它們燒寫不同的韌體。總之,你需要更換藍牙模組。

      have fun!
      jeffrey

  10. 老師你好,我直接燒寫了您的測試藍牙開關LED程式碼,HC-05 TX-ArduinoRX, RX-Arduino TX 在串口監視器輸入0和1並沒有反應 但是拔掉了HC-05的TX RX 再輸入0 1又有反應了,这是藍牙的问题吗?还是Arduino板的问题

    1. 呃…這在邏輯上有點說不通…你電腦上的通訊軟件,有選擇成藍牙串口的埠號嗎?

      thanks,
      jeffrey

  11. 老師您好!請問leonardo的板子可以燒寫嗎?因爲leonardo是USB(CDC)通信;對于引腳0和1上的TTL串口,使用Serial1類。然後我用USB轉串口進行燒寫代碼也遇到錯誤。特求老師指點。

    1. 可以,但我沒試過,主要是序列通訊速率不一樣。採用ATmega32U4的控制板在接收程式檔案時的速率是57600,因此藍牙序列埠的鮑率須設置成57600, 也就是執行 AT+UART=57600,0,0。

      詳細步驟可參考這個老外的說明,他把控制板的Bootloader換成比較精簡的Optiboot,以便透過序列埠而非預設的USB接收程式檔。

      thanks,
      jeffrey

  12. 老師你好
    想請問我是用HC-05藍芽模組+加上ARDUINO UNO面板 要在LabVIEW上透過藍芽的方式做COM的連接
    在程式上有看到COM可是執行錯誤卻說沒連接到(一個簡單的LED ON/OFF開關程式),想問老師 是否還需要在Arduino上編譯程式嗎?如果需要大概要怎麼編寫

    1. 我沒用過LabView,建議先用電腦或智慧型手機的序列通訊程式,直接和Arduino藍牙連接測試,看看是否能收發訊息。

      thanks,
      jeffrey

  13. 想請問一下是否HC-08也可以這麼做,因為目前是使用低功耗藍芽為主,所以想使用HC-08來當作藍芽模組
    不知道可程式化I/O跟命令回應模式的pin角該如何知道是哪個

    1. 可以,有一款結合Bluetooth 4.0和Arduino Uno的產品,叫做Bluno,支援低功耗藍牙上傳程式檔的功能,但我沒試過。或許你可以參考這個Bluno簡介網頁裡的電路圖,嘗試接線看看。

      thanks,
      jeffrey

  14. 老師,請問這個RESET是什麽時候開始,我的怎麽是藍牙壹配對好就RESET。

    1. 不同廠商的藍牙晶片韌體版本和指令語法可能不一樣,所以實際要以廠商提供的技術文件為主。

      thanks,
      jeffrey

    1. 我用原廠的Uno R3測試沒問題,Nano我相信也可以,請自行測試看看。

      thanks,
      jeffrey

  15. 老師我可以詢問
    如何使用VS2012 C++ 經由PC傳送資料到Arduino 有相關程式碼嗎?

    1. 抱歉,我跟VS2012 C++完全不熟。你可以找尋C++與序列埠通訊的相關程式,搞懂流程,跟Arduino通訊就簡單了。

      thanks,
      jeffrey

  16. 老師您好 :
    我最近在做”雙a計畫”,AppInventor搭配Arduino的實驗,傳輸方式就是藉由您這邊所提到的藍芽裝置,只是我發現到一個問題 :
    如果我斷開後重新連線,Arduino會把斷開這段時間的data存在於HC-05這邊,導致重新連線後,會把資料一口氣傳送過去。
    不知道老師您是否知道,有沒有辦法清除HC-05裡面的暫存空間,或是要如何下指令使Arduino當接收到App的訊息後,才開始傳送資料呢?

    1. 應該是序列資料暫存在Arduino端等待被傳送,如果可以在傳送資料之前,先檢測藍牙是否處於連線狀態,就能避免這個問題。不過,HC-05/06這種模組並沒有簡單的方法可以檢測連線狀態,只能透過STATE腳的狀態得知。

      或者,你可以設計讓資料傳送後,接收端必須傳回確認訊息,發射端在收到確認回應後,才能發出下一筆資料。

      thanks,
      jeffrey

  17. 老師您好,我最近要做的專題是跟arduino的藍芽模組有關,請問要如何用讓手機的藍芽裝置透過arduino跟些許的藍芽模組進行一對多的功能?是要用手機跟HC-05先做連接,再讓HC-05跟許多HC-06同時連接嗎?

  18. 老師您好,上述的程式屬於連線候傳值。
    如果藍芽沒有連線到能夠Serial.print顯示沒有連線的字,該如何寫呢?

  19. 老師您好,我藍牙連結了。
    然後在上傳控制燈的程式。
    卻沒辦法用藍牙控制成功。
    怎麼辦呢?

    1. 請先確認RX和TX接腳是否接反了,如果沒有接錯,可以先把藍牙的TX和RX相接,如此,藍牙收到的訊息會被轉發回去。到Google Play下載藍牙序列通訊軟體,從中發訊息給藍牙模組,如果該模組沒有故障,序列通訊App會接收到你剛剛發出的訊息。

      thanks,
      jeffrey

  20. 想請問一下,我照著您的方法接,可以上傳程式碼,但是序列埠監控視窗沒辦法顯示
    我是做一個程式,可以讀取馬達的轉速,並顯示轉速在序列埠監控視窗上面
    在用有線連接的狀態下可以上傳程式碼並且顯示讀值,但是用HC-05上傳之後,點開序列埠監控視窗卻是空白的

    1. 透過藍牙上傳程式成功,代表成功用藍牙取代了有線序列埠…無法顯示訊息,可能是序列埠程式碼有誤(如:鮑率設錯了)。

      thanks,
      jeffrey

  21. 趙老師您好,這陣子買了一個Arduino Nano 33想要將IMU資料用藍芽做無線傳輸到PC,原本打算用內建的BLE來完成,上網找了資料看到很多人說傳輸速率很慢(10Hz以下?),再來是PC端找不到比較方便用來接收BLE的library(我是用python)。今天在網路上搜尋發現了這個內容才了解到原來有這種直接將資料透過藍芽做serial輸出的模組,更棒的是若我理解沒有錯在與電腦配對成功時會產生虛擬com port,這樣我就可以直接用寫好的pyserial來收取資料了!! 在這裡想請問老師的是在BLE的使用方法是不是跟像HC-05這樣的serial bluetooth不一樣呢? 若不一樣未來老師有打算新增在書籍裡面嗎? 謝謝

    1. 藍牙低功耗(BLE)4.2版的傳輸速率理論上限為1Mbps。

      BLE的規範並沒有藍牙2.1的SPP序列通訊規範;使用BLE必須自訂服務(service)、特徵(characteristic)和屬性(properties),程式寫法跟藍牙2.1完全不同,也相對複雜許多。

      我的新書有兩個章節解說藍牙低功耗和應用實作,但控制板不是用Arduino Nano 33。

      thanks,
      jeffrey

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top