Datenverlust DAC und UART

OP #4653572
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.
#4653609
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 ;-)
#4653622
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.
OP #4653629
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.
Gast #4653632
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.
Gast #4653649
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.
OP #4653652
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 ;)
Gast #4653672
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.
Gast #4653675
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.
OP #4653682
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.
Gast #4653708
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.
OP #4653743
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.
OP #4653759
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.
OP #4653769
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.
#4653784
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
#4653804
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.
Gast #4653834
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.
OP #4653919
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.
Gast #4654359
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.
#4654404
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren