Forum: Mikrocontroller und Digitale Elektronik 8 Kanal ADC Ausgabe alle 100ms


von Piet (Gast)


Lesenswert?

Hi,

ich wende mich mal ans Forum, vlt. könnt ihr mir weiterhelfen!

Ich programmiere mit einem Atmega16 in C.

Ich verwende alle 8Kanäle des ADC und möchte nun meine gemessenen 8 
Spannungswerte zwischenspeichern und ca 100 Messwerte alle 100ms per 
RS232 ausgeben.

Der Timer dazu ist auch schon fertig.

Es funktioniert die AD-Wandlung auch problemlos nur mein Problem ist 
(bis jetzt frag ich einfach alle Kanäle nacheinander ab) ist wie ich die 
ADC Werte zwischenspeichern kann (sind ja dann 8*100)und dann alle auf 
einaml per Uart ausgeben kann.

Kann man das mit einem Array machen wie müsste ich es dann realisieren ?
Und kann man bei meiner Problemstellung den ADC auch per Interupt machen 
oder ist dieser nur bei einer einfach AD Wandlung sinnvoll?

Hab leider im Forum nichts weiteres gefunden.

VG Piet

von Dietrich L. (dietrichl)


Lesenswert?

Piet schrieb:
> Ich verwende alle 8Kanäle des ADC und möchte nun meine gemessenen 8
> Spannungswerte zwischenspeichern und ca 100 Messwerte alle 100ms per
> RS232 ausgeben.

Bei 10Bit Auflösung braucht Du 2 Byte je Messwert. Das bedeutet: es 
fallen mindestens 16 Byte je Millisekunde an.

Zum Verschicken braucht Du also mindestens eine Übertragungsrate von

   (10 Bits je UART-Zeichen * 16) / 1ms = 160 kBaud

Und das nur, wenn Du sie als "Rohwerte" verschickst (wobei das Problem 
existiert die Bytes den Messwerten zuzuordnen).
Bei besserer Codierung brauchst Du also noch mehr Bytes je Messwert.
Das ist geschwindigkeitsmäßig schon sehr grenzwertig...

> ist wie ich die
> ADC Werte zwischenspeichern kann (sind ja dann 8*100)und dann alle auf
> einaml per UART ausgeben kann.

"Alles auf einmal" geht sowieso nicht. Der UART schickt ein Zeichen nach 
dem andern und kann nur ein Zeichen zwischenspeichern.

Warum willst Du die Werte nicht nach Auslesen aus dem ADC direkt 
verschicken? Die 8*100 Werte kannst Du sowieso nicht gleichzeitig 
"erzeugen", das braucht schon etwas Zeit. Ich habe allerdings jetzt 
nicht nachgerechnet, wie schnell das beim ATmega16 maximal ginge.

Die maximale Geschwindigkeit ergibt sich dann aus der maximal möglichen 
Baudrate und der Codierung der Messwerte.

Gruß Dietrich

von Dussel (Gast)


Lesenswert?

Es wäre besser, die Werte direkt zu senden, wie Dietrich schrieb.

Wenn du das nicht willst, kannst du die Werte in einem Array 
zwischenspeichern. Sinnvoll fände ich da ein zweidimensionales Array, 
eine Dimension für die Kanäle und eine Dimension für die Messreihen.
1
unsigned short int Array[100][8]
Natürlich musst du wissen, ob genug RAM vorhanden ist. Wenn du umsteigen 
kannst, kann es sein, dass ein XMega das Senden im Hintergrund über DMA 
machen kann.

von Piet (Gast)


Lesenswert?

Vielen Dank für die schnelle Antwort.

Ich hab eine Baudrate von 115200. Das mit den 100 Messwerten 100/ms war 
nur eine Idee wäre auch mit 50 oder 20 /100ms zufrieden.

Ich habe mir gedacht, dass der ADC ja um welten schneller ist als der 
Uart, dass ich per Timer(angenommen jede 5ms => 20 Werte/100ms) die 8 
gemessen Werte in einem Array speichere. Dann wiederum die gemessen 
Reihe(20 mal diese 8 Messungen) in ein neues Array ablege und dann 
dieses per Rs232 ausgebe.

VG Piet

von Dussel (Gast)


Lesenswert?

Warum willst du mit dem Versenden warten? Wie du sagst, ist die 
Übertragung langsamer als der ADC, gerade deshalb solltest du sofort 
nach der ersten Wandlung mit dem Senden beginnen.
Ich kenne deine Anwendung nicht, aber so wie es klingt, würde ich einen 
Ringpuffer verwenden. Daten, die vom ADC kommen, werden in den Puffer 
geschrieben und nach jedem gesendeten Wert werden die nächsten zu 
sendenden Daten aus dem Puffer genommen und gesendet. Wenn der Puffer 
voll ist, muss eben mit der Wandlung gewartet werden.
Wenn du die Daten nur zu bestimmten Zeitpunkten brauchst, kannst du den 
Puffer noch leeren und dann bis zum nächsten Sendeanstoß warten.
Auf diese Weise brauchst du weniger Speicher und kannst die beiden Dinge 
parallel ausführen. Wahrscheinlich könnte man das sogar in der 
Interruptfunktion machen, so dass das Hauptprogramm völlig unabhängig 
vom Wandeln und Senden laufen kann.

von Piet (Gast)


Lesenswert?

Vielen Dank für die zahlreichen Tips,

werde jetzt einfach direkt per Uart das signal senden. Das funktioniert 
einwandfrei.

Habe dazu noch eine weitere Frage ob es möglich ist entweder die 
Baudrate noch weiter zu erhöhen oder irgendwie anders eine schnellere 
Übertragung hinzubekommen ? Weil ich bekomm jetzt mit ner Baudrate von 
115200 nur eine einwandfreie Übertragung von 100 Hz hin (bei 8 Werten 
pro Messreihe).Wünschenswert wäre 200Hz oder sogar 500Hz.

VG Piet

von San L. (zwillingsfreunde)


Lesenswert?

Piet schrieb:
> Habe dazu noch eine weitere Frage ob es möglich ist entweder die
> Baudrate noch weiter zu erhöhen oder irgendwie anders eine schnellere
> Übertragung hinzubekommen ?

SPI / I2C wären da vielleicht angebracht...

von uwe (Gast)


Lesenswert?

Also der AVR kann schon mit 1Mbit senden, steht in der Tabelle für die 
Baudratenfehler (Er sollte dann allerdings auch mit nem 16MHz Quarz 
laufen.
Die FTDI USB zu seriell Wandler können auch Problemlos 1Mbit.
1Mbit habe ich geschaft mit nem 1m langen ungeschirmten Flachbandkabel 
mit RX/TX/GND. Hab ne 10Mbyte Datei drübergeschickt (hin und zurück) und 
CRC verglichen.

von Karol B. (johnpatcher)


Lesenswert?

Piet schrieb:
> Habe dazu noch eine weitere Frage ob es möglich ist entweder die
> Baudrate noch weiter zu erhöhen oder irgendwie anders eine schnellere
> Übertragung hinzubekommen ? Weil ich bekomm jetzt mit ner Baudrate von
> 115200 nur eine einwandfreie Übertragung von 100 Hz hin (bei 8 Werten
> pro Messreihe).Wünschenswert wäre 200Hz oder sogar 500Hz.

Ich frage mich manchmal ja wirklich, warum die Gruppe derjenigen (und zu 
der ich mich selber zähle), die solche Fragen im Vorfeld klären, so 
verschwindend gering ist. Die Datenmenge an Messwerten war dir doch 
bereits im Vorfeld bekannt, das sind einfachste Matheaufgaben und 
Dietrich L. hat dir das in seinem Beitrag bereits vorgerechnet. Welche 
Baudraten möglich sind  (und die dazugehörigen relativen Fehler), steht 
dann wiederum im Datenblatt.

Alles in allem: Dein Vorhaben ist schon ziemlich sportlich und bei 
deiner "Art" der Recherche im Vorfeld, stellt sich mir die Frage, ob du 
wirklich den sinnvollsten Ansatz verfolgst, oder dir das hier nur Leben 
unnötig schwer machst. Was wird denn überhaupt gemessen und wie weit 
weichen die einzelnen Messungen voneinander ab? Ist es wirklich 
notwendig die vollen 10 Bit zu verschicken und damit die notwendige 
Datenrate zu verdoppeln? Ggf. lässt sich das Ganze auch effizient 
komprimieren ...

Mit freundlichen Grüßen,
Karol Babioch

von Piet (Gast)


Lesenswert?

Hi,

mein Vorhaben liegt darin analoge Sensorsignale(Gyro, Beschleunigung und 
Kraft) über den MC zu wandeln und dann die digitalen Werte per UART über 
ein Bluetoothmodul an einen PC über einem virtuellen COM-Port zu senden 
(Anzeige der Daten via LabView Hyperterminal)und die Messwerte grafisch 
anzeigen zu lassen.

Das ganze funktioniert schon einwandfrei und bin mit den 100Hz 
zufreiden, aber mich hätte einfach interessiert ob es mit meinem Aufbau 
funktioniert das ganze noch schneller zu bekommen.

Der Mikrocontroller ist an einem 16MHz Quarz. Bluetoothmodul/Atmega16 
und Hyperterminal laufen mit ner Baudrate von 115200.

VG

von San L. (zwillingsfreunde)


Lesenswert?

Piet schrieb:
> mein Vorhaben liegt darin analoge Sensorsignale(Gyro, Beschleunigung und
> Kraft) über den MC zu wandeln und dann die digitalen Werte per UART über
> ein Bluetoothmodul an einen PC über einem virtuellen COM-Port zu senden
> (Anzeige der Daten via LabView Hyperterminal)und die Messwerte grafisch
> anzeigen zu lassen.

Dafür gibt es fertige Sensoren wie bspw. ein MPU6050. Da kannst du die 
Daten bequem per SPI auslesen, je nachdem sogar Fusioniert.

von uwe (Gast)


Lesenswert?

> Bluetoothmodul
Und kann das Ding mehr als 115kBaud?

von hm (Gast)


Lesenswert?

uwe schrieb:
>> Bluetoothmodul
> Und kann das Ding mehr als 115kBaud?

Wieso überrascht dich sowas? Die meisten gehen bis 921kBaud...

von Bastler (Gast)


Lesenswert?

Um die Messwerte einigermassen zeitäquidistant zu halten, würde ich 
zuerst jeweils alle 8 Kanäle wandeln, die 8 Messwerte zwischenspeichern 
und nach der Messung aller 8 Kanäle erst über die Schnittstelle 
schicken. Dann das Ganze von vorne.

von bal (Gast)


Lesenswert?

Dietrich L. schrieb:
> (10 Bits je UART-Zeichen * 16) / 1ms = 160 kBaud

Mit 115,2 kBaud übertrage ich 11,52 Byte pro Millisekunde.
Wieso brauchst du also 160 kBaud, um 2 Bytes pro ms übertragen zu 
können?

von uwe (Gast)


Lesenswert?

> Wieso überrascht dich sowas? Die meisten gehen bis 921kBaud...
Wieso überraschen? Das war ne einfache Frage...

von hm (Gast)


Lesenswert?

uwe schrieb:
> Wieso überraschen? Das war ne einfache Frage...

Interpretationsfehler. :P Nicht immer einfach alles so zu verstehen wie 
es gemeint ist wenn man dem Menschen nicht ins Gesicht schauen kann und 
die Stimmlage nicht hört ;P Sry!

von Dietrich L. (dietrichl)


Lesenswert?

bal schrieb:
> Dietrich L. schrieb:
>> (10 Bits je UART-Zeichen * 16) / 1ms = 160 kBaud
>
> Mit 115,2 kBaud übertrage ich 11,52 Byte pro Millisekunde.
> Wieso brauchst du also 160 kBaud, um 2 Bytes pro ms übertragen zu
> können?

Piet hat doch 8 Messwerte, die er jede ms übertragen wollte:

Piet schrieb:
> 8 Spannungswerte zwischenspeichern und ca 100 Messwerte alle 100ms
>  per RS232 ausgeben.

Allerdings kann man das auch anders verstehen. Aber Piet hat die 
Rechnung nicht reklamiert, also will er wohl wirklich 8 * 100 Messwerte 
alle 100ms übertragen.

Gruß Dietrich

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.