2013/12/22

Arduino藍牙無線燒錄:使用Adafruit公司的Bluefruit EZ-Link

我買了Adafruit公司的藍牙模組Bluefruit EZ-Link - Bluetooth Serial Link & Arduino Programmer - v1.0,它就是個支援SPP序列傳輸的基本藍牙模組,與電腦配對後就會以序列埠出現。

一般的藍牙模組需要先設定一堆組態,而這個產品能夠自動偵測並調整傳輸速率,支援常見的速率2400、4800、9600、19200、38400、57600、115200、230400,相當不錯。而且還能與電腦的序列埠自動同步DTR/RTS/DSR這些控制線路的訊號,一般模組多半沒有,甚至根本不拉出這些腳位。

結合上述功能,便可以經由藍牙介面無線燒錄Arduino的草稿碼,但能加上此功能的板子限於Uno、Duemilanove、Mega、以及其他使用ATmega328/168/1280/2560微控制器晶片並加上「USB轉Serial」轉換器的相容開發板,不能用於模擬出USB埠的Arduino板子(譬如Leonardo與Micro)。

這就是Bluefruit EZ-Link,長2.0公分、寬4.1公分、高0.4公分。

先介紹一下規格:
  • 含有穩壓器(regulator),可輸入3.3~16V直流電源,轉換成3.3V供應藍牙晶片。
  • 含有準位調節器(level-shifting),在外部訊號與內部藍牙晶片之間進行電壓準位轉換,所以可連接3.3V或5V的Arduino開發板。
  • 有三個狀態LED,分別標示為TX(傳送)、RX(接收)、Conn(連線狀態),Conn若快速閃爍代表沒有配對,若緩慢閃爍代表已配對但並未開啟連線,若亮著代表電腦端開啟序列傳輸介面並進行資料傳輸。
  • Pair按鈕,長按5秒後可重新配對。
  • 模組背面有JST插座,由這裡提供電源的話,那麼就能從Vin供電給Arduino板。
接下來試試無線燒錄吧。線路如下:
Arduino使用9V電池供電。
Bluefruit的Vin接Arduino 5V腳位。
Bluefruit的GND接Arduino GND腳位。
Bluefruit的DSR接Arduino GND腳位。
Bluefruit的TX接Arduino RX(腳位0)。
Bluefruit的RX接Arduino TX(腳位1)。
Bluefruit的DTR,接1uF電解電容的陰極,電容陽極接Arduino RESET腳位。
藍牙模組部分的近照。
開啟電源後,首先要與電腦端進行藍牙配對,預設配對碼是1234,過程此處就不詳述,細節可看這裡。注意,電腦端的藍牙至少要符合Bluetooth v2.1,有些非常便宜的模組僅支援2.0。

成功後,開啟Arduino IDE,便可看到代表藍牙模組的序列埠。譬如在我的Mac上,會出現兩個含有AdafruitEZ-Link字樣的裝置,需選擇「cu」那一個。
然後就可以經由藍牙無線燒錄囉,耶!

