Interfacciare Arduino con Visual Basic

In questo tutorial vedremo come è possibile interfacciare Arduino con Visual Basic utilizzando la comunicazione seriale attraverso la porta usb.

E’ possibile stabilire questo genere di comunicazione in tutte le versioni di Visual Basic, dalla mitica versione 6 alle più recenti versioni .net; i componenti da utilizzare sono sempre gli stessi per tutte le versioni, a parte eventuali piccole differenze di sintassi o di nomi dei metodi da invocare.

Visual Basic 2008 express. In questo tutorial vedremo un esempio di comunicazione seriale tra Arduino Uno ed un piccolo programmino scritto in Visual Basic 2008 express. La scelta di utilizzare questa versione di Visual Basic nasce da alcuni vantaggi che essa offre:

  • è una versione abbastanza avanzata ed evoluta, ma contemporaneamente molto snella;
  • è gratuita, scaricabile dal sito Microsoft, e non richiede particolari licenze d’uso;
  • richiede il framework 3.5 che è già presente in Windows 7 e successivi e che non è eccessivamente pesante se installato in pc più vecchi o con Windows xp (il framework 4.0 è un po’ più pesante e potrebbe creare rallentamenti nel caso di utilizzo in pc con processori più lenti o con meno Ram);
  • rispetto al vb6 (immagino gli amanti di vb6 desiderosi di non abbandonare questa versione) non presenta un inconveniente di cui parleremo tra poco che renderebbe poco fruibile il programma.

Funzionamento. Iniziamo subito col dire che qualunque versione di Visual Basic decidiamo di utilizzare, il principio di funzionamento della comunicazione tra Arduino e Visual Basic sarà sempre lo stesso: si innescherà la comunicazione seriale tra i due sistemi. Visual Basic invierà ad Arduino una richiesta e Arduino risponderà di conseguenza.

Comandi e interrogazioni. Solo per una questione di semplicità e chiarezza, e per fissare meglio le idee, distingueremo in questo tutorial due generi di richieste: comandi e interrogazioni.

Un comando sarà la richiesta di effettuare qualcosa, ad esempio settare un pin o eseguire una procedura presente nello sketch di Arduino.

L’interrogazione sarà la richiesta di avere restituito in risposta da Arduino una stringa, che può contenere ad esempio il valore di una o più variabili, oppure lo stato di un sensore.

E’ sempre bene comunque prevedere, anche nel caso di comandi, una risposta da parte di Arduino, che può essere di semplice conferma se il comando è stato eseguito correttamente oppure un codice di errore nel caso qualcosa non sia andato per il verso giusto.

Carattere contro Stringa. Fatta questa premessa è necessario fare un’ulteriore precisazione prima di passare a vedere concretamente dei semplici esempi per realizzare quello di cui stiamo parlando: Arduino in generale riesce a leggere dalla seriale un carattere alla volta (diciamo un byte alla volta), però è in grado di scrivere sulla seriale diversi byte tutti insieme (ad esempio una stringa intera anche abbastanza lunga).

Dal lato suo, Visual Basic è in grado di scrivere e di leggere dalla seriale stringhe intere senza grossi problemi, quindi per mettere d’accordo le esigenze di entrambi procederemo così: Visual Basic invierà la propria richiesta scrivendo un byte sulla seriale (convenendo una certa codifica, ad esempio ‘T’ significa ‘restituiscimi il valore della temperatura‘, oppure ‘R’ significa ‘fai scattare il relè‘ oppure ‘3’ significa ‘cambia lo stato del pin 3‘, ecc…) e riceverà da Arduino una stringa che potrà contenere la conferma di avvenuta esecuzione di un comando oppure la risposta all’interrogazione fatta.

Pronti? Via! Dato che esistono diversi sensori, ciascuno con le proprie sintassi e configurazioni, partiamo da un esempio molto semplice che non richiede alcuna componente aggiuntiva.

Come per ogni “Hello World” che si rispetti, scriviamo un programma in Visual Basic che possa fare accendere e spegnere il led del pin 13 di Arduino e che possa anche interrogarlo sullo stato attuale del pin.

In Arduino. Dopo avere scelto il pin e settato le variabili di rito, nel loop il metodo Serial.available() ci dice se ci sono byte in arrivo sulla seriale.

In questo esempio stiamo convenendo che un punto interrogativo ‘?’ deve dire ad Arduino di leggere lo stato del pin e restituirlo.

Una ‘A’ deve fare accendere il pin, una ‘S’ deve farlo spegnere, una ‘C’ deve cambiarne lo stato. In ogni caso deve poi fornire una risposta di conferma che conveniamo debba finire con un punto e virgola.

