Arduino MICRO (LEONARDO) e Serial

Ho un problema che non riesco a risolvere con MICRO (LEONARDO).

Alla fine del ciclo di loop, effettuo un serie di Serial.print per monitorare le variabili.

Se non apro sull'IDE il Serial Monitor il ciclo procede normalmente.

Se lo apro, succede lo stesso, con in più il fatto che il Serial Monitor visualizza le informazioni.

Ma se lo chiudo, dopo un po' il loop rallenta moltissimo, forse perché il buffer di uscita si è riempito.

Se riapro il Serial Monitor, tutto ritorna normale.

Avevo pensato di usare if (Serial) , ma if (Serial) verifica solo la connessione USB e quindi non è di aiuto.

Come posso evitare questo blocco?

Al 99% problema è lato pc e quasi sicuramente totalmente a carico del IDE.
Prova ad usare un terminale seriale alternativo a quello del IDE e dovrebbe scomparire.
La causa è legata a come l'IDE usa la seriale e al fatto che se non viene svuotato il buffer dei dati in arrivo dalla Vcom, sul pc, si mettono in mezzo delle attese che si ripercuotono sulla gestione della USB sul 32u4, integrata nel micro e gestita da software, che possono causare rallentamenti in esecuzione.
La soluzione è semplicemente chiudere la Vcom quando viene cessata la comunicazione, cosa che il serial monitor di Arduino non fa o lo fa male, ho riscontrato problemi anche con la UNO per questa cosa.

Intendi dire usare Serial.end() e nuovamente Serial.begin() prima di stampare?

Ho fatto una prova.

La cosa succede anche con un programma come HyperTerminal su Windows XP, quindi deduco che l'IDE sia innocente.

A questo sospetto sia il driver USB, cosa ne dici?

Se è vero che la stessa cosa accade con la UNO, possibile che nessuno si sia accorto di questa anomalia?

cyberhs:
Se è vero che la stessa cosa accade con la UNO, possibile che nessuno si sia accorto di questa anomalia?

Non la stessa cosa, con la UNO, originale, a volte capita che dopo aver chiuso il serial monitor alla successiva apertura arriva un errore di porta giù in uso, tipico di quando una Vcom non viene chiusa e si cerca di accedervi nuovamente, unico modo per risolvere è disconnettere la UNO dalla USB e ricollegarla.
Questa cosa capita solo con il serial monitor del IDE, con qualunque altro programma per accedere alla seriale non ho mai riscontrato lo stesso problema.
So per certo che la Vcom non sempre viene correttamente chiusa dal serial monito perché l'ho verificato con un programma che analizza il traffico e lo stato della seriale, problema riscontrato su pc diversi e non limitatamente al mio desktop.

mmmm io posterei il codice che usi....

Versione dell'IDE utilizzata?

cyberhs:
A questo sospetto sia il driver USB, cosa ne dici?

In realtà non esiste un driver usb per la Leonardo o la UNO, c'è solo il file .inf che descrive quale driver usare e i relativi parametri, perché viene usato il driver nativo di Windows, usbser.sys, ed è lo stesso per tutti i modelli di Arduino, originali, non dotati di FTDI.

vbexteme: in setup Serial.begin(9600); mentre alla fine del loop if (Serial) Monitor() ove monitor è una semplice serie di print. Anche senza if (Serial) il problema permane.

PaoloP: IDE 1.6.5

Astro: con la MICRO si aprono due COM una per Arduino MICRO (COM3) e l'altra per il programmer (COM5) anche se solo per qualche istante. Presumo che sia dovuto al fatto che inizialmente la USB inizializzata non sappia cosa verrà usato. Cosa seccante perché ogni volta che resetto il micro, devo anche selezionare la porta COM3.

avrei detto il codice e non il riassunto.... o una sua versione semplificata ma che effettivamente crei il problema.

vbexteme: purtroppo, fa parte di un articolo per una rivista e, per ora, non posso pubblicarlo.

Comunque, è uno sketch molto semplice e la parte seriale si limita a quanto ho detto.

Posso solo aggiungere che il MICRO in realtà è il Beetle, di cui ti avevo già parlato.

@cyberhs ma il problema lo hai solo con quel firmware o è generale?
Puoi postare qualsiasi firmware basta che riproduca il problema.
Io sono dell'idea che ci sia qualche problema nel codice.
Hai controllato che la if(serial) funzioni a dovere?
Perché se richiami l'output solo se sei collegato allora quando non lo sei dovresti avere un ritardo semplicemente di 10ms.
In teoria non ci sarebbe neanche bisogno di controllare se sei connesso perché lo fa in automatico nella write, quindi se hai poche chiamate è ridicolmente più performante non controllarlo proprio!

Bho posso solo fare supposizioni, mi hanno rubato la sfera...ahahhahaha...

vbextreme: if(Serial) non è fondamentale, poiché serve soltanto ad evitare di stampare se la porta USB non è pronta (ti ricordo che su quel tipo di schede è emulata via software).

Se hai una MICRO o una LEONARDO puoi verificare facilmente la cosa.

Mi spiace che hai perso una sfera: fa molto male? :slight_smile:

cyberhs:
Posso solo aggiungere che il MICRO in realtà è il Beetle, di cui ti avevo già parlato.

Molte interessante. :slight_smile:

Nell'articolo che dovrebbe andare presto in stampa, ho inserito anche una "elaborazione" del Beetle per aggiungere altri pin e dotarlo di zoccolo DIY.

Vedi anche il Bluno Beetle, che in più è dotato di più pin e di Bluetooth:

@PaoloP è moolto bella e costa poco, o meglio il giusto!

@cyberhs la if(serial) non è fondamentale! anzi in alcune circostanze ridicola....
La funzione write controlla gia se sei collegato o meno e invia i dati solo se sei collegato.
Quindi tecnicamente

Serial.print("ciao");

è quasi identico a scrivere

if (Serial) Serial.print("ciao");

Perché ho scritto quasi? perche nel secondo codice in caso tu non sia connesso hai un delay(10) mentre nel primo codice no, nonostante anche il primo codice non invii i dati se non si è connessi.
Questo discorso naturalmente è valido solo per la leonardo o chip simili che conunque usino l'usb hardware.

È difficile però capire quale sia il problema senza vedere il codice!
P.S. penso di aver perso la sfera ma può essere che goku me l'abbia sottratta!

vbextreme:
@cyberhs la if(serial) non è fondamentale! anzi in alcune circostanze ridicola....
La funzione write controlla gia se sei collegato o meno e invia i dati solo se sei collegato.

Secondo me la write non controlla. Scrive nel registro di spedizione. Se la porta non è aperta semplicemente la MCU non fa nulla. Parere mio.

@nid69ita il codice parla chiaro:
Vai alla riga 229 e vedi l'overload dell'operatore bool sulla chiamata alla Serial, tale funzione controlla lo stato della variabile "_usbLineInfo.lineState" e se e' 0 aspetta 10 millisecondi a ritornare false.
Ora vai alla riga 198 la write controlla sempre la stessa variabile solo che setta l'errore ed esce immediatamente.

L'attesa nel mio ciclo raggiunge circa 4 secondi ed uso 14 Serial.print.

Ma ti sei avvicinato al problema: ho provato a ridurre il numero di print a 2 e l'attesa si riduce a circa mezzo secondo o poco più.

Sembra che sia una sorta di riempimento di un buffer in quanto il rallentamento non si manifesta subito ma dopo un certo tempo (diciamo 60 secondi con 2 print), variabile secondo il numero di print e, suppongo, il numero di caratteri.

magari se posti il codice mi avvicino ancora di più.....