Comunicazione Arduino Visual Basic express 2013

Buongiorno, essendo nuovo del mondo arduino ho cercato di imparare la programmazione di arduino. Volevo adesso far comunicare arduino con visul basic express 2013. Per quanto riguarda l'invio dei dati da VB a Arduino non ci sono problemi, anche perchè nelle ricerche effettuate ho trovato abbastanza roba. Il mio problema è l'opposto, cioè comunicare da arduino a VB. in internet ho trovato qualcosa ma non funziona come vorrei. Quando premo un pulsante ho un led che si accende, quindi invia sulla seriale la stringa "ACCESO", quando il led è spento invia sulla seriale "SPENTO". Il problema è quando ricevo le stringhe da arduino in VB in una listbox, la stringa mi viene spezzata a random. non capisco il perchè. Il codice che ho inserito in VB è il seguente, che sarebbe uguale a un codice trovato in un topic di questo forum.

Private Sub SP1_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)

        UpdateFormDelegate1 = New UpdateFormDelegate(AddressOf UpdateDisplay)

        Dim n As Integer = SP1.BytesToRead 'find number of bytes in buf 
        comBuffer = New Byte(n - 1) {} 're dimension storage buffer 
        SP1.Read(comBuffer, 0, n) 'read data from the buffer 
        Me.Invoke(UpdateFormDelegate1) 'call the delegate 

    End Sub

    Private Sub UpdateDisplay()
        ' ricevo bytes, se invio 'A' oppure 65, ricevo 65
        ' chr(65) -> "A"
        Dim sBuf As String = "", i As Integer
        For i = 0 To comBuffer.Length - 1
            sBuf = sBuf & Chr(comBuffer(i))
        Next
        ListBox1.Items.Add(sBuf)
    End Sub

Qualcuno sa darmi una mano? Grazie

Ti invitiamo a presentarti qui: http://forum.arduino.cc/index.php?topic=113640.0 e a leggere il regolamento: http://forum.arduino.cc/index.php?topic=149082.0 - qui una serie di schede by xxxPighi per i collegamenti elettronici vari: http://forum.arduino.cc/index.php?topic=146152.0 - qui le pinout delle varie schede by xxxPighi: http://forum.arduino.cc/index.php?topic=151646.0 - qui una serie di link utili: http://forum.arduino.cc/index.php?topic=126861.0

SP1 che oggetto è ? Posta anche il codice Arduino. Senza non si può dire granchè.

Qui mi pare Microsoft scriva l'handler con un'altra sintassi: http://msdn.microsoft.com/it-it/library/system.io.ports.serialport.datareceived(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1

Ho dimenticato di dire che, uso arduino 1. Le stringhe le ricevo correttamente sul monitor seriale, mentre su VB le ricevo tipo questo: SP ent o Acces o Ac ce so

Grazie

Ciao
il codice di arduino per le prove che sto facendo è:

int ledPin = 13;
int ledPin_1=3;
int statoInterruttore=0;
int primaStatoInterruttore=0;
char* myStrings[]={"Spento", "Acceso"};
void setup() {
 Serial.begin(9600); // set serial speed
 pinMode(ledPin, OUTPUT); // set LED as output
 pinMode(ledPin_1, OUTPUT); // set LED as output
 pinMode(2, INPUT);
 digitalWrite(ledPin, LOW); //turn off LED
 digitalWrite(ledPin_1, LOW); //turn off LED
}

void loop(){
 if (Serial.available() != 0){
 int val=Serial.read()-'0';
  if (val == 1) { // test for command 1 then turn on LED
  digitalWrite(ledPin, HIGH); // turn on LED
  }
   else if (val == 0){ // test for command 0 then turn off LED
   digitalWrite(ledPin, LOW); // turn off LED
   }
 } 
 statoInterruttore=digitalRead(2);
 if(primaStatoInterruttore != statoInterruttore){
  if(statoInterruttore == LOW){
    digitalWrite(ledPin_1, LOW);
    Serial.println(myStrings[0]);
   }
   else if(statoInterruttore == HIGH){
     digitalWrite(ledPin_1, HIGH);
     Serial.println(myStrings[1]);
     }   
     primaStatoInterruttore = statoInterruttore;
   } 
}

Posto anche tutto il codice di VB. SP1 è la porta di comunicazione

Imports System.IO.Ports 'Importa la libreria 

