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.




Antwort per Email an