In ogni caso deve poi fornire una risposta di conferma che conveniamo debba finire con un punto e virgola.

#define OFF LOW //spento
#define ON HIGH // acceso
#define PinLed 13 //pin da comandare
char* Risp; // risposta di Arduino
byte data; // carattere ricevuto

void setup() {
 pinMode(PinLed,OUTPUT);
 Serial.begin(9600);
}

void loop() {
 if(Serial.available()>0) //se arriva un byte dal pc
 {
   Risp="?;";
   data = Serial.read(); // leggo dalla seriale
 
   if (data=='?'){
     if (digitalRead(PinLed)==ON) Risp="ON;";
     else Risp="OFF;";
   }
 
   if (data=='A'){ // accendi il led
     digitalWrite(PinLed,ON);
     Risp="ON;";
   }
 
   if (data=='S'){ // spegni il led
     digitalWrite(PinLed,OFF);
     Risp="OFF;";
   } 
 
   if (data=='C'){ // cambia lo stato del led
     if (digitalRead(PinLed)==ON)
       {
       digitalWrite(PinLed,OFF);
       Risp="OFF;";
       }
   else 
      {
       digitalWrite(PinLed,ON);
       Risp="ON;";
      }
   }
 
   if (data=='T'){
      // in base al vostro sensore di temperatura
      // scrivete il codice opportuno
      //leggi la temperatura dal sensore e poi
     Risp="Temperatura...;";
   }

   //altri if e poi...
  
   Serial.write(Risp); // restituiamo la risposta

  } // if serial.available
} // loop

Per chi volesse fare un piccolo passo in più, conveniamo di leggere il valore della Temperatura dall’apposito sensore e restituirlo quando sulla seriale perviene una richiesta tramite il byte ‘T’.

Visual Basic. In un nuovo progetto Visual Basic, inseriamo nel Form principale (che chiameremo Desktop) un oggetto picture in cui alterneremo una qualunque coppia di immagini OnOff (su Google Immagini se ne trovano un milione).

Le immagini le salveremo nella stessa cartella dove verrà creato l’eseguibile con nomi on.jpgoff.jpg; i più ardimentosi potranno inserire un secondo oggetto picture con l’immagine di un termometro.

Poi ci serve una Label in cui visualizzare i messaggi di ritorno di Arduino.

Esempio di applicazione visual Basic

Inseriamo nel progetto un oggetto SerialPort e conveniamo di associarlo alla Com7. Nel Form_Load dobbiamo settare le variabili e, nel caso la porta Com7 non fosse disponibile, diamo la possibilità all’utente di rettificare la scelta di default grazie all’intercettazione dell’errore 57.

Private Sub Desktop_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  On Error GoTo Errore
  With SerialPort
     .PortName = "COM7" ' oppure altra porta 
     .Open()
     Me.Text = "Serial 2008 Arduino - " & .PortName
  End With
  Dim OnOff As String
  OnOff = Invia("?")
  Img.Load(Application.StartupPath & "/" & OnOff & ".jpg")
  Label1.Text = OnOff
  Exit Sub
Errore:
  If Err.Number = 57 Then
    Dim Porta As String
    Porta = "" & InputBox(Err.Description & " Inserisci nome porta", , "COM7")
    If Porta <> "" Then
       SerialPort.PortName = Porta
       Resume
    End If
  End If
  MsgBox("[" & Err.Number & "] " & Err.Description)
End Sub

La funzione Invia prende come parametro una Stringa, ovvero il carattere da inviare ad Arduino tramite la scrittura sulla seriale.

Gestisce l’eventuale verificarsi di errori e restituisce una stringa che è la risposta di Arduino. Questa viene letta dalla seriale fino a che non arriva il punto e virgola che decreta la fine della trasmissione.

Nel Form_Load viene subito interrogato Arduino sullo stato attuale del pin, e viene visualizzata l’immagine on.jpg oppure off.jpg.

Private Function Invia(ByVal Carattere As String) As String
  If Carattere = "" Then
     Return ""
  End If
  Dim Risultato As String = ""
  Dim c As String = ""
  SerialPort.DiscardInBuffer()
  SerialPort.DiscardOutBuffer()
  Try
   SerialPort.Write(Carattere)
  Catch ex As Exception
   Return "Errore [" & Err.Number & "] " & Err.Description
  End Try

  While True
    While SerialPort.BytesToRead > 0
      c = Chr(SerialPort.ReadChar)
      If c = ";" Then
        Return Risultato
      Else
        Risultato = Risultato & c.ToString
      End If
    End While
  End While
  Return ""
End Function

