2016/04/10

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

Yún的Atheros AR9331本身具有Flash快閃記憶體空間,但只有16 MB,而且其中約9 MB已用來儲存OpenWrt-Yun,剩下約7 MB。另外可插micro SD記憶卡。

可登入Yun的主控台,下指令查知內部Flash空間剩餘多少,請把192.168.1.61換成你的Yun的IP位址:
$ ssh root@192.168.1.61
root@192.168.1.61's password:

BusyBox v1.19.4 (2014-11-13 19:03:47 CET) built-in shell (ash)
Enter 'help' for a list of built-in commands.
  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------

root@ArduinoYun:~# df -h
Filesystem                Size      Used Available Use% Mounted on
rootfs                    6.9M    604.0K      6.3M   9% /
/dev/root                 7.5M      7.5M         0 100% /rom
tmpfs                    29.8M    152.0K     29.7M   0% /tmp
tmpfs                   512.0K         0    512.0K   0% /dev
/dev/mtdblock3            6.9M    604.0K      6.3M   9% /overlay
overlayfs:/overlay        6.9M    604.0K      6.3M   9% /


從以上輸出可知,總共有6.9 MB,已用掉604 KB,剩餘6.3 MB。

透過Bridge程式庫的FileIO類別,可以存取內部Flash與外接micro SD卡。範例程式如下,燒錄後,開啟序列埠監控視窗,輸入w會讀取類比腳位A0的值,並且取得當時的日期時間,記錄在檔案裡;輸入r則會讀取該記錄檔的內容,顯示在序列埠監控視窗。

#include <FileIO.h>

void setup() {
    Bridge.begin();
    Serial.begin(57600);
    BridgeFileSystem.begin(); // 初始化檔案系統

    while(!Serial && millis() < 5000){
    }
}
String timestamp(){
    String result;
    Process p;
    p.begin("date");
    p.run();
    while(p.available() > 0){
        char c = p.read();
        if(c != '\n')
            result += c;
    }

    return result;
}
void log_write(const char *filepath, String data){

    // 根據檔案存在與否、判斷開檔模式
    const int mode = BridgeFileSystem.exists(filepath) ? FILE_APPEND : FILE_WRITE;
    BridgeFile file = BridgeFileSystem.open(filepath, mode); // 開檔

    if(file){ // 確認開檔成功
        file.print(data); // 寫入資料
        Serial.println(data);
        file.close(); // 關檔
    }
    else{
        Serial.print("File open failed: ");
        Serial.println(filepath);
    }

}
void log_read(const char *filepath){
    if(BridgeFileSystem.exists(filepath)){
        BridgeFile file = BridgeFileSystem.open(filepath, FILE_READ);
        if(file){
            char buf[128+1]; // 讀取緩衝區,假定檔案的一行最多128個字元
            int cnt;
            while( (cnt = file.readBytesUntil('\n', buf, 128)) > 0){
                buf[cnt] = '\0'; // +1 是為了放進'\0'
                Serial.println(buf);
            }
            file.close();
        }
        else{
            Serial.print("File open failed: ");
            Serial.println(filepath);
        }
    }
    else{
        Serial.print("File doesn't exist: ");
        Serial.println(filepath);
    }
}

// 檔案路徑
const char filepath[] = "/root/data.txt";
// 若想儲存在micro SD卡裡,路徑需改成/mnt/sda1/
// const char filepath[] = "/mnt/sda1/data.txt";

void loop () {
    if(Serial.available()){
        char c = Serial.read();
        switch(c){
            case 'w':{
                String data; // 將要寫入檔案的資料
                data += timestamp(); // 取得日期時間
                data += ", Analog Pin A0 = ";
                data += analogRead(A0); // 讀取A0的值
                data += "\n";
                log_write(filepath, data);
            }
            break;
            case 'r':{
                log_read(filepath);
            }
            break;
        }
    }
}


因為原有的內建程式庫或第三方程式庫,多半已有名為File和FileSystem的類別,所以Bridge程式庫採用BridgeFile與BridgeFileSystem之名,但也以typedef作對應。

檔案內容大概如下:
Tue Jan 26 15:22:14 CST 2016, Analog Pin A0 = 253
Tue Jan 26 15:24:47 CST 2016, Analog Pin A0 = 339
Tue Jan 26 15:34:41 CST 2016, Analog Pin A0 = 338
...

序列埠監控視窗如下,輸入兩次w、一次r的結果:


同時只能開啟一支檔案,所以必須先關掉前一支檔案,然後才能開啟另一支檔案。


參考資料:

No comments:

Post a Comment