Serial.flush() ide 1.03 NON FUNZIONA

salve,

sto usando arduino uno con ide 1.0.3 ma quando uso il comando Serial.flush() il buffer non viene cancellato. si può cancellare il buffer in altri modi, oppure c'è un modo per far funzionare il Serial.flush()?

ringrazio anticipatamente :-))

E' cambiato il suo comportamento.
Adesso non svuota più il buffer.

Devi farlo tu via codice con una semplice funzioncina:

void svuotaBuffer() {
  while (Serial.available()) {
    byte temp = Serial.read();
  }
}

Basta chiamarla con svuotaBuffer() che ti svuota tutto.

Ehmmm.... e adesso cosa fa, svuota solo il buffer di uscita?

Ciao Uwe

approfitto per chiedere un chiarimento.
ho visto che flush fa parte di Stream, e che Stream viene usata da altre funzioni tipo il print.
vuol dire che quindi manualmente non serve usarla ?

quando leggo un byte dal buffer seriale con il serial.read automaticamente lo tolgo anche dal buffer, mica serve il flush, viene usato in sottofondo dal core stesso ?

Ne approfitto anche io per chiedere qualcosa.

Il buffer viene riempito automaticamente anche se non uso Serial.read? In altre parole se tra il Serial.begin e il Serial.read arrivano caratteri, questi vanno persi?

Testato
credo dipende da cosa intendi per byte tolto dal buffer. Una volta che lo leggi con Serial.read non lo puoi rileggere più con Serial.read ma non so se venga eliminato in maniera irrecuperabile dal buffer o invece semplicemente non venga spostato un puntatore, bisognerebbe leggere il codice.

Testato:
approfitto per chiedere un chiarimento.
ho visto che flush fa parte di Stream, e che Stream viene usata da altre funzioni tipo il print.
vuol dire che quindi manualmente non serve usarla ?

quando leggo un byte dal buffer seriale con il serial.read automaticamente lo tolgo anche dal buffer, mica serve il flush, viene usato in sottofondo dal core stesso ?

Il flush() nella versione fino alla IDE0023 serviva a svuotare il buffer di entrata non considerando i dati per avere un buffer vuoto, pronto per la prossima spedizione.
Sí, il Serial.read togle il bte letto dal buffer.

Ciao Uwe

Ciao Uwe

zoomx:
Ne approfitto anche io per chiedere qualcosa.
Il buffer viene riempito automaticamente anche se non uso Serial.read? In altre parole se tra il Serial.begin e il Serial.read arrivano caratteri, questi vanno persi?
...

Il buffer si riempie automaticamente se arrivano dati sulla seriale finche é pieno. Non perdi niente a patto che il buffer non é pieno.
Devi svuotarlo regolarmente con Serial.Read() per non farlo riempire troppo.

Nella comunicazione seriale RS232 sono previti diversi protocolli (Handshake) per segnalare che il trasmettitore ha disponibile dei dati e il ricevitore é pronto per riceverele. Vengono usati dei Segnale RTS/CTS e altri, oppure via SW con i caratteri XON/XOFF (Xon = 11h und Xoff = 13h).

Ciao Uwe

Quindi alla fine si conferma che non serve usarlo.
Personalmente ho sempre fatto così: quando uso la seriale voglio che quello che spedisco venga ricevuto, non è che mi metto a spedire cose che non voglio ricevere, qyindi da dove deriva il discorso di diver svuotare il buffer ? Automaticamente il buffer lo svuoto con il read.
Se ho problemi a ricevere perderò i dati visto che il buffer è di tipo ring. Ma ripeto in nessun caso chiamo manualmente il flush

Grazie Uwe

questa informazione non mi sembra sia presente nella documentazione, io non l'ho trovata ma potrei benissimo non averla vista.

Testato:
Quindi alla fine si conferma che non serve usarlo.
Personalmente ho sempre fatto così: quando uso la seriale voglio che quello che spedisco venga ricevuto, non è che mi metto a spedire cose che non voglio ricevere, qyindi da dove deriva il discorso di diver svuotare il buffer ? Automaticamente il buffer lo svuoto con il read.
Se ho problemi a ricevere perderò i dati visto che il buffer è di tipo ring. Ma ripeto in nessun caso chiamo manualmente il flush

Ci sono occassioni dove serve come per esempio se puoi ignorare certi comandi perché non li decodifichi oppure se non Ti interessano delle risposte a delle istruzioni con cui un apparecchio risponde.

Ciao Uwe

ok, intendi nel caso ti interfacci ad un oggetto non progettato da te, si in quel caso puo' servire

zoomx:
Ehmmm.... e adesso cosa fa, svuota solo il buffer di uscita?

Svuota il buffer in ingresso, essendoci un Serial.read :wink:

