c++ Kommunikation mit externem Gerät
Hallo zusammen,
ich habe ein c++ Problem. Ich weiß nicht wie ich über einen seriellen Port (RS232) mit dem daran angeschlossenen Gerät kommunizieren kann.
Laufen soll das ganze unter:
KDE Version 3.5.5
Linux version 2.6.24.3
Debian 4.1.1-21
Machine: i686
Ich benutze dabei hauptsächlich KDE.
den Port initialisiere ich doch so:
nun sollte mm=-1 sein, wenn das öffnen nicht geklappt hat.
Wie sende ich nun Befehle an das Gerät?
In dessen Anleitung steht: Command Syntax:
yy::xxAAnn
yy - Controller address, in RS-232-C addressable mode
xx - Optional or required preceding
AA - Common mode
nn - some parameter
Wenn ich jetzt also z.B. den Befehl "2DA" an das Gerät schicken will - wie geht das?
Hat da jemand eine Idee oder weiß, wo ich sowas nachlesen kann?
ich habe ein c++ Problem. Ich weiß nicht wie ich über einen seriellen Port (RS232) mit dem daran angeschlossenen Gerät kommunizieren kann.
Laufen soll das ganze unter:
KDE Version 3.5.5
Linux version 2.6.24.3
Debian 4.1.1-21
Machine: i686
Ich benutze dabei hauptsächlich KDE.
den Port initialisiere ich doch so:
|
|
C/C++-Quelltext |
1 |
int mm=open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); |
nun sollte mm=-1 sein, wenn das öffnen nicht geklappt hat.
Wie sende ich nun Befehle an das Gerät?
In dessen Anleitung steht: Command Syntax:
yy::xxAAnn
yy - Controller address, in RS-232-C addressable mode
xx - Optional or required preceding
AA - Common mode
nn - some parameter
Wenn ich jetzt also z.B. den Befehl "2DA" an das Gerät schicken will - wie geht das?
Hat da jemand eine Idee oder weiß, wo ich sowas nachlesen kann?
danke fürs Lesen
Alludo Animali
Alludo Animali
naja du brauchst doch ein eingabefeld. ich habe mal unter windows ein c++ programm geschrieben welches über COM1 schnittstelle nach COM2 befehle sendet beide COM schnittstellen sind am PC gewesen und waren mit einem kabel überbrückt. du kannst hier mal nachschauen wie ich mit der schnittstelle verbinde und daten rüberschicke. vllt hilft dir das weiter
MFG
MFG
Mein kleines Projekt
-Cruel Online-
-Cruel Online-
RE: c++ Kommunikation mit externem Gerät
Hallo zusammen,
Wenn ich jetzt also z.B. den Befehl "2DA" an das Gerät schicken will - wie geht das?
Hat da jemand eine Idee oder weiß, wo ich sowas nachlesen kann?
|
|
C/C++-Quelltext |
1 2 |
char *szData = "2DA"; write( mm, szData, sizeof(szData)); |
Aktuell nutze ich: Windows, Linux, MacOS X, Solaris...weil die Welt nicht nur S/W ist!
Blog
Blog
RE: RE: c++ Kommunikation mit externem Gerät
![]()
C/C++-Quelltext
1 2 char *szData = "2DA"; write( mm, szData, sizeof(szData));
Vielen Dank, das werde ich demnächst probieren. Leider klappt das heute nicht mehr und dann bin ich eine Woche weg. Aber spätestens wenn ich wieder da bin werde ich das mal testen.
Wo kann ich denn die Eigenschaften dieser "open" und "write" Funktionen nachlesen? Ich finde das immernur für Files.
Wo kann ich denn die Eigenschaften dieser "open" und "write" Funktionen nachlesen? Ich finde das immernur für Files.
Wir lese ich denn dann die Antwort des Gerätes?
char antwort;
antwort=read(mm);
?
danke fürs Lesen
Alludo Animali
Alludo Animali
Ja, aber die Parameter für read sind ssize_t read(int fd, void *buf, size_t count);
Bei Kommunikation mit anderen Geräten sollte man bedenken, dass evtl. noch nicht alle Daten angekommen sind. "count" gibt die Anzahl der Bytes an, die du lesen möchtest.
Gibtst du für coutn 4 an, aber nur 3 befinden sich im Buffer, so gibt die Funktion z.B. -1 zurück.
Man könnte z.B. etwas in der Richtung machen ( Achtung: sehr schnelles und kurzes Beispiel, bitte Fehler richtig behandeln ):
Die obere Funktion ließt so lange den input buffer, bis sie zwei Byte erhalten hat. Anschließend wird der Kram ausgegeben
Nachlesen kann man das z.B. hier: http://linux.die.net/man/2/read
Bei Kommunikation mit anderen Geräten sollte man bedenken, dass evtl. noch nicht alle Daten angekommen sind. "count" gibt die Anzahl der Bytes an, die du lesen möchtest.
Gibtst du für coutn 4 an, aber nur 3 befinden sich im Buffer, so gibt die Funktion z.B. -1 zurück.
Man könnte z.B. etwas in der Richtung machen ( Achtung: sehr schnelles und kurzes Beispiel, bitte Fehler richtig behandeln ):
|
|
C/C++-Quelltext |
1 2 3 4 |
char *szAntwort = new char[3]; while( read( mm, szAntwort, sizeof(szAntwort)-1) <= 0 ) wait(100); cout << "Antwort: " << szAntwort << endl; |
Die obere Funktion ließt so lange den input buffer, bis sie zwei Byte erhalten hat. Anschließend wird der Kram ausgegeben
Nachlesen kann man das z.B. hier: http://linux.die.net/man/2/read
Aktuell nutze ich: Windows, Linux, MacOS X, Solaris...weil die Welt nicht nur S/W ist!
Blog
Blog
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »silence« (13. Mai 2009, 01:09)
Hi, also ich habe das nun folgendermaßen versucht:
Als Ausgabe wenn ich das Programm laufen lasse erhalte ich folgende Meldung:
Port RS232 has been sucessfully opened and 3 is the file description
Motor Status: Achse 1 ist -1
-1 ist der Wert, welchen "read()" im Falle eines Fehlers ausgibt.
Hat jemand eine Idee, woran das liegen könnte?
Das Gerät sollte einen ASCII Charakter zurückliefern.
|
|
C/C++-Quelltext |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
char *buffer; char pos1,pos2; char* szData; int main() { int rs232ali=open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); if (rs232ali == -1 ) { perror("open_port: Unable to open /dev/ttyS0 - "); } else { printf("Port RS232 has been sucessfully opened and %d is the file description\n",rs232ali); } szData="1MS"; write( rs232ali, szData, sizeof(szData)); pos1=read(rs232ali,buffer,10); printf("Motor Status: Achse 1 ist %d \n",pos1); close(rs232ali); } |
Als Ausgabe wenn ich das Programm laufen lasse erhalte ich folgende Meldung:
Port RS232 has been sucessfully opened and 3 is the file description
Motor Status: Achse 1 ist -1
-1 ist der Wert, welchen "read()" im Falle eines Fehlers ausgibt.
Hat jemand eine Idee, woran das liegen könnte?
Das Gerät sollte einen ASCII Charakter zurückliefern.
danke fürs Lesen
Alludo Animali
Alludo Animali
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Chenda« (19. Mai 2009, 09:22)
Du schickst etwas an ein Gegenstück ( write ) und versuchst sofort wieder zu lesen - read gibt -1 zurück, da es (noch) nichts zu lesen gibt.
D.h. read so lange aufrufen, bis etwas zurückkam.
D.h. read so lange aufrufen, bis etwas zurückkam.
Aktuell nutze ich: Windows, Linux, MacOS X, Solaris...weil die Welt nicht nur S/W ist!
Blog
Blog
Vielen Dank für deine Antwort,
aber ich habe auch einen anderen Befehl per write() geschickt, der an dem Gerät ein Lämpchen zum leuchten bringen sollte. Da tut sich jedoch nichts. Ich vermute, dass die Kommunikation nicht richtig initialisiert ist.
also zuerst irgendwie die richtige Baud Rate und parity setzen.
aber ich habe auch einen anderen Befehl per write() geschickt, der an dem Gerät ein Lämpchen zum leuchten bringen sollte. Da tut sich jedoch nichts. Ich vermute, dass die Kommunikation nicht richtig initialisiert ist.
also zuerst irgendwie die richtige Baud Rate und parity setzen.
danke fürs Lesen
Alludo Animali
Alludo Animali
schau mal paar beiträge weiter oben ich habe dort ein objekt angelegt und dann die baudrate und alles andere gesetzt und die kommunikation über RS232 schnittstelle ging wunderbar.
Mein kleines Projekt
-Cruel Online-
-Cruel Online-
schau mal paar beiträge weiter oben ich habe dort ein objekt angelegt und dann die baudrate und alles andere gesetzt und die kommunikation über RS232 schnittstelle ging wunderbar.
Du hast das aber mit der WinAPI gemacht, er muss aber ein Programm schreiben, das auf einem Unix-Unterbau fußt.
Btw, und ein Objekt wurde auch nicht angelegt *klugscheiß
*@Problem: Ich werde wohl vor morgen nicht nachschauen können, poste dann aber was.
Aktuell nutze ich: Windows, Linux, MacOS X, Solaris...weil die Welt nicht nur S/W ist!
Blog
Blog
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »silence« (20. Mai 2009, 17:34)
ja ich habe es unter WinApi erstellt aber sind die funktionen unter c++ nicht auf allen betriebssystemen gleich? ich meine eigentlich ist das einzige was er ändern muss wäre der pfad bei
hFile=CreateFile
oder ist jetzt HANDLE hFile und CreateFile nur in Borland C++ Compiler einsetzbar?
ach ja und kein Objekt stimmt da fehlt das = new usw..
hFile=CreateFile
oder ist jetzt HANDLE hFile und CreateFile nur in Borland C++ Compiler einsetzbar?
ach ja und kein Objekt stimmt da fehlt das = new usw..
Mein kleines Projekt
-Cruel Online-
-Cruel Online-
C++ und STL sind gleich, aber nicht die anderen Libs:
Sind z.B. reine WinAPI Strukturen (gibt es also nur unter Windows), CreateFile gibt es nur unter Windows, genauso wie CloseHandle, DWORD ist auch kein C/C++ Datentyp ( typedef unsigned long DWORD ), etc.
Kurzum, nichts von dem Code lässt sich auf anderen Systemen verwenden.
|
|
C/C++-Quelltext |
1 2 3 |
DCB sDcb; HANDLE hFile; COMMTIMEOUTS sTo; |
Sind z.B. reine WinAPI Strukturen (gibt es also nur unter Windows), CreateFile gibt es nur unter Windows, genauso wie CloseHandle, DWORD ist auch kein C/C++ Datentyp ( typedef unsigned long DWORD ), etc.
Kurzum, nichts von dem Code lässt sich auf anderen Systemen verwenden.
Aktuell nutze ich: Windows, Linux, MacOS X, Solaris...weil die Welt nicht nur S/W ist!
Blog
Blog
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »silence« (21. Mai 2009, 07:45)
Ich habe nun bisschen rumgemacht und das Programm wie folgt geändert:
Leider funktioniert die Kommunikation immernoch nicht.
Ich erhalte folgende Ausgabe:
Port RS232 has been sucessfully opened and 3 is the value of open()
folgender Befehl wird gesendet: 1TP
Bytes written: write_size=4
Error reading: Resource temporarily unavailable
Hat jemand eine Idee, woran das liegt? (Gerät angeschlossen und verbunden).
|
|
C/C++-Quelltext |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include <stdio.h> #include <string.h> #include <fcntl.h> #include <errno.h> #include <termios.h> #include <unistd.h> #include <iostream> #include <errno.h> using namespace std; char *buffer; char* szData; int write_size=0,read_size=0; int main() { int rs232ali=open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK); if (rs232ali == -1 ) { perror("open_port: Unable to open /dev/ttyS0"); } else { printf("Port RS232 has been sucessfully opened and %d is the value of open()\n",rs232ali); } szData="1TP"; cout<<"folgender Befehl wird gesendet: "<<szData<<endl; write_size=write( rs232ali, szData, sizeof(szData)); cout<<"Bytes written: write_size="<<write_size<<endl; if(write_size==-1) { printf( "Error writing: %s\n", strerror( errno ) );} read_size=read(rs232ali,buffer,10); if(read_size==-1) { printf( "Error reading: %s\n", strerror( errno ) );cout<<"Buffer= "<<buffer<<endl;} else {cout<<"Bytes read: read_size="<<read_size<<endl;printf("Position Achse1 = %d\n",buffer);} close(rs232ali); } |
Leider funktioniert die Kommunikation immernoch nicht.
Ich erhalte folgende Ausgabe:
Port RS232 has been sucessfully opened and 3 is the value of open()
folgender Befehl wird gesendet: 1TP
Bytes written: write_size=4
Error reading: Resource temporarily unavailable
Hat jemand eine Idee, woran das liegt? (Gerät angeschlossen und verbunden).
danke fürs Lesen
Alludo Animali
Alludo Animali
Liest du überhaupt, was ich schreibe?
Die Lösung für das Problem habe ich bereits in diesen Thread geschrieben...
Übringens, die Schnittstellenparameter ( Baudrate u.s.w. ) kannst du mit tcsetattr, diese müssen dann logischerweise mit dennen deines Gegenübers übereinstimmen.
Mal so aus reinem Interesse, ist das ein Hobby-Projekt, oder was Kommerzielles?
Die Lösung für das Problem habe ich bereits in diesen Thread geschrieben...
Übringens, die Schnittstellenparameter ( Baudrate u.s.w. ) kannst du mit tcsetattr, diese müssen dann logischerweise mit dennen deines Gegenübers übereinstimmen.
Mal so aus reinem Interesse, ist das ein Hobby-Projekt, oder was Kommerzielles?
Aktuell nutze ich: Windows, Linux, MacOS X, Solaris...weil die Welt nicht nur S/W ist!
Blog
Blog
read(rs232ali,buffer,10) <-- ich glaube das musste so schreiben
while(read(rs232ali,buffer,10))
{
usw..
}
EDIT:
hab den Beitrag von silence nicht gelesen
while(read(rs232ali,buffer,10))
{
usw..
}
EDIT:
hab den Beitrag von silence nicht gelesen
Mein kleines Projekt
-Cruel Online-
-Cruel Online-
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »cccpmik« (27. Mai 2009, 19:58)
|
|
C/C++-Quelltext |
1 |
while(read.....
|
sollte btw nicht funktionieren, da -1 in C zu wahr evaluiert, man könnte vielleicht was in Richtung
|
|
C/C++-Quelltext |
1 2 3 4 |
while(read(rs232ali,buffer,10) <= 0 ) { //n ms sleepen } //buffer enthält nun Daten |
Aktuell nutze ich: Windows, Linux, MacOS X, Solaris...weil die Welt nicht nur S/W ist!
Blog
Blog
Nein, sizeof(buffer) ergibt immer sizeof(void*), auf 32Bit System also 4, auf 64Bit System 8.
Was mir gerade auffällt: Wo wird eigentlich in Chendas Quelltext Speicher für buffer alloziiert?
Was mir gerade auffällt: Wo wird eigentlich in Chendas Quelltext Speicher für buffer alloziiert?
Aktuell nutze ich: Windows, Linux, MacOS X, Solaris...weil die Welt nicht nur S/W ist!
Blog
Blog
Liest du überhaupt, was ich schreibe?
Die Lösung für das Problem habe ich bereits in diesen Thread geschrieben...
Übringens, die Schnittstellenparameter ( Baudrate u.s.w. ) kannst du mit tcsetattr, diese müssen dann logischerweise mit dennen deines Gegenübers übereinstimmen.
Mal so aus reinem Interesse, ist das ein Hobby-Projekt, oder was Kommerzielles?
Ich lese was du schreibst, habe aber bisher hier keine Lösung gefunden bzw. etwas was mir weiterhilft.
Schreibe ich eine Schleife (in etwa so wie von dir vorgeschlagen), dann wird gewartet und gewartet und gewartet. Es kommt also nichts ->funktioniert nicht.
Die Baudrate habe ich mit setserial gesetzt und hoffe das dies funktioniert hat, da ich keine Fehlermeldung erhalten habe.
Die Kommunikation ist also noch nicht richtig initialisiert, oder der Befehlt (den ich per write an das Gerät schicke) wird nicht korrekt übermittelt / interpretiert.
PS: das ist kein kommerzielles Projekt.
danke fürs Lesen
Alludo Animali
Alludo Animali
Du schickst etwas an ein Gegenstück ( write ) und versuchst sofort wieder zu lesen - read gibt -1 zurück, da es (noch) nichts zu lesen gibt.
D.h. read so lange aufrufen, bis etwas zurückkam.
Ok dein Tipp war schon ganz gut, allerdings nicht auf die von dir vorgeschlagene Art - das hatte nicht funktioniert.
Ich habe das nun mal soweit geändert, dass ich ne Schleife gemacht habe, die nichts tut außer Zeit zu verbrauchen. Wenn ich den PC von 0 bis 10^6 zählen lasse erhalte ich immernoch die Fehlermeldung: strerror( errno )=Resource temporarily unavailable
Lasse ich den PC bis 10^7 zählen, dann ändert sich die Fehlermeldung: strerror( errno ) = Bad address
Wieso sagt der mit bad address?
Für diesen test habe ich die Pins (2 und 3) der seriellen Schnittstelle verbunden, s.d. der Befehl sofort wieder zurück gelesen werden sollte.
|
|
C/C++-Quelltext |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#include <stdio.h> #include <string.h> #include <fcntl.h> #include <errno.h> #include <termios.h> #include <unistd.h> #include <iostream> #include <time.h> using namespace std; char *buffer; char* szData; int write_size=0,read_size=0; int main() { int rs232ali=open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK); if (rs232ali == -1 ) { perror("open_port: Unable to open /dev/ttyS0"); } else { printf("Port RS232 has been sucessfully opened and %d is the value of open()\n",rs232ali); } szData="MR\n"; cout<<"folgender Befehl wird gesendet: "<<szData<<endl; write_size=write( rs232ali, szData, sizeof(szData)); if(write_size==-1) { printf( "Error writing: %s\n", strerror( errno ) );} else { cout<<"Bytes written: write_size="<<write_size<<endl;} for(int e=0;e<1e7;e++){} cout << "rs232ali = "<<rs232ali << endl; //read_size=read("/dev/ttyS0",buffer,10); read_size=read(rs232ali,buffer,10); if(read_size==-1) { printf( "Error reading: %s\nBuffer= %s\n", strerror( errno ),buffer);} else {cout<<"Bytes read: read_size="<<read_size<<endl;printf("Position Achse1 = %d\n",buffer);} close(rs232ali); } |
danke fürs Lesen
Alludo Animali
Alludo Animali
Ähnliche Themen
-
Hardware »-
Will mir einen neuen Multifunktionsdrucker zulegen, aber von welcher Marke? HP, Epson oder Canon
(16. September 2008, 21:32)
-
Chat & IRC & Instant Messenger »-
Jabber
(10. Dezember 2006, 18:17)
-
Hardware »-
USB-Geschw.
(23. Dezember 2005, 16:09)
-
Hardware »-
Wie kann ich treiber updaten?
(1. Juni 2004, 17:55)
-
Hardware »-
DivX-DVD-Player von ALDI
(22. Dezember 2003, 17:34)


