Forum: Mikrocontroller und Digitale Elektronik serielle Daten aufzeichnen mit einem µC


von Dominik Schmidt (Gast)


Lesenswert?

Moin !

Ich würde gerne mit meinem µC (AVR) serielle Daten loggen und in ein
EEProm oder auf eine SD Karte sichern. Was ich dabei noch nicht ganz
durchschaue ist die generelle Vorgehensweise.
Also angenommen wir haben ein beliebiges Gerät - sagen wir mal ein GPS.
Das sendet jede Sekunde eine Anzahl X Bytes über die Schnittstelle. Nun
könnte ich jedes Byte einfach in den Speicher schieben, aber dann geht
mir letztlich die Struktur und der zeitliche Ablauf der Daten verloren.

Wie kriege ich das nun hin, dass Die Daten so abgespeichert werden, das
ich sie später nach dem Übertragen in den PC wieder sinnvoll auswerten
kann?
Und wie würde man das ganze angehen, wenn der Zeitabstand zwischen den
Paketen nicht immer eine Sekunde sondern variabel ist?

Hätte da jemand mal einen generellen Tip wie man sowas angeht?

Greetz Dominik
http://www.logview.info

von Rufus, das dicke Ei (Gast)


Lesenswert?

Am einfachsten ist es, wenn die Datenpakete eine feste Länge haben.
Nimm einen Zeitstempel dazu, je nach geplanter Länge der
Aufzeichnungsdauer halt ein paar Byte und schreib die nacheinander ins
Eeprom.
Beim Auslesen musst Du dann nur noch die Zeitstempel und die folgenden
Daten dekodieren.

von Dominik Schmidt (Gast)


Lesenswert?

Moin !

Soweit so gut ...
Aber das ganze soll universell sein. Das bedeutet, ich weiss nicht wie
lang die Pakete sind und ích weiss nicht ob die zeitlichen Abstände
immer gleich sind.
Sonst wäre deine Methode sicherlich ok.

Greetz Dominik
http://www.logview.info

von Rufus, das dicke Ei (Gast)


Lesenswert?

Die zeitlichen Abstände sind ja egal, dafür hast Du den Zeitstempel, der
nichts anderes als ein durchlaufender Zähler ist.
Du musst natürlich den "Nullpunkt" kennen bzw. festlegen.

Nach dem Zeitstempel kannst Du ja ein oder mehrere Bytest für die Länge
des Paketes reservieren. Mehr ist nicht nötig!

von Dominik Schmidt (Gast)


Lesenswert?

Moin !

Hmm, dann müsste ich im schlimmsten Fall für jedes Byte den Zeitstempel
speichern? Weil ich weiss ja zu dem Zeitpunkt noch garnicht welche Bytes
zusammen gehören ...

Greetz Dominik
http://www.logview.info

von Michael (Gast)


Lesenswert?

Willst Du einen MIDI-Sequenzer bauen? => Time-Stamp (Delta-Time)

von Dominik Schmidt (Gast)


Lesenswert?

Moin !

Nein. Ich will im Modellbaubereich die Daten z.B. von Ladegeräten auf
dem Flugfeld aufzeichnen können. Und da weiss man halt erstmal nicht
was an Daten kommt, denn jeder Lader ist anders.

Greetz Dominik
http://www.logview.info

von Volker Kattoll (Gast)


Lesenswert?

@Dominik

Wenn du wirklich diesen universellen Ansatz nutzen willst, so bleibt
dir nichts anderes uebrig:
>Hmm, dann müsste ich im schlimmsten Fall für jedes Byte den
Zeitstempel
>speichern? Weil ich weiss ja zu dem Zeitpunkt noch garnicht welche
>Bytes zusammen gehören ...

Da kann es dir passieren, das deine Datenaufkommen mit den Zeitstempeln
versehen plötzlich enorme Grössenordnungen annimmt und das Verhältnis
Nutzdaten / Zeitstempel sehr ungünstig ausfaellt.

Wenn es dir gelingt, eine Datenstruktur per Software zu erkennen, so
wandelt sich das Verhältnis Nutzdaten/Zeitstempel zu deinen Gunsten.

Gruss Volker

von Rufus, das dicke Ei (Gast)


Lesenswert?

"Hmm, dann müsste ich im schlimmsten Fall für jedes Byte den
Zeitstempel
speichern? Weil ich weiss ja zu dem Zeitpunkt noch garnicht welche
Bytes
zusammen gehören ... "

