2016/04/10

Arduino Yún:Bridge程式庫入門之Console

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

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

(呃,arduino.cc不是改成OpenWRT-Yun了嗎,怎麼還留著Linino的字樣。)

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

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

顧名思義,Console的作用類似於主控台、終端機的功能,跟以前的序列埠很像,但現在可經由Wi-Fi無線登入。

底下這支程式會從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 = (char) Console.read();
      
        if(b == 'H'){
            Console.println(b);
            digitalWrite(LED_PIN, HIGH);
        }
        else if(b == 'L'){
            Console.println(b);
            digitalWrite(LED_PIN, LOW);
        }
        else if(b == '\n' || b == '\r'){
        }
        else{
            Console.println("type H or L to turn pin 13 on or off");
        }
    }
}


Console類別本身,用起來就跟Serial差不多。然後可從選單「工具」-「序列埠」選擇「Arduino at xxx.xxx.xxx.xx (Arduino Yún)」,此時開啟序列埠監控視窗的話,便可連接Yún的Console,畫面如下。
似乎有點複雜,搞不清楚哪個是哪個,簡單關係示意圖如下:

主機電腦的Arduino IDE的序列埠監控視窗-經由網路連線-Yun的Linux(OpenWRT-Yun)-再到Yun的微控制器(ATmega32U4)的草稿碼

也可自己透過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亮滅。(上述指令可合併成$ ssh root@arduino.local 'telnet localhost 6571')

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

#include <Process.h>

void setup() {
    Bridge.begin();
    Serial.begin(56700);

    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、等等。


參考資料:

11 comments:

  1. 我想請問一下
    因為我要用無線連接yun 再用監控視窗測試
    (以下程式是原程式,需要運到console
    可是我試了很多次都不行
    不知道葉難可不可以幫我看一下
    float L;
    long dx,dy;
    long rex,rey;
    long rx0,ry0;
    float unitx,unity;
    long start;

    float fr;
    long rx,ry;
    float length;
    char A;
    void setup() {
    // put your setup code here, to run once:
    Serial.begin(9600);

    }

    void loop() {
    // put your main code here, to run repeatedly:
    if (Serial.available()!=0) A=Serial.read();

    switch (A)
    {
    case 'a':
    { dx=-100;} break;
    case 'b':
    { dx=100;} break;
    case 'c':
    { dy=-50;} break;
    case 'd':
    { dy=50;} break;
    case 'e':
    { fr=0.1;} break;
    case 'f':
    { fr=0.4;} break;
    case 's':
    {
    length=sqrt(dx*dx+dy*dy);
    unitx=(float)dx/length;
    unity=(float)dy/length;
    rx0=rx;
    ry0=ry;
    rex=rx+dx;
    rey=ry+dy;
    start=1;
    L=0.0;
    A=0;
    } break;
    default:
    {
    } break;
    }
    if (start==1)
    {
    L=L+fr;
    rx=rx0+(long)(L*unitx);
    ry=ry0+(long)(L*unity);
    if (L>=length)
    {
    rx=rex;
    ry=rey;
    start=0;
    L=length;
    }
    }

    Serial.print(rx); Serial.print("---"); Serial.print(ry);
    Serial.print("---"); Serial.print(A);
    Serial.print("---"); Serial.print(L);
    Serial.print("---"); Serial.print(fr);
    Serial.print("---"); Serial.println(start);
    }

    ReplyDelete
    Replies
    1. 你的問題是什麼?

      > 可是我試了很多次都不行
      什麼不行?

      你沒有使用Console啊。

      Delete
  2. 上面那是我的原程式
    是下面這個才對
    #include
    #include
    #include
    #include
    #define PORT 23
    YunServer server(PORT);
    YunClient client;
    float L;
    long dx,dy;
    long rex,rey;
    long rx0,ry0;
    float unitx,unity;
    long start;

    float fr;
    long rx,ry;
    float length;
    char A;
    void setup() {
    // put your setup code here, to run once:
    Serial.begin(9600);
    // Bridge startup
    Console.begin();
    while (!Console);
    Console.println(start);


    }

    void loop() {
    // put your main code here, to run repeatedly:
    if (Console.available()!=0)
    {char A=Console.read();

    switch (A)
    {
    case 'a':
    { dx=-100;} break;
    case 'b':
    { dx=100;} break;
    case 'c':
    { dy=-50;} break;
    case 'd':
    { dy=50;} break;
    case 'e':
    { fr=0.1;} break;
    case 'f':
    { fr=0.4;} break;
    case 's':
    {
    length=sqrt(dx*dx+dy*dy);
    unitx=(float)dx/length;
    unity=(float)dy/length;
    rx0=rx;
    ry0=ry;
    rex=rx+dx;
    rey=ry+dy;
    start=1;
    L=0.0;
    A=0;
    } break;
    default:
    {
    } break;
    }
    if (start==1)
    {
    L=L+fr;
    rx=rx0+(long)(L*unitx);
    ry=ry0+(long)(L*unity);
    if (L>=length)
    {
    rx=rex;
    ry=rey;
    start=0;
    L=length;
    }
    }
    {
    Console.print(rx); Console.print("---"); Console.print(ry);
    Console.print("---"); Console.print(A);
    Console.print("---"); Console.print(L);
    Console.print("---"); Console.print(fr);
    Console.print("---"); Console.println(start);
    }
    }
    }

    ReplyDelete
  3. 我的問題是連結不成功
    不知是哪裡有問題

    ReplyDelete
    Replies
    1. 請提供相關資訊。
      錯誤訊息?螢幕擷圖?

      你程式裡有
      YunServer server(PORT);
      YunClient client;
      但後面並沒有使用。

      Delete
  4. 編輯無錯誤
    那我要怎麼修改呢

    ReplyDelete
    Replies
    1. 請先試試這一篇的程式吧,
      Console的作用類似於主控台、終端機的功能,跟以前的序列埠很像,但現在可經由Wi-Fi無線登入。

      先把Console搞定。

      Delete
    2. 對阿~我就是要用Wi-Fi把主控台的這個程式傳到終端機
      只是我現在連結失敗~不知道如何修改

      Delete
    3. > 用Wi-Fi把主控台的這個程式傳到終端機
      看不懂。

      你應該先燒錄這支程式,可以有線燒錄或無線燒錄,
      參考這篇http://yehnan.blogspot.tw/2016/04/arduino-yunwi-fi.html

      然後,使用Console的話,便可從wi-fi無線登入終端機介面,開啟序列埠監控視窗後,可看到程式裡使用Console.print輸出的訊息。

      > 連結失敗
      什麼連結。

      Delete
  5. 把主控台的程式運用Wi-Fi傳到終端機
    https://scontent.xx.fbcdn.net/v/t1.0-9/13912342_1063842933652607_7429268553309855823_n.jpg?oh=8293a78a97f9500b59a8be85cec3f27a&oe=58113EE3

    ReplyDelete
    Replies
    1. Console是讓你從wi-fi無線登入yun的終端機介面。

      請先「燒錄」程式,可以透過USB有線燒錄或wifi無線燒錄,
      無線燒錄部分,可參考這篇http://yehnan.blogspot.tw/2016/04/arduino-yunwi-fi.html

      程式燒錄完畢後,使用Console的話,便可從wi-fi無線登入終端機介面,開啟序列埠監控視窗後,可看到程式裡使用Console.print輸出的訊息。

      Delete