2014/04/13

Arduino Yún:Bridge程式庫入門(Console與Process)

Yún除了有一顆微控制器ATmega32U4(跟Leonardo相同),還有一顆Atheros AR9331,運行Linux發行套件Linino(以OpenWRT為基礎修改而成),這顆晶片連接有線網路(Ethernet)介面、無線網路(WiFi)介面、板子上的USB A埠(主方)與micro SD記憶卡插槽。

當我們撰寫ATmega32U4的草稿碼時,可透過Bridge程式庫來跟Atheros AR9331的Linino溝通,使用各種功能。請看官方網站提供的架構示意圖。

Bridge程式庫裡有許多類別,分別對應各種功能包括Bridge、Process、Console、FileIO、Mailbox、HttpClient、YunClient與YunServer。其原始碼都在Arduino軟體開發環境安裝目錄\libraries\Bridge底下。

接下來就嘗試一下Console與Process,底下的程式碼大部分都是從Arduino官方網站與軟體開發環境提供的範例修改而來。

首先是Console,顧名思義就是類似主控台、終端機之類的功能,跟以前的序列埠很像,但現在可經由WiFi無線登入。

底下這支程式會從Console接收資料,若收到字元H就點亮板子上內建的LED,若收到字元L就熄滅。

#include <Console.h>
#define LED_PIN 13

void setup() {
  Bridge.begin(); // 啟動Bridge,其他類別都需要它
  Console.begin(); // 初始化Console

  while (!Console) // 等待開啟Console
    ;
  if(Console.connected()){
    Console.println("Console is connected");
  }
  Console.println("type H or L to turn pin 13 on or off");

  pinMode(LED_PIN, OUTPUT);
}
void loop() {
  if(Console.available() > 0){
    char b = Console.read();
    Console.println(b);
    if(b == 'H'){
      digitalWrite(LED_PIN, HIGH);
    }
    else if(b == 'L'){
      digitalWrite(LED_PIN, LOW);
    }
  }
}

Console類別用起來就跟Serial差不多。然後可從選單「工具-連接埠」選擇「Arduino at xxx.xxx.xxx.xx (Arduino Yún)」,此時開啟序列埠監控視窗的話,便可連接Yún的Console,畫面如下。
也可自己透過SSH登入取得Console,請把arduino.local換成你的Yún的IP位址。

$ ssh root@arduino.local
root@arduino.local's password:
...省略...

登入後下指令連接Console,如下:

root@Arduino:~# telnet localhost 6571
Console is connected
type H or L to turn pin 13 on or off

然後就可以輸入H或L控制LED亮滅。

然後是Process,可要求執行某程式或Linux指令,底下程式碼會執行uptime指令,得知系統開機後已經過多少時間,然後執行curl,取回以ASCII畫出來的Arduino logo。

#include <Process.h>

void setup() {
  Bridge.begin();
  Serial.begin(19200);
  while(!Serial)
    ;

  run_uptime();
  run_curl();
}
void loop() {
}
void run_curl() {
  Process p;
  p.begin("curl"); // 指令Linux指令
  p.addParameter("http://arduino.cc/asciilogo.txt"); // 加上參數
  p.run(); // 執行,這是阻斷式方法,執行結束後才會回傳

  while(p.available() > 0){ // 將指令執行結果送往序列埠監控視窗
    char c = p.read();
    Serial.print(c);
  }
  Serial.flush();
}
void run_uptime(){
  Process p;
  p.begin("uptime");
  p.run();

  while(p.available() > 0){
    char c = p.read();
    Serial.print(c);
  }
  Serial.flush();
}

其結果如下圖:
對Bridge程式庫有基本了解後,就可以開始玩玩其他更進階的類別,諸如YunServer、YunClient、HttpClient、MailBox、等等。


參考資料:

19 comments:

  1. Dear 葉難:
    不好意思打擾了,想請教一下程式中有while(!Console) ,加了驚嘆號意思是什麼?

    Behram

    ReplyDelete
  2. 等待開啟Console。
    在執行setup()時,Console可能還沒準備好,其值為假,
    那麼 !Console 就會為真,while迴圈就會一直空轉,直到準備好。

    ReplyDelete
  3. Dear:
    謝謝你,不過還是有些不太懂,當使用 !Console 時,他會判斷它是否為真嗎? 若我不使用驚嘆號他會怎麼運作??

    Behram

    ReplyDelete
    Replies
    1. while會判斷()裡的運算式是否為真,若為真就執行while迴圈裡的程式碼,直到為假。
      當Console還沒準備好時、其值為假,所以!Console為真,while迴圈不斷執行。
      當Console準備好時,!Console為假,就會跳出while迴圈。

      Delete
  4. 您好,請問一下,
    1. 我的Yun 設定後,用 Wifi 來上傳Blink 能正常執行,但是只要用到 "Serial Command" 就會出現:
    Unable to connect: retrying (1)...
    Unable to connect: retrying (2)...
    Unable to connect: retrying (3)...
    Unable to connect: retrying (4)...
    Unable to connect: is the sketch using the bridge?
    請問是哪裡出了問題?
    2. 使用 Arduino Yun Serial Command, Baud Rate要設多少?(依您的範例,設的是 300;我的 Serial Command 在Baud Rate 設定改起來也很慢)

    ReplyDelete
    Replies
    1. 1.
      請看http://playground.arduino.cc/Hardware/Yun#console_cant_connect
      解決辦法是從一般的USB連線來上傳程式。

      原因應該是setup()裡面有while(!Serial){},造成序列埠沒開啟,於是無法連線。

      2. 不確定。應該不用改。

      Delete
    2. 葉大你好 串列埠視窗是不是簡單的解釋說
      如果使用wifi方式 就要使用 Console 這個來取代Serial
      要使用Serial就要去將串列埠改為 COM 來連接 不能選擇網路IP?

      另外一個問題 我的ardunio yun 一直無法驅動 試過 http://www.openjumper.com/arduino-driver-support/ 這網站的方法也不行
      電腦內的IDE 也刪除重新安裝都不行 請問還有沒有其他方式 或者有驅動程式可以下載

      Delete
    3. 嗯,應可如此解釋。

      > 一直無法驅動
      yun其實是Leonardo加上wifi晶片,請問哪部分不行?
      Leonardo驅動程式,請參考 http://yehnan.blogspot.tw/2013/09/arduino-leonardo.html

      wifi晶片的設定,請參考 http://yehnan.blogspot.tw/2013/10/arduino-yun.html

      Delete
  5. Thank you, I'll try it again.

    ReplyDelete
  6. 請問葉老師,如果我想要利用一塊Yun傳輸資料讓多台電腦接收的話我該怎麼做?
    我之前跟弟弟試過一次,但是好像沒辦法同時連線,我先讓Yun連上我們家的AP,再一起開筆電連它(Yun),這是我的程式碼,請老師幫我看看。
    #include
    int i = 0;
    void setup() {
    Bridge.begin();
    Console.begin();
    }
    void loop() {
    for ( i=0; i <= 1000; i++)
    {
    Console.println(i);
    delay(10);
    }
    }

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. 你的程式碼跟想要的功能,不一樣吧。

      Yun連上AP後,就能作為client端或server端,看給它什麼程式而定。

      > 利用一塊Yun傳輸資料讓多台電腦接收
      嗯,可以使用YunServer讓yun板子作為server端,
      請參考
      http://yehnan.blogspot.tw/2014/04/arduino-yunbridgeyunserveryunclient.html
      別台電腦連線時,yun就送出資料。
      不過Yun連上AP,一般情況會是private IP,若無特殊設定,其他電腦必須位於同網域。

      另一種作法是反過來,讓yun板子作為client端,
      定時連線到別台電腦(該台電腦必須跑server程式),送出資料。

      Delete
    3. 謝謝葉老師 ^^

      我再試試看!

      Delete
    4. 請問葉老師
      我上面的那個程式裡有一個" Console.println(i); "
      請問我該怎麼把"i"的值抓到"C#"的程式裡面去判斷?

      Delete
    5. Yun的Console的主要功用類似於序列埠介面,但不是有線,而是透過wifi存取。除了透過Arduino IDE的serial monitor,也可以透過ssh、再執行telnet,就可以連接到你的程式的Console輸出。詳情請看https://www.arduino.cc/en/Guide/ArduinoYun#toc18
      嗯,所以C#程式須使用SSH相關程式庫,方能連線、讀取到Console.println(i);的輸出,感覺很麻煩。

      一般要傳輸資料的話,應會透過wifi網路與HTTP協定吧,也就是YunServer與YunClient。C#程式使用HTTP程式庫連線,Yun的程式也要改寫。

      Delete
  7. 請問
    我要如何運用Arduino yun wifi labview (Arduino yun本身可無線通聯
    labview 和Arduino yun 各要如何設定才能連接上

    ReplyDelete
    Replies
    1. 不懂labview,無法回答。
      或許可參考
      http://forum.arduino.cc/index.php?topic=323690.0

      Delete
  8. 請問
    arduino uno板讀取感測器資料的程式這樣打

    #include

    #define RXPIN 11
    #define TXPIN 12
    SoftwareSerial nss(RXPIN, TXPIN);

    void setup() {
    Serial.begin(115200);
    nss.begin(9600); // Communicate at 9600 baud (default for PAM-7Q module)
    Serial.println("Reading GPS...");
    }

    void loop() {
    while(nss.available()) {

    Serial.write(nss.read());

    }

    }

    將板子換成yun後是變成下面這樣嗎
    #include
    #include
    #include


    #define RXPIN 11
    #define TXPIN 12
    SoftwareSerial nss(RXPIN, TXPIN);


    void setup() {
    Bridge.begin();
    Console.begin();
    nss.begin(4800); // Communicate at 9600 baud (default for PAM-7Q module)
    while(!Console){
    ;
    }
    Console.println("Reading GPS...");
    }

    void loop() {
    while(nss.available()) {
    Console.write(nss.read());
    }

    ReplyDelete
    Replies
    1. Serial是有線序列埠介面,
      Console是無線Wi-Fi終端機介面,
      功能類似。
      看你要哪個。

      Delete