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