Hallo,
momentan habe ich ein Problem beim Lesen von der RS232 Schnittstelle.
Mit meinem Raspberry Pi habe ich einen TCP Server erstellt, welcher die
Daten von einem C# Programm per Ethernet empfängt und diese anschließend
über die RS232 Schnittstelle (MAX232 dazwischen) an ein Funkgerät
(Elecraft K3) weiterreicht.!
Ziel ist es das Funkgerät von dem Internet fernsteuern zu können.
Befehle zum Funkgerät senden funktioniert.
Mit dem String "IF;" sollten sich die eingestellten Parameter
zurücklesen lassen, dies funktioniert nicht, obwohl die Daten auf der
Leitung zurückgesendet werden (mit Oszi geschaut).
Zusätzlich stürzt mein Programm nachdem uart_read benutzt wurde ab - es
zeigt sich keinerlei Reaktion mehr und das C# Programm erkennt, dass die
Socket Verbindung nicht mehr vorhanden ist.
1
/* A simple server in the internet domain using TCP
// printf("Nachricht von RS232 Schnittstelle: %s\n", rs232_buffer);
138
//write(sock,rs232_buffer,255); //Write Rs232 Message to TCPIP
139
}
140
141
bzero(tcpip_buffer,256);
142
rs232_buffer=NULL;
143
}
144
}
145
146
147
148
149
150
151
152
153
154
intuart_init(void)
155
{
156
intuart0_filestream=-1;
157
158
159
//-------------------------
160
//----- SETUP USART 0 -----
161
//-------------------------
162
//At bootup, pins 8 and 10 are already set to UART0_TXD, UART0_RXD (ie the alt0 function) respectively
163
//OPEN THE UART
164
//The flags (defined in fcntl.h):
165
// Access modes (use 1 of these):
166
// O_RDONLY - Open for reading only.
167
// O_RDWR - Open for reading and writing.
168
// O_WRONLY - Open for writing only.
169
//
170
// O_NDELAY / O_NONBLOCK (same function) - Enables nonblocking mode. When set read requests on the file can return immediately with a failure status
171
// if there is no input immediately available (instead of blocking). Likewise, write requests can also return
172
// immediately with a failure status if the output can't be written immediately.
173
//
174
// O_NOCTTY - When set and path identifies a terminal device, open() shall not cause the terminal device to become the controlling terminal for the process.
175
176
177
system("sudo chmod a+rw /dev/ttyAMA0");
178
179
uart0_filestream=open("/dev/ttyAMA0",O_RDWR|O_NOCTTY|O_NDELAY);//Open in non blocking read/write mode
180
// uart0_filestream = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY); //Open in non blocking read/write mode
181
if(uart0_filestream==-1)
182
{
183
printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
184
}
185
186
//CONFIGURE THE UART
187
//The flags (defined in /usr/include/termios.h - see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html):
Der Fehler scheint momentan in der dostuff Funktion zu liegen
(Uart_read).
Sowohl Lesen mittels O_NDELAY als auch ohne, führt zu keinem Ergebnis.
Ich weiß nicht mehr weiter :(.
printf("Nachricht von TCP/IP Schnittstelle: %s\n",tcpip_buffer);
den String in tcpip_buffer mal so ausgeben
1
printf("Nachricht von TCP/IP Schnittstelle: #%s#\n",tcpip_buffer);
Hintergrund ist der, dass man sich vor bzw. nach dem eigentlichen String
ein Sonderzeichen einfügt, damit man im String Dinge wie Leerzeichen
bzw. Zeilenvorschübe sehen kann.
Die Ausgabe muss dann
1
...lle: #IF;#
sein. D.h. zwischen dem eigentlichen String und den Sonderzeichen dürfen
keine Leerzeichen sein.
1
...lle: # IF;#
So etwas
1
...lle: #
2
IF;#
würde darauf hindeuten, dass sich ein \n eingeschmuggelt hat. Genauso
wie bei
1
...lle: #IF;
2
#
All das sind Dinge, die man ansonsten bei einer Text-Ausgabe nur
allzuleicht übersieht. Daher Begrenzungen in die Ausgabe einfügen, so
dass man exakt sieht, wo der String beginnt und wo er endet. Auch die
zusätzliche Ausgabe der Stringlänge ist manchmal hilfreich, weil es auch
Zeichen gibt, die zwar im String enthalten sind, von einer normalen
Terminalausgabe aber nicht angezeigt werden.
Achja, der Fehler, welcher ausgegeben wird lautet:
error("UART Read: Error -1\n"); //An error occured (will occur if
there are no bytes)
Erscheint also wenn die read Funktion einen Wert <0 zurückgibt...
Aber warum stürzt das Programm anschließend ab?
Schonmal vielen Dank, Karl Heinz. Werde ich mich gleich darum kümmern.
Die Steuerkommandos wie z.B. IF kommen aber am Funkgerät an, da dieses
daraufhin mir die Daten zurücksendet. Die eine Richtung (senden)
funktioniert einwandfrei - lesen leider nicht :/.
Autor schrieb:> Schonmal vielen Dank, Karl Heinz. Werde ich mich gleich darum kümmern.
Vergiss es.
Ich liebe es, wenn die wensentlichen Informationen ganz am Ende eines
Postings kommen und erst mal am Anfang eine falsche Fährte gelegt wird.
Das macht das Fehlersuchen interessanter.
Autor schrieb:> Achja, der Fehler, welcher ausgegeben wird lautet:>> error("UART Read: Error -1\n"); //An error occured (will occur if> there are no bytes)>> Erscheint also wenn die read Funktion einen Wert <0 zurückgibt...
Das scheint nicht nur so, das ist auch so.
> Aber warum stürzt das Programm anschließend ab?
Sorg erst mal dafür, dass der Aufrufer einen ordentlichen String
zurückbekommt, wenn ein Fehler auftritt. SChliesslich kümmert sich dein
aufrufender Code einen Scheissdreck darum, dass irgendwas schief
gelaufen ist.
Und für den Rest hast du einen Debugger. Lerne damit umzugehen.
Sorry, ich hatte oben lediglich geschrieben, dass er nach Uart_Read
abstürzt.
Trotzdem war dein Tipp ganz gut, dadurch konnte ich zumindest schon
einmal ausschließen, dass nach IF; noch unnötige Zeichen gesendet werden
und dadurch vielleicht das Lesen blockiert wird. Dies scheint aber nicht
der Fall zu sein.
Die Antwort des Funkgerätes habe ich am aufgeknüpften Kabel feststellen
können - jetzt vermute ich aber langsam, dass das Problem hinter dem
Max232 liegen könnte. Also dass dieser das Signal nicht mehr
entsprechend weiterreicht.
Sagtest du nicht ganz am Anfang, dass deine RS232 getestet wäre?
Scheint wohl doch nicht so gut getestet zu sein.
Edit: Oh, sehe gerade im Eröffnungsposting, dass nur vom Senden zur
Funke sprichst. Was ist mit der Gegenrichtung? Hast du die erst mal
ebenfalls unabhängig von irgendwelchen TCP-IP Sachen getestet?
Ernsthaft: Schreib nie zu viel Code, zu viele Module auf einmal!
Du hängst eine Funke per RS232 an deinen Pi. Gut. Dann teste das auch.
Und zwar unabhängig von allem anderen. Denn was du auf keinen Fall haben
willst, das ist, dass du in deinem Programm 5 ungetestete
Module/Funktionalitäten hast, .. nichts funktioniert, ... und du hast
keinen Schimmer, welches der 5 Module dafür verantwortlich ist. Im
Idealfall hantelt man sich von einer funktinierenden Programmversion zur
nächsten hoch, indem man mit einem Trivialprogramm anfängt und dann
sukzessive Schritt für Schritt neue Funktionalität ergänzt. So behält
man die Kontrolle über Änderungen und welche Auswirkungen diese
Änderungen haben. Das kann auch heißen, eine gewisse Teilfunktionalität
erst mal unabhängig für sich alleine (mit einem eigenen Programm) zu
testen, ehe sie dann ins Programm eingebaut wird.
Also: Klär erst mal ab, ob du ein Hardware Problem hast. Dazu brauchst
du kein TCP/IP und keinen fork. Das sind alles nur Dinge, die die Sache
erst mal komplizierter machen als minimal notwendig, wenn es um die
Frage geht: kann ich mit meinem Funkgerät per RS232 kommunizeren, ja
oder nein?
Hinter dem Pegelwandler kommt auf der RXD Seite fast nur noch Peaks auf
der Leitung an. Vor dem Wandler ist das Signal noch in Ordnung. D.h.
für mich ich muss den Wandler nochmal neu aufbauen ... Ich hoffe dannach
funktioniert das ganze, ansonsten melde ich mich nochmal.
Wer misst, misst Mist....
Das Signal auf RXD Seite sieht nun nach sauberer Masseanzapfung doch in
Ordnung aus. Die Funktiono read scheint nicht zu funktionieren. Jemand
eine Idee? Der Rückgabewert der Funktion ist immer <1, egal ob ständig
daten gesendet werden...
Der MAX232 funktioniert nicht mit 3,3V Betriebsspannung. Wenn du ihn an
die 5V-Schiene des RPi angeschlossen hast, hast du den RX-Eingang der
seriellen Schnittstelle AMA0 geschossen. Der verträgt nämlich nur
3,3V-Signale.
Ich sehe keinen Unterschied zu meinen, funktionierenden, Code. Kann es
daran liegen, dass das System immer noch (Raspberry-Default) einen
Zugriff auf die serielle Schnittstelle hat?
In meinem "ProjektLog" steht dazu folgendes:
- enable serial interface for own use:
- run
nano /etc/inittab
- auskommentieren
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
- run
init q
Ich bin alles andere als ein Linux-Experte, aber bei mir läuft die
Schnittstelle in beiden Richtungen.
Autor schrieb:> Achja, der Fehler, welcher ausgegeben wird lautet:>> error("UART Read: Error -1\n"); //An error occured (will occur if> there are no bytes)
Du solltest Dich mal mit errno bzw. perror() beschäftigen. Dann bekommst
Du auch den Grund mitgeteilt, warum Du eine -1 zurückbekommst.
Erhältst Du auch den Error, wenn Du ohne O_NDELAY arbeitest?
Disable Serial Port Login:
To enable the serial port for the RPi-extension you need to disable
login on the port. There are two files that need to be edited.
The first and main one is /etc/inittab
This file has the command to enable the login prompt and this needs to
be disabled. Edit the file and move to the end of the file. You will see
a line similar to:
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
Disable it by adding a # character to the beginning.
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100</note>
Save the file.
Disable Bootup Info:
Disable it by editing the file /boot/cmdline.txt .
The contents of the file look like this:
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200
console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline
rootwait
Remove all references to ttyAMA0 (which is the name of the serial port).
The file will now look like this:
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4
elevator=deadline rootwait
Save the file.
Reboot
In order you enable the changes you have made, you will need to reboot
the Raspberry Pi:
sudo shutdown -r now
Daniel T. schrieb:> Ich sehe keinen Unterschied zu meinen, funktionierenden, Code. Kann es> daran liegen, dass das System immer noch (Raspberry-Default) einen> Zugriff auf die serielle Schnittstelle hat?>> In meinem "ProjektLog" steht dazu folgendes:>> - enable serial interface for own use:> - run> nano /etc/inittab> - auskommentieren> T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100> - run> init q>> Ich bin alles andere als ein Linux-Experte, aber bei mir läuft die> Schnittstelle in beiden Richtungen.
Das war der Fehler!
Vielen Dank! :)
Ich meine ich hatte in der Datei schon einen Teil auskommentiert, aber
dort gibt es leider zwei dieser Anweisungen :).
Was mich dabei wundert, der Schreibvorgang hat trotzdem funktioniert....
... schrieb:> Der MAX232 funktioniert nicht mit 3,3V Betriebsspannung. Wenn du ihn an> die 5V-Schiene des RPi angeschlossen hast, hast du den RX-Eingang der> seriellen Schnittstelle AMA0 geschossen. Der verträgt nämlich nur> 3,3V-Signale.
Den Pegelwandler habe ich von meinem Betreuer bekommen, war wohl ein
Max323, also schon der richtige. Mein Fehler - Sorry.