Forum: Mikrocontroller und Digitale Elektronik Modbus RTU mit LTC485


von Johannes (Gast)


Angehängte Dateien:

Lesenswert?

Ich versuche einen CO2 Sensor der Modbus RTU (mit RS485 Schnittstelle) 
kompatibel ist auszulesen.
Da ich dies mit einem ATMega2560 durchführen möchte verwende ich den 
LTC485 zur Wandlung von Rs485 auf TTL Pegel.
Der Sendevorgang scheint mit meinem Programm zu funktionieren, jedoch 
funktioniert der Receive-Vorgang nicht. In der Revceive Funktion wird 
zurzeit über eine while Schleife auf ein Zeichen gewartet, jedoch kommt 
nie eines an.
Ph1 wird für den Wechsel zwischen Senden und Empfangen verwendet. Uart1 
für die Kommunikation.
Ansteuerschaltung wurde keine für den LTC485 verwendet(also alles direkt 
verbunden, lediglich 120Ohm Abschlusswiderstände für die Datenleitungen)
Ich hoffe es kann jemand weiterhelfen.
Das Programm befindet sich im Anhang.
Mfg Johannes

von Stephan (Gast)


Lesenswert?

Haste es hin bekommen?

Deine Infos sind seeehhhrrr dürftig!!! (Schaltplan, bessere Doku der SW, 
usw.)

Aber 2 Fehler sind im Code mindestens:
Vor dem Senden prüfen ob alle Daten vom Empfänger gelesen wurden, erst 
dann in den Sende-Modus umschaltten!!!
1
  for(i=0;i<8;i++)
2
  {
3
    uart1_putc(buffer[i]);
4
  }
5
  while ( (UCSR1A & (1<<UDRE1)) == 0);  // <- ist FALSCH
6
 // nicht UDREn ist wichtig, sondern TXCn

Bei RS485 müssen alle Daten aus dem Transmitter gesendet worden sein, 
erst dann darfst du in den Empfangsmodus umschalten!!!
Das Umschalten ist 'AusKommentiert' ?!?
1
  for(i=0;i<8;i++)
2
  {
3
    receive_buffer[i]=uart1_getc(); 
4
  }

Das kann funktionieren, muß aber nicht. Der Slave kann auch mit einem 
FehlerCode antworten, was bei dir im Programm zum Blocking führt(Daten 
<8 Byte) Mach es richtig, auch wenn das nur zum Testen ist.(Deine getc 
Funktion wartet unendlich?)

Kannst du deine SW mit Hilfe eines PC-Modbus-Simulation vorher 
testen?(Freeware)

von Johannes (Gast)


Lesenswert?

Danke für die schnelle Antwort.
Tut mir leid für die dürftigen Angaben!

Über welche Schnittstelle funktioniert eine derartige 
PC-Modbus-Schnittstelle?
Denn ich habe zurzeit einen Testaufbau auf einem Breadboard.

Und wegen der Abfrage. Ich habe auch bereits versucht auf 1 Byte zu 
warten, jedoch kommt auch hier nichts an.


Weiß vielleicht auch jemand welche Adresse beim Modbusbefehl zu 
Übergeben ist, wenn ich das Inputregister12 abfragen möchte?

von Stephan (Gast)


Lesenswert?

Johannes schrieb:
> Über welche Schnittstelle funktioniert eine derartige
> PC-Modbus-Schnittstelle?
> Denn ich habe zurzeit einen Testaufbau auf einem Breadboard.

Das wäre dann RS232. Einfach Max232 und gut is.
hier mal ein Beispiel was dir hilft den Master(dein AVR) zu testen:
http://www.modbustools.com/modbus_slave.html
(nur Beispiel gibt bessere!!!)

Johannes schrieb:
> Und wegen der Abfrage. Ich habe auch bereits versucht auf 1 Byte zu
> warten, jedoch kommt auch hier nichts an.
mhm. RS485 Steuerung? TX / RX Umschaltung????
auf TXCn Bit getestet????

> Weiß vielleicht auch jemand welche Adresse beim Modbusbefehl zu
> Übergeben ist, wenn ich das Inputregister12 abfragen möchte?
das ist schon richtig.
1
  buffer[0]=0x01; // Sende Telegramm an Gerät mit Adr. 1
2
  buffer[1]=0x04; // Read Input Reg.
3
  buffer[2]=0x00; //
4
  buffer[3]=0x0C; // Reg Adr 12
5
  buffer[4]=0x00; //
6
  buffer[5]=0x01; // Reg Anzahl 1

versuchmal das PC-Programm mit deinem AVR per RS232 zutesten.
Es gibt auch noch adapter die von RS232 auf RS485 wandeln, damit 
könntest du auch testen wenn dein AVR mit dem PC läuft.(wenn du sowas 
hast)

von Johannes (Gast)


Lesenswert?

Ich habe es jetzt mit dem Modbus Slave Simulator versucht.

Als Converter von RS485 auf RS232 habe ich einen ADAM-4520

Mit dem Picoscope habe ich den UART Ausgang und zwischen den 
Datenleitungen gemessen. Wenn ich jedoch eine der beiden Datenleitungen 
gegen ground messe kommt zwar das richtige Signal, es ist aber immer 
positiv. Sollte nicht bei einer Differentiellen Übertragung logisch 0 im 
negativen Bereich sein?

Für die Versorgung des LTC485 habe ich die 5V des ATMEGA verwendet.
Den ADAM-4520 versorge ich mit 24V

Beim Modbus Slave Simulator kommt nichts an und am Mikrocontroller 
empfange ich auch nichts.
Hat vl jemand Erfahrung mit einem derartigen Simulator Programm?

Mfg Johannes

von Johannes (Gast)


Angehängte Dateien:

Lesenswert?

Das wäre das gemessene Signal nach dem RS485 auf RS232 Converter
Für die Schnittstelle beim Simulator habe ich COM1 gewählt.
Sollte der Slave Simulator die Daten anzeigen die er bekommt?

von Stephan (Gast)


Lesenswert?

Du hast jetzt mit RS485 getestet?
Kannst du den PC an die andere COM vom AVR Testen und dort das Modbus 
Telegramm senden RS232?

wie hast du den Slave konfiguriert?

von Johannes (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe jetzt den AVR via Uart mit dem LTC485 verbunden. Von dort gehe 
ich auf den RS485 auf RS232 converter und dieser steckt an meinem PC.
Leider muss ich einen alten PC verwenden da der neue keine RS232 
Schnittstelle hat.

Den Converter kann ich nicht umstecken, da sich von der Größe des 
Converters nur eine der beiden Rs232 Schnittstellen ausgeht. Der AVR 
steckt aber am neuen PC.
Wenn der Converter an so einer Schnittstelle hängt ist eh trotzdem ein 
COM auszuwählen oder?

Einstellungen:
Connection: Serial Port
Serial Settings: Kommunikationsanschluss(COM1)
9600 Baud
8 Data bits
None Parity
2 Stop Bits
Mode: RTU

Die genauen Einstellungen sind auf den Bildern

Eine Frage noch zum Code:
Wenn ich die Leitung mit der zwischen Send und Receive gewechselt wird 
folgendermaßen konfiguiere:
DDRH &=~(1<<PH0);
sollte es ja eigentlich ein Eingang sein, aber der Converter ist grün, 
also meiner meinung nach kein fehler.
verwende ich jedoch DDRH |=(1<<PH0);
also als Ausgang definiert springt der Converter sofort auf Orange
das verwirrt mich ein bischen.

von Johannes (Gast)


Lesenswert?

Habe den falschen COM verwendet :O
Jetzt funktioniert zumidest mal die Übertragung von AVR zum PC
und due Daten werden Korrekt übertragen.

von Johannes (Gast)


Lesenswert?

Doch das Empfangen der Daten vom PC funktioniert immer noch nicht
Es wird zwar am Simulator zwar die korrekte Rücksendung angezeigt, 
jedoch kommt dies am AVR nie an.

von Stephan (Gast)


Lesenswert?

Johannes schrieb:
> Jetzt funktioniert zumidest mal die Übertragung von AVR zum PC
> und due Daten werden Korrekt übertragen.

Gut. Die halbe Miete hast schon. :-)

Johannes schrieb:
> Doch das Empfangen der Daten vom PC funktioniert immer noch nicht

Ok, hab ich vermutet, wie sieht dein Programm jetzt aus?
Wie schaltest du jetzt zwischen TX und RX um?

von Johannes (Gast)


Angehängte Dateien:

Lesenswert?

Im Anhang befindet sich das Programm
ein Bild von der Tera Term Ausgabe (UART0)
und ein Bild vom Simulator
Ich verwende den Modbus Slave Simulator da der Master auf dem alten 
Windows XP PC nicht funktioniert.
Könnte es an dem auch liegen, oder sendet dieser auch automatisch die 
Antwort zurück?

von Stephan (Gast)


Lesenswert?

Der Slave Simulator ist richtig!
Im 2. Bild ist deine Kommunikation am laufen. supi

