On boot, logs 10 seconds of current draw information from an INA169 breakout board to an SD card.

Dependencies:   SDFileSystem mbed

Committer:
ShawnHymel
Date:
Fri Jul 24 13:48:24 2015 +0000
Revision:
0:c407693ac016
Initial release. Used in the SBC Benchmarking video.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ShawnHymel 0:c407693ac016 1 /**
ShawnHymel 0:c407693ac016 2 * Current Log-O-Matic
ShawnHymel 0:c407693ac016 3 * Author: Shawn Hymel @ SparkFun Electronics
ShawnHymel 0:c407693ac016 4 * Date: July 1, 2015
ShawnHymel 0:c407693ac016 5 *
ShawnHymel 0:c407693ac016 6 * Measures current using an INA169 breakout board. Stores current and timestamp
ShawnHymel 0:c407693ac016 7 * to an SD card.
ShawnHymel 0:c407693ac016 8 *
ShawnHymel 0:c407693ac016 9 * INA169 Vout -> Pin 15
ShawnHymel 0:c407693ac016 10 * SD Card DI -> Pin 5
ShawnHymel 0:c407693ac016 11 * SD Card DO -> Pin 6
ShawnHymel 0:c407693ac016 12 * SD Card SCK -> Pin 7
ShawnHymel 0:c407693ac016 13 * SD Card CS -> Pin 8
ShawnHymel 0:c407693ac016 14 *
ShawnHymel 0:c407693ac016 15 * This code is beerware; if you see me (or any other SparkFun
ShawnHymel 0:c407693ac016 16 * employee) at the local, and you've found our code helpful, please
ShawnHymel 0:c407693ac016 17 * buy us a round!
ShawnHymel 0:c407693ac016 18 *
ShawnHymel 0:c407693ac016 19 * Distributed as-is; no warranty is given.
ShawnHymel 0:c407693ac016 20 */
ShawnHymel 0:c407693ac016 21
ShawnHymel 0:c407693ac016 22 #include "mbed.h"
ShawnHymel 0:c407693ac016 23 #include "SDFileSystem.h"
ShawnHymel 0:c407693ac016 24
ShawnHymel 0:c407693ac016 25 #define DEBUG 1 // 1 to print to console. 0 to turn off.
ShawnHymel 0:c407693ac016 26 #define MAX_FILES 100 // Maximum number of log files to store on SD
ShawnHymel 0:c407693ac016 27 #define DELAY_MS 0.02 // Time between samples (in seconds)
ShawnHymel 0:c407693ac016 28 #define NUM_SAMPLES 500 // Number of samples to collect
ShawnHymel 0:c407693ac016 29 #define RS 0.5 // Value of RS (sensing resistor) in ohms
ShawnHymel 0:c407693ac016 30 #define RL 10000 // Value of RL (output resistor) in ohms
ShawnHymel 0:c407693ac016 31
ShawnHymel 0:c407693ac016 32 // Digital output (status LED)
ShawnHymel 0:c407693ac016 33 DigitalOut status_led(LED1);
ShawnHymel 0:c407693ac016 34
ShawnHymel 0:c407693ac016 35 // Analog input (pin 15)
ShawnHymel 0:c407693ac016 36 AnalogIn ain(p15);
ShawnHymel 0:c407693ac016 37
ShawnHymel 0:c407693ac016 38 // USB serial (tx, rx)
ShawnHymel 0:c407693ac016 39 Serial pc(USBTX, USBRX);
ShawnHymel 0:c407693ac016 40
ShawnHymel 0:c407693ac016 41 // SD card (SPI pins)
ShawnHymel 0:c407693ac016 42 SDFileSystem sd(p5, p6, p7, p8, "sd");
ShawnHymel 0:c407693ac016 43
ShawnHymel 0:c407693ac016 44 // Global variables
ShawnHymel 0:c407693ac016 45 const char file_root[] = "idata";
ShawnHymel 0:c407693ac016 46 const char file_suffix[] = ".csv";
ShawnHymel 0:c407693ac016 47 char filename[20];
ShawnHymel 0:c407693ac016 48 Timer timer;
ShawnHymel 0:c407693ac016 49
ShawnHymel 0:c407693ac016 50 // Return true if file (or directory) 'filename' is present in directory 'root'
ShawnHymel 0:c407693ac016 51 // Based on: https://developer.mbed.org/forum/mbed/topic/463/
ShawnHymel 0:c407693ac016 52 bool exists(char * root, char *filename)
ShawnHymel 0:c407693ac016 53 {
ShawnHymel 0:c407693ac016 54 DIR *d = opendir(root);
ShawnHymel 0:c407693ac016 55 struct dirent *p;
ShawnHymel 0:c407693ac016 56 bool found = false;
ShawnHymel 0:c407693ac016 57 if ( d != NULL )
ShawnHymel 0:c407693ac016 58 {
ShawnHymel 0:c407693ac016 59 while ( !found && (p = readdir(d)) != NULL )
ShawnHymel 0:c407693ac016 60 {
ShawnHymel 0:c407693ac016 61 if ( strcmp(p->d_name, filename) == 0 )
ShawnHymel 0:c407693ac016 62 found = true;
ShawnHymel 0:c407693ac016 63 }
ShawnHymel 0:c407693ac016 64 }
ShawnHymel 0:c407693ac016 65 closedir(d);
ShawnHymel 0:c407693ac016 66 return found;
ShawnHymel 0:c407693ac016 67 }
ShawnHymel 0:c407693ac016 68
ShawnHymel 0:c407693ac016 69 // Main
ShawnHymel 0:c407693ac016 70 int main( void )
ShawnHymel 0:c407693ac016 71 {
ShawnHymel 0:c407693ac016 72 FILE *file;
ShawnHymel 0:c407693ac016 73 char str[5];
ShawnHymel 0:c407693ac016 74 int i;
ShawnHymel 0:c407693ac016 75 int led_state;
ShawnHymel 0:c407693ac016 76 float voltage_in;
ShawnHymel 0:c407693ac016 77 float current;
ShawnHymel 0:c407693ac016 78 float timestamp;
ShawnHymel 0:c407693ac016 79
ShawnHymel 0:c407693ac016 80 // Debugging start
ShawnHymel 0:c407693ac016 81 #if DEBUG == 1
ShawnHymel 0:c407693ac016 82 printf("\n\r");
ShawnHymel 0:c407693ac016 83 printf("-------------------\n\r");
ShawnHymel 0:c407693ac016 84 printf("Current Log-O-Matic\n\r");
ShawnHymel 0:c407693ac016 85 printf("-------------------\n\r");
ShawnHymel 0:c407693ac016 86 #endif
ShawnHymel 0:c407693ac016 87
ShawnHymel 0:c407693ac016 88 // Create next file in sequence
ShawnHymel 0:c407693ac016 89 for ( i = 0; i < MAX_FILES; i++ ) {
ShawnHymel 0:c407693ac016 90
ShawnHymel 0:c407693ac016 91 // Construct filename
ShawnHymel 0:c407693ac016 92 strcpy(filename, file_root);
ShawnHymel 0:c407693ac016 93 sprintf(str, "%d", i);
ShawnHymel 0:c407693ac016 94 strcat(filename, str);
ShawnHymel 0:c407693ac016 95 strcat(filename, file_suffix);
ShawnHymel 0:c407693ac016 96
ShawnHymel 0:c407693ac016 97 // If file exists, skip to next. If not, create it.
ShawnHymel 0:c407693ac016 98 if ( exists("/sd", filename) ) {
ShawnHymel 0:c407693ac016 99 #if DEBUG == 1
ShawnHymel 0:c407693ac016 100 printf ("%s found\n\r", filename);
ShawnHymel 0:c407693ac016 101 #endif
ShawnHymel 0:c407693ac016 102 if ( i == (MAX_FILES - 1) ) {
ShawnHymel 0:c407693ac016 103 error("ERROR: Too many files!\n\r");
ShawnHymel 0:c407693ac016 104 return -1;
ShawnHymel 0:c407693ac016 105 }
ShawnHymel 0:c407693ac016 106 } else {
ShawnHymel 0:c407693ac016 107 #if DEBUG == 1
ShawnHymel 0:c407693ac016 108 printf ("%s not found. Creating.\n\r", filename);
ShawnHymel 0:c407693ac016 109 #endif
ShawnHymel 0:c407693ac016 110 break;
ShawnHymel 0:c407693ac016 111 }
ShawnHymel 0:c407693ac016 112 }
ShawnHymel 0:c407693ac016 113
ShawnHymel 0:c407693ac016 114 // Construct absolute path to file
ShawnHymel 0:c407693ac016 115 strcpy(filename, "/sd/");
ShawnHymel 0:c407693ac016 116 strcat(filename, file_root);
ShawnHymel 0:c407693ac016 117 sprintf(str, "%d", i);
ShawnHymel 0:c407693ac016 118 strcat(filename, str);
ShawnHymel 0:c407693ac016 119 strcat(filename, file_suffix);
ShawnHymel 0:c407693ac016 120
ShawnHymel 0:c407693ac016 121 // Open file for writing
ShawnHymel 0:c407693ac016 122 #if DEBUG == 1
ShawnHymel 0:c407693ac016 123 printf("Opening %s\n\r", filename);
ShawnHymel 0:c407693ac016 124 #endif
ShawnHymel 0:c407693ac016 125 file = fopen(filename, "w");
ShawnHymel 0:c407693ac016 126 if ( file == NULL ) {
ShawnHymel 0:c407693ac016 127 error("ERROR: Could not open file for writing!\n\r");
ShawnHymel 0:c407693ac016 128 return -1;
ShawnHymel 0:c407693ac016 129 }
ShawnHymel 0:c407693ac016 130
ShawnHymel 0:c407693ac016 131 // Write header to file
ShawnHymel 0:c407693ac016 132 fprintf(file, "Time,Current\n\r");
ShawnHymel 0:c407693ac016 133
ShawnHymel 0:c407693ac016 134 // Start timer and begin sampling
ShawnHymel 0:c407693ac016 135 led_state = 0;
ShawnHymel 0:c407693ac016 136 #if DEBUG == 1
ShawnHymel 0:c407693ac016 137 printf("Sampling. Do not remove SD card!\n\r");
ShawnHymel 0:c407693ac016 138 #endif
ShawnHymel 0:c407693ac016 139 timer.start();
ShawnHymel 0:c407693ac016 140 for ( i = 0; i < NUM_SAMPLES; i++ ) {
ShawnHymel 0:c407693ac016 141
ShawnHymel 0:c407693ac016 142 // Write data to csv file
ShawnHymel 0:c407693ac016 143 timestamp = timer.read();
ShawnHymel 0:c407693ac016 144 voltage_in = ain * 3.3;
ShawnHymel 0:c407693ac016 145 current = (voltage_in * 1000) / (RS * RL);
ShawnHymel 0:c407693ac016 146 fprintf(file, "%2.2f,%1.3f\n", timestamp, current);
ShawnHymel 0:c407693ac016 147 #if DEBUG == 1
ShawnHymel 0:c407693ac016 148 printf("%2.2f, %1.3f\n\r", timestamp, current);
ShawnHymel 0:c407693ac016 149 #endif
ShawnHymel 0:c407693ac016 150
ShawnHymel 0:c407693ac016 151 // Toggle LED to show logging
ShawnHymel 0:c407693ac016 152 led_state ^= 1;
ShawnHymel 0:c407693ac016 153 status_led = led_state;
ShawnHymel 0:c407693ac016 154
ShawnHymel 0:c407693ac016 155 // Wait until next sample cycle as defined by sample delay
ShawnHymel 0:c407693ac016 156 while ( (timer.read() - timestamp) < DELAY_MS );
ShawnHymel 0:c407693ac016 157 }
ShawnHymel 0:c407693ac016 158
ShawnHymel 0:c407693ac016 159 // Close file
ShawnHymel 0:c407693ac016 160 #if DEBUG == 1
ShawnHymel 0:c407693ac016 161 printf("Done! Closing file");
ShawnHymel 0:c407693ac016 162 #endif
ShawnHymel 0:c407693ac016 163 fclose(file);
ShawnHymel 0:c407693ac016 164
ShawnHymel 0:c407693ac016 165 // Turn off LED to show done
ShawnHymel 0:c407693ac016 166 status_led = 0;
ShawnHymel 0:c407693ac016 167
ShawnHymel 0:c407693ac016 168 return 0;
ShawnHymel 0:c407693ac016 169 }