-         
Ergebnis 1 bis 6 von 6

Thema: Eleganter Ersatz gesucht für Datenübertragung per uart in C

  1. #1
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.056

    Eleganter Ersatz gesucht für Datenübertragung per uart in C

    Anzeige

    Hallo C-Freaks

    meine Lösung zur Übertragung von uint8_t-Werten per UART von einem Controller zum andern funktioniert, aber irgendwie finde ich sie nicht ansprechend.
    Code:
      char ab3[3];                    // Übersetzungsfeld für Werteausgabe
    
      while ( 1 )                   //      >>>>    Dauerschleife
      {                             //
        wmus (  200);               // Delays zu Testzwecken im Logikanalyzer
        uputs0 ("\x5");             // 0b 0000 0101
        wmus (   50);               //
        ab3 [0]     = 187;
        ab3 [1]     = 0;
        uputs0 ( ab3 );
    //  uputs0 ("\128");            //
        wmus (   50);               //
        ab3 [0]     = 73;
        uputs0 ( ab3 );
      }                     // Ende while ( 1 )
    Es gibt ja die Möglichkeit im uart-String auch Zahlen als ASCII zu senden, beispielsweise, siehe oben
    Code:
      uputs0 ("\128");
    Soweit ich weiß, geht das nicht mit (benannten) Variablen, es werden auf diese Weise nur Konstanten (hier \128 ) oktal oder hex (dann z.B. \x80) akzeptiert.

    Oder gibts doch ne Möglichkeit ? ?

    Danke für Hinweise und Hilfen
    Ciao sagt der JoeamBerg

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    4.840
    für Arduino zu PC habe ich eine Lösung entwickelt, die Werte werden übertragen per
    VarName (der Token)
    und arg (sein Wert als ASCII String),
    beiden bilden zusammen eine Übertragungseinheit
    (Übrigens funktioniert es genau so auch die Übertragung von html-strings von Arduino-esp8266-WebClients zu WebServern und weder zurück, per esp8266, die bei WifiServer.h integriert ist, für WebServer.h habe ich sie zusätzlich implementiert)

    Jede Einheut wird übertragen als
    "&VarName1=arg1;&varName2=arg2; &varName3=arg3;....\n"
    Die Werte sind dabei strings, also Zahlen, die per itoa oder ftoa umgewandelt wurden.
    '&' ist dabei das Startzeichen des VarNames, '=' das Ende und der Beginn des arg-Wert-Strings, ';' schließlich ist das Ende des arg-Wert-Strings und '\n' das Ende des gesamten msg-Strings..
    Der Empfänger klambüsert dann wieder diesen String zu einzelnen Tokens auseinander und ordnet den einzelnen Zielvariablen des Empfängers die einzelnen Werte des Senders zu.

    Suchst du so etwas? Wenn ja, kann ich dir den Code verlinken.

    Vorteil: die Tokens können beliebig gruppiert werden und können auch nur beliebige Untermengen enthalten. Weiterhin besonders geeignet, wenn auch int und float übertragen werden sollen.
    Geändert von HaWe (21.02.2019 um 09:37 Uhr)
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    07.04.2015
    Beiträge
    532
    Wenn Du nen Byte von Controller zu Controller schickst, willst Du das wirklich wandeln? Warum? Der Empfänger versteht das Datenformat doch auch nicht ohne Rückwandlung.

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.056
    für Arduino zu PC habe ich eine Lösung .. VarName .. arg .. zusammen eine Übertragungseinheit .. Suchst du so etwas .. kann ich dir den Code verlinken ..
    Gut! DAs klingt auf jeden Fall interessant. Das Angebot nehme ich gern an und bitte um den Link; danke im Voraus.

    .. Wenn Du nen Byte von Controller zu Controller schickst, willst Du das wirklich wandeln ..
    Wenn ich Werte an einen Controller sende, sollte der auch mitgeteilt bekommen wofür oder wovon diese Werte sind. Mein ÖDNV (öffentlicher Daten-Nahverkehr) bei archie und andern Projekten läuft z.B. über ne UART- oder I²C-Kommunikation und insbes. z.B. beim I²C-Bus ist die Kommunikation für die angeschlossenen Teilnehmer "öffentlich". Es gibt einzelne Kommandobytes mit denen kurze Telegramme identifiziert werden; Beispiel "A", "T", "P", "p" etc. Die zugehörigen, verschiedenen Kommandos haben unterschiedliche Längen, die dem ersten Byte natürlich fest zugeordnet sind. In diesen Längen stecken zugehörige Daten, die das jeweilige Kommando benötigt. Mit diesen Telegrammen kann Controller-Controller-Kommunikation oder PC-Controller-Kommunikation gefahren werden. Selbst WLAN-Fernsteuerung von archie ist so (simpel) möglich - ein RasPi mit autostart eines Terminalprogramms wird an den Hauptcontroller angeschlossen, der RasPi läuft mit RDP und erhält von irgendwo auf der Welt übers Internet/WLAN die Kommandodaten . . .

    Beispiel "p23400030" - aufgedrüselt p 2 3400 030 - übermittelt eine (neue) gewünschte Position an die ein Servo fahren soll: p .. KommandoID für Servoposition, 2 .. Servo Nr. 2, 3400 .. neue, gewünschte Servoposition, 030 .. gewählte Servospeed - etwa 15% der üblichen Servo-Fullspeed. Anderes Beispiel: "d" .. sende eine Liste von aktuellen Zustandsdaten eines Controllers an das Terminal. Beispiel "<<<" bzw. "<<>" : Fahre Links- oder Rechtskurve . . . jedes Kommando verändert die Geschwindigkeitsdifferenz der beiden Antriebe rechts und links.
    Fazit: das erste Byte MUSS sich von allen andern Daten unterscheiden, um Kuddelmuddel zu verhindern.

    Nun, siehe Eingangspost, will ich Entfernungen von meinem NaCo (NavigationsController) an den MoCo (MotorController) senden. Die Ultraschallsensoren messen Entfernungen bis an die sechs Meter in Zentimetern; bei der vorhandenen Speed reicht mir ein maximaler Horizont von fünf Metern - also Werte bis etwa 500. Das ist für ein Byte zu groß und ausserdem in den ersten ca. 20 cm nicht glaubwürdig und sowieso zu wenig. Also halbiere ich den Wert und erhalte nen Bereich z.B. von 10 bis 250 der als halbe Entfernung brauchbar ist - als Angabe in 2-cm-Einheiten. In den ersten Digits, genauer 1 bis 9, steckt die Kodierung der jeweils festgelegten Sensorgruppe (oder Einzelsensor) mit der auch die Anzahl Folgebytes feststeht. Die ASCII-Steuerzeichen 1 bis >10 sind bei mir noch nicht in Verwendung, hier machen sie dann Sinn und die KommandoID ist damit eindeutig von Parameter-Bytes unterscheidbar. Akzeptiert ? Verständlich ?
    Ciao sagt der JoeamBerg

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.395
    Oder du gehst hin und verwendest gleich ein richtiges Protokoll, dass die Übertragung von mehreren Bytes erlaubt.
    Dabei kannst du prinzipiell zwei Varianten machen statisch oder dynamisch.
    Statisch wäre z.B.

    | Command | byte1 | ... | byte-n |
    Anhand des Commands (das ein byte groß ist oder mehr wenn man mehr braucht) weißt du wie viele Datenbytes danach kommen müssen. Die kannst du dann entsprechend interpretieren.

    Dynamisch hat man ein Längenfeld als erstes:

    | Length | byte1 | ... | byte -n |
    Die Daten muss man dann natürlich entsprechend interpretieren.

    Das ganze binär zu übertragen hat den großen Vorteil, dass man weniger Bandbreite und Rechenleistung braucht als wenn man das in ASCII überträgt. Vorallem kann man auch so nette dinge machen wie: Man hat ein struct in dem alle Daten liegen: Übertragt das struct binär und kann die übertragenen Daten wieder direkt in das Struct casten. Dadurch spart man sich viel Aufwand beim Interpretieren.
    Außerdem kann man ziemlich einfach noch eine Prüfsummen hinzufügen wenn man will.

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    4.840
    hallo,
    hier wäre der Arduino-Code:
    https://github.com/dsyleixa/Borland-..._BCB6_RxTx.ino

    und hier die UART-Routinen (+GUI) für den PC:
    https://github.com/dsyleixa/Borland-...RxTx/Unit1.cpp

    die wesentliche Funktion ist cstringarg() samt Hilfsfunktion strstrpos() , sie wird von beiden Plattformen benutzt:

    Code:
    //----------------------------------------------------------------------------
    // tools
    //----------------------------------------------------------------------------
    
    int16_t  strstrpos(char * haystack,  char * needle)   // find 1st occurance of substr in str
    {
       char *p = strstr(haystack, needle);
       if (p) return p - haystack;
       return -1;   // Not found = -1.
    }
    
    
    //------------------------------------------------------------
    char * cstringarg( char* haystack, char* vname, char* carg ) {
       int i=0, pos=-1;
       unsigned char  ch=0xff;
       const char*  kini = "&";       // start of varname: '&'
       const char*  kin2 = "?";       // start of varname: '?'
       const char*  kequ = "=";       // end of varname, start of argument: '='
       char  needle[TOKLEN] = "";     // complete pattern:  &varname=abc1234
    
       strcpy(carg,"");
       strcpy(needle, kini);
       strcat(needle, vname);
       strcat(needle, kequ);
       pos = strstrpos(haystack, needle); 
       if(pos==-1) {
          needle[0]=kin2[0];
          pos = strstrpos(haystack, needle);
          if(pos==-1) return carg;
       }
       pos=pos+strlen(vname)+2; // start of value = kini+vname+kequ   
       while( (ch!='&')&&(ch!='\0') ) {
          ch=haystack[pos+i];    
          if( (ch=='&')||(ch==';')||(ch==' ')||(ch=='\0') ||(ch=='\n')
            ||(i+pos>=strlen(haystack))||(i>TOKLEN-1) ) {
               carg[i]='\0';
               return carg;
          }       
          if( (ch!='&') ) {
              carg[i]=ch;          
              i++;       
          }      
       } 
       return carg;
    }
    cstringarg() gibt einen cstring zurück, der dem Teil entspricht, der hinter dem Gleichheitszeichen steht, also bei

    char msg[100];
    strcpy(msg, "&i=12;&myfloat=1234.56;&foo=8765; &bas="56473.563736";\n");

    char cwert[20];

    wird nach
    cstringarg(msg, "i", cwert );
    "12" in cwert[] zurückgegeben, Null-terminiert, und nach

    cstringarg(msg, "myfloat", cwert );
    entsprechend
    "1234.56"


    (ich hoffe, ich habe jetzt nicht noch einen c+p Fehler drin)
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

Ähnliche Themen

  1. Datenübertragung über UART zu 2xSMci33-2 von Nanotec
    Von jiodatsinga im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 16.05.2012, 13:36
  2. Uart -> Com Datenübertragung
    Von johannes_b im Forum Robby RP6
    Antworten: 8
    Letzter Beitrag: 26.01.2011, 19:23
  3. Ersatz für Gleichrichterdiode gesucht
    Von magic33 im Forum Suche bestimmtes Bauteil bzw. Empfehlung
    Antworten: 2
    Letzter Beitrag: 16.01.2010, 16:22
  4. Datenübertragung zwischen 2 AVR mit UART
    Von MichWuhr im Forum AVR Hardwarethemen
    Antworten: 2
    Letzter Beitrag: 04.01.2010, 19:48
  5. RS232-Ersatz: Datenübertragung über die ISP-Schnittstelle
    Von talentraspel_kai im Forum AVR Hardwarethemen
    Antworten: 0
    Letzter Beitrag: 30.12.2004, 17:55

Stichworte

Berechtigungen

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