arduino e visual studio

Un saluto a tutti ,mi chiamo Stefano e mi sono da poco iscritto a questo forum perché appassionato di elettronica.
Ho da poco iniziato con arduino e il relativo interfacciamento con visual studio per comandare varie apparecchiature.
Premetto che sono un neofita del settore , mi arrangio come posso,ho qualche esperienza di elettronica e di software ma su quest' ultimo un po' meno.
Avrei un problemino da risolvere e chiedo a voi esperti se mi potete dare qualche dritta ?
In caso posso postare se qualcuno e' interessato ad aiutarmi le righe di codice.

Ho gia realizzato un software (per ora molto semplificato) che tramite l'interfaccia grafica di visual studio e arduino comando dei rele' e ricevo i vari stati da essi, fin qui tutto ok.
Su visual studio accendo il rele col pulsante (normale ,passo passo ,ecc) e ricevo il feedfack di ritorno e dentro una casella mi scrivo se il rele' e' acceso e spento (classico programmino che si trova anche su internet).
Il problema nasce nel rilevare questo stato di "acceso e spento" per comandare una casella "picturebox"
per disegnare la lampadina accesa o viceversa.

Dentro una textbox scrivo "acceso" o "spento" proveniente da arduino sulla seriale ma la condizione
if valore="acceso" then non viene rilevata come nelle istruzioni normali.
Devo fare in modo da rilevare (in visual studio) queste due condizioni per poter gestire le caselle "picturebox"

magari questo problema e' gia stato affrontato?

saluti

Buonasera,
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il su citato REGOLAMENTO ... Grazie. :slight_smile:

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione, nessuno ti potrà rispondere, quindi ti consiglio di farla al più presto. :wink:

stefanotransam:
Dentro una textbox scrivo “acceso” o “spento” proveniente da arduino sulla seriale ma la condizione
if valore=“acceso” then non viene rilevata come nelle istruzioni normali.
Devo fare in modo da rilevare (in visual studio) queste due condizioni per poter gestire le caselle “picturebox”

Dopo la presentazione, spiega meglio questa parte. Mi pare hai problema in VS, ma a me non è chiaro che problema hai. Poi… visual studio dice poco. Programmi in VB o C# ??

Ciao,ho effettuato la presentazione stamattina,spero di aver fatto tutto in modo corretto.
Innanzitutto grazie per l interessamento.
Ho scaricato visual studio 2018 e creato un form in vb con i relativi pulsanti (botton) per eccitare dei rele.
Ho anche creato una textbox dove viene rilevato per ogni rele lo stato (viene scritto nella textbox se il rele e' eccitato o no,in questo caso ho scritto acceso e spento)
Fin qui tutto ok funziona bene
Il tutto e' collegato ad arduino dove ho programmato i pin in entrata e uscita ,settato la porta,e aggiunto le relative istruzioni.
Il problema nasce che devo aggiungere l immagine di una lampadina ,accesa e spenta a secondo del rele eccitato e questa immagine e' contenuta in una istruzione picturebox .
La cosa piu semplice penso e' usare un istruzione "if" che rileva la scritta acceso e spento nella textbox ma viene ignorata.??

Posta almeno il pezzo di codice che dici viene ignorata.
soprattutto dobbiamo capire la frase
if valore="acceso" then non viene rilevata

 Private Sub SerialPort1_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
      valore = SerialPort1.ReadLine
      

  End Sub


  Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
      TextBox1.Text = valore

      questo dalla parte di vb  mentre dalla parte di arduino :



val=digitalRead(8);

if (val==HIGH)
{
Serial.println("acceso");

}
else
{
Serial.println("spento");
}




  End Sub

Questa e' la parte di codice e funziona tutto.
il problema e' rilevare la scritta acceso o spento nella textbox di vb,
in condizioni "normali" uso un if ecc ecc ma leggendola nella text box non va ,per esempio:
io scriverei : if valore ="acceso" then pictorebox.visible=true ma viene ignorata e non fa nulla
??

In primis:
In conformità al suddetto regolamento, punto 7, edita (in basso a destra del post, bottone More → Modify) il tuo post e racchiudi il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone fatto così: </>, tutto a sinistra). Grazie.
Infatti vedi che appare una faccina nel codice !!

valore è una variabile globale As String ?
Dici che hai provato con un if … ma dove lo hai messo ? se non dai info …
Comunque non capisco perchè la scrittura nel textbox lo fai in un timer.
Hai già l’evento sulla seriale quando ricevi dati. Fai tutto li.

Private Sub SerialPort1_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
  valore = SerialPort1.ReadLine
  TextBox1.text = Valore
  if valore = "acceso" then
    picturebox1.visible=true
  else
    picturebox1.visible=false
  end if
  doevents
End Sub

Inoltre prova ad aggiungere un doevents

valore e’ una variabile ‘as string’
attribuisce a quello che legge sulla seriale il nome ‘valore’
per il resto e’ quello che ho fatto io ma la condizione if non la vede,e’ come se non legge la parola ‘acceso’

arduino rileva se lo stato logico del piedino di ingresso e’ alto o basso ,lo salva nella variabile ‘val’ e lo scrive tramite il comando 'Serial.Println (“acceso”) sul monitor seriale.
da parte di vb lo legge sulla serialport1.readline e me lo scrive nella textbox.
e qui funziona tutto,qualsiasi azionamento che faccio si eccita il rele e si porta a livello logico il piedino di arduino (5v o massa tramite un resistenza da 10k) per avere un riferimento veritiero.

in altre occasioni ho gia usato la condizione if /then ,ma in questo caso sembra non leggerla.

il timer continua a controllare lo stato della seriale,per ora i rele sono uno o due ma poi li moltiplico a 20,30 (arduino mega ecc,per ora uso arduino uno per gli esperimenti)

Le righe if then , non ci sono perché le ho cancellate vedendo che il programma non funzionava.

Mi sorge un dubbio! Non so se sia il vero problema. che è molto comune inviando comandi sotto forma di stringa da seriale con arduino.
Nel tuo programma in VB, fai una readline, questo fa supporre che nella stringa inviata ci sia il terminatore di riga il newline.
Da ducumentazione non riesco a capire se serialport.readline TOGLIE O NO IL NEWLINE
Quando confronti la stringa ricevuta da arduino con la costante stringa nel programma, potrebbero risultare diverse perché in quella ricevuta da arduino è presente un carattere non visibile di newline, mentre nella costante non c'è.

Potrebbe essere che l'istruzione if faccia qualcosa del genere IF "accendi\n"= "accendi" THEN.
Per cui risulta falsa.

Magari se controlli la lunghezza della stringa con apposita funzione, ti indicherà un carattere in più.

Come potresti risolvere?? Adesso conosco un po C# ma non Vb.net, quindi dovrai vedere come si fa in
vb.

1)Ricevo la stringa da seriale che contiene il newline
2)Prelevo una sottostringa da inizio stringa a posizione del newline
3)Adesso ho il comando senza newline e nell' IF dovrebbe fare il confronto in modo corretto.

Non conosco VB.net ma dovrebbe essere SIMILE a questo

valore=valore.Substring(0,valore.Length-1)

IF valore="accendi" THEN

Se non sbaglio il comando .readline dovrebbe gia togliere quel carattere in piu che si aggiunge alla stringa ma faro delle prove .

In effetti ho letto che readline, dovrebbe togliere il newline.
Sta di fatto che è quasi certo, che se il confronto tra le due stringhe è falso vuol dire che le due stringhe non sono uguali :confused:

torn24:
In effetti ho letto che readline, dovrebbe togliere il newline.
Sta di fatto che è quasi certo, che se il confronto tra le due stringhe è falso vuol dire che le due stringhe non sono uguali :confused:

Per cui basterebbe mettere un punto di interruzione in Visual Studio in quel punto e vedere i valori delle stringhe.

stefanotransam:
Questa e' la parte di codice e funziona tutto.
il problema e' rilevare la scritta acceso o spento nella textbox di vb,
in condizioni "normali" uso un if ecc ecc ma leggendola nella text box non va ,per esempio:
io scriverei : if valore ="acceso" then pictorebox.visible=true ma viene ignorata e non fa nulla

Allora, intanto per prima cosa modifica subito il tuo post per racchiudere nel tag "code" come ti è stato già chiesto.

Detto questo, tu fai:

 Private Sub SerialPort1_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived

        valore = SerialPort1.ReadLine

    End Sub

Ok, quindi nell'evento DataReceived registri nella variabile "valore" quello che leggi dalla seriale. Ma prima di tutto la variabile "valore" dove l'hai definita? E' globale, si? Diciamo di si.

Poi nell'evento (ossia se ci sono dati ricevuti nel buffer) tu fai ReadLine, ma non è così che si gestisce la cosa, mai usare ReadLine in eventi come DataReceived: la DataReceived ti informa che ci sono dei dati ricevuti dallo stream e messi nel buffer, mentre la ReadLine è sincrona ossia ferma il programma fino a che non riceve un vbLF (che non include nel valore di ritorno) dallo stesso stream!

O usi la ReadLine in una parte di codice che non sia questo (ad esempio in una while quando premi un pulsante, o in un timer, ma non in un evento seriale), oppure nella DataReceive leggi i caratteri ricevuti accumulandoli in una variabile dalla quale poi vai a cercare il vbLF estraendo tu i caratteri ricevuti fino a quel separatore.

In ogni caso tu poi con un timer metti nella textbox il valore:

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        TextBox1.Text = valore

e questo va anche bene, ma poi non hai mostrato il codice con i tuoi "If": se non funziona è perché le stringhe che confronti sono diverse, tu metti un breakpoint sulla "If" e vedi cosa contiene esattamente la variabile.

Per finire:

  Serial.println("acceso");

La Serial.println() aggiunge vbCRLF alla stringa, quindi la coppia CR e LF...

Ipotizzando che "valore" sia una variabile globale di tipo "String" e che tutti i caratteri inviati da Arduino siano arrivati puoi verificare il contenuto di "valore" anche nel seguente modo:

If valore.Contains("Acceso") then
 .
 .
 .  
End If

Ti togli così il dubbio di cosa possa esserci al termine della stringa.

Ho messo il tag code (non so se ho fatto giusto) ,ho provato ad aggiungere l'struzione dettatami da (torn24) e funziona, ora riconosce la stringa acceso e spento memorizzata nella variabile (valore ),evidentemente come avete detto non erano uguali.

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.

stefanotransam:
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.

L'istruzione che ti ho postato, prende tutta la stringa ricevuta meno l'ultimo carattere.

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ù :slight_smile:

nid69ita:
No, per me è okay. In evento datareceived ci sei quando ci sono dati, quindi readline legge e basta.

Eh ma anche no. :slight_smile: 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ù).

@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.

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.

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. :wink:

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... :wink: 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 :smiley: