-
        

Seite 1 von 4 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 33

Thema: Optimieren von UART-Komunikation, bitte um Meinungen

  1. #1
    RN-Premium User Fleißiges Mitglied
    Registriert seit
    19.05.2012
    Ort
    Sigmaringen
    Beiträge
    169

    Optimieren von UART-Komunikation, bitte um Meinungen

    Anzeige

    Ich habe für mein aktuelles Projekt Datenpakete per UART zu empfangen.

    Vorgabe ist das empfangen von 16Byte für die weiterverarbeitung im Hauptprogramm.
    Aktuell ist es so gelöst, das die Pakete jeweils mit einem vorgegebenen Startzeichen beginnen müssen.
    Diese sind dann entweder bis 16Byte begrenzt oder werden durch ein vorgegebenes Endzeichen abgeschlossen.

    Ich möchte mir damit eine art Universelle Übertragung schaffen, die ich für weitere Projekte einfach anpassen kann.

    Der Code sieht so aus:
    Code:
    '-------------------------------------------------------------------------------
    'Variablen
    '-------------------------------------------------------------------------------
    Dim Temp_byte As Byte
    Dim Datenblock(16) As Byte
    Dim Indexposition As Byte
    Dim Startzeichen As String * 1
    Startzeichen = "{"
    Dim Endzeichen As String * 1
    Endzeichen = "}"
    Dim Datenblock_komplett As Bit
    Dim Datenblock_laenge As Byte
    Datenblock_laenge = 16
    
    Dim Datenblock_string As String * 16
    '-------------------------------------------------------------------------------
    'Hauptprogramm
    '-------------------------------------------------------------------------------
    
    Do
    
     If Datenblock_komplett = 1 Then
        For Indexposition = 1 To Datenblock_laenge Step 1
           Insertchar Datenblock_string , Indexposition , Datenblock(indexposition)
        Next
        Print Datenblock_string
        Datenblock_string = ""
        Datenblock_komplett = 0
     End If
    
    Loop
    
    End
    
    
    '-------------------------------------------------------------------------------
    'Interrupt
    '-------------------------------------------------------------------------------
    
    Serial0charmatch:
    
    While Ischarwaiting() = 1
       Temp_byte = Inkey()
       waitus 2000
       If Temp_byte = Asc(startzeichen) Then
          Indexposition = 0
          Datenblock_komplett = 0
       Elseif Temp_byte = Asc(endzeichen) Then
          Datenblock_komplett = 1
       Else
          Indexposition = Indexposition + 1
          Datenblock(indexposition) = Temp_byte
       End If
       If Indexposition = Datenblock_laenge Then
          Datenblock_komplett = 1
          Clear Serialin
       End If
    Wend
    
    If Indexposition < Datenblock_laenge Then
       Do
          Indexposition = Indexposition + 1
          Datenblock(indexposition) = 0
       Loop Until Indexposition = Datenblock_laenge
       Datenblock_komplett = 1
    End If
    
    Return
    Funktioniert soweit auch zufriedenstellend.
    Kurz noch Beispiele...
    Code:
    {1234567890123456}   ergibt   1234567890123456
    {123456   ergibt   123456
    {123456}   ergibt   123456
    123456   ergibt  "nix" (weil kein Startzeichen)
    Allerdings möchte ich gerne eure Meinung hören, inwieweit es da zu Problemem kommen kann,
    oder ob man das noch optimieren könnte (speziell wegen der Abarbeitungszeit im Interupt).

    Derzeit wird per Kabel übertragen... soll aber die nächsten Tage durch ein Funkmodul (APC220) ersetzt werden.

    P.S. ... sorry, das es nicht auskommentiert ist... sollte aber trotzdem leicht überschaubar sein.
    Geändert von JoeM1978 (03.03.2013 um 20:39 Uhr)
    JAAAA... Microchips kann man essen... aber der Geschmack ist furchtbar.

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    46
    Beiträge
    765
    Start, Endzeichen und Datenblocklänge würde ich als Konstante hinterlegen. Spart Laufzeit.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  3. #3
    RN-Premium User Fleißiges Mitglied
    Registriert seit
    19.05.2012
    Ort
    Sigmaringen
    Beiträge
    169
    Joa... hast du recht. werd ich noch anpassen.

    Generell geht es mir aber mehr um das einlesen der Bytes in das Array... und späther um das Entschlüsseln
    in einzelne "Komandos" ... bzw was ich da jetzt schon für Probleme vermeiden könnte.

    In die Gegenrichtung (also senden) werde ich ebenso ein System einfügen mit vermutlich16byte-paketen.
    Damit werden dann sensordaten zum pc (zur auswertung) gesendet.

    EDIT:
    Nachdem gestern das Programm im test funktionierte... heute auf einmal nicht... musste ich fehlersuche betreiben.
    Anscheinend ist die Routine für meine derzeitige Baudrate (9600) ZU SCHNELL.
    Ich hatte im test hier 2 printbefehle drinn. Dann hats funktioniert.

    Also... Ich habs getestet... es werden rund 1500 bis 2000 us Wartezeit benötigt bis überhaupt die Zeichen aus dem
    Serial-buff verwendbar sind. Dann geht es wieder
    Geändert von JoeM1978 (03.03.2013 um 20:38 Uhr)
    JAAAA... Microchips kann man essen... aber der Geschmack ist furchtbar.

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    46
    Beiträge
    765
    Das ist mir noch nicht passiert. Allerdings arbeite ich mit ischarwaiting() in der Hauptschleife. Die Interruptroutine nutze ich nur bei Softuart. Pausen brauchte ich bisher aber nie einbauen.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437

    Beitrag

    Zitat Zitat von JoeM1978 Beitrag anzeigen
    inwieweit es da zu Problemem kommen kann
    Zitat Bascom Hilfe:
    When using the BYTEMATCH option, you must preserve the registers you alter.
    oder ob man das noch optimieren könnte
    Ich versteh nicht so recht, was das werden soll, aber 2ms in einem Interrupt zu warten, funktioniert gar nicht.
    Ist da vielleicht ein BYTEMATCH = ALL in der Config drin ? Dann führt der Code in Verbindung mit dem gepufferte Serialin in's Leere, kurz macht die ganze Sache sinnlos.
    Da baut man sich besser selbst 'ne Routine auf Basis des URXC-Interrupts auf.
    Anscheinend ist die Routine für meine derzeitige Baudrate (9600) ZU SCHNELL.
    Halte ich für ein Gerücht, wenn der Code nur mit Delay funktioniert, ist der Wurm drin.
    Mein Gefühl von der ganzen Konstruktion ist, die ist reif für die Tonne
    Geändert von MagicWSmoke (03.03.2013 um 23:06 Uhr)

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    08.07.2008
    Beiträge
    6
    Ich kann dir nur empfehlen, die Lib von P.Fleury zu benutzen. Das spart dir viel Ärger und Sucherei und die Lib funktioniert.

    http://homepage.hispeed.ch/peterfleu...-software.html

    Gruss Hambone

  7. #7
    Erfahrener Benutzer Roboter Genie Avatar von Michael
    Registriert seit
    17.01.2004
    Ort
    Karlstadt
    Alter
    48
    Beiträge
    1.254
    Hallo Hambone,
    Ich kann dir nur empfehlen, die Lib von P.Fleury zu benutzen.
    kannst du bitte noch kurz erklären, wie man die in Bascom einbindet?

    @Joe:
    Ist da vielleicht ein BYTEMATCH = ALL in der Config drin ?
    wenn du deinen ganzen Code posten würdest, bräuchte man nichts vermuten.

    Gruß, Michael

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    08.07.2008
    Beiträge
    6
    Oh, das weiss ich nicht, da ich Bascom nicht benutze. Ich arbeite mit GCC. GCC ist auch nicht schwerer als Basic. Ich habe früher mit verschiedenen Basic-dialekten gearbeitet und finde C auf Dauer besser, wenn auch an manchen Stellen gewöhnungsbedürftig (wie Kurzschreibwesen i++ --> i=i+1, wobei das noch harmlos ist.) . Aber es müsste im Forum etwas ähnliches geben. Der Vorteil der Fleury Lib ist, daß die von vielen Usern getestet ist und funktioniert.
    Ich kann mich erinnern, dass es früher bei Turbo-Pascal die Möglichkeit gab, C- und / oder Assembler Routinen in den Code einzubinden möglicherweise auch in Bascom?

    Gruss Hambone

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    46
    Beiträge
    765
    Inline ASM geht. C-Code lässt sich nicht so einfach einbinden. Ich habe unter Bascom mit dem UART keinerlei Probleme. Das hier beschriebene Problem kann überall liegen, da der Code nicht komplett da steht. Auch möglich, dass der AVR ins Nirvana läuft und dann neustartet und daher die Ausgabe passt.

    Ich nutze wie gesagt die IsCharWaiting() Methode ohne Interrupts. Evlt. noch buffered Empfang einstellen. Dann geht nichts verloren. Mein X300T Programm lässt nach dem Starten erstmal eine Meldung mehrere Sekunden übers Display laufen bevor es in die Mainloop geht und trotzdem kann ich einfach schon Daten losschicken. Da geht nichts verloren.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  10. #10
    RN-Premium User Fleißiges Mitglied
    Registriert seit
    19.05.2012
    Ort
    Sigmaringen
    Beiträge
    169
    So... der komplette code wäre dann:
    Es ist ohne diese Verzögerung in serial0charmatch.

    Das Funkmodul ist an sich schon in betrieb und ich kann dann wahlweise über Kabel oder Funk die Verbindung testen.

    Der Hinweis auf die Register ist von mir noch nicht geprüft...
    Da muss ich mich erst noch bissl einarbeiten... hab mich mit den Registern noch nicht wirklich beschäftigt.

    Was ich auch etwas seltsam finde...
    Wenn ich vom pc aus den port öffne und sende... ok. kommt an wie gedacht"... wenn ich den port aber trenne und
    ein zweites mal öffne sind irgendwelche "zeichen" im buffer, die mir das ganze array zerschiessen.
    wird beim trennen des ports auf der tx/rx-leitung noch was gesendet ??


    Code:
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    'Programmname:    UART-Schnittstelle.bas
    'Letzte Änderung: 03.03.2013
    'Funktion:        Empfang von gesamt 18Byte,
    '                 ausgabe als echo über seriell und lcd zur kontrolle
    'Mikrocontroller: Mega8
    '
    'Input:
    'Output:
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    'Den Atmega mit den passenden Daten füttern.
    '-------------------------------------------------------------------------------
    $regfile = "m8def.dat"                                      'eingesetzter Mikrocontroller
    $crystal = 8000000                                          'eingestellte Taktfrequenz (8MHz)
    $hwstack = 100                                              'Standardwert
    $swstack = 100                                              'Standardwert
    $framesize = 100                                            'Standardwert
    $baud = 9600
    
    '-------------------------------------------------------------------------------
    'Ports/Pins/Configs
    '-------------------------------------------------------------------------------
    
    '-------------------------------------------------------------------------------
    'Timer/OCR/PWM/ISR usw. setzen
    '-------------------------------------------------------------------------------
    Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
    Config Lcd = 16 * 2
    Config Serialin = Buffered , Size = 18 , Bytematch = 123    '123={
    Enable Interrupts
    
    '-------------------------------------------------------------------------------
    'Variablen
    '-------------------------------------------------------------------------------
    Dim Temp_byte As Byte
    Dim Datenblock(16) As Byte
    Dim Indexposition As Byte
    Dim Startzeichen As String * 1
    Startzeichen = "{"
    Dim Endzeichen As String * 1
    Endzeichen = "}"
    Dim Datenblock_komplett As Bit
    Dim Datenblock_laenge As Byte
    Datenblock_laenge = 16
    Dim Lcd_position As Byte
    Dim Datenblock_string As String * 16
    
    '-------------------------------------------------------------------------------
    'Hauptprogramm
    '-------------------------------------------------------------------------------
    Cls
    Waitms 100
    
    Do
       If Datenblock_komplett = 1 Then
       'UART-Datenblock in String füllen
          For Indexposition = 1 To Datenblock_laenge Step 1
             Insertchar Datenblock_string , Indexposition , Datenblock(indexposition)
          Next
       Disable Interrupts
       'Ausgabe/Abarbeiten des UART-Datenblock
          Cls
          Waitms 100
          For Indexposition = 1 To 3 Step 1
             Lcd_position = Indexposition
             Locate 1 , Lcd_position
             Lcd Chr(datenblock(indexposition))
          Next
          For Indexposition = 3 To Datenblock_laenge Step 1
             Lcd_position = Indexposition - 8
             Locate 2 , Lcd_position
             Lcd Chr(datenblock(indexposition))
          Next
       'Echo zurücksenden zur Kontrolle
          Print Datenblock_string
          Datenblock_string = ""
          Datenblock_komplett = 0
       Enable Interrupts
       End If
    Loop
    End
    
    '-------------------------------------------------------------------------------
    'Interrupt
    '-------------------------------------------------------------------------------
    
    Serial0charmatch:
    
    While Ischarwaiting() = 1
       Temp_byte = Inkey()
       Waitus 2000
    
       Locate 2 , 13
       Lcd Chr(temp_byte)
       Wait 1
    
       If Temp_byte = Asc(startzeichen) Then
          Indexposition = 0
          Datenblock_komplett = 0
       Elseif Temp_byte = Asc(endzeichen) Then
          Datenblock_komplett = 1
       Else
          Indexposition = Indexposition + 1
          Datenblock(indexposition) = Temp_byte
       End If
       If Indexposition = Datenblock_laenge Then
          Datenblock_komplett = 1
          Clear Serialin
       End If
    Wend
    
    If Indexposition < Datenblock_laenge Then
       Do
          Indexposition = Indexposition + 1
          Datenblock(indexposition) = 22
       Loop Until Indexposition = Datenblock_laenge
       Datenblock_komplett = 1
       Clear Serialin
    End If
    
    Return
    Das bytematch ist 123 (also wie das Startzeichen { )

    Nachtrag: ... bei dem jetzigen code... wenn ich die verzögerung rausnehm...

    Ich sende {xyz1234567890123}
    es kommt die ersten 2 vorgänge nur "leerstellen" ins array... ab dem dritten dritten mal ist dann
    "y} " im Array
    Geändert von JoeM1978 (04.03.2013 um 19:05 Uhr)
    JAAAA... Microchips kann man essen... aber der Geschmack ist furchtbar.

Seite 1 von 4 123 ... LetzteLetzte

Ähnliche Themen

  1. Daten von Software UART nach Hardware UART weiterleiten
    Von kusli im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 8
    Letzter Beitrag: 06.10.2008, 22:24
  2. Anfängerprojekt - Bitte um Hilfe und Meinungen
    Von Al_Andaluz im Forum Vorstellung+Bilder+Ideen zu geplanten eigenen Projekten/Bots
    Antworten: 22
    Letzter Beitrag: 20.06.2007, 11:27
  3. frequenzverhalten von mosfets optimieren...
    Von Bibiman im Forum Elektronik
    Antworten: 3
    Letzter Beitrag: 18.03.2007, 11:37
  4. Erster UART Versuch... schaut mal bitte kurz drüber...
    Von popi im Forum C - Programmierung (GCC u.a.)
    Antworten: 19
    Letzter Beitrag: 25.07.2006, 21:16
  5. BL-521 - Bluetooth RS232 Converter (Eure Meinungen Bitte !!)
    Von PabloEscoba im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 1
    Letzter Beitrag: 11.05.2006, 17:56

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •