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
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)
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?
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)
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
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?
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?
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.
Habe den falschen COM verwendet :O Jetzt funktioniert zumidest mal die Übertragung von AVR zum PC und due Daten werden Korrekt übertragen.
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.
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?
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?
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.
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
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.
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
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!!
freut mich das ich helfen konnte. Für die anderen wäre DIE Lösung bestimmt auch interessant.
Es funktioniert jetzt auch mit dem Sensor Ich kann den Wert auslesen und dieser scheint zu stimmen Danke für die Hilfe!!!
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.