Lettura dati seriale con Visual Basic

Buonasera a tutti.

In seguito a diverse prove, sono qui a chiedervi un'aiuto in merito all'estrapolazione di dati ricevuti via seriali al pc.
In pratica, dispongo di un sensore di colore, che attraverso l'elaborazione di arduino, riesce a inviarmi via seriale i tre valori rgb dell'oggetto posto difronte al sensore proprio così come di seguito:

R: 255
G:255
B:255

In sintesi, i valori RGB dell'oggetto posto difronte al sensore, vengono inviati ciascuno su una riga differente.

Come potrei riuscire ad assegnare ognuno di questi valori una variabile così da poterli gestire in visual basic 2010?

Grazie mille in anticipo.

Come al solito, è meglio agire con progressività.
Lascia stare i TRE dati.
Dimmi se UN dato riesci a leggerlo da VB. Fatto questo, il resto sarà semplicissimo.

Buonasera.
In realtà ci stavo guardando, però non sono riuscito a capire granchè in rete.
Ti posto qui di seguito il codice che ho scritto fin ora...
Praticamente avvio un timer con intervallo = 1000 ms. Mi scrive "A" sulla seriale precedentemente settata e aperta.
Aspetta 1000 ms, tempo nel quale di aspetta di ricevere da arduino i valori di RGB facenti riferimento alla richiesta inviata con il carattere "A".
L'unica cosa è che non ho proprio idea di come andare a prelevare l'integer dopo i caratteri "R,G e B" e assegnarlo a una variabile.
Avresti qualche suggerimento per aiutarmi?

Grazie mille.

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

            SerialPort1.Write("A")
            SerialPort1.ReadTimeout = 1000
            data = SerialPort1.ReadExisting()
           
           'dovrei leggere dopo la R e associare il valore a una red1'
           'dovrei leggere dopo la G e associare il valore a green1'
           'dovrei leggere dopo la B e associare il valore a blue1'
          

            PictureBox1.BackColor = Color.FromArgb(red_slot_1, green_slot_1, blue_slot_1)

End Sub

Quindi sono TRE invii, uno per R, uno per G ed uno per B.
Visto che il formato è sempre X:numero, dove X: può essere R:, G:, B:, potresti leggere tre stringhe e su ciascuna splittare al terzo carattere, poi fai da stringa a numero sulla seconda parte. Puoi usare la prima parte per sicurezza per sapere se stai leggendo R, G, B.
Il timeout 1000 ms lo toglierei... puoi anche modificare il timer a 100 ms se ti serve una maggiore fluidità nell'aggiornamento dei valori.

Ecco quello che sono riuscito ad ottenere fin ora.
Però mi sembra che manchi qualcosa.

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        If slot1_flag = 1 And SerialPort1 IsNot Nothing Then

            SerialPort1.Write("A")
            SerialPort1.ReadTimeout = 1000
            data = SerialPort1.ReadLine()

            If InStr(1, data, "R", CompareMethod.Binary) = 1 Then

                red_slot_1 = Microsoft.VisualBasic.Right(data, 3)

            ElseIf InStr(1, data, "G", CompareMethod.Binary) = 1 Then

                green_slot_1 = Microsoft.VisualBasic.Right(data, 3)

            ElseIf InStr(1, data, "B", CompareMethod.Binary) = 1 Then

                blue_slot_1 = Microsoft.VisualBasic.Right(data, 3)

            End If

Ho lasciato il timeout, perchè la procedura di lettura e scrittura in seriale dei valori ricavati dal sensore, prende circa 500 ms.
Non vorrei che il visual basic leggesse quando i valori non sono ancora arrivati.

Attualmente nel debug non ricevo nessun errore, però non so se le funzioni che uso per manipolare le stringhe sono adeguate.

E poi, hai qualche idea su come possa leggere ogni riga separatamente delle tre righe che mi arrivano in seriale?

Con la funzione "SerialPort1.ReadLine()" credo che riuscirei a leggere solo una riga e basta. Giusto?

Grazie mille.

In alternativa ho questa soluzione.

Secondo te può andare?

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        If slot1_flag = 1 And SerialPort1 IsNot Nothing Then

            SerialPort1.Write("A")
            SerialPort1.ReadTimeout = 1000
            data = SerialPort1.ReadExisting()

            data_array = Split(data, "/n")

            If InStr(1, data_array(0), "R", CompareMethod.Binary) = 1 Then

                red_slot_1 = Microsoft.VisualBasic.Right(data_array(0), 3)

            ElseIf InStr(1, data_array(1), "G", CompareMethod.Binary) = 1 Then

                green_slot_1 = Microsoft.VisualBasic.Right(data_array(1), 3)

            ElseIf InStr(1, data_array(2), "B", CompareMethod.Binary) = 1 Then

                blue_slot_1 = Microsoft.VisualBasic.Right(data_array(2), 3)

Grazie.

Puoi anche leggere una sola riga alla volta, come nel caso I.
Però devi dirgli di leggere TRE VOLTE, così legge le tre righe.
Oppure in alternativa ti scegli un fine dati, qui ipotizziamo che sia il carattere "E",
e trasmetti

R:230
G:122
B:255
E

Potresti avere difficoltà con cifre con meno di tre caratteri come
G:24
oppure
B:9

quindi anche nel primo caso ti conviene usare lo split mediante ":" e poi leggere il valore dei due pezzi, uno ti dice se stai leggendo R, G o B - e sarebbe anche inutile visto che li trasmetti in sequenza e già sai che il primo sarà R e così via - l'altro pezzo invece contiene il valore.

Infine... faresti bene a convertire da caratteri ad int

Grazie dei suggerimenti,

sto andando un pò a tentativi perchè non sono molto pratico di VB.

Ad ogni modo, credi che il seguente codice sia pertinente con quanto mi hai detto?

 Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        If slot1_flag = 1 And SerialPort1 IsNot Nothing Then

            SerialPort1.Write("A")
            SerialPort1.ReadTimeout = 1000

            For counter As Integer = 0 To 3

                data = SerialPort1.ReadLine()
                data_array = Split(data, ":", 2)

            Next

            data_array(0) = red_slot_1
            data_array(1) = green_slot_1
            data_array(2) = blue_slot_1


            Return

        Else

            Return

        End If

    End Sub

Grazie mille ancora.

0 to 3 ti legge 4 volte e credo che l'assegnazione fuori dal for sia fatta al contrario...
secondo me stai facendo più complicazioni del dovuto
mentre sei nel for potresti assegnare color(counter) dove hai
color(0) = valore R
color(1) = valore G
color(2) = valore B
ovviamente variabile globale
così all'uscita dal for ti ritrovi direttamente i tre valori già assegnati e poi ci fai quello che ti pare
Se vuoi semplificare ulteriormente, elimina quegli R: G: B: all'inizio delle righe, tanto sai già che riceverai tre valori che rappresentano R, G, B e ti risparmi lo split, ti basta convertire in int quello che leggi. In alternativa, puoi usare:
Val(stringa)
che ti restituisce solo la parte numerica quindi
Val("R:23") restituisce 23
Val("B:121") sarà 121
e così proseguendo.

          For counter As Integer = 0 To 2

                data = SerialPort1.ReadLine()
                color(counter) = Val(data)

            Next

Grazie mille!!!

Sei stato chiarissimo e sono riuscito nel mio intento.

Grazie ancora dei suggerimenti.

A presto.