Eigentlich ist mein Problem ganz einfach:
Wie bekomme ich signed 24 Bit über SPI aus einem ADC über einen 32Bit µC
(SAM4S) am sparsamsten über eine UART schnittstelle verschickt?
a) Zur Frage wie die daten sinnvoll in eine signed 32 bit variable
umzuwandeln sind habe ich bereits das hier gefunden...
Beitrag "24 bit signed in einer 32bit variablen?"
Die shifts mache ich bisher ähnlich (jedoch ohne ausdrücklichen 32 bit
cast der buffer-elemente. Ist das hier WICHTIG?):
1
uint8_tSPIbuffer[3];// Hier liegen die empfangenen signed 24 Bit
Bezüglich der Abfrage des Vorzeichenbits des MSB der 24bit daten ergibt
sich bei mir allerdings ein Fragezeichen. Im Post oben prüft holger
(hier übertragen auf mein Beispiel) bit D7 vom MSB (bei mir in
buffer[0]) und setzt daraufhin bits 31:24 zu 1 und castet danach die
uint32 auf eine int32.
1
if(buffer[0]&0x80)temp|=0xFF000000;
2
int32_ttemp2=(int32_t)temp;
Wenn ich nun aber die obersten 8 bit einer signed 32bit variablen zu 1
setze, bekomme ich zwar das Vorzeichen - aber doch auch eine viel
größere Zahl!? Müsste ich nicht eigentlich nur bit 31 für das Vorzeichen
zu 1 setzen und den rest zu 0, damit die Zahl die selbe bleibt?
Teil b) der Frage: Ich schicke nun mit recht hoher durchlaufrate viele
dieser messpunkte über uart (Bluetooth). Eigentlich wäre es
wünschenswert, die Daten im ASCII format (printf) zu schicken (höherer
overhead aber dafür direkt aus der konsole auslesbar) - hier würde ich
mir natürlich gerne das eine Byte pro übertragung sparen, das ich nur
wegen der notwendigen 32bit breite auf dem Controller hinzugefügt habe.
Gibt es dazu Ideen?
Alex V. L. schrieb:> hier würde ich> mir natürlich gerne das eine Byte pro übertragung sparen, das ich nur> wegen der notwendigen 32bit breite auf dem Controller hinzugefügt habe.> Gibt es dazu Ideen?
kann denn der Controller keine 8bit zahlen? Einfach 3bytes wie sie vom
SPI kommen per uart weiter senden. Dafür brauchst du gar nichts rechnen
und sparst auch noch 1byte.
Peter II schrieb:> kann denn der Controller keine 8bit zahlen? Einfach 3bytes wie sie vom> SPI kommen per uart weiter senden. Dafür brauchst du gar nichts rechnen> und sparst auch noch 1byte.
Doch kann er. Ich möchte aber auf dem µC noch mit den Daten rechnen und
will dann gerne betitelte pakete schicken - wie gesagt auch mit der
option ASCII, so dass man die daten in der konsole direkt lesen kann..
Alex V. L. schrieb:> Doch kann er. Ich möchte aber auf dem µC noch mit den Daten rechnen und> will dann gerne betitelte pakete schicken - wie gesagt auch mit der> option ASCII, so dass man die daten in der konsole direkt lesen kann..
du kannst halt nicht beides haben, entweder versendet du nur 3byte
(+datenprotokoll) wie du sie auch per SPI bekommst - oder du sendest
ASCII dafür aber teilweise mehr als 10byte.
Alex V. L. schrieb:> Die shifts mache ich bisher ähnlich (jedoch ohne ausdrücklichen 32 bit> cast der buffer-elemente. Ist das hier WICHTIG?):
Ohne den Cast wird der Shift mit (signed) int durchgeführt. Das dürfte
in deinem Fall passen. Auf einem 16-Bit-Controller wäre es aber falsch.
> Bezüglich der Abfrage des Vorzeichenbits des MSB der 24bit daten ergibt> sich bei mir allerdings ein Fragezeichen. Im Post oben prüft holger> (hier übertragen auf mein Beispiel) bit D7 vom MSB (bei mir in> buffer[0]) und setzt daraufhin bits 31:24 zu 1 und castet danach die> uint32 auf eine int32.
Klingt plausibel. Nennt sich "sign extension".
http://en.wikipedia.org/wiki/Sign_extension> Wenn ich nun aber die obersten 8 bit einer signed 32bit variablen zu 1> setze, bekomme ich zwar das Vorzeichen - aber doch auch eine viel> größere Zahl!?
Nein, zmindest nicht, wenn du im Zweierkomplement rechnest. Gehen wir
mal von 8 Bit aus. Was kommt raus, wenn du von 0 den Wert 1 abziehst?
Das Ergebnis ist das Bitpattern 11111111. Und als vorzeichenbehaftete
Zahl im Zweierkomplement ist das der Wert -1. Was passiert nun, wenn die
Zahl 16 Bit breit ist? Dann ist das Pattern für -1 eben
1111111111111111. Was muß ich also tun, wenn ich eine 8-Bittige -1 auf
16 Bit erweitern will?
> Teil b) der Frage: Ich schicke nun mit recht hoher durchlaufrate viele> dieser messpunkte über uart (Bluetooth). Eigentlich wäre es> wünschenswert, die Daten im ASCII format (printf) zu schicken (höherer> overhead aber dafür direkt aus der konsole auslesbar) - hier würde ich> mir natürlich gerne das eine Byte pro übertragung sparen, das ich nur> wegen der notwendigen 32bit breite auf dem Controller hinzugefügt habe.> Gibt es dazu Ideen?
Nun, wenn du es als Text überträgst, ergibt sich die Größe doch eh ganz
anders. Also "das eine Byte" sparen kannst du nur, wenn du es auch als
eigenes Byte überträgst.
Alex V. L. schrieb:> Wie bekomme ich signed 24 Bit über SPI aus einem ADC über einen 32Bit µC> (SAM4S) am sparsamsten über eine UART schnittstelle verschickt?
Ich finde nirgends an was du sparen willst.
Ist es Strom, Taktfrequenz, Registerbreite, Variablenbreite,
Speicherplatz, Anzahl der Variablen, Anzahl der übertragenen
Bytes oder Zeit oder was?
Danke für deine Erläuterungen Rolf!
Mitlesa schrieb:> Ich finde nirgends an was du sparen willst.
Ich habe nur begrenzte Bandbreite zur Verfügung. Das Bluetoothmodul kann
max 560kbps, wenn ich mit 115kbps hinkäme, wäre das aber besser.
Die Antwort ist also Anzahl der zu übertragenden Bytes (und damit auch
strom). Klar ist dabei: Als text übertragen wäre nett, im Notfall geht
es natürlich auch roh.
Alex V. L. schrieb:> Ich habe nur begrenzte Bandbreite zur Verfügung. Das Bluetoothmodul kann> max 560kbps, wenn ich mit 115kbps hinkäme, wäre das aber besser.
wenn man jetzt noch wüsste, wie oft du diese 24bit Daten übertragen
musst. Und was sonst noch übertragen werden soll, könnte man sogar
weiterhelfen.
Ich wollte euch die Informationen gar nicht vorenthalten, weil ich die
mathe ja selber machen kann - aber auch noch nicht festgelegt bin, wie
meine paketstruktur genau aussehen soll:
MINDESTENS vorhanden sind in jedem fall:
4 x 24 Bit (32 Bit) ADC daten +32 bit zeitstepmpel mit 1kSPS
2 x 24 Bit (32 Bit) ADC daten +32 bit zeitstepmpel mit 100SPS
3 x 12 Bit (16 Bit) ADC daten +32 bit zeitstepmpel mit 200SPS
Das sind ja schonmal 185600 kbit/s. Damit ist natürlich auch die
115kBaud-hoffnung von oben hinfällig... Ob ich aber auf dem µC noch
mittele für besseres SNR und mit weniger SPS (z.B: 500, 50, 100)
übertrage ist zB auch noch offen und möglich.
Paketinformationen (ChannelNummer, Config etc: ca. 16 Bit/Übertragung)
Mindestens, weil alle Sampleraten konfigurierbar sind und das oben die
Mindestanforderungen sind.
Schön wäre eben gewesen, als Text Pakete mit CH1: XXXX, Ch2: XXXX, ...
Time: XXXX verschicken zu können, die man seriell direkt aufnehmen
kann...
Eine andere Frage: Kennt sich jemand mit der Cortex M4 Architektur genug
aus um UNGEFÄHR abschätzen zu können wie viel tics so eine einzelne sign
extension wie unten kostet?
Alex V. L. schrieb:> wie viel tics so eine einzelne sign> extension wie unten kostet?
Einen Takt. Der Cortex M4 hat einen entsprechenden Befehl dafür. Kann
aber sein, dass ein Compiler den nicht immer automagisch benutzt.
Na das wäre ja klasse! Naja ich würde mal hoffen, dass AVRStudio 6 mit
ARM/GNU C Compiler die eigenen (SAM4S) Befehle kennz und benutzt...
Die Frage ist: Gibt es dann nicht auch einen C sign-extension befehl -
oder ist der compiler so klug aus meinem code oben das richtige
abzuleiten?
Mir ist noch nicht klar, wofür du die Sign-Extension brauchst?! 24 Bit
ergeben eine integer Zahl mit 8 signifikanten Stellen. Du musst also
statt 3 byte AD Werte 8 Byte Text übertragen. Das scheint mir bei deiner
Abschätzung der Datenübertragungsraten nicht möglich zu sein. Nur in
diesem Fall müsstest du die 3 Byte (inklusive Sign-Extension) in einen
String umwandeln.
Wenn du aber sowieso die Rohdaten schicken musst solltest du die 3 Byte
schicken und sie nicht erst in 32 bit umrechnen. Das muss dann halt das
empfangende Programm machen.
Gerhard
Gerhard Z. schrieb:> Mir ist noch nicht klar, wofür du die Sign-Extension brauchst?!> Gerhard
Du hast mit deinen Aussagen recht Gerhard!
Sollte ich aber vor dem Senden der daten noch auf dem µC
Verarbeitungsschritte vornehmen, wie z.B. einen gleitenden Mittelwert
o.Ä., wäre es schon sinnvoll jeden ADC channel in einer signed variablen
und nicht als 8 bit pakete zu haben. Deshalb die sign extension.
Bezüglich der Datenraten habe ich inzwischen jetzt auch eingesehen, dass
Text schicken da keinen Sinn macht. Getestet habe ich es auch - bei
115kbaud/s bekomme ich bei meinen paketgrößen (als text) momentan gerade
so eine samplerate von 50Hz gestemmt...
dein 32bit Zeitstempel ist etwas ungünstig. Hier könnte man besser
optimieren. In dem man regelmäßig die Zeit in Sekunden überträgt und
dazwischen nur die Millisekunden.
Wenn du CPU noch genug zeit hat, könnte man auch über eine Komprimierung
der Daten nachdenken.
Peter II schrieb:> dein 32bit Zeitstempel ist etwas ungünstig. Hier könnte man besser> optimieren. In dem man regelmäßig die Zeit in Sekunden überträgt und> dazwischen nur die Millisekunden.
das stimmt, danke für den hinweis!
Peter II schrieb:> Wenn du CPU noch genug zeit hat, könnte man auch über eine Komprimierung> der Daten nachdenken.
den gedanken hatte ich auch schon- mit komprimierung allerdings keine
erfahrung. Letztendlich fällt es mir derzeit noch schwer abzuschätzen
wie viel zeit die cpu hat.
Eigentlich müsste sie (auf 120MHz coreclock) noch hoffnungslos
unterfordert sein, weil außer den o.g. daten aus dem SPI schaufeln und
in den UART buffer schieben im "running" mode nichts weiter läuft als
mit den niedrig gesampelten daten noch ein bisschen averaging und
sortieren.
Lässt sich z.B. über den debugger von AVR Studio 6 oder auf anderem wege
ungefähr abschätzen wie ausgelastet so ein prozessor mit dem aktuellen
code gerade ist?
Jim Meba schrieb:> Alex V. L. schrieb:>> wie viel tics so eine einzelne sign>> extension wie unten kostet?>> Einen Takt. Der Cortex M4 hat einen entsprechenden Befehl dafür. Kann> aber sein, dass ein Compiler den nicht immer automagisch benutzt.
Der hat einen eigenen Befehl für eine Sign-Extension von 24 Bit auf 32
Bit?
Alex V. L. schrieb:> Lässt sich z.B. über den debugger von AVR Studio 6 oder auf anderem wege> ungefähr abschätzen wie ausgelastet so ein prozessor mit dem aktuellen> code gerade ist?
Was macht der Prozessor denn, während er nicht die von dir beschriebenen
Tätigkeiten durchführt? Wenn du ermittelst, wieviel seiner Zeit er dort
verbringt, dann weißt du auch, wie ausgelastet er ist.