Forum: Mikrocontroller und Digitale Elektronik 24 bit signed data in 32 bit int (ARM SAMS4) und das sparsam über UART


von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

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_t SPIbuffer [3]; // Hier liegen die empfangenen signed 24 Bit
2
3
uint32_t temp = ((buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]));

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_t temp2 = (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?

von Peter II (Gast)


Lesenswert?

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.

von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

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..

von Peter II (Gast)


Lesenswert?

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.

von Rolf Magnus (Gast)


Lesenswert?

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.

von Mitlesa (Gast)


Lesenswert?

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?

von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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.

von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

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...

: Bearbeitet durch User
von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

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?
1
temp = ((uint32_t)buffer[18] << 16) | ((uint32_t)buffer[19] << 8) | buffer[20];
2
  if(buffer[18] & 0x80) temp |= 0xFF000000;
3
  measurement->ch6= (int32_t) temp;

von Jim M. (turboj)


Lesenswert?

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.

von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

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?

: Bearbeitet durch User
von Gerhard Z. (germel)


Lesenswert?

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

von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

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...

von Peter II (Gast)


Lesenswert?

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.

von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

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?

von ProtoBufUser (Gast)


Lesenswert?

Google Protobuf (komprimiert die daten)

https://github.com/google/protobuf

in der Embedded Version

http://koti.kapsi.fi/~jpa/nanopb/benchmark/

verwenden. :)

von Rolf Magnus (Gast)


Lesenswert?

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.

von Jim M. (turboj)


Lesenswert?

Rolf Magnus schrieb:
> Der hat einen eigenen Befehl für eine Sign-Extension von 24 Bit auf 32
> Bit?

Siehe SBFX Instruktion: 
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/BABIDBHE.html

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.