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 5

Pagine: [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ] Precedente | Prossimo
Avatar
nightwolf (Normal User)
Pro


Messaggi: 149
Iscritto: 14/09/2010

Segnala al moderatore
Postato alle 22:15
Domenica, 17/03/2024
buonasera a tutti, sono andato avanti con il mio progetto, ho collegato i valori di arduino alla mia bussola e il tutto funziona alla grande. questo è il codice di arduino che uso per inviare i dati alle seriale di vb.net:
Codice sorgente - presumibilmente Delphi

  1. if (headingDegrees >= 337.5 || headingDegrees < 22.5)
  2.     Serial.write("N");
  3.   else if (headingDegrees >= 22.5 && headingDegrees < 67.5)
  4.     Serial.write("NE");
  5.   else if (headingDegrees >= 67.5 && headingDegrees < 112.5)
  6.     Serial.write("E");
  7.   else if (headingDegrees >= 112.5 && headingDegrees < 157.5)
  8.      Serial.write("SE");
  9.   else if (headingDegrees >= 157.5 && headingDegrees < 202.5)
  10.      Serial.write("S");
  11.   else if (headingDegrees >= 202.5 && headingDegrees < 247.5)
  12.      Serial.write("SW");
  13.   else if (headingDegrees >= 247.5 && headingDegrees < 292.5)
  14.      Serial.write("W");
  15.   else if (headingDegrees >= 292.5 && headingDegrees < 337.5)
  16.     Serial.write("NW");



e questo è il codice di visual basic x la bussola
Codice sorgente - presumibilmente VB.NET

  1. Imports System.Drawing.Drawing2D
  2.  
  3. Partial Public Class Form1
  4.  
  5.     Dim bussola As Image = New Bitmap("bussola.png") ' bmp in ram dal file originale, deve esistere nella cartelle dell'eseguibile
  6.     Dim destinazione As Integer
  7.     Dim avanzamento As Integer
  8.     Dim direzione As Integer
  9.     Dim cX As Integer = bussola.Width \ 2
  10.     Dim cY As Integer = bussola.Height \ 2
  11.     Dim dX As Integer = bussola.Width
  12.     Dim dY As Integer = bussola.Height
  13.     Dim vel As Integer = 2 ' velocità, valori supportati 1, 2, 3, 5, 6, 9, 10 (divisibili per 90)
  14.  
  15.     Private Sub timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles timer1.Tick
  16.         avanzamento += direzione
  17.         avanzamento = avanzamento Mod 360 ' azzera a 360°
  18.         PictureBox1.Invalidate() ' scatena il paint
  19.         If avanzamento = destinazione Then timer1.Enabled = False
  20.  
  21.     End Sub
  22.  
  23.     Private Sub Label1_TextChanged(sender As Object, e As EventArgs) Handles Label1.TextChanged
  24.         If Label1.Text = "NORD" Then
  25.             If avanzamento = 0 Then Exit Sub
  26.             destinazione = 0
  27.             ' sceglie la direzione di rotazione
  28.             If avanzamento < 180 Then direzione = -vel Else direzione = vel
  29.             timer1.Enabled = True
  30.         ElseIf Label1.Text = "WEST" Then ' o WEST
  31.             If avanzamento = 90 Then Exit Sub
  32.             destinazione = 90
  33.             ' sceglie la direzione di rotazione
  34.             If avanzamento > 90 Then direzione = -vel Else direzione = vel
  35.             timer1.Enabled = True
  36.         ElseIf Label1.Text = "SUD" Then
  37.             If avanzamento = 180 Then Exit Sub
  38.             destinazione = 180
  39.             ' sceglie la direzione di rotazione
  40.             If avanzamento > 180 Then direzione = -vel Else direzione = vel
  41.             timer1.Enabled = True
  42.         ElseIf Label1.Text = "EST" Then ' o EST
  43.             If avanzamento = 270 Then Exit Sub
  44.             destinazione = 270
  45.             ' normalizza
  46.             If avanzamento = 0 Then avanzamento = 360 ' forza la rotazione antioraria se si è a nord
  47.             ' sceglie la direzione di rotazione
  48.             If avanzamento > 180 Then direzione = -vel Else direzione = vel
  49.             timer1.Enabled = True
  50.         ElseIf Label1.Text = "NORD-EST" Then
  51.             If avanzamento = 320 Then Exit Sub
  52.             destinazione = 320
  53.             ' sceglie la direzione di rotazione
  54.             If avanzamento > 320 Then direzione = -vel Else direzione = vel
  55.             timer1.Enabled = True
  56.         ElseIf Label1.Text = "NORD-WEST" Then
  57.             If avanzamento = 50 Then Exit Sub
  58.             destinazione = 50
  59.             ' sceglie la direzione di rotazione
  60.             If avanzamento > 50 Then direzione = -vel Else direzione = vel
  61.             timer1.Enabled = True
  62.         ElseIf Label1.Text = "SUD-EST" Then
  63.             If avanzamento = 220 Then Exit Sub
  64.             destinazione = 220
  65.             ' sceglie la direzione di rotazione
  66.             If avanzamento > 220 Then direzione = -vel Else direzione = vel
  67.             timer1.Enabled = True
  68.         ElseIf Label1.Text = "SUD-WEST" Then
  69.             If avanzamento = 130 Then Exit Sub
  70.             destinazione = 130
  71.             ' sceglie la direzione di rotazione
  72.             If avanzamento > 130 Then direzione = -vel Else direzione = vel
  73.             timer1.Enabled = True
  74.  
  75.         End If
  76.     End Sub
  77.  
  78.     Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
  79.         e.Graphics.TranslateTransform(cX + PictureBox1.Width / 2 - cX, cY + PictureBox1.Height / 2 - cY) ' posizione centro
  80.         e.Graphics.RotateTransform(avanzamento) ' rotazione in gradi
  81.         e.Graphics.DrawImage(bussola, -cX, -cY, dX, dY) ' dimensione 100%
  82.     End Sub
  83.  
  84.     Private Sub btnscanport_Click(sender As Object, e As EventArgs) Handles btnscanport.Click
  85.         cmbPorte.Items.Clear()
  86.         Dim myPort As Array
  87.         Dim i As Integer
  88.         myPort = IO.Ports.SerialPort.GetPortNames
  89.         cmbPorte.Items.AddRange(myPort)
  90.         i = cmbPorte.Items.Count
  91.         i = i - i
  92.         Try
  93.             cmbPorte.SelectedIndex = i
  94.  
  95.         Catch ex As Exception
  96.             Dim result As DialogResult
  97.             result = MessageBox.Show("com port non trovata", "Attenzione !!!", MessageBoxButtons.OK)
  98.             cmbPorte.Text = ""
  99.             cmbPorte.Items.Clear()
  100.  
  101.         End Try
  102.         btnconnetti.Enabled = True
  103.         cmbPorte.DroppedDown = True
  104.     End Sub
  105.  
  106.     Private Sub btnconnetti_Click(sender As Object, e As EventArgs) Handles btnconnetti.Click
  107.         btnconnetti.Enabled = False
  108.         SerialPort1.BaudRate = cmbbaund.SelectedItem
  109.         SerialPort1.PortName = cmbPorte.SelectedItem
  110.         SerialPort1.Open()
  111.         btnChiudi.Enabled = True
  112.         timer2.Start()
  113.  
  114.     End Sub
  115.  
  116.     Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
  117.         Dim str As String
  118.         str = RiceviDati()
  119.         If str = "N" Then
  120.             Label1.Text = "NORD"
  121.         ElseIf str = "E" Then
  122.             Label1.Text = "EST"
  123.         ElseIf str = "W" Then
  124.             Label1.Text = "WEST"
  125.         ElseIf str = "S" Then
  126.             Label1.Text = "SUD"
  127.         ElseIf str = "NE" Then
  128.             Label1.Text = "NORD-EST"
  129.         ElseIf str = "NW" Then
  130.             Label1.Text = "NORD-WEST"
  131.         ElseIf str = "SE" Then
  132.             Label1.Text = "SUD-EST"
  133.         ElseIf str = "SW" Then
  134.             Label1.Text = "SUD-WEST"
  135.         End If
  136.     End Sub
  137.     Function RiceviDati() As String
  138.         Dim Ricevuti As String
  139.         Try
  140.             Ricevuti = SerialPort1.ReadExisting
  141.             If Ricevuti <> Nothing Then
  142.                 Return Ricevuti
  143.             End If
  144.         Catch ex As Exception
  145.             Return "ERRORE:" & ex.Message
  146.         End Try
  147.     End Function
  148. End Class


