Datenerfassung mit SD-Karte

Hallo zusammen, ich mache gerade meine Technikerarbeit. Dazu habe ich mich entschieden mit dem Arduino MEGA 2560 zu arbeiten. Dazu kommt noch ein SD- Speicherkartenmodul. Es sollen Daten aufgenommen werden, diese über Display anzeigen und auf eine SD-Karte im FAT32 Sytem speichern.

Ich baue eine Prüfbox die Signalwechsel zweier OSSD- Ausgänge auswertet (OSSD-A;OSSD-B). Die Signalwechsel sollen mit ihrer zeitlichen Auflösung (1ms oder 10ms) erfasst werden. Diese Werte sollen dann auf 2 Displays angezeigt werden, je für OSSD-A und OSSD-B.

Anzeige OSSD-A: minimale / maximale / mittlere Zeitdauer → Ein Zustand minimale / maximale / mittlere Zeitdauer → Aus Zustand Signalwechsel Anzeige OSSD-B: minimale / maximale / mittlere Zeitdauer → Ein Zustand minimale / maximale / mittlere Zeitdauer → Aus Zustand Signalwechsel

Ein Ablauf soll mind. 50.000 Signalwechsel umfassen können ( 2OSSD's , 1 Hz Schaltfrequenz → 4 Signalwechsel p.Sec → 14.400 Signalwechsel p.Std)

Ich habe das ganze mal ausgerechnet und benötige für einen Eintrag 4 Byte. Also für einen gesamten Ablauf mind. 200kB.

Dieser Ablauf sollte öfter ausgeführt werden.

Frage: Wie kann ich die Daten Zwischenspeichern, oder muss ich das überhaupt ? Oder kann ich immer direkt auf die SD-Karte speichern und beim nächsten Prüfvorgang einfach eine neue Datei auf der SD-Karte anlegen ?

Ich hoffe ihr könnt mir weiterhelfen. Voraus schon mal besten Danke ;)

Gruß Tobi

Keine Ahnung was OSSD ist, aber 200kB kannst du nicht im RAM zwischenspeichern.

4 Ereignisse / sec solltest du allerdings locker auf einer SD Karte loggen können. Mir stellt sich eher die Frage, woran du das Ende eines "Prüfvorgangs" erkennst, um die Datei zu schliessen.

OSSD = Output Signal Switching Devices – Geräte zum Schalten von Ausgangssignalen...

Es ist so vorgesehen, das ein Prüfvorgang wird mit einem Bedienelement "Messung starten" gestartet und durch ein Bedienelement "Messung beenedet" beendet.

Also ist es kein Problem die Daten direkt auf die SD-Karte zu schreiben, ohne das ich grobe, zeitliche Differenzen habe ?

Weiss nicht woher deine Schätzung der 4 Byte / Ereignis herkommt, aber ein Großteil wird wohl die Zeit in ms sein.

Wenn erforderlich, kannst du die Ereignisse selbst per Interrupt (Pin Change Interrupt für beliebige Pins) erfassen und Auswertung, Anzeige und Logging gemütlich in loop machen.

Sollen denn die statistischen Werte (minimale / maximale / mittlere Zeitdauer) oder jeder Einzelwert auf SD-Karte gespeichert werden?

Ein Ablauf soll mind. 50.000 Signalwechsel umfassen können ( 2OSSD’s , 1 Hz Schaltfrequenz → 4 Signalwechsel p.Sec → 14.400 Signalwechsel p.Std)

Ich habe das ganze mal ausgerechnet und benötige für einen Eintrag 4 Byte. Also für einen gesamten Ablauf mind. 200kB.

Das riecht eher nach Rohdaten - Logging :wink:

michael_x:
Das riecht eher nach Rohdaten - Logging :wink:

Ja, fürchte ich auch, aber lieber mal fragen. :wink:

1 Ablauf sollen ja mind. 50.000 Signalwechsel erfassen können. Daraus berechne ich dann 50.000 Sw / 4 Sw.p.Sec = 12.500 Sw p.Sec Die zeitliche Erfassung soll eben in 1ms oder in 10ms erfasst werden. -> 12.500.000 ms

Mit 3 Byte kann ich 16.777.216 verschieden Zahlen darstellen. Also benötige ich für die Auflösung von 12.500.000 ms mind. 3 Byte. Dazu werden zur Auuflösung der OSSD's und der Flanken (Rechtecksignal) ca. 1 Byte. Somit werden also ca. 4 Byte pro Eintrag benötigt.

50.000 Signalwechsel x 4Byte = 200 kB -> Speichergröße für einen kompletten Ablauf :)

Die Werte (minimale / maximale / mittlere Zeitdauer) und Anzahl der Signalwechsel sollen dann auf die SD-Karte gespeichert werden, damit sie dann mit Excel anschaulich dargestellt werden können.

Interessant. Gut dass du gefragt hast, agmue.

Nun ist die Aufgabe also nur: - Min, Max, Mittl. Dauer, Anzahl zu ermitteln, ohne die ganzen Rohdaten zu speichern    (was aber kein Problem sein sollte) - auf einem Display (?) die laufenden Werte anzeigen - beim Ende die endgültigen Werte auf SD Karte zu schreiben

So verstehe ich dich jedenfalls jetzt, rumtob.

50.000 Sw / 4 Sw.p.Sec = 12.500 Sw p.Sec

versteh ich allerdings nicht. Wenn Sw "Schaltwechsel" bedeutet, und Sw.p.Sec " Schaltwechsel pro Sekunde", ist das Ergebnis der Division 12.500 s (= dreieinhalb Stunden), und die Gegenfrage heisst: "Ja und ?"

michael_x: Interessant. Gut dass du gefragt hast, agmue.

"Manchmal ist man das Denkmal, manchmal die Taube!" :D

Es handelt sich also um zwölf zu aktualisierende Statistikwerte während der Messung, die am Ende der Messung auf SD-Karte gespeichert werden sollen. Dann ist das Speichern auf SD-Karte ja außerhalb des Messens und daher vollkommen unkritisch. Richtig?

50.000 Sw / 4 Sw.p.Sec = 12.500 Sec

Zeitlich ist das eh unkritisch.

ich schreibe bei meinem Grillregler alle 30 sek ca. 60Byte auf die SD-Karte.

Wie das geht, steht im Beispiel “Datalogger” in der SD.lib.

Wenn du die Schaltflanken über Interrupt erfasst, ist das, auch während des Schreibens, zeitgenau.

Aber, wie schon angemerkt:
Es ist noch offen, was genau du willst: Nur ein wenig Statistik und dann Ergebnis abspeichern, oder Aufnahme aller Messgrößen, um die dann offline auszuwerten.
Echte Statistik, also nicht nur Mittelwert, sondern auch Standardabweichung, Varianz etc. sind in Excel sowieso besser zu machen.

Die aktuellen Werte der Messung sollen immer im Display angezeigt werden und am Ende einer Messung die kompletten Daten auf der SD-Karte abgespeichert sein, damit man eben sieht zu welcher Zeit ein OSSD ein/aus war und für wie lange er ein/aus war und wie viele Signalwechsel stattgefunden haben.

Werte für jeweils : OSSD'A & OSSD'B: min. / max. / mitt. Zeitdauer EIN-Zustand min. / max. / mitt. Zeitdauer AUS-Zustand + Anzahl Signalwechsel

Wie schon gesagt, werden diese Daten in den Displays angezeigt und eben auf die SD-Karte gespeichert. Somit sind es also keine 12 sondern 14 aktualisierende Statistikwerte.

Die Aufzeichnung erfolgt dann auf eine Micro-SD im Datei-System FAT32 (wenn nicht möglich FAT16).

Am Ende sollen die Daten in einer Statistik in Excel eben anschaulich sein.

und am Ende einer Messung die kompletten Daten auf der SD-Karte abgespeichert sein, damit man eben sieht zu welcher Zeit ein OSSD ein/aus war

Das geht nur während der Messung. 200 kB kannst du nicht auf einem 2560 zwischenspeichern.

Das geht, aber wie Michael schon bemerkt hat, musst du wärend der Messung schreiben.

Ich würde das, grob skizziert, so machen:

  • die Flankenwechsel über Interrupts auswerten.

  • Fortlaufend Min/Max/MittelW... berechnen und anzeigen.

  • Die Messwerte in einem Array sammeln und z.B. alle 10 Zyklen auf die SD-Karte schreiben.

rumtob: .. am Ende einer Messung die kompletten Daten auf der SD-Karte abgespeichert sein

Sorry, so richtig hab ich es noch nicht verstanden: Sollen nach der Messung 14 oder ein paar Tausend Meßwerte auf der SD-Karte gespeichert sein?

Zum zu messenden Signal: Die Extremwerte sind - 1 ms HIGH, 999 ms LOW - 999 ms HIGH, 1 ms LOW ?

Die Messwerte in einem Array sammeln und z.B. alle 10 Zyklen auf die SD-Karte schreiben

Das ist egal. Auf die SD Karte werden sowieso nur ganze Sektoren geschrieben (wenn du nicht mutwillig flush() aufrufst). Wenn du nur wenige bytes schreibst, landen die sowieso erstmal nur im RAM Puffer der SD Library.

Hat eben den Nebeneffekt, dass du nie genau weisst, wie lange das SD.write(buffer,size) dauert, und du daher besser ms-genaue Sachen in einer Interrupt-Routine machst.

rumtob:
Die aktuellen Werte der Messung sollen immer im Display angezeigt werden und am Ende einer Messung die kompletten Daten auf der SD-Karte abgespeichert sein, damit man eben sieht zu welcher Zeit ein OSSD ein/aus war und für wie lange er ein/aus war und wie viele Signalwechsel stattgefunden haben.

Ich finde, das klingt recht eindeutig:
die aktuellen Werte werden angezeigt,
und alle Werte werden auf SD geschrieben.

Und mit “aktuelle Werte” ist anscheinend die statistische Auswertung der Daten von Start bis Jetzt gemeint.
laufender Mittelwert geht so:
MW(n) = (MW(n-1) * (n-1) + X ) / n

mit n: Anzahl der bisher erfolgten Messungen
X: aktueller Messwert
MW: Mittelwert

laufender Mittelwert geht so: MW(n) = (MW(n-1) * (n-1) + X ) / n

So geht es natürlich auch (insbesondere bei float Mittelwerten).

Einfacher ist oft (falls der Wertebereich unsigned long groß genug ist)

SX += X;
n++;
MW = SX /n;

Also ich glaube ich hab's jetzt verstanden wie ich es machen muss. Wenn wieder Probleme auftreten werde ich mich melden :) Ich danke euch auf alle Fälle mal. Super ...

Gruß Tobi

Nur mal so als Anmerkung. Wenn du eh einen Rechner in der Nähe am laufen hast kannst du die Werte auch direkt vom Arduino zu Excel schicken. Die Diskussion hier ist aber sehr lehrreich :)