Go Down

Topic: arduino e visual studio (Read 1 time) previous topic - next topic

nid69ita

#15
May 03, 2019, 09:06 am Last Edit: May 03, 2019, 09:08 am by nid69ita
Non ho capito bene il discorso della readline nell'evento dataReceived che ferma il programma in attesa?
Dovrei usare la readline fuori dall'evento datareceived ? il programma praticamente e' sempre in attesa di un evento esterno per rilevare lo stato dei rele.
No, per me è okay. In evento datareceived ci sei quando ci sono dati, quindi readline legge e basta.
Io trovo invece inutile l'uso del timer.
my name is IGOR, not AIGOR

torn24

L'istruzione che ti ho postato, prende tutta la stringa ricevuta meno l'ultimo carattere.
Code: [Select]
valore=valore.Substring(0,valore.Length-1)

Il problema era che avevi un carattere in più, ma visto che la readline() toglie il newline, non era questo il carattere in più   :)

docdoc

No, per me è okay. In evento datareceived ci sei quando ci sono dati, quindi readline legge e basta.
Eh ma anche no. :) La gestione ad eventi deve essere ad eventi, non puoi avere un evento che al primo byte ricevuto attende in modo sincrono che finisca la linea. O gestisci in modo sincrono le cose o in modo asincrono.

La ReadLine() la usi fuori dagli eventi, se usi l'evento devi accumulare in un buffer i caratteri ricevuti e processare quelli non appena riceve il separatore (sempre nell'evento DataReceived, per cui anche il timer non serve più).

Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

nid69ita

#18
May 03, 2019, 11:35 am Last Edit: May 03, 2019, 11:37 am by nid69ita
@docdoc   è un programmino in VB.  Hai un s.o. sotto il cofano. Secondo me non hai grossi problemi avendo su usb/seriale collegato l'Arduino. Ovviamente leggere 1 byte alla volta fino alla ricezione del cr/lf sarebbe meglio.
my name is IGOR, not AIGOR

docdoc

@docdoc   è un programmino in VB.  Hai un s.o. sotto il cofano. Secondo me non hai grossi problemi avendo su usb/seriale collegato l'Arduino.
Beh non parlavo di problemi, ma di logica di implementazione e di corretto uso della programmazione ad eventi: o sei procedurale o vai ad eventi, mischiare le due cose è sempre potenzialmente negativo o per il corretto funzionamento (se arresti l'esecuzione di un evento può dare problemi ad altre parti di codice) o quantomeno per il debugging.
Sai, con Arduino sono un hobbista, ma da decenni programmo in ambiente Windows, e se in azienda un programmatore mi facesse queste cose lo avrei cazziato allo stesso modo. ;)

Quote
Ovviamente leggere 1 byte alla volta fino alla ricezione del cr/lf sarebbe meglio.
Si, ovviamente. Ma dipende da cosa fa (deve fare) il programma oltre ad attendere il CRLF... ;) Se è sequenziale ossia procedurale, si usa ReadLine nella procedura e niente eventi DataReceived, se non lo è e si usano gli eventi allora vanno usati come Bill comanda :D
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

docdoc

#20
May 03, 2019, 01:22 pm Last Edit: May 03, 2019, 01:23 pm by docdoc
Il problema era che avevi un carattere in più, ma visto che la readline() toglie il newline, non era questo il carattere in più :)
E' perché in realtà la println() aggiunge DUE caratteri, CR e LF (o vbCr e vbLf, oppure char(13)+chr(10)) e se il LF viene tolto dalla ReadLine resta il CR...

Io risolverei genericamente con un semplice Replace, per sicurezza:

Code: [Select]
valore=valore.Replace(chr(13), "")

In ogni caso per me continua a non avere senso implementare dei protocolli (che servono a due programmi per dialogare) usando caratteri e stringhe "umane". Basta anche mandare "0" per "spento" e "1" per "acceso" ed evitare i separatori, quindi basta leggere UN byte senza tanti problemi:

Code: [Select]
Private Sub SerialPort1_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
  valore = SerialPort1.ReadChar
  If valore = "1" Then
    TextBox1.text = "acceso"
  Else
    TextBox1.text = "spento"
  End If
  picturebox1.visible = (valore = "1")
  doevents
End Sub
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

Federico66

Scusate se mi intrometto :-)

Eh ma anche no. :) La gestione ad eventi deve essere ad eventi, non puoi avere un evento che al primo byte ricevuto attende in modo sincrono che finisca la linea. O gestisci in modo sincrono le cose o in modo asincrono.
La ReadLine() la usi fuori dagli eventi, se usi l'evento devi accumulare in un buffer i caratteri ricevuti e processare quelli non appena riceve il separatore (sempre nell'evento DataReceived, per cui anche il timer non serve più).
Mi trovi perfettamente d'accordo, inoltre, nello caso specifico (poca esperienza), opterei per gestire il tutto con un Timer che legge il contenuto della seriale tramite ReadExisting e sulla base di quello trova agisce di conseguenza.

Premesso che da Arduino venga inviato:
Code: [Select]

  Serial.println("acceso");


allora in VB potrebbe essere qualcosa del genere, se le immagini sono su file:
Code: [Select]

  Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    Dim Incoming As String = SerialPort1.ReadExisting()
    If Not String.IsNullOrEmpty(Incoming) Then
      If Incoming.StartsWith("acceso") Then
        TextBox1.text = "acceso"
        pictureBox1.Image = New Bitmap("acceso.png")
      Else
        TextBox1.text = "spento"
        pictureBox1.Image = New Bitmap("spento.png")
      End If
    End If
  End Sub

E' molto elementare, ma così evita gli eventuali cr lf (non ricordo se ReadExisting li elimina :) )
Naturalmente andrebbe gestito almeno l'eventuale timeout/scollegamento della seriale

F.

"La logica vi porterà da A a B. L'immaginazione vi porterà dappertutto." A. Einstein

nid69ita

In ogni caso per me continua a non avere senso implementare dei protocolli (che servono a due programmi per dialogare) usando caratteri e stringhe "umane". Basta anche mandare "0" per "spento" e "1" per "acceso" ed evitare i separatori, quindi basta leggere UN byte senza tanti problemi:
Quoto in toto.
my name is IGOR, not AIGOR

Federico66

In ogni caso per me continua a non avere senso implementare dei protocolli (che servono a due programmi per dialogare) usando caratteri e stringhe "umane". Basta anche mandare "0" per "spento" e "1" per "acceso" ed evitare i separatori, quindi basta leggere UN byte senza tanti problemi:
Daccordissimo :-)
"La logica vi porterà da A a B. L'immaginazione vi porterà dappertutto." A. Einstein

docdoc

E' molto elementare, ma così evita gli eventuali cr lf (non ricordo se ReadExisting li elimina :) )
Non credo. ReadLine si, ma ReadExisting legge tutti i caratteri presenti nel buffer, inclusi CR e LF.
In ogni caso per me l'OP (visto anche che non mi sembra abbia molta esperienza) fa prima a mandare "0" o "1" e basta, niente println() ma solo print() di un singolo carattere, quindi eviti anche .StartsWith()...

Quote
Naturalmente andrebbe gestito almeno l'eventuale timeout/scollegamento della seriale
Eh, certo, qui però entriamo in questioni più complesse visto anche che non hai Hardware Handshake con Arduino, quindi bisognerebbe implementare handshake o qualche heartbeat, cose che per ora risparmierei all'OP... ;)
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

Federico66

Eh, certo, qui però entriamo in questioni più complesse visto anche che non hai Hardware Handshake con Arduino, quindi bisognerebbe implementare handshake o qualche heartbeat, cose che per ora risparmierei all'OP... ;)
Non sapevo, ho poca esperienza con Arduino, buono a sapersi.
Grazie
"La logica vi porterà da A a B. L'immaginazione vi porterà dappertutto." A. Einstein

zoomx

E' perché in realtà la println() aggiunge DUE caratteri, CR e LF (o vbCr e vbLf, oppure char(13)+chr(10)) e se il LF viene tolto dalla ReadLine resta il CR...
Stiamo parlando di VB e Windows, se la readline toglie i caratteri in più alla fine credo proprio che li tolga entrambi. Ma devo controllare.

docdoc

#27
May 03, 2019, 04:15 pm Last Edit: May 03, 2019, 04:17 pm by docdoc
Stiamo parlando di VB e Windows, se la readline toglie i caratteri in più alla fine credo proprio che li tolga entrambi. Ma devo controllare.
Ecco, si, controlla... ;)

Quote
SerialPort.ReadLine Method
Spazio dei nomi:
System.IO.Ports
Assemblies:
System.dll, System.IO.Ports.dll
Legge fino al valore di NewLine nel buffer di input.

public string ReadLine ();
Restituisce
String
Contenuto del buffer di input fino alla prima occorrenza di un valore di NewLine.
Ed il NewLine:

Quote
Valore della proprietà
Valore che rappresenta la fine di una riga. Il valore predefinito è un avanzamento riga, NewLine.

Questa proprietà determina quale valore (byte) definisce la fine di una riga per il ReadLine e WriteLine metodi. Per impostazione predefinita è il valore end-of-line NewLine.
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

zoomx

Ho controllato
https://docs.microsoft.com/it-it/dotnet/api/system.environment.newline?view=netframework-4.8
Quote
NewLine può essere usato in combinazione con il supporto di nuova riga specifiche del linguaggio, ad esempio i caratteri di escape '\r' e '\n' in Microsoft c# e C/C++, o vbCrLf in Microsoft Visual Basic.
In altre parole in VB il NewLine è la combinazione di CR+LF ma, credo, solo sotto Windows perché, appunto, fa riferimento ad Environment.Newline, mentre sotto Linux/Unix (con Mono o altri compilatori) dovrebbe essere il solo LF ma anche qui dovrei controllare.


Era così anche nel Visual Basic che precedeva il NET solo che li era sempre la combinazione dei 2 caratteri e non dipendeva dall'ambiente.


Federico66

#29
May 03, 2019, 04:32 pm Last Edit: May 03, 2019, 04:39 pm by Federico66
In altre parole in VB il NewLine è la combinazione di CR+LF ma, credo, solo sotto Windows perché, appunto, fa riferimento ad Environment.Newline, mentre sotto Linux/Unix (con Mono o altri compilatori) dovrebbe essere il solo LF ma anche qui dovrei controllare.
Da quello che leggo, in realtà è configurabile, quindi puoi decidere cosa considerare NewLine nella trasmissione seriale.

UPDATE
Cioè per assurdo puoi fare una cosa del genere:
Code: [Select]

'Da Arduino
'Serial.print("ciaoPIPPO");

'Da Net
SerialPort1.NewLine = "PIPPO"
SerialPort1.ReadLine() '-> Ritorna Ciao


Interessante :-)

F
"La logica vi porterà da A a B. L'immaginazione vi porterà dappertutto." A. Einstein

Go Up