Re: Rückgabe von mehrdimensionalem String in C++
Tobias Schlemmer <[email protected]>
| Newsgroups | gmane.user-groups.linux.dresden |
|---|---|
| Message-ID | <[email protected]> |
Hallo Sebastian,
nutzt Du eine Hardware-UART? Dann solltest Du mal versuchen, die
High-Level-Funktionen zu nutzen. Das heißt in dem Fall ist es vermutlich
günstiger, Du gehst über den Linux-Treiber, genauso wie das minicom tut.
Das sollte ausreichend dokumentiert sein. Such einfach nicht nach Pi +
UART, sondern nach linux serial io. Ich würde mal vermuten, dass
gpioSerialRead eine Software-UART implementiert, das heißt, sie liest
das GPIO-Pin direkt und spielt selber UART.
Was Du nicht machen solltest, ist, Software-UART und Hardware-UART über
denselben Pin laufen zu lassen. Dann muss der Pin nämlich zwei Herren
dienen. Und jeder, der das mal versucht hat, weiß, dass es früher oder
später zu Konflikten führt. Grundsätzlich kann ein Pin zu jedem
Zeitpunkt maximal eine Funktion ausführen: GPIO oder UART oder ... (je
nachdem, was im Datenblatt steht).
Was auch nicht funktioniert: minicom und Dein Programm gleichzeitig auf
/dev/ttyS0 – oder was auch immer es ist – zuzugreifen. Die Datenströme
werden nicht dupliziert.
Eine Weitere Fehlerquelle besteht darin, wenn Du das ganze im Polling
betreibst und nicht im Interrupt. Wenn Dein Prozess aus irgendeinem
Grund zu spät aufwacht (und das ist meist erlaubt), dann kann es
passieren, dass der Empfangspuffer schon überschrieben wurde, bevor er
ausgelesen wurde (das sollte aber andere Probleme bringen). An der
Stelle solltest Du auch immer im Hinterkopf haben, dass Linux kein
Echtzeit-System ist.
Wie stellst Du sicher, dass das erste Zeichen im read_buf auch das erste
Zeichen einer neuen Zeile ist?
Wenn Du Kauderwelsch empfängst solltest Du davon ausgehen, dass die
Übertragung gestört war und warten, bis eine <Start of Record>-Nachricht
kommt (das ist hier in dem Fall gleich dem <End of Record> und wird
durch das Zeichen CR ausgedrückt).
Viele Grüße
Tobias
Am 14.05.22 um 22:13 schrieb Sebastian Reinhardt:
> Hallo zusammen,
> Ich sitze immer noch an meinem kleinen Programm und bin fast fertig.
> Ich habe mir in Anlehnung an Andreas Beispiele ein paar eigene
> Unterprogramme erstellt und kann nun die Vectordaten ordentlich
> auslesen. Auch habe ich einen Beispielcode von der PiGPIO- Webseite
> für das Auslesen eines Drehencoders, was auf dem "callback"- Prinzip
> basiert angepasst und noch den Druckschalter des Encoder und den
> Sensoreingang für den Ein-/Ausschalter zum Herunterfahren des PI
> hinzugefügt. Funktioniert ganz gut und ich kann nun das rudimentäre
> Menü bedienen.
>
> Leider verbleibt noch ein Problem:
> Ich lasse eine Schleife laufen, die per "gpioSerialRead" einen
> Ultraschallsensor am UART-Port abfragt. Es ist ein Maxbotics
> Sonar-Sensor, der nach Anlegen der Spannungsversorgung ohne weiteres
> Zutun auf der RX-Leitung den gemessenen Abstand sendet. Es wird immer
> "R123\CR" (R- Range, 123- 3-stelliger Wert in cm, \CR-
> Carriage-return) gesendet.
> Nun funktioniert meine Routine grundsätzlich, aber ich bekomme, wenn
> ich mir den "read_buff" ausgeben lasse immer wieder so was:R105��v5
> Je nach "Sleep"-Zeit in der Schleife verändert sich das und ich
> bekomme leere Antworten oder anderes "Kauderwelsch" oder auch nur
> Teile (z.B. "R1", "05R1" usw.) des 5-bit langen Wertes. Wenn ich zur
> gleichen Zeit mit "minicom -D /dev/serial0 -b 9600" auf den Sensor
> bzw. dessen Ausgabe ansehe, dann funktioniert das problemlos. Es muss
> also an meinem Code liegen!
>
> Auch mit Blick auf den Code des Drehencoders stellen sich mir nun mal
> wieder ein paar Fragen:
> 1. Liegt das an der zeitlichen Abstimmung des Auslesens meiner
> Schleife? Wie muss ich das auf die Baudrate von "9600" abstimmen?
> 2. Es kommen neue Werte nur mit Verzögerung (wenn ich z.B. meine Hand
> vor den Sensor halte), bei "minicom" nicht. Hab ich da ein Problem mit
> einem Puffer?
> 3. zu 2.: Kann ich den seriellen Puffer vor dem Lesen löschen, um
> immer nur "frische" Werte zu bekommen?
> 4. oder ist es besser, wenn ich das nicht mit einer "Endlosschleife"
> mache, sondern mit einer Callback-Funktion mache, die bei einem neuen
> Wert getriggert wird (aber wie könnte so was aussehen, beim Encoder
> wird das ja durch die Funktion "gpioSetAlertFuncEx" getriggert, wenn
> ich das richtig verstehe....)?
>
> Mein problematischer Code sieht so aus:
> ------------------------
> while( i < num_samples && j < num_samples + 50 )
> {
> memset(&read_buf, '\0', sizeof(read_buf));
> rx_stat_bytes = gpioSerialRead(RXD, read_buf,
> sizeof(read_buf));
>
> cout << " rx_stat: " << rx_stat_bytes << " readbuf: " <<
> sizeof(read_buf) << endl;
> cout << read_buf << endl;
>
> if ( rx_stat_bytes > 0 )
> {
> if( memcmp ( read_buf, "R",
> sizeof(read_buf) ) == 1 )
> {
> r_value.push_back(atoi(read_buf+1));
> i++;
> }
> }
> else
> {
> // printf("Sensor aus?\n");
> }
> j++;
> usleep(1000);
> }
> ------------------------
>
> Eine Ausgabe der cout-"debug"-Zeile ist:
> ----------------------
> rx_stat: 5 readbuf: 5
> ��v5
> rx_stat: 5 readbuf: 5
> ��v5
> rx_stat: 5 readbuf: 5
> ��v5
> rx_stat: 5 readbuf: 5
> ��v5
> rx_stat: 5 readbuf: 5
> ��v5
> rx_stat: 5 readbuf: 5
> ��v5
> rx_stat: 5 readbuf: 5
> ��v5
>
> rx_stat: 1 readbuf: 5
> R
> rx_stat: 3 readbuf: 5
> 105
> rx_stat: 1 readbuf: 5
>
> rx_stat: 5 readbuf: 5
> 8�v0
> rx_stat: 5 readbuf: 5
> 8�v0
> rx_stat: 5 readbuf: 5
> 8�v0
> rx_stat: 5 readbuf: 5
> 8�v0
> rx_stat: 5 readbuf: 5
> 8�v0
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 1 readbuf: 5
> R
> rx_stat: 0 readbuf: 5
>
> rx_stat: 1 readbuf: 5
> 1
> rx_stat: 1 readbuf: 5
> 2
> rx_stat: 1 readbuf: 5
> 0
> rx_stat: 1 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> rx_stat: 0 readbuf: 5
>
> r_value_mean:120
>
> ----------------------
>
>
> Das Blöde ist, das ich bis Montag 6.30Uhr dafür eine Lösung brauche,
> das dann Abgabe ist :-(
>
> Wäre schön, wenn ihr mich noch mal "erleuchten" könntet.
>
>