Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - creare una bussola
Forum - C# / VB.NET - creare una bussola - Pagina 6

Pagine: [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ] Precedente | Prossimo
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2316
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 14:55
Lunedì, 18/03/2024
Testo quotato

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:

Codice sorgente - presumibilmente C# / VB.NET

  1. char send [20]; // send può contenere 20 caratteri
  2. sprintf(send, "1; %f", headingDegrees); // converti in stringa i gradi e aggiungi l'identificativo: 1; per i gradi
  3. 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:

Codice sorgente - presumibilmente VB.NET

  1. Dim valoreRicevuto As String = "1; 320.500000" ' solo per provare
  2. Dim valoriDivisi() As String ' matrice senza dimensione
  3. valoriDivisi = valoreRicevuto.Split(";") ' il puntoevirgola separa le stringe: in valoriDivisi(0) ci va 1 e in valoriDivisi(1) ci va 320
  4. If valoriDivisi(0) = "1" Then ' se è 1 allora sono gradi
  5.     ' Il dato è riferito ai gradi della bussola
  6.     ' in valoriDivisi(1) i gradi ricevuti in formato stringa
  7. 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.



https://mire.forumfree.it/ - Mire Engine
C# UI Designer
PM Quote
Avatar
nightwolf (Normal User)
Pro


Messaggi: 149
Iscritto: 14/09/2010

Segnala al moderatore
Postato alle 19:01
Lunedì, 18/03/2024
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:

PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1364
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 7:38
Martedì, 19/03/2024
Testo quotato

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

Codice sorgente - presumibilmente VB.NET

  1. Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
  2.     Dim str As String
  3.     str = RiceviDati()
  4.  
  5.     Dim valoriDivisi() As String ' matrice senza dimensione
  6.     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
  7.     If valoriDivisi(0) = "1" Then
  8.            ' Il dato è riferito ai gradi della bussola
  9.             valoriDivisi(1) = valoriDivisi(1).Replace(".", ",") ' se ci fosse il punto decimale viene sostituito con la virgola decimale
  10.             avanzamento = CInt(valoriDivisi(1))
  11.             Label1.Text = avanzamento.ToString("000°")
  12.             PictureBox1.Invalidate() ' scatena il paint
  13.     End If
  14.  
  15.     If valoriDivisi(0) = "2" Then
  16.            ' Il dato in: valoriDivisi(1), è riferito al volume
  17.             ....
  18.             ....
  19.     End If
  20.      
  21. 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 il 19/03/2024 alle 14:31


in programmazione tutto è permesso
PM Quote
Avatar
nightwolf (Normal User)
Pro


Messaggi: 149
Iscritto: 14/09/2010

Segnala al moderatore
Postato alle 18:45
Martedì, 19/03/2024
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

