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.5senza 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/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.
/*
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;
}
}