Forum: Mikrocontroller und Digitale Elektronik Datenverlust DAC und UART


von Peter L. (dcp12)


Lesenswert?

Ich habe mir auf dem ATmega 2560 ein Programm geschrieben mit dem ich 
analoge Signale über den ADC auslesen kann. Dieser läuft im single 
conversion Modus.

Über das UART lasse ich mir unter anderem die analogen Signale ausgeben. 
Insgesamt werden pro Zyklus 160 Bit an Daten versendet. Eingestellt habe 
ich eine Baudrate von 115200.
Das müsste dann ja heißen, dass ich nach folgender Formel (115200*8 / 
160) = 5,76 kbit / s versende.

Mein ADC arbeitet mit einem Taktzyklus von 125 kHz und einer Abtastrate 
von etwa 9,6 ksps. Meine Frage ist jetzt ob Abtastwerte verloren gehen, 
da der UART langsamer als der AD-Wandler läuft oder arbeitet der AD 
Wandler langsamer, weil ich mich im single conversion Modus befinde und 
mit der nächsten Konvertierung erst gewartet wird, bis alle Daten 
ausgegeben wurden.

von Jim M. (turboj)


Lesenswert?

Peter L. schrieb:
> Das müsste dann ja heißen, dass ich nach folgender Formel (115200*8 /
> 160) = 5,76 kbit / s versende.

Falsch. Du kannst 115200/200 = 576 Zyklen pro Sekunde versenden. Ich 
gehe mal gavon aus das bei den 160 Bits keine Start- und Stopbits dabei 
sind.

von Falk B. (falk)


Lesenswert?

@Peter L. (dcp12)

>ich eine Baudrate von 115200.
>Das müsste dann ja heißen, dass ich nach folgender Formel (115200*8 /
>160) = 5,76 kbit / s versende.

Uhhhhh, mal bitte nicht Bits, Bytes und Pakete mischen!! Hat dein 
Datenpaket WIRKLICH 160 Bit? Oder eher 160 Bytes?

115200 Baud sind 11520 Bytes/s

11520 Bytes/s / (160 Bytes/Paket) = 72 Pakete/s

Wenn es 160 Bit sind, dann sind es 576 Pakete/s.

> Meine Frage ist jetzt ob Abtastwerte verloren gehen,
>da der UART langsamer als der AD-Wandler läuft oder arbeitet der AD
>Wandler langsamer, weil ich mich im single conversion Modus befinde und
>mit der nächsten Konvertierung erst gewartet wird, bis alle Daten
>ausgegeben wurden.

Das hängt von deiner Software ab ;-)

von Pandur S. (jetztnicht)


Lesenswert?

115.2kBit bedeuten 11.52kbyte, weil ein byte mit 10bit versandt wird.

Wieviele bits oder bytes auch immer versendet werden muessen ist unklar.
Wieviele bits oder bytes auch immer gesampelt werden ist unklar.

Darf ich annehmen es werden 10bit gesampelt, mit 9.6kSample ?
Das waeren dann 96kbit, resp 12kbytes, welche auf dem UART dann schon 
120kBit waeren. Allenfalls koennte man auch nur 9 Bit nehmen, weil das 
10te eh Rauschen ist.

Wie auch immer, entweder es passt oder nicht. Falls es nicht passt, hat 
man folgende Optionen :
1) Etwas langsamer samplen, mit gleichen Abstaenden, sodass es passt.
2) Etwas langsamer samplen, mit maximaler Rate, dann warten bis der 
buffer es wieder zulaesst
2) Jeweils einen Block fuer einen Buffer sampeln, und diesen 
?Kontinuierlich uebertragen.

Eine Frage was man will. Sampeln und Uebertragen kann man mit den 
angegebenen Werten gleichzeitig, ohne Einschraenkung, dazu ist genuegend 
Zeit vorhanden.

Ich wuerd erst mal testen ob die 9.6kSample noch brauchbare Werte 
liefert, oder schon zuviel Rauschen.