Public Class Form1
    Dim SP1 As New SerialPort
    Dim SP1open As Boolean
    Dim comBuffer As Byte()
    Private Delegate Sub UpdateFormDelegate()
    Private UpdateFormDelegate1 As UpdateFormDelegate

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim PortName As String
        Dim a() = System.IO.Ports.SerialPort.GetPortNames() ' Dichiarare un Array che si occupa della porte disponibili 
        SP1.Close()
        AddHandler SP1.DataReceived, AddressOf SP1_DataReceived
        For Each PortName In a ' un ciclo si occuperà di aggiungere le porte disponibili nella combobox 
            ComboBox1.Items.Add(PortName) ' Test l'ho scelto io a caso 
        Next
    End Sub

    Private Sub BtnSendB_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSendB.Click
        If SP1open Then SP1.Write("0")
    End Sub

    Private Sub BtnSendA_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSendA.Click
        If SP1open Then SP1.Write("1")
    End Sub

    Private Sub BtnOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpen.Click
        With SP1
            .BaudRate = 9600
            .DataBits = 8
            .PortName = ComboBox1.Text   '"COM1"
            .Parity = IO.Ports.Parity.None
            .StopBits = IO.Ports.StopBits.One
            .Handshake = IO.Ports.Handshake.None
            .Encoding = System.Text.Encoding.Default
        End With
        Try
            SP1.Open()
            SP1open = True
        Catch ex As Exception
            MessageBox.Show(ex.Message)
            SP1open = False
        End Try
        SP1.DiscardInBuffer()
    End Sub

    Private Sub BtnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
        SP1.Close()
        SP1open = False
    End Sub


    Private Sub SP1_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)

        UpdateFormDelegate1 = New UpdateFormDelegate(AddressOf UpdateDisplay)
        Dim n As Integer = SP1.BytesToRead 'find number of bytes in buf 
        comBuffer = New Byte(n - 1) {} 're dimension storage buffer 
        SP1.Read(comBuffer, 0, n) 'read data from the buffer 
        Me.Invoke(UpdateFormDelegate1) 'call the delegate 

    End Sub

    Private Sub UpdateDisplay()
        ' ricevo bytes, se invio 'A' oppure 65, ricevo 65
        ' chr(65) -> "A"
        Dim sBuf As String = "", i As Integer
        For i = 0 To comBuffer.Length - 1
            sBuf = sBuf & Chr(comBuffer(i))
        Next
        ListBox1.Items.Add(sBuf)
    End Sub

End Class

Grazie

Ciao nid69ita, ho visto il link che hai allegato, ma non ho avuto risultati. Sinceramente conosco poco del codice VB, sono alle prime armi, e la nuova sintassi non so come posso integrarla nel mio progetto, da principiante.

Guarda, io uso ancora VB6 perciò non conosco molto VB.Net, soprattutto la Seriale su Net. Noto però che nell'esempio di Microsoft usa ReadExisting() mentre tu usi SP1.Read() Prova a fare così:

Private Sub SP1_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
  UpdateFormDelegate1 = New UpdateFormDelegate(AddressOf UpdateDisplay)
  Dim indata As String = SP1.ReadExisting()
  Console.WriteLine("Data Received:")   ' solo per debug
  Console.Write(indata)                 ' solo per debug
  comBuffer = indata
  Me.Invoke(UpdateFormDelegate1) 'call the delegate 
End Sub

ciao, ho provato ma non è possibilee. La variabile indata è una as string mentre comBuffer è byte, quindi mi dà errore.

Fai diventare comBuffer di tipo String e nella UpdateFormDelegate1 usa direttamente comBuffer e non sBuf. In questo modo non devi più passare da un vettore/array di byte

ho provato a dichiarare Dim comBuffer As String e ho scritto il codice come segue:

Private Sub SP1_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)

        UpdateFormDelegate1 = New UpdateFormDelegate(AddressOf UpdateDisplay)
        Dim indata As String = SP1.ReadExisting()
        Console.WriteLine("Data Received:")   ' solo per debug
        Console.Write(indata)                 ' solo per debug
        comBuffer = indata
        Me.Invoke(UpdateFormDelegate1) 'call the delegate 

    End Sub

    Private Sub UpdateDisplay()
        ' ricevo bytes, se invio 'A' oppure 65, ricevo 65
        ' chr(65) -> "A"
        Dim sBuf As String = "", i As Integer
        For i = 0 To comBuffer.Length - 1
            sBuf = sBuf & Chr(AscW(comBuffer(i)))
        Next
        ListBox1.Items.Add(sBuf)

    End Sub

non ho errori, gira, ma ho sempre lo stesso problema, cioe: SP ent o Acces o Ac ce so

non capisco come fare a far capire a VB quanto è lunga la stringa che c'è nella seriale, oppure non so se arduino è lento a scrivere, quindi VB vede più stringhe.

adamo: Private Sub UpdateDisplay()        ' ricevo bytes, se invio 'A' oppure 65, ricevo 65        ' chr(65) -> "A"        Dim sBuf As String = "", i As Integer        For i = 0 To comBuffer.Length - 1            sBuf = sBuf & Chr(AscW(comBuffer(i)))        Next        ListBox1.Items.Add(sBuf)    End Sub

Ripeto, sBuf non serve più.

Private Sub UpdateDisplay()
        ListBox1.Items.Add(comBuffer)
    End Sub

si scusa avevo dimenticato di scriverlo. Ho provato in tutti e due i casi anche usando sBuf, ma il risultato è uguale.

non so se c'è un modo per far inviare una stringa da arduino con un carattere speciale. Quando VB legge questo carattere significa che la stringa è terminata.

Se qualcuno sa come si fa, credo che possa andare bene.

Grazie

Ma anche questo:

Console.WriteLine("Data Received:")   ' solo per debug
  Console.Write(indata)

Ti da i dati in malo modo su console?

Purtroppo si. In pratica tra il codice che avevo postato all'inizio e quest'ultimo codice, con le varie modifiche, non c'è differenza nel risultato. Ho sempre le stringhe slittate a caso. Tipo: SP ent o Acces o Ac ce so