Oppure

Loading
18/03 13:10
Carlo
Mi sembra che stai complicando la questione inutilmente.

parché non fai:
Serial.write(headingDegrees); ???

se mandi i gradi togli tutti gli if, sia in C che in VB e come risultato la bussola si orienta a passi di 1 grado invece che a passi di 45 gradi :pat:

Per identificare il dato ricevuto, ribadisco che puoi aggiungere un valore o carattere iniziale che ti faccia capire di cosa si tratta.

Per esempio nel codice C per i gradi:

char send [20]; // send può contenere 20 caratteri
sprintf(send, "1; %f", headingDegrees); // converti in stringa i gradi e aggiungi l'identificativo: 1; per i gradi
Serial.write(send);


se i gradi presenti in: headingDegrees erano per esempio 320.5, in VB riceverai: "1; 320.500000"

in VB per dividere i valori lo puoi fare con split:

Dim valoreRicevuto As String = "1; 320.500000" ' solo per provare
valoreRicevuto = valoreRicevuto.Replace(".", ",") ' se ci fosse il punto decimale viene sostituito con la virgola decimale
Dim valoriDivisi() As String ' matrice senza dimensione
valoriDivisi = valoreRicevuto.Split(";") ' il puntoevirgola separa le stringe: in valoriDivisi(0) ci va 1 e in valoriDivisi(1) ci va 320,500000
If valoriDivisi(0) = "1" Then
        ' Il dato è riferito ai gradi della bussola
        ' in valoriDivisi(1) i gradi ricevuti in formato stringa
        Dim gradi As Integer = CInt(valoriDivisi(1))
End If


e così via per tutto quello che invii sulla seriale.
Potresti anche preparare una stringa che contiene tutti i dati separati da ; e fare un unico invio... L'ordine stabilisce il tipo di dato!!! :k:
Ultima modifica effettuata da Carlo 18/03 14:46
in programmazione tutto è permesso
18/03 13:55
Thejuster
Postato originariamente da Carlo:

Mi sembra che stai complicando la questione inutilmente.

parché non fai:
Serial.write(headingDegrees); ???

se mandi i gradi togli tutti gli if, sia in C che in VB e come risultato la bussola si orienta a passi di 1 grado invece che a passi di 45 gradi :pat:

Per identificare il dato ricevuto, ribadisco che puoi aggiungere un valore o carattere iniziale che ti faccia capire di cosa si tratta.

Per esempio nel codice C per i gradi:

char send [20]; // send può contenere 20 caratteri
sprintf(send, "1; %f", headingDegrees); // converti in stringa i gradi e aggiungi l'identificativo: 1; per i gradi
Serial.write(send);


se i gradi presenti in: headingDegrees erano per esempio 320.5, in VB riceverai: "1; 320.500000"

in VB per dividere i valori lo puoi fare con split:

Dim valoreRicevuto As String = "1; 320.500000" ' solo per provare
Dim valoriDivisi() As String ' matrice senza dimensione
valoriDivisi = valoreRicevuto.Split(";") ' il puntoevirgola separa le stringe: in valoriDivisi(0) ci va 1 e in valoriDivisi(1) ci va 320
If valoriDivisi(0) = "1" Then ' se è 1 allora sono gradi
    ' Il dato è riferito ai gradi della bussola
    ' in valoriDivisi(1) i gradi ricevuti in formato stringa
End If


e così via per tutto quello che invii sulla seriale.
Potresti anche preparare una stringa che contiene tutti i dati separati da ; e fare un unico invio... L'ordine stabilisce il tipo di dato!!! :k:



Ma infatti la scorsa volta gli avevo mostrato il mio controllo che accettava direttamente valori in gradi.
così da raddrizzarsi in modo autonomo ed evitare tutte quelle inutili condizioni. :rotfl:

PS:
A Gratis intendevo che era gratis non che te lo faccio pagare :rotfl:
Scrissi, solitamente per controlli del genere li faccio sotto commissione ma qui è un eccezione.
Siamo su pierotofy. Al max, Closed Source ma gratis.

E cmq il consiglio di carlo è esatto.
In Diversi miei progetti ho utilizzato dei separatori di stringa quando arduino invia una o più istruzioni al programma.
Per velocizzare tutto, in una sola scrittura hai i dati separati che poi sta a te gestirli.
ad esempio:

Volume;StatoLed;Bussola;ValoreA;ValoreB ecc. ecc.

Quindi saprai che l'ordinazione dei valori è sempre quella.

Utilizzai questo sistema per creare un programma per calibrare dei carburatori (per un amico meccanico)
Utilizzando 4 sensori della bosh per ottenere valori, li inviavo aggiornando i dati sul computer e vari grafici.
Separando i valori proprio come dice carlo.

