Offline
Newbie
Karma: 0
Posts: 19
|
 |
« on: May 23, 2012, 12:45:45 pm » |
###SOLVED### Failed by design. To many open files ###/SOLVED### I've wrote a measured value every 0.025 seconds to an sd card. that works fine so far. but after ~250 times (+/-25) it fails. In SerialMonitor it fails e.g. after 266 writings, but the file has just written 237 times. Any idea why that happened? SerialMonitor Output: http://paste.osuv.de/index.php/okQs/TXT Output: http://paste.osuv.de/index.php/EtWt/And this is my code: /* Voltage-Logger SD Card Pins ** MOSI - pin 11 ** MISO - pin 12 ** CLK - pin 13 ** CS - pin 10 Voltage-Input analogInput = 1 */ #include <SD.h>
File myFile; int analogInput = 1; int refresh = 200; float vout = 0.0; float vin = 0.0; float R1 = 46300.0; // !! resistance of R1 !! float R2 = 4630.0; // !! resistance of R2 !! int value = 0; long startTime; // to keep track of when the last action was int duration = 100; // 0,1 sekunden void setup(){
// declaration of pin modes pinMode(analogInput, INPUT); // begin sending over serial port Serial.begin(9600); Serial.print("Initializing SD card..."); pinMode(10, OUTPUT); if (!SD.begin(10)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done.");
}
void loop() { char ch = '0'; //alles nur nicht 1, damit der loop nicht direkt am anfang ohne eingabe startet while (1) //while(true) = endlosschleife { if (Serial.available() >0) //wenn Serial Eingabe groesser als 0 ist { ch = Serial.read(); //lies am seriel inputt if (ch == '0') //wenn input == null ist halt(); //anhalten } if (ch == '1') // wenn input == 1 ist startlogging(); //start logging } }
void startlogging() { startTime = millis(); value = analogRead(analogInput); vout = (value * 5.0) / 1024.0; vin = vout / (R2/(R1+R2)); // if (millis() >= startTime + duration) // delay
// { myFile = SD.open("logging2.txt", FILE_WRITE); // if the file opened okay, write to it: if (myFile) { myFile.print(startTime, 4); myFile.print(", "); myFile.print(vout); myFile.println(); // close the file: myFile.close(); Serial.println("done."); } else { // if the file didn't open, print an error: Serial.println("error opening test.txt"); } delay(25); } //}
void halt() { myFile.close(); }
|
|
|
|
« Last Edit: May 23, 2012, 02:54:16 pm by markuman »
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #1 on: May 23, 2012, 12:52:32 pm » |
The loop() function is called in an endless loop. What purpose does it serve to create an infinite loop inside an infinite loop? myFile.print(startTime, 4); You want to print the time in base 4? Why? Seems a strange base to me... Perhaps the thing you need to do is open the file once, then close it in the halt() function, rather than opening and closing the file every 25 milliseconds.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 19
|
 |
« Reply #2 on: May 23, 2012, 01:20:53 pm » |
The loop() function is called in an endless loop. What purpose does it serve to create an infinite loop inside an infinite loop?
Yay, because if (Serial.available()) //wenn daten am usb port ankommen { ch=Serial.read(); if(ch == 0) { halt(); } else { startlogging(); } } }
just starts startlogging() just one time. myFile.print(startTime, 4); You want to print the time in base 4? Why? Seems a strange base to me... This was just a bit playground. I just need a straight forward timeline Perhaps the thing you need to do is open the file once, then close it in the halt() function, rather than opening and closing the file every 25 milliseconds.
This fails now after ~40 writings.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 19
|
 |
« Reply #3 on: May 23, 2012, 01:24:40 pm » |
if (Serial.available()) //wenn daten am usb port ankommen { ch=Serial.read(); if(ch == 0) { halt(); } else { startlogging(); } } }
Even if i use this code instead of the while loop, it fails writing after 23 times. http://paste.osuv.de/index.php/0lM0//* Voltage-Logger SD Card Pins ** MOSI - pin 11 ** MISO - pin 12 ** CLK - pin 13 ** CS - pin 10 Voltage-Input analogInput = 1 */ #include <SD.h>
File myFile; int analogInput = 1; int refresh = 200; float vout = 0.0; float vin = 0.0; float R1 = 46300.0; // !! resistance of R1 !! float R2 = 4630.0; // !! resistance of R2 !! int value = 0; long startTime; // to keep track of when the last action was int duration = 100; // 0,1 sekunden char ch = '0'; //alles nur nicht 1, damit der loop nicht direkt am anfang ohne eingabe startet void setup(){
// declaration of pin modes pinMode(analogInput, INPUT); // begin sending over serial port Serial.begin(9600); Serial.print("Initializing SD card..."); pinMode(10, OUTPUT); if (!SD.begin(10)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done.");
}
void loop() {
if (Serial.available()) //wenn daten am usb port ankommen { ch=Serial.read(); if(ch == 0) { halt(); } else { startlogging(); } } }
// while (1) //while(true) = endlosschleife // { // if (Serial.available() >0) //wenn Serial Eingabe groesser als 0 ist // { // ch = Serial.read(); //lies am seriel inputt // if (ch == '0') //wenn input == null ist // halt(); //anhalten // } // if (ch == '1') // wenn input == 1 ist // startlogging(); //start logging //} //}
void startlogging() { startTime = millis(); value = analogRead(analogInput); vout = (value * 5.0) / 1024.0; vin = vout / (R2/(R1+R2)); // if (millis() >= startTime + duration) // delay
// { myFile = SD.open("logging3.txt", FILE_WRITE); // if the file opened okay, write to it: if (myFile) { myFile.print(startTime); myFile.print(", "); myFile.print(vout); myFile.println(); // close the file: //myFile.close(); Serial.println("done."); } else { // if the file didn't open, print an error: Serial.println("error opening test.txt"); } delay(25); } //}
void halt() { Serial.println("Nothing to do here..."); myFile.close(); }
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #4 on: May 23, 2012, 01:36:28 pm » |
just starts startlogging() just one time. It wouldn't if ch was declared static and set at the appropriate time/place (only when there was serial data). This fails now after ~40 writings. Please describe how you detect a failure.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 19
|
 |
« Reply #5 on: May 23, 2012, 01:47:55 pm » |
This fails now after ~40 writings. Please describe how you detect a failure. if (myFile) { myFile.print(startTime); myFile.print(", "); myFile.print(vout); myFile.println(); // close the file: //myFile.close(); Serial.println("done."); } else { // if the file didn't open, print an error: Serial.println("error opening test.txt"); }
i get "done" feedback in serial monitor for every print/write until it failed. i'm guessing the library gets in trouble when to many files are opened !? so i have to open the file one time in void.setup when start logging and close it in void.setup when stop logging. (not try yet, will do it soon) but that would not explain why it fails in my first code version, where the file was opened and closed in every measure step.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #6 on: May 23, 2012, 01:52:27 pm » |
i'm guessing the library gets in trouble when to many files are opened !? Yes. Why is the close commented out? so i have to open the file one time in void.setup when start logging and close it in void.setup when stop logging. (not try yet, will do it soon) You could do it that way. I wouldn't. I'd open the file when the request came to start logging. I'd close it when the request came to stop logging. but that would not explain why it fails in my first code version, where the file was opened and closed in every measure step. No, but opening and closing the file requires searching for the end of the file every time, and is to be avoided if you want to log quickly.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 19
|
 |
« Reply #7 on: May 23, 2012, 02:08:08 pm » |
so i have to open the file one time in void.setup when start logging and close it in void.setup when stop logging. (not try yet, will do it soon) You could do it that way. I wouldn't. I'd open the file when the request came to start logging. I'd close it when the request came to stop logging. yay, i was wrong with my explanation (bad english skills and interchanged void.setup and void.loop). i've meant just opening one time for logging and closing when stopping. however, like that way it seems to work now. but now i can't stop it anymore with 0 input on serial monitor. the code looks now like this http://paste.osuv.de/index.php/tIyOO/but there is a lot of unused waste in it now.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #8 on: May 23, 2012, 02:13:38 pm » |
if(ch == 0) How are you sending data to the Arduino? Sending a binary 0 seems like a strange thing to do. startlogging() is incorrectly named, since it does not start the logging. The else clause is misplaced, now, since the file is not created in startlogging().
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 19
|
 |
« Reply #9 on: May 23, 2012, 02:33:30 pm » |
if(ch == 0) How are you sending data to the Arduino? Sending a binary 0 seems like a strange thing to do. With ch=Serial.read(); and now with char ch = '0'; don't? startlogging() is incorrectly named, since it does not start the logging.
O_o but it starts. that works fine. stopping don't work. The else clause is misplaced, now, since the file is not created in startlogging().
i've created the file when checking for ch (serial.read). and startlogging will just execute when ch get's something else, but not 0. and if ch is not 0, i've opened the file.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #10 on: May 23, 2012, 02:45:14 pm » |
With ch=Serial.read(); and now with char ch = '0'; don't? I'm not sure how, or if, this answers my question. I'd do something like this: if (Serial.available()) //wenn daten am usb port ankommen { ch=Serial.read(); if(ch == 'S') { myFile = SD.open("logging3.txt", FILE_WRITE); } else if(ch == 'Q') { halt(); } }
if(ch == 'S') { startlogging(); }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 19
|
 |
« Reply #11 on: May 23, 2012, 02:52:11 pm » |
I'd do something like this:
Ah okey, this works fine. Thank you!
|
|
|
|
|
Logged
|
|
|
|
|
|