Arduino Forum

International => Italiano => Software => Topic started by: zoomx on May 24, 2016, 04:24 pm

Title: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: zoomx on May 24, 2016, 04:24 pm

Durante la realizzazione di un progetto mi sono accorto di un comportamento curioso che non so a cosa sia dovuto.

Quando apro la porta COM da PC senza resettare Arduino la routine che aspetta caratteri nello sketch rileva un F0 che non ho spedito io.

Succede ogni volta che apro la porta ma solo in quel momento. Se chiudo la porta da Windows e poi la riapro il problema si ripresenta.

Mi accade con macchine diverse che hanno sempre Windows. Non ho provato con Linux.


Una ricerca in rete mi ha dato come risultato utile solo questa discussione del 2013

http://forum.arduino.cc/index.php?topic=150620.5 (http://forum.arduino.cc/index.php?topic=150620.5)

senza alcuna soluzione.


I test sono stati effettuati con Arduino UNO R3 originale.

Se carico lo sketch in un clone Nano con CH340 il problema non si presenta. Non ho a portata di mano altri cloni per fare altre prove.

Sembrerebbe quindi che il problema stia nel chip usato da Arduino come convertitore seriale come del resto ipotizza l'autore della discussione che ho linkato.


Per vedere l'effetto bisogna usare un terminale che non cambi le linee RTS e DTR.

Usando il terminale seriale dell'IDE il problema non si presenta perché dopo l'apertura della porta viene effettuato un reset.

Se si usa Realterm bisogna prima andare nella scheda "pins" e fare il clear sia della linea RTS che DTR. A questo punto basta tornare alla scheda "display" e aprire e chiudere la porta con il pulsante open per vedere che succede.

Il programma che uso si chiama semplicemente Terminal ed è possibile scaricarlo da qui

https://sites.google.com/site/terminalbpp/ (https://sites.google.com/site/terminalbpp/)
Se ogni volta che aprite la porta dopo pochi secondi vi appare la scritta "F0problem" , che viene stampata nel setup, vuol dire che è stato effettuato un reset.

Code: [Select]
/*
   F0problem
   Test program to resolve the F0 problem
   When Serial port is opened in Windows
   I found an F0 in the Serial buffer
*/

//Serial input with termination section
#define INLENGTH 6          //Max string lenght over serial. Needed for input with termination
#define INTERMINATOR 13     //GetCharFromSerial routine cycle waiting for this character. Needed for input with termination

char inString[INLENGTH + 1]; //GetCharFromSerial returns this char array. Needed for input with termination
unsigned char comm; //First character received. Needed for input with termination

//SerialInputNewline
const byte numChars = 32;
char receivedChars[numChars];  // an array to store the received data
boolean newData = false;

//***********************************************************************************************
void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = 13;   //'\r';
  char rc;

  // if (Serial.available() > 0) {
  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();
    Serial.print("recvWithEndMarker->");
    Serial.println(rc);

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}

void ParseMenu(char Stringa) {
  boolean IsKnownCommand = true;
  switch (Stringa) {

    case 'p':
      break;
    case 'm':

      Serial.println("Print menu");
      break;
    case 'w':
      Serial.println("Execute w");
      break;
    default:
      IsKnownCommand = false;
  }
  if (IsKnownCommand == true)
  {
    Serial.println("OK");
    EndCommand();
  } else {
    Serial.println("ERROR!");
    Serial.println(Stringa, HEX);
  }
}

//***********************************************************************************************
void EndCommand() {
  Serial.println("End command");
}

void setup() {
  Serial.begin(115200);
  Serial.println("F0problem");
}


void loop() {

  recvWithEndMarker();
  if (newData == true) {
    comm = receivedChars[0];

    Serial.print("Command->");
    Serial.print(comm);
    Serial.print(" ");
    Serial.println(comm, HEX);

    if (comm != 0xF0) {
      ParseMenu(comm);
    }
    else
    {
      //comm = 'p';
      Serial.println("Discard F0");
      Serial.println("OK");
      EndCommand();
    }
    newData = false;
  }
}



Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: astrobeed on May 24, 2016, 10:13 pm
La "colpa" è del 16u2.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: zoomx on May 25, 2016, 09:22 am
Nelle issue non ho trovato nulla. Per adesso ho aggiunto un check per eliminare il dato errato ma non è una bella soluzione.
L'altra ipotesi è sostituire l'originale con un clone con CH340.

Curioso che abbia trovato solo un thread che ne parli ma può essere che nessuno si sia intestardito a trovarne le cause o abbia ritenuto che il problema fosse nello sketch come all'inizio avevo supposto io.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: astrobeed on May 25, 2016, 09:36 am
Curioso che abbia trovato solo un thread che ne parli ma può essere che nessuno si sia intestardito a trovarne le cause o abbia ritenuto che il problema fosse nello sketch come all'inizio avevo supposto io.
Più semplicemente non ci ha fatto caso nessuno sia perché normalmente fanno resettare Arduino quando si apre la seriale oppure non si sono accorti della cosa.
Personalmente quando apro la seriale sul pc faccio sempre un flush dopo 100 ms, questo perché non è insolito ricevere del garbage dai device, quindi non mi sono mai accorto di questo specifico problema di Arduino fino a che ieri sera non l'ho verificato dopo la tua segnalazione.
Ti conferma che è il 16u2 perché ho controllato con l'analizzatore di stati logici se il 328 invia qualcosa all'apertura della seriale, senza reset, e non lo fa.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: zoomx on May 25, 2016, 02:43 pm
Ne avevo il forte sospetto ma tu mi dai conferma. GRAZIE!

Non posso adottare la tua soluzione in quanto all'apertura della porta è Arduino che riceve la spazzatura e credo non abbia modo di sapere se la porta è aperta o no. Dal lato PC ovviamente lo so e per adesso il workaround è mandare un primo comando che non fa nulla.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: paulus1969 on May 25, 2016, 04:49 pm
Quindi è Windows che invia quel carattere, quando apri la porta da Windows.

Usalo a tuo vantaggio, appena arriva quel carattere, sai che hai aperto la porta  :)
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: zoomx on May 25, 2016, 05:01 pm
Non è Windows, è il chip 16u2. Se uso un clone con CH340 non succede.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: astrobeed on May 25, 2016, 05:50 pm
Se uso un clone con CH340 non succede.
Esatto è lui, viene inviato nei due sensi, sia verso l'ATmega che verso il PC.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: zoomx on May 26, 2016, 08:26 am
Non me ne ero accorto dell'invio anche verso il PC, Eppure lo avevi scritto prima. Rigrazie!
E' l'unico caso in cui un clone risulta superiore. Penso che anche gli altri chip di conversione USB seriale come l'FTDI e il Prolific non generino caratteri.
Il carattere generato però è sempre lo stesso, un F0.
Ne programma di test però ho aggiunto una print nella routine di ricezione e succede che il primo print è sporcato in maniera casuale.

L'Arduino non può sapere se la porta è aperta o meno poiché vede i caratteri arrivargli dal chip 16u2. Potrebbe essere quindi un problema nel firmware del 16u2?
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: astrobeed on May 26, 2016, 08:34 am
L'Arduino non può sapere se la porta è aperta o meno poiché vede i caratteri arrivargli dal chip 16u2. Potrebbe essere quindi un problema nel firmware del 16u2?
Tocca andare a vedere il codice del 16u2 per capire cosa succede quando viene aperta la com virtuale, può essere sia un bug sia una cosa voluta per un qualche scopo, magari pensato in origine e mai utilizzato in pratica.
Devo verificare se avviene la stessa cosa anche sulla Mega visto che pure lei usa il 16u2.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: zoomx on May 26, 2016, 10:57 am
Io per adesso posso dire che capita sia sugli Arduino UNO R3 di Arduino.cc che su quelli di Arduino.org.
La Mega è sepolta da qualche parte a casa.

Ho provato con il Launchpad MSP430 che ha anche lui un micro sempre Texas che svolge lo stesso compito del 16u2 con Energia e riducendo la velocità della seriale a 9600 (alrimenti non funziona!). Il bug non c'è.

Se trovo il tempo vorrei provare anche con l'HoodLoader2 che è il bootloader alternativo che consente l'uso del 16u2 in ambiente Arduino.
https://github.com/NicoHood/HoodLoader2/wiki (https://github.com/NicoHood/HoodLoader2/wiki)
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: astrobeed on May 26, 2016, 11:13 am
Se trovo il tempo vorrei provare anche con l'HoodLoader2 che è il bootloader alternativo che consente l'uso del 16u2 in ambiente Arduino.
Interessante, devo provarlo.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: zoomx on May 26, 2016, 11:24 am
Dopo aver provato sul Launchpad a 9600 mi è venuto il dubbio se il bug fosse dipendente o meno dalla velocità.

Ho ricompilato quindi lo sketch per i 9600 su Arduino Uno originale e sembra che a questa velocità il bug non ci sia. Non me lo aspettavo. Non sembrerebbe però che sia una caratteristica voluta, il carattere cambia.
Idem per 57600
A 128000 il carattere è ancora un F0
A 256000 il carattere è uno zero
A 38400 è un FF

E a questo punto mi son fermato. Speravo che si presentasse da 115200 in poi. Non è così.

Edit: mi rendo conto che notarlo sarebbe stato difficile visto che ad alcune velocità non si presenta.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: astrobeed on May 26, 2016, 11:38 am
Edit: mi rendo conto che notarlo sarebbe stato difficile visto che ad alcune velocità non si presenta.
Più che altro perché nella stragrande maggioranza dei casi si lascia resettare Arduino all'apertura della seriale, oppure si utilizza un protocollo dati che ignora il carattere e non ci si fa caso, p.e. io implemento sempre un timeout sulla seriale dei micro/mcu, se il pacchetto dati non arriva completo azzero il buffer, se non aprivi questo topic quasi sicuramente non mi sarei mai accorto della cosa. :)
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: speedyant on May 26, 2016, 11:43 am
Possibile che sia un problema di "sincronia" con le frequenze per la usb.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: astrobeed on May 26, 2016, 11:53 am
Possibile che sia un problema di "sincronia" con le frequenze per la usb.
Cosi intendi con "frequenze" ?
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: speedyant on May 26, 2016, 12:00 pm
Forse sto facendo confusione con il pll dei micro... Nel senso che per la gestione della usb il micro "genera" la frequenza a seconda di come imposti i parametri del pll.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: astrobeed on May 26, 2016, 12:18 pm
Penso di aver capito da cosa dipende, mi ha ingannato il fatto che la prima verifica strumentale l'ho fatta con l'analizzatore di stati logici, adesso ho rifatto il test con il DSO, allego lo screen shot di cosa avviene all'apertura della seriale.
In pratica all'apertura della seriale il 16u2 genera un impulso negativo di circa 4 us sul Rx del 328, a seconda della velocità della seriale questo viene interpretato come un carattere valido con vari valori.
Devo verificarlo, però è probabile che il pin Tx del 16u2 viene tenuto in condizione di alta impedenza quando la seriale usb non è in uso, questo per limitare possibili interferenze con l'uso della seriale da parte di altro hardware, nel momento in cui il pin viene riportato alla condizioni di output si crea l'impulso dato che probabilmente è settato a 0 logico e ci vuole qualche us perché ritorni a 1 logico per la condizione di idle.
Nota aggiuntiva, al lato pc in realtà non arriva nulla, mi sono scordato che stavo facendo il test con uno sketch che fa l'eco del Rx sul Tx del 328 pertanto è normale che al pc arriva tutto quello che riceve l'Atmega, eliminato lo sketch non arriva più nulla.

