- Messaggi: 1010
- Ringraziamenti ricevuti 107
Arduino e ricezione seriale
9 Anni 7 Mesi fa #11
da Pinna
Chi vola vale, chi vale vola, chi non vola è un vile
Risposta da Pinna al topic Arduino e ricezione seriale
è proprio questo il punto: l'evento datareceived è uguale sia per il thread principale che per quello esterno, con il classico delegate che punta ad una richtext box che viene aggiornata continuamente... infatti posso muovere ogni singolo servo dal thread principale senza problemi, mantenendo l'impulso costante. Ma nell'altro caso, per inviarlo ciclicamente, devo ricorrere all'altro thread che ho creato. Per questo ho il dubbio che il thread secondario della porta seriale non sia equivalente ad un thread esterno. Comunque questo fatto potrebbe dipendere anche da come ho scritto il firmware per il pic...
Chi vola vale, chi vale vola, chi non vola è un vile
Si prega Accedi o Crea un account a partecipare alla conversazione.
- Pinna
- Moderator
Riduci
Di più
9 Anni 7 Mesi fa #12
da Gianni
Sono tutti bravi ad essere "open" con il "source" degli altri.
Un amico è colui che ti dice sempre quando stai sbagliando. Il mio miglior amico è il parser.
SettoreZero
Risposta da Gianni al topic Arduino e ricezione seriale
Allora, faccio il punto della situazione, anticipando che non ho ancora risolto il problema.
Marcello ti ringrazio innanzitutto per il suggerimento che mi hai dato. Ho cercato un po' e ho trovato un esempio su MSDN a questo indirizzo:
msdn.microsoft.com/en-us/library/system....ng=vb#code-snippet-2
anche qui, come dicevi tu, fa uso di un thread a parte... e solo leggendo questo esempio ho capito quello che volevi dire tu.
In pratica si svincola completamente dall'evento DataReceived, ed avvia un thread con una sub bloccata su un ciclo continuo che esegue continuamente la lettura della seriale.
Ho implementato anche io questo sistema, e ho trovato molti vantaggi:
- ho potuto eliminare alcune sub e alcune istruzioni che servivano a svuotare il buffer
- ho ridotto notevolmente alcuni tempi che mi servivano all'avvio del software per riconoscere se l'interfaccia collegata era quella giusta o meno
- il timeout lo posso gestire direttamente usando la proprietà apposita dell'oggetto serialport
- l'aggiornamento dei dati mi sembra anche piu veloce, ma questa potrebbe essere solo una mia impressione.
Nonostante tutto questo, a random, l'interfaccia si blocca ugualmente nel senso che la porta seriale va in timeout (non ho piu ricezione di dati) e si impasta (nel senso che è presente nel pannello di controllo ma non è possibile eseguirci operazioni).
Arrivati a questo punto, ho realizzato un firmware demo per arduino in cui il conteggio dei pezzi viene incrementato via software svincolandomi dal segnale rilevato sul pin. In pratica nella routine che scrive sulla porta seriale, richiamo la funzione per incrementare il numero di pezzi (funzione normalmente "attaccata" all'interrupt generato al cambio di stato sul pin che conteggia i pezzi). E cosa accade? Funziona tutto perfettamente da giorni, H24.
A questo punto, mi sono detto, il problema può stare soltanto nel firmware su Arduino.
Controllando e rileggendo sul sito di Arduino, mi sono accorto che, usando variabili che possono essere modificate sia negli interrupt che nel main, queste devono essere dichiarate con la parola chiave "volatile" (arduino.cc/en/reference/volatile), cosa che io *NON* ho fatto, perchè abituato coi pic, questo problema non l'ho mai avuto, e già la gestione degli interrupt con il wiring è un po diversa.
Farò quindi quest'altra prova, anche se mi pare strano che per via di questo la seriale possa impastarsi al punto di non essere più riconosciuta lato PC / andare in timeout. Spero con tutto il cuore che il problema sia soltanto questo perchè ve lo giuro, sto impazzendo.
Marcello ti ringrazio innanzitutto per il suggerimento che mi hai dato. Ho cercato un po' e ho trovato un esempio su MSDN a questo indirizzo:
msdn.microsoft.com/en-us/library/system....ng=vb#code-snippet-2
anche qui, come dicevi tu, fa uso di un thread a parte... e solo leggendo questo esempio ho capito quello che volevi dire tu.
In pratica si svincola completamente dall'evento DataReceived, ed avvia un thread con una sub bloccata su un ciclo continuo che esegue continuamente la lettura della seriale.
Ho implementato anche io questo sistema, e ho trovato molti vantaggi:
- ho potuto eliminare alcune sub e alcune istruzioni che servivano a svuotare il buffer
- ho ridotto notevolmente alcuni tempi che mi servivano all'avvio del software per riconoscere se l'interfaccia collegata era quella giusta o meno
- il timeout lo posso gestire direttamente usando la proprietà apposita dell'oggetto serialport
- l'aggiornamento dei dati mi sembra anche piu veloce, ma questa potrebbe essere solo una mia impressione.
Nonostante tutto questo, a random, l'interfaccia si blocca ugualmente nel senso che la porta seriale va in timeout (non ho piu ricezione di dati) e si impasta (nel senso che è presente nel pannello di controllo ma non è possibile eseguirci operazioni).
Arrivati a questo punto, ho realizzato un firmware demo per arduino in cui il conteggio dei pezzi viene incrementato via software svincolandomi dal segnale rilevato sul pin. In pratica nella routine che scrive sulla porta seriale, richiamo la funzione per incrementare il numero di pezzi (funzione normalmente "attaccata" all'interrupt generato al cambio di stato sul pin che conteggia i pezzi). E cosa accade? Funziona tutto perfettamente da giorni, H24.
A questo punto, mi sono detto, il problema può stare soltanto nel firmware su Arduino.
Controllando e rileggendo sul sito di Arduino, mi sono accorto che, usando variabili che possono essere modificate sia negli interrupt che nel main, queste devono essere dichiarate con la parola chiave "volatile" (arduino.cc/en/reference/volatile), cosa che io *NON* ho fatto, perchè abituato coi pic, questo problema non l'ho mai avuto, e già la gestione degli interrupt con il wiring è un po diversa.
Farò quindi quest'altra prova, anche se mi pare strano che per via di questo la seriale possa impastarsi al punto di non essere più riconosciuta lato PC / andare in timeout. Spero con tutto il cuore che il problema sia soltanto questo perchè ve lo giuro, sto impazzendo.
Sono tutti bravi ad essere "open" con il "source" degli altri.
Un amico è colui che ti dice sempre quando stai sbagliando. Il mio miglior amico è il parser.
SettoreZero
Si prega Accedi o Crea un account a partecipare alla conversazione.
9 Anni 7 Mesi fa - 9 Anni 7 Mesi fa #13
da Mauro Laurenti
Rendering Error in layout Message/Item: array_keys(): Argument #1 ($array) must be of type array, null given. Please enable debug mode for more information.
Risposta da Mauro Laurenti al topic Arduino e ricezione seriale
Rendering Error in layout Message/Item: array_keys(): Argument #1 ($array) must be of type array, null given. Please enable debug mode for more information.
Si prega Accedi o Crea un account a partecipare alla conversazione.
9 Anni 7 Mesi fa #14
da Gianni
Sono tutti bravi ad essere "open" con il "source" degli altri.
Un amico è colui che ti dice sempre quando stai sbagliando. Il mio miglior amico è il parser.
SettoreZero
Risposta da Gianni al topic Arduino e ricezione seriale
Ciao Mauro.
Credo che il problema non sia sulla routine di lettura seriale sul PC.
Il codice che mi hai postato tu è uguale a quello che usavo prima: evento datareceived => delegato che richiama una sub, è il metodo classico. Poi ho utilizzato il sistema suggerito da Marcello (avviare un thread, in cui c'è una sub che esegue un ciclo continuo, leggendo di continuo la seriale) e ho avuto dei miglioramenti nel senso che posso gestire il timeout sulla seriale e ho potuto snellire parti del mio codice.
In aggiunta il codice scritto cosi, col thread a parte con un ciclo continuo, ha continuato a ricevere i dati anche in casi estremi di "programma che non risponde", sai quel difetto che a volte fanno i programmi, senza motivo, che si incantano... oggi me l'ha fatto, dopo 5 minuti di attesa si è sbloccato tutto e nel frattempo non ho avuto problemi sulla seriale, quindi è un metodo valido.
Per quanto riguarda il codice lato PC quindi per me è tutto ok.
Per il codice lato scheda... ho fatto tutto quello che andava fatto:
Ho dapprima dichiarato volatile tutte le variabili che dovevano esserlo (quelle utilizzate sia nelle ISR che in altre funzioni), e ho corretto alcuni tipi (avevo dichiarato alcune variabili come unsigned char, ma il char è solo signed, il valore unsigned a 8 bit si chiama byte... errori stupidi ma che non penso c'entrino nulla... comunque li ho corretti).
Nonostante questo... dopo qualche tempo la seriale è andata in timeout lo stesso.
Ho quindi fatto un'altra modifica: dato che sulla seriale inviavo dei dati che prendevo man mano da variabili (richiamavo piu volte la funzione serial.print passandole variabili da stampare), ho costruito una stringa nella quale ho infilato tutti i dati, dopodichè ho passato la stringa alla seriale, in maniera da richiamare la funzione serial.print una volta sola e con una stringa già fatta, senza prendere i dati da variabili.
Stessa cosa: dopo un po'... timeout
Ho fatto l'ultima modifica possibile, drastica: disattivare gli interrupt prima di inviare i dati alla seriale, dopo averli inviati, riattivo gli interrupt. Drastica perchè il conteggio dei pezzi avviene sull'interrupt al fronte di discesa di un pin digitale. Pensavo che disattivare gli interrupt mi avrebbe fatto perdere il conteggio di alcuni pezzi... invece non è successo, probabilmente perchè la cosa è talmente rapida che non influisce (il segnale massimo del contapezzi è 33Hz, quindi ho 15 ms di tempo per fare tutto). Funziona tutto ugualmente ma.... dopo un po' timeout.
e con "dopo un po'" posso intendere sia giorni e giorni 24h su 24 che pochi secondi: la cosa è troppo, troppo variabile e non legata a nessun evento particolare!
A questo punto, lato firmware per me è tutto corretto: le variabili sono volatile, mi costruisco una stringa completa con dentro tutte le variabili in maniera da passare la stringa alla serial.print che richiamo quindi una volta sola, disattivo gli interrupt prima dell'utilizzo della seriale per riattivarli subito dopo... non vedo quali altri problemi possano esserci.
A questo punto passo a descrivere com'è fatta la scheda:
c'è un arduino leonardo (olimexino 32U4) con su uno shield con fotoaccoppiatori: prendo un segnale contapezzi da un macchinario.
l'altro giorno che ho fatto? ho programmato un arduino con lo stesso firmware, e ci ho collegato un altro arduino che mi simula il funzionamento del macchinario: mi produce un'onda quadra per simulare il pezzo che passa (circa 33Hz), dopo un po' si ferma, dopo un po riparte con una velocità più bassa (tipo 8Hz per simulare un rallentamento del macchinario ecc.) risultato: la simulazione non si sta bloccando mai, mentre sul macchinario reale ogni tanto, a random, si blocca. e ho notato che quando si blocca... se stacco la porta usb e la riattacco per far riconoscere nuovamente la porta com... funziona per pochi secondi per poi bloccarsi sempre piu spesso e rapidamente....
Se apro la scatola, stacco i fili, li riattacco ecc.... poi funziona per più tempo (qualche giorno)... dopo qualche giorno va in timeout e una volta che ci va.. di nuovo lo fa sempre piu spesso, fino a che non smanetto di nuovo. Quindi arrivati a questo punto posso pensare si tratti di un problema hardware: falsi contatti o cose simili....
Ho escluso cali di tensione: l'alimentazione la prendo dalla porta usb del pc e l'assorbimento totale è intorno agli 80mA (c'è soltanto un display lcd), i fotoaccoppiatori per evitare interferenze li alimento con un alimentatore a parte. Sui cavi usb ho messo filtri in ferrite, il circuito è contenuto in una scatola metallica messa a terra, tra lo shield e la scheda ho messo un foglio isolante per evitare che i fili (la scheda sopra è fatta col wire wrap) possano toccare la scheda sotto.
Ma il punto è: la seriale USB è embedded... se ci fosse pure qualche falso contatto sullo shield, che si collega soltanto a 4 ingressi digitali.. cosa cavolo può interferire con la comuncazione usb, al punto di impallarla e non fare piu inviare dati???
Ragà io sto impazzendo ve lo giuro!! Questa cosa mi sta togliendo la salute!!!
Credo che il problema non sia sulla routine di lettura seriale sul PC.
Il codice che mi hai postato tu è uguale a quello che usavo prima: evento datareceived => delegato che richiama una sub, è il metodo classico. Poi ho utilizzato il sistema suggerito da Marcello (avviare un thread, in cui c'è una sub che esegue un ciclo continuo, leggendo di continuo la seriale) e ho avuto dei miglioramenti nel senso che posso gestire il timeout sulla seriale e ho potuto snellire parti del mio codice.
In aggiunta il codice scritto cosi, col thread a parte con un ciclo continuo, ha continuato a ricevere i dati anche in casi estremi di "programma che non risponde", sai quel difetto che a volte fanno i programmi, senza motivo, che si incantano... oggi me l'ha fatto, dopo 5 minuti di attesa si è sbloccato tutto e nel frattempo non ho avuto problemi sulla seriale, quindi è un metodo valido.
Per quanto riguarda il codice lato PC quindi per me è tutto ok.
Per il codice lato scheda... ho fatto tutto quello che andava fatto:
Ho dapprima dichiarato volatile tutte le variabili che dovevano esserlo (quelle utilizzate sia nelle ISR che in altre funzioni), e ho corretto alcuni tipi (avevo dichiarato alcune variabili come unsigned char, ma il char è solo signed, il valore unsigned a 8 bit si chiama byte... errori stupidi ma che non penso c'entrino nulla... comunque li ho corretti).
Nonostante questo... dopo qualche tempo la seriale è andata in timeout lo stesso.
Ho quindi fatto un'altra modifica: dato che sulla seriale inviavo dei dati che prendevo man mano da variabili (richiamavo piu volte la funzione serial.print passandole variabili da stampare), ho costruito una stringa nella quale ho infilato tutti i dati, dopodichè ho passato la stringa alla seriale, in maniera da richiamare la funzione serial.print una volta sola e con una stringa già fatta, senza prendere i dati da variabili.
Stessa cosa: dopo un po'... timeout
Ho fatto l'ultima modifica possibile, drastica: disattivare gli interrupt prima di inviare i dati alla seriale, dopo averli inviati, riattivo gli interrupt. Drastica perchè il conteggio dei pezzi avviene sull'interrupt al fronte di discesa di un pin digitale. Pensavo che disattivare gli interrupt mi avrebbe fatto perdere il conteggio di alcuni pezzi... invece non è successo, probabilmente perchè la cosa è talmente rapida che non influisce (il segnale massimo del contapezzi è 33Hz, quindi ho 15 ms di tempo per fare tutto). Funziona tutto ugualmente ma.... dopo un po' timeout.
e con "dopo un po'" posso intendere sia giorni e giorni 24h su 24 che pochi secondi: la cosa è troppo, troppo variabile e non legata a nessun evento particolare!
A questo punto, lato firmware per me è tutto corretto: le variabili sono volatile, mi costruisco una stringa completa con dentro tutte le variabili in maniera da passare la stringa alla serial.print che richiamo quindi una volta sola, disattivo gli interrupt prima dell'utilizzo della seriale per riattivarli subito dopo... non vedo quali altri problemi possano esserci.
A questo punto passo a descrivere com'è fatta la scheda:
c'è un arduino leonardo (olimexino 32U4) con su uno shield con fotoaccoppiatori: prendo un segnale contapezzi da un macchinario.
l'altro giorno che ho fatto? ho programmato un arduino con lo stesso firmware, e ci ho collegato un altro arduino che mi simula il funzionamento del macchinario: mi produce un'onda quadra per simulare il pezzo che passa (circa 33Hz), dopo un po' si ferma, dopo un po riparte con una velocità più bassa (tipo 8Hz per simulare un rallentamento del macchinario ecc.) risultato: la simulazione non si sta bloccando mai, mentre sul macchinario reale ogni tanto, a random, si blocca. e ho notato che quando si blocca... se stacco la porta usb e la riattacco per far riconoscere nuovamente la porta com... funziona per pochi secondi per poi bloccarsi sempre piu spesso e rapidamente....
Se apro la scatola, stacco i fili, li riattacco ecc.... poi funziona per più tempo (qualche giorno)... dopo qualche giorno va in timeout e una volta che ci va.. di nuovo lo fa sempre piu spesso, fino a che non smanetto di nuovo. Quindi arrivati a questo punto posso pensare si tratti di un problema hardware: falsi contatti o cose simili....
Ho escluso cali di tensione: l'alimentazione la prendo dalla porta usb del pc e l'assorbimento totale è intorno agli 80mA (c'è soltanto un display lcd), i fotoaccoppiatori per evitare interferenze li alimento con un alimentatore a parte. Sui cavi usb ho messo filtri in ferrite, il circuito è contenuto in una scatola metallica messa a terra, tra lo shield e la scheda ho messo un foglio isolante per evitare che i fili (la scheda sopra è fatta col wire wrap) possano toccare la scheda sotto.
Ma il punto è: la seriale USB è embedded... se ci fosse pure qualche falso contatto sullo shield, che si collega soltanto a 4 ingressi digitali.. cosa cavolo può interferire con la comuncazione usb, al punto di impallarla e non fare piu inviare dati???
Ragà io sto impazzendo ve lo giuro!! Questa cosa mi sta togliendo la salute!!!
Sono tutti bravi ad essere "open" con il "source" degli altri.
Un amico è colui che ti dice sempre quando stai sbagliando. Il mio miglior amico è il parser.
SettoreZero
Si prega Accedi o Crea un account a partecipare alla conversazione.
9 Anni 7 Mesi fa #15
da Video Lab
Volere è Potere
Risposta da Video Lab al topic Arduino e ricezione seriale
Ciao Gianni !!
Riesci a postare qualche foto ? Ho bisogno di vedere per poter pensare.
Anche perchè se a livello soft è tutto ok e quindi rimane un problema hardware è meglio vedere.
Hai modo di poter tenere sotto controllo con un oscilloscopio il sengnale in uscita dalla macchina industriale ?
Puoi visualizzare sul display della scheda il numero di pezzi contati ? così da poter capire se la parte contapezzi continua a funzionare nonostante la parte seriale si sia piantata.
Riesci a postare qualche foto ? Ho bisogno di vedere per poter pensare.
Anche perchè se a livello soft è tutto ok e quindi rimane un problema hardware è meglio vedere.
Hai modo di poter tenere sotto controllo con un oscilloscopio il sengnale in uscita dalla macchina industriale ?
Puoi visualizzare sul display della scheda il numero di pezzi contati ? così da poter capire se la parte contapezzi continua a funzionare nonostante la parte seriale si sia piantata.
Volere è Potere
Si prega Accedi o Crea un account a partecipare alla conversazione.
Moderatori: Mauro Laurenti, Pinna, StefA, Matteo Garia
Registrati al sito
Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.
Login
© LaurTec 2006 - 2024