mire.forumfree.it/ - Mire Engine
C# UI Designer
18/03 18:01
nightwolf
Grazie mille, domani se riesco modifico lo sketch di arduino, il cod. Di visual basic cosi da far girare la bussola atraverso i gradi e non attraverso il nome della direzione.
Vediamo cosa salta fuori :rofl:
aaa
19/03 6:38
Carlo
Postato originariamente da nightwolf:

Grazie mille, domani se riesco modifico lo sketch di arduino, il cod. Di visual basic cosi da far girare la bussola atraverso i gradi e non attraverso il nome della direzione.
Vediamo cosa salta fuori :rofl:


Con i gradi che ti arrivano da arduino ciclicamente, non hai più bisogno di Timer1 che fa l'animazione, non hai neanche bisogno dell'evento Label1_TextChanged è sufficiente Timer2


Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
    Dim str As String
    str = RiceviDati()

    Dim valoriDivisi() As String ' matrice senza dimensione
    valoriDivisi = str.Split(";") ' il puntoevirgola separa le stringe: in valoriDivisi(0) ci va il codice identificativo (1 = gradi bussola, 2 = volume, ecc) e in valoriDivisi(1) ci va il valore relativo
    If valoriDivisi(0) = "1" Then
           ' Il dato è riferito ai gradi della bussola
            valoriDivisi(1) = valoriDivisi(1).Replace(".", ",") ' se ci fosse il punto decimale viene sostituito con la virgola decimale
            avanzamento = CInt(valoriDivisi(1))
            Label1.Text = avanzamento.ToString("000°")
            PictureBox1.Invalidate() ' scatena il paint
    End If

    If valoriDivisi(0) = "2" Then
           ' Il dato in: valoriDivisi(1), è riferito al volume
            ....
            ....
    End If
     
End Sub


Magari per l'identificativo invece di scegliere 1 per la bussola e 2 per il volume, puoi mettere B per la bussola e V per il volume...
Ultima modifica effettuata da Carlo 19/03 13:31
in programmazione tutto è permesso
19/03 17:45
nightwolf
grazie mille x l aiuto, adesso sulla seriale di arduino ho:
B 293.00
B 292.74
che sarebbero le coordinate del magnetometro, ma quando avvia vb.net mi da errore.
questo è tutto il codice del form

Imports System.IO.Ports
Imports System.Drawing.Drawing2D
Public Class principale
    Dim bussola As Image = New Bitmap("bussola.png") ' bmp in ram dal file originale, deve esistere nella cartelle dell'eseguibile
    Dim destinazione As Integer
    Dim avanzamento As Integer
    Dim direzione As Integer
    Dim cX As Integer = bussola.Width \ 2
    Dim cY As Integer = bussola.Height \ 2
    Dim dX As Integer = bussola.Width
    Dim dY As Integer = bussola.Height
    Dim vel As Integer = 2 ' velocità, valori supportati 1, 2, 3, 5, 6, 9, 10 (divisibili per 90)
    Private Sub principale_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.CenterToParent()
        btnconnetti.Enabled = False
        btnChiudi.Enabled = False
        cmbbaund.SelectedItem = "9600"
        media_pleyer.Timer5.Start()
    End Sub

    Private Sub btnscanport_Click(sender As Object, e As EventArgs) Handles btnscanport.Click
        cmbPorte.Items.Clear()
        Dim myPort As Array
        Dim i As Integer
        myPort = IO.Ports.SerialPort.GetPortNames
        cmbPorte.Items.AddRange(myPort)
        i = cmbPorte.Items.Count
        i = i - i
        Try
            cmbPorte.SelectedIndex = i

        Catch ex As Exception
            Dim result As DialogResult
            result = MessageBox.Show("com port non trovata", "Attenzione !!!", MessageBoxButtons.OK)
            cmbPorte.Text = ""
            cmbPorte.Items.Clear()
            Call principale_Load(Me, e)
        End Try
        btnconnetti.Enabled = True
        cmbPorte.DroppedDown = True
    End Sub

    Private Sub btnconnetti_Click(sender As Object, e As EventArgs) Handles btnconnetti.Click
        btnconnetti.Enabled = False
        SerialPort1.BaudRate = cmbbaund.SelectedItem
        SerialPort1.PortName = cmbPorte.SelectedItem
        SerialPort1.Open()
        btnChiudi.Enabled = True
        Timer1.Start()
        Timer2.Start()
        lblConnessione.Text = "Connesso"
        lblConnessione.ForeColor = Color.Green
        Timerpanelincrease.Enabled = True
    End Sub

    Private Sub btnChiudi_Click(sender As Object, e As EventArgs) Handles btnChiudi.Click
        btnChiudi.Enabled = False
        SerialPort1.Close()
        btnconnetti.Enabled = True
        Timer1.Stop()
        Timer2.Stop()
        lblConnessione.Text = "Disconnesso"
        lblConnessione.ForeColor = Color.Red
        Timerpanelincrease.Enabled = True
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        If SerialPort1.BytesToRead > 0 Then
            Try
                Dim i As Integer = SerialPort1.ReadByte
                Console.WriteLine($"DATO: [{i}] ({i.ToString})")
                media_pleyer.lb_volume.Text = i.ToString + "%"
                media_pleyer.Volume_control1.value = i.ToString
                lb_volume.Text = i.ToString + "%"
                Volume_control1.value = i.ToString
                media_pleyer.Timer3.Start()
                media_pleyer.AxWindowsMediaPlayer1.settings.volume = media_pleyer.Volume_control1.value
                AxWindowsMediaPlayer1.settings.volume = media_pleyer.Volume_control1.value
                video.Wmp1.settings.voume = video.Volume_control1.value
            Catch ex As Exception

            End Try
        End If

    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        media_pleyer.Show()
        Me.Hide()
        lb_title.Text = ""
        AxWindowsMediaPlayer1.Ctlcontrols.stop()
        AxWindowsMediaPlayer1.URL = ""
    End Sub

    Private Sub Timerpanelincrease_Tick(sender As Object, e As EventArgs) Handles Timerpanelincrease.Tick
        If Panel3.Height > 0 Then
            Panel3.Height -= 5
        Else
            Timerpanelincrease.Enabled = False
        End If
    End Sub

    Private Sub timerpanelreduce_Tick(sender As Object, e As EventArgs) Handles timerpanelreduce.Tick
        If Panel3.Height < 80 Then
            Panel3.Height += 5
        Else
            timerpanelreduce.Enabled = False
        End If
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        If Panel3.Height > 0 Then
            Timerpanelincrease.Enabled = True

        Else
            timerpanelreduce.Enabled = True

        End If
    End Sub

    Private Sub Btn_105_Click(sender As Object, e As EventArgs) Handles Btn_105.Click
        AxWindowsMediaPlayer1.URL = "https://icy.unitedradio.it/Radio105.mp3"
        lb_title.Text = "Radio 105"
    End Sub

    Private Sub Btn_gamma_Click(sender As Object, e As EventArgs) Handles Btn_gamma.Click
        AxWindowsMediaPlayer1.URL = "https://rn2.fluidstream.eu/gammaradio.aac"
        lb_title.Text = "Gamma Radio"
    End Sub

    Private Sub Btn_r101_Click(sender As Object, e As EventArgs) Handles Btn_r101.Click
        AxWindowsMediaPlayer1.URL = "http://icecast.unitedradio.it/r101"
        lb_title.Text = "R101"
    End Sub

    Private Sub Btn_radioitalia_Click(sender As Object, e As EventArgs) Handles Btn_radioitalia.Click
        AxWindowsMediaPlayer1.URL = "https://radioitaliasmi.akamaized.net/hls/live/2093120/RISMI/stream01/streamPlaylist.m3u8"
        lb_title.Text = "Radio Italia Solo Musica Italiana"
    End Sub

    Private Sub Btn_kisskiss_Click(sender As Object, e As EventArgs) Handles Btn_kisskiss.Click
        AxWindowsMediaPlayer1.URL = "http://ice07.fluidstream.net:8080/KissKiss.mp3"
        lb_title.Text = "Radio Kiss Kiss"
    End Sub

    Private Sub Btn_Rds_Click(sender As Object, e As EventArgs) Handles Btn_Rds.Click
        AxWindowsMediaPlayer1.URL = "http://stream1.rds.it:8000/rds64k"
        lb_title.Text = "RDS"
    End Sub
    Dim x As Integer
    Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click

        If x = 0 Then
            PictureBox1.BackgroundImage = My.Resources.power_off
            SerialPort1.Write("A")
            x = 1
        Else
            PictureBox1.BackgroundImage = My.Resources.power_on
            SerialPort1.Write("O")
            x = 0
        End If
    End Sub

    Private Sub Pcboxbussola_Paint(sender As Object, e As PaintEventArgs) Handles Pcboxbussola.Paint
        e.Graphics.TranslateTransform(cX + Pcboxbussola.Width / 2 - cX, cY + Pcboxbussola.Height / 2 - cY) ' posizione centro
        e.Graphics.RotateTransform(avanzamento) ' rotazione in gradi
        e.Graphics.DrawImage(bussola, -cX, -cY, dX, dY) ' dimensione 100%
    End Sub
    Function RiceviDati() As String
        Dim Ricevuti As String
        Try
            Ricevuti = SerialPort1.ReadExisting
            If Ricevuti <> Nothing Then
                Return Ricevuti
            End If
        Catch ex As Exception
            Return "ERRORE:" & ex.Message
        End Try
    End Function

    Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
        Dim str As String
        str = RiceviDati()

        Dim valoriDivisi() As String ' matrice senza dimensione
        valoriDivisi = str.Split(";") ' il puntoevirgola separa le stringe: in valoriDivisi(0) ci va il codice identificativo (1 = gradi bussola, 2 = volume, ecc) e in valoriDivisi(1) ci va il valore relativo
        If valoriDivisi(0) = "1" Then
            ' Il dato è riferito ai gradi della bussola
            valoriDivisi(1) = valoriDivisi(1).Replace(".", ",") ' se ci fosse il punto decimale viene sostituito con la virgola decimale
            avanzamento = CInt(valoriDivisi(1))
            lblgradi.Text = avanzamento.ToString("000°")
            Pcboxbussola.Invalidate() ' scatena il paint
        End If

    End Sub

End Class
aaa
19/03 20:23
Thejuster
Metti un breakpoint qui

      Dim valoriDivisi() As String ' matrice senza dimensione


Avvia il debugger, quando si ferma, rimani il mouse fermo su str = RiceviDati()

E controlla il contenuto di quella variabile.

l'errore dice che la variabile str potrebbe essere vuota o nulla.
Ed il problema potrebbe essere relativo alla parte di arduino che invia la stringa
o da qualche errore nella funzione RiceviDati che restituisce alla variabile str una stringa vuota o nulla.
mire.forumfree.it/ - Mire Engine
C# UI Designer
20/03 5:53
Carlo
Postato originariamente da nightwolf:

grazie mille x l aiuto, adesso sulla seriale di arduino ho:
B 293.00
B 292.74


Dopo la B non c'è il puntoevirgola, l'istruzione su split va modificata se vuoi usare lo spazio come separatore delle stringhe, ma sconsigliato perché così da Arduino non potresti mandare messaggi interi contenenti spazi.

Thejuster e la segnalazione dell'errore già ti dicono che str è vuoto o nullo per cui split non ha nulla da dividere.

la tua funzione RiceviDati() legge ciclicamente, non è detto che sulla seriale ci siano dei dati da leggere veramente.
la situazione Nothing va gestita:

Function RiceviDati() As String
    Dim Ricevuti As String
    Try
        Ricevuti = SerialPort1.ReadExisting
        If Ricevuti = Nothing Then
            Return "N null" ' ritorna facendoti sapere che non si è ricevuto nulla (N)
        else
            Return Ricevuti
        End If
        Catch ex As Exception      
            ' ex.Message può contenere spazi, li sostituisco con il tratto basso, inutile se poi ripristini l'uso del puntovirgola come separatore      
            Return "E " & ex.Message.Replace(" ", "_") ' ritorna facendoti sapere che si è ricevuto un errore (E)
        End Try
    End Function


e nel Timer2 puoi usare le info ricevute, le stringhe vengono divise usando lo spazio come separatore ma ti consiglio di usare il puntoevirgola:

Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
    Dim str As String
    str = RiceviDati() ' ora str contiene sempre una stringa
 
    Dim valoriDivisi() As String ' matrice senza dimensione
    valoriDivisi = str.Split(" ") ' lo spazo separa le stringhe: in valoriDivisi(0) ci va il codice identificativo (B = gradi bussola, N = null, E = errore) e in valoriDivisi(1) ci va il valore relativo
    If valoriDivisi(0) = "B" Then 
        ' Il dato è riferito ai gradi della bussola
        valoriDivisi(1) = valoriDivisi(1).Replace(".", ",") ' se ci fosse il punto decimale viene sostituito con la virgola decimale
        avanzamento = CInt(valoriDivisi(1))
        lblgradi.Text = avanzamento.ToString("000°")
        Pcboxbussola.Invalidate() ' scatena il paint
    End If

    ' possibili usi degli errori ritornati
    If valoriDivisi(0) = "N" Then
        ' Il dato è riferito a nessun valore ricevuto
        lblgradi.Text = valoriDivisi(1) ' l'info su lblgradi, oppure dove vuoi
    End If

    If valoriDivisi(0) = "E" Then
        ' Il dato è riferito a errore sulla seriale
        lblgradi.Text = valoriDivisi(1) ' il tipo d'errore su lblgradi, oppure dove vuoi
    End If
 
End Sub


non ho controllato le altre parti del codice.
Ultima modifica effettuata da Carlo 20/03 8:07
in programmazione tutto è permesso
20/03 12:53
nightwolf
ho modificato il codice di invio da arduino con il punto e virgola, adesso sulla seriale di arduino esce scritto:
B;301.91
B;302.00
rimane però il problema sempre che dalla seriale non riceve nulla, la variabile str è nulla.
aaa