Log data to a micro SD card.

Dependencies:   SDFileSystem mbed

Files at this revision

API Documentation at this revision

Comitter:
onaka
Date:
Mon May 04 07:10:55 2015 +0000
Parent:
0:56d642e39289
Commit message:
revision 1

Changed in this revision

Log.cpp Show annotated file Show diff for this revision Revisions of this file
Log.h Show annotated file Show diff for this revision Revisions of this file
RingBuffer.cpp Show annotated file Show diff for this revision Revisions of this file
RingBuffer.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Log.cpp	Mon May 04 07:10:55 2015 +0000
@@ -0,0 +1,114 @@
+#include "Log.h"
+
+Log::Log(PinName rx, PinName tx, PinName mosi, PinName miso, PinName sck, PinName cs, const char* name) :
+    _device(rx, tx), _sd(mosi, miso, sck, cs, name){
+    buf_send.initialize_buffer();
+    _device.attach(this, &Log::int_serial_tx, Serial::TxIrq);
+}
+
+int Log::initialize_sdlog(const char* str){
+    char filename[15];
+    int n = find_last();
+    if(n < 0) return 0;
+    
+    //ログ番号を+1してファイルを新規作成
+    //ファイル名は"logXXX.csv"
+    sprintf(filename, "/sd/log%03d.csv", n+1);
+    fp = fopen(filename, "w");
+    
+    _device.printf(str);
+    fprintf(fp, str);
+    return 1;
+}
+
+void Log::close(){
+    wait(0.5);
+    fclose(fp);
+}
+
+//SDカード内からログ番号の最大値を取得する関数
+int Log::find_last() {
+    int i, n = 0;
+    char c;
+    DIR *dp;
+    struct dirent *dirst;
+    dp = opendir("/sd/");
+    if (!dp){
+        printf("Could not open directry\n");
+        return -1;
+    }
+    while((dirst = readdir(dp)) != NULL) {
+        if(sscanf(dirst->d_name, "log%03d.csv%c", &i, &c) == 1 && i>n) {
+            n = i;
+        }
+    }
+    closedir(dp);
+    return n;
+}
+
+void Log::puts(const char* str){
+    int16_t len=strlen(str);
+    int16_t capa=buf_send.buffer_capacity();
+    bool empty=buf_send.is_buffer_empty();
+    char ch;
+    if(len>capa){
+        len=capa;
+    }
+    buf_send.write_buffer((const uint8_t*)str, 0, len);
+    if((_device.writeable()) && (empty)){
+        ch=buf_send.read_buffer_byte();
+        _device.putc(ch);
+        fputc(ch, fp);
+    } 
+}
+
+void Log::putc(char ch){
+    int16_t capa=buf_send.buffer_capacity();
+    if(capa==0) return;
+    buf_send.write_buffer_byte(ch);
+}
+
+void Log::write_data(uint8_t* buf, int16_t size){
+    int capa=buf_send.buffer_capacity();
+    if(size>capa){
+        size=capa;
+    }
+    buf_send.write_buffer(buf, 0, size);
+}
+
+bool Log::is_empty(){
+    return buf_send.is_buffer_empty();
+}
+
+int16_t Log::recieve_buffer_size(){
+    return buf_recieve.buffer_size();
+}
+
+int16_t Log::getc(){
+    if(buf_recieve.is_buffer_empty()){
+        return -1;
+    }
+    return buf_recieve.read_buffer_byte();
+}
+
+int16_t Log::read_data(uint8_t* buf, int16_t size){
+    int len=buf_recieve.buffer_size();
+    if(size>len){
+        size=len;
+    }
+    buf_recieve.read_buffer(buf, 0, size);
+    return size;
+}
+
+char Log::int_tx(){
+    return buf_send.read_buffer_byte();
+}
+
+void Log::int_serial_tx(){
+    char ch;
+    while((_device.writeable()) && (buf_send.is_buffer_empty()==false)){
+        ch=buf_send.read_buffer_byte();
+        _device.putc(ch);
+        fputc(ch, fp);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Log.h	Mon May 04 07:10:55 2015 +0000
@@ -0,0 +1,37 @@
+//**** Log.h ****
+//ログをリングバッファを用いて、
+//シリアル送信、SDカード出力を行う
+//***************
+
+#ifndef LOG_H_ 
+#define LOG_H_ 
+
+#include "mbed.h"
+#include "SDFileSystem.h"
+#include "RingBuffer.h"
+
+class Log{
+public:
+    Log(PinName rx, PinName tx, PinName mosi, PinName miso, PinName sck, PinName cs, const char* name);
+    int initialize_sdlog(const char* str);
+    void close();
+    int find_last();
+    void puts(const char *str);
+    void putc(char ch);
+    void write_data(uint8_t* buf, int16_t size);
+    bool is_empty();
+    int16_t recieve_buffer_size();
+    int16_t getc();
+    int16_t read_data(uint8_t* buf, int16_t size);
+    char int_tx();
+    void int_serial_tx();
+
+protected:
+    SDFileSystem _sd;
+    FILE *fp;
+    Serial _device;
+    RingBuffer buf_send;
+    RingBuffer buf_recieve;
+};
+
+#endif /* LOG_H_ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RingBuffer.cpp	Mon May 04 07:10:55 2015 +0000
@@ -0,0 +1,63 @@
+#include "RingBuffer.h"
+
+void RingBuffer::initialize_buffer(){
+    start=0;
+    end=0;
+}
+
+int16_t RingBuffer::buffer_size(){
+    if(end >= start){
+        return end - start;
+    }
+    return RING_BUFFER_SIZE - (start - end);
+}
+
+uint8_t RingBuffer::read_buffer_byte(){
+    uint8_t a;
+    a=buffer[start];
+    start=(start+1)%RING_BUFFER_SIZE;
+    return a;
+}
+
+int16_t RingBuffer::read_buffer_short(){
+    int16_t a, b;
+    a=buffer[start];
+    b=buffer[(start+1)%RING_BUFFER_SIZE];
+    start=(start+2)%RING_BUFFER_SIZE;
+    return (a&0xff)|(b<<8);
+}
+
+void RingBuffer::read_buffer(uint8_t buf[], int16_t offset, int16_t size){
+    int16_t i;
+    uint8_t* p=buf+offset;
+    
+    for(i=0; i<size; i++){
+        *(p++)=buffer[start];
+        start=(start+1)%RING_BUFFER_SIZE;
+    }
+}
+
+int16_t RingBuffer::buffer_capacity(){
+    if(end >= start){
+        return RING_BUFFER_SIZE-(end-start)-1;
+    }
+    return (start-end)-1;
+}
+
+void RingBuffer::write_buffer_byte(uint8_t ch){
+    buffer[end]=ch;
+    end=(end+1)%RING_BUFFER_SIZE;
+}
+
+void RingBuffer::write_buffer(const uint8_t buf[], int16_t offset, int16_t size){
+    int16_t i;
+    const uint8_t* p=buf+offset;
+    for(i=0; i<size; i++){
+        buffer[end]=*(p++);
+        end=(end+1)%RING_BUFFER_SIZE;
+    }
+}
+
+bool RingBuffer::is_buffer_empty(){
+    return (start==end);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RingBuffer.h	Mon May 04 07:10:55 2015 +0000
@@ -0,0 +1,26 @@
+#ifndef RING_BUFFER_H_
+#define RING_BUFFER_H_
+
+#include "mbed.h"
+
+#define RING_BUFFER_SIZE 512
+
+class RingBuffer{
+public:
+    void initialize_buffer();
+    int16_t buffer_size();
+    uint8_t read_buffer_byte();
+    int16_t read_buffer_short();
+    void read_buffer(uint8_t buf[], int16_t offset, int16_t size); 
+    int16_t buffer_capacity();
+    void write_buffer_byte(uint8_t ch);
+    void write_buffer(const uint8_t buf[], int16_t offset, int16_t size);
+    bool is_buffer_empty();
+
+protected:
+    uint8_t buffer[RING_BUFFER_SIZE];
+    int16_t start;
+    int16_t end;
+};
+
+#endif /* RING_BUFFER_H_ */
\ No newline at end of file
--- a/main.cpp	Wed Apr 22 06:57:07 2015 +0000
+++ b/main.cpp	Mon May 04 07:10:55 2015 +0000
@@ -1,63 +1,42 @@
 #include "mbed.h"
-#include "SDFileSystem.h"
+#include "Log.h"
 
 DigitalIn mybutton(USER_BUTTON);
 Serial pc(SERIAL_TX, SERIAL_RX);
 
-SDFileSystem sd(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS, "sd");
-FILE *fp;
+Log logger(SERIAL_TX, SERIAL_RX, SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS, "sd");
 
 Ticker timer;
-static double t;    //時間t
-
-//SDカード内からログ番号の最大値を取得する関数
-int find_last() {
-    int i, n = 0;
-    DIR *dp;
-    struct dirent *dirst;
-    dp = opendir("/sd/");
-    if (!dp){
-        printf("Could not open directry\n");
-        return -1;
-    }
-    while((dirst = readdir(dp)) != NULL) {
-        if(sscanf(dirst->d_name, "log%03d.csv", &i) == 1 && i>n) {
-            n = i;
-        }
-    }
-    closedir(dp);
-    return n;
-}
-
-void Int_Timer() {
-    //ボタンが押されているかどうかをログする
-    fprintf(fp, "%.1f,%d\n", t, (int)mybutton);
-    t += 0.1;
-}
+void Int_Timer();
+static double t;
 
 int main() {
-    char filename[15];
-    int n = find_last();
-    if(n < 0) return 0;
-    
-    //ログ番号を+1してファイルを新規作成
-    //ファイル名は"logXXX.csv"
-    sprintf(filename, "/sd/log%03d.csv", n+1);
-    fp = fopen(filename, "w");
-    
-    printf("Start writing!\n");
-    fprintf(fp, "time,x\n");
-    
-    //0.1s間隔のタイマー割り込み
+    /** ログのタイトル行 **/
+    char* str="time,button\n";
+    if(!(logger.initialize_sdlog(str))){
+        return 0;
+    }
+
+//    printf("Start!\n");
     timer.attach(&Int_Timer, 0.1);
     
     t = 0.0;
-    //10.0sで終了
-    while(t < 10.0){
+    while(1){
+        if(t > 10.0){
+            timer.detach();
+            break;
+        }
     }
 
-    timer.detach();
-    fclose(fp);
+    logger.close();
     printf("Finish!\n");
 }
- 
\ No newline at end of file
+
+
+void Int_Timer() {
+    char buf[20];
+    /** ログをとりたい値を記入 **/
+    sprintf(buf, "%.1f,%d\n", t, (int)mybutton);
+    logger.puts(buf);
+    t += 0.1;
+}
\ No newline at end of file
--- a/mbed.bld	Wed Apr 22 06:57:07 2015 +0000
+++ b/mbed.bld	Mon May 04 07:10:55 2015 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/433970e64889
\ No newline at end of file
+http://mbed.org/users/mbed_official/code/mbed/builds/8ab26030e058
\ No newline at end of file