il tutto funziona alla grande.

PM Quote
Avatar
nightwolf (Normal User)
Pro


Messaggi: 149
Iscritto: 14/09/2010

Segnala al moderatore
Postato alle 22:32
Domenica, 17/03/2024
adesso il mio dubbio è:
avendo gia in visual basic i valori che arrivano dalla seriale riguardanti il potenziometro per il volume, come posso leggere anche questi valori senza che entrino in conflitto? mi spiego meglio,
sulla seriale transiteranno sia i valori del potenziometro x il volume, sia x adesso le lettere riguardanti la direzione, sia più avanti il numero di satelli collegati, che la velocità.
PS. le direzioni arrivano tramite un magnetometro, il numero di satelliti e la velocità attraverso un gps, entrambi collegati ad arduino, ma sempre il tutto tramite la scritta
Serial.write(...)
Posto il codice riguardante la lettura del poteziometro dalla quale regolo il volume del player

Codice sorgente - presumibilmente VB.NET

  1. Private Sub btnconnetti_Click(sender As Object, e As EventArgs) Handles btnconnetti.Click
  2.         btnconnetti.Enabled = False
  3.         SerialPort1.BaudRate = cmbbaund.SelectedItem
  4.         SerialPort1.PortName = cmbPorte.SelectedItem
  5.         SerialPort1.Open()
  6.         btnChiudi.Enabled = True
  7.         Timer1.Start()
  8.         lblConnessione.Text = "Connesso"
  9.         lblConnessione.ForeColor = Color.Green
  10.         Timerpanelincrease.Enabled = True
  11.     End Sub
  12.  Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
  13.         If SerialPort1.BytesToRead > 0 Then
  14.             Try
  15.                 Dim i As Integer = SerialPort1.ReadByte
  16.                 Console.WriteLine($"DATO: [{i}] ({i.ToString})")
  17.                 media_pleyer.lb_volume.Text = i.ToString + "%"
  18.                 media_pleyer.Volume_control1.value = i.ToString
  19.                 lb_volume.Text = i.ToString + "%"
  20.                 Volume_control1.value = i.ToString
  21.                 media_pleyer.Timer3.Start()
  22.                 media_pleyer.AxWindowsMediaPlayer1.settings.volume = media_pleyer.Volume_control1.value
  23.                 AxWindowsMediaPlayer1.settings.volume = media_pleyer.Volume_control1.value
  24.                 video.Wmp1.settings.voume = video.Volume_control1.value
  25.             Catch ex As Exception
  26.  
  27.             End Try
  28.         End If
  29.  
  30.     End Sub


dovrei mettere le varie letture che arrivano dalla seriale dentro timer1? o devo creare qualcos'altro?
il mio dubbio adesso è leggere cio che arriva dalla seriale e inviarla alle rispettive label.
grazie mille

PM Quote
Avatar
nightwolf (Normal User)
Pro


Messaggi: 149
Iscritto: 14/09/2010

