Forum: Mikrocontroller und Digitale Elektronik SD Modul und Beschleunigssensor gleichzeitig nutzen?


von Vwirt (Gast)


Lesenswert?

Hallo Leute,

ich habe mir einen Sketch gebastelt der soweit eigentlich ut 
funktioniert, nur habe ich leider ein kleines Problem dabei. Ich kann 
entweder den Beschleunigungssensor auslesen oder auf meine SD Karte 
schreiben, aber beides gleichzeitig will nicht funktionieren.
Ich benutze die Standard SD-Library von Arduino und eine Library von 
Adafruit für meinen ADXL345 Beschleunigungssensor. Das SD-Modul ist über 
SPI angebunden und der ADXL345 über I2C was mich noch mehr verzweifelt, 
da Sie sich ja da eigentlich garnicht in die Quere kommen dürften.
Ich hoffe jemand hat einen Tip für mich und kann mir helfen das Problem 
zu Lösen.
Es soll ein Datenlogger werden, der Die 
Uhrzeit/Datum/IR-Signal/Beschleunigungswerte einmal pro sekunde 
abspeichert. Gehört eigentlich zu meinem Positionsbestimmungs Thread 
aber ich dachte aufgrund des Problems bietet sich ein seperater Beitrag 
an. Hoffe das geht in Ordnung.


1
#include <SD.h>                   // SD
2
#include <Time.h>                 // Millis
3
#include <Wire.h>                 // I2C / TWI
4
#include <DS1307RTC.h>            // a basic DS1307 library that returns time as a time_t
5
#include <IRremote.h>             // IR
6
#include "I2Cdev.h"
7
#include "ADXL345.h"
8
9
/* ** MOSI - pin 11  SD
10
 ** MISO - pin 12    SD
11
 ** CLK - pin 13     SD
12
 ** CS - pin 10       SD
13
 
14
 ** SDA - pin A4     RTC
15
 ** SCL - pin A5     RTC
16
 
17
 */
18
 
19
///// IR-EMPFÄNGER /////
20
int RECV_PIN = 7;
21
IRrecv irrecv(RECV_PIN);
22
decode_results results;
23
24
25
///// SD /////
26
File myFile;
27
28
const int chipSelect = 10;
29
30
//// ADXL345 Beschleunigungssensor /////
31
ADXL345 accel;
32
33
int16_t ax, ay, az;
34
35
//// Sleep /////
36
37
/*////////////////////////////////////// Setup ////////////////////////////////////////////*/
38
39
void setup()  {
40
  Serial.begin(38400);
41
  
42
  //////// SD //////////
43
  if (!SD.begin(10)) {
44
    Serial.println("initialization failed!");
45
    return;
46
  }
47
  Serial.println("initialization done.");
48
    pinMode(10, OUTPUT);     // change this to 53 on a mega
49
  
50
  
51
  ///// RTC /////
52
  
53
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
54
55
  //////// IR /////////
56
57
  irrecv.enableIRIn(); // Start the receiver
58
  
59
  ///////// AXDXL ////////
60
 // initialize device
61
    Serial.println("Initializing I2C devices...");
62
    accel.initialize();
63
64
    // verify connection
65
    Serial.println("Testing device connections...");
66
    Serial.println(accel.testConnection() ? "ADXL345 connection successful" : "ADXL345 connection failed");
67
68
}
69
70
/*/////////////////////////////////////// Loop ///////////////////////////////////////////*/
71
72
void loop()
73
{
74
  
75
  delay(1000);
76
  String dataString = " ";
77
  //Sleepy::loseSomeTime(1000);
78
  ///// TIME /////  
79
  
80
  int Start = millis();
81
    
82
  dataString += hour();
83
  dataString += ":";
84
  dataString += minute();
85
  dataString += ":";
86
  dataString += second();
87
  dataString += "; Datum: ";
88
  dataString += day();
89
  dataString += ".";
90
  dataString += month();
91
  dataString += ".";
92
  dataString += year();  
93
  dataString += " ; IR-Code: ";
94
  //// IR RECEIVE /////
95
96
  if (irrecv.decode(&results)) {
97
    if (results.value < 2000){
98
      dataString += String(results.value, HEX);
99
      Serial.print("case1!");
100
      irrecv.resume(); // Receive the next value
101
    }
102
    else{
103
      dataString += "0";
104
      Serial.print("case2!");
105
      irrecv.resume();
106
    }
107
  }
108
  dataString += " ; ";
109
  
110
  ///// ADXL /////
111
  // read raw accel measurements from device
112
  /* accel.getAcceleration(&ax, &ay, &az);
113
114
    // display tab-separated accel x/y/z values
115
    Serial.print("accel:\t");
116
    Serial.print(ax); Serial.print("\t");
117
    Serial.print(ay); Serial.print("\t");
118
    Serial.println(az);
119
  int x = ax;
120
  int y = ay ; 
121
  int z = az ;
122
  
123
  dataString += " ; x:";
124
  dataString += x;
125
  dataString += " ; y:";
126
  dataString += y;
127
  dataString += "; z:";
128
  dataString += z;
129
  dataString += "; Status:"; */
130
  
131
  ///// SD CARD /////
132
   myFile = SD.open("test.txt", FILE_WRITE);
133
   
134
    if (myFile) {
135
    Serial.print("Writing to test.txt...");
136
    myFile.println(dataString);
137
  // close the file:
138
    myFile.close();
139
    Serial.println("done.");
140
   } else {
141
    // if the file didn't open, print an error:
142
    Serial.println("error opening test.txt");
143
  }
144
145
  ///// EXECUTION TIME /////
146
  int Stop = millis();
147
  Serial.print("Time needed: ");
148
  int Time = Stop - Start;
149
  Serial.print(Time);
150
  Serial.print("ms");
151
  Serial.println();
152
 
153
  Serial.print(dataString);
154
  Serial.println("OK");
155
  
156
  
157
}
158
159
/////// SETUP END //////////


