Datentyp Formatierung

Gast #3162414
Lesenswert?

Hallo,

ich habe folgendes Problem:

Ich sende vom ATmega:

c = 55;
fwrite(&c, sizeof(uint16_t), 1, f);

an einen RaspberryPi und lese dort mit:

char    rx_header_buffer [4] = {0};
read(uart0_filestream, rx_header_buffer, 2);


Nach einem

printf("%i ... %i \n", rx_header_buffer[3],...,rx_header_buffer[0])

erscheint folgendes auf der Konsole:

0 0 0 55

D.h. die 55 wurde richtig übertragen und befindet sich nun in einem 
Array aus 4 Char Typen, also in 32 Bit.

Nun möchte ich mit dieser Zahl ganz normal weiter arbeiten:

z.B. so:
if (rx_header_buffer == 55){ printf("Ja");}

oder so:
printf("Data Size: %s \n", rx_header_buffer);


Leider funktioniert das nicht so wie ich mir das denke.

Was muss ich tun?
Gast #3162489
Lesenswert?

> wenn du ein int sendest, solltest du auch ein int lesen und kein char*

Woher weiß denn der Pi das ich einen Int gesendet habe? Die Daten kommen 
doch über den UART und werden Bit für Bit übertragen.
Die obige read Funktion liest 2 Byte und schreibt sie in 
rx_header_buffer.

Wenn ich nun folgendes probiere:

int    rx_header_buffer;
read(uart0_filestream, rx_header_buffer, 2)

Kommt folgender Fehler:
invalid conversion from 'int' to 'void*' [-fpermissive]

> außerdem musst du beachten das ein int auf dem atmel 2byte ist und auf
> den Raspi 4byte.

Das ist richtig.
Mit:
fwrite(&c, sizeof(uint16_t), 1, f);
sende ich 2 Byte vom ATmega zum Pi.

Mir ist auch noch nicht so richtig klar, wie ich das Zahlen bzw. Werte 
senden am besten mache.
- dachte als Zeichen dauert zu lang, weil ich ja dann für z.B. 55 16-Bit 
brauch.

>Dazu kommt noch eventuell ein Big/Little Endian problem.

Noch nie gehört.. ich google mal.
Gast #3162573
Lesenswert?

> fread(&c, sizeof(uint16_t), 1, f);

Geht leider nicht, da fread eine Highlevel Funktion ist und ein File 
benötigt.

Für den Pi verwende ich aber:
uart0_filestream = open(UART, O_RDWR | O_NOCTTY);

Ich habe somit kein FILE sondern einen Int-Wert.
Gast #3162576
Lesenswert?

Gäst_5 schrieb:
>> fread(&c, sizeof(uint16_t), 1, f);
>
> Geht leider nicht, da fread eine Highlevel Funktion ist und ein File
> benötigt.
>
> Für den Pi verwende ich aber:
> uart0_filestream = open(UART, O_RDWR | O_NOCTTY);
>
> Ich habe somit kein FILE sondern einen Int-Wert.

dann verwende read. Das geht doch dort genauso.
#3162603
Lesenswert?

Gäst_5 schrieb:
>> dann verwende read. Das geht doch dort genauso.
>
> genau das mache ich auch und da wären wir wieder bei meiner
> ursprünglichen Frage angelangt ;-)

Und die Antwort ist immer noch die gleiche.
Der Empfänger kann nicht a priori wissen, wieviele Bytes kommen werden 
und welcher Datentyp da dahinter steckt.
Es sei denn, es gibt eine Absprache zwischen Sender und Empfänger. Diese 
Absprache muss der Programmierer in Code umsetzen. Wie auch immer diese 
Absprache auch aussieht. Und bei rein binärer Datenübertragung landet 
man dann oft bei dem Problem, dass der Empfänger eine Möglichkeit 
braucht, wie er reine Nutzdaten von Steuerdaten unterscheiden kann. Denn 
den Bytes sieht man nicht an, was sie sind.
#3162622
Lesenswert?

Gäst_5 schrieb:
> wenn ich dies ändere:
>
> int     rx_header_buffer;
> read(uart0_filestream, &rx_header_buffer, sizeof(int));
>
> stützt das Programm ab...

Ist ein int auf deinem Pi 2 Bytes groß?


Genau aus dem Grund sind die später eingeführten Datentypen wie

int16_t   oder
uint16_t

so nützlich. Das steht drauf, wieviele Bits es sind (und damit wieviele 
Bytes)
Gast #3162626
Lesenswert?

> Ist ein int auf deinem Pi 2 Bytes groß?

nein, 4.

Aber wo liegt das Problem, dass es gleich abstürzt?
Wenn die Int Datei vom ATmega 2 Byte ist, sollte der PI diese doch 
trotzdem in die ersten 2 Byte des 4-Byte Int Typs des Pi schaffen, oder?
#3162628
Lesenswert?

Karl Heinz Buchegger schrieb:

> Ist ein int auf deinem Pi 2 Bytes groß?

um das näher auszuführen:
ein int ist NICHT auf allen Computern gleich groß!

Der Datentyp int ist gedacht als die "Leib und Magenspeise" einer CPU. 
Das womit sie am leichtesten zurecht kommt, und man trotzdem noch 
einigermassen vernünftig rechnen kann.
Auf einem AVR ist ein int 2 Bytes (also 16 Bit) groß. Auf einer 32-Bit 
CPU ist ein int aber meistens 4 Bytes groß (also 32 Bit). Wo sollen denn 
auf der UART Übertragung plötzlich 2 zusätzliche Bytes herkommen, wenn 
der Sender nur 2 Bytes wegschickt, der Empfänger aber auf 4 Bytes 
wartet?
Gast #3162634
Lesenswert?

Mal ein zwischenzeitliches Danke für die Hilfe! :-)

> Wo sollen denn
> auf der UART Übertragung plötzlich 2 zusätzliche Bytes herkommen, wenn
> der Sender nur 2 Bytes wegschickt, der Empfänger aber auf 4 Bytes
> wartet?

Okay, ich dachte dann ist der Rest einfach irgendwelcher Mist der dem 
Filestream entnommen wird.

Ich habe nun folgendes geändert und schick dem Pi 32 Bit:

fwrite(&c, sizeof(uint32_t), 1, f);

...unverändert stürzt es ab.
#3162637
Lesenswert?

> - dachte als Zeichen dauert zu lang, weil ich ja dann für
> z.B. 55 16-Bit brauch.

Und? Wieso ist das ein Problem?

(In Wirklichkeit sind für "55" 3 Bytes zu übertragen, weil du ja auch 
noch eine Endekennung brauchst, an der der Empfänger erkennen kann, dass 
jetzt nichts mehr kommt und die Zahl in Textform vollständig vorliegt. 
Aber auch dann ist das noch kein Problem, es sei denn man will ein Video 
von einem Rechner zum anderen Streamen oder muss 4 Gigabyte übertragen. 
Um die Aussentemperatur von A nach B zu schicken, spielt das aber sowas 
von überhaupt keine Rolle)
Gast #3162641
Lesenswert?

>> Übertrag deine Werte als Ascii:

Das Projekt soll aber darauf hinauslaufen, dass ich viele Messwerte 
schnell vom ATmega an den Pi übertragen will.

Habt ihr dafür Ratschläge, wie ich das am besten anstelle?
Ich habe auch noch nirgends rausgefunden, wie groß dieser UART RX-FIFO 
Speicher im Pi ist.
Was passiert denn wenn ich dem Pi über den UART 1000 Zeichen schicke, 
und sie 30 sek. später erst von dem FIFO Speicher nehme?
Wie viele Byte kann der maximal Fassen?
Gast #3162659
Lesenswert?

Gäst_5 schrieb:
> Was passiert denn wenn ich dem Pi über den UART 1000 Zeichen schicke,
> und sie 30 sek. später erst von dem FIFO Speicher nehme?
> Wie viele Byte kann der maximal Fassen?

warum solltest du das machen. so ein RaSpi ist doch so schnell das man 
ein paar tausend mal pro sekunden abfragen kann. Mach dir darüber 
erstmal keine sorgen. (Du solltest das abfragen in einem eigenen thread 
machen damit er nicht ausgebremst wird und dann die daten selber 
puffern)
Gast #3162676
Lesenswert?

> (Du solltest das abfragen in einem eigenen thread
> machen damit er nicht ausgebremst wird und dann die daten selber
> puffern)

Ich hab mir dazu folgendes überlegt:

Der Pi sendet dem ATmega ein Zeichen oder String und fordert ihn damit 
auf, die Anzahl der anstehenden Messwerte, quasi als Header des 
Datenstromes, und sofort anschließend die Messwerte zu übertragen.

Mit der read Funktion im Pi kann ich festlegen wie viel vom Filestream 
gelesen wird um dann mit Hilfe der Anzahl, die ich anfangs als Header 
übertragen habe, die kompletten Daten individuell lesen zu können.

Anschließend will ich die Daten dann in einem File auf der SD Karte des 
Pi ablegen.

Könnte das so klappen?
Gast #3162686
Lesenswert?

Gäst_5 schrieb:
> Könnte das so klappen?

ja, sehe dabei kein Problem. Du musst nur auch damit rechnet das Zeichen 
verloren gehen (und wenn nur jemand dem atmel resettet). Also musst ein 
sinnvolles Timeout einbauen. Und wenn du 100% sicher gehen willst das 
alles richtig übertragen ist. Dann solltest du nach den Messwerten noch 
eine Prüfsumme übertragen.
Gast #3162704
Lesenswert?

> ja, sehe dabei kein Problem

Und wie sollte ich diese ganze Messwerte übertragen?
Dachte als Zeichen wird es insgesamt zu viel und damit dann zu langsam.

Somit wollte ich die einzelnen Messwerte als Int übertragen.

Und damit stehen ich wieder vor dem Problem, was ich immer noch nicht in 
den Griff bekommen habe.

Wenn in dem RX FIFO-Speicher des Pi nur 16 Bit liegen, ich mit

read(uart0_filestream, &rx_header_buffer, sizeof(int));

aber 32 Bit einlesen möchte, meint Karl Heinz Buchegger das dies zum 
Absturzt führt.
Nun sende ich aber 32 Bit, können ja auch mehr sein, mit:

fwrite(&c, sizeof(uint32_t), 1, f);

Trotzdem stürzt das Programm ab.

Woran liegt das?

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