Ora è facile associare al click dell’immagine l’invio di una “C” che faccia cambiare lo stato del pin e visualizzi la nuova jpg.

Private Sub Img_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Img.Click
  Dim OnOff As String
  OnOff = Invia("C")
  Label1.Text = OnOff
  Img.Load(Application.StartupPath & "" & OnOff & ".jpg")
End Sub

Analogamente, possiamo associare al click dell’immagine del termometro l’invio del carattere “T” e la visualizzazione della risposta sulla Label1

Private Sub Temperatura_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Temperatura.Click
  Label1.Text = Invia("T")
End Sub

Prendendo spunto da questi semplici comandi possiamo adesso arricchire il progetto di nuovi invii di caratteri avendo cura di creare apposite procedure nella corrispondente controparte in Arduino.

Un’ultima raccomandazione. Allo stato attuale, l’invio di un comando non riconosciuto da Arduino comporta la restituzione della stringa “?;” che verrà percepita da Visual Basic come una risposta che contiene un punto interrogativo.

Non dimentichiamo il punto e virgola finale quando Arduino invia una risposta a Visual Basic, altrimenti quest’ultimo riceve la risposta ma rimane in attesa del punto e virgola rischiando di bloccare la porta seriale in un loop infinito.

Agli amanti di vb6. Come promesso, mi rimane un ultimo debito da saldare nei confronti degli amanti di vb6.

Lo stesso progettino si può realizzare anche in vb6, anzi, vi confesso che anche io la prima volta l’ho scritto in vb6 per sbrigarmi presto.

Succede però un inconveniente: ogni volta che si lancia il programma in vb6 e viene stabilita la connessione seriale, Arduino si resetta. Ricarica il setup e poi regolarmente esegue il suo loop.

In questa maniera, se ad esempio abbiamo lasciato uno o più pin settati in un certo modo, non appena apriamo il vb6 si ritorna allo stato iniziale di setup.

Questo non è accettabile se il sistema deve mantenere la sua vita e la sua configurazione con continuità nel tempo.

In Visual Basic 2008 questo non succede.

Si può accendere un led, settare dei pin e uscire dal programma, quando si riapre il programma Arduino continua il suo lavoro.

La comunicazione seriale si comporta in maniera assolutamente trasparente e indolore, al contrario del vb6.