Segnala al moderatore
Postato alle 22:49
Domenica, 17/03/2024
ho provato ad integrare il codice nel mio progetto, in teoria funziona, perche quando giro il magnetometro, la bussola si muove, la lbldirezione cambia stato, ma,  contemporaneamente come prevedevo, ricevento i valori dal magnetometro si attiva anche il volume, cosa che si dovrebbe attivare soltanto quando aziono il potenziometro, premetto che collegato ad arduino c'è soltanto il magnetometro, il potenziometro non è minimamente collegato.
questo è l intero codice che ho collegato
Codice sorgente - presumibilmente VB.NET

  1. Private Sub btnconnetti_Click(sender As Object, e As EventArgs) Handles btnconnetti.Click
  2.         btnconnetti.Enabled = False
  3.         SerialPort1.BaudRate = cmbbaund.SelectedItem
  4.         SerialPort1.PortName = cmbPorte.SelectedItem
  5.         SerialPort1.Open()
  6.         btnChiudi.Enabled = True
  7.         Timer1.Start()
  8.         Timer2.Start()
  9.         lblConnessione.Text = "Connesso"
  10.         lblConnessione.ForeColor = Color.Green
  11.         Timerpanelincrease.Enabled = True
  12.     End Sub
  13.  
  14.     Private Sub btnChiudi_Click(sender As Object, e As EventArgs) Handles btnChiudi.Click
  15.         btnChiudi.Enabled = False
  16.         SerialPort1.Close()
  17.         btnconnetti.Enabled = True
  18.         Timer1.Stop()
  19.         Timer2.Stop()
  20.         lblConnessione.Text = "Disconnesso"
  21.         lblConnessione.ForeColor = Color.Red
  22.         Timerpanelincrease.Enabled = True
  23.     End Sub
  24.  
  25.  Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
  26.         If SerialPort1.BytesToRead > 0 Then
  27.             Try
  28.                 Dim i As Integer = SerialPort1.ReadByte
  29.                 Console.WriteLine($"DATO: [{i}] ({i.ToString})")
  30.                 media_pleyer.lb_volume.Text = i.ToString + "%"
  31.                 media_pleyer.Volume_control1.value = i.ToString
  32.                 lb_volume.Text = i.ToString + "%"
  33.                 Volume_control1.value = i.ToString
  34.                 media_pleyer.Timer3.Start()
  35.                 media_pleyer.AxWindowsMediaPlayer1.settings.volume = media_pleyer.Volume_control1.value
  36.                 AxWindowsMediaPlayer1.settings.volume = media_pleyer.Volume_control1.value
  37.                 video.Wmp1.settings.voume = video.Volume_control1.value
  38.             Catch ex As Exception
  39.  
  40.             End Try
  41.         End If
  42.  
  43.     End Sub
  44.  
  45.  Private Sub Lbldirezione_TextChanged(sender As Object, e As EventArgs) Handles Lbldirezione.TextChanged
  46.         If Lbldirezione.Text = "NORD" Then
  47.             If avanzamento = 0 Then Exit Sub
  48.             destinazione = 0
  49.             ' sceglie la direzione di rotazione
  50.             If avanzamento < 180 Then direzione = -vel Else direzione = vel
  51.             tmrbussola.Enabled = True
  52.         ElseIf Lbldirezione.Text = "WEST" Then ' o WEST
  53.             If avanzamento = 90 Then Exit Sub
  54.             destinazione = 90
  55.             ' sceglie la direzione di rotazione
  56.             If avanzamento > 90 Then direzione = -vel Else direzione = vel
  57.             tmrbussola.Enabled = True
  58.         ElseIf Lbldirezione.Text = "SUD" Then
  59.             If avanzamento = 180 Then Exit Sub
  60.             destinazione = 180
  61.             ' sceglie la direzione di rotazione
  62.             If avanzamento > 180 Then direzione = -vel Else direzione = vel
  63.             tmrbussola.Enabled = True
  64.         ElseIf Lbldirezione.Text = "EST" Then ' o EST
  65.             If avanzamento = 270 Then Exit Sub
  66.             destinazione = 270
  67.             ' normalizza
  68.             If avanzamento = 0 Then avanzamento = 360 ' forza la rotazione antioraria se si è a nord
  69.             ' sceglie la direzione di rotazione
  70.             If avanzamento > 180 Then direzione = -vel Else direzione = vel
  71.             tmrbussola.Enabled = True
  72.         ElseIf Lbldirezione.Text = "NORD-EST" Then
  73.             If avanzamento = 320 Then Exit Sub
  74.             destinazione = 320
  75.             ' sceglie la direzione di rotazione
  76.             If avanzamento > 320 Then direzione = -vel Else direzione = vel
  77.             tmrbussola.Enabled = True
  78.         ElseIf Lbldirezione.Text = "NORD-WEST" Then
  79.             If avanzamento = 50 Then Exit Sub
  80.             destinazione = 50
  81.             ' sceglie la direzione di rotazione
  82.             If avanzamento > 50 Then direzione = -vel Else direzione = vel
  83.             tmrbussola.Enabled = True
  84.         ElseIf Lbldirezione.Text = "SUD-EST" Then
  85.             If avanzamento = 220 Then Exit Sub
  86.             destinazione = 220
  87.             ' sceglie la direzione di rotazione
  88.             If avanzamento > 220 Then direzione = -vel Else direzione = vel
  89.             tmrbussola.Enabled = True
  90.         ElseIf Lbldirezione.Text = "SUD-WEST" Then
  91.             If avanzamento = 130 Then Exit Sub
  92.             destinazione = 130
  93.             ' sceglie la direzione di rotazione
  94.             If avanzamento > 130 Then direzione = -vel Else direzione = vel
  95.             tmrbussola.Enabled = True
  96.  
  97.         End If
  98.     End Sub
  99.  
  100.  Function RiceviDati() As String
  101.         Dim Ricevuti As String
  102.         Try
  103.             Ricevuti = SerialPort1.ReadExisting
  104.             If Ricevuti <> Nothing Then
  105.                 Return Ricevuti
  106.             End If
  107.         Catch ex As Exception
  108.             Return "ERRORE:" & ex.Message
  109.         End Try
  110.     End Function
  111.  
  112.     Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
  113.         Dim str As String
  114.         str = RiceviDati()
  115.         If str = "N" Then
  116.             Lbldirezione.Text = "NORD"
  117.         ElseIf str = "E" Then
  118.             Lbldirezione.Text = "EST"
  119.         ElseIf str = "W" Then
  120.             Lbldirezione.Text = "WEST"
  121.         ElseIf str = "S" Then
  122.             Lbldirezione.Text = "SUD"
  123.         ElseIf str = "NE" Then
  124.             Lbldirezione.Text = "NORD-EST"
  125.         ElseIf str = "NW" Then
  126.             Lbldirezione.Text = "NORD-WEST"
  127.         ElseIf str = "SE" Then
  128.             Lbldirezione.Text = "SUD-EST"
  129.         ElseIf str = "SW" Then
  130.             Lbldirezione.Text = "SUD-WEST"
  131.         End If
  132.     End Sub


