-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 18

Thema: UART ohne CrLf?

  1. #1
    Erfahrener Benutzer Robotik Einstein Avatar von Geistesblitz
    Registriert seit
    16.03.2011
    Ort
    Dresden
    Alter
    30
    Beiträge
    1.937

    UART ohne CrLf?

    Anzeige

    Ich frage mcih, ob es möglich ist, UART (oder auch alle anderen seriellen Kommunikationsmöglichkeiten) möglichst gut auszunutzen, indem man CrLf weglässt und stattdessen wirklich jedes übertragene Byte einzeln auswertet. Vorteil sehe ich darin, dass man die Bytes wirklich als ganzes Byte auswerten kann, würde man CrLf nicht ignoroeren, so würde die Übertragung ja unerwartet abgebrochen werden, wenn der zu übertragende Wert ausgerechnet 10 oder 13 ist. Daher ließe sich das doch bestimmt so lösen, dass Sender und Empfänger wissen, was es so an Befehlen gibt und dass nach gewissen Befehlen x Bytes als Daten interpretiert werden sollen. Wäre sowas denkbar oder ist das ungünstig? Wonach müsste ich suchen, um dazu mehr zu erfahren? Bisher Musste ich Zahlen als Strings übertragen, was ich jedoch als furchtbar ineffizient empfinde. Außerdem schafft es der Pololu-Maestro ja auch, daher würde mich interessieren, wie man so eine Kommunikation am besten aufbauen kann.
    AI - Artificial Idiocy

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von malthy
    Registriert seit
    19.04.2004
    Ort
    Oldenburg
    Beiträge
    1.379
    Hey!

    Ich kenne das Problem auch. Die simpel-Lösung die ich bisher verwende, ist die Daten in ASCII hexcodiert zu übertragen. Damit kann man dann immernoch die klassischen Steuerzeichen verwenden (CR/LF), hat aber den Vorteil das 1.) die Übertragung im Mittel etwas effizienter ist als ASCII dezimalcodiert und 2.) die Zahlen eine feste Breite von zwei ASCII Zeichen haben. Das ist für meinen Geschmack ein großer Vorteil bei der Nachrichtenauswertung, die wird dann zu einem einfachen hex2dec oder dec2hex (je nach Sprache).

    Natürlich könnte man das Prinzip weitertreiben und ein eigenes Zahlenformat verwenden, das 254 Datenzeichen und 1 Steuerzeichen (zB Nachricht Ende) verwendet. Bisher war ich zu faul das mal zu implementieren.

    Gruß
    Malte

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    599
    Hallo,

    habe da schon verschiedene Protokolle gesehen:

    Zum Beispiel STX Datenbytes ETX, wenn in den Datenbytes die Werte der Steuerzeichen vorkommen wird z.B. ESC STX, ESC ETX und ESC ESC gesendet. STX (Start of Transmission) usw. findet man in einer ASCII Tabelle.

    Dann eine Variante von ISO-TP angepasst an UART: STX Framennummer-Byte Anzahl-Datenbytes-Byte Datenbytes Checksum-Byte.
    http://de.wikipedia.org/wiki/ISO_15765-2

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    29
    Beiträge
    1.221
    Es steht dir vollkommen frei, ein beliebiges Protokoll zu entwickeln und zu implementieren, bei dem die ASCII-Steuerzeichen wie CR und LF kein oder eine komplett andere Bedeutung haben. Der primäre Einsatzzweck von CR/LF ist die Ausgabe auf einer Textkonsole, da verbessert der Zeilenumbruch die Lesbarkeit. Für ein Binärprotokoll ist das aber komplett irrelevant.

    mfG
    Markus
    Tiny ASURO Library: Thread und sf.net Seite

  5. #5
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.557
    ... ob es möglich ist, UART ... möglichst gut auszunutzen ... CrLf weglässt und stattdessen wirklich jedes übertragene Byte einzeln auswertet ...
    Ich weiß nicht, ob ich das jetzt richtig verstehe. Meine UART-Telegramme sind - bis auf Textausgaben an Terminal - eigentlich immer ohne CR/LF. Mal Beispiele.

    Befehle per UART sind bei mir meist Steuerbefehle zu Testzwecken von PC nach Controller aber eben auch einzelne Controller-Controller-Kommunikation (der 1284 hat praktischerweise zwei UARTs). So ein Telegramm hat dann allerlei Inhalt - aber praktisch nie ein CrLF (Ausnahme die Terminalmeldungen) - es wird allerdings der gesendete String mit einer 0x00 abgeschlossen. Der Befehlsempfänger weiß dann, wann welcher Wert beginnt und wann er aufhört. Die Telegramme sind dabei recht kurz, derzeit deutlich unter 14 Bytes (einschließlich er String-Null). Soweit die Übertragung von Zeichen und Zahlen per ASCII-String. Mal ein aktuelles Beispiel vom Kopfcontroller meines Archie.
    Code:
      #define   KOMMANDO_APPS       'A'     // Anwendungsprogramme fahren, diverse
      #define   KOMMANDO_APPS_LEN     7     //   Annkkkk
                                            //    nn =:   01..99 - Programmnummer
                                            //      kkkk  Parameter für Prog
    
      #define   KOMMANDO_DATS       'D'     // (aktuelle) Daten der Servos
      #define   KOMMANDO_DATS_LEN     1     // Kommandolänge
    
      #define   KOMMANDO_NORM       'N'     // Normposition der Servos anfahren
      #define   KOMMANDO_NORM_LEN     1     // Kommandolänge
    
      #define   KOMMANDO_OFFA       'O'     // Offset anzeigen für akt Servo x
      #define   KOMMANDO_OFFA_LEN     2     // Kommandolänge
    
      #define   KOMMANDO_OFFC       'o'     // Offset ändern (Change) für akt Servo x
      #define   KOMMANDO_OFFC_LEN     5     // Kommandolänge
                                    // bei ox333 => akt. Wert ins EEPROM schreiben
    
      #define   KOMMANDO_POSER      'P'     // Positionierbefehl Servo
      #define   KOMMANDO_POSER_LEN    6     //   Pn3600 {1-9, j, z} 10 Servo
                                            //    n =:  1..9, j=10, z=alle
      #define   klz                 122     //   kleines "z"
      #define   GRZ                  90     //   Grosses "Z"
    
      #define   KOMMANDO_WICHTIG    'W'     // Wichtiger Befehl
      #define   KOMMANDO_WICHTIG_LEN  1
    
      #define   KOMMANDO_TEST       'T'     // Test x {0 .. 9} aufrufen
      #define   KOMMANDO_TEST_LEN     2     //   .. in do_test/r4n
    
      #define   KOMMANDO_VOICE      'V'     // Audioausgabe aufrufen
      #define   KOMMANDO_VOICE_LEN    4     //   .. in ~aud~/plyWTV
    
      #define   KOMMANDO_PC_CON     'Z'     // Zurück zur Console
      #define   KOMMANDO_PC_CON_LEN   2
    
    //      Muss nur das laengste Kommando aufnehmen koennen.
    //#define   KOMMANDO_BUFFER_LAENGE   14         // ##>> Deklaration => ~com~
    //  eigener BUFFER-Speicher um aus dem 'unsichtbaren' FIFO-Speicher umzukopieren
    //u8 mein_rx_buff [KOMMANDO_BUFFER_LAENGE];     // ##>> Deklaration => ~com~
    Der rot markierte String ist hier nur EIN Beispiel für einen tatsächlich gesendete/empfangene String OHNE String-Ende-Marke. Der bedeutet in diesem Beispiel
    Fahre Position von Servo n auf den Wert 3600. Anm.: Ich stelle meine analogen Servos mit einem Puls der fast 14 Bit fein codierbar ist.
    Zu sehen ist hier auch deutlich, dass die Länge des Befehlsstrings vom Kommandoanfang codiert wird. Das hat nicht zuletzt den Hintergrund mir selbst eine Eselsbrücke bein Programmieren und beim Testen zu bauen.

    Solche Strings sendet auch in manchen Situationen per UART der Master an Slaves.

    I²C: Werte mit ein oder zwei Bytes übertrage ich häufig, insbes. per I²C - und dann als "richtige" Integerwerte mit ein oder zwei Bytes. Da muss der Befehlsempfänger eben wissen wie er die verschiedenen Bytes auszuwerten hat. Das löse ich dadurch, dass z.B. eine Dekade Pufferbytes für Motorenwerte benutzt wird. Byte x9 ist das Statusbyte - ist das auf 85 so der Puffer bereit zur Aufnahme eines neuen Befehls. Dann schreibt der Master seine z.B. zwei Motorstellwerte, z.B. 240 / 250 in die Pufferzellen 52-53 und 54-55, in die 59 kommt ne 99 als Zeichen, dass neue Daten im Puffer stehen. Der Slave liest das und quittiert mit ner 85 auf Byte 59.

    Ist das der Hintergrund der Frage?
    Ciao sagt der JoeamBerg

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Geistesblitz
    Registriert seit
    16.03.2011
    Ort
    Dresden
    Alter
    30
    Beiträge
    1.937
    Danke schonmal für die Anregungen. Hex-Strings hören sich schonmal ganz gut an, mich würde trotzdem mal interessieren, wie man da noch weiter gehen könnte. Ich hab auch schonmal ein Testprogramm in Bascom geschrieben, das nicht erst auf CrLf warten soll, sondern direkt das jeweils empfangene Byte aufnimmt, allerdings kam so keine Kommunikation zustande.
    AI - Artificial Idiocy

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    59
    Beiträge
    2.435
    Hallo,

    Zitat Zitat von Geistesblitz Beitrag anzeigen
    Ich frage mcih, ob es möglich ist, UART (oder auch alle anderen seriellen Kommunikationsmöglichkeiten) möglichst gut auszunutzen, indem man CrLf weglässt und stattdessen wirklich jedes übertragene Byte einzeln auswertet.
    Grundsätzlich ist das kein Problem, wenn man es kann.

    Bei 8 Datenbits, kann man 256 unterschiedliche Symbole übertragen. Für den Computer sind das erst mal nur Binärwerte.

    Nun begab es sich, dass man verschieden Geräte, z.B. einen Computer und ein Terminal mit einander verbinden wollte.
    Das geht aber nur, wenn beide Geräte die selbe Sprache sprechen, sonst hat man nur Datensalat.
    Irgendwer hat dann mal den ASCII-Code definiert, weil die Amis waren, dachte da keiner an Umlaute und 7 Bit genügten.
    http://de.wikipedia.org/wiki/ASCII

    IBM ging einen anderen Weg:
    http://de.wikipedia.org/wiki/EBCDIC

    Du kannst ja mal durchspielen, was sich so tut, wenn du zwei Geräte verbindest, welche diese beiden unterschiedliche Codierungen verwenden.

    Bevor man Bildschirmterminals hatte, waren TTYs das Standartgerät, kennt man auch als Telex oder Fernschreiber.
    Da brauchte man in der Norm auch Steuerzeichen. bei ASCII sind die ersten 32 Zeichen als Steuerzeichen reserviert.
    CR komm von Carriage Return (Wagenrücklauf) und LF ist Line Feed (Zeilenvorschub) dinge die man bei einem TTY halt noch hat.

    Zu dieser Zeit hatte man noch Lochstreifen als Speichermedium.
    Um den Lochstreifen in den Leser einlegen zu können, braucht man am Anfang schon Löcher, dazu wurde das Zeichen NUL benötigt. Allgemein hat man am Anfang des Lochstreifens eine ganze Reihe NUL gestanzt.
    Da man damals ganze Dateien auf Lochstreifen gespeichert hat, gibt es noch Steuerzeichen für diese, wie z.B. EOF (End Of File).
    Dann brauchte man noch ein paar Steuerzeichen für die Regelung des Datenverkehrs.

    Das Ganze hat dann dazu geführt, dass Standard-Treiber entwickelt wurden, welche den Datenverkehr regeln, ohne dass jeder Programmierer dies in seinem Programm extra programmieren muss.

    Allerdings kann man normalerweise bei jedem Betriebssystem diese Treiber auf Transparent, bzw. Binär, umschalten, dann werden die ganzen Steuerzeichen nicht ausgewertet.

    Wenn man jetzt Binäre Daten übertragen will, hat man ein kleines Problem, man benötigt immer noch Steuerzeichen, aber es sind schon alle möglichen 256 Kombinationen belegt.

    Wie schon erwähnt wurde kann man alles in ASCII-Hex wandeln, das verdoppelt aber die Datenmenge.
    Eine andere Methode ist MIME
    http://de.wikipedia.org/wiki/MIME

    Bei MIME-64 wird der Datenstrom zuerst in 6-Bit Grüppchen aufgeteilt. Zu den 6-Bit Werten addiert man dann noch 32 (für die reservierten Steuerzeichen) und sendet das so über die Leitung. Das Datenvolumen wird dann nur um den Faktor 1.5 aufgebläht.

    Um jetzt bei einem reinen binären Datenstrom noch zusätzlich Steuerzeichen zu gewinnen, arbeitet man mit einem Escape-Zeichen.
    Gerne wird dafür der Wert 0x1B (ESC) verwendet.
    Will man ein Steuerzeichen einfügen sendet man zuerst ein ESC und dann das Steuerzeichen.
    Da der Wert 0x1B aber auch in den Daten vorkommen kann, sendet man in diesem Falle zwei mal ESC.

    Fazit:
    Du kannst die Daten senden wie dir Lustig ist. Musst dann aber die Software für Sender und Empfänger selber schreiben!
    Was du aber auch nicht vergessen darfst, ist, dass immer damit zu rechnen ist, dass Zeichen verloren gehen oder gestört ankommen.
    Da muss dein Protokoll dann wieder synchronisieren können, andernfalls hängt sich das einfach auf.

    Bei der crlf-Methode geschieht die Synchronisierung immer an dieser Stelle.
    Stell dir vor du sendest lauter Zahlen, der Empfänger weiss, dass jede Zahl 5 Stellen hat.
    Wenn du kein crlf verwendest und ein Zeichen verloren geht, gibt es keine Möglichkeit herauszufinden wo jetzt welche Zahl aufhört und wo die nächste beginnt.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  8. #8
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.557
    ... ein Testprogramm in Bascom geschrieben, das nicht erst auf CrLf warten soll ... allerdings kam so keine Kommunikation zustande.
    Schon klar dass es so nicht geht. Die üblichen Bibliotheken warten eben auf einen Standard-Abschluss. Da muss man schon selbst aktiv werden. Bei mir stehen die empfangenen Daten noch dazu in einem FIFO und die Kommunikation läuft "im Hintergrund" interruptgesteuert. Geht recht fix.

    Mal ein paar rausgeschnibbelte Code-Zeilen um das Vorgehen zu skizzieren:

    Code:
         // ==================================================
         /* ... auf Inhalt im FIFO ... wartem */
         if ( ! ukbhit0 () )
           continue;
    
    
         // ==================================================
         /* EIN EINZIGES Zeichen aus FIFO lesen.    */
         zeichen_aus_fifo = ugetchar0();
    
    
         // ==================================================
         /* Wenn noch kein Kommando bekannt ist, muessen wir erst einen 
            Kommando-Buchstaben erkennen.
    
            Randbemerkung
            Hier ist auch ein switch/case-Dingsda erlaubt, da zeichen_aus_fifo und
            auch der Define genau ein char-Zeichen bzw. ein numerisch auswertbarer
            einfacher Datentyp sind.                     */
         if (zeiger == 0)
         {                                          //
           if (zeichen_aus_fifo == KOMMANDO_APPS)   // Fahre Anwendungsprogramme
             telegrammlaenge = KOMMANDO_APPS_LEN;   //   mit und ohne Parameter
    
           if (zeichen_aus_fifo == KOMMANDO_DATS)   // Servo Daten von allen
             telegrammlaenge = KOMMANDO_DATS_LEN;   //   Servos anzeigen
    
           if (zeichen_aus_fifo == KOMMANDO_NORM)   // Servo Normposition
             telegrammlaenge = KOMMANDO_NORM_LEN;   //   anfahren
    
           if (zeichen_aus_fifo == KOMMANDO_OFFA)   // Offsetwert A nzeigen
             telegrammlaenge = KOMMANDO_OFFA_LEN;   //   von Servo x
    ....
         }
    
    
         // ==================================================
         /* Wenn keine Telegrammlaenge bekannt ist, dann ist auch kein Kommando
           bekannt, dann muss auch nichts weiter gemacht werden, als auf das 
           naechste Zeichen zu warten bzw. es abzuholen und dann wieder auf 
           einen Kommando-Buchstaben zu testen                      */
         if (telegrammlaenge == 0)
           continue;
    
         // ==================================================
         /* Wenn ein erkanntes Kommando seine Telegrammlaenge angegeben hat, dann
           muessen wir nun die EINZELN aus dem FIFO abgeholten Zeichen in den BUFFER
           schreiben. Da ja schon der erkannte Kommando-Buchstabe in der Variablen 
           "zeichen_aus_fifo" steht, und "zeiger" noch nicht veraendert wurde, wird 
           auch zum Glueck der Kommando-Buchstabe direkt als erstes Zeichen in
           unserem BUFFER landen.
           Und alle weiteren Zeichen werden dank "zeiger++" dahinter geschrieben. */
         mein_rx_buff [zeiger] = zeichen_aus_fifo;
         zeiger++;
    
         // ==================================================
         /*  Und jetzt das geniale Ergebnis:
           Wenn nun "zeiger" und "telegrammlaenge" gleich sind,
           dann haben wir ein fertig empfangenes Kommando mit
           seiner erwarteten Laenge.        */
         if (zeiger == telegrammlaenge)
         {
           /*  DIESE INITIALISIERUNGEN SIND LEBENSWICHTIG  */
           zeiger          = 0;
           telegrammlaenge = 0;
    
           /*  Die Funktionen koennen nun gemuetlich das
               Telegramm auswerten.       */
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //    Fahre verschiedene Anwendungsprogramme, je nach Nummer 
        if (mein_rx_buff [0] == KOMMANDO_APPS)      // Tastatur-Eingabe "Annkkkk"
        {                                   //   Annkkkk
                                            //    nn =:  01..99 - Programm-Casenummer
                                            //      kkkk  Parameter für Prog
    //      Dekodiere Programmkennziffer im Byte mein_rx_buff 1 und 2
          for ( u8 i=0; i<=1; i++) { s[i] = mein_rx_buff [i + 1]; }
          s[2]  = 0;                        // Markiere Stringende "0"
          nmbr  = atoi ( s );               //
    
    // - - - - - - - - - - - - - - -
    //    case
    //      10      Augen rollen k mal (erstes "k")
    //      11      Alle Lider auf, full speed
    //      12      Alle Lider  zu, full speed
    ....
    //                  Fahrgeschwindigkeit "Servo-Standard+SloMo"
    //      43      Augenprogramm AuP43 = ähnlich 42, eher langsamer
    
    // - - - - - - - - - - - - - - -
          switch (nmbr)     // Fahre gewählte Aktionen
          {                         //
            case 10:                // Augen rollen k-mal
              s[0]  = mein_rx_buff [3]; s[1] = 0;   // Dekodiere 1stes k
              npar1 = atoi ( s );   //
              AuRoll ( npar1 , 100 );       // Augen rollen mit Standard-slow
              for ( u8 i=1; i<=6; i++) {mein_rx_buff [i]  =  '9'; }
              mein_rx_buff [7]  =  0;       // Hilft das bei unvollständiger Eingabe ?
              break;
    
            case 11:                // Alle Lider auf, full speed
    //        s[0]  = mein_rx_buff [3]; s[1] = 0;   // Dekodiere 1stes k
    //        npar1 = atoi ( s );   //
              Srv_tm [ 5]   =  2400;
              Srv_tm [ 6]   =  4800;
              Srv_tm [ 8]   =  5400;
              wms (  500);          //
              break;                //
    .....
            case 51:        // NUR ANSCHLUSS SERVO 1 mit TasteA/3 auf- und abdrehen
    //        AuP51 ( );                    // Fahre AuP51                         r4n
              N1Srvo ();                    // Fahre Servo-Einzel-Einrichtung      r2n
              break;                        //
    
    // - - - - - - - - - - - - - - -
            default:
              break;
          }                         // Ende switch (nmbr)
        }        // Ende if (mein_rx_buff [0] == KOMMANDO_APPS)
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //      Wurde "KOMMANDO_DATS" = "D" erkannt ?   DatenAusgabe Servos
        if (mein_rx_buff [0] == KOMMANDO_DATS)      // Tastatur-Eingabe "D"
        {                                           //
    //    Daten für ALLE zehn Servos ausgeben
          uputs0 ("\r\tServodaten");   //
          dat_aus ();               // Servodaten ausgeben
        }        // Ende if (mein_rx_buff [0] == KOMMANDO_DATS)
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //      Wurde "KOMMANDO_NORM" = "N" erkannt ?   Normposition der Servos anfahren
        if (mein_rx_buff [0] == KOMMANDO_NORM)      // Tastatur-Eingabe "N"
        {                                           //
          uputs0 ("\r\tServonormposition,");       //
          kal_0();                          // Initialiswerte einstellen           kal
          uputs0 ("\tneue Servodaten :");   //
          dat_aus ();                       // Servodaten ausgeben
    
        }        // Ende if (mein_rx_buff [0] == KOMMANDO_NORM)
    
    
    und so weiter
    Ist das so (andeutungsweise) verständlich ?
    Ciao sagt der JoeamBerg

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544
    Hi,

    ich hab auch vor einiger Zeit mein eigenes Protokoll entwickelt (mittlerweile gibts ein paar Verbesserungen, aber das wäre zuviel).
    Es ging damals darum, ein Byte-Array von einem µC auf einen PC und andersrum zu übertragen. Da ich aber nichtmehr soviel Platz auf dem µC hatte, dachte ich mir, jedes einzelne Byte, das gespart werden kann, wird gespart!
    Also hab ich mir die Situation rausgesucht, bei der die meisten Byte übertragen werden müssen und diese Byte-Anzahl als Norm-Länge verwendet.
    Nun wird einfach immer ein Array dieser Länge (bei mir sind 132 Byte) übertragen, incl. Erkennungsbytes (damit der Empfänger weiß, was er mit den Daten machen soll).
    Um niemals die Synchronisation zu verlieren, frage ich regelmäßig die Anzahl der bereits empfangenen Daten ab und kucke mir die Zeit an, seit der sich die Anzahl nicht mehr verändert hat. Wird eine bestimmte Zeit überschritten, gehe ich davon aus, dass Daten verlorengegangen sind und setze die Zähler zurück.
    Das ganze läuft bei mir auf dem µC per DMA, so wird sogut wie keine Zeit für das Empfangen verschwendet.
    Neuerdings schwirren mir wieder ein paar Verbesserungen im Kopf rum, welche ich demnächst wohl mal einpflegen werde.
    Zum Beispiel will ich von der festen Array-Länge weg, da es in manchen Fällen vorkommen kann, dass nur 10% von den 132 Bytes effektiv genutzt werden. Das ist zwar grundsätzlich egal, sieht aber nicht schön aus.
    Auch wäre eine Verbindung verschiedener µCs untereinander nicht schlecht, sodass am Anfang eines Arrays zuerst der Empfänger, dann der Sender, dann die Anzahl der folgenden Bytes und anschließend evtl. noch eine Checksumme integriert sind. Außerdem wäre es eine schicke Idee, die Daten sozusagen Seitenweise zu übertragen, heißt:
    Eine Seite ist z.b. 10Bytes lang, in ihr befinden sich alle relevanten Informationen für die Übertragung ansich, ebenso wie die zu übertragenden Daten selbst. Unter den für die Übertragung relevanten Daten finden sich noch zwei Werte, die akt. Seitenzahl und die Gesamtseitenzahl. So liesen sich mit nur 10Bytes Speicher große Datenmengen übertragen.
    Das Alles noch mit einem ACK abgerundet, fertig ist ein High-Level-Protokoll.

    Es kommt aber eben darauf an, WAS du willst. Willst du Daten schnell austauschen, störsicher, große Datenmengen, etc ... ?

    Gruß
    Chris

  10. #10
    Erfahrener Benutzer Roboter Genie Avatar von malthy
    Registriert seit
    19.04.2004
    Ort
    Oldenburg
    Beiträge
    1.379
    Ich denke man braucht dedizierte Steuerzeichen (das heißt Zeichen, die nur Steuerzeichen sind). Ob das nun historische wie LF oder CR sind, ist dabei natürlich erstmal wurscht.

    Um jetzt bei einem reinen binären Datenstrom noch zusätzlich Steuerzeichen zu gewinnen, arbeitet man mit einem Escape-Zeichen.
    Gerne wird dafür der Wert 0x1B (ESC) verwendet.
    Will man ein Steuerzeichen einfügen sendet man zuerst ein ESC und dann das Steuerzeichen.
    Da der Wert 0x1B aber auch in den Daten vorkommen kann, sendet man in diesem Falle zwei mal ESC.
    Die Logik verstehe ich nicht ganz. Wenn der Wert des Steuerzeichens auch in den Daten vorkommen kann, wie kann man dann ausschließen, dass es sich bei einem "scheinbaren" Steuerbefehl nicht zufällig um zwei Datenwerte handelt, die aussehen wie ein Steuerbefehl. Also konkret: wenn 0x1B einen Befehl markieren würde und ein 0x50 würde zB die Ausgabe von der folgenden drei Bytes (binary) auf einem LCD bedeuten, wie wäre der Fall davon zu unterscheiden, dass einfach zufällig dezimal 27 und 80 in einem anderen Zusammenhang aufgetaucht sind? Sich nämlich darauf zu verlassen, dass man immer sicher im Leseraster ist (was natürlich eine Lösung wäre), finde ich etwas gewagt ... Oder habe ich da irgendwo einen Denkfehler?

    Ich hab auch schonmal ein Testprogramm in Bascom geschrieben, das nicht erst auf CrLf warten soll, sondern direkt das jeweils empfangene Byte aufnimmt, allerdings kam so keine Kommunikation zustande.
    Hm, verstehe ich nicht ganz ... Ich verwende zwei Varianten. Die eine ist im Hauptloop - also quasi durch permanentes Polling - mit

    Code:
    If Ischarwaiting() = 1
    jeweils zu gucken ob was im UART Puffer für mich zum abholen liegt, und falls ja, es mit

    Code:
    Uart_buf(uart_buf_i) = Inkey()
    abzuholen. Meist schreibe ich die Zeichen in einen Ringpuffer, den ich dann nach jedem neuen Byte nach der Sequenz absuche, die das Ende der Nachricht signalisiert (bei mir idR CR/LF, das kann definitionsgemäß nicht als Datenwerte vorkommen). Wenn das Ende erreicht ist, wird eine Anzahl Bytes vorher im Ringpuffer, die der Nachrichtenlänge entspricht ausgewertet. Das heißt in meinem Falle von Hex (String) nach Dezimal (oder wie auch immer man die Variable dann interpretiert) umgewandelt. Meist schleppe ich noch einen 8 bit CRC Wert mit, der dann noch ausgewertet wird.

    Die andere Varainte geht fast genauso, da verwende ich dann allerdings den urxc Interrupt, dh mit

    Code:
    On Urxc Rxc_isr
    wird bei jedem neuen Zeichen die entsprechende ISR angesprungen, die dann die Auswertung wie eben gesagt macht.

    Ist methodisch nicht sehr intellektuell und die Codierung ist auch "far from optimal", aber es funktioniert stumpf

    Gruß
    Malte
    Geändert von malthy (08.08.2014 um 18:20 Uhr) Grund: typos

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Antworten: 4
    Letzter Beitrag: 13.06.2012, 19:22
  2. Soft-Uart - Intergerzahlen ohne ext. Quarz übermitteln
    Von #fritz# im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 10.10.2011, 20:31
  3. Übertrageung zwischen PC/µC und µC aber ohne Uart
    Von Michael 123 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 10
    Letzter Beitrag: 18.06.2006, 10:15
  4. Software-UART ohne Start-, Stop- und Paritybit
    Von TurboFischer im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 05.06.2006, 23:07
  5. Ohne mampf kein Kampf (ohne strohm geht nichts)
    Von Andal im Forum Elektronik
    Antworten: 21
    Letzter Beitrag: 26.11.2004, 20:40

Berechtigungen

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