13 commenti su “Interfacciare Arduino con Visual Basic”

  1. Ciao Michele,
    complimenti per il sito.
    Mi chiamo Maurizio e sono un progettista elettronico , che come tutti ormai oltre all’HW devo avere anche conoscenze SW.
    Devo sviluppare un programma in Visual Basic che si interfaccia con arduino e altro HW.

    Io utilizzo il 2010 express , volevo chiederti se un programma sviluppato in questo ambiente gira bene su tutti i sistemi operativi e su altri PC , dato che io ho un pc in azienda con caricato XP .

    Mi ricordo che caricando un programma .exe su un altro pc , e’ comparso un messaggio di errore che diceva di installare una patch di microsoft ecc,. e poi ha funzionato bene.
    In pratica e’ necessario che su quel PC su cui si copia l’applicazione che ho sviluppato si installi anche VISUAL BASIC 2010 EXPRESS per non avere problemi ?
    Scusa se mi dilungo , mi e’ anche successo che durante le trasmissioni dati , ogni tanto mi comparisse un’eccezione di errore che blocca la comunicazione e bisogna resettare il programma.
    C’e’ un sistema per bypassare le eccezioni ?

    Grazie se mi puoi rispondere
    Ciao e complimenti ancora

    Rispondi
    • Ciao Maurizio, grazie per i complimenti e per l’avere apprezzato il mio lavoro. Io ho lavorato sia con vb2008 express che VB 2010 pro. Ti dico subito che in entrambi i casi non basta l’exe, ma serve almeno il framework .net, fino alla versione vb 2008 bastava il framework 3.5, mentre per le versioni successive serve il framework 4.0 o addirittura il 4.5 a volte, che sono un po pesanti specie per una macchina XP.
      Il framework potrebbe in generale bastare, ma converrebbe sempre accoppiare un pacchettino di installazione di una generica applicazione. Ad esempio io ho creato un form con sopra tutti gli oggetti standard di VB (listbox, combo, griglie, label, ecc…) e poi il pacchetto di installazione, così quando devo installare i miei programmi installo framework e pacchetto per avere le librerie e poi mi copio liberamente miei file exe.
      Non so se mi sono spiegato bene.
      Scrivimi quando vuoi, io di solito posso rispondere la sera. Grazie ancora.
      Con framework e pacchetto non hai bisogno di installare VB express sui pc.

      Rispondi
  2. Ciao Michele,
    complimenti per il tutorial.
    Al fine di dare all’utente la possibilità di impostare un parametro dello sketch di arduino (nel mio caso un numero di telefono) ho la necessità di costruire una interfaccia tramite PC (tipo un programma realizzato in Visual Basic).
    Potresti indicarmi come procedere ?
    Grazie !

    Rispondi
  3. Ciao Michele,
    complimenti per il tutorial.
    Al fine di dare all’utente la possibilità di impostare un parametro dello sketch di arduino (nel mio caso un numero di telefono) ho la necessità di costruire una interfaccia tramite PC (tipo un programma realizzato in Visual Basic).
    Potresti indicarmi come procedere ?
    Grazie !

    Rispondi
  4. Ciao Gianluca, grazie per il tuo apprezzamento. Non ho capito bene cosa ti serve esattamente: il numero di telefono lo scrive l’utente nell’interfaccia vb e questo deve essere comunicato ad Arduino, oppure al contrario il numero di telefono lo sa Arduino e lo deve trasmettere al visual basic? E a che scopo lo scambio del numero di telefono (tanto per capire meglio che soluzioni possono essere appropriate).

    Rispondi
  5. Ciao Gianluca, grazie per il tuo apprezzamento. Non ho capito bene cosa ti serve esattamente: il numero di telefono lo scrive l’utente nell’interfaccia vb e questo deve essere comunicato ad Arduino, oppure al contrario il numero di telefono lo sa Arduino e lo deve trasmettere al visual basic? E a che scopo lo scambio del numero di telefono (tanto per capire meglio che soluzioni possono essere appropriate).

    Rispondi
  6. Il problema del reset dell’arduino dovrebbe derivare dai settaggi di base della porta seriale, che evidentemente nel VB6 lasciano alto il pin (RTS CTS non ricordo di preciso) che viene usato per resettare arduino, di solito per avviare il bootloader. Dunque probabilmente basta impostare l’oggetto COM di VB6 in modo da lasciare sempre spenti (o accesi a secondo il funzionamento del reset di arduino) quei pin opzionali della seriale. Altrimenti si può anche lasciare collegati alla scheda arduino solo i due pin TX ed RX. In questo modo “fisicamente” non può avvenire il reset ad ogni nuova connessione della seriale. Però la soluzione software è comunque facile e pratica.
    Il povero e mitico VB6, ancora una volta, NON C’ENTRA NIENTE!.

    Rispondi
  7. Buongiorno Michele, Sono alle prime armi sia di visual studio che di Arduino.
    Ho cominciato ad appassionarmi ad Arduino da qualche tempo usandolo per i soliti giochi di luci.
    Ho trovato il tuo tutorial molto interessante, è proprio quello che cercavo,
    infatti adesso sto provando a lavorare ad un progetto un po’ più ambizioso.
    vorrei eventualmente poterti chiedere aiuto.
    intanto grazie per avermi dato degli spunti con il tuo tutorial.

    Rispondi
  8. Buongiorno Michele, Sono alle prime armi sia di visual studio che di Arduino.
    Ho cominciato ad appassionarmi ad Arduino da qualche tempo usandolo per i soliti giochi di luci.
    Ho trovato il tuo tutorial molto interessante, è proprio quello che cercavo,
    infatti adesso sto provando a lavorare ad un progetto un po’ più ambizioso.
    vorrei eventualmente poterti chiedere aiuto.
    intanto grazie per avermi dato degli spunti con il tuo tutorial.

    Rispondi
  9. Ciao Michele, scusa ho visto la tua risposta solo ora (pensavo che avrei ricevuto una avviso tramite mail). Il numero di telefono deve impostarlo l’utente e deve essere utilizzato dallo sketch per inviare un sms.
    Ti sarei grato se potessi darmi qualche dritta !

    Rispondi
  10. Ciao Michele, scusa ho visto la tua risposta solo ora (pensavo che avrei ricevuto una avviso tramite mail). Il numero di telefono deve impostarlo l’utente e deve essere utilizzato dallo sketch per inviare un sms.
    Ti sarei grato se potessi darmi qualche dritta !

    Rispondi
  11. Buongiorno Michele,
    ho letto il tuo articolo riguardo: Interfacciare Arduino con Visual Basic, con molto interesse in quanto
    mi diverto a realizzare, per hobby, piccoli progetti con Arduino e Visual basic 6.0. Passare ai successivi VB, non me la sento in verità. Ho letto che lo stesso progetto lo hai realizzato in VB6, potesti gentilmente inviarmelo?
    Te ne sarei molto grato. Ti auguro buon lavoro.
    Luciano

    Rispondi

Lascia un commento