I am currently trying to add in functionality of reading external calculated values from a CSV file and storing them into variables in my sketch. Before integrated it into the larger project I wanted to try and get the basics of the examples from the SDfat library first. I have made a few modifications to the example such as trying to read the file with my data rather than writing the example data etc. What happens is I get the serial output to print the first columns header and then it throws a failure to parse error and Im not 100% sure why. I hope its something simple like the way my csv file is formatted. I have tried a few other of the examples with similar success where it will print only some of the information and then stop. I have tried to trim my "flowmeter" headers and information down to a more manageable number with no success as well as trying to read from a csv formatted .txt file. I have attached the csv file that it reads from and the slightly modified SDfat example. My hunch is it has something to do with the file formatting or it is too many columns. I am using a nano every if it matters.
#include "SdFat.h"
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
#define SD_FAT_TYPE 3
/*
Change the value of SD_CS_PIN if you are using SPI and
your hardware does not use the default value, SS.
Common values are:
Arduino Ethernet shield: pin 4
Sparkfun SD shield: pin 8
Adafruit SD shields and modules: pin 10
*/
// SDCARD_SS_PIN is defined for the built-in SD on some boards.
#ifndef SDCARD_SS_PIN
const uint8_t SD_CS_PIN = SS;
#else // SDCARD_SS_PIN
// Assume built-in SD is used.
const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
#endif // SDCARD_SS_PIN
// Try max SPI clock for an SD. Reduce SPI_CLOCK if errors occur.
#define SPI_CLOCK SD_SCK_MHZ(50)
// Try to select the best SD card configuration.
#if HAS_SDIO_CLASS
#define SD_CONFIG SdioConfig(FIFO_SDIO)
#elif ENABLE_DEDICATED_SPI
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
#else // HAS_SDIO_CLASS
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
#endif // HAS_SDIO_CLASS
#if SD_FAT_TYPE == 0
SdFat sd;
File file;
#elif SD_FAT_TYPE == 1
SdFat32 sd;
File32 file;
#elif SD_FAT_TYPE == 2
SdExFat sd;
ExFile file;
#elif SD_FAT_TYPE == 3
SdFs sd;
FsFile file;
#else // SD_FAT_TYPE
#error Invalid SD_FAT_TYPE
#endif // SD_FAT_TYPE
char line[280];
//------------------------------------------------------------------------------
// Store error strings in flash to save RAM.
#define error(s) sd.errorHalt(&Serial, F(s))
//------------------------------------------------------------------------------
// Check for extra characters in field or find minus sign.
char* skipSpace(char* str) {
while (isspace(*str)) str++;
return str;
}
//------------------------------------------------------------------------------
bool parseLine(char* str) {
char* ptr;
// Set strtok start of line.
str = strtok(str, ",");
if (!str) return false;
// Print text field.
Serial.println(str);
// Subsequent calls to strtok expects a null pointer.
str = strtok(nullptr, ",");
if (!str) return false;
// Convert string to long integer.
int32_t i32 = strtol(str, &ptr, 0);
if (str == ptr || *skipSpace(ptr)) return false;
Serial.println(i32);
str = strtok(nullptr, ",");
if (!str) return false;
// strtoul accepts a leading minus with unexpected results.
if (*skipSpace(str) == '-') return false;
// Convert string to unsigned long integer.
uint32_t u32 = strtoul(str, &ptr, 0);
if (str == ptr || *skipSpace(ptr)) return false;
Serial.println(u32);
str = strtok(nullptr, ",");
if (!str) return false;
// Convert string to double.
double d = strtod(str, &ptr);
if (str == ptr || *skipSpace(ptr)) return false;
Serial.println(d);
// Check for extra fields.
return strtok(nullptr, ",") == nullptr;
}
//------------------------------------------------------------------------------
void setup() {
Serial.begin(9600);
// Wait for USB Serial
while (!Serial) {
yield();
}
Serial.println("Type any character to start");
while (!Serial.available()) {
yield();
}
// Initialize the SD.
if (!sd.begin(SD_CONFIG)) {
sd.initErrorHalt(&Serial);
return;
}
// Create the file.
if (!file.open("calibrations.csv", FILE_READ)) {
error("open failed");
}
while (file.available()) {
int n = file.fgets(line, sizeof(line));
if (n <= 0) {
error("fgets failed");
}
if (line[n - 1] != '\n' && n == (sizeof(line) - 1)) {
error("line too long");
}
if (!parseLine(line)) {
error("parseLine failed");
}
Serial.println();
}
file.close();
Serial.println(F("Done"));
}
void loop() {}`Use code tags to format code for the forum`
Flowmeter1,Flowmeter2,Flowmeter3,Flowmeter4,Flowmeter5,Flowmeter6,Flowmeter7,Flowmeter8,Flowmeter9,Flowmeter10,Flowmeter11,Flowmeter12,Flowmeter13,Flowmeter14,Flowmeter15,Flowmeter16,Flowmeter17,Flowmeter18,Flowmeter19,Flowmeter20,Flowmeter21,Flowmeter22
0.112,0.095,0.089,0.128,0.104,0.109,0.101,0.217,0.105,0.111,0.1,0.106,0.114,0.118,0.119,0.104,0.114,0.12,0.118,0.117,0.111,0.127