Codice sorgente - presumibilmente VB.NET

  1. Imports System.IO.Ports
  2. Imports System.Drawing.Drawing2D
  3. Public Class principale
  4.     Dim bussola As Image = New Bitmap("bussola.png") ' bmp in ram dal file originale, deve esistere nella cartelle dell'eseguibile
  5.     Dim destinazione As Integer
  6.     Dim avanzamento As Integer
  7.     Dim direzione As Integer
  8.     Dim cX As Integer = bussola.Width \ 2
  9.     Dim cY As Integer = bussola.Height \ 2
  10.     Dim dX As Integer = bussola.Width
  11.     Dim dY As Integer = bussola.Height
  12.     Dim vel As Integer = 2 ' velocità, valori supportati 1, 2, 3, 5, 6, 9, 10 (divisibili per 90)
  13.     Private Sub principale_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  14.         Me.CenterToParent()
  15.         btnconnetti.Enabled = False
  16.         btnChiudi.Enabled = False
  17.         cmbbaund.SelectedItem = "9600"
  18.         media_pleyer.Timer5.Start()
  19.     End Sub
  20.  
  21.     Private Sub btnscanport_Click(sender As Object, e As EventArgs) Handles btnscanport.Click
  22.         cmbPorte.Items.Clear()
  23.         Dim myPort As Array
  24.         Dim i As Integer
  25.         myPort = IO.Ports.SerialPort.GetPortNames
  26.         cmbPorte.Items.AddRange(myPort)
  27.         i = cmbPorte.Items.Count
  28.         i = i - i
  29.         Try
  30.             cmbPorte.SelectedIndex = i
  31.  
  32.         Catch ex As Exception
  33.             Dim result As DialogResult
  34.             result = MessageBox.Show("com port non trovata", "Attenzione !!!", MessageBoxButtons.OK)
  35.             cmbPorte.Text = ""
  36.             cmbPorte.Items.Clear()
  37.             Call principale_Load(Me, e)
  38.         End Try
  39.         btnconnetti.Enabled = True
  40.         cmbPorte.DroppedDown = True
  41.     End Sub
  42.  
  43.     Private Sub btnconnetti_Click(sender As Object, e As EventArgs) Handles btnconnetti.Click
  44.         btnconnetti.Enabled = False
  45.         SerialPort1.BaudRate = cmbbaund.SelectedItem
  46.         SerialPort1.PortName = cmbPorte.SelectedItem
  47.         SerialPort1.Open()
  48.         btnChiudi.Enabled = True
  49.         Timer1.Start()
  50.         Timer2.Start()
  51.         lblConnessione.Text = "Connesso"
  52.         lblConnessione.ForeColor = Color.Green
  53.         Timerpanelincrease.Enabled = True
  54.     End Sub
  55.  
  56.     Private Sub btnChiudi_Click(sender As Object, e As EventArgs) Handles btnChiudi.Click
  57.         btnChiudi.Enabled = False
  58.         SerialPort1.Close()
  59.         btnconnetti.Enabled = True
  60.         Timer1.Stop()
  61.         Timer2.Stop()
  62.         lblConnessione.Text = "Disconnesso"
  63.         lblConnessione.ForeColor = Color.Red
  64.         Timerpanelincrease.Enabled = True
  65.     End Sub
  66.  
  67.     Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
  68.         If SerialPort1.BytesToRead > 0 Then
  69.             Try
  70.                 Dim i As Integer = SerialPort1.ReadByte
  71.                 Console.WriteLine($"DATO: [{i}] ({i.ToString})")
  72.                 media_pleyer.lb_volume.Text = i.ToString + "%"
  73.                 media_pleyer.Volume_control1.value = i.ToString
  74.                 lb_volume.Text = i.ToString + "%"
  75.                 Volume_control1.value = i.ToString
  76.                 media_pleyer.Timer3.Start()
  77.                 media_pleyer.AxWindowsMediaPlayer1.settings.volume = media_pleyer.Volume_control1.value
  78.                 AxWindowsMediaPlayer1.settings.volume = media_pleyer.Volume_control1.value
  79.                 video.Wmp1.settings.voume = video.Volume_control1.value
  80.             Catch ex As Exception
  81.  
  82.             End Try
  83.         End If
  84.  
  85.     End Sub
  86.  
  87.     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
  88.         media_pleyer.Show()
  89.         Me.Hide()
  90.         lb_title.Text = ""
  91.         AxWindowsMediaPlayer1.Ctlcontrols.stop()
  92.         AxWindowsMediaPlayer1.URL = ""
  93.     End Sub
  94.  
  95.     Private Sub Timerpanelincrease_Tick(sender As Object, e As EventArgs) Handles Timerpanelincrease.Tick
  96.         If Panel3.Height > 0 Then
  97.             Panel3.Height -= 5
  98.         Else
  99.             Timerpanelincrease.Enabled = False
  100.         End If
  101.     End Sub
  102.  
  103.     Private Sub timerpanelreduce_Tick(sender As Object, e As EventArgs) Handles timerpanelreduce.Tick
  104.         If Panel3.Height < 80 Then
  105.             Panel3.Height += 5
  106.         Else
  107.             timerpanelreduce.Enabled = False
  108.         End If
  109.     End Sub
  110.  
  111.     Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
  112.         If Panel3.Height > 0 Then
  113.             Timerpanelincrease.Enabled = True
  114.  
  115.         Else
  116.             timerpanelreduce.Enabled = True
  117.  
  118.         End If
  119.     End Sub
  120.  
  121.     Private Sub Btn_105_Click(sender As Object, e As EventArgs) Handles Btn_105.Click
  122.         AxWindowsMediaPlayer1.URL = "https://icy.unitedradio.it/Radio105.mp3"
  123.         lb_title.Text = "Radio 105"
  124.     End Sub
  125.  
  126.     Private Sub Btn_gamma_Click(sender As Object, e As EventArgs) Handles Btn_gamma.Click
  127.         AxWindowsMediaPlayer1.URL = "https://rn2.fluidstream.eu/gammaradio.aac"
  128.         lb_title.Text = "Gamma Radio"
  129.     End Sub
  130.  
  131.     Private Sub Btn_r101_Click(sender As Object, e As EventArgs) Handles Btn_r101.Click
  132.         AxWindowsMediaPlayer1.URL = "http://icecast.unitedradio.it/r101"
  133.         lb_title.Text = "R101"
  134.     End Sub
  135.  
  136.     Private Sub Btn_radioitalia_Click(sender As Object, e As EventArgs) Handles Btn_radioitalia.Click
  137.         AxWindowsMediaPlayer1.URL = "https://radioitaliasmi.akamaized.net/hls/live/2093120/RISMI/stream01/streamPlaylist.m3u8"
  138.         lb_title.Text = "Radio Italia Solo Musica Italiana"
  139.     End Sub
  140.  
  141.     Private Sub Btn_kisskiss_Click(sender As Object, e As EventArgs) Handles Btn_kisskiss.Click
  142.         AxWindowsMediaPlayer1.URL = "http://ice07.fluidstream.net:8080/KissKiss.mp3"
  143.         lb_title.Text = "Radio Kiss Kiss"
  144.     End Sub
  145.  
  146.     Private Sub Btn_Rds_Click(sender As Object, e As EventArgs) Handles Btn_Rds.Click
  147.         AxWindowsMediaPlayer1.URL = "http://stream1.rds.it:8000/rds64k"
  148.         lb_title.Text = "RDS"
  149.     End Sub
  150.     Dim x As Integer
  151.     Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
  152.  
  153.         If x = 0 Then
  154.             PictureBox1.BackgroundImage = My.Resources.power_off
  155.             SerialPort1.Write("A")
  156.             x = 1
  157.         Else
  158.             PictureBox1.BackgroundImage = My.Resources.power_on
  159.             SerialPort1.Write("O")
  160.             x = 0
  161.         End If
  162.     End Sub
  163.  
  164.     Private Sub Pcboxbussola_Paint(sender As Object, e As PaintEventArgs) Handles Pcboxbussola.Paint
  165.         e.Graphics.TranslateTransform(cX + Pcboxbussola.Width / 2 - cX, cY + Pcboxbussola.Height / 2 - cY) ' posizione centro
  166.         e.Graphics.RotateTransform(avanzamento) ' rotazione in gradi
  167.         e.Graphics.DrawImage(bussola, -cX, -cY, dX, dY) ' dimensione 100%
  168.     End Sub
  169.     Function RiceviDati() As String
  170.         Dim Ricevuti As String
  171.         Try
  172.             Ricevuti = SerialPort1.ReadExisting
  173.             If Ricevuti <> Nothing Then
  174.                 Return Ricevuti
  175.             End If
  176.         Catch ex As Exception
  177.             Return "ERRORE:" & ex.Message
  178.         End Try
  179.     End Function
  180.  
  181.     Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
  182.         Dim str As String
  183.         str = RiceviDati()
  184.  
  185.         Dim valoriDivisi() As String ' matrice senza dimensione
  186.         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
  187.         If valoriDivisi(0) = "1" Then
  188.             ' Il dato è riferito ai gradi della bussola
  189.             valoriDivisi(1) = valoriDivisi(1).Replace(".", ",") ' se ci fosse il punto decimale viene sostituito con la virgola decimale
  190.             avanzamento = CInt(valoriDivisi(1))
  191.             lblgradi.Text = avanzamento.ToString("000°")
  192.             Pcboxbussola.Invalidate() ' scatena il paint
  193.         End If
  194.  
  195.     End Sub
  196.  
  197. End Class



nightwolf ha allegato un file: errore.png (157124 bytes)
Clicca qui per guardare l'immagine
PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2316
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 21:23
Martedì, 19/03/2024
Metti un breakpoint qui

Codice sorgente - presumibilmente C# / VB.NET

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


https://mire.forumfree.it/ - Mire Engine
C# UI Designer
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1364
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 6:53
Mercoledì, 20/03/2024
Testo quotato

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:

Codice sorgente - presumibilmente VB.NET

  1. Function RiceviDati() As String
  2.     Dim Ricevuti As String
  3.     Try
  4.         Ricevuti = SerialPort1.ReadExisting
  5.         If Ricevuti = Nothing Then
  6.             Return "N null" ' ritorna facendoti sapere che non si è ricevuto nulla (N)
  7.         else
  8.             Return Ricevuti
  9.         End If
  10.         Catch ex As Exception      
  11.             ' ex.Message può contenere spazi, li sostituisco con il tratto basso, inutile se poi ripristini l'uso del puntovirgola come separatore      
  12.             Return "E " & ex.Message.Replace(" ", "_") ' ritorna facendoti sapere che si è ricevuto un errore (E)
  13.         End Try
  14.     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:

Codice sorgente - presumibilmente VB.NET

  1. Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
  2.     Dim str As String
  3.     str = RiceviDati() ' ora str contiene sempre una stringa
  4.  
  5.     Dim valoriDivisi() As String ' matrice senza dimensione
  6.     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
  7.     If valoriDivisi(0) = "B" Then
  8.         ' Il dato è riferito ai gradi della bussola
  9.         valoriDivisi(1) = valoriDivisi(1).Replace(".", ",") ' se ci fosse il punto decimale viene sostituito con la virgola decimale
  10.         avanzamento = CInt(valoriDivisi(1))
  11.         lblgradi.Text = avanzamento.ToString("000°")
  12.         Pcboxbussola.Invalidate() ' scatena il paint
  13.     End If
  14.  
  15.     ' possibili usi degli errori ritornati
  16.     If valoriDivisi(0) = "N" Then
  17.         ' Il dato è riferito a nessun valore ricevuto
  18.         lblgradi.Text = valoriDivisi(1) ' l'info su lblgradi, oppure dove vuoi
  19.     End If
  20.  
  21.     If valoriDivisi(0) = "E" Then
  22.         ' Il dato è riferito a errore sulla seriale
  23.         lblgradi.Text = valoriDivisi(1) ' il tipo d'errore su lblgradi, oppure dove vuoi
  24.     End If
  25.  
  26. End Sub



non ho controllato le altre parti del codice.

Ultima modifica effettuata da Carlo il 20/03/2024 alle 9:07


in programmazione tutto è permesso
PM Quote
Avatar
nightwolf (Normal User)
Pro


Messaggi: 149
Iscritto: 14/09/2010

Segnala al moderatore
Postato alle 13:53
Mercoledì, 20/03/2024
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.

PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1364
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 21:53
Mercoledì, 20/03/2024
Testo quotato

Postato originariamente da 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.



Da Arduino esce, dove?? Dove lo hai letto che esce B;301.91 se str è nulla?
Posti il codice C?


in programmazione tutto è permesso
PM Quote
Pagine: [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ] Precedente | Prossimo