You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

readCSV.ino 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // Functions to read a CSV text file one field at a time.
  2. //
  3. #include <limits.h>
  4. #include <SPI.h>
  5. // next line for SD.h
  6. //#include <SD.h>
  7. // next two lines for SdFat
  8. #include <SdFat.h>
  9. SdFat SD;
  10. #define CS_PIN SS
  11. // example can use comma or semicolon
  12. #define CSV_DELIM ','
  13. File file;
  14. /*
  15. * Read a file one field at a time.
  16. *
  17. * file - File to read.
  18. *
  19. * str - Character array for the field.
  20. *
  21. * size - Size of str array.
  22. *
  23. * delim - csv delimiter.
  24. *
  25. * return - negative value for failure.
  26. * delimiter, '\n' or zero(EOF) for success.
  27. */
  28. int csvReadText(File* file, char* str, size_t size, char delim) {
  29. char ch;
  30. int rtn;
  31. size_t n = 0;
  32. while (true) {
  33. // check for EOF
  34. if (!file->available()) {
  35. rtn = 0;
  36. break;
  37. }
  38. if (file->read(&ch, 1) != 1) {
  39. // read error
  40. rtn = -1;
  41. break;
  42. }
  43. // Delete CR.
  44. if (ch == '\r') {
  45. continue;
  46. }
  47. if (ch == delim || ch == '\n') {
  48. rtn = ch;
  49. break;
  50. }
  51. if ((n+1) >= size) {
  52. // string too long
  53. rtn = -2;
  54. n--;
  55. break;
  56. }
  57. str[n++] = ch;
  58. }
  59. str[n] = '\0';
  60. return rtn;
  61. }
  62. //------------------------------------------------------------------------------
  63. int csvReadInt32(File* file, int32_t* num, char delim) {
  64. char buf[20];
  65. char* ptr;
  66. int rtn = csvReadText(file, buf, sizeof(buf), delim);
  67. if (rtn < 0) return rtn;
  68. *num = strtol(buf, &ptr, 10);
  69. if (buf == ptr) return -3;
  70. while(isspace(*ptr)) ptr++;
  71. return *ptr == 0 ? rtn : -4;
  72. }
  73. //------------------------------------------------------------------------------
  74. int csvReadInt16(File* file, int16_t* num, char delim) {
  75. int32_t tmp;
  76. int rtn = csvReadInt32(file, &tmp, delim);
  77. if (rtn < 0) return rtn;
  78. if (tmp < INT_MIN || tmp > INT_MAX) return -5;
  79. *num = tmp;
  80. return rtn;
  81. }
  82. //------------------------------------------------------------------------------
  83. int csvReadUint32(File* file, uint32_t* num, char delim) {
  84. char buf[20];
  85. char* ptr;
  86. int rtn = csvReadText(file, buf, sizeof(buf), delim);
  87. if (rtn < 0) return rtn;
  88. *num = strtoul(buf, &ptr, 10);
  89. if (buf == ptr) return -3;
  90. while(isspace(*ptr)) ptr++;
  91. return *ptr == 0 ? rtn : -4;
  92. }
  93. //------------------------------------------------------------------------------
  94. int csvReadUint16(File* file, uint16_t* num, char delim) {
  95. uint32_t tmp;
  96. int rtn = csvReadUint32(file, &tmp, delim);
  97. if (rtn < 0) return rtn;
  98. if (tmp > UINT_MAX) return -5;
  99. *num = tmp;
  100. return rtn;
  101. }
  102. //------------------------------------------------------------------------------
  103. int csvReadDouble(File* file, double* num, char delim) {
  104. char buf[20];
  105. char* ptr;
  106. int rtn = csvReadText(file, buf, sizeof(buf), delim);
  107. if (rtn < 0) return rtn;
  108. *num = strtod(buf, &ptr);
  109. if (buf == ptr) return -3;
  110. while(isspace(*ptr)) ptr++;
  111. return *ptr == 0 ? rtn : -4;
  112. }
  113. //------------------------------------------------------------------------------
  114. int csvReadFloat(File* file, float* num, char delim) {
  115. double tmp;
  116. int rtn = csvReadDouble(file, &tmp, delim);
  117. if (rtn < 0)return rtn;
  118. // could test for too large.
  119. *num = tmp;
  120. return rtn;
  121. }
  122. //------------------------------------------------------------------------------
  123. void setup() {
  124. Serial.begin(9600);
  125. // Wait for USB Serial
  126. while (!Serial) {
  127. yield();
  128. }
  129. Serial.println("Type any character to start");
  130. while (!Serial.available()) {
  131. yield();
  132. }
  133. // Initialize the SD.
  134. if (!SD.begin(CS_PIN)) {
  135. Serial.println("begin failed");
  136. return;
  137. }
  138. // Remove existing file.
  139. SD.remove("READTEST.TXT");
  140. // Create the file.
  141. file = SD.open("READTEST.TXT", FILE_WRITE);
  142. if (!file) {
  143. Serial.println("open failed");
  144. return;
  145. }
  146. // Write test data.
  147. file.print(F(
  148. #if CSV_DELIM == ','
  149. "36,23.20,20.70,57.60,79.50,01:08:14,23.06.16\r\n"
  150. "37,23.21,20.71,57.61,79.51,02:08:14,23.07.16\r\n"
  151. #elif CSV_DELIM == ';'
  152. "36;23.20;20.70;57.60;79.50;01:08:14;23.06.16\r\n"
  153. "37;23.21;20.71;57.61;79.51;02:08:14;23.07.16\r\n"
  154. #else
  155. #error "Bad CSV_DELIM"
  156. #endif
  157. ));
  158. // Rewind the file for read.
  159. file.seek(0);
  160. // Read the file and print fields.
  161. int16_t tcalc;
  162. float t1, t2, h1, h2;
  163. // Must be dim 9 to allow for zero byte.
  164. char timeS[9], dateS[9];
  165. while (file.available()) {
  166. if (csvReadInt16(&file, &tcalc, CSV_DELIM) != CSV_DELIM
  167. || csvReadFloat(&file, &t1, CSV_DELIM) != CSV_DELIM
  168. || csvReadFloat(&file, &t2, CSV_DELIM) != CSV_DELIM
  169. || csvReadFloat(&file, &h1, CSV_DELIM) != CSV_DELIM
  170. || csvReadFloat(&file, &h2, CSV_DELIM) != CSV_DELIM
  171. || csvReadText(&file, timeS, sizeof(timeS), CSV_DELIM) != CSV_DELIM
  172. || csvReadText(&file, dateS, sizeof(dateS), CSV_DELIM) != '\n') {
  173. Serial.println("read error");
  174. int ch;
  175. int nr = 0;
  176. // print part of file after error.
  177. while ((ch = file.read()) > 0 && nr++ < 100) {
  178. Serial.write(ch);
  179. }
  180. break;
  181. }
  182. Serial.print(tcalc);
  183. Serial.print(CSV_DELIM);
  184. Serial.print(t1);
  185. Serial.print(CSV_DELIM);
  186. Serial.print(t2);
  187. Serial.print(CSV_DELIM);
  188. Serial.print(h1);
  189. Serial.print(CSV_DELIM);
  190. Serial.print(h2);
  191. Serial.print(CSV_DELIM);
  192. Serial.print(timeS);
  193. Serial.print(CSV_DELIM);
  194. Serial.println(dateS);
  195. }
  196. file.close();
  197. }
  198. //------------------------------------------------------------------------------
  199. void loop() {
  200. }