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?
Gäst_5 schrieb: > Was muss ich tun? wenn du ein int sendest, solltest du auch ein int lesen und kein char* außerdem musst du beachten das ein int auf dem atmel 2byte ist und auf den Raspi 4byte. Dazu kommt noch eventuell ein Big/Little Endian problem.
> 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.
Gäst_5 schrieb: > Woher weiß denn der Pi das ich einen Int gesendet habe? gar nicht aber du kannst es einfach als int lesen so wie du es einfach als int sendest. senden: fwrite(&c, sizeof(uint16_t), 1, f); lesen: fread(&c, sizeof(uint16_t), 1, f);
> 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.
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.
> 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 ;-)
Gäst_5 schrieb: > genau das mache ich auch und da wären wir wieder bei meiner > ursprünglichen Frage angelangt ;-) habe ich doch, wenn lies doch einfach in ein int ein und nich in ein char.
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.
wenn ich dies ändere: int rx_header_buffer; read(uart0_filestream, &rx_header_buffer, sizeof(int)); stützt das Programm ab...
Übertrag deine Werte als Ascii: + Leicht les- und debugbar + Plattformunabhängig + Mit jedem terminal-Programm empfangbar (Screen, minicom, Putty, ...) - mehr Bytes zu übertragen - itoa-Methode am AVR benötigt Oder zumindest in Netzwerk-Byteorder (htons, ntohs)
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)
> 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?
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?
Εrnst B✶ schrieb: > Übertrag deine Werte als Ascii: das ist für einen Anfänger sowieso das Beste, bis er die ganzen Untiefen von Byteorder, Protokoll und Timeout durchschaut hat.
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.
> - 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)
>> Ü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?
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)
> (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?
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.
> 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?
Gäst_5 schrieb: > fwrite(&c, sizeof(uint32_t), 1, f); > Trotzdem stürzt das Programm ab. dann zeige uns ein vollständiges Programm, das wir sehen was du machst.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.