Wie sind DE und /RE bei dir verdrahtet?
1
  //send command via Rs485
2
  for(i=0;i<8;i++)
3
  {
4
    uart1_putc(buffer[i]);
5
  }
6
  
7
  while ( (UCSR1A & (1<<TXC1)) == 0);
Das geht? Ok.....

Wenn die Pins DE und /RE noch änderbar sind, kannst du TX aktive und RX 
aktiv schalten? So wäre eine Loop möglich, wenn du ein 'A' über UART1 
sendest kannst du das 'A' auch empfangen. Dann wäre der die Ansteuerung 
des LTCs und der Empfang geprüft.

von Johannes (Gast)


Angehängte Dateien:

Lesenswert?

Ich hab zurzeit noch einen Bread-Board Aufbau also wars kein Problem die 
zu ändern. Vorher waren DE und /Re direkt miteinander verbunden, sodass 
immer nur eines der beiden aktiv waren.

Ich hab jetzt beide aktiviert und folgenden Code verwendet:
uart1_putc('a');
c=uart1_getc();
uart0_putc(c);

Das Zeichen a wurde auf Teraterm ausgegeben, also es scheint zu 
funktionieren

Ich bin nur etwas skeptisch bei der Ansteuerung von DE und /RE da bei 
der Ansteuerung eines low Pegels stets der Converter orange wurde und 
wenn ich statt diesen den Sensor verwende blinkt die Bus-LED rot

Im anhang sind noch die verwendeten UART-Funktionen. Die für uart0 ist 
gleich nur hald überall 0 statt 1

von Stephan (Gast)


Lesenswert?

So ok, deine putc sendet nur über den Buffer, also müsstest du den Code 
so ändern.
1
  //send command via Rs485
2
  for(i=0;i<8;i++)
3
  {
4
    uart1_putc(buffer[i]);
5
  }
6
  while ( (UCSR1A & (1<<UDRE1)) == 0); // wait until transmit buffer is empty
7
  while ( (UCSR1A & (1<<TXC1)) == 0);  // wait until transmiter is empty

Dann solltest du richtig zw. TX und RX umschalten können.

Johannes schrieb:
> Das Zeichen a wurde auf Teraterm ausgegeben, also es scheint zu
> funktionieren
sehr gut :-)
Ich würde eigentlich erwarten das dann das andere dann auch 
funktioniert.....

Kannst du mal schauen was die Bits machen: FEn DORn UPEn


Eigentlich hast du jetzt alles getestet, deine HW und SW sollte 
funktionieren. Jetzt musst du irgendwie die Dinge nur zusammen bringen.

von Stephan (Gast)


Lesenswert?

Johannes schrieb:
> Ich bin nur etwas skeptisch bei der Ansteuerung von DE und /RE da bei
> der Ansteuerung eines low Pegels stets der Converter orange wurde und
> wenn ich statt diesen den Sensor verwende blinkt die Bus-LED rot

Das verstehe ich auch nicht so ganz, vielleicht kann ein anderer dir da 
weiter helfen.
Sorry

von Johannes (Gast)


Lesenswert?

Ich hatte einen ganz blöden programmierfehler :(
Aber jetzt mit ein bischen herumprobieren scheint es zu funktionieren.
Ich erhalte die Daten, die am Simulator angezeigt werden.

Ich hoffe das dies jetzt auch mit dem Sensor funktioniert.

Aber im vorhinein möchte ich mich schon mal bedanken für die viele 
Hilfe!!

von Stephan (Gast)


Lesenswert?

freut mich das ich helfen konnte.
Für die anderen wäre DIE Lösung bestimmt auch interessant.

von Johannes (Gast)


Lesenswert?

Es funktioniert jetzt auch mit dem Sensor
Ich kann den Wert auslesen und dieser scheint zu stimmen

Danke für die Hilfe!!!

von Johannes (Gast)


Angehängte Dateien:

Lesenswert?

Im Anhang befindet sich das fertige Programm

Ich habe zuletzt noch den Pin getauscht( von PH0 auf PB7)
und beim Übertragen der Daten an Teraterm hab ich zuvor blöderweise in 
der for-schleife das array receive_buffer[0] anstatt receive_buffer[i] 
verwendet.

Die Uart-Funktionen ließ ich unverändert.

von Johannes (Gast)


Lesenswert?

Und bevor ich es vergesse, das orange licht war aufgrund des Pullup und 
Pull-Down Widerstands die ich für die Datenleitungen verwendet habe (ist 
so im datenblatt gestanden ^^).
Möglicherweise war das an allem Schuld und nicht der Pin.

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.