-         
Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 27

Thema: UART Kommunikation zwischen Raspi und Arduino hängt sich ständig auf

  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    4.770

    UART Kommunikation zwischen Raspi und Arduino hängt sich ständig auf

    Anzeige

    hallo,
    ich komme zur Zeit nicht weiter: meine UART Kommunikation zwischen Raspi und Arduino hängt sich ständig auf.
    Ich vermute den Fehler eher Raspi-seitig, weil der Arduino-Code in ähnlicher Form bereits mit Borland C++ Builder auf dem PC funktioniert hat (wenn sich nicht ein c+p Fehler eingeschlichen hat, den ich allerdings noch nicht gefunden habe).
    Der Arduino (momentan ein Mega2560) ist per USB mit einem Raspi-USB-Port verbunden ("/dev/ttyACM0") .

    Hat jemand einen Tipp, das zu beheben?

    Raspi code:
    Code:
    /*
       UART communication
       send/receive string of tokens
        
       Raspberry Pi  master
       ver 0101
     */
    
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string>
    #include <math.h>
    #include <fcntl.h>
    #include <string.h>
    #include <sys/ioctl.h>
    #include <stdint.h>
    #include <time.h>
    #include <sys/time.h>
    #include <errno.h>
    #include <pthread.h>
    
    #include <wiringPi.h>
    #include <wiringSerial.h>
    
    #define  byte  uint8_t
    
    char   uart[256]  =  "/dev/ttyACM0";
    int    Serial;
    
    const uint32_t UARTclock = 115200;
    
    
    
    int i0;
    
    #define TOKLEN 30
    #define MSGLEN 1024
    #define iINVALID -29999
    
    
    std::string  inputString="";
    char   cval[TOKLEN];  // number as cstring
    char   mbuf[MSGLEN];  // cstring msg buffer
    
    
    
    
    
    //==================================================================
    // serial TCP
    //==================================================================
    
    
    void loop() {
        
      while(1) {  
          
         static bool stringComplete = false;
         
         
         //-------------------------------------------------------------
         // send    
         
         char formatstr[MSGLEN];
         
         // debug, cut-down:
         strcpy(formatstr, "§");
         strcat(formatstr, "message from Raspi: %d;\n");
         sprintf(mbuf, formatstr, i0);
                        
         for(uint8_t i=0; i<strlen(mbuf); i++) {           //
            serialPutchar( Serial, mbuf[i]);               // Send values to the slave       
         }   
          
         // strcpy(mbuf, "");   //  <~~~~~~~~~~~~~~~~~~~~~~~~editiert!
         
         //delay?
         delay(10);  //  <~~~~~~~~~~~~~~~~~~~~~~~~editiert!
       
         
         
         
         //-------------------------------------------------------------
         // receive
         
         inputString="";
         char cstr[TOKLEN];
       
         int  n=0;
         char inChar;
         
         
         while (serialDataAvail( Serial ) && n<MSGLEN-1) { 
           if(n==MSGLEN-2) inChar='\n'; // emergency brake
           else  
           inChar = serialGetchar( Serial ); 
        
           inputString += inChar;
           
           if (inChar == '\n')  {
             stringComplete = true;
           }
           n++;
         }
       
         
         if (stringComplete)  {
    
           strcpy (mbuf, inputString.c_str() );
           // strcat(mbuf, "\0");  //  <~~~~~~~~~~~~~~~~~~~~~~~~editiert!
           fprintf(stderr,mbuf); fprintf(stderr,"\n"); 
           
           // process mbuf !
       
           
           inputString="";
           stringComplete = false;
       
           //delay?
           delay(1);
         }
       
       }     
    }
    
    
    
    
    //==================================================================
    
     
    int main() {
         
        printf("initializing..."); printf("\n");
       
        // UART Serial com port
        Serial = serialOpen (uart, UARTclock);   
        printf("starting UART loop..."); printf("\n");   
        
        loop(); 
       
        serialClose( Serial);
        exit(0);
    }
    
    
    //
    // eof

    Arduino code:
    Code:
    // Arduino COM to Raspi
    // (C) 2018 by dsyleixa
    
    // ver 0101
    
    
    // I2C
    #include <Wire.h>    
    
    
    int i0 = 0;
    
    #define TOKLEN 30
    #define MSGLEN 1024
    #define iINVALID -29999
    
    String  inputString="";
    char    cval[TOKLEN];  // number as cstring
    char    mbuf[MSGLEN];  // cstring msg buffer
    
    
    //==================================================================
    // setup
    //==================================================================
    void setup() {
      Serial.begin(115200);
      
      pinMode(LED_BUILTIN, OUTPUT);
      digitalWrite(LED_BUILTIN, LOW);
    
    }
    
    
    //==================================================================
    // loop
    //==================================================================
    
    void loop() {
      static bool stringComplete = false;
    
      //-------------------------------------------------------------
      // receive
      
      int  n=0;
      char inChar;
    
         
      while (Serial.available() && n<MSGLEN-1) { 
           if(n==MSGLEN-2) inChar='\n';
           else  
           inChar = (char)Serial.read();
        
           inputString += inChar;
           
           if (inChar == '\n')  {
             stringComplete = true;
           }
           n++;
      }
    
      if (stringComplete)  {
        inputString.toCharArray(mbuf, MSGLEN-1);
    
        // process mbuf !
        
        //
        
        inputString="";
        stringComplete = false;
    
        //delay?
        delay(1);
      }
      //-------------------------------------------------------------
      // send  
      
    
      //----------------------
      
      char formatstr[MSGLEN];
      strcpy(formatstr, "§");
      strcat(formatstr, "message from Arduino: %d;\n");
      sprintf(mbuf, formatstr, i0);                 
      
      for (int i=0; i<strlen(mbuf); i++ ) Serial.print(mbuf[i]);
      
      // strcpy(mbuf, "");  //  <~~~~~~~~~~~~~~~~~~~~~~~~editiert!
      
      i0++;
    
      //delay?
      delay(10); //  <~~~~~~~~~~~~~~~~~~~~~~~~editiert!
    }
    
    
    
    
    // end of file

    console output:
    Code:
    initializing...
    starting UART loop...
    §message from Arduino: 0;
    §message fr211;
    §message from Arduino: 2212;
    §message from Arduino: 2213;
    §message from Arduino: 221�no: 2210;
    §message from Arduino: 2211;
    §message from Arduino: 2212;
    §message from Arduino: 2213;
    §message from Arduino: 221�
    dann bleibt es stehen...

    Restart, neuer output:
    Code:
    initializing...
    starting UART loop...
    §message from Arduino: 0gno: 618;
    §message fr��message from Arduino: 615;
    §message from Arduino: 616;
    §message from Arduino: 617;
    §message from Arduino: 618;
    §message fr
    dann bleibt es wieder stehen...
    Geändert von HaWe (01.06.2019 um 11:43 Uhr) Grund: Siros Vorschläge eingearbeitet
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    937
    Hallo HaWe,

    115200 Baud:
    sind 8,68 us pro Bit
    10 Bits = 1 Byte wegen Start Stop Bit
    also 68,8us pro Byte
    * 30 Byte = 2,6 Millisekunden
    Du wartest 1 Millisekunde, läuft Dir da evtl. ein Puffer über ?

    Siro

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    4.770
    kann sein, kenne mich da nicht aus -
    aber wenn der Arduino sendet, dann nur bis zu einem \n,
    dann kann der Raspi empfangen, ebenfalls bis zum \n,
    und solange sollte der Arduino ja gar nichts mehr tun, bis der Raspi wieder sendet und der Arduino empfängt.
    Erst danach dürfte der Arduino erneut senden - so ist es jedenfalls gedacht, quasi als Handshake.

    Wie könnten sich Puffer füllen, wenn jeder immer mit erneutem Senden wartet, bis der andere mit Empfangen fertig ist und dann erst die Rück-Antwort empfangen wurde?

    Kann ich evtl. Puffer (welche?) zwischendurch manuell löchen?
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    937
    Eigentlich sollte er nach dem Senden ja erstmal etwas empfangen, sehe ich auch so.
    Mach doch testweise mal ein delay(10) beim Senden und schau was passiert.

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    4.770
    kein Unterschied mit 10, mit 100 auch nicht,
    einziger Unterschied: keine Sonderzeichen � � mehr zwischendrin
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    937
    Wenn ich das richtig sehe,
    löschst Du den Buffer strcpy(mbuf, ""); direkt nach dem Senden.
    Oder wofür ist das gut, ich bin da jetzt nicht sicher.

    Wenn das serielle Ausschieben Interrupt gesteuert ist,
    dann muss der Buffer aber noch erhalten bleiben bis wirklich alles ausgesendet wurde.

    Bau mal vor dem Löschen also vor dem strcpy(mbuf, ""); zum testen noch eine Delay ein 10 ein.

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    4.770
    stimmt, das Löschen von mbuf ist überflüssig, habe es überall rausgenommen, danach delay(10) testweise.
    Bleibt aber leider immer noch hängen nach ein paar Runden.

    - - - Aktualisiert - - -

    update:
    habe den Code jetzt auf einen Due hochgeladen:

    FUNZT!

    danach wieder auf Mega umgesteckt!
    HÄNGT!

    was ist DA denn los...?

    - - - Aktualisiert - - -

    Könnte das bitte jemand mal selber bei sich testen, mit einem Mega2560 am Raspi?
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    4.770
    kann jemand was dazu sagen, wieso es beim Mega2560 hängt und beim Due einwandfrei klappt?
    USB Kabel habe ich auch schon getauscht, ohne dass sich was ändert.

    Ist evtl mein Mega kaputt - oder ist das generell so? (habe leider nur den einen zum Testen)
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    4.770
    kriegs nicht hin mit dem Mega, auch nicht wenn MSGLEN=256, bleibt immer hängen.
    Due nach wie vor kein Problem.
    Gerade für manche 5V-Uno-Shields wäre das interessant am Raspi gewesen, aber wenn es nicht geht, dann ist man leider auf den Due festgelegt, wenn man ein Arduino-Huckepackboard mit sehr vielen GPIOs braucht.

    Oder ist doch ein Spezialist hier, der den Code hinkriegt mit einem Mega?
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.046
    Ich hab jetzt den Code nicht zerpflückt und bin auch kein ARDUINO Mann aber,

    könnte es sein das der Raspberry einen Softwareloop auf die serielle Schnittstelle macht und somit der Eingangspuffer mit den empfangenen Daten, die der Arduino selbst gesendet hat überläuft?
    Das sollte sich testen lassen, wenn man die RxD Leitung des Arduino mal auftrennt und den Sendecode umschreibt.

    Ich lös das immer so, das der Datenempfang im Interrupt läuft und einen Ringpuffer befüllt.
    Dann gibt's da noch einen Schreib- und einen Lesezeiger auf den Ringbuffer und in der Hauptroutine wird dann, wenn die beiden unterschiedlich sind eine Abfrageroutine ausgeführt und die empfangenen Bytes ausgewertet.

    Die Senderoutine läuft dann ganz normal mit Polling auf das USARTx DRE Bit.
    Da die Atmegas einen Doppelpuffer haben gehen da am Anfang immer gleich 2 Bytes rein.
    Kriegt man die Hauptroutine unter 86µs pro Durchlauf sollten da auch keine Lücken im Sendedatenstrom entstehen.

Seite 1 von 3 123 LetzteLetzte

Ähnliche Themen

  1. Antworten: 32
    Letzter Beitrag: 04.07.2018, 09:34
  2. Kommunikation zwischen Android und Sensor(UART)
    Von Alasa im Forum Elektronik
    Antworten: 3
    Letzter Beitrag: 18.10.2017, 11:48
  3. [ERLEDIGT] Problem bei UART Kommunikation zwischen ATmega und VB.net
    Von masasibe im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 15
    Letzter Beitrag: 10.09.2011, 18:41
  4. LCD-Kontrast und UART-Kommunikation zwischen 2 µcs
    Von MelMan im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 04.12.2008, 16:25
  5. Uart-Kommunikation zwischen µCs
    Von ProgDom im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 20.04.2006, 01:37

Berechtigungen

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