I'm going to try and keep this simple.
After upgrading from:
Arduino 1.8.8, TeensyDuino 1.4.5
to
Arduino 1.8.19, Teensyduino 1.56
My SD card code for reading data from files no longer works. It now crashes the T4.1. I have tested on T3.5 and it crashes now as well. This is code that previously worked on T3.5 before upgrading dev environment. It crashes after reading to the last line and then trying to close the file. If I read some of the fields but do not try and read to the last line, I can close the file without crashing.
Here is Code. Serial log with crash report below.
Log
After upgrading from:
Arduino 1.8.8, TeensyDuino 1.4.5
to
Arduino 1.8.19, Teensyduino 1.56
My SD card code for reading data from files no longer works. It now crashes the T4.1. I have tested on T3.5 and it crashes now as well. This is code that previously worked on T3.5 before upgrading dev environment. It crashes after reading to the last line and then trying to close the file. If I read some of the fields but do not try and read to the last line, I can close the file without crashing.
Here is Code. Serial log with crash report below.
Code:
#include <SD.h>
File sdDir;
int sdFileCount = 0;
int sdLastFileNum = 0;
float testData[2][162][2];
float testData_Zero = 0;
float testData_limitVal = 0;
String dataSaveFileDesc = "";
const int sdChipSelect = BUILTIN_SDCARD;
void setup(){
Serial.begin(38400); //USB
delay(10);
while (!Serial && millis() < 10000);
Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
if (CrashReport)
Serial.print(CrashReport);
if (!SD.begin(sdChipSelect)) {
Serial.println("SD init failed!");
}
else {
Serial.println("SD init passed.");
if (SD.exists("/DATA")) {
Serial.println("Directory Already Exists");
}
else {
if (SD.mkdir("/DATA")) { //Will create if doesnt exist
Serial.println("Directory Created");
}
else {
Serial.println("Directory Create Failed");
}
}
}
delay(1000);
Serial.println("Calling File Load");
SD_loadFileData(1,0);
}
void loop(){
Serial.println("Looping");
delay(2000);
}
void SD_loadFileData(int _fileNumToOpen, int _dataSet) {
//Reset Data Array
for (int i = 0; i < 162; i++) {
testData[_dataSet][i][0] = -1000; //Flag -1000 for unused DataPoints
}
testData_Zero = 0;
testData_limitVal = 0;
sdDir = SD.open("/DATA");
int _tempFileCount = 1;
Serial.println("Looking for File #: " + String(_fileNumToOpen));
while (true) {
File datafile = sdDir.openNextFile();
if (!datafile) {
// no more files
break;
}
if (!datafile.isDirectory()) {
Serial.println("Opening: " + String(datafile.name()));
if (_tempFileCount == _fileNumToOpen) {
Serial.println("File Match: " + String(datafile.name()));
size_t n; // Length of returned field with delimiter.
char str[24]; // Must hold longest field with delimiter and zero byte.
char *ptr; // Test for valid field.
char delim[3] = ",\n";
bool _readComplete = false;
// Read the file and store the data in testData Array
for (int j = 0; j < 3; j++) { //Skip first 3 Values.
n = skipField(&datafile, delim);
if (n == 0) {
dataSaveFileDesc = "Invalid File: E:3:" + String(j);
}
}
n = readField(&datafile, str, sizeof(str), delim); // Read Limit Value
if (n == 0) {
dataSaveFileDesc = "Invalid File: E:4";
}
else {
testData_limitVal = strtod(str, &ptr);
Serial.println("Limit Value: " + String(testData_limitVal));
if (ptr == str) {
dataSaveFileDesc = "Invalid File: E:4-1";
}
}
n = readField(&datafile, str, sizeof(str), delim); // Read Zero Value
if (n == 0) {
dataSaveFileDesc = "Invalid File: E:5";
}
else {
testData_Zero = strtol(str, &ptr, 10);
Serial.println("Zero: " + String(testData_Zero));
if (ptr == str) {
dataSaveFileDesc = "Invalid File: E:5-1";
}
}
//break; //Wont crash if I break here and Close file.
Serial.println(" - Reading Temp Data - ");
for (int j = 0; j < 90; j++) { //File has 80 (*2) Data point. Wont crash if I lower this below 80 and don't read to end of file.
if (_readComplete) { break; };
for (int i = 0; i < 2; i++) {
n = readField(&datafile, str, sizeof(str), delim);
if (n == 0) { //No Data
_readComplete = true;
Serial.println(" End of Data: Break");
break;
}
else { //Has Data
if (i == 0) {
testData[_dataSet][j][i] = strtod(str, &ptr);
if (ptr == str) {
_readComplete = true;
}
else {
if (testData[_dataSet][j][i] < -999) {
Serial.println(" Bad Data: Break");
break;
}
}
}
if (i == 1) {
testData[_dataSet][j][i] = strtol(str, &ptr,10);
if (ptr == str) {
_readComplete = true;
dataSaveFileDesc = "Invalid File: E:8-" + String(j);
}
}
}
} // for i
} //for j
}
}
Serial.println("Closing File");
datafile.close(); // <-----------------Crashes and resets here
Serial.println("File Closed");
_tempFileCount++;
if (_tempFileCount > _fileNumToOpen) {
Serial.println("File Count Exceeded; break"); break; } //Already past the Needed File#
}
Serial.println("Closing Dir");
sdDir.close();
}
size_t readField(File* file, char* str, size_t size, char* delim) {
char ch;
size_t n = 0;
while ((n + 1) < size && file->read(&ch, 1) == 1) {
// Delete CR.
if (ch == '\r') {
continue;
}
str[n++] = ch;
if (strchr(delim, ch)) {
break;
}
}
str[n-1] = '\0';
return n;
}
size_t skipField(File* file, char* delim) {
char ch;
size_t n = 0;
while ((n + 1) < 24 && file->read(&ch, 1) == 1) {
// Delete CR.
n++;
if (strchr(delim, ch)) {
break;
}
}
return n;
}
Log
Code:
CrashReport:
A problem occurred at (system time) 19:4:32
Code was executing from address 0xD2A
CFSR: 82
(DACCVIOL) Data Access Violation
(MMARVALID) Accessed Address: 0x4615222C
Temperature inside the chip was 37.84 °C
Startup CPU clock speed is 151MHz
Reboot was caused by auto reboot after fault or bad interrupt detected
SD init passed.
Directory Already Exists
Calling File Load
Looking for File #: 1
Opening: 0000001.csv
File Match: 0000001.csv
Limit Value: 21.00
Zero: 80.00
- Reading Temp Data -
End of Data: Break
Closing File