80 comments:

  1. 一直有在注意您的網誌,您最近常分享Adafruit的組件,想請問台灣是否有管道可購買?謝謝您。

    ReplyDelete
  2. 據我所知,沒有。
    我直接到www.adafruit.com購買。

    ReplyDelete
  3. 謝謝您的回覆,請問他的運費怎麼計算?大約多久會到?謝謝您。

    ReplyDelete
    Replies
    1. Adafruit的國際運送有兩種方式,US Postal Service與UPS (United Parcel Service) ,購買物品若超過$200(美金)就必須使用UPS,我也只用過UPS。
      UPS國際運送有底下三選項:
      UPS Worldwide Express: 1-3 Business Days. Delivery by 10:30 a.m. or 12:00 noon.
      UPS Worldwide Saver: 1-3 Business Days. Delivery by end of day.
      UPS Worldwide Expedited: 2-5 Business Days. Delivery by end of day.

      我有一次買了約2.5公斤的物品,使用Expedited,運費約$55。
      有一次買約0.6公斤,使用Saver,運費約$27。
      大約7天內到。

      我用信用卡刷卡,信用卡公司又跟我收國外交易手續費。

      另外,物品過海關也要繳稅,UPS送貨員到你家後會跟你收。

      還有,若買無線傳輸的東西(GPS、WiFi),要提供資料報關。

      算一算其實滿貴的,orz。

      Delete
  4. 謝謝您的回覆,我也是因為運費計算出來很高才作罷,真希望有廠商代理他們家的東西orz

    ReplyDelete
    Replies
    1. 那就只好一次買多一點囉。

      Delete
    2. 不知您下次何時採購,方便的話想和您一起分擔運費~哈哈哈

      Delete
    3. 下一次不知道是什麼時候了。

      Delete
  5. 請問葉大有沒有做過用HC-05來遙控另一塊Arduino呢
    目前只讓兩塊HC-05互連而已之後就不知道該怎麼做了= =

    ReplyDelete
    Replies
    1. 可以互連了,之後就是制定收發雙方的溝通格式吧,也就是協定,
      譬如從這邊傳送出類似「get digital 2」之類的訊息,然後另一邊就必須回傳數位腳位2的狀態,類似這樣的形式,
      或許可以參考看看Firmata(
      http://www.firmata.org/wiki/Main_Page)。

      Delete
  6. 大大你好,我寫一個APP,要透過藍牙連線,傳訊息0到9進去arduino來控制東西,不過arduino程式碼裡面好像要給這0-9存變數甚麼的還是怎樣我可能沒有去輸入,結果COM那邊不是顯示0-9而是顯示一堆無關0-9的數字,能請您教教我嗎?? APP那功能除了藍牙連線之外 就只有傳單純0-9的數字而已,arduino的程式碼那邊要怎樣改,板子才能正常接收0-9呢

    ReplyDelete
    Replies
    1. 你的藍牙連線傳輸編碼應該是ASCII,所以當要傳數字23時,須先轉成字串"23",然後一個byte一個byte傳,也就是先傳字元'2'的ASCII碼(也就是0x32),然後傳字元'3'的ASCII碼(0x33),接收後再逆轉,還原成數字23。
      以上所說是可行作法之一。

      所以,當你傳0進去時,你傳的是數字0、還是字元0(ASCII碼是0x30)?

      Delete
    2. 我希望傳數字0到數字9優><

      Delete
    3. This comment has been removed by the author.

      Delete
    4. 我是參考這個網站,我把他的APP做修改,範例是傳a,我改為0-9,所以是傳數字0-9進去板子
      http://blog.cavedu.com/appinventor-%E5%9C%96%E5%BD%A2%E5%8C%96android/appinventorandarduinowithbluetooth/

      Delete
    5. 然後我測試結果是這樣
      input size = 1
      0
      input size = 2
      28
      0
      感覺0正確 1就不對 以上我是輸入數字0及數字1

      Delete
    6. 他的AppInventor的程式碼傳的是text "a",也就是我說的那樣。
      該網站也已提供Arduino端的程式碼,讀取後轉為char。

      Delete
    7. 所以他傳的a是ASCII碼的意思嗎?然後假如我要傳0-9,APP那邊按鈕的0-9也要改成ASCII碼嗎?

      Delete
    8. 嗯,看起來不太對,哪裡出錯了呢...

      Delete
    9. 每次都這樣啊?

      input size = 1
      0
      input size = 2
      28
      0

      Delete
    10. 你的序列埠跟藍牙都是SoftwareSerial,有可能是兩者的速率差太多所致,
      試試讓它們都用同樣的傳輸速率。

      Delete
    11. 對壓,啊我現在改ASCII碼,結果案0的話傳
      input size = 1
      0
      input size = 1
      224
      input size = 3
      28
      240
      224
      案一的話傳
      input size = 1
      0
      input size = 1
      224
      input size = 3
      28
      240
      224
      好像也不太對

      Delete
    12. 說錯了
      結果案0的話傳
      input size = 1
      0
      input size = 1
      224

      案一的話傳

      input size = 3
      28
      240
      224

      Delete
    13. 要把胞率改回9600的意思嗎

      Delete
    14. 嗯,或是兩者都改成57600。

      Delete
  7. 你好 想請問
    我想讓arduino的序列阜值用藍芽上傳到手機顯示
    請問有甚麼方法可以做到

    ReplyDelete
    Replies
    1. 嗯,
      Arduino加上藍牙模組,與手機端經由SPP(Serial Port Profile)形式連線,
      Arduino端要寫程式,從序列埠(連接電腦)接收資料,然後從藍牙模組送出,
      手機端也要執行程式,接收藍牙資料並顯示。

      Delete
    2. 請問大師要寫教學嗎@@
      關於這種的

      Delete
    3. 可能、或許、maybe、perhaps,但不是現在。

      網路上應該可以找到分享文,介紹你需要的功能。

      Delete
  8. Anonymous15/7/15 15:54

    老師您好!
    請問我用BLE v1.0的低功率藍芽模組為甚麼我都無法新增裝置一直找不到但能解決的方案都試過了!!

    ReplyDelete
    Replies
    1. 呃,既然你說能解決的方案都試過了,那要我怎麼辦呢。

      Delete
  9. Anonymous16/7/15 23:39

    老師您好
    我現在可以新增了但卡在無法將低功率藍芽變成是串列埠

    ReplyDelete
    Replies
    1. 問題很清楚,但沒有任何說明描述,無法幫你。

      Delete
  10. 老師你好!
    請問我該如何用APP inventor2寫一個APP程式接收由Arduino傳送的值(用藍芽)

    ReplyDelete
    Replies
    1. 你的問題需要一篇文章的篇幅才能回答。
      請到網路找找介紹文,譬如cavedu的部落格。

      Delete
  11. 小弟我想寫個程式給腳踏車用 搭配手機 使用向燈和里程數 但以下程式中我無法進入里程數程式變得只剩下方向燈
    可以請問一下要怎麼解決?
    #include
    #include
    SoftwareSerial BT(10,11);
    const int buttonPin=2;
    byte serialA;
    boolean RED_LIGHT;
    boolean buttonState;
    boolean buttonState2;

    void setup()
    {
    pinMode(13, OUTPUT);
    pinMode(4, OUTPUT);
    Serial.begin(9600);
    BT.begin(9600);
    pinMode (buttonPin,INPUT);
    }

    void loop()
    {
    int Data[1];
    int insize;
    byte cmmd[20];
    buttonState= digitalRead(buttonPin);
    delay(10);
    buttonState2= digitalRead(buttonPin);
    RED_LIGHT=buttonState^buttonState2;//開關一次 動作一次
    serialA=BT.read();
    Data[0]='e';
    boolean i=digitalRead(2);

    while(1)
    {
    if( RED_LIGHT==1) //里程數
    {
    Serial.println(1);
    BT.write(Data[0]); //傳e
    delay(10);
    BT.write(RED_LIGHT);
    }

    if ((insize=(BT.available()))>0)
    {
    Serial.print("input size = ");
    Serial.println(insize);
    for (int i=0; i<insize; i++)
    {
    Serial.print(cmmd[i]=char(BT.read()));
    Serial.print(" ");
    }
    switch (cmmd[0])
    {
    case 97: //97為"a"的ASCII CODE
    digitalWrite(13,HIGH); //點亮LED
    break;
    case 98://98為"b"的ASCII CODE
    digitalWrite(13,LOW); //熄滅LED
    break;
    case 99: //99為"c"的ASCII CODE
    digitalWrite(4,LOW); //點亮LED
    break;
    case 100://100為"d"的ASCII CODE
    digitalWrite(4,HIGH); //熄滅LED
    break;

    }//switch
    }//if
    }//while
    }//loop

    ReplyDelete
  12. 把while(1)拿掉,應該就可以了吧。

    ReplyDelete
    Replies
    1. 可是我把while拿掉後LED他就無法動作了

      Delete
    2. This comment has been removed by the author.

      Delete
    3. 會變成RED_LIGHT==1進入下方里程數程式下面才跟著動作
      這樣方向燈有時按得時候RED_LIGHT沒有動作 方向燈就不會暗滅

      Delete
    4. 我把while(1){} 拿掉而已

      Delete
    5. 修改後的程式碼?

      Delete
  13. #include
    #include
    SoftwareSerial BT(10,11);
    const int buttonPin=2;
    byte serialA;
    boolean RED_LIGHT;
    boolean buttonState;
    boolean buttonState2;

    void setup()
    {
    pinMode(13, OUTPUT);
    pinMode(4, OUTPUT);
    Serial.begin(9600);
    BT.begin(9600);
    pinMode (buttonPin,INPUT);
    }

    void loop()
    {
    int Data[1];
    int insize;
    byte cmmd[20];
    buttonState= digitalRead(buttonPin);
    delay(10);
    buttonState2= digitalRead(buttonPin);
    RED_LIGHT=buttonState^buttonState2;//開關一次 動作一次
    serialA=BT.read();
    Data[0]='e';
    boolean i=digitalRead(2);



    if( RED_LIGHT==1)
    {
    Serial.println(1);
    BT.write(Data[0]); //傳e
    delay(10);
    BT.write(RED_LIGHT);
    }

    if ((insize=(BT.available()))>0)
    {
    Serial.print("input size = ");
    Serial.println(insize);
    for (int i=0; i<insize; i++)
    {
    Serial.print(cmmd[i]=char(BT.read()));
    Serial.print(" ");
    }
    switch (cmmd[0])
    {
    case 97: //97為"a"的ASCII CODE
    digitalWrite(13,HIGH); //點亮LED
    break;
    case 98://98為"b"的ASCII CODE
    digitalWrite(13,LOW); //熄滅LED
    break;
    case 99: //99為"c"的ASCII CODE
    digitalWrite(4,LOW); //點亮LED
    break;
    case 100://100為"d"的ASCII CODE
    digitalWrite(4,HIGH); //熄滅LED
    break;

    }//switch
    }//if

    }//loop

    ReplyDelete
  14. 嗯,的確行為不同了。

    那請你先詳述想要哪些行為。
    BT雙方會互傳哪些資料。
    BT.write(Data[0]); //傳e 這是什麼意思。
    RED_LIGHT什麼時候要亮、什麼時候不亮。
    buttonPin的作用是什麼。

    等等。
    cmmd記錄的東西,其格式為何。

    ReplyDelete
    Replies
    1. 手機會傳49這數字當驗證碼到BT
      傳E到手機是代表腳踏車轉一圈
      buttonPin2是我外接紅外線來當開關 輪子轉一圈 輪子上的板子會反射讓他開關一次
      cmmd 我是抄這個 http://ppt.cc/W85Pu 我也不太懂那段程式

      Delete
    2. https://www.dropbox.com/s/bc04embgxh6gzoq/12765661_1117028274996840_709316614_o.jpg?dl=0
      這是我APP的程式

      Delete
    3. > 手機會傳49這數字當驗證碼到BT
      什麼驗證碼?程式中沒有這東西。

      > 傳E到手機是代表腳踏車轉一圈
      可是你原本程式裡有while(1)無窮迴圈,不就沒辦法持續偵測腳踏車的轉動。

      這樣看來,拿掉while(1)是對的。

      Delete
    4. if ((insize=(BT.available()))>0)這段判斷有沒有連線成功

      Delete
    5. Serial.print("input size = ");
      Serial.println(insize);
      會顯示input size = 1 49

      Delete
    6. > if ((insize=(BT.available()))>0)這段判斷有沒有連線成功
      不是,這是判斷BT介面有無收到資料。

      Delete
  15. This comment has been removed by the author.

    ReplyDelete
  16. 請問arduino用一般藍芽傳輸資料 和BLE 4.0傳輸資料的程式碼會是一樣的嗎?

    ReplyDelete
    Replies
    1. 不一樣。
      一般藍芽跟BLE 4.0是兩回事。

      Delete
    2. 我想請問您,那如果用BLE來讓arduino裡要傳的數值傳到網頁上 是可以的嗎?
      然後我們想用資料庫來抓網頁上的資料來顯示在app上

      Delete
    3. > 如果用BLE來讓arduino裡要傳的數值傳到網頁上 是可以的嗎?
      可以。
      不過這大概不是你想聽到的答案,但我也猜不出你真正想問的是什麼。
      如果你要問怎麼做,嘿,太多種作法了,不該、也沒辦法在留言裡回答。

      > 想用資料庫來抓網頁上的資料來顯示在app上
      資料庫抓網頁上的資料?
      嗯,看不太懂耶,資料庫是讓人存資料、取資料的技術,怎麼抓網頁上的資料啊?
      你想要抓網頁資料、放進資料庫、讓app可以存取顯示,應該是這樣吧?

      加油。

      Delete
    4. 我是想用BLE讓arduino上讀到的重量值傳到網頁,然後像你所說的抓網頁資料、放進資料庫、讓app可以存取顯示,只是對於arduino要怎麼寫利用BLE傳到網頁上的程式有些疑問。

      我們資料庫是使用phpmyadmin 那邊是可以抓資料了,那如果arduino這邊程式寫好,資料庫那邊是不是也要寫接收的程式,還是用原來寫好的抓取資料就可以呢?不好意思,因為我對於資料庫很不了解。

      Delete
    5. > arduino要怎麼寫利用BLE傳到網頁上的程式
      arduino與網頁端,透過BLE連線嗎?不是wifi?
      你的網頁是指已經架好的網站吧,不是透過HTTP、REST API送出資料嗎?

      > 資料庫那邊是不是也要寫接收的程式
      資料庫本身就能接收資料吧。是否要寫sql、把資料送進去。

      建議你找找網路上有無範例,問問老師同學,看看書,
      這樣問我,也沒什麼用,呵呵。

      加油。

      Delete
    6. 可能要用wifi,我們是有架好的伺服器,那可不可以問你這樣要用什麼關鍵字來找程式範例比較快呢?

      Delete
    7. 我想問你一個小問題,外接wifi模組的話,可以利用wifi來控制何時亮燈嗎?

      Delete
    8. 那有辦法不用USB的方式連接電腦 來控制亮燈嗎

      Delete
    9. wi-fi、藍牙、XBee、序列埠。
      不懂你想問什麼?

      Delete
    10. 假如我們app上有個按鈕,按下之後可以利用wifi來讓連接arduino上的燈亮嗎?

      Delete
    11. 可以,可以,可以。

      Delete
    12. 那使用wifi模組時 可以不使用USB線連接電腦 而是用焊接的方式?

      Delete
    13. 你問的太模糊了。
      哪個wifi模組?usb連電腦是為了什麼?焊接什麼東西?

      Delete
    14. 不好意思... 你看看這個http://yhhuang1966.blogspot.tw/2015/10/esp8266-wifi-arduino.html
      類似這種的 我可以不使用USB和麵包板來讓arduino和wifi模組運作嗎

      Delete
    15. 開發的時候需要。開發完後就可以拿掉。

      Delete
    16. 好的,感謝您!

      Delete
    17. 請問一下~~~
      我最近買了一個wifi模組 ESP8266,起初是不是都要燒錄更新韌體呢?

      Delete
    18. 自己看
      http://yhhuang1966.blogspot.tw/2015/10/esp8266-wifi-arduino.html
      慢慢玩吧。

      或是參考 趙英傑 的大作
      超圖解物聯網IoT實作入門:使用JavaScript/Node.JS/Arduino/Raspberry Pi/ESP8266/Espruino

      Delete
    19. 請問您! 我的bluoduino rev2運作於3.3V,那ESP8266也是3.3V,如果兩個溝通起來電量會不足嗎?是否可以運作?

      Delete
    20. 電量會不會不足,那就看你提供多少電量啊。
      沒道理不能運作。
      為什麼你會有此疑問?

      Delete
    21. 因為有看到一些ESP8266韌體更新的資訊,有接電源模組,所以有些困惑???
      我可以問你對於更新ESP8266的看法嗎?更新是不是比較好呢?

      Delete
    22. 去swf.com.tw問趙大,更清楚。

      視情況而定,你有能力可掌握的話,那就更新吧。

      Delete
  17. Anonymous4/5/22 14:51

    您好,很感謝您整理出大量的資訊,對我幫助很大。
    最近正想要做一個測試,想把Arduino Nano板的兩筆數據(例如: a=100,b=200)透過藍牙(HC-05、06)傳輸給Arduino Uno,在Uno那邊的LCD上就會顯示a=100,b=200,不知道是否可行呢?

    ReplyDelete