17/03 21:15
nightwolf
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:
e questo è il codice di visual basic x la bussola
il tutto funziona alla grande.
if (headingDegrees >= 337.5 || headingDegrees < 22.5) Serial.write("N"); else if (headingDegrees >= 22.5 && headingDegrees < 67.5) Serial.write("NE"); else if (headingDegrees >= 67.5 && headingDegrees < 112.5) Serial.write("E"); else if (headingDegrees >= 112.5 && headingDegrees < 157.5) Serial.write("SE"); else if (headingDegrees >= 157.5 && headingDegrees < 202.5) Serial.write("S"); else if (headingDegrees >= 202.5 && headingDegrees < 247.5) Serial.write("SW"); else if (headingDegrees >= 247.5 && headingDegrees < 292.5) Serial.write("W"); else if (headingDegrees >= 292.5 && headingDegrees < 337.5) Serial.write("NW");
e questo è il codice di visual basic x la bussola
Imports System.Drawing.Drawing2D Partial Public Class Form1 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 timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles timer1.Tick avanzamento += direzione avanzamento = avanzamento Mod 360 ' azzera a 360° PictureBox1.Invalidate() ' scatena il paint If avanzamento = destinazione Then timer1.Enabled = False End Sub Private Sub Label1_TextChanged(sender As Object, e As EventArgs) Handles Label1.TextChanged If Label1.Text = "NORD" Then If avanzamento = 0 Then Exit Sub destinazione = 0 ' sceglie la direzione di rotazione If avanzamento < 180 Then direzione = -vel Else direzione = vel timer1.Enabled = True ElseIf Label1.Text = "WEST" Then ' o WEST If avanzamento = 90 Then Exit Sub destinazione = 90 ' sceglie la direzione di rotazione If avanzamento > 90 Then direzione = -vel Else direzione = vel timer1.Enabled = True ElseIf Label1.Text = "SUD" Then If avanzamento = 180 Then Exit Sub destinazione = 180 ' sceglie la direzione di rotazione If avanzamento > 180 Then direzione = -vel Else direzione = vel timer1.Enabled = True ElseIf Label1.Text = "EST" Then ' o EST If avanzamento = 270 Then Exit Sub destinazione = 270 ' normalizza If avanzamento = 0 Then avanzamento = 360 ' forza la rotazione antioraria se si è a nord ' sceglie la direzione di rotazione If avanzamento > 180 Then direzione = -vel Else direzione = vel timer1.Enabled = True ElseIf Label1.Text = "NORD-EST" Then If avanzamento = 320 Then Exit Sub destinazione = 320 ' sceglie la direzione di rotazione If avanzamento > 320 Then direzione = -vel Else direzione = vel timer1.Enabled = True ElseIf Label1.Text = "NORD-WEST" Then If avanzamento = 50 Then Exit Sub destinazione = 50 ' sceglie la direzione di rotazione If avanzamento > 50 Then direzione = -vel Else direzione = vel timer1.Enabled = True ElseIf Label1.Text = "SUD-EST" Then If avanzamento = 220 Then Exit Sub destinazione = 220 ' sceglie la direzione di rotazione If avanzamento > 220 Then direzione = -vel Else direzione = vel timer1.Enabled = True ElseIf Label1.Text = "SUD-WEST" Then If avanzamento = 130 Then Exit Sub destinazione = 130 ' sceglie la direzione di rotazione If avanzamento > 130 Then direzione = -vel Else direzione = vel timer1.Enabled = True End If End Sub Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint e.Graphics.TranslateTransform(cX + PictureBox1.Width / 2 - cX, cY + PictureBox1.Height / 2 - cY) ' posizione centro e.Graphics.RotateTransform(avanzamento) ' rotazione in gradi e.Graphics.DrawImage(bussola, -cX, -cY, dX, dY) ' dimensione 100% 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() 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 timer2.Start() End Sub Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick Dim str As String str = RiceviDati() If str = "N" Then Label1.Text = "NORD" ElseIf str = "E" Then Label1.Text = "EST" ElseIf str = "W" Then Label1.Text = "WEST" ElseIf str = "S" Then Label1.Text = "SUD" ElseIf str = "NE" Then Label1.Text = "NORD-EST" ElseIf str = "NW" Then Label1.Text = "NORD-WEST" ElseIf str = "SE" Then Label1.Text = "SUD-EST" ElseIf str = "SW" Then Label1.Text = "SUD-WEST" End If 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 End Class
il tutto funziona alla grande.
aaa
17/03 21:32
nightwolf
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
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
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
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() lblConnessione.Text = "Connesso" lblConnessione.ForeColor = Color.Green 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
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
aaa
17/03 21:49
nightwolf
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
c'è un qualche modo che il tutto funzioni separatamente?
grazie mille
questo è l intero codice che ho collegato
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 Lbldirezione_TextChanged(sender As Object, e As EventArgs) Handles Lbldirezione.TextChanged If Lbldirezione.Text = "NORD" Then If avanzamento = 0 Then Exit Sub destinazione = 0 ' sceglie la direzione di rotazione If avanzamento < 180 Then direzione = -vel Else direzione = vel tmrbussola.Enabled = True ElseIf Lbldirezione.Text = "WEST" Then ' o WEST If avanzamento = 90 Then Exit Sub destinazione = 90 ' sceglie la direzione di rotazione If avanzamento > 90 Then direzione = -vel Else direzione = vel tmrbussola.Enabled = True ElseIf Lbldirezione.Text = "SUD" Then If avanzamento = 180 Then Exit Sub destinazione = 180 ' sceglie la direzione di rotazione If avanzamento > 180 Then direzione = -vel Else direzione = vel tmrbussola.Enabled = True ElseIf Lbldirezione.Text = "EST" Then ' o EST If avanzamento = 270 Then Exit Sub destinazione = 270 ' normalizza If avanzamento = 0 Then avanzamento = 360 ' forza la rotazione antioraria se si è a nord ' sceglie la direzione di rotazione If avanzamento > 180 Then direzione = -vel Else direzione = vel tmrbussola.Enabled = True ElseIf Lbldirezione.Text = "NORD-EST" Then If avanzamento = 320 Then Exit Sub destinazione = 320 ' sceglie la direzione di rotazione If avanzamento > 320 Then direzione = -vel Else direzione = vel tmrbussola.Enabled = True ElseIf Lbldirezione.Text = "NORD-WEST" Then If avanzamento = 50 Then Exit Sub destinazione = 50 ' sceglie la direzione di rotazione If avanzamento > 50 Then direzione = -vel Else direzione = vel tmrbussola.Enabled = True ElseIf Lbldirezione.Text = "SUD-EST" Then If avanzamento = 220 Then Exit Sub destinazione = 220 ' sceglie la direzione di rotazione If avanzamento > 220 Then direzione = -vel Else direzione = vel tmrbussola.Enabled = True ElseIf Lbldirezione.Text = "SUD-WEST" Then If avanzamento = 130 Then Exit Sub destinazione = 130 ' sceglie la direzione di rotazione If avanzamento > 130 Then direzione = -vel Else direzione = vel tmrbussola.Enabled = True End If 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() If str = "N" Then Lbldirezione.Text = "NORD" ElseIf str = "E" Then Lbldirezione.Text = "EST" ElseIf str = "W" Then Lbldirezione.Text = "WEST" ElseIf str = "S" Then Lbldirezione.Text = "SUD" ElseIf str = "NE" Then Lbldirezione.Text = "NORD-EST" ElseIf str = "NW" Then Lbldirezione.Text = "NORD-WEST" ElseIf str = "SE" Then Lbldirezione.Text = "SUD-EST" ElseIf str = "SW" Then Lbldirezione.Text = "SUD-WEST" End If End Sub
c'è un qualche modo che il tutto funzioni separatamente?
grazie mille
aaa
18/03 5:28
Carlo
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.
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
18/03 9:05
nightwolf
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
nel void loop
questo è una parte di codice della bussola
prima di void setup ho creato una variabile
questo è il codice del potenziometro
int val0=0;
nel void loop
int val = 0; // Somma tre letture consecutive for(int i=0; i<3; ++i) val += analogRead(A0); // Calcola la media val = val/3; // Riporta il valore tra 0 e 100 val = map(val,0,1023,0,100); // Se il valore è cambiato if (val < val0-1 || val > val0+1) { // Manda il dato come singolo byte Serial.write(val); val0 = val; } delay(100);
questo è una parte di codice della bussola
if (headingDegrees >= 337.5 || headingDegrees < 22.5) Serial.write("N"); else if (headingDegrees >= 22.5 && headingDegrees < 67.5) Serial.write("NE"); else if (headingDegrees >= 67.5 && headingDegrees < 112.5) Serial.write("E"); else if (headingDegrees >= 112.5 && headingDegrees < 157.5) Serial.write("SE"); else if (headingDegrees >= 157.5 && headingDegrees < 202.5) Serial.write("S"); else if (headingDegrees >= 202.5 && headingDegrees < 247.5) Serial.write("SW"); else if (headingDegrees >= 247.5 && headingDegrees < 292.5) Serial.write("W"); else if (headingDegrees >= 292.5 && headingDegrees < 337.5) Serial.write("NW");
aaa
18/03 11:32
Thejuster
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.
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.
mire.forumfree.it/ - Mire Engine
C# UI Designer
C# UI Designer
18/03 12:13
nightwolf
questo è l intero codice dove leggo i valori del magnetometro
#include <Wire.h> #include <Adafruit_SSD1306.h> #include <Adafruit_Sensor.h> #include <Adafruit_HMC5883_U.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) #define SCREEN_ADDRESS 0x3C // See datasheet for Address Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); /* Assign a unique ID to this sensor at the same time */ Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345); void setup(void) { Serial.begin(9600); Serial.println("HMC5883 Magnetometer Test"); /* Initialise the sensor */ if (!mag.begin()) { /* There was a problem detecting the HMC5883 ... check your connections */ Serial.println("Ooops, no HMC5883 detected ... Check your wiring!"); while (1); } // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1306 allocation failed")); for (;;); // Don't proceed, loop forever } display.clearDisplay(); display.display(); delay(500); } void loop(void) { /* Get a new sensor event */ sensors_event_t event; mag.getEvent(&event); // Calculate heading when the magnetometer is level, then correct for signs of axis. float heading = atan2(event.magnetic.y, event.magnetic.x); float declinationAngle = 0.06; heading += declinationAngle; // Correct for when signs are reversed. if (heading < 0) heading += 2 * PI; // Check for wrap due to addition of declination. if (heading > 2 * PI) heading -= 2 * PI; // Convert radians to degrees for readability. float headingDegrees = heading * 180 / M_PI; display.clearDisplay(); display.setTextColor(SSD1306_WHITE); // Display angle in degrees display.setTextSize(2); display.setCursor(10, 10); display.print(headingDegrees, 0); display.print((char)247); // Display direction in bold letters display.setTextSize(3); display.setCursor(10, 40); if (headingDegrees >= 337.5 || headingDegrees < 22.5) display.print("N"); else if (headingDegrees >= 22.5 && headingDegrees < 67.5) display.print("NE"); else if (headingDegrees >= 67.5 && headingDegrees < 112.5) display.print("E"); else if (headingDegrees >= 112.5 && headingDegrees < 157.5) display.print("SE"); else if (headingDegrees >= 157.5 && headingDegrees < 202.5) display.print("S"); else if (headingDegrees >= 202.5 && headingDegrees < 247.5) display.print("SW"); else if (headingDegrees >= 247.5 && headingDegrees < 292.5) display.print("W"); else if (headingDegrees >= 292.5 && headingDegrees < 337.5) display.print("NW"); if (headingDegrees >= 337.5 || headingDegrees < 22.5) Serial.write("N"); else if (headingDegrees >= 22.5 && headingDegrees < 67.5) Serial.write("NE"); else if (headingDegrees >= 67.5 && headingDegrees < 112.5) Serial.write("E"); else if (headingDegrees >= 112.5 && headingDegrees < 157.5) Serial.write("SE"); else if (headingDegrees >= 157.5 && headingDegrees < 202.5) Serial.write("S"); else if (headingDegrees >= 202.5 && headingDegrees < 247.5) Serial.write("SW"); else if (headingDegrees >= 247.5 && headingDegrees < 292.5) Serial.write("W"); else if (headingDegrees >= 292.5 && headingDegrees < 337.5) Serial.write("NW"); // Draw compass int centerX = SCREEN_WIDTH - 35; int centerY = SCREEN_HEIGHT / 2; int radius = min(centerX, centerY) - 3; // Increase the radius value for a larger circle display.drawCircle(centerX, centerY, radius, SSD1306_WHITE); display.fillCircle(centerX, centerY, 2, SSD1306_WHITE); // Added small dot at the center display.drawLine(centerX, centerY, centerX + radius * cos(heading - PI / 2), centerY + radius * sin(heading - PI / 2), SSD1306_WHITE); display.display(); delay(500); }
aaa