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
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
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
unsignedshortintArray[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.
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
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.
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
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...
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.
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
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
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.
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.
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?
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!
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