Der Teil des Beschleunigungssensors ist derzeit auskommentiert. In dem 
Fall wird der Datenstring auf SD-Karte gespeichert, so wie es sein soll. 
Wenn ich allerdings das kommentieren aufhebe, gibt er mir immer die 
Meldung "error openingt test.txt" aus. Er kann also die Datei garnicht 
erst öffnen um in sie hinein zu schreiben.

Bin echt für jegliche Hilfe dankbar!

Gruß Vwirt

von Jürgen S. (jurs)


Lesenswert?

Vwirt schrieb:
> Das SD-Modul ist über SPI angebunden und der ADXL345 über
> I2C was mich noch mehr verzweifelt,
> da Sie sich ja da eigentlich garnicht in die Quere kommen dürften.

Welches "SD-Modul" verwendest Du?
Pegelwandlung auf 3.3 Volt?
Instabile Stromversorgung des Kartenmoduls?

von Vwirt (Gast)


Lesenswert?

Hab so ein typisches Breakoutboard von Ebay. Eine 3,3V Pegelwandlung ist 
da schon mit drauf. Hätte die möglichkeit das sd modul seperat mit strom 
zu versorgen, sollte ich das mal versuchen, könnte das tatsächlich eine 
Fehlerquelle sein?

von Jürgen S. (jurs)


Lesenswert?

Vwirt schrieb:
> Hab so ein typisches Breakoutboard von Ebay.

Welches? Link?

Bei eBay werden ganz unterschiedliche Artikel gehandelt. Und 
SD-Kartenmodule, die einen 5V-Spannungswandler drauf haben, müssen 
deshalb noch lange keinen 5V-Pegelwandler dabei haben.

Beispiel:
eBay 121277779755 ==> Spannungswandler JA, Pegelwandler NEIN

Andere Module haben Pegelwandler mit drauf, dann meistens aber für 
Micro-SD Karten statt für SD-Karten in Standardgröße.

Wenn ein Spannungswandler 5V->3.3V auf der Platine ist, reicht der 
Spannungswandler aus, wenn Du das SD-Kartenmodul mit 5V vom 
Arduino-Board aus versorgst.

Was allerdings in den meisten Fällen nicht ausreicht: Ein Modul ohne 
Pegelwandler direkt an die Arduino 5V-Datenleitungen dranzuhängen.

von Vwirt (Gast)


Lesenswert?

Genau so ein Modul wie du verlinkt hast benutze ich! Vielleicht sollte 
ich noch dazu sagen das ich einen Arduino Nano benutze (@5V)

von Vwirt (Gast)


Lesenswert?

Habe mal von einem Arduino Uno die 5V angezapft, an dem nichts anderes 
dranhängt und damit die Stromversorgung für das SD-Modul gestellt. Damit 
funktioniert es komischer weise gleichmal garnicht.

von max (Gast)


Lesenswert?

Du könntest mal den Versuch starten den Code ohne folgende Zeilen laufen 
zu lassen :

Vwirt schrieb:
>   int x = ax;
>   int y = ay ;
>   int z = az ;
>
>   dataString += " ; x:";
>   dataString += x;
>   dataString += " ; y:";
>   dataString += y;
>   dataString += "; z:";
>   dataString += z;
>   dataString += "; Status:"; */

Die Werte in einen neuen 16 Bit Integer zu kopieren sieht für einen 
nicht Arduino Nutzer sinnlos aus, ebenso die Zuweisung eines Integers an 
einen String.
Kann es sein das die maximale String Länge erreicht wurde ?

von Vwirt (Gast)


Lesenswert?

Danke Max,

zur zeit sind die Zeilen ja auch als Kommentar belassen, läuft also ohne 
diese Zeilen. Aber ich brauche ja die Beschleunigungsdaten. :(

Woran erkenne ich denn ob die maximale Stringlänge erreicht wurde? 
Fehlermeldungen beim kompilieren gibts nicht. :(
Würde sich ja überprüfen lassen indem ich die Beschleunigungswerte in 
einen neuen String schreibe und diesen dann mit auf SD Karte schreiben 
lasse, oder?

von Vwirt (Gast)


Lesenswert?

Achso und mit der zuweisung zum integer wollte ich erreichen das aus der 
float die mir der Sensor liefert eine Ganzzahl wird.
Int ist doch eigentlich bloß 2byte groß oder irre ich mich da?

von max (Gast)


Lesenswert?

Die Idee die dahinter steckt war zu prüfen ob der Beschleunigungssensor 
grundsätzlich zusammen mit der SD-Karte (und der RealTimeClock ? ) 
arbeitet.
Wenn das der Fall ist könnte man einen Hardwarefehler ausschließen.

Sollte heißen diese Zeilen :

Vwirt schrieb:
>  accel.getAcceleration(&ax, &ay, &az);
>
>  // display tab-separated accel x/y/z values
>  Serial.print("accel:\t");
>  Serial.print(ax); Serial.print("\t");
>  Serial.print(ay); Serial.print("\t");
>  Serial.println(az);

wider zu aktivieren und zu prüfen ob alles läuft.

von Vwirt (Gast)


Lesenswert?

Achso, sorry da hab ich dich wohl missverstanden. Werd ich gleich morgen 
vormittag mal testen, komme heute leider nicht mehr dazu.
(Ja ne RTC wird auch über I2C mit einbezogen)

von Jürgen S. (jurs)


Lesenswert?

Vwirt schrieb:
> Habe mal von einem Arduino Uno die 5V angezapft, an dem nichts anderes
> dranhängt und damit die Stromversorgung für das SD-Modul gestellt. Damit
> funktioniert es komischer weise gleichmal garnicht.

Minimalbeschaltung als Notbehelfs-Levelshifter für Dein Modul an einem 
5V Arduino-UNO wäre so etwas, die drei Leitungen CS, MOSI, und SCK am 
Mittelabgriff einer Widerstands-Spannungsteilerschaltung abgegriffen:

Nur die MISO-Leitung wird direkt mit Pin-12 verbunden.

Aufgemalt, ungetestet:
1
Arduino UNO
2
+---------+
3
|         |               _______     SD CS       ________
4
|         |- Pin-10 -----|_______|------+--------|________|----- GND
5
|         |                 1K                      2.2K             
6
|         |
7
|         |               _______     SD MOSI     ________
8
|         |- Pin-11 -----|_______|------+--------|________|----- GND
9
|         |                 1K                       2.2K
10
|         |
11
|         |                           SD MISO
12
|         |- Pin-12 --------------------+ 
13
|         |                           
14
|         |                           
15
|         |               _______     SD SCK      ________
16
|         |- Pin-13 -----|_______|------+--------|________|----- GND
17
+---------+                 1K                       2.2K

von Vwirt (Gast)


Lesenswert?

Ich habe auch noch sowas rumliegen von ebay 131196183140 ! Dann werd ich 
es morgen Vormittag mal damit probieren und mit dem Vorschlag von Max.

von Vwirt (Gast)


Lesenswert?

Also der Vorschlag von Max hat leider keine Änderung bewirkt, wenn ich 
die vorgeschlagenen Code-Zeilen wieder mit rein nehme, kann er wieder 
nicht auf die SD Karte zugreifen/schreiben. Bin grad noch am suchen nach 
dem Level Converter

von Vwirt (Gast)


Lesenswert?

Habs intereeshalber auch mal andersrum probiert und nur den Int x, y und 
z einfach werte vorgegeben, ohne das der ADXL ausgelesen wird. Dabei 
tritt das gleiche Problem auf!

Daher dachte ich, naja vielleicht ist der String ja zu lang, hab also 
diese Werte in einen neuen String "dataSring2" gesammelt. Und trotzdem 
wieder kein zugriff auf die SD-Karte. Und das obwohl der zweite String 
nichtmal mit auf die Karte geschrieben werden sollte. :(

Kann das irgendwie überhaupt nicht nachvollziehen wo es gerade klemmt. 
:(

(Levelconverter habe ich leider bislang nicht gefunden und da müssten 
auch noch die Stiftleisten angelötet werden, weil ich ihn bislang noch 
nicht benutzt habe. Deshalb wird es wohl nix vor heute abend es mit ihm 
auszuprobieren)

von Vwirt (Gast)


Lesenswert?

So gleich mal noch ein kleines Update hinterher. Ich habe mal alles ausm 
Code geworfen was nicht zur SD-Karte oder dem Beschleunigungssensor 
gehört.
(Außer die includes für die Libraries)
Da funktionieren beide zusammen. Dann hab ich die RTC wieder mit 
reingenommen und schon ging es wieder nicht mehr. Andererseits haben ja 
vorher die RTC und der BEschleunigungssensor zusammen funktioniert, nur 
eben dann die SD-Karte nicht mehr. :(

von Vwirt (Gast)


Lesenswert?

Sorry das es hier jetzt so häppchenweise kommt. Ich hab mal die RTC mit 
dringelassen und lass mir nur die Minute und Stunde per Serial.print 
ausgeben, aber ohne es auch noch in den Datenstring schreiben zu lassen. 
Da schreibt er fein auf die SD Karte (und liest den Sensor aus!)
Kann es vielleicht wirklich an der Strinlänge liegen oder am SRAM? 
Soweit reichen meine Kenntnisse leider nicht um das irgendwie zu prüfen. 
:(

von Vwirt (Gast)


Lesenswert?

JUHU! Es läuft! Hab diesen dummen dataString weggelassen und schreibe 
die werte einzeln auf die SD und das klappt 1A. Hab außerdem die 
Umwandlung der float werte in Int nochmal geändert ich glaube so sollte 
man das eignetlich machen oder?
Falls es jemanden interessiert oder selber mal Teile des Codes braucht 
poste ich ihn hier nochmal:
Danke an Jürgen und Max!
1
#include <SD.h>                   // SD
2
#include <Time.h>                 // Millis
3
#include <Wire.h>                 // I2C / TWI
4
#include <DS1307RTC.h>            // a basic DS1307 library that returns time as a time_t
5
#include <IRremote.h>             // IR
6
#include "I2Cdev.h"
7
#include "ADXL345.h"
8
9
/* ** MOSI - pin 11  SD
10
 ** MISO - pin 12    SD
11
 ** CLK - pin 13     SD
12
 ** CS - pin 10       SD
13
 
14
 ** SDA - pin A4     RTC
15
 ** SCL - pin A5     RTC
16
 
17
 */
18
19
///// IR-EMPFÄNGER /////
20
int RECV_PIN = 7;
21
IRrecv irrecv(RECV_PIN);
22
decode_results results;
23
24
///// SD /////
25
File myFile;
26
27
const int chipSelect = 10;
28
29
//// ADXL345 Beschleunigungssensor /////
30
ADXL345 accel;
31
32
int16_t ax, ay, az;
33
34
//// Sleep /////
35
36
/*////////////////////////////////////// Setup ////////////////////////////////////////////*/
37
38
void setup()  {
39
  Serial.begin(38400);
40
  
41
  //////// SD //////////
42
  if (!SD.begin(10)) {
43
    Serial.println("initialization failed!");
44
    return;
45
  }
46
  Serial.println("initialization done.");
47
    pinMode(10, OUTPUT);     // change this to 53 on a mega
48
49
   ///// RTC /////
50
  
51
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
52
53
  //////// IR /////////
54
55
  irrecv.enableIRIn(); // Start the receiver
56
57
  ///////// AXDXL ////////
58
   // initialize device
59
    Serial.println("Initializing I2C devices...");
60
    accel.initialize();
61
62
    // verify connection
63
    Serial.println("Testing device connections...");
64
    Serial.println(accel.testConnection() ? "ADXL345 connection successful" : "ADXL345 connection failed");
65
66
}
67
68
/*/////////////////////////////////////// Loop ///////////////////////////////////////////*/
69
70
void loop()
71
{
72
  
73
  delay(1000);
74
  String dataString = " ";
75
  String ir = 0;
76
  int x = 0;
77
  int y = 0;
78
  int z = 0;
79
  
80
  //Sleepy::loseSomeTime(1000);
81
  
82
  ///// TIME /////  
83
    
84
  //// IR RECEIVE /////
85
86
  if (irrecv.decode(&results)) {
87
    if (results.value < 2000){
88
      ir = String(results.value, HEX);
89
      irrecv.resume(); // Receive the next value
90
    }
91
    else{
92
      ir = "0";
93
      irrecv.resume();
94
    }
95
  }
96
  else{
97
    ir = "0";
98
  }
99
  
100
  ///// ADXL /////
101
  // read raw accel measurements from device
102
   accel.getAcceleration(&ax, &ay, &az);
103
104
    // display tab-separated accel x/y/z values
105
    
106
    x = (int)ax ;
107
    y = (int)ay ; 
108
    z = (int)az ;
109
  
110
  
111
  ///// SD CARD /////
112
  
113
   myFile = SD.open("test.txt", FILE_WRITE);
114
   
115
    if (myFile) {
116
    Serial.print("Writing to test.txt...");
117
    myFile.print("TIME: ");
118
    myFile.print(hour());
119
    myFile.print(":");
120
    myFile.print(minute());
121
    myFile.print(":");
122
    myFile.print(second());
123
    myFile.print(" // Date:");
124
    myFile.print(day());
125
    myFile.print(".");
126
    myFile.print(month());
127
    myFile.print(".");
128
    myFile.print(year());
129
    myFile.print(" // IR:");
130
    myFile.print(ir);
131
    myFile.print(" // ADXL: ");
132
    myFile.print(x);
133
    myFile.print(":");
134
    myFile.print(y);
135
    myFile.print(":");
136
    myFile.print(z);
137
    myFile.println(" // DATA OK!");
138
    
139
  // close the file:
140
    myFile.close();
141
    Serial.print("SD done! ");
142
   } else {
143
    // if the file didn't open, print an error:
144
    Serial.println("error opening test.txt");
145
  }
146
  Serial.println("Data OK");
147
  
148
  
149
}
150
151
/////// LOOP END //////////

von max (Gast)


Lesenswert?

Denke nicht das es eine gute Lösung ist.
http://de.wikipedia.org/wiki/SD-Karte#Maximale_Anzahl_der_Schreibvorg.C3.A4nge

Eine SD- Karte kann nicht beliebig oft beschrieben werden, in diesem 
Fall wären es 21 Schreibzugriffe pro Sekunde. Vorausgesetzt die Arduino 
SD Bibiliothek schreibt bei jedem myFile.print() physikalisch auf den 
Speicher und nicht erst beim aufrufen von myFile.close().
Das sollte vorher geklärt werden, bestimmt gibt es in einem Arduino 
Forum Hilfe dazu.

Es macht also durchaus Sinn einen großen String einmal auf die Karte zu 
schreiben.
Da der Verursacher des Problems anscheinend der dataString ist, wäre 
dieser kleine Test möglich :
1
String dataString;
2
3
dataString = String(year(),DEC);
4
Serial.println(dataString);
5
6
dataString = year();
7
Serial.println(datastring);
http://arduino.cc/en/Tutorial/StringConstructors

Es wäre Interessant was dort ausgegeben wird.

von Vwirt (Gast)


Lesenswert?

Mit den Schreibzyklen haste natürlich recht, aber zu einem kompletten 
String lies es sich ja leider nicht zusammenfassen. :(

von Jürgen S. (jurs)


Lesenswert?

Vwirt schrieb:
> Mit den Schreibzyklen haste natürlich recht, aber zu einem kompletten
> String lies es sich ja leider nicht zusammenfassen. :(

Nein, nicht jede print-Anweisung bei offener Datei führt zu einem 
Schreibvorgang. Schreibvorgänge werden immer in einem 512-Byte großen 
Sektorpuffer zwischengepuffert und tatsächliche Schreibvorgänge auf der 
SD-Karte treten auf:

- wenn Du über die 512 Byte Puffergrenze schreibst
- wenn Du die Datei nach dem Schreiben schließt

Das kritische in Sachen "SD-Karte kaputtschreiben" ist dabei nicht das 
ständige dranhängen von Daten an eine Datei, so dass diese beim 
Schreiben größer und größer wird. Das ist harmlos, weil dabei ja stets 
jeder Sektor nur einmal mit Daten beschrieben wird. Erst wenn die Datei 
gelöscht wurde, würde dann beim Schreiben einer neuen Datei der Bereich 
neu beschrieben werden.

Das kritische ist die FAT (File Allocation Table), bei der nach jedem 
Schließen der Datei die dann neue Dateigröße reingeschrieben wird. Der 
FAT-Eintrag der Datei bleibt stets an derselben Stelle und wenn Du nach 
dem Schreiben die Datei schließt, wird jedesmal an Ort und Stelle die 
aktuelle Dateigröße reingeschrieben. D.h. bei jedem "myFile.close();" 
wird an derselben Stelle der SD-Karte in die FAT geschrieben.

Machst Du das 86400 mal pro Tag, dann ist der FAT-Sektor nach wenigen 
Tagen kaputtgeschrieben und der Kartencontroller muss "Ersatzsektoren" 
auf der Karte aktivieren. Das macht er von ganz alleine im Hintergrund. 
Allerdings ist die Anzahl der "Ersatzsektoren" auf einer SD-Karte 
begrenzt, so dass Du nur eine begrenzte Anzahl Sektoren kaputtschreiben 
darfst, ohne dass die Karte komplett unbrauchbar wird.

Mögliche Abhilfe: Weniger häufig auf dieselben Sektoren schreiben. Bei 
einem Datenlogger zum Beispiel weniger oft "myFile.close();" verwenden.

Beispiel: Wenn Du bei einem 1-Sekunden-Logging die Datei nur einmal pro 
Minute öffnen und einmal pro Minute schließen würdest, könnte der Logger 
sechzig mal so lange laufen, bis der FAT-Sektor kaputtgeschrieben ist 
und intern gegen einen Ersatzsektor ausgetauscht werden muss.

Nachteil dabei ist allerdings: Wenn Du den Datenlogger abschaltest, 
während die Datei geöffnet ist, ist im Fat-Eintrag die falsche (zu 
kleine) Dateigröße vermerkt und Dir gehen diejenigen Logzeilen verloren, 
die seit dem letzten "myFile.close();" geschrieben wurden.

von Vwirt (Gast)


Lesenswert?

Danke für die ausführlichen Hinweise Jürgen. Hab das auch soweit 
verstanden denke ich. Aber würde das nicht bedeuten ich müsste die 
Datensätze einer ganzen Minute (also 60) zwischenspeichern um sie dann 
mit einem mal auf die SD zu schreiben?

Oder würde das auch über eine Zählschleife funktionieren? z.B. so :

-jede Sekunde wie bisher Daten speichern

 aber das "myFile.close();" durch folgende Schleife ersetzen:
1
if (int i = 0; i == 60){
2
  myFile.close();
3
  i = 0;
4
}
5
else{
6
i++;
7
}

von Vwirt (Gast)


Lesenswert?

Aber vielleicht gleich mal noch eine andere Frage. Wenn ich die (zurzeit 
auskommentierte Sleepfunktion (1 Sekunde) benutze, gibt er mir 
komischerweise mehrere Datensätze mit der selben Uhrzeit aus bis er zur 
nächsten Sekunde kommt und dann wieder mehrmals diese Uhrzeit ausspuckt. 
Ich kapier bloß nicht warum, da ja eigentlich die Funktion den 
Controller in den PowerDown versetzt und somit nur durch einen externen 
Interrupt oder eben den WDT gewckt werden dürfte. Mir scheint es aber 
so, als ob er mehrfach geweckt wird, wüßte bloß nicht durch was. HAt 
jemand vielleicht dazu auch noch eine Idee?
mit dem Delay funktioniert es ja nun alles, wie es soll. Aber da es sich 
um einen akkubetriebenen Datenlogger handeln soll, währe ein 
funktionerende Sleepfunktion natürlich um welten besser! :(

gruß Vwirt

von Jürgen S. (jurs)


Lesenswert?

Vwirt schrieb:
> Danke für die ausführlichen Hinweise Jürgen. Hab das auch soweit
> verstanden denke ich. Aber würde das nicht bedeuten ich müsste die
> Datensätze einer ganzen Minute (also 60) zwischenspeichern um sie dann
> mit einem mal auf die SD zu schreiben?

Nein, es muss nichts zwischengespeichert werden.

Du müßtest die Datei eben nur nicht nach jeder Datenzeile schließen, 
sondern nur dann, wenn seit dem letzten Schließen der Datei mindestens 
60 Sekunden vergangen sind.
>
> Oder würde das auch über eine Zählschleife funktionieren? z.B. so :

Ich würde die Zählschleife basierend auf dem Stand des 
Millisekundenzählers realisieren. Und selbstverständlich muß die Datei 
auch nach dem Schließen gleich wieder zum Schreiben geöffnet werden.

Ich würde einfach Deine bisherige Logik zum Öffnen der Datei
1
myFile = SD.open("test.txt", FILE_WRITE);
durch diesen Code ersetzen:
1
  static unsigned long lastOpened=0; // statisch, nur einmalig initialisiert!
2
  if (myFile && millis()-lastOpened>60000L) myFile.close();
3
  if (!myFile)
4
  {
5
    myFile = SD.open("test.txt", FILE_WRITE);
6
    lastOpened=millis();
7
  }

Dadurch wird eine länger als 60 Sekunden geöffnete Datei zuerst mal 
geschlossen, und danach wird die Datei geöffnet, falls sie nicht 
geschlossen ist.

Der bisherige close-Befehl nach dem Ausgeben der Daten muss dann 
gelöscht werden, sonst wird die Datei weiterhin nach jedem Schreiben 
geschlossen.

: Bearbeitet durch User
von Vwirt (Gast)


Lesenswert?

Super! Danke!
Habs durch deine Zeilen ersetzt und funktioniert wie gedacht!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.