嘗試使用Bridge程式庫的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();
}
結果如下圖:
#include <Process.h>
void setup() {
Bridge.begin();
Serial.begin(56700);
while(!Serial){
}
}
void loop() {
if(Serial.available() > 0){
int b = Serial.read();
Process p;
switch(b){
case '1':
p.begin("cat");
p.addParameter("/proc/cpuinfo");
p.run();
break;
case '2': // 注意!
p.begin("cat /proc/cpuinfo");
p.run();
break;
case '3':
p.runShellCommand("cat /proc/cpuinfo");
break;
case '4':
p.runShellCommand("iw dev wlan0 station dump");
break;
case '5':
p.runShellCommand("/usr/bin/pretty-wifi-info.lua");
break;
case '6':
p.runShellCommand("/usr/bin/pretty-wifi-info.lua | grep Signal");
break;
}
while(p.available() > 0){
Serial.print((char) p.read());
}
Serial.flush();
}
}
其中2的p.begin("cat /proc/cpuinfo");將會失敗,因為若以begin起始指令,須以addParameter加入參數,Process會以特殊字元分隔。至於若使用runShellCommand的話,會把整行指令丟給shell(ash),由它處理。
以上都是同步執行方式執行,意思是說,指令需完全執行完畢,才會回傳。
接下來試試非同步的呼叫方式,
#include <Process.h>
void setup() {
Bridge.begin();
Serial.begin(57600);
while(!Serial){
}
}
Process p; // 注意,Process是全域變數
void loop() {
if(Serial.available() > 0){ // 在序列埠監控視窗隨便輸入些什麼東西
int b = Serial.read();
switch(b){
case '1':
p.begin("cat");
p.addParameter("/proc/cpuinfo");
p.runAsynchronously();
break;
case '2':
p.runShellCommandAsynchronously("uptime");
break;
}
}
if(!p.running()){
while(p.available() > 0){
char c = p.read();
Serial.print(c);
}
}
Serial.flush();
}
以runAsynchronously或runShellCommandAsynchronously來執行指令,然後以running判斷是否執行完畢。
其實run的底層會去呼叫runAsynchronously,裡頭同樣會利用running作判斷,完成後才回傳。而runShellCommand的底層會去呼叫runShellCommandAsynchronously,同樣會利用running作判斷。有ShellCommand字樣的方法,會再指定shell(ash)罷了。
使用非同步方法時,有不少地方需要注意,若把Process p;放在函式裡成為區域變數,那麼當指令尚未完成、p就會消失不見;而且若每次進入loop就呼叫begin("uptime"),begin不僅會設定新的指令,也會呼叫close結束上次的指令,所以上次指令尚未執行完成就被結束了。
參考資料:
- Arduino官方文件的ArduinoYun與Bridge Library for Arduino Yún。
- Arduino官方部落格Hands on: the Arduino Yún’s Bridge。
No comments:
Post a Comment