c'è un qualche modo che il tutto funzioni separatamente?
grazie mille

PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1364
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 6:28
Lunedì, 18/03/2024
Il codice su arduino lo hai scritto tu???

E' indispensabile identificare i dati.

Puoi inviare la richiesta dati ad Arduino, specificando cosa vuoi ricevere.

Oppre Arduino quando trasmette li deve identificare es:
1; NORD  (1; significa che il dato è della bussola)
2; 10%    (2; significa che è il volume)
3; ecc

Se come sembra ricevi anche Byte singoli, li puoi organizzare in gruppi congegnati in modo che si sappia a cosa si riferiscano.


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


Messaggi: 149
Iscritto: 14/09/2010

Segnala al moderatore
Postato alle 10:05
Lunedì, 18/03/2024
in parte si, in parte mi hanno aiutato perchè quando leggevo i valori il volume oscillava troppa, questo è il codice che uso su arduino per leggere i valori del potenziometro, in pratica creo una variabile dove faccio la media di tre valori e trasmetto il risultato.
prima di void setup ho creato una variabile
questo è il codice del potenziometro

Codice sorgente - presumibilmente C# / VB.NET

  1. int val0=0;



nel void loop
Codice sorgente - presumibilmente C# / VB.NET

  1. int val = 0;
  2.   // Somma tre letture consecutive
  3.   for(int i=0; i<3; ++i)
  4.     val += analogRead(A0);
  5.   // Calcola la media
  6.   val = val/3;
  7.   // Riporta il valore tra 0 e 100
  8.   val = map(val,0,1023,0,100);
  9.   // Se il valore è cambiato
  10.   if (val < val0-1 || val > val0+1) {
  11.     // Manda il dato come singolo byte
  12.     Serial.write(val);
  13.     val0 = val;
  14.   }
  15.   delay(100);



