diff --git a/README.md b/README.md index 606cfad..3efe4d2 100644 --- a/README.md +++ b/README.md @@ -67,10 +67,9 @@ working: - GPS data parsing - RTC date and time synchronisation to GPS time - forward Bluetooth <-> Forumslader data +- log GPS, Bluetooth, and Forumslader data on SD card (in file `forumslogger_YYYY-%MM-DD_hh-mm-ss.txt`) TODO: -- log forumslader data -- log GPS data - provide Bluetooth commands to list, retrieve, and delete files The forumslader data does not include timestamps. @@ -121,7 +120,7 @@ the 2nd 0 is the speed in 0.6 km/h steps 4135 is the cell 3 voltage in mV -24 is the accu current in mA the 3rd 0 is the consumer power in 0.0124 Watt steps (dependant on another parameter) -1 is the cinsumer current in mA +1 is the consumer current in mA 232 is the temperature in F 260 is the micropulsecounter 6750 is the pulsecounter diff --git a/application.c b/application.c index 23a7b4c..c1e1b54 100644 --- a/application.c +++ b/application.c @@ -177,9 +177,9 @@ error: */ DWORD get_fattime (void) { - time_rtc= rtc_get_counter_val(); // get time from internal RTC + time_rtc = rtc_get_counter_val(); // get time from internal RTC time_tm = localtime(&time_rtc); // convert time - return ((1900+time_tm->tm_year-1800)<<25)+((time_tm->tm_mon)<<21)+((time_tm->tm_mday)<<16)+((time_tm->tm_hour)<<11)+((time_tm->tm_min)<<5)+((time_tm->tm_sec/2)<<0); // convert time to DWORD + return ((1900+time_tm->tm_year-1980)<<25)+((time_tm->tm_mon)<<21)+((time_tm->tm_mday)<<16)+((time_tm->tm_hour)<<11)+((time_tm->tm_min)<<5)+((time_tm->tm_sec/2)<<0); // convert time to DWORD } #endif @@ -314,6 +314,47 @@ DRESULT disk_write (BYTE drv, const BYTE* buff, DWORD sector, UINT count) return RES_OK; } +/** file name for log file (empty when SD card is not mounted) */ +static char log_name[36+1] = ""; + +/** log message to SD card + * @param[in] message string message to be logged (must be NULL terminated + * @return if logging message succeeded (SD card is available and messages can be appended to log file) + * @note data will be written on SD card only after a least one 512 bytes block of messages is available + */ +static bool log(char* message) +{ + static char log_buffer[600] = ""; // buffer messages until we have a 512 bytes block to write + static uint16_t log_used = 0; // how much of the buffer has been used + if (0==strlen(log_name)) { // there is no file to log to + return false; + } + if (strlen(message)+log_used>LENGTH(log_buffer)) { // message too long to be saved + return false; + } + for (uint16_t i=0; i=512) { // one data block is available for writing + FIL log_file; // file to log the data + if (FR_OK!=f_open(&log_file, log_name, FA_OPEN_APPEND | FA_WRITE)) { // open file to put log in + return false; + } + UINT written = 0; + if (FR_OK!=f_write(&log_file, log_buffer, log_used, &written)) { // write data + return false; + } + if (FR_OK!=f_close(&log_file)) { // close file (and flush data) + return false; + } + if (written!=log_used) { // did not log all bytes + return false; + } + log_used = 0; // reset buffer + } + return true; +} + /** program entry point * this is the firmware function started by the micro-controller */ @@ -358,6 +399,11 @@ void main(void) nvic_enable_irq(NVIC_RTC_IRQ); // allow the RTC to interrupt printf("OK\n"); + // print time + time_rtc= rtc_get_counter_val(); // get time from internal RTC + time_tm = localtime(&time_rtc); // convert time + printf("date: %d-%02d-%02d %02d:%02d:%02d\n", 1900+time_tm->tm_year, time_tm->tm_mon, time_tm->tm_mday, time_tm->tm_hour, time_tm->tm_min, time_tm->tm_sec); + printf("setup forumslader UART: "); sensor_forumslader_setup(); // setup USART printf("OK\n"); @@ -372,60 +418,21 @@ void main(void) printf("OK\n"); printf("setup SD card file system: "); - FATFS card_fs; - FRESULT result = f_mount(&card_fs, "", 0); + FATFS card_fs; // SD card FAT file system + DIR directory; // for the root directory + FRESULT result = f_mount(&card_fs, "", 0); // mount file system if (FR_OK!=result) { printf("failed (result=%u)\n", result); } else { - printf("OK\n"); - DIR directory; result = f_opendir(&directory, ""); if (FR_OK!=result) { printf("failed to open directory (result=%u)\n", result); } else { - printf("directory opened\n"); - FILINFO info; - result = f_findfirst(&directory, &info, "", "*"); - if (FR_OK!=result) { - printf("failed to find item (result=%u)\n", result); - } else { - printf("item found: %s\n", info.fname); - FIL file; - result = f_open(&file, info.fname, FA_READ); - if (FR_OK!=result) { - printf("failed to open file (result=%u)\n", result); - } else { - printf("file opened\n"); - printf("file content:\n"); - char line[100]; - while (f_gets(line, sizeof(line), &file)) { - printf(line); - } - f_close(&file); - FIL file2; - result = f_open(&file2, info.fname, FA_OPEN_APPEND | FA_WRITE); - if (FR_OK!=result) { - printf("failed to open file for appending (result=%u)\n", result); - } else { - int chars = f_puts("hello me\n", &file2); - if (-1==chars) { - printf("failed to append file\n"); - } else { - printf("file appended by %d characters\n", chars); - } - f_close(&file2); - } - - } - } + snprintf(log_name, LENGTH(log_name), "forumslogger_%04d-%02d-%02d_%02d-%02d-%02d.txt", 1900+time_tm->tm_year, time_tm->tm_mon, time_tm->tm_mday, time_tm->tm_hour, time_tm->tm_min, time_tm->tm_sec); // create file name for log file based on date + printf("log will be saved in %s\n", log_name); } } - // print time - time_rtc= rtc_get_counter_val(); // get time from internal RTC - time_tm = localtime(&time_rtc); // convert time - printf("date: %d-%02d-%02d %02d:%02d:%02d\n", 1900+time_tm->tm_year, time_tm->tm_mon, time_tm->tm_mday, time_tm->tm_hour, time_tm->tm_min, time_tm->tm_sec); - // main loop printf("command input: ready\n"); bool action = false; // if an action has been performed don't go to sleep @@ -461,12 +468,26 @@ void main(void) action = true; // action has been performed printf("button pressed\n"); led_toggle(); // toggle LED - if (!sensor_forumslader_transmit("hello\n")) { - printf("could not transmit to forumslader\n"); - } for (uint32_t i=0; i<1000000; i++) { // wait a bit to remove noise and double trigger __asm__("nop"); } + + if (strlen(log_name)) { // check is card file system is available + printf("log files:\n"); + FILINFO info; + result = f_findfirst(&directory, &info, "", "forumslogger_?\??\?-?\?-?\?_?\?-?\?-?\?.txt"); + while (FR_OK==result && strlen(info.fname)) { + printf("- %s\n", info.fname); + result = f_findnext(&directory, &info); + } + if (log((char*)"0123456789112345678921234567893123456789412345678951234567896123456789")) { // log message + printf("logging message worked\n"); + } else { + printf("logging message failed\n"); + } + } else { + printf("card file system not available\n"); + } button_flag = false; // reset flag } while (rtc_internal_tick_flag) { // the internal RTC ticked @@ -485,18 +506,25 @@ void main(void) sensor_forumslader_received = false; // clear flag action = true; // action has been performed radio_bluetooth_transmit((const char*)sensor_forumslader_message); // forward message over Bluetooth - printf("forumslader: %s", sensor_forumslader_message); // print message + //printf("Forumslader: %s", sensor_forumslader_message); // print message + if (!log((char*)sensor_forumslader_message)) { // log Forumslader message + printf("logging Forumslader message failed\n"); + } + } while (radio_bluetooth_received) { // a message has been received over Bluetooth radio_bluetooth_received = false; // clear flag action = true; // action has been performed sensor_forumslader_transmit((const char*)radio_bluetooth_message); // forward message to forumslader - printf("Bluetooth: %s", radio_bluetooth_message); // print message + //printf("Bluetooth: %s", radio_bluetooth_message); // print message + if (!log((char*)radio_bluetooth_message)) { // log Bluetooth message + printf("logging Bluetooth message failed\n"); + } } while (radio_gps_received) { // a GPS message has been received radio_gps_received = false; // clear flag action = true; // action has been performed - //printf("GPS: %s", radio_gps_message); // print GPS message + if (!gps_rtc_synced) { // if the RTC has not been synced with the GPS time, try to do it if (0==strncmp((const char *)radio_gps_message,"$GPRMC,",7)) { // get time from GPS uint8_t arg = 0; @@ -536,6 +564,10 @@ void main(void) } } } + //printf("GPS: %s", radio_gps_message); // print GPS message + if (!log((char*)radio_gps_message)) { // log GPS message + printf("logging GPS message failed\n"); + } } if (action) { // go to sleep if nothing had to be done, else recheck for activity action = false;