Forum: Mikrocontroller und Digitale Elektronik 2x RS232 auf USB (mit modifizierten Daten)


von Stefan Schmidt (Gast)


Lesenswert?

Hallo Community,

leider bin ich über die Suchfunktion nicht auf eine Lösung gestoßen.

Es geht darum 2x serielle Schnittstellen (RS232) am PC auszulesen. Die 
Daten gehören zu einer Punkt zu Punkt Linienstromverbindung (2 kanalig, 
daher auch 2xRS232. Eine Leitung gehört sozusagen dem Master, die zweite 
dem Slave). Um die Daten mithorchen zu können, benötige ich die Daten in 
der Richtigen Reihenfolge.

Beispiel:
Master           |         Slave

 Request         ->
                 <-        positive Quittierung
 Daten 1         ->
 Daten 2         ->
 Daten Ende      ->
                 <-        positive Quittierung

Mein erster Ansatz an die Daten zu gelangen war die Nutzung von zwei USB 
<-> RS232 Konvertern. Das Problem ist eine Kombination aus der 
Scheduling- und Packet-basierten USB-Übertragung und der sehr 
unterschiedlichen
Datagramm-Größen des seriellen Protokolls. Die Folge war das die 
Reihenfolge der Daten vertauscht ankam, sozusagen die zeitliche 
Zuordnung nicht möglich ist. Die Daten wurden empfangen und unmittelbar 
in einer gemeinsamen TextBox angezeigt. (Farblich unterschieden)

Von daher hatte ich folgende Überlegung: (<-> ist jeweils ein Konverter)

2x RS232 zu
2x RS232 <-> UART zu
z.B. ATmega1280 (da 4x UART) (dort Daten modifizieren) zu
UART <-> USB

Dieses Lösung hätte den Vorteil, das ich den einzelnen Daten beim 
Modifizieren schon außerhalb des Betriebssystems die zugehörigen Sender 
zuordne und dann nur noch am PC auswerten muss.

Mein momentanes Wissen zu IC's und µC Programmierung  ist noch relativ 
dürftig. Deswegen hoffe ich auf Anregungen, die mir bei der IC Wahl 
helfen und auch bei der Programmierung des µC, da ich die Daten ja auch 
verlässlich modifizieren muss. Oder es kennt jemand eine andere Lösung 
für mein Problem :)

Vielen Dank
Stefan

von Peter II (Gast)


Lesenswert?

was ist wenn auf RS232 ein großes Packet und etwas später auf dem 2. 
RS232 ein kleineres Packet ankommt.

Das kleiner Packet ist zuerst fertig. Welches packet wurde nun zu erst 
empfangen?

Gilt also der Start oder das ende der Übertragung?

von Stefan Schmidt (Gast)


Lesenswert?

Das sollte eigentlich nicht vorkommen, da es sich ja um eine Punkt zu 
Punkt Verbindung handelt. Die zweite Leitung wird erst wieder 
beansprucht, wenn das  Signal "Daten Ende" von der ersten Leitung 
erhalten wurde. Somit kann wenn überhaupt nur ein Problem auftreten, 
wenn beide gleichzeitig mit einer Übertragung starten wollen. Dafür ist 
aber in der PtP Verbindung eine Prioritätenregelung hinterlegt.

Es geht Insgesamt auch nur darum, die Daten der PtP Verbindung 
abzuhören. Es wird nichts gesendet.

von Stefan S. (stefanschmidt)


Lesenswert?

Hat vielleicht jemand schon mal etwas ähnliches gemacht oder gebaut ?

von Frank K. (fchk)


Lesenswert?

Nimm doch einfach einen Logic Analyzer wie den hier.

https://www.saleae.com/logic

Das ist ein fertiges Gerät, mit dem Du das Timing exakt erfassen und 
Deine beiden UART-Kanäle dekodieren kannst. Wenn Du Deine Arbeitszeit 
einrechnest, ist das die billigste Lösung - und mit Sicherheit die 
einfachste.

Der Logic Analyzer kann allerdings keine RS232-Pegel direkt verarbeiten, 
aber ein Max232 ist ja schnell aufgebaut.

fchk

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Frank K. schrieb:
> Der Logic Analyzer kann allerdings keine RS232-Pegel direkt verarbeiten,
> aber ein Max232 ist ja schnell aufgebaut.

Den braucht man zum Mithören nicht, da reicht ein 1489/75189. Der 
enthält keine Ladungspumpe, braucht also nicht die vier Kondensatoren, 
an deren Dimensionierung hier üblicherweise 15% der Forennutzer 
scheitern.

