之前已經初步介紹過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