Archiv verlassen und diese Seite im Standarddesign anzeigen : RS-232-Datenüberwachung
Hallo,
ich hab seit einer Weile ein Projekt. Ich soll die Datenübertragung zwischen zwei Geräten, die mit rs232 kommunizieren, abfangen und dann mit einem Laptop protokolieren. Dazu muss ich theoretisch ja nur eine Platine bauen, auf der ich dann die Sende und Empfangsleitung abzweige und an eine zusätzliche Buchse anschließen. Allerdings, müsste ich bei dieser leichten Lösung dazu die Software schreiben, die die Daten dann protokolliert. Ich hab nur absolut keine Ahnung von dem Programmieren und fertige Software ist nicht erlaubt :(.Gibt es einen anderen Weg diese Daten zu überwachen? Irgendeine schwerere Hardwarelösung, weil es mir angedeutet wurde, dass diese Platine so zu einfach sei.
Ich hoffe irgendjemand hat eine Idee und kann mir helfen.
Gruß
BurningWave
02.09.2009, 18:41
Z.B. die abgezweigten Leitungen an einen anderen µC anschließen, der das ganze protokoliert und z.B. in einem externen RAM speichert. Dann kann man zusätzlich noch ein LCD an diesen µC anschließen und sich die Daten (nachdem die Kommunikation beendet ist) anzeigen lassen.
Das ist sicher nicht die beste (und vor allem nicht die schnellste Lösung), sollte aber funktionieren.
mfg
hi,
wenn es eine HW Lösung sein muss, siehe R2D2.
Für eine SW-Lösung würde ich einen Laptop nehmen,
die beiden RS232 Signale über zwei RS232 / USB Konverter in
den Laptop führen und sowas wie ein abgespecktes Hypter-Term
programmieren.
BurningWave
02.09.2009, 18:55
Ich hab auch so ein Terminal programmiert, das geht nicht sehr schwer. Ich kann es auch mal mit Quellcode posten (C++).
Von hier habe ich meine Informationen wie's geht:
http://www.progforum.com/archive/index.php/t-5504.html
mfg
Danke für die Tipps. Das mit dem Mikrocontroller hab ich mir auch schon überlegt. Das Problem ist, dass ich auch davon noch nicht viel Ahnung habe und es auch leider nicht so einfach ist sich da schnell einzuarbeiten :). Aber ich glaube, dass der Mikrocontroller wahrscheinlich die Lösung ist, die von mir erwartet wird. Könnt ihr mir noch irgendwelche Tipps geben welcher Mikrocontroller sich für soetwas anbietet?
Das wär echt super wenn du mir den Quellcode schicken könntest. C++ lerne ich gerade, dass würde mir bestimmt weiterhelfen.
Alternativ gehts auch so:
http://www.rn-wissen.de/index.php/Windows_Programm_zum_Steuern_des_AVR%27s
BurningWave
02.09.2009, 19:20
Hier ist das Programm und der Quellcode. Wenn beim Ausführen Fehler wegen fehlenden Dlls kommen schreib mir bitte wie die fehlenden heißen, damit ich sie posten kann oder such mit google nach ihnen und lade sie irgendwo runter (das geht schneller). Wenn du sie alle runtergeladen hast, dann schreib mir bitte trotzdem welche gefehlt haben, damit ich das für die Zukunft weiß.
(Ich habe das Programm mit Borland C++ erstellt.)
Als µC würde sich der AtMega8 eignen.
mfg
Danke, ich weiß nicht ob ich diese woche noch dazu komme das programm zu testen, aber ich werd mich melden welche dll's fehlen.
OK, Mikrocontroller fällt flach, zu aufwendig. Gibt es noch eine Möglichkeit, vielleicht über irgendeine Logikschaltung oder soetwas. Ich weiß langsam echt nicht mehr was ich machen soll :(.
Könnt ich das Signal der Sende- und Empfangsleitung nehmen in ein Pegelwandler geben und dann in ein Schieberegister einlesen? Ich weiß nur nicht wie ich den Takt des Schieberegisters einstellen muss, dass er jedes Bit übernimmt.
na ja, Du könntest natürlich die ASCII-Zeichen über einen von einer Logik-
Schaltung gesteuerten UART (also ohne µC) in einem analogen oder digitalen Speicher ablegen.
Das WÄRE aufwendig!
Leider kenne ich keinen Chip (der UART ist kein Problem), der so was kann.
Dann bräuchtest Du immer noch SW, die die Auswertung auf dem Laptop
vornimmt.
Edit: hatte Deinen Eintrag von 8:14 übersehen...
RS232 überträgt die Daten asyncron, mit Start- und Stopbit.
Wenn Du das in ein Shiftregister überträgst, hast Du noch lange keine
Ahnung, was die Zeichen bedeuten. Deshalb nimmt man dafür einen UART,
der das asyncrone Signal in 8-bit parallel umwandelt.
>>>Ich weiß nur nicht wie ich den Takt des Schieberegisters einstellen
>>>muss, dass er jedes Bit übernimmt.
Die Taktfrequenz ist 1/Baudrate.
Z.B. 9600 Baud = 9600 Bits/s oder 104 µs pro Bit.
38400 Baud = 38400 Bits/s oder 26µs
Danke, was die Zeichen bedeuten ist glaub unwichtig. Ich kann dann ja einfach alles was gesendet und empfangen wird in 1 und 0 anzeigen lassen.
noch was:
wenn ein µC, der für diese Aufgabe ideal wäre, zu aufwändig ist,
solltest Du mit Deinem "Auftraggeber" reden.
Entweder sind die Vorgaben falsch, zu wenig, ungenau, etc. oder Du bist dafür einfach überfordert?
Auch wenn es heute dazu gehört, sich Info aus den Foren zu holen,
wird Dir niemand eine fertige Lösung präsentieren können,
das wäre ja auch nicht der Sinn der Sache, oder?
Ich glaub auch dass ich damit überfordert bin .... Dann muss ich mich doch selbst in µC einarbeiten. Ist es realistisch meine Aufgabe ohne Kenntnisse über µC noch bis ende des Monats zu lösen :) ?
siehst Du, das ist was ich meine:
>>>dann mit einem Laptop protokolieren
das war Dein erster Post.
>>>Danke, was die Zeichen bedeuten ist glaub unwichtig.
>>>Ich kann dann ja einfach alles was gesendet und empfangen
>>>wird in 1 und 0 anzeigen lassen.
das jetzt...
Wo anzeigen?
Falls auf dem Laptop muss zwischengespeichert werden,
was ohne µC schwierig (aufwändig) ist.
Versuche das zu klären und komme dann mit konkreter Aufgabe wieder, ok?
BurningWave
03.09.2009, 12:08
Dann muss ich mich doch selbst in µC einarbeiten. Ist es realistisch meine Aufgabe ohne Kenntnisse über µC noch bis ende des Monats zu lösen ?
Das ist möglich, wenn du dir möglichst schnell (falls du es nicht schon hast) ein Buch über µC Programmierung und einen Programmer (z.B. bei www.myAVR.de) kaufst und sehr viel Zeit zur Verfügung hast (jeden Tag). Sonst würde ich sagen nein.
Wie hm_heli schon gesagt hat, um einen µC wirst du auf keinen Fall herumkommen. Es geht zwar auch ohne, aber dann kannst du nur eine Leitung (entweder RxD oder TxD) überwachen (außer du hast 2 serielle Schnittstellen).
Und wenn ich es so mache? Dann brauch ich doch nur ein Com.
http://embeddedfreak.files.wordpress.com/2008/08/rs232_sniffer.png
BurningWave
03.09.2009, 13:10
An die Möglichkeit habe ich gar nicht gedacht, aber das würde gehen.
Du musst aber noch eine kleine Schaltung dazwischen schalten (um USART in RS232 umzuwandeln) Den Schaltplan habe ich angehängt. Du musst eben noch vor die Pins 2 und 3 der seiellen Schnittstelle jeweils eine Diode setzen und mit Pin 2 verbinden (so wie in dem Schaltplan von deinem Link).
BurningWave
05.09.2009, 20:46
Jetzt müsste xTerm ohhne zusätzliche DLLs laufen.
Moin moin.
Es gibt für Win Programme welche den datenverkehr auf RS232
oder auch (anderes programm) USB überwachen und "Loggen" =
Mitschreiben. Die Trennen Nutzdaten automatisch von Steuerdaten
wie Ak, Start,Stopp, xon/xoff u.s.w. Dazu muß natürlich zumindenst
auf einem der Geräte so ein Programm laufen.
Man könnte auch einen 3 PC/Laptop nehmen und so ein Programm
2 x Starten eines für com 1 und eines für com 2 und dann jeweils
RDX com1/2 mit TDX der zu belaschenden Geräte verbinden oder,
oder, oder...Da bremst allenfalls die Fantasie, geht nicht gibt es dabei
nicht wirklich.
Gogle einmal nach RS232 Logging oder USB Logging. Aus Linux bin
ich leider etwas raus, dort sollte Dump tty(x) > datei(xyz) schon
reichen um alles zu Speichern was so auf der Schnittstelle abläuft.
Gruß Richard
reichen u
Hallo,
also das mit dem USART versteh ich nicht ganz, was macht denn der?
Mit den Dioden hab ich ja das Problem, dass sie dann nur die positive Spannung durchlassen und das negative Signal sperren, das hab ich verstanden. Ich weiß nur nicht wie ich das Problem lösen soll. Ich könnte ein Pegelwandler dazwischen schalten, hab dann aber ja nur noch 0V und 5V und das Signal kann ich ja nicht einfach wieder in einen rs232 stecker geben ......
Kann mir jemand eine einfach Lösung zeigen?
BurningWave
08.09.2009, 18:10
Mit den Dioden hab ich ja das Problem, dass sie dann nur die positive Spannung durchlassen und das negative Signal sperren, das hab ich verstanden.
Wie wärs mit einem Pulldown hinter den Dioden. Dann hättest du wieder ein negatives Signal.
Moin moin.
Die Dioden sollen parallel zu der µC TDX Datenleitung und leiten die
negativen - 15 V (PC) gegen 0V ab (wie eine Freilaufdiode). Dann bleiben
auf den µc Seite nur - 0,/7 V übrig und die werden verkraftet.
In die RDX Leitung vom µC kommt noch ein ca. 1k8 R, der begrenzt den
Srom.
Ich habe leider keinen Schaltplan parat, aber eine aufgebaute Platine.
Dort könnte ich noch einmal genau nachschauen, aber ich habe in den
letzten 3 Tagen jeweils 14 h durchgehend gearbeitet und bin zu müde.
vor dem Wochenende wird das NIX.
Gruß Richard
So, also ich habs jetzt einfach mal ohne µC aufgebaut und zwar so wie es hier aufgebaut wurde:
http://www.paa.co.uk/labauto/information/f-serial-port-communications.asp
Ich habe die Halbduplexüberwachung gewählt, mit der Diode und dem Widerstand.
Nun muss ich das Programm dazu schreiben, welches mir die ankommenden Daten protokolliert, also aufm Bildschirm anzeigt. Hab mich mal ein wenig in C++ und WinAPI eingelesen. Ich weiß auch jetzt wie ich den Port öffne, aber nicht wirklich wie ich die Daten die ankommen mit C++ abrufe und anzeigen lasse. Vielleicht habt ihr ja einen Tipp, ein Beispiel oder eine Seite, die mir weiterhilft :).
Danke für eure Mühe, diese Forum ist wirklich hilfreich.
BurningWave
14.09.2009, 15:15
nicht wirklich wie ich die Daten die ankommen mit C++ abrufe und anzeigen lasse. Vielleicht habt ihr ja einen Tipp, ein Beispiel oder eine Seite, die mir weiterhilft
Ich habe doch shon einen Link und den Quellcode meines Programms gepostet (auf 1. Seite). Also einfach Schnittstelle mit OpenFile öffnen und dann kann man mit ReadFile Daten lesen. ReadFile könnte man dann mit einem Timer jede ms aufrufen und die empfangenen Daten (falls welche empfangen wurden) in eine ListBox schreiben.
Hallo,
also ich bin mittlerweile an der Software mit C++.
Und ich wollte mal fragen, wieso wenn ich dcb.BaudRate ausgebe er mir die BaudRate anzeigt. Gebe ich aber z.B dcb.ByteSize aus, bekomme ich entweder gar nichts oder ein komisches Zeichen. Das gleiche bei dcb.Parity oder dcb.Stopbit. Ist das normal?
Danke für eure Hilfe.
BurningWave
21.09.2009, 14:08
Und ich wollte mal fragen, wieso wenn ich dcb.BaudRate ausgebe er mir die BaudRate anzeigt.
Ich verstehe deine Frage nicht ganz.
Aber wenn die Baudrate, ByteSize, Parity und Stoppbits nicht mit den Einstellungen des µCs / der der übertragenden Geräte übereinstimmen, ist es klar, dass du komische Zeichen empfängst. Außerdem musste ich bei mir bei allen empfangenen Bytes Bit 8 löschen, da es komischerweise immer gesetzt war, um das richtige Zeichen zu empfangen.
Ich setze einfach zum Beispiel dcb.BaudRate=600; dcb.ByteSize=8;
Mach ich nun cout << dcb.BaudRate, gibt er mir 600 aus. Mach ich aber cout << dcb.ByteSize, gibt er mir nichts aus. Wollte nur mal fragen ob das normal ist, oder ob dann 8 ausgegeben werden müsste. :)
BurningWave
21.09.2009, 14:25
Nein, das ist wohl nicht ganz normal, aber um den Fehler zu finden solltest du deinen Code posten. Funktioniert das Datenauslesen schon oder bist du noch am programmieren?
Also, so sieht er aus, ein bisschen umständlich, aber ich hab ja die Hoffnung, dass es funktioniert. Und wenn ich das Xterminal Programm von dir auf nem anderen Pc öffne und dort etwas schreibe und sende wird es auch mit meiner Software angezeigt. Das Problem ist, wenn ich die BaudRate oder Stopbit etc. ändere klappt es nicht mehr, auch wenn ich die einstellungen dementsprechend auch in meiner Software ändere.
Naja hier erstmal der Quellcode:
//-----------------------------------Hauptmenü-----------------------------------------------------------
menue:
cout << "Hauptmen\201:" << endl
<< "----------" << endl
<< "[1] Konfiguration des Com-Ports" << endl
<< "[2] Port \224ffnen" << endl
<< "[3] Programm starten" << endl
<< "[4] Programm beenden" << endl
<< "-------------" << endl
<< "Ihre Eingabe: ";
cin >> eingabe;
cout << endl;
//----------------------------Programm beenden----------------------------------------
if(eingabe == 4)
{
return EXIT_SUCCESS; //beendet Programm
}
//--------------------------------Port öffnen-----------------------------------------
if(eingabe==2)
{
hCom = CreateFile ("COM1",
GENERIC_READ | GENERIC_WRITE,
0, // must be opened with exclusive-access
NULL, // no security attributes
OPEN_EXISTING, // must use OPEN_EXISTING
0, // non overlapped I/O
NULL // hTemplate must be NULL for comm devices
);
if (hCom == INVALID_HANDLE_VALUE) //bei fehler beim Portöffnen gibt Error aus
{ cout << " Error opening COM1" << endl << endl;}
else
{ cout << " COM 1 successfully opened" << endl << endl;}
Sleep(1000);
goto menue;
}
if(eingabe==1)
{
//-------------------Baudrate einstellen-----------------------------------------
GetCommState(hCom,&dcb); //Porteinstellungen werden abgerufen
neuBaudrate:
cout << "Welche Baudrate soll eingestellt werden: " << endl <<
"----------------------------------------" << endl <<
"[1] 115200" << endl <<
"[2] 57600" << endl <<
"[3] 38400" << endl <<
"[4] 19200" << endl <<
"[5] 9600" << endl <<
"[6] 4800" << endl <<
"[7] 2400" << endl <<
"[8] 1200" << endl <<
"[9] 600" << endl <<
"[10] 300" << endl <<
"-------------" << endl <<
"Ihre Eingabe: ";
cin >> Baudrate;
cout << endl;
switch (Baudrate)
{
case 1: dcb.BaudRate = CBR_115200; //Baudrate
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 2: dcb.BaudRate = CBR_57600; //Baudrate
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 3: dcb.BaudRate = CBR_38400; //Baudrate
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 4: dcb.BaudRate = CBR_19200; //Baudrate
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 5: dcb.BaudRate = CBR_9600; //Baudrate
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 6: dcb.BaudRate = CBR_4800; //Baudrate
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 7: dcb.BaudRate = CBR_2400; //Baudrate
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 8: dcb.BaudRate = CBR_1200; //Baudrate
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 9: dcb.BaudRate = CBR_600; //Baudrate
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 10: dcb.BaudRate = CBR_300; //Baudrate
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
default: goto neuBaudrate; //springe zurück
}
//---------------------Anzahl Datenbits festlegen-------------------------------
neuDatenbits:
cout << "Wieviele Datenbits werden gesendet: " << endl <<
"-----------------------------------" << endl <<
"[1] 5" << endl <<
"[2] 6" << endl <<
"[3] 7" << endl <<
"[4] 8" << endl <<
"-------------" << endl <<
"Ihre Eingabe: ";
cin >> Datenbits;
cout << endl;
switch(Datenbits)
{
case 1: dcb.ByteSize= 5; //Datenbits
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 2: dcb.ByteSize= 6; //Datenbits
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 3: dcb.ByteSize= 7; //Datenbits
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 4: dcb.ByteSize= 8; //Datenbits
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
default: goto neuDatenbits;
}
//------------------Parität festlegen---------------------------------------------
neuParitaet:
cout << "Welche Parit\204t soll gesetzt werden: " << endl <<
"-----------------------------------" << endl <<
"[1] NOPARITY" << endl <<
"[2] ODDPARITY" << endl <<
"[3] EVENPARITY" << endl <<
"[4] MARKPARITY" << endl <<
"[5] SPACEPARITY" << endl <<
"-------------" << endl <<
"Ihre Eingabe: ";
cin >> Paritaet;
cout << endl;
switch(Paritaet)
{
case 1: dcb.Parity= NOPARITY; //Parität
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 2: dcb.Parity= ODDPARITY; //Parität
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 3: dcb.Parity= EVENPARITY; //Parität
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 4: dcb.Parity= MARKPARITY; //Parität
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 5: dcb.Parity= SPACEPARITY; //Parität
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
default: goto neuParitaet;
}
//---------------------Stopbits festlegen------------------------------------------
neuStopbits:
cout << "Wieviel Stopbits sollen gesetzt werden: " << endl <<
"---------------------------------------" << endl <<
"[1] 1 Stopbit" << endl <<
"[2] 2 Stopbits" << endl <<
"[3] 1,5 Stopbits" << endl <<
"-------------" << endl <<
"Ihre Eingabe: ";
cin >> Stopbit;
cout << endl;
switch(Stopbit)
{
case 1: dcb.StopBits= ONESTOPBIT; //Stopbits
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 2: dcb.StopBits= TWOSTOPBITS; //Stopbits
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
case 3: dcb.StopBits= ONE5STOPBITS; //Stopbits
SetCommState (hCom, &dcb); //COM-Einstellungen speichern
break;
default: goto neuStopbits;
}
//----------------------------Eingaben prüfen--------------------------------------
cout << "Sind diese Eingaben OK?" << endl <<
"-----------------------" << endl <<
"[1] Ja" << endl <<
"[2] Nein" << endl <<
"-------------" << endl <<
"Ihre Eingabe: ";
cin >> ok;
cout << endl;
switch(ok)
{
case 1: goto menue;
break;
case 2: goto neuBaudrate;
break;
default: goto neuBaudrate;
}
{
system("cls"); //löscht Bildschirm
}
}
dcb.DCBlength = sizeof(DCB); //Länge des Blockes muss gesetzt werden
SetCommMask (hCom, EV_RXCHAR); //Kontrolliert ob an RXD-Leitung Daten ankommen
COMMTIMEOUTS ct;
ct.ReadIntervalTimeout = MAXDWORD;
ct.WriteTotalTimeoutConstant = 0;
ct.ReadTotalTimeoutMultiplier = 0;
ct.WriteTotalTimeoutConstant = 0;
ct.WriteTotalTimeoutMultiplier = 0;
SetCommTimeouts (hCom, &ct);
if(!SetCommTimeouts(hCom, &ct))
{
CloseHandle(hCom);
cout << "Fehler SetCommTimeouts";
}
//-------------------------------Bytes auslesen------------------------------------------
if(eingabe==3)
{
DWORD dwRead;
char chRead;
cout << dcb.BaudRate << endl
<< dcb.ByteSize << endl
<< dcb.Parity << endl
<< dcb.StopBits;
do
{
if(ReadFile(hCom, &chRead, 1, &dwRead, NULL));
{
if(dwRead)
{
printf("%c<%03u>", chRead, chRead, chRead);
}
}
} while(1);
}
system("PAUSE");
return EXIT_SUCCESS;
}
Es ist egal, was ich bei meiner Software einstelle, die Daten werden nur richtig angezeigt, wenn ich bei deinem XTerm Baud 9600 einstelle....
Sonst kommen nur seltsame zeichen an.
Ah, wenn ich SetCommState() nicht überall bei den Einstellungen dazuschreibe, scheint es zu funktionieren.
Also die Baudrate kann ich jetzt verstellen, aber die Stopbits und Datenbitanzahl nicht ... :(
Also, das einzige Problem ist jetzt noch die Datenbitanzahl, damit stimmt irgendetwas nicht. Außerdem hab ich noch keine Lösung für die Endlosschleife:). Über Tipps wär ich sehr dankbar.
Gruß
BurningWave
21.09.2009, 20:04
Also, das einzige Problem ist jetzt noch die Datenbitanzahl, damit stimmt irgendetwas nicht. Außerdem hab ich noch keine Lösung für die Endlosschleife:). Über Tipps wär ich sehr dankbar.
Ich hoffe ja nicht, dass in meinem Progamm diesbezüglich irgendwas nicht stimmt.
Was stört dich denn an der Endlosschleife? Die scheint doch zu funktionieren oder? Außerdem empfehle ich dir if(!(cin >> irgendeinevar)) stat nur cin zu schreiben, da man nie wissen kann was der Benutzer eingibt (wenn man das nicht macht stürzt das Programm ja ab) und dann irgendeine Fehlerbehandlungsroutine einbaut (z.B. mit MessageBox).
Also, ich glaub mein Programm funktioniert soweit. Das mit den Datenbits lass ich jetzt einfach mal. Allerdings zeigt mir das Programm die Daten als ASCII-Code an. Gibt es eine Möglichkeit es einfach als Binärcode darzustellen?
BurningWave
22.09.2009, 18:17
ja gibt's:
http://www.cplusplus.com/reference/clibrary/cstdio/printf/
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.