questo è una parte di codice della bussola

Codice sorgente - presumibilmente Delphi

  1. if (headingDegrees >= 337.5 || headingDegrees < 22.5)
  2.     Serial.write("N");
  3.   else if (headingDegrees >= 22.5 && headingDegrees < 67.5)
  4.     Serial.write("NE");
  5.   else if (headingDegrees >= 67.5 && headingDegrees < 112.5)
  6.     Serial.write("E");
  7.   else if (headingDegrees >= 112.5 && headingDegrees < 157.5)
  8.      Serial.write("SE");
  9.   else if (headingDegrees >= 157.5 && headingDegrees < 202.5)
  10.      Serial.write("S");
  11.   else if (headingDegrees >= 202.5 && headingDegrees < 247.5)
  12.      Serial.write("SW");
  13.   else if (headingDegrees >= 247.5 && headingDegrees < 292.5)
  14.      Serial.write("W");
  15.   else if (headingDegrees >= 292.5 && headingDegrees < 337.5)
  16.     Serial.write("NW");







PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2316
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 12:32
Lunedì, 18/03/2024
controlla la lettura

headingDegrees

hai scritto solo la parte per quanto riguarda il potenziometro, ma non la parte dove assegni i valori a headingDegrees.

deve esserci un conflitto tra headingDegrees  e val.



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 13:13
Lunedì, 18/03/2024
questo è l intero codice dove leggo i valori del magnetometro

Codice sorgente - presumibilmente C++

  1. #include <Wire.h>
  2. #include <Adafruit_SSD1306.h>
  3. #include <Adafruit_Sensor.h>
  4. #include <Adafruit_HMC5883_U.h>
  5.  
  6. #define SCREEN_WIDTH 128 // OLED display width, in pixels
  7. #define SCREEN_HEIGHT 64 // OLED display height, in pixels
  8. #define OLED_RESET -1    // Reset pin # (or -1 if sharing Arduino reset pin)
  9. #define SCREEN_ADDRESS 0x3C // See datasheet for Address
  10.  
  11. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  12.  
  13. /* Assign a unique ID to this sensor at the same time */
  14. Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);
  15.  
  16. void setup(void)
  17. {
  18.   Serial.begin(9600);
  19.   Serial.println("HMC5883 Magnetometer Test");
  20.  
  21.   /* Initialise the sensor */
  22.   if (!mag.begin())
  23.   {
  24.     /* There was a problem detecting the HMC5883 ... check your connections */
  25.     Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
  26.     while (1);
  27.   }
  28.  
  29.   // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  30.   if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS))
  31.   {
  32.     Serial.println(F("SSD1306 allocation failed"));
  33.     for (;;); // Don't proceed, loop forever
  34.   }
  35.  
  36.   display.clearDisplay();
  37.   display.display();
  38.   delay(500);
  39. }
  40.  
  41. void loop(void)
  42. {
  43.   /* Get a new sensor event */
  44.   sensors_event_t event;
  45.   mag.getEvent(&event);
  46.  
  47.   // Calculate heading when the magnetometer is level, then correct for signs of axis.
  48.   float heading = atan2(event.magnetic.y, event.magnetic.x);
  49.  
  50.   float declinationAngle = 0.06;
  51.   heading += declinationAngle;
  52.  
  53.   // Correct for when signs are reversed.
  54.   if (heading < 0)
  55.     heading += 2 * PI;
  56.  
  57.   // Check for wrap due to addition of declination.
  58.   if (heading > 2 * PI)
  59.     heading -= 2 * PI;
  60.  
  61.   // Convert radians to degrees for readability.
  62.   float headingDegrees = heading * 180 / M_PI;
  63.  
  64.   display.clearDisplay();
  65.   display.setTextColor(SSD1306_WHITE);
  66.  
  67.   // Display angle in degrees
  68.   display.setTextSize(2);
  69.   display.setCursor(10, 10);
  70.   display.print(headingDegrees, 0);
  71.   display.print((char)247);
  72.  
  73.   // Display direction in bold letters
  74.   display.setTextSize(3);
  75.   display.setCursor(10, 40);
  76.  
  77.   if (headingDegrees >= 337.5 || headingDegrees < 22.5)
  78.     display.print("N");
  79.   else if (headingDegrees >= 22.5 && headingDegrees < 67.5)
  80.     display.print("NE");
  81.   else if (headingDegrees >= 67.5 && headingDegrees < 112.5)
  82.     display.print("E");
  83.   else if (headingDegrees >= 112.5 && headingDegrees < 157.5)
  84.     display.print("SE");
  85.   else if (headingDegrees >= 157.5 && headingDegrees < 202.5)
  86.     display.print("S");
  87.   else if (headingDegrees >= 202.5 && headingDegrees < 247.5)
  88.     display.print("SW");
  89.   else if (headingDegrees >= 247.5 && headingDegrees < 292.5)
  90.     display.print("W");
  91.   else if (headingDegrees >= 292.5 && headingDegrees < 337.5)
  92.     display.print("NW");
  93.  
  94.    if (headingDegrees >= 337.5 || headingDegrees < 22.5)
  95.     Serial.write("N");
  96.   else if (headingDegrees >= 22.5 && headingDegrees < 67.5)
  97.     Serial.write("NE");
  98.   else if (headingDegrees >= 67.5 && headingDegrees < 112.5)
  99.     Serial.write("E");
  100.   else if (headingDegrees >= 112.5 && headingDegrees < 157.5)
  101.      Serial.write("SE");
  102.   else if (headingDegrees >= 157.5 && headingDegrees < 202.5)
  103.      Serial.write("S");
  104.   else if (headingDegrees >= 202.5 && headingDegrees < 247.5)
  105.      Serial.write("SW");
  106.   else if (headingDegrees >= 247.5 && headingDegrees < 292.5)
  107.      Serial.write("W");
  108.   else if (headingDegrees >= 292.5 && headingDegrees < 337.5)
  109.     Serial.write("NW");  
  110.  
  111.   // Draw compass
  112.   int centerX = SCREEN_WIDTH - 35;
  113.   int centerY = SCREEN_HEIGHT / 2;
  114.   int radius = min(centerX, centerY) - 3; // Increase the radius value for a larger circle
  115.  
  116.   display.drawCircle(centerX, centerY, radius, SSD1306_WHITE);
  117.   display.fillCircle(centerX, centerY, 2, SSD1306_WHITE); // Added small dot at the center
  118.  
  119.   display.drawLine(centerX, centerY, centerX + radius * cos(heading - PI / 2), centerY + radius * sin(heading - PI / 2), SSD1306_WHITE);
  120.  
  121.   display.display();
  122.  
  123.   delay(500);
  124. }


PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1364
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 14:10
Lunedì, 18/03/2024
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. valoreRicevuto = valoreRicevuto.Replace(".", ",") ' se ci fosse il punto decimale viene sostituito con la virgola decimale
  3. Dim valoriDivisi() As String ' matrice senza dimensione
  4. valoriDivisi = valoreRicevuto.Split(";") ' il puntoevirgola separa le stringe: in valoriDivisi(0) ci va 1 e in valoriDivisi(1) ci va 320,500000
  5. If valoriDivisi(0) = "1" Then
  6.         ' Il dato è riferito ai gradi della bussola
  7.         ' in valoriDivisi(1) i gradi ricevuti in formato stringa
  8.         Dim gradi As Integer = CInt(valoriDivisi(1))
  9. 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 il 18/03/2024 alle 15:46


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