Il buffer viene riempito automaticamente anche se non uso Serial.read? In altre parole se tra il Serial.begin e il Serial.read arrivano caratteri, questi vanno persi?

La seriale riempie il buffer attraverso gli interrupt. In caso il buffer sia pieno, essendo circolare, i dati nuovi sovrascrivono quelli più vecchi. Il fatto di perdere i dati si ha con le vecchie implementazioni di SoftSerial che NON erano ad interrupt, e quindi non aveva il buffer in entrata ed era facile perdere i dati.

venga spostato un puntatore, bisognerebbe leggere il codice.

bhe certo, viene spostato il puntatore di "inizio" sul buffer circolare. il dato è ancora nel buffer ma salvo pesanti modifiche della libreria è irrecuperabile.

Quindi alla fine si conferma che non serve usarlo.

infatti prima la flush() aveva poco senso. Ora la flush() segue gli standard "de facto" per cui la flush ti mette in attesa che venga svuotata il buffer IN USCITA.
se tu scrivi "ciao", esso viene parcheggiato nel buffer in uscita, e scritto quando gli interrupt HW della sriale sengnalano la possibilità di inviare un carattere. Mettiamo caso che tu vuoi essere sicuro che prima di procedere nel codice, l'altra parte abbia ricevuto il messaggio: chiami la flush e sei a posto. notare che se provi a scrivere quando il buffer è pieno, o quando chiudi la seriale, la flush() viene chiamata automaticamente.

Tra l'altro molto simile è il motivo per cui le USB (ma anche file, filesystem, periferiche e mille altre cose) vanno "smontate in modo sicuro": i dati non sono scritti subito, ma salvati nel buffer del SO. Nel momento in cui fai la rimozione sicura, o che il software lo richiede, viene effettuata la scrittura vera e propria.

lesto,

la tua spiegazione è chiarissima e mi aiuterà a debuggare meglio il codice che avevo postato qui
http://forum.arduino.cc/index.php?topic=166840.0
dove avevo il sospetto che la stampa su seriale venisse interrotta da un reset dovuto ad un problema di memoria successivo. E dire che avevo letto la documentazione, evidentemente con poca attenzione.
A pensarci bene in effetti ha più senso per il buffer in uscita che per quello in entrata.

Se il buffer è circolare e c'è un puntatore posso sempre recuperare il contenuto con una lettura diretta della memoria. Ma è pura masturbazione mentale, non credo servirebbe a qualcosa.
Ma le informazioni sulle grandezze dei buffer, sull'interrupt usato, sul fatto che i buffer siano circolari, dove sono scritte? Sono io incapace (possibilissimo) oppure nella guida di riferimento non ci sono?

Ma le informazioni sulle grandezze dei buffer, sull'interrupt usato, sul fatto che i buffer siano circolari, dove sono scritte? Sono io incapace (possibilissimo) oppure nella guida di riferimento non ci sono?

tempo fa misi le mani nel codice della libreria, per questo lo so. Purtoppo la documentazione di arduino è frammentaria e alle volte errata, molto spesso si risparmia tempo leggendosi direttamente le librerie.

Grazie Lesto della spiegazione karma+1 :slight_smile:

Quando scrivi che il flush ti da garanzia cge sia stato ricevuto il dato crwdo intendessi garanzia che sia stati inviato, poi se viene ricevuto non si sa, servw una gestione degli handshake per quello.

Ma il flush quindi esiste solo in trasmissione ? Oppure anche in ricezione ? Come lo si deve intendere per la ricezione ?

non esiste in ricezione, o meglio esisteva per la vecchia versione di SoftSerial e svuotava il buffer di lettura... cosa abbastanza inutile data la sua natura circolare, oltre che essere fuorviante con la flush() che come spiegato è uno standard di fatto; esiste in tutti i linguaggi e in tutti funziona allo stesso modo. Diciamo che al massimo potevano chiamarla clear() :grin:

non a caso, ora che tutto ciò che scrive/legge su flusso è sottoclasse della classe Stream, la funzione flush è stata uniformata allo standard. Tra l'altro, in teoria, ora anzichè usare serial potete usare:

Stream qualcosa = Serial;

e fare le vostre cose con qualcosa (ovviamente limitati da ciò che offre la classe Stream). Quando vorrete passare da Serial a File, basterà cambia la riga di codice nel modo corretto, tipo

Stream qualcosa = File("log.txt");

e così via. In teoria anche i2c, spi etc. POTREBBERO divenire sottoclassi di strem.

Questa è la vera flush() :grin:

e' un nuovo modello arduino ? :stuck_out_tongue_closed_eyes:

x Lesto:

Sorry, you can't repeat a karma action without waiting 1 hours.

:slight_smile: