Arduino e ricezione seriale
- Gianni
-
Autore della discussione
- Elit Utente
-
Less
Di più
10 Anni 2 Settimane fa #1
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
Arduino e ricezione seriale è stato creato da Gianni
Salve,
mi scuso se è da un po che non mi faccio sentire, ma tra famiglia e cercare di mantenermi un lavoro ormai non ho piu tempo per nulla. Sto sviluppando un progetto con Arduino Leonardo (in particolare sto usando un Olimexino 32U4, con la batteria tampone) e Visual Basic.Net (framework 3.5). L'Arduino funziona come una sorta di contapezzi, e mi invia una stringa su due porte seriali (quella USB funzionante come CDC, che il Leonardo ce l'ha come nativa, e quella seriale sui pin 1/0 utilizzando un adattatore). La stringa me la invia su due porte seriali perchè il dato mi va ad alimentare due programmi diversi.
La porta seriale "nativa" (quella su USB) mi alimenta il programma in visualbasic.net. Accade che ogni tanto, quasi a Random, visual basic non riceva più dati sulla porta seriale (arduino li invia in continuo). Il programma su Arduino non si blocca, perchè sull'altra porta seriale continua ad inviarli, c'è un display che viene aggiornato costantemente e un led che lampeggia su interrupt ad 1secondo, e tutto questo funziona... solo la porta USB... dopo qualche tempo sembra avere qualche problema: non invia piu dati, nel pannello di controllo è presente, ma non si riesce piu a chiuderla ne a riapririla (visual basic fornisce un'eccezione del tipo: un dispositivo collegato non è in funzione). L'unico sistema per farla riprendere è staccarla, aspettare un po e ricollegarla.
Non ho la minima idea se è un problema di Arduino Leonardo, della scheda Olimexino 32U4 in questione, o del programma in visual basic che sta facendo un utilizzo scorretto della porta. Lato Visual Basic utilizzo questo codice per ricevere i dati sulla seriale
Spiego:
la variabile "InterfaceAlive" la incremento in un timer che scatta ogni secondo: è per fare in modo che, se quel counter arriva ad un certo numero, dato che viene azzerato su ricezione seriale, mi considera l'interfaccia disconnessa.
Il flag "ClosingInProgress" mi viene impostato su true sull'evento formclosing, ho aggiunto questa cosa perchè a volte ricevevo un errore sulla chiusura del form causato dalla sub di ricezione dati.
Quello che arriva sulla seriale lo memorizzo nella variabile rxBuffer e lo processo, per mostrarlo e farci elaborazioni, nella sub SerialDataProcessing. Questa funzione mi setta un flag, FlagSerialDataProcessing, che controllo per evitare di impastarmi i dati man mano che arrivano se non ho finito di processarli.
Ho aggiunto i vari metodi DiscardInBuffer perchè ho notato che se non lo facevo, arduino mi rallentava (esempio: il contatore pezzi sul display non si aggiornava piu in tempo reale ma molto lento).
Sapete se Arduino Leonardo ha qualche problema con la porta USB (A parte che ci ho messo un po a capire che dovevo abilitare anche le linee RTS/DTS per poterlo utilizzare)? o è VisualBasic ad averne?
In aggiunta ho notato che un solo form richiamato dal form principale e aperto col metodo ShowDialog, fino a quando era presente, mi bloccava la ricezione su seriale, per cui ho dovuto visualizzarlo con Show anzichè con ShowDialog (altri form invece non mi danno problemi). Questa cosa non è anomala?
E' possibile che uno standby prolungato del pc possa bloccare la ricezione? Ma nelle impostazioni di standby c'è solo lo screen saver, hard disk e porte USB rimangono attive.
mi scuso se è da un po che non mi faccio sentire, ma tra famiglia e cercare di mantenermi un lavoro ormai non ho piu tempo per nulla. Sto sviluppando un progetto con Arduino Leonardo (in particolare sto usando un Olimexino 32U4, con la batteria tampone) e Visual Basic.Net (framework 3.5). L'Arduino funziona come una sorta di contapezzi, e mi invia una stringa su due porte seriali (quella USB funzionante come CDC, che il Leonardo ce l'ha come nativa, e quella seriale sui pin 1/0 utilizzando un adattatore). La stringa me la invia su due porte seriali perchè il dato mi va ad alimentare due programmi diversi.
La porta seriale "nativa" (quella su USB) mi alimenta il programma in visualbasic.net. Accade che ogni tanto, quasi a Random, visual basic non riceva più dati sulla porta seriale (arduino li invia in continuo). Il programma su Arduino non si blocca, perchè sull'altra porta seriale continua ad inviarli, c'è un display che viene aggiornato costantemente e un led che lampeggia su interrupt ad 1secondo, e tutto questo funziona... solo la porta USB... dopo qualche tempo sembra avere qualche problema: non invia piu dati, nel pannello di controllo è presente, ma non si riesce piu a chiuderla ne a riapririla (visual basic fornisce un'eccezione del tipo: un dispositivo collegato non è in funzione). L'unico sistema per farla riprendere è staccarla, aspettare un po e ricollegarla.
Non ho la minima idea se è un problema di Arduino Leonardo, della scheda Olimexino 32U4 in questione, o del programma in visual basic che sta facendo un utilizzo scorretto della porta. Lato Visual Basic utilizzo questo codice per ricevere i dati sulla seriale
Code:
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
' se il form non si sta chiudendo, allora mi leggo i dati da seriale
InterfaceAlive = 0 ' l'interfaccia sta ricevendo dati, azzero il timer di inattività
If (Not ClosingInProgress) Then
If (Not FlagSerialDataProcessing) Then
Try
rxBuffer = SerialPort1.ReadLine
Catch ex As Exception
rxBuffer = ""
LogErrore("Errore di ricezione sulla porta seriale", "SerialPort1_DataReceived", ex.ToString)
End Try
' invoco il processore dei dati ricevuti da seriale
Me.Invoke(New MethodInvoker(AddressOf SerialDataProcessing))
Else
' la funzione di processaggio è occupata, svuoto il buffer di ricezione
Try
SerialPort1.DiscardInBuffer()
Catch ex As Exception
End Try
End If
Else ' il form si sta chiudendo
Try
SerialPort1.DiscardInBuffer()
Catch ex As Exception
End Try
End If
End Sub
Spiego:
la variabile "InterfaceAlive" la incremento in un timer che scatta ogni secondo: è per fare in modo che, se quel counter arriva ad un certo numero, dato che viene azzerato su ricezione seriale, mi considera l'interfaccia disconnessa.
Il flag "ClosingInProgress" mi viene impostato su true sull'evento formclosing, ho aggiunto questa cosa perchè a volte ricevevo un errore sulla chiusura del form causato dalla sub di ricezione dati.
Quello che arriva sulla seriale lo memorizzo nella variabile rxBuffer e lo processo, per mostrarlo e farci elaborazioni, nella sub SerialDataProcessing. Questa funzione mi setta un flag, FlagSerialDataProcessing, che controllo per evitare di impastarmi i dati man mano che arrivano se non ho finito di processarli.
Ho aggiunto i vari metodi DiscardInBuffer perchè ho notato che se non lo facevo, arduino mi rallentava (esempio: il contatore pezzi sul display non si aggiornava piu in tempo reale ma molto lento).
Sapete se Arduino Leonardo ha qualche problema con la porta USB (A parte che ci ho messo un po a capire che dovevo abilitare anche le linee RTS/DTS per poterlo utilizzare)? o è VisualBasic ad averne?
In aggiunta ho notato che un solo form richiamato dal form principale e aperto col metodo ShowDialog, fino a quando era presente, mi bloccava la ricezione su seriale, per cui ho dovuto visualizzarlo con Show anzichè con ShowDialog (altri form invece non mi danno problemi). Questa cosa non è anomala?
E' possibile che uno standby prolungato del pc possa bloccare la ricezione? Ma nelle impostazioni di standby c'è solo lo screen saver, hard disk e porte USB rimangono attive.
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 Accesso o Crea un account a partecipare alla conversazione.
10 Anni 2 Settimane fa #2
da Mauro Laurenti
Risposta da Mauro Laurenti al topic Arduino e ricezione seriale
Ciao Gianni!
personalmente non ho usato la scheda per cui non posso dirti se i driver sono stabili.
In ogni modo potresti visualizzare i dati con un terminal e vedere se il problema si presenta.
Se non si presenta il problema potrebbe essere il programma scritto ma se si presenta potrebbe significare che il problema sia nel driver.
Personalmente, nell'applicazione RS232 Terminal, gestisco la ricezione dei dati in maniera diversa.
In primo luogo leggo ogni singolo byte non facendo affidamento a SerialPort1.ReadLine visto che il NewLine potrebbe anche non essere presente (nel caso generico supportato da RS232 Terminal).
Se memoria non mi inganna avevo delegato la gestione dei dati ad un secondo thread, per superare alcune difficolta' multithread, ma dovrei vedere il codice che ora non ho sotto mano.
...sono fuori casa per qualche altro giorno.
Saluti,
Mauro
personalmente non ho usato la scheda per cui non posso dirti se i driver sono stabili.
In ogni modo potresti visualizzare i dati con un terminal e vedere se il problema si presenta.
Se non si presenta il problema potrebbe essere il programma scritto ma se si presenta potrebbe significare che il problema sia nel driver.
Personalmente, nell'applicazione RS232 Terminal, gestisco la ricezione dei dati in maniera diversa.
In primo luogo leggo ogni singolo byte non facendo affidamento a SerialPort1.ReadLine visto che il NewLine potrebbe anche non essere presente (nel caso generico supportato da RS232 Terminal).
Se memoria non mi inganna avevo delegato la gestione dei dati ad un secondo thread, per superare alcune difficolta' multithread, ma dovrei vedere il codice che ora non ho sotto mano.
...sono fuori casa per qualche altro giorno.
Saluti,
Mauro
Si prega Accesso o Crea un account a partecipare alla conversazione.
10 Anni 2 Settimane fa #3
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
Uso il ReadLine perchè la stringa che invio ha i ritorni a capo e mi risulta più semplice concettualmente separare i vari dati. Poi per quanto riguarda la questione del thread separato, credo sia una cosa d'obbligo dal momento che dalla sub di ricezione non si possono modificare controlli (viene sollevata un'eccezione), difatti metto la stringa ricevuta dalla seriale in una variabile e poi invoco un'altra sub tramite un delegato:
Adesso non ho idea se questo sistema esegue la sub (SerialDataProcessing) su un thread separato o meno, ma credo di no.
Code:
Me.Invoke(New MethodInvoker(AddressOf SerialDataProcessing))
Adesso non ho idea se questo sistema esegue la sub (SerialDataProcessing) su un thread separato o meno, ma credo di no.
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 Accesso o Crea un account a partecipare alla conversazione.
- Pinna
-
- Moderatore
-
Less
Di più
- Messaggi: 1010
- Ringraziamenti ricevuti 107
10 Anni 2 Settimane fa #4
da Pinna
Chi vola vale, chi vale vola, chi non vola è un vile
Risposta da Pinna al topic Arduino e ricezione seriale
Ciao Gianni (che piacere risentirti)... 
per quel poco che so, e tu me lo insegni
, se non hai dichiarato quella routine come un thread esterno tu starai sempre all'interno del thread principale... questo vincola non poco per cui seguirei il consiglio di Mauro. Nel progetto del pilotaggio per 8 servi ho dovuto creare un thread esterno per inviare in sequenza e ciclicamente otto segnali che mi tenessero bloccati i servi nella loro posizione, altrimenti mi si bloccava tutto, si impallava la gui ed ottenevo una marea di errori in ricezione seriale. In pratica, mi si impallava anche il pc, per cui dovevo resettarlo e iniziare da capo (neanche utilizzando il task manager riuscivo ad interromperlo...
Marcello
p.s. spero di esserti stato un pochino di aiuto

per quel poco che so, e tu me lo insegni

Marcello
p.s. spero di esserti stato un pochino di aiuto

Chi vola vale, chi vale vola, chi non vola è un vile
Si prega Accesso o Crea un account a partecipare alla conversazione.
10 Anni 2 Settimane fa #5
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
uhmmm allora... il sistema che ho usato li sopra... a quanto pare non esegue il processo su un thread separato.
In Droid Controller invece usavo un altro sistema sull'evento datareceived:
Facevo invocare una funzione da un delegato da un controllo qualsiasi... Ma anche questo penso non venga eseguito su un thread separato.
Voi generate proprio un nuovo thread o utilizzate un background worker?
In Droid Controller invece usavo un altro sistema sull'evento datareceived:
Code:
txtPWML.Invoke(New myDelegate(AddressOf RefreshAnalogGauges), New Object() {})
Facevo invocare una funzione da un delegato da un controllo qualsiasi... Ma anche questo penso non venga eseguito su un thread separato.
Voi generate proprio un nuovo thread o utilizzate un background worker?
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 Accesso 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.
Forum - Ultimi messaggi
-
- progetto can
- da Mauro Laurenti
-
- MODULO GSM SIM900A
- da Mauro Laurenti
-
- Freedom III e compilazioni fallite
- da Mauro Laurenti
-
- Gestione degli errori su comunicazione seriale
- da Mauro Laurenti
-
- Timer0 e interrupt
- da Mauro Laurenti