(http://www.mdaproject.it/doc/F0.png)
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: astrobeed on May 26, 2016, 01:58 pm
Il "problema" dovrebbe stare in queste righe di codice del firmware del 16u2:

Code: [Select]
/* Must turn off USART before reconfiguring it, otherwise incorrect operation may occur */
UCSR1B = 0;
UCSR1A = 0;
UCSR1C = 0;

/* Special case 57600 baud for compatibility with the ATmega328 bootloader. */
UBRR1  = (CDCInterfaceInfo->State.LineEncoding.BaudRateBPS == 57600)
? SERIAL_UBBRVAL(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)
: SERIAL_2X_UBBRVAL(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS);

UCSR1C = ConfigMask;
UCSR1A = (CDCInterfaceInfo->State.LineEncoding.BaudRateBPS == 57600) ? 0 : (1 << U2X1);
UCSR1B = ((1 << RXCIE1) | (1 << TXEN1) | (1 << RXEN1));


Vengono invocate ogni volta che si apre la seriale, o viene resettato il 16u2, in pratica l'UART viene resettata e reinizializzata ogni volta che si apre la seriale.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: zoomx on May 26, 2016, 03:10 pm
Il fatto che a 9600 non compaia spiega a me perché non l'ho notato prima: usavo sempre i 9600 come standard.




Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: astrobeed on May 26, 2016, 04:18 pm
Il fatto che a 9600 non compaia spiega a me perché non l'ho notato prima: usavo sempre i 9600 come standard.
Non compare perché un impulso di 4 us è troppo breve per poter essere interpretato come un carattere dalla UART.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: PaoloP on Jun 10, 2016, 12:51 pm
Questo topic mi era sfuggito.  :smiley-confuse:
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: testato on Jun 11, 2016, 09:56 am
bella scoperta, non lo avevo mai notato nemmeno io

Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: zoomx on Jun 22, 2016, 03:44 pm
Ho appena provato l'l'HoodLoader2 e il problema sembra sparito. Apro una issue? Non devo per forza aprirla io lo può fare anche un altro.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: PaoloP on Jun 22, 2016, 04:23 pm
Ma l'HoodLoader va caricato sul 16U2?
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: zoomx on Jun 22, 2016, 04:58 pm
Si, ho seguito la Wiki. Una volta caricato è praticamente trasparente ma non presenta il problema che invece aveva prima: niente F0 a 115200.

Il bug è presente anche nelle Arduino.org che ho preso da RS.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: zoomx on Nov 21, 2017, 08:40 am
Riapro questa vecchia discussione perché sembrerebbe che tale comportamento si presenti con Windows e non in Linux.
L'utente Robin2 ha provato lo sketch su una Mega,Linux Mint con minicom e putty e non ha notato tale comportamento che invece è presente nell'argomento del primo post.
https://forum.arduino.cc/index.php?topic=512209.msg3493962#msg3493962 (https://forum.arduino.cc/index.php?topic=512209.msg3493962#msg3493962)

Non ho una macchina Linux sottomano per cui per adesso non posso replicare le sue prove.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: gpb01 on Nov 21, 2017, 08:45 am
Riapro questa vecchia discussione perché ...
... te la lascio passare SOLO perché tu sei l'autore originale del thread ed i vari partecipanti tutt'ora molto attivi ! :)

Altrimenti, in conformità al REGOLAMENTO (http://forum.arduino.cc/index.php?topic=149082.0), punto 16.9, il tuo post sarebbe stato cancellato ed il thread chiuso. Tienilo presente per altri casi ;)

Guglielmo

Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: astrobeed on Nov 21, 2017, 09:04 am
Riapro questa vecchia discussione perché sembrerebbe che tale comportamento si presenti con Windows e non in Linux.
Dato che il problema è legato al firmware sul 16u2, non al sistema operativo, trovo difficile credere che questa cosa dipende da Windows, anzi lo trovo impossibile. :)
Adesso non ho tempo per fare verifiche incrociate con Linux, però durante il fine settimana qualche provo dovrei riuscire a farla.
Title: Re: Buffer di ricezione sporco di F0 all’apertura della porta COM Su Arduino UNO R3
Post by: zoomx on Nov 21, 2017, 12:12 pm
Guglielmo,
ho meditato sulla cosa ma la possibile novità mi sembrava un piccolo cambiamento, oppure uno grande, dipende dai risultati.
Ho pensato che aprendo un nuovo post avrei dovuto riscrivere praticamente tutto quanto già scritto qui, sebbene avrei potuto aggiungere un link. Tenerlo unito penso che sia stato meglio.

Ho presente il necroposting, il forum mi avverte con una bella scritta rossa. Grazie comunque!