Ach so ist das.
Das ist natürlich unschön. Normalerweise kennt man die Daten, die
kommen und fasst die dann zusammen.

Irgendwie erscheint es mir aber unlogisch, daß die Daten völlig
unbekannt sind. Du weißt ja, woher sie sind.
Ich würde mir einfach anschauen, welche Muster da vorhanden sind und
dann diese entsprechen in der Software abbilden.

Anders wird das schwer möglich sein, ohne daß Platz verschwendet wird.

von Philipp Sªsse (Gast)


Lesenswert?

Definiere Dir ein universelles Datenformat, das Deinen möglichen
Anforderungsbereich möglichst kompakt abdeckt. Beispiel: Du willst
GPS-Positionen, Spannung und Strom über die Zeit auftragen und zwar in
unterschiedlichen Intervallen ab einer Sekunde (aber z.B. GPS-Daten nur
selten, wenn sie sich nur langsam ändern).

Dein Format muß also jeweils aus einem Kopf bestehen, der verrät, was
für ein Wert dort gesichert wurde und wie lang das Feld ist, sowie aus
dem Wert selbst.

Um wenig Overhead zu haben, soll der Kopf nur ein Byte lang sein, davon
sind dann z.B. 5 Bit die Sekunden seit dem letzten Wert, die restlichen
drei Bit markieren die Art der Daten (GPS oder Strom oder Spannung).
Damit hast Du aber nur eine relative Zeit, Du definierst Dir also noch
ein weiteres Feld für die Absolutzeit. Nehmen wir:

1) Absolutzeit  001xxxxx
   (7 Datenbytes für Jahr, Monat, Tag, Stunde, Minute, Sekuden)
2) GPS-Position 010xxxxx
   (6 Datenbytes für 3xLänge und 3xBreite)
3) Spannung     011xxxxx
   (1 Datenbyte mit der Spannung)
4) Strom        100xxxxx
   (2 Datenbytes mit dem Ladestrom

Nun seien Deine Eingangsdaten (mal extrem)

10:00:00 GPS-Position X
10:00:03 Spannung A
10:00:03 Strom B
10:00:30 GPS-Position Y
10:00:40 Spannung C
10:00:41 Spannung D
10:02:00 Spannung E

Dann beginnst Du mit der Absolutzeit und dann relativen Daten:

$20 2005 06 21 10 00 00 (Absolutzeit)
$40 ll ll ll bb bb bb   (GPS-Position, 0 Sekunden später)
$63 aa                  (Spannung, 3 Sekunden später)
$80 bb bb            (Strom, 0 Sek. später, also mit der Spannung)
$5B ll ll ll bb bb bb   (010 11011 GPS-Position nach 27 Sek.)
$6A cc                  (011 01010 Spannung nach 10 Sek)
$61 dd                  (011 00001 Spannung nach 0 Sek)
$1F                     (000 11111 Nichts nach 31 Sek, 10:01:12)
$1F                     (000 11111 Nichts nach 31 Sek, 10:01:43)
$71 ee                  (011 10001 Spannung nach 17 Sek, 10:02:00)

Zum Schluß habe ich noch einen Trick eingeführt: wenn über eine halbe
Minute keine Daten kommen, ist keine relative Zeit mehr möglich. Damit
man nicht immer einen neuen (großen) Block mit der Absolutzeit
schreiben muß, definiert man sich noch einen leeren Block (000xxxxx),
der nur die relative Zeit vor sich herschiebt, ohne Daten zu tragen;
damit kann man kurze Pausen gut Überbrücken.

Beim Parsen hat man dann eine Schleife mit etwas wie

Zeit += Byte[Position] & 0x1F;
switch (Byte[Position++])
  {
    case 01:
      // Absolutzeit parsen
      Position += 7;
      break;
    case 02:
      // GPS-Position parsen
      Position += 6;
      break;
    case 03:
      // Spannungswert verarbeiten
      Position++;
      break;
    case 04:
      // Stromwert verarbeiten
      Position += 2;
      break;
    }

Was noch fehlt, ist eine Abbruchbedingung, wo denn die
Datenaufzeichnung zuende ist. Man könnte ein Nullbyte als Header
nehmen; bei Aufzeichnung auf Flash wäre ein $FF aber wohl sinnvoller.

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.