2014/04/13

Arduino Yún:Bridge程式庫入門(使用Process執行命令列模式下的指令)

之前已經初步介紹過Yún的Bridge程式庫,這一篇要使用Process執行命令列模式的指令,並且試著以非同步方式執行。

至於Linux命令列模式下有哪些指令,不在本篇討論範圍。

首先以同步方式執行,意思是說,指令需完全執行完畢,才會回傳。程式碼如下:

#include  <Process.h>

void setup() {
  Bridge.begin();
  Serial.begin(19200);
  while(!Serial)
    ;
}
void loop() {
  Process p; // 使用Process類別來執行指令
  // 呼叫runShellCommand方法執行Shell指令
  p.runShellCommand("iw dev wlan0 station dump");
  // runShellCommand屬於阻斷式呼叫,
  // 等到該方法回傳時,指令已執行完畢

  while(p.available() > 0){  // 把結果送往序列埠監控視窗
    char c = p.read();
    Serial.print(c);
  }
  Serial.flush();
  delay(5000); // 每5秒執行一次
}

執行結果大概如下:
Station 5d:05:a1:5a:e2:78 (on wlan0)
    inactive time:    11600 ms
    rx bytes:    5684813
    rx packets:    55634
    tx bytes:    90102
    tx packets:    804
    tx retries:    269
    tx failed:    0
    signal:      -35 dBm
    signal avg:    -34 dBm
    tx bitrate:    72.2 MBit/s MCS 7 short GI
    rx bitrate:    1.0 MBit/s
    authorized:    yes
    authenticated:    yes
    preamble:    long
    WMM/WME:    yes
    MFP:        no
    TDLS peer:    no

其中signal代表的就是RSSI值。

你也可以把
p.runShellCommand("iw dev wlan0 station dump");
換成
p.runShellCommand("/usr/bin/pretty-wifi-info.lua");

可得到類似底下的輸出:
Current WiFi configuration
SSID: N10U
Mode: Client
Signal: 100%
Encryption method: WPA2 PSK (CCMP)
Interface name: wlan0
Active for: 49 minutes
IP address: 192.168.1.235/255.255.255.0
MAC address: 90:A2:DA:F1:06:36
RX/TX: 303/84 KBs

接下來試試非同步的呼叫方式,
#include  <Process.h>

void setup() {
  Bridge.begin();
  Serial.begin(19200);
  while(!Serial)
    ;
}
Process p; // 注意,Process物件改為全域變數
void loop() {
  if(Serial.available()){ // 在序列埠監控視窗隨便輸入些什麼東西
    while(Serial.read() != -1) // 就可以觸發執行指令
      ;
    // 呼叫非同步方法runShellCommandAsynchronously
    p.runShellCommandAsynchronously("iw dev wlan0 station dump");
  }

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

其實runShellCommandAsynchronously的底層實作會去呼叫runAsynchronously,只不過再指定shell與參數-c罷了,兩者用法差不多。而run跟runShellCommand最後都是去呼叫非同步的方法,但是再加上delay,一直等到執行結束,然後再回傳。

使用非同步方法時,有不少地方需要注意,譬如底下的程式碼,看起來似乎沒錯,但執行時卻什麼東西也沒有,沒有輸出。
#include  <Process.h>
void setup() {
  Bridge.begin();
  Serial.begin(19200);
  while(!Serial)
    ;
}

void loop() {
  Process p; // 注意
  p.begin("uptime"); // 注意
  if(Serial.available()){
    while(Serial.read() != -1)
      ;
    p.runAsynchronously();
  }

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

原因在於使用非同步方法時,若Process物件位於函式內、屬於區域變數,那麼當指令尚未完成就會消失不見了;而且若每次進入loop就呼叫begin("uptime"),begin不僅會設定新的指令,也會呼叫close結束上次的指令,所以上次指令尚未執行完成就被結束了。

呼,慢慢嘗試吧。

No comments:

Post a Comment