von Stefan S. (stefanschmidt)


Lesenswert?

Frank K. schrieb:
> Nimm doch einfach einen Logic Analyzer wie den hier.

Das sieht an sich viel versprechend aus...nur muss ich die Daten ja in 
mein eigenes Programm bekommen und nicht in deren Anzeige/Terminal.
Dazu kommt, das ich wirklich nur die zwei Kanäle brauche und keine 8. Es 
ist für mich eigentlich zu groß dimensioniert und damit teurer als 
notwendig.

von Frank K. (fchk)


Lesenswert?

Und eine PCI/PCIe-Karte mit echten UARTs kannst Du in Deinen Rechner 
nicht einbauen?

fchk

von Stefan S. (stefanschmidt)


Lesenswert?

Nein bei dem Laptop sind keine Steckplätze vorhanden. Und außerdem soll 
das ganze System/PC unabhängig sein. Es soll sozusagen eine Mobile 
Lösung sein.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?


von Mat (Gast)


Lesenswert?

oder du schnappst dir einen beliebigen Controller mit >=3 UART,
bufferst die 2 Eingänge und schiebst sie in richtiger reihenfolge zum 3. 
wieder raus. Dann hast du mit dem PC nur eine Schnittstelle und da 
kommen die Daten dann schon in der richtigen Reihenfolge.

Der Controller muss halt noch davor schreiben zu welchem Anschluss das 
Paket gehört und der 3. UART muss die Baudraten der beiden anderen 
zusammen packen.

lg

von Stefan S. (stefanschmidt)


Lesenswert?

Mat schrieb:
> oder du schnappst dir einen beliebigen Controller mit >=3 UART,
> bufferst die 2 Eingänge und schiebst sie in richtiger reihenfolge zum 3.
> wieder raus. Dann hast du mit dem PC nur eine Schnittstelle und da
> kommen die Daten dann schon in der richtigen Reihenfolge.

Genau das wäre mein Ansatz :)

Dazu will ich einen ATmega640 verwenden der die beiden seriellen RS232 
Pegel mittels MAX232 wandelt. Auf der anderen Seite will ich ein FT232RL 
für die USB Übertragung nutzen. Den µC will ich Interrupt gesteuert 
programmieren, sprich immer wenn Daten per UART kommen, direkt per 
USB-UART weiter senden.

Kann das so funktionieren ?

Edit:

Rufus Τ. Firefly schrieb:
> Nun, dann hilft das hier:
> https://iftools.com/analyzer/msb-rs232/index.de.php

Danke für den Hinweis, das sieht vielversprechend aus

: Bearbeitet durch User
von думлихер троль (Gast)


Lesenswert?

Dafuer gibt es fertige Geraete, die genau das machen fuer relaiv wenig 
Geld. Eine Streichholzschachtel mit USB dran

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Stefan Schmidt schrieb:
> Dazu will ich einen ATmega640 verwenden

Hat der drei serielle Schnittstellen?

Die brauchst Du nämlich dafür - zwar verwendest Du von jeder 
Schnittstelle nur die Hälfte, nämlich von je zwei nur den RxD-Pin (zum 
Mithören) und von einer den TxD-Pin (zum Senden via FT232), aber die 
dritte ist erforderlich, weil die mit (mindestens) der doppelten 
Baudrate der beiden anderen Schnittstellen betrieben werden muss. 
Deswegen kannst Du nicht den TxD-Pin einer der beiden 
Mithör-Schnittstellen verwenden, um die empfangenen Daten zum PC zu 
senden.

Und wenn Du das Gerät mit etwas Komfort betreiben willst, willst Du 
natürlich auch die verwendete Mithörbaudrate und gegebenenfalls noch 
andere Parameter vom PC aus einstellen können, wozu sich der RxD-Pin der 
dritten Schnittstelle anbietet, der ebenfalls mit dem FT232 zu verbinden 
ist.

Möchtest Du weiteren Komfort, wie z.B. Erkennung von Übertragungsfehlern 
wie Parity- oder Framing-Fehlern, dann muss die Schnittstelle zum PC mit 
noch höherer Datenrate betrieben werden, weil Du dann für jedes einzelne 
empfangene Byte auch noch ein Statusbyte übertragen musst. Das könntest 
Du auch noch benutzen, um den Zustand der Handshakeleitungen zu 
übertragen, die Du mit deinem Mithörer ebenfalls aufzeichnen kannst.

Ein sicherlich schickes Projekt, wenn die pc-seitige Auswertungssoftware 
auch noch schick gemacht wird.

