Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Italian
  4. Streaming seriale ... disordinato : comunicazioni tra QT e microcontrollori

Streaming seriale ... disordinato : comunicazioni tra QT e microcontrollori

Scheduled Pinned Locked Moved Solved Italian
5 Posts 2 Posters 1.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • lagodolioL Offline
    lagodolioL Offline
    lagodolio
    wrote on last edited by
    #1

    Ciao a tutti, ho un problema con la lettura di un flusso dati da seriale.
    In pratica il pc (Win10) legge i pacchetti passati da un microcontrollore (Arduino UNO o STM32), tali pacchetti consistono in una serie di 8 valori racchiusi tra parentesi quadre e separati
    da una virgola:

    [357,3812,375,357,3811,375,3811,0][357,3814,375,357,3812,375,3812,0] ecc

    In particolare il secondo valore si riferisce al valore di millis(), cioè al tempo trascorso in millisecondi, mentre il quarto, il quinto e il sesto contengono i primi tre valori
    del pacchetto precedente a scopo di debug, il settimo è ancora il millis() e l'ultimo è una variabile di controllo che assume il valore uno nel caso il 4°, il 5° o il
    6° valore non concordassero con quelli precedenti. Tale controllo viene fatto dal microcontrollore per verificere problemi interni.
    Il problema però è sul lato PC.
    il mio programmino legge la seriale tramite:

    //Funzione di lettura seriale "arduino"
    
    void MainWindow::readSerial()
    {
        char * dataBuffer;
        uint16_t size = arduino->bytesAvailable();
        //qDebug() << " size" << size;
        dataBuffer = new char[size + 1];           // + 1 byte for '\0'
        arduino->read(dataBuffer, size);
        dataBuffer[size] = '\0';  // to cut a long story short ;-)
        
    if (dataBuffer!="") 
        {
    //Salva il file nel percorso indicato da pathfile. Il file sarà "dataraw_yy_mm_dd-hh_mm_ss"  
    
            QString dateTimeStringraw=(pathfile+"dataraw_"+dateTimeString);
    
    
            QFile fOut(dateTimeStringraw);
    
            if (fOut.open(QFile::WriteOnly | QFile::Text | QIODevice::Append))
            {
                QTextStream z(&fOut);
                z << dataBuffer << '\n';
                fOut.close();
            } else
            {
    .
                std::cerr << "error opening output file\n";
                //  return EXIT_FAILURE;
            }
    

    tutto sembra procedere bene (a volte anche 25min di acquisizione a 230400 baud) finchè, improvvisamente:

    [290,862252,0,290,862249,0,862249,0] 1927 32768
    [290,862254,0,290,862252,0,862252,0] 1927 32768
    [290,862256,0,290,862254,0,862254,0] 1927 32768
    [290,862258,0,290,862256,0,86226,0,866206,0] 1928 32768 <-----
    [368,866211,0,368,866208,0,866208,0] 1928 32768
    [368,866213,0,368,866211,0,866211,0] 1928 32768
    [370,866215,0,368,866213,0,866213,0] 1928 32768
    [370,866217,0,370,866215,0,866215,0] 1928 32768

    ....
    [372,866571,0,372,866569,0,866569,0] 1928 32768
    [372,866573,0,372,866571,0,866571,0] 1928 32768
    [372,866575,0,372,866573,0,866573,0] 1928 32768
    [372,866577,0,372,8665723,0] 1928 32768 <------
    [308,862627,0,309,862625,0,862625,0] 1928 32768
    [309,862629,0,308,862627,0,862627,0] 1928 32768
    ....

    I valori che seguono la parentesi chiusa indicano il numero di chiamate di arduino->read(dataBuffer, size) e il valore di "size", cioè il valore di arduino->bytesAvailable();
    Da quello che ho visto l'errore si verifica quando c'è una nuova lettura.
    Da notare che il tempo prima "salta" avanti di circa 4sec e poi torna indietro di circa 4sec.
    I valori di controllo (4°,5° e 6° valore) sembrano conservati come se non fosse un errore di trasmissione ma, piuttosto , qualcosa avesse sovrascitto la parte evidenziata tra le due frecce e, in effetti, i due valori di tempo "esterni" all'errore (862258 e 862627) coprono circa lo stesso intervallo di quello "interni" ( 866211 e 866577).
    La mia impressione è che il buffer vada in overflow e continui a prendere valori che poi andranno a sovrascrivere la parte iniziale del buffer stesso ( forse ho detto una bestialità...) ma non capisco il perchè... (il valore finale della terz'ultima riga "8665723" potrebbe essere il 866575 con il 5 troncato- quindi (86657) - che ha sovrascritto un 862623 (valore plausibile per la riga precedente) ->(86657)(23))
    La parte finale del file, interrotta , è:

    [368,866017,0,368,866015,0,866015,0]
    [368,866019,0,368,866017,0,866017,0]
    [368,866021

    e potrebbe essere sensato come ordine di grandezza.
    Qualcuno ha qualche consiglio? Il problema non sembra influenzato dalla velocità di trasmissione, penso sia più un problema di controllo dei dati...
    Grazie 1000

    1 Reply Last reply
    0
    • mrdebugM Offline
      mrdebugM Offline
      mrdebug
      wrote on last edited by
      #2

      Ciao, si tratta di un protocollo elementare, a caratteri stampabili.
      Lato pc il buffer di lettura è enorme e dubito proprio che vada in overflow. Ad ogni modo basta che provi con un putty o con qualche altro programma a monitorare la seriale e vedi subito se l'errore è lato pc o lato mico.
      Se vuoi puoi usare questo programma
      http://www.denisgottardello.it/QtComPort/index.php
      di cui trovi anche i sorgenti
      metterlo in bridge tra micro e programma pc e vedere cosa di dicono programma e pc.
      Secondo me il problema sta lato micro, ma senza codice è dura vedere dove sta il problema.
      Non avete previsto un crc o qualcosa del genere?

      Need programmers to hire?
      www.labcsp.com
      www.denisgottardello.it
      GMT+1
      Skype: mrdebug

      1 Reply Last reply
      0
      • lagodolioL Offline
        lagodolioL Offline
        lagodolio
        wrote on last edited by
        #3

        Ciao e grazie per il suggerimento, in effetti monitorando contemporaneamente la porta potrei vedere subito se i problemi dipendono dalla comunicazione o dal programma in acquisizione. Avevo rinunciato al controllo crc perchè alla fine dovrei leggere i dati provenienti da un altro micro e sul quale non potrei intervenire sul codice di uscita. L'idea dell'overflow era in effetti buttata lì, idee che vengono all'una di notte...
        Non ho messo il codice del micro perchè è poco più di una sequenza di Serial.print e non volevo appesantire troppo il post.
        Lunedì controllo e posto i risultati.
        Grazie mille e buon fine settimana a tutti.

        1 Reply Last reply
        0
        • lagodolioL Offline
          lagodolioL Offline
          lagodolio
          wrote on last edited by lagodolio
          #4

          Un grazie immenso a drdebug, grazie al suo consiglio ho visto subito che il problema era proprio nel micro (o, meglio , nei micro visto che ho usato un Arduino UNO e un STM32...), ora devo capire perchè, visto che -come ho già detto- è poco più di una serie di Print.Serial().
          I

          #define SERIAL_SPEED 115200
          const int y_Pin = A0;
          const int trav_pin = A1;
          
          const int delayTime = 700;
          int test = 0;
          struct
          {
            unsigned long time_x;
            uint16_t y_value;
            uint16_t tr_value;
            unsigned long time_x_old;
            uint16_t y_value_old;
            uint16_t tr_value_old;
          
          } csv_array;
          
          uint16_t y_value_temp;
          uint16_t tr_value_temp;
          uint16_t y_value_arch;
          uint16_t tr_value_arch;
          unsigned long time_x_arch;
          bool start = true;
          
          void setup()
          {
          
            Serial.begin(SERIAL_SPEED);
            csv_array.time_x = millis();
            Serial.flush();
          }
          
          void loop()
          {
            for (;;)
            {
              y_value_temp = analogRead(y_Pin);
              tr_value_temp = analogRead(trav_pin);
              csv_array.time_x_old = csv_array.time_x;
              csv_array.y_value_old = csv_array.y_value;
              csv_array.tr_value_old = csv_array.tr_value;
          
              csv_array.y_value = map(y_value_temp, 0, 1023, 0, 1023);
              csv_array.tr_value = map(tr_value_temp, 0, 1023, 0, 1023);
              csv_array.time_x = millis();
              if (start == false)
              {
                if (y_value_arch != csv_array.y_value_old)
                {
                  test = 1;
                }
                if (tr_value_arch != csv_array.tr_value_old)
                {
                  test = 1;
                }
          
                if (time_x_arch != csv_array.time_x_old)
                {
                  test = 1;
                }
                if (csv_array.time_x_old > csv_array.time_x)
                {
                  test = 1;
                }
              }
              start = false;
              Serial.print("[");
          
              Serial.print(csv_array.y_value);
              Serial.print(",");
          
              Serial.print(csv_array.time_x);
              Serial.print(",");
          
              Serial.print(csv_array.tr_value);
              Serial.print(",");
          
              Serial.print(csv_array.y_value_old);
              Serial.print(",");
          
              Serial.print(csv_array.time_x_old);
              Serial.print(",");
          
              Serial.print(csv_array.tr_value_old);
              Serial.print(",");
          
              Serial.print(time_x_arch);
              Serial.print(",");
          
              Serial.print(test);
              Serial.print("]");
          
              Serial.flush();
              y_value_arch = csv_array.y_value;
              tr_value_arch = csv_array.tr_value;
              time_x_arch = csv_array.time_x;
            }
          }
          

          Grazie comunque a tutti, il codice QT in realtà è parte di un progetto più complesso e fare il debug di tutto , temendo di essere vittima di un errore annidiato in un ciclo if o di un vero e proprio errore di impostazione , beh , mi stava già facendo venire il mal di testa! ;-)

          1 Reply Last reply
          0
          • lagodolioL Offline
            lagodolioL Offline
            lagodolio
            wrote on last edited by
            #5

            Ho capito che il problema stava nella comunicazione tra pc e micro, infatti facendo alcune prove con Linux e concatenando da terminale l'output su un file non ho riscontrato problemi.
            Grazie ancora a tutti!

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved