Hexdaten über die serielle Schnittstelle empfangen und auswerten

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • In dem Fall wohl nicht das Echo sondern übersprechen auf floating Rx. Wenn die Möglichkeit besteht das da nichts dranhängt würde ich den Pullup aktivieren oder einen extern dranhängen. Jedes Low "stört" den Avr. Er denkt es gibt was zu empfangen und füllt den Buffer mit Quatsch.

      Ralf wrote:

      Der positive Nebeneffekt ist, das ich $timeout dann nicht benötige, es ist immer was da zum lesen
      und ich werte ja aus, ob der Header stimmt.
      Nicht so ganz. Wenn der Sensor abgeklemmt ist kann eine Brücke von Tx zu Rx das bewerkstelligen. Antwortet er aber nicht wird das Timeout benötigt.
    • Pluto25 wrote:

      In dem Fall wohl nicht das Echo sondern übersprechen auf floating Rx. Wenn die Möglichkeit besteht das da nichts dranhängt würde ich den Pullup aktivieren oder einen extern dranhängen. Jedes Low "stört" den Avr. Er denkt es gibt was zu empfangen und füllt den Buffer mit Quatsch.
      Hast 100% Recht! Wenn ich den Eingang auf Masse lege, verhält sich das Programm wie erwartet.
      Erstaunlich, das er wirklich jedes Mal sauber die Kennung vom Sendebefehl drin hat!


      Pluto25 wrote:

      Nicht so ganz. Wenn der Sensor abgeklemmt ist kann eine Brücke von Tx zu Rx das bewerkstelligen. Antwortet er aber nicht wird das Timeout benötigt.
      Hab ich jetzt so gemacht, das Problem ist gelöst!

      Wirklich ein klasse Forum hier, ohne euch hätte ich schon oft im Regen gestanden. a_17_af3b400f
      Besten Dank und einen schönen Abend.

      Gruß Ralf
    • BASCOM Source Code

      1. Config Com3 = 115000 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
      2. Open "Com3:" For Binary As #3
      3. On Urxc Daten_tfmini_isr
      Wie gebe ich den bei der Interruptroutine den entsprechenden Kanal an?
      Alles versucht #3 eingefügt mit und ohne Kommas, es funktioniert nicht.
    • So müßte es nach dem, was ich gefunden habe funktionieren:

      BASCOM Source Code

      1. Config Com3 = 115000 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
      2. Open "Com3:" For Binary As #3
      3. On Urxc3 Daten_tfmini_isr
      4. Enable Urxc3
      5. Enable Interrupts
      6. Daten_tfmini_isr:
      7. Locate 2 , 1 : Lcd "Pointer_tfmini"
      8. If Flag_datentfmini = 0 Then
      9. Tfmini(pointer_tfmini) = Udr
      10. Incr Pointer_tfmini
      11. If Pointer_tfmini > 10 Then
      12. Flag_datentfmini = 1
      13. End If
      14. End If
      15. Return
      Display All
      Klappt aber nicht.
    • Ralf wrote:

      Klappt aber nicht.
      Du hast nicht gesagt, welchen Prozessor du benutzt, oder habe ich das überlesen?
      Ich frage da jetzt auch nicht danach, ich wollte nur mal auf die geschwindigkeitssteigernde Möglichkeit hinweisen, die das Posten des Programmes bieten kann.
      Oft sieht man dann den Fehler, ohne raten zu müssen.
      So wie du schreibst, scheint es ja eilig zu sein und der Thead ist schon 2 Tage alt.
    • Hallo Michael,

      hab nur das Wesentliche rauskopiert, das Programm hat mittlerweile fast 450 Zeilen.

      Da laufen 6 Interrupts und der serielle wird dadurch blockiert.
      Ich habe mal die Sachen, die für diesen Interrupt zuständig sind
      in eine neue Datei kopiert, da klappt es sofort, ist also so richtig.

      Ich schau mir das jetzt mal in Ruhe an.

      Danke dir!
    • Michael wrote:

      So wie du schreibst, scheint es ja eilig zu sein und der Thead ist schon 2 Tage alt.
      Montag wollte ich es fertig haben, kann es aber noch ein paar Tage rauszögern.
      Im Prinzip funktioniert alles, bis auf ein kleines technisches Detail. Weiß
      aber nicht, ob das interessiert.
    • Bilder vom Projekt hatte ich ja schon mal reingestellt.

      Ich hab das gestern fertig programmiert und es hat alles einwandfrei geklappt, aber...

      Erhöhe ich die Drehzahl der Motoren, dann habe ich im oberen Bereich den Effekt, das sie
      für dem Bruchteil einer Sekunde kurz stoppen und sofort wieder anfahren wenn ich die Daten
      vom Distanzsensor anfordere. Die Motore haben richtig Power und die Mechanik eine nicht
      zu vernachlässigende Trägheit. Da gibt es jedesmal ein unschönes Ruckeln

      six1 wrote:

      1) Array of Byte definieren
      2) Variable "Pointer auf Array" erstellen (Byte)
      2) wenn Zeit ist, Pointer auf Element 0 stellen
      3) Anfrage an Sensor senden
      4) Ankommende Bytes im Interrupt in Array schreiben, Pointer erhöhen
      5) wenn Pointer Arraygrenze erreicht, Flag für gültige Daten setzen
      6) Solange Flag für gültige Daten gesetzt, keine Daten mehr annehmen im Interrupt!
      7) ganz gemütlich in der Hauptschleife reagieren, wenn Flag für gültige daten an ist, CRC prüfen, Daten verwenden
      8 ) Pointer wieder zurücksetzen auf Element 0, Flag gültige daten zurücksetzen

      vielleicht noch einen Timoutzähler, welcher Sensoranfrage nach einer gewissen Zeit alles zurücksetzt, falls etwas außer Tritt kommt

      so ähnlich würde ich das machen...
      six1 hatte ja gestern einen guten Vorschlag gemacht, den ich aber verworfen hatte, weil in dem Drehzahlbereich wo ich es getestet habe keine Probleme aufgetreten sind, den wollte ich jetzt umsetzen.

      Die Takte zum Steuern der Motoren haben im oberen Bereich eine Periodendauer von 0,3mS, das Anfordern der Daten dauert ca. 1,3ms. Eine Zeitverzögerung von bis zu 5ms ist akzeptabel, da läuft es noch flüssig.
      Was ich nicht berücksichtigt hatte ist, das der Sensor ja Zeit zum Messen braucht und das sind ungefähr 7ms, die kommen zu den 1,3ms noch dazu. Deshalb ruckelt es halt. Da das Projekt für eine sehr lange Laufzeit ausgelegt ist, ist das nicht so gut.
      Ich könnte es abmildern, indem ich die Parameter in den Servosteuerungen ändere, so das es weicher läuft, wollte aber eben erst mal den Vorschlag von six1 umsetzen.
      Hoffe, es klingt nicht zu verworren.
    • Ralf wrote:

      das der Sensor ja Zeit zum Messen braucht und das sind ungefähr 7ms
      Mangels gescheitem Datenblatt kann ich das nicht nachvollziehen.
      Aber folgt man dem 1. Link im 1.Post dann gibt es dort eine Art Manual, wo von 115200 Baud und 9 Bytes die Rede ist. Das sind etwa 0,8 ms.
      Da ich dein Programm nicht kenne, kann ich dir keinen Rat geben, sonst würde ich fragen, ob du FP Routinen benutzt, aber das mach ich jetzt nicht.
    • Michael wrote:

      Aber folgt man dem 1. Link im 1.Post dann gibt es dort eine Art Manual, wo von 115200 Baud und 9 Bytes die Rede ist. Das sind etwa 0,8 ms.
      Genau, ich hatte aber nicht daran gedacht, das der Sensor nach dem Anfordern der Daten ja Zeit braucht um die Distanz zu messen. Er schickt die nicht ohne Verzögerung und braucht doch einige Millisekunden. Ich finde den TF Mini-S übrigens richtig Klasse, er ist wirklich genau und auch noch preisgünstig.

      Ich schau mit Morgen das Programm noch mal genau an, aber eine kleine Änderung ist da nicht möglich, ich hab zuviel Kram in den ISR untergebracht und müßte das komplett umschreiben. a_27_b277ca12
      Ist aber nicht so tragisch, es tut genau was es soll und nach der Prüfung habe ich noch alle Zeit der Welt, das zu optimieren.

      Ich kann dann gerne hier einen Link zur Ausstellung reinstellen, die kennt mit Sicherheit jeder.
      Wenn ich mich blamiere, lasse ich das natürlich. ;)
    • Ralf wrote:

      ch hatte aber nicht daran gedacht, das der Sensor nach dem Anfordern der Daten ja Zeit braucht um die Distanz zu messen. Er schickt die nicht ohne Verzögerung und braucht doch einige Millisekunden.
      Musst du wirklich warten? Dein UART sammelt normalerweise die Daten im Hintergrund und du brauchst nur in Aktion treten, wenn alles da ist.

      Ralf wrote:

      Ich finde den TF Mini-S übrigens richtig Klasse, er ist wirklich genau und auch noch preisgünstig.
      Den Preis im Link finde ich alles andere als preiswert.
      Deine Anwendung ist leider ein Geheimnis.
      Hier hatte ich einen preisgünstigen Sensor im Test: VL53L0X Time-of-Flight Distance Sensor Carrier with Voltage Regulator
      Der geht halt nur bis 2m


      Ralf wrote:

      ich hab zuviel Kram in den ISR untergebracht und müßte das komplett umschreiben.
      Das Problem haben alle Anfänger, alles in den Interrupt.
      Dabei ist doch die goldene Regel, so wenig wie möglich dort machen und sofort wieder verlassen.
      Die Hauptarbeit muss im Hauptprogramm bleiben, dann geht das auch mit mehr als einem Interrupt.
    • Hab gestern einen Fehler gemacht im geposteten Programm, habe das "do loop" vergessen und da ist das Programm dann in der ISR gelandet.

      So sollte es eigentlich aussehen:


      BASCOM Source Code

      1. $regfile = "m2560def.dat" ' specify the used micro
      2. $crystal = 16000000 ' used crystal frequency
      3. $baud = 9600
      4. $hwstack = 64 ' default use 32 for the hardware stack
      5. $swstack = 20 ' default use 10 for the SW stack
      6. $framesize = 80 ' default use 40 for the frame space
      7. Config Com3 = 115000 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
      8. Open "Com3:" For Binary As #3
      9. On Urxc3 Daten_tfmini_isr 'define serial receive ISR
      10. Config Lcdpin = Pin , Db4 = Portg.5 , Db5 = Porte.3 , Db6 = Porth.3 , Db7 = Porth.4 , E = Porth.6 , Rs = Porth.5
      11. Config Lcd = 16 * 2 'configure lcd screen
      12. Cls
      13. Cursor Off
      14. Enable Urxc3 'enable receive isr
      15. Enable Interrupts
      16. Do
      17. Printbin #3 , 90 ; 4 ; 4 ; 98
      18. Wait 1
      19. Loop 'Datensatz anfordern
      20. Daten_tfmini_isr:
      21. Locate 2 , 1 : Lcd "ISR URXC"
      22. Waitms 3000
      23. Return
      24. End
      Display All
      Warum landet das Programm nicht in der ISR, sieht jemand den Fehler?
    • Michael wrote:

      Nein, aber benutzt deine Hardware PortD.2 und D.3 ?
      Läuft dein LCD schon? Ich würde in Zeile 17 mal ein Hallo schreiben.
      LCD und Wartezeiten im Interrupt sind tödlich. Setz dort ein Flag oder lass eine LED einschalten.
      Wenn das UDR nicht geleert wird im Interrupt, dann gibt es keinen Interrupt mehr.
      Hat sich überschnitten mit meiner Antwort.
      Da hab ich wirklich stundenlang gesucht!

      Danke!
    • Michael wrote:

      Steht im Datenblatt. Auch das Datfile deines Prozessors hilft ein bissschen.
      Gute Idee, hätte ich mal schauen sollen.

      Michael wrote:

      Deshalb meine Frage nach der Hardware, ist das ein Geheimnis?
      Meinst du den Prozessor? Ein Mega2560, steht jeweils im Programm.

      Es läuft jetzt absolut ruckelfrei. Die Daten rufe ich in der ISR ab, wie es six1 vorgeschlagen hat.

      Vielen Dank noch Mal.
    • Michael wrote:

      Steht im Datenblatt. Auch das Datfile deines Prozessors hilft ein bissschen.

      Ralf wrote:

      Gute Idee, hätte ich mal schauen sollen.
      Was auch hilfreich und wenig bekannt ist, ist die Tastenkombination CTRL-SPACE.

      CTRL-SPACE gibt dir immer kontext-sensitive Vorschläge, auch zu Variablennamen, Labeln und ähnliches.
      Gibst du z.B. "On " ein und dann CTRL-SPACE wird dir eine Liste aller Interrupts angezeigt, die dein Prozessor hat.

      Da siehst du dann auch, dass die UART Interrupts hier URXC, URXC1, URXC2 und URXC3 heißen.
      Das ist jetzt ein wenig der Historie geschuldet, wo Controller nur einen UART hatten und der dann über URXC und UDR usw angesprochen wurde. So war das auch bei Atmel. Dann haben die welche mit zwei oder mehr UARTS herausgebracht und haben dann bei 0 (URXC0) mit der Bezeichnung angefangen. MCS ist dem nicht so ganz gefolgt, wahrscheinlich aus Kompatibilitätsgründen. Korrekt wäre gewesen, sie hätten bei solchen Chips URXC nicht erlaubt, sondern nur URXC0 und URXC1 usw. Selbst auf die Gefahr hin, das beim Portieren auf einen anderen Controller dann Fehlermeldungen kommen.
    • Franz wrote:

      Was auch hilfreich und wenig bekannt ist, ist die Tastenkombination CTRL-SPACE.

      CTRL-SPACE gibt dir immer kontext-sensitive Vorschläge, auch zu Variablennamen, Labeln und ähnliches.
      Gibst du z.B. "On " ein und dann CTRL-SPACE wird dir eine Liste aller Interrupts angezeigt, die dein Prozessor hat.
      Klasse, das war mir neu.

      Auf jeden Fall eine Menge gelernt in den letzten Tagen. Scheint jetzt zu Laufen, teste jetzt noch mal alles in Ruhe durch.