Dann aber landet man irgendwann bei so etwas wie dem von mir erwähnten 
Gerät ...

von Stefan S. (stefanschmidt)


Lesenswert?

думлихер троль schrieb:
> Dafuer gibt es fertige Geraete, die genau das machen fuer relaiv wenig
> Geld. Eine Streichholzschachtel mit USB dran

Unter welchem Suchbegriff sind diese denn zu finden ? Ich habe sie 
nämlich noch nicht gefunden :)

von Stefan S. (stefanschmidt)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Stefan Schmidt schrieb:
>> Dazu will ich einen ATmega640 verwenden
>
> Hat der drei serielle Schnittstellen?
>

Ja der hat 4 UART Schnittstellen.

> Und wenn Du das Gerät mit etwas Komfort betreiben willst, willst Du
> natürlich auch die verwendete Mithörbaudrate und gegebenenfalls noch
> andere Parameter vom PC aus einstellen können, wozu sich der RxD-Pin der
> dritten Schnittstelle anbietet, der ebenfalls mit dem FT232 zu verbinden
> ist.

Habe ich auch vor. Die maximale Baudrate auf der Abhöhrseite sollte bei 
19,2k liegen. Die USB-Seite Baudrate versuche ich auf das 3-4 fache zu 
setzen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Na dann: Freudiges Entwickeln!

von Frank K. (fchk)


Lesenswert?

Stefan Schmidt schrieb:

> Dazu will ich einen ATmega640 verwenden der die beiden seriellen RS232
> Pegel mittels MAX232 wandelt. Auf der anderen Seite will ich ein FT232RL
> für die USB Übertragung nutzen. Den µC will ich Interrupt gesteuert
> programmieren, sprich immer wenn Daten per UART kommen, direkt per
> USB-UART weiter senden.

Dann solltest Du für jedes empfangene Byte noch die Portnummer und einen 
Timestamp mitsenden. Das Timing am USB-Port ist nicht vorhersehbar, und 
der Mikrocontroller ist der einzige, der einen Timestamp liefern kann.

Wind wenn Du statt des FT232 einen FT245 nimmst, brauchst Du keinen 
100-Pin AVR und hast eine schnellere Hostschnittstelle, weil der FT245 
ein paralleles Interface hat. Du kannst zwar weiterhin PC-seitig eine 
Bitrate einstellen, die aber ignoriert wird. Wahlweise kannst Du auch 
einen FT2232D oder FT2232H verwenden.

Die eleganteste und technisch beste Lösung wäre ein Controller mit 2 
UARTS und USB-Hardware. Leider gibts es keine AVR, der diese Bedingung 
erfüllt. Ein PIC24FJ64GB002 (28 Pins, auch DIL) würde das alles können.

fchk

von Stefan S. (stefanschmidt)


Angehängte Dateien:

Lesenswert?

So, die Platine ist gelötet und funktioniert soweit. Allerdings bin ich 
nun auf ein Programmier Problem gestoßen. Ich verwende einen ATmega1280 
mit einem externen Quarz (7,3728MHz).

Ich möchte mit meinem Programm erstmal nur die Daten von USART1 und 
USART2 an USART3 schicken.

Zwei von drei ISR funktionieren, aber sind alle identisch.

Meine Interrupt Routinen funktionieren auch, bis auf die von USART1. Das 
senden über USART1 funktioniert (also TxD). Nur RxD löst die ISR nicht 
aus. Die anderen beiden ISR funktionieren hingegen. Ich bin ratlos. Muss 
ich den UART-Interrupt für diesen Port besonders einstellen ? Auf dem 
RxD Pin kann auch ein externen Interrupt eingestellt werden (INT2 Pin 
45). Kann daher das Problem kommen ?


------------------------------------------------------------------
Hier mein Programm:
1
//Includes
2
//#include "defines.h"
3
#include <avr/interrupt.h>
4
#include <avr/io.h>
5
//#include <avr/iomxx0_1.h>
6
#include <string.h>
7
#include <util/delay.h>
8
9
10
void uart_send_byte(char c){
11
  while (!(UCSR3A & (1<<UDRE3)));
12
  UDR3=c;
13
}
14
void uart_send_string(const char *c){
15
  while ( *c != '\n' )
16
    uart_send_byte(*(c++));
17
}
18
19
20
int main(void){
21
  DDRJ = 0b00000010;
22
  DDRH = 0b00000010;
23
  DDRD = 0b00001000;
24
  DDRA = 0b00001111;
25
26
  UBRR3H = 0x00;
27
  UBRR3L = 3;       //115200Hz bei 7,382700 MHZ Quarz
28
29
  UBRR2H = 0x00;
30
  UBRR2L = 47;     //9600Hz bei 7,382700 MHZ Quarz
31
32
  UBRR1H = 0x00;
33
  UBRR1L = 47;    //9600Hz bei 7,382700 MHZ Quarz
34
35
36
  UCSR1B |= (1<<TXEN1)|(1<<RXEN1)|(1<<RXCIE1);    // UART1 RX und Interupt einschalten
37
38
  UCSR3B |= (1<<TXEN3)|(1<<RXEN3)|(1<<RXCIE3);  // UART TX einschalten
39
40
  UCSR2B |= (1<<TXEN2)|(1<<RXEN2)|(1<<RXCIE2);  // UART TX einschalten
41
42
  _delay_ms(2000);
43
44
  PORTA |= (1<<PA3);    //LED Test
45
46
  sei();
47
48
  while(1){
49
50
51
    UDR3='3';
52
    _delay_ms(2000);
53
    UDR2='2';
54
    PORTA &= ~(1<<PA3);
55
56
    _delay_ms(2000);
57
    UDR1='1';
58
    PORTA |= (1<<PA3);
59
    _delay_ms(2000);
60
    }
61
}
62
63
//ISR(USART1_RX_vect) {
64
//  cli();
65
////  if ( (UCSR1A & ( 1<<FE1)) != 0 )
66
////    uart_send_string("Frame ERROR1\n");
67
////  if ( (UCSR1A & ( 1<<DOR1)) != 0 )
68
////    uart_send_string("Data OverRun1\n");
69
////  if ( (UCSR1A & ( 1<<UPE1)) != 0 )
70
////    uart_send_string("Parity Error1\n");
71
////
72
////  while (!(UCSR3A & (1<<UDRE3)));
73
////    UDR3='!';
74
////  while (!(UCSR3A & (1<<UDRE3)));
75
////    UDR3=UDR2;
76
////  while (!(UCSR3A & (1<<UDRE3)));
77
////    UDR3='\\';
78
//
79
//  while(1) {
80
//  PORTA &= ~(1<<PA2);
81
//  _delay_ms(500);
82
//  PORTA |= (1<<PA2);
83
//  _delay_ms(500);
84
//
85
//  }
86
//  sei();
87
//}
88
89
ISR(_VECTOR(36)) {    //Funktioniert auch nicht, Vectornummer oben stimmt überein
90
  cli();
91
  while(1) {
92
  PORTA &= ~(1<<PA2);
93
  _delay_ms(500);
94
  PORTA |= (1<<PA2);
95
  _delay_ms(500);
96
97
  }
98
  sei();
99
}
100
ISR(USART2_RX_vect){
101
  cli();
102
  PORTA &= ~(1<<PA3);
103
  if ( (UCSR2A & ( 1<<FE2)) != 0 )
104
    uart_send_string("Frame ERROR2\n");
105
  if ( (UCSR2A & ( 1<<DOR2)) != 0 )
106
    uart_send_string("Data OverRun2\n");
107
  if ( (UCSR2A & ( 1<<UPE2)) != 0 )
108
    uart_send_string("Parity Error2\n");
109
110
  while (!(UCSR3A & (1<<UDRE3)));
111
    UDR3='!';
112
  while (!(UCSR3A & (1<<UDRE3)));
113
    UDR3=UDR2;
114
  while (!(UCSR3A & (1<<UDRE3)));
115
    UDR3='\\';
116
117
  sei();
118
  PORTA |= (1<<PA3);
119
}
120
121
ISR(USART3_RX_vect){
122
  cli();
123
  if ( (UCSR3A & ( 1<<FE3)) != 0 )
124
    uart_send_string("Frame ERROR\n");
125
  if ( (UCSR3A & ( 1<<DOR3)) != 0 )
126
    uart_send_string("Data OverRun\n");
127
  if ( (UCSR3A & ( 1<<UPE3)) != 0 )
128
    uart_send_string("Parity Error\n");
129
  //char recChar = UDR3;
130
131
  while (!(UCSR3A & (1<<UDRE3)));
132
  UDR3=UDR3;
133
134
  sei();
135
}
--------------------------------------------------------------------

Vielen Dank schonmal für eure hoffentlich zielführenden Antworten.

: Bearbeitet durch User
von R. W. (Gast)


Lesenswert?

Hallo Stefan,

meine 5ct dazu: BIN TERM

http://mmvisual.de/

USB Datenspion ect.

LG
Rudi
;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.