RS485 Problem - Empfängt nur beim ersten Mal korrekt

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • Michael schrieb:

      Snatch schrieb:

      Bild 2 ist das erste mal. Links das hinsenden rechts daneben die Antwort alles 1A!
      ja, wie ich es gedacht habe, sieht man das Byte, das er am Anfang mitschleppt.Schau mal Config Input an.

      Außerdem hast du ein Masseproblem.
      Hallo,

      Das mit der Masse könnte auch daran liegen, dass die Masse der Tastköpfe etwas blöde angebunden habe. Aber das sollte die Übertragung nicht stören.

      Ich verstehe deinen ersten Satz nicht. Was schleppt er mit? Er macht doch im Prinzip was er soll.
      "hallo+cr" empfangen und "hallo+cr+lf" senden. Config Imput.

      Ich habe mal dennoch "CONFIG INPUT = cr , ECHO = cr" verwendet. Ändert nichts am Ergebnis.

      Wisst ihr, dass ist nicht das erste mal, dass ich mit Bascom über RS232 oder RS485 Daten verarbeite. Ich habe hier eine Software auf meinem Tablet, womit ich meine Schaltungen Steuere. Aber gerade bei dieser Applikation geht es nicht und ich schnall es einfach nicht.

      Dennoch habe ich einige kleine Fehler hier durch euch gefunden und auch einige kleine Sachen gelernt, die ich so nicht kannte. Aber ich glaube es ist an der Zeit einfach mal von vorne zu beginnen :D

      Grüße
    • fredred schrieb:

      Michael schrieb:

      ja, wie ich es gedacht habe, sieht man das Byte, das er am Anfang mitschleppt.
      Ist wohl sehr allgemein gefasst. In einem Textstring kann eigentlich reingemalt werden was ASCII ist.Musst schon den String zerlegen um ein beliebiges Zeichen als Steuerzeichen zu nutzen.

      @Snatch Ist schon eigenartig.
      Aber ich würde zum testen die HW Version des µC nutzen.
      Schau mal in Codeschnipsel > Uart als kleine Programmier-Hilfe.
      SO, habe deinen Schnipsel mal drauf gehauen.

      Habe im mal die Zeichenfolge "00096|00512|00512|hallo" gesendet.

      Die Antwort war das:
      erstallt am : 22-11-2017 16:29?
      Version Code : WB V1.2_RS485 TEST.BAS
      String =
      N = 26
      Wert1 = 0
      Wert2 = 0
      Wert3 = 0
      Wert4 =
      Hast übrigens einen Schreibfehler drin. Es heißt "erstellt" nicht "erstallt" :D

      Grüße

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Snatch ()

    • Snatch schrieb:

      Hast übrigens einen Schreibfehler drin. Es heißt "erstellt" nicht "erstallt"
      Vielen Dank für diesen Hinweis.
      Hast doch nicht das Systeminterne String [Version] mit eigenem Text ersetzt?
      Nun siehst du aber trotz Schreibfehler, dass auch 2 Strings gesendet werden. Somit liegt es nicht an der Übertragung.
      Vermute immer noch das dein Empfangspuffer nicht zurückgesetzt wird sonder mit Steuerzeichen befüllt wird.
      Beweis ist Sring- Variable = bekommt kein "Text"
      Setze mal nach „Hallo“ ein „ ; “.
      Gruß
    • Snatch schrieb:

      Ich verstehe deinen ersten Satz nicht. Was schleppt er mit?
      Das hatte ich doch in Beitrag 8 geschrieben, ich meine das Steuerzeichen.
      Oder was ist das am Anfang deines Telegramms in Bild 2+3?

      Snatch schrieb:

      Wisst ihr, dass ist nicht das erste mal, dass ich mit Bascom über RS232 oder RS485 Daten verarbeite. Ich habe hier eine Software auf meinem Tablet, womit ich meine Schaltungen Steuere. Aber gerade bei dieser Applikation geht es nicht und ich schnall es einfach nicht.
      Weißt du, es ist nicht das erste mal, dass sich einer verrennt. Ich hoffe du verstehst, wie dein Satz hier ankommt.
      Ich hatte ja schon vermutet, dass da eine Software dahinter steckt. In Beitrag 12 schreibst du zwar von Hterm, aber später ist es dann doch was anderes.
      Hast du meinen Rat aus Beitrag 8 mal ausprobiert?
      Wird CR-LF von deiner Software wirklich erwartet oder nur CR?
    • fredred schrieb:

      Snatch schrieb:

      Hast übrigens einen Schreibfehler drin. Es heißt "erstellt" nicht "erstallt"
      Vielen Dank für diesen Hinweis.Hast doch nicht das Systeminterne String [Version] mit eigenem Text ersetzt?
      Nun siehst du aber trotz Schreibfehler, dass auch 2 Strings gesendet werden. Somit liegt es nicht an der Übertragung.
      Vermute immer noch das dein Empfangspuffer nicht zurückgesetzt wird sonder mit Steuerzeichen befüllt wird.
      Beweis ist Sring- Variable = bekommt kein "Text"
      Setze mal nach „Hallo“ ein „ ; “.
      Gruß
      Hallo,

      ja, senden ging ja schon immer. Dass ist es ja. Aber Empfangen nicht. Empfangen geht nur ein String, danach nichts mehr.

      Ich habe deinen Rat versucht und ein ";" angehängt:
      "00096|00512|00512|hallo;"
      Damit geht es. Aber es geht auch mit:
      "00096|00512|00512|hallo1"
      "00096|00512|00512|hallox"
      "00096|00512|00512|hallo,"
      etc. Also ein Zeichen an "hallo" dran und ich bekomme es richtig zurück:
      "00096|00512|00512|hallo;"
      hterm.JPG

      Das Lustige daran ist aber, dass wenn ich einmal ein Zeichen mehr gesendet habe, es danach auch ganz normal mit:
      "00096|00512|00512|hallo"
      geht. So lange bis ich wieder resette, dann geht es nicht mehr, bis ich eben wieder ein Zeichen an das "hallo" dran setzte, ab dann auch wieder ohne.

      Sehr verwirrend :D

      Aber vielen Dank mal soweit. Ich habe zwar noch nicht verstanden warum. Aber es scheint so, als ob der Weg stimmt.

      Michael schrieb:

      Snatch schrieb:

      Ich verstehe deinen ersten Satz nicht. Was schleppt er mit?
      Das hatte ich doch in Beitrag 8 geschrieben, ich meine das Steuerzeichen.Oder was ist das am Anfang deines Telegramms in Bild 2+3?

      Snatch schrieb:

      Wisst ihr, dass ist nicht das erste mal, dass ich mit Bascom über RS232 oder RS485 Daten verarbeite. Ich habe hier eine Software auf meinem Tablet, womit ich meine Schaltungen Steuere. Aber gerade bei dieser Applikation geht es nicht und ich schnall es einfach nicht.
      Weißt du, es ist nicht das erste mal, dass sich einer verrennt. Ich hoffe du verstehst, wie dein Satz hier ankommt.Ich hatte ja schon vermutet, dass da eine Software dahinter steckt. In Beitrag 12 schreibst du zwar von Hterm, aber später ist es dann doch was anderes.
      Hast du meinen Rat aus Beitrag 8 mal ausprobiert?
      Wird CR-LF von deiner Software wirklich erwartet oder nur CR?
      In Beitrag 8 Schreibst du, dass sich mein Terminal Programm, also HTerm daran verschluckt. Aber das kann nicht sein, weil mein Oszi beweist, dass der µC den String gar nicht erst zurück sendet und der deswegen nicht angezeigt wird (Siehe Bild 3).

      Bild 2 zeigt links den String den ich hinsende und rechts die Antwort, welche auch in HTerm am PC angezeigt wird.

      Eine Sekunde später sende ich den gleichen String los, es kommt aber nur ein leerer Sting mit cr+lf zurück (Bild 3). Starte ich den µC neu geht es wieder für genau ein Mak.

      Nein sorry, da hast du falsch vermutet. Ich teste hier nur mit Hterm. Die Software habe ich nur als weiterer Test verwendet, da es hieß, dass HTerm was mitsendet was es nicht sollte. Daher habe ich es mal kurz händisch versucht. Aber alles was wir hier testen etc. kommt über HTerm ohne eigene Software. Also kein Grund zu vermuten, dass das Problem aus eigener Software kommt.
      Der Satz ist missverständlich, dass stimmt. Aber ich meinte damit, dass es bei anderen Aplikationen ohne Probleme geht und bei dieser, die wir hier testen nicht. Trotz gleicher Hardware.

      Grüße,

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Snatch ()

    • Snatch schrieb:

      Quellcode

      1. '*******************************************************************************'*
      2. ISR wird ausgelöst, wenn Serielle Daten (CR) empfangen wurden *'*******************************************************************************
      3. SUB Serial0charmatch()
      4. Local Incoming_data As String * 30 'Daten vom Buffer auslesen
      5. Input Incoming_data Noecho 'Ausgelesene Daten zurück schicken
      6. Print Incoming_data
      7. Incoming_data = ""
      8. END SUB
      Hallo Zusammen.

      Habe beim flotten Durchlesen folgenden Vorschlag noch nicht gelesen:

      BASCOM HILFE schrieb:

      When using the BYTEMATCH option, you must preserve the registers you alter. If you do not know which one, use PUSHALL and POPALL.
    • Galahat schrieb:

      Snatch schrieb:

      Quellcode

      1. '*******************************************************************************'*
      2. ISR wird ausgelöst, wenn Serielle Daten (CR) empfangen wurden *'*******************************************************************************
      3. SUB Serial0charmatch()
      4. Local Incoming_data As String * 30 'Daten vom Buffer auslesen
      5. Input Incoming_data Noecho 'Ausgelesene Daten zurück schicken
      6. Print Incoming_data
      7. Incoming_data = ""
      8. END SUB
      Hallo Zusammen.
      Habe beim flotten Durchlesen folgenden Vorschlag noch nicht gelesen:

      BASCOM HILFE schrieb:

      When using the BYTEMATCH option, you must preserve the registers you alter. If you do not know which one, use PUSHALL and POPALL.

      Ich hab' das gelesen, konnte aber nix damit anfangen. Es wird doch eine isr nach dem interrupt angesprungen, da werden doch alle Register gesichert. Wann und wo sollte man das noch tun?
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Galahat schrieb:

      Habe beim flotten Durchlesen folgenden Vorschlag noch nicht gelesen:
      Ja das war ja meine Vermutung mit Empfangspuffer zurücksetzen. Da er aber warum auch immer Local Incoming_data As String * 30 in die Sub schreibt, hatte ich bedenken.
      Lokale Variablen verhalten sind anders als globale.
      Könnte Reentranz- Probleme mit sich bringen. Muss zugeben dieses Thema ist für mich zu hoch. Hatte nur die Erfahrung gemacht mit Pushall und Popall gab es mit Lokal Probleme.

      Einfach mal testen.

      SUB Serial0charmatch()
      Local Incoming_data As String * 30
      Pushall
      Input Incoming_data Noecho
      Popall
      Print Incoming_data
      Incoming_data = "" ‘Macht auch keinen Sinn wird ja wieder vom Puffer befüllt.
      END SUB

      Vorabtest:
      String * 30 auf String*6 setzen. „Hallo“ + CR = 6.

      Begründung:
      Wer die Bascom-Funktion Input nutzt. Muss wissen das diese Funktion intern nach der Poll-Methode arbeitet und kehrt erst zurück, wenn alle angegebenen Bytes empfangen wurden.
      Will man mit Input z.B. Zeichen in einen String einlesen, der mit 30 Bytes Länge dimensioniert wurde, dann kehrt Input erst zurück, wenn tatsächlich 30 Bytes empfangen wurden, vorher nicht. Im Terminalprogramm macht es den Anschein, dass das Programm spinnt.

      Mit freundlichen Grüßen
    • @fredred das input auf die 30 Buchstaben wartet, glaub ich nicht. Bei numerischen Daten, wird gewartet, bis die Anzahl der bytes für das Zahlenformat eingetrudelt sind, da gebe ich dir Recht. Beit Text ist das wohl nicht so, wie das diverse Beispiele aus der bascom-Hilfe zeigen.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Quellcode

      1. $REGFILE = "m644def.dat"
      2. $CRYSTAL = 8000000
      3. $hwstack = 50
      4. $swstack = 50
      5. $framesize = 70
      6. $BAUD = 9600
      7. CONFIG Serialin = Buffered , Size = 100 , Bytematch = 13
      8. CONFIG Print = PORTb.2 , Mode = SET
      9. CONFIG PORTb.2 = OUTPUT
      10. DECLARE SUB Serial0charmatch()
      11. ENABLE INTERRUPTS
      12. DO
      13. LOOP
      14. END
      15. SUB Serial0charmatch()
      16. Local Incoming_data As String * 6
      17. Pushall
      18. Input Incoming_data Noecho
      19. Popall
      20. Print "EMPFANGEN: " ; Incoming_data
      21. END SUB
      Alles anzeigen
      Genau das gleiche. Einmal geht es, dann wieder nur leere die Zurückkommt.
      Ich werde nun hier abbrechen und mir die Elektronik nochmals ansehen bzw. das Layout etwas anpassen.
      Ich glaube langsam nicht mehr daran, dass die Software spinnt.

      Grüße und vielen lieben Dank an alle!
    • tschoeatsch schrieb:

      @fredred das input auf die 30 Buchstaben wartet, glaub ich nicht. Bei numerischen Daten, wird gewartet, bis die Anzahl der bytes für das Zahlenformat eingetrudelt sind, da gebe ich dir Recht. Beit Text ist das wohl nicht so, wie das diverse Beispiele aus der bascom-Hilfe zeigen.

      Systembedingt wird die Uart- Schnittstelle als Zeichenkette betrachtet und grundsätzlich Byte für Byte übertragen. Ob Byte eine Zahl, Buchstabe oder ein Steuerzeichen ist interessiert in der Übertragung nicht.
      Serial0charmatch() rattert im Hintergrund also bremst die Hauptschleife nicht aus.

      Aber, aber wie es so oft ist. Muss einiges beachtet werden. Nur ein Byte hin und her schicken ist kein Problem aber wir wollen ja mehrere. Somit benötigen wir einen Puffer und die Speicherkontrolle übernimmt [Ischarwaiting]. Also erst wenn der Puffer nach Vorgabe befüllt ist
      wird der Inhalt in einem Ruck in Variable geschrieben. Somit sollte die Puffergröße optimal sein.
      Für Test nutze ich eine Variable. Puffer = Ischarwaiting() Print Puffer.


      Möchte auch hier betonen sind meine Praxiserfahrungen und nicht immer gleich BASCOM- Hilfe.

      Gruß

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von fredred ()

    • Hallo Snatch,
      meiner Meinung nach ist dein Hauptproblem, dass du in der Sub das Print machst. Dieses Print dauert genau so lange, wie der Empfang gedauert hat.
      Während dieser Zeit ist dein UART praktisch taub. Dies, weil die Sub aus der ISR im Hintergrund aufgerufen wird, sobald dein ByteMatch Zeichen empfangen wurde. Zu diesem Zeitpunkt sind Interrupts aber immer noch global ausgeschaltet. Die Zeichen werden von der HW zwar empfangen, aber keiner liest sie aus.
      Also mein Rat, setze ein Flag (eine Variable) in der Sub und frage diese in der Hauptschleife periodisch ab. Wenn sie gesetzt ist, kannst du printen.
      Der Compiler rettet übrigens nur die Register, die in der Hintergrund ISR genutzt werden. Dieser werden nach Beendigung der Sub wieder zurückgeschrieben.
      Die Register, die in deiner Sub benutzt werden, musst du selber sichern. Weil man meistens nicht weiß, welche das sind, gibt die Hilfe den Vorschlag Pushall zu benutzen.
      Dein Popall muss dazu aber hinter den letzten Befehl innerhalb der Sub.
    • Galahat hat da schon den richtigen Hinweis gegeben:

      Quellcode

      1. $REGFILE = "m644def.dat"
      2. $CRYSTAL = 8000000
      3. $hwstack = 50
      4. $swstack = 50
      5. $framesize = 64
      6. Dim S As String * 20
      7. Config Serialin = Buffered , Size = 20 , Bytematch = 13 ' Serieller Port ist für den Empfang gepuffert und härt auf Zeichen 13 (CR)
      8. Enable Interrupts
      9. Do
      10. Loop
      11. Serial0charmatch:
      12. Pushall
      13. Input S Noecho 'without echo
      14. Print S
      15. Popall
      16. Return
      Alles anzeigen
      Im Simulator getestet, wobei der Bascom Simulator noch immer Probleme mit UDRE hat. Die Zeichen werden erst rausgetaktet, wenn man den Interrupt manuell im "Interrupts" Tab auslöst.

      Falls SerialXCharMatch ein Sub sein soll (was es laut Hilfe nicht sein soll) muss das Pushall vor dem Local stehen.
    • hero schrieb:

      meiner Meinung nach ist dein Hauptproblem, dass du in der Sub das Print machst.
      Ja hatte ich auch als erstes vermutet. @Snatch hat dann Print in die Hauptschleife gelegt. Ohne Erfolg wie er vermittelt.

      hero schrieb:

      Also mein Rat, setze ein Flag (eine Variable) in der Sub und frage diese in der Hauptschleife periodisch ab. Wenn sie gesetzt ist, kannst du printen.
      Macht er ja in dem er sagt wenn im Puffer 30 Byte sind, dann ab in Variable und dann printen. Ist doch eine abfrage nach Vorgabe.
      Nun mich mal mit RS485 beschäftigt.
      Wie schon geschrieben.
      Der µC muss halt wissen wann ein Paket komplett empfangen wurde. Ist schon sehr von der Aufgabe abhängig.
      Kannst natürlich auch wie bei einem Modem abfragen wenn x µs nix übertragen wurde ist das Paket komplett.

      Oh die Richtungsumschaltung des RS485 mit Basom möchte ich nun wirklich nicht mehr verstehen müssen.
      CONFIG Print = PORTb.2 , Mode = SET
      CONFIG PORTb.2 = OUTPUT

      Eins würde mich nur noch interessieren, warum muss es ein RS485 sein?

      Gruß
    • Hallo fredred,
      im Moment steht der Print Befehl jedenfalls im Interrupt und da der Controller keine 30 Byte Ausgabepuffer hat, wird er dort solange verweilen, bis das letzte Zeichen raus ist.
      Und nein, macht er eben nicht. Die 30 Zeichen stehen erst im Puffer, dann in seiner Variablen S und dann wird gewartet, bis sie geprintet sind. Solange wird nur ein einziges Zeichen eingelesen.
      Man kann das jetzt akzeptieren oder nicht, aber in einer ISR printet man grundsätzlich nicht.
      Und da in der Hauptschleife kein Register verwendet wird, hat es zunächst auch mal nichts mit dem Push- und Popall zu tun.
    • Das ist das Dissassembly von der ISR die Bascom für Buffered SerialIn anlegt:

      Quellcode

      1. 00000127 7f.93 PUSH R23 Push register on stack
      2. 00000128 0f.93 PUSH R16 Push register on stack
      3. 00000129 af.93 PUSH R26 Push register on stack
      4. 0000012A bf.93 PUSH R27 Push register on stack
      5. 0000012B 8f.93 PUSH R24 Push register on stack
      6. 0000012C 9f.93 PUSH R25 Push register on stack
      7. 0000012D 8f.b7 IN R24,0x3F In from I/O location
      8. 0000012E 8f.93 PUSH R24 Push register on stack
      9. 0000012F e8.94 CLT Clear T in SREG
      10. 00000130 80.91.8b.00 LDS R24,0x008B Load direct from data space
      11. 00000132 04.e1 LDI R16,0x14 Load immediate
      12. 00000133 08.1b SUB R16,R24 Subtract without carry
      13. 00000134 21.f4 BRNE PC+0x05 Branch if not equal
      14. 00000135 9c.b1 IN R25,0x0C In from I/O location
      15. 00000136 0e.94.17.01 CALL 0x00000117 Call subroutine
      16. 00000138 13.c0 RJMP PC+0x0014 Relative jump
      17. 00000139 00.91.8a.00 LDS R16,0x008A Load direct from data space
      18. 0000013B a5.e7 LDI R26,0x75 Load immediate
      19. 0000013C b0.e0 LDI R27,0x00 Load immediate
      20. 0000013D 77.27 CLR R23 Clear Register
      21. 0000013E 9c.b1 IN R25,0x0C In from I/O location
      22. 0000013F a0.0f ADD R26,R16 Add without carry
      23. 00000140 b7.1f ADC R27,R23 Add with carry
      24. 00000141 9c.93 ST X,R25 Store indirect
      25. 00000142 68.94 SET Set T in SREG
      26. 00000143 83.95 INC R24 Increment
      27. 00000144 80.93.8b.00 STS 0x008B,R24 Store direct to data space
      28. 00000146 03.95 INC R16 Increment
      29. 00000147 04.31 CPI R16,0x14 Compare with immediate
      30. 00000148 09.f4 BRNE PC+0x02 Branch if not equal
      31. 00000149 00.27 CLR R16 Clear Register
      32. 0000014A 00.93.8a.00 STS 0x008A,R16 Store direct to data space
      33. 0000014C 9d.30 CPI R25,0x0D Compare with immediate
      34. 0000014D 11.f4 BRNE PC+0x03 Branch if not equal
      35. 0000014E 0e.94.50.00 CALL 0x00000050 Call subroutine
      36. 00000150 8f.91 POP R24 Pop register from stack
      37. 00000151 8f.bf OUT 0x3F,R24 Out to I/O location
      38. 00000152 9f.91 POP R25 Pop register from stack
      39. 00000153 8f.91 POP R24 Pop register from stack
      40. 00000154 bf.91 POP R27 Pop register from stack
      41. 00000155 af.91 POP R26 Pop register from stack
      42. 00000156 0f.91 POP R16 Pop register from stack
      43. 00000157 7f.91 POP R23 Pop register from stack
      44. 00000158 18.95 RETI Interrupt return
      Alles anzeigen
      In Zeile 35 ist der Sprung zum Serial0CharMatch-Label. Werden also in der Serial0CharMatch-Routine andere Register als R16 und R23-R27 verwendet, kann das zu Problemen führen.

      Mit Flow-Control in Bascom habe ich noch nicht gearbeitet, aber in diesem Beispiel geht das problemlos. Ohne Buffered-SerialOut benötigt der Print Befehl so lange, bis das letzte Zeichen gesendet wurde. So lange bleibt auch der Controller in der Interrupt-Routine. Den Anforderungen nach stört das nicht...
      Buffered SerialOut ist ähnlich wie SerialIn Interrupt-basiert und wird wohl auch funktionieren, aber den UDRE mag der Bascom-Simulator nicht so gerne, daher habe ich das in dem Minimal-Beispiel auch weggelassen