Log data to a micro SD card.
Dependencies: SDFileSystem mbed
Revision 1:c5e56e2580bf, committed 2015-05-04
- Comitter:
- onaka
- Date:
- Mon May 04 07:10:55 2015 +0000
- Parent:
- 0:56d642e39289
- Commit message:
- revision 1
Changed in this revision
--- /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