: Bearbeitet durch User
von Peter L. (dcp12)


Lesenswert?

Also die Programmierung lief über das Atmel Studio 6.2

Lässt sich die Baudrate denn nicht umrechnen?
Hier mal ein einfacheres Beispiel.

uint16_t analog0;
uint16_t Time;

Für die beiden Variablen werden ja jeweils 16 Bit reserviert. Außerdem 
habe ich für jede Variable jeweils 2 Start und 2 Stopbits. Also komme 
ich doch auf insgesamt 40 Bit, die mit dem UART ausgegeben werden.
Ich sollte noch erwähnen, dass ich auf dem Arduino Mega Board 
programmiere.

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

Peter L. schrieb:
> Für die beiden Variablen werden ja jeweils 16 Bit reserviert. Außerdem
> habe ich für jede Variable jeweils 2 Start und 2 Stopbits. Also komme
> ich doch auf insgesamt 40 Bit, die mit dem UART ausgegeben werden.

da braucht man aber noch ein paar Infos mehr. Du musst wissen wo was 
anfängt (eine Protokoll) sonst muss man beim auslesen raten, welches 
Byte wo ist.

von Peter L. (dcp12)


Lesenswert?

Peter II schrieb:
> da braucht man aber noch ein paar Infos mehr. Du musst wissen wo was
> anfängt (eine Protokoll) sonst muss man beim auslesen raten, welches
> Byte wo ist.

Für mich ist doch nur die Länge der zu versendenden Dateien interessant.

von Peter II (Gast)


Lesenswert?

Peter L. schrieb:
> Für mich ist doch nur die Länge der zu versendenden Dateien interessant.

also nicht der Inhalt?

Wozu brauchst du dann den DAC?

von Peter L. (dcp12)


Lesenswert?

Peter II schrieb:

> also nicht der Inhalt?
>
> Wozu brauchst du dann den DAC?

Die Werte des ADC's (Auflösung 10 Bit) speicher ich in der Variablen 
analog0 in einem 16 Bit Paket.

Ich sehe gerade das die Überschrift falsch ist. Es sollte ADC heißen.

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

Peter L. schrieb:
> Die Werte des ADCs speicher ich in der Variablen analog0 in einem 16 Bit
> Paket.

richtig

aber wenn man 2mal 16bit überträgt, woher weißt du was zu wem gehört?

Das ganze ist ein Datenstrom ohne Anfang und Ende. Wenn man mittendrin 
anfängt die Daten zu speichern, kannst du nicht mehr wissen was das 
erste uint16 und was das 2. uint16 ist.

Da du die Daten kennst, könnte man das erraten. Aber schön ist das 
nicht.

von Peter L. (dcp12)


Lesenswert?

Peter II schrieb:
> Das ganze ist ein Datenstrom ohne Anfang und Ende. Wenn man mittendrin
> anfängt die Daten zu speichern, kannst du nicht mehr wissen was das
> erste uint16 und was das 2. uint16 ist.

Ich trenne die Daten mit einem Semikolon voneinander. Also da gibt es 
keine Probleme.

Das ganze soll auch nur eine grobe Überschlagsrechnung werden ;)

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

Peter L. schrieb:
> Ich trenne die Daten mit einem Semikolon voneinander. Also da gibt es
> keine Probleme.

doch, du überträgt scheinbar binary und da kommt das Semikolon auch in 
den Daten vor.

von S. Landolt (Gast)


Lesenswert?

> Datenstrom ohne Anfang und Ende
Pro Wert sind ja noch 4 bits übrig für eine irgendwie gestaltete 
Kennung.

von S. Landolt (Gast)


Lesenswert?

?? Wie komme ich auf 4, ich meinte 6.

von Peter L. (dcp12)


Lesenswert?

Peter II schrieb:
> doch, du überträgt scheinbar binary und da kommt das Semikolon auch in
> den Daten vor.

Ne, ich gebe die Werte als String aus. Dann passt aber meine erste 
Vermutung bezüglich der 160 Bit nicht mehr. Ups....
Aber wie gesagt es soll auch nur eine grobe Überschlagsrechnung werden.

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

Peter L. schrieb:
> Ne, ich gebe die Werte als String aus. Dann passt aber meine erste
> Vermutung bezüglich der 160 Bit nicht mehr. Ups....

> Aber wie gesagt es soll auch nur eine grobe Überschlagsrechnung werden.
naja, dann sollte man aber auch nicht 100% daneben liegen.

> uint16_t Time
als string kann können das 5 Zeichen werden (65535). Dazu kommt dann 
meist noch ein [ENTER] am ende also schon mal 6 Zeichen + der ADC wert.

von Der Andere (Gast)


Lesenswert?

Peter L. schrieb:
> Aber wie gesagt es soll auch nur eine grobe Überschlagsrechnung werden.

In den ersten 3 Beiträgen wird dir genau diese Überschlagsrechnung 
vorgerechnet.

Trotzdem solltest du darüber nachdenken, wie du die Daten so packst dass 
er Empfänger sauber erkennt wann ein Paket anfängt und wann es endet.

von Peter L. (dcp12)


Lesenswert?

Peter II schrieb:
> als string kann können das 5 Zeichen werden (65535). Dazu kommt dann
> meist noch ein [ENTER] am ende also schon mal 6 Zeichen + der ADC wert.

Da hast du recht. Die Rechnung bekomme ich aber noch selber hin (da 
werde ich mich mal in Ruhe dransetzen...)

Der Andere schrieb:
> In den ersten 3 Beiträgen wird dir genau diese Überschlagsrechnung
> vorgerechnet.
>
> Trotzdem solltest du darüber nachdenken, wie du die Daten so packst dass
> er Empfänger sauber erkennt wann ein Paket anfängt und wann es endet.

Was genau kann ich mir denn unter den 576 Paketen die pro Sekunde 
versendet werden vorstellen? Da blicke ich nicht ganz durch.

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

Vielleicht bin ich ja der Einzige, aber sei's drum: ich habe noch immer 
nicht verstanden, was da übertragen werden soll - ein 160 bit-Paket, ein 
Zeitstempel, ein ADC-Wert oder mehrere davon? Für Ersteres wurde oben ja 
ausführlich vorgerechnet.

von Peter L. (dcp12)


Lesenswert?

S. Landolt schrieb:
> Vielleicht bin ich ja der Einzige, aber sei's drum: ich habe noch immer
> nicht verstanden, was da übertragen werden soll - ein 160 bit-Paket, ein
> Zeitstempel, ein ADC-Wert oder mehrere davon? Für Ersteres wurde oben ja
> ausführlich vorgerechnet.

Verschiedene Werte aus Integer Variablen. Unter anderem auch die 
analogen Werte des ADC.

von S. Landolt (Gast)


Lesenswert?

Nach dieser vagen Angabe bleibt als Konkretum ja nur das 160 bit-Paket, 
und dazu ist ganz oben alles gesagt.

von Peter L. (dcp12)


Lesenswert?

Vielleicht sollte ich es anders formulieren. Mir ist es noch nicht ganz 
klar.

Und zwar möchte ich die Werte des ADC (Auflösung 10 Bit, Abtastrate 9,6 
ksps) in der Variablen analog0 (Größe 16 Bit) speichern und über das 
UART mit einer Baudrate von 115200 ausgeben. Meine Frage ist nun, ob die 
Ausgabe schnell genug erfolgt, oder ob der ADC "zu schnell" abtastet, 
sodass Werte, die noch nicht ausgegeben wurden überschrieben werden und 
somit verfallen.

von Stefan K. (stefan64)


Lesenswert?

Definiere mal "schnell genug".

Wer gibt denn bei Dir das Timing vor? Der ADC? Der UART? Oder möchtest 
Du lieber eine feste Zeitbasis, z.B. die ADC-Werte alle 1ms senden?

Gruß, Stefan

von Peter L. (dcp12)


Lesenswert?

Wenn ich das richtig verstanden habe, dann sind die Zeiten vom UART und 
ADC unterschiedlich (also arbeiten die beiden getrennt voneinander).
Und mich würde interessieren ob der UART mit der Ausgabe "aller Werte" 
hinterher kommt oder ob welche überschrieben werden.

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

Wenn der ADC schneller abtastet als der UART senden kann, und es 
dazwischen keinen genügend großen Puffer gibt der das abfangen kann, 
dann kommt es natürlich zum Datenverlust.

von Stefan K. (stefan64)


Lesenswert?

Peter L. schrieb:
> Mein ADC arbeitet mit einem Taktzyklus von 125 kHz und einer Abtastrate
> von etwa 9,6 ksps

D.h. der ADC soll Deine Zeitbasis sein? Und nach jedem ADC-Samplen 
willst Du 16 Bytes = 16 * (8+2) = 160 Bits senden?
Dann muss Deine Baudrate MINDESTENS 9,6 ksps * 160 Bit = 1538,5kbaud ~ 
1,5Mbaud sein. Schwierig.

921,k kbaud sind mit dem Atmega ganz gut machbar und auch am PC ganz gut 
einstellbar. Dazu muss allerdings der Quarz des Atmega entsprechend 
gewählt werden. Damit ändert sich dann übrigens auch die 
Eingangsfrequenz des ADC etwas.

Gruß, Stefan

von Peter L. (dcp12)


Lesenswert?

Mark B. schrieb:
> Wenn der ADC schneller abtastet als der UART senden kann, und es
> dazwischen keinen genügend großen Puffer gibt der das abfangen kann,
> dann kommt es natürlich zum Datenverlust.

Und das ganze würde ich gerne mit einer Rechnung beweisen oder 
veranschaulichen ;)

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

@Peter L. (dcp12)

>Und zwar möchte ich die Werte des ADC (Auflösung 10 Bit, Abtastrate 9,6
>ksps) in der Variablen analog0 (Größe 16 Bit) speichern und über das
>UART mit einer Baudrate von 115200 ausgeben. Meine Frage ist nun, ob die
>Ausgabe schnell genug erfolgt,

Nö.

> oder ob der ADC "zu schnell" abtastet,

Ja.

>sodass Werte, die noch nicht ausgegeben wurden überschrieben werden und
>somit verfallen.

9600 Samples/s * 2 Byte = 19200 Byte/s

Der UART schafft bei 115200 Baud aber nur 11520 Bytes/s, reichlich die 
Hälfte. Da musst du die Baudrate verdoppeln oder die Abtastrate 
vermindern.

von Peter L. (dcp12)


Lesenswert?

Falk B. schrieb:
> 9600 Samples/s * 2 Byte = 19200 Byte/s
>
> Der UART schafft bei 115200 Baud aber nur 11520 Bytes/s, reichlich die
> Hälfte. Da musst du die Baudrate verdoppeln oder die Abtastrate
> vermindern.

Alles klar. Besten Dank

von S. Landolt (Gast)


Lesenswert?

Peter L. schrieb:
> Falk B. schrieb:
>> 9600 Samples/s * 2 Byte = 19200 Byte/s
>>
>> Der UART schafft bei 115200 Baud aber nur 11520 Bytes/s, reichlich die
>> Hälfte. Da musst du die Baudrate verdoppeln oder die Abtastrate
>> vermindern.
>
> Alles klar. Besten Dank

Nichts ist klar. Wie passt das zu

Peter L. schrieb:
> Verschiedene Werte aus Integer Variablen. Unter anderem auch die
> analogen Werte des ADC.

Mir scheint jetzt, dass eher die Vermutung von Stefan K. stimmt.

von Peter L. (dcp12)


Lesenswert?

Dann versuch ich jetzt nochmal meine endgültige Rechnung hier 
aufzuführen.
Ich habe eine Baudrate von 115200, diese entspricht 11520 Bytes/s (1 
Startbit, 8 Datenbits und 1 Stopbit)
Meine Daten die ich über das UART ausgeben möchte (Wobei diese von 
Integer in einen String umgeformt werden. Angegeben habe ich die max. 
Zeichengröße)
- Time: Größe 32 Bit --> Umformung in String: 10 Zeichen --> 10 Byte
- ';': Größe 8 Bit: --> String: 1 Zeichen --> 1 Byte
- analog0 (Speichert die Werte des ADCs): Größe 16 Bit --> String: 5 
Zeichen --> 5 Byte
- Zeilenumbruch: Größe: 8 Bit --> String: 1 Zeichen --> 1 Byte
Summe: 17 Bytes

Das heißt ein Datenpaket enthält 17 Bytes. Mit (11520 Bytes/s) / (17 
Bytes) = 678 Zyklen / s.

Also kann ich das Datenpaket etwa 678 mal pro Sekunde ausgeben.

Nun zum ADC. Die Auflösung beträgt 10 Bit, also Werte zwischen 0 und 
1023. Die Werte werden in analog0 gespeichert in einem 16 Bit 
Datenpaket. Aufgeteilt in einzelne Zeichen macht dies wiederum 5 Bytes.

Wie kann ich jetzt die Abtastrate von 9,6ksps in Verhältnis mit meinem 
Übertragungszyklus setzen. Mich würde interessieren, wie viele Werte 
tatsächlich verloren gehen. Meine Baudrate möchte ich fürs erste nicht 
ändern, genauso wie die Abtastrate.

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

Mag sein, dass ich schwer von Begriff bin, aber es scheint mir 
offensichtlich: es lässt sich nur jeder 15. ADC-Wert übertragen, die 
anderen 14 gehen verloren.
  Wobei ich mich frage, ob diese aufwändige Stringübertragung wirklich 
nötig ist, weshalb bei jedem ADC-Wert der komplette Zeitstempel 
mitlaufen muss und warum aus einem 10 bit-Wert (0..1023) fünf Zeichen 
werden, ich hätte gedacht "0000".."1023" im schlimmsten Fall.

von Stefan K. (stefan64)


Lesenswert?

Peter L. schrieb:
> Meine Baudrate möchte ich fürs erste nicht
> ändern, genauso wie die Abtastrate.

Das kann ich gut verstehen. Nur so kann man im Flyer der 
Gerätebeschreibung groß "9,6ksps" schreiben.
Hinten im Kleingedruckten kann man immer noch "678 übertragene 
Datensätze/s" nebenbei erwähnen.

von Dorian H. (dorianh)


Lesenswert?

Diese ganze Umwandlung in strings sollte erstmal entfernt werden. Dann 
die Zeitstempel rausnehmen. Schick so viel Daten wie nötig, aber nicht 
mehr. Z.B. wenn du 10 bits an Daten hast, kannst du mit den restlichen 6 
(wenns dann 2 Bytes sein sollen) noch ne Pakete Nummerierung machen, 
dann hast du 16 bits pro sample. Aber keine 15 ascii Zeichen. Vielleicht 
jede 100ms oder 1 sec ein Synchronisierungspacket (mit Zeitstempel). 
Dann brauchst du nicht jedesmal deinen Zeitstempel, sondern du weisst wo 
du bist.
Und kein "mal schauen wieviel Daten verloren gehen", zumindest nicht bei 
UART Verbindungen (im Funk lässt nicht das nicht vermeiden, aber das ist 
ein komplett anderes Thema). Entweder schnellere Verbindung oder weniger 
Daten schicken. Die Daten die du schickst müssen!! im Normalfall 
ankommen.
Aber das ist nur meine Meinung.

: Bearbeitet durch User
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.