Oppure

Loading
20/03 20:53
Carlo
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
21/03 10:05
nightwolf
questo è quello che leggo dal serial monitor di arduino
P;52
B;300.90
B;301.02
B;301.06
B;300.86
B;301.26
B;300.98
B;300.90
B;301.10
B;301.14
B;301.10


dove P sta ad indicare il valore del potenziometro x il volume, che nel programma lo gestisce timer1, solo che è da modificare perchè adesso da arduino x il potenziometro invio delle stringhe e non il semplice byte, e B che sarebbero le coordinate del magnetometro
questo è il codice di arduino:

#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>

// CONFIGURAZIONE
const byte P_LED = 9;
const byte P_SET = 6;
const byte P_RESET = 7;
const byte P_RELE_APRE = 10;    //relè x sbloccare porta
const byte P_RELE_BLOCCA = 11;  //rele x bloccare porta

Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);  //identifiacativo magnetometro

LiquidCrystal_I2C lcd(0x27, 16, 2);  //display lcd x la visualizzazione dell orario

RTC_DS3231 rtc;
DateTime now;

char str[3];
int stato1 = 0;
int val = 0;

int val0 = 0;

// Buffer per la composizione delle stringhe da inviare via seriale
char outBuf[20];

void setup() {
  Wire.begin();
  Serial.begin(9600);

  lcd.backlight();
  lcd.init();

  //pulsanti set e reset
  pinMode(P_SET, INPUT);
  pinMode(P_RESET, INPUT);
  pinMode(P_LED, OUTPUT);
  pinMode(P_RELE_APRE, OUTPUT);
  pinMode(P_RELE_BLOCCA, OUTPUT);
  digitalWrite(P_RELE_APRE, HIGH);
  digitalWrite(P_RELE_BLOCCA, HIGH);

  if (!rtc.begin()) {  //inizializzo l rtc
    Serial.println("Couldn't find RTC");
    while (true)
      ;
  }

  if (!rtc.lostPower()) {
    //Serial.println("RTC is NOT running, let's set the time!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  if (!mag.begin())  //inizializzo il magnetometro
  {
    /* There was a problem detecting the HMC5883 ... check your connections */
    Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
    while (1)
      ;
  }
}

void loop() {
  MostraOra();
  bussola();
  if (Serial.available()) {
    // Gestione comandi da VB
    // Per ora leggo solo un singolo carattere per volta
    char comando = Serial.read();
    switch (comando) {
      case 'A':
        digitalWrite(P_RELE_APRE, LOW);
        delay(100);  // attivo o disattivo i rele in base al comando ricevuto da visual basic
        digitalWrite(P_RELE_APRE, HIGH);
        break;
      case 'O':
        digitalWrite(P_RELE_BLOCCA, LOW);
        delay(100);
        digitalWrite(P_RELE_BLOCCA, HIGH);
        break;
      default:
        // Ignoro qualsiasi altro carattere
        break;
    }
  }
  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            //calcolo la media dei valori del potenziometro x il controllo del volume e li invio tramite la seriale,
  val = map(val, 0, 1023, 0, 100);  // visualbasic cosi regolerà il volume del player
  // Se il valore è cambiato
  if (val < val0 - 1 || val > val0 + 1) {
    // Manda il dato ("P" = potenziometro)
    sprintf(outBuf, "P;%d", val);
    Serial.println(outBuf);
    val0 = val;
  }
  delay(100);
}

void bussola() {  //evento bussola per indicare i gradi del magnetometro,
  sensors_event_t event;
  mag.getEvent(&event);
  float heading = atan2(event.magnetic.y, event.magnetic.x);
  float declinationAngle = 0.06;
  heading += declinationAngle;
  if (heading < 0) {
    heading += 2 * PI;
  }
  if (heading > 2 * PI) {
    heading -= 2 * PI;
  }
  float headingDegrees = heading * 180 / M_PI;
  // Manda la lettura ("B"=bussola)
  char deg[8];
  // Gradi: ###.## quindi 6 caraatteri totali, inclusi 2 decimali)
  dtostrf(headingDegrees, 6, 2, deg);
  sprintf(outBuf, "B;%s", deg);
  Serial.println(outBuf);
  delay(500);
}

void MostraOra() {
  switch (stato1) {
    case 0:
      displayTime();
      break;
    case 1:
      setHour();
      break;
    case 2:
      setMinute();
      break;
    case 3:
      setSecond();
      break;
    case 4:
      setyear();
      break;
    case 5:
      setmonth();
      break;
    case 6:
      setday();
      break;
  }
}


unsigned long t1, dt1;
bool FIRST = true;

void displayTime() {
  if (FIRST) {
    lcd.clear();
    t1 = millis();
    FIRST = false;
  }

  dt1 = millis() - t1;
  if (dt1 > 1000) {
    now = rtc.now();
    lcd.setCursor(4, 1);

    sprintf(str, "%02d", now.hour());
    lcd.print(str);
    lcd.print(':');
    sprintf(str, "%02d", now.minute());
    lcd.print(str);
    lcd.print(':');
    sprintf(str, "%02d", now.second());
    lcd.print(str);

    lcd.setCursor(3, 0);

    sprintf(str, "%02d", now.day());
    lcd.print(str);
    lcd.print('/');
    sprintf(str, "%02d", now.month());
    lcd.print(str);
    lcd.print('/');
    sprintf(str, "%02d", now.year());
    lcd.print(str);

    t1 = millis();
  }

  if (digitalRead(P_SET)) {
    //imposta ora
    stato1 = 1;
    delay(300);
    FIRST = true;
  }
}

int seth = 0;

void setHour() {
  if (FIRST) {
    lcd.clear();
    now = rtc.now();
    seth = now.hour();
    lcd.setCursor(0, 0);
    lcd.print("Imposta ora");
    FIRST = false;
  }
  lcd.setCursor(0, 1);
  sprintf(str, "%02d", seth);
  lcd.print(str);

  if (digitalRead(P_RESET)) {
    seth++;
    if (seth >= 24) seth = 0;
    delay(200);
  }
  if (digitalRead(P_SET)) {
    //salva ora scelta e passa ai minuti
    rtc.adjust(DateTime(now.year(), now.month(), now.day(), seth, now.minute(), now.second()));
    stato1 = 2;
    FIRST = true;
    delay(200);
  }
}

int setm;
void setMinute() {
  if (FIRST) {
    lcd.clear();
    now = rtc.now();
    setm = now.minute();
    lcd.setCursor(0, 0);
    lcd.print("Imposta minuti");
    FIRST = false;
  }
  lcd.setCursor(0, 1);
  sprintf(str, "%02d", setm);
  lcd.print(str);

  if (digitalRead(P_RESET)) {
    setm++;
    if (setm >= 60) setm = 0;
    delay(200);
  }
  if (digitalRead(P_SET)) {
    //salva min scelta e passa ai sec
    rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), setm, now.second()));
    stato1 = 3;
    delay(200);
    FIRST = true;
  }
}

int sets = 0;

void setSecond() {
  if (FIRST) {
    lcd.clear();
    now = rtc.now();
    sets = now.second();
    lcd.setCursor(0, 0);
    lcd.print("Imposta sec.");
    FIRST = false;
  }
  lcd.setCursor(0, 1);
  sprintf(str, "%02d", sets);
  lcd.print(str);

  if (digitalRead(P_RESET)) {
    sets++;
    if (sets >= 60) sets = 0;
    delay(200);
  }
  if (digitalRead(P_SET)) {
    //salva sec scelta e passa ai minuti
    rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), sets));
    stato1 = 4;
    delay(200);
    FIRST = true;
  }
}

int sety = 0;

void setyear() {
  if (FIRST) {
    lcd.clear();
    now = rtc.now();
    sety = now.year();
    lcd.setCursor(0, 0);
    lcd.print("Imposta anno");
    FIRST = false;
  }
  lcd.setCursor(0, 1);
  sprintf(str, "%02d", sety);
  lcd.print(str);

  if (digitalRead(P_RESET)) {
    sety++;
    if (sety >= 9999) sety = 0;
    delay(200);
  }
  if (digitalRead(P_SET)) {
    //salva sec scelta e passa ai minuti
    rtc.adjust(DateTime(sety, now.month(), now.day(), now.hour(), now.minute(), now.second()));
    stato1 = 5;
    delay(200);
    FIRST = true;
  }
}

int setmo = 0;

void setmonth() {
  if (FIRST) {
    lcd.clear();
    now = rtc.now();
    setmo = now.month();
    lcd.setCursor(0, 0);
    lcd.print("Imposta mese");
    FIRST = false;
  }
  lcd.setCursor(0, 1);
  sprintf(str, "%02d", setmo);
  lcd.print(str);

  if (digitalRead(P_RESET)) {
    setmo++;
    if (setmo >= 12) setmo = 0;
    delay(200);
  }
  if (digitalRead(P_SET)) {
    //salva sec scelta e passa ai minuti
    rtc.adjust(DateTime(now.year(), setmo, now.day(), now.hour(), now.minute(), now.second()));
    stato1 = 6;
    delay(200);
    FIRST = true;
  }
}

int setd = 0;

void setday() {
  if (FIRST) {
    lcd.clear();
    now = rtc.now();
    setd = now.day();
    lcd.setCursor(0, 0);
    lcd.print("Imposta giorno");
    FIRST = false;
  }
  lcd.setCursor(0, 1);
  sprintf(str, "%02d", setd);
  lcd.print(str);

  if (digitalRead(P_RESET)) {
    setd++;
    if (setd >= 32) setd = 0;
    delay(200);
  }
  if (digitalRead(P_SET)) {
    //salva sec scelta e passa ai minuti
    rtc.adjust(DateTime(now.year(), now.month(), setd, now.hour(), now.minute(), now.second()));
    stato1 = 0;
    delay(200);
    FIRST = true;
  }
}
aaa
21/03 10:49
nightwolf
ho provato a disabilitare timer2, per vedere se il tutto funzionasse, in parte si, soltanto che nel mio programma il livello del volume impazzisce, e si alza e abbassa senza nessun controllo. molto probabilmente perchè non riceve più i singoli byte ma una stringa?
aaa
21/03 16:21
Carlo
Certo, il codice del volume deve filtrare i dati ricevuti.

Riguardando il tuo codice, semplificherei ulteriormente, perché mi sembra vantaggioso inviare i dati nella seriale in un colpo solo, gli identificativi non servono più e i valori li identifichi in base alla posizione (già accennato), ho scritto un esempio in C che ti dovrebbe chiarire il concetto, inoltre puoi provare il codice su: onlinegdb.com/…

#include <stdio.h>

void bussola(char *outBussola)
{
    float headingDegrees = 320.5; // gradi di esempio tu li prenderai dal magnetometro
    sprintf(outBussola, "%.2f", headingDegrees); // converte in stringa con 2 cifre decimali
}

void loop() {
    char outBussola[8]; // conterrà la stringa creata in bussola()
    bussola(outBussola); // richiama la routine che legge i gradi
    
    char outBuf[20]; // spazio per la stringa d'uscita
    int val = 10; // volume a 10, tu lo prenderai dal potenziometro
    
    sprintf(outBuf, "%s;%d", outBussola, val); // concatena i due valori separati da puntovirgola
    
    printf("%s\n", outBuf); // check stringa da inviare
    //Serial.println(outBuf); // tu invece invii alla seriale
}

int main()
{
    loop(); // richiama la routine una volta, tu tutte le volte che vuoi
    return 0;
}


in questo modo invii:

320.50;10

in VB tutto si semplifica e un timer è sufficiente:
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 vanno i gradi bussola e in valoriDivisi(1) ci va il volume
    If valoriDivisi(0) = "E" Then
           lblgradi.Text = "errore"
           ' in valoriDivisi(1) ' il tipo d'errore da mostrare dove vuoi
    else
           ' Il primo dato è riferito ai gradi della bussola
            valoriDivisi(0) = valoriDivisi(0).Replace(".", ",") ' se ci fosse il punto decimale viene sostituito con la virgola decimale
            avanzamento = CInt(valoriDivisi(0))
            Label1.Text = avanzamento.ToString("000°")
            PictureBox1.Invalidate() ' scatena il paint

           ' Il dato in: valoriDivisi(1), è riferito al volume e è una stringa

            media_pleyer.lb_volume.Text = valoriDivisi(1) + "%"
            media_pleyer.Volume_control1.value = valoriDivisi(1)
            lb_volume.Text = valoriDivisi(1) + "%"
            Volume_control1.value = valoriDivisi(1)
            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
    End If       
End Sub


anche la function va modificata:

Function RiceviDati() As String
    Dim Ricevuti As String
    Try
        Ricevuti = SerialPort1.ReadExisting
        If Ricevuti = Nothing Then
            Return "E;null" ' ritorna con la E
        else
            Return Ricevuti
        End If
    Catch ex As Exception      
        Return "E;" & ex.Message ' ritorna con la E
    End Try
End Function


Naturalmente non ho provato nulla, se c'è qualche svista perdonami.
Ultima modifica effettuata da Carlo 21/03 21:52
in programmazione tutto è permesso
23/03 0:51
nightwolf
buonasera a tutti, purtroppo dal tuo esmpio non ho capito quasi niente, o per lo meno, dovrei stare a modificare anche il codice di arduino, quando adesso funziona bene su quello che ci siamo detti prima, ho scritto un codice facendo la prova nel realizzare un monitor seriale per vedere se visualbasic ricevesse ciò che arduino invia, e dal programma tutto funziona, adesso, tornando al discorso di prima di splkittare le varie stringhe che arrivano, è fattibile, e posizionarle nelle rispettive funzioni, quali voume e lbldirezione? questo è il codice del monitor seriale, fatto alla ben meglio senza stare a modificare nomi o altro. Da qui si può pensare di fare i, tutto spiegato prima, scusa ancora ma star a modificare ancora il codice di arduino è un impresa.
Imports System.IO.Ports
Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ComboBox1.Items.AddRange(IO.Ports.SerialPort.GetPortNames)
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click  //pulsante x ricaricare
        ComboBox1.Items.Clear()
        ComboBox1.Items.AddRange(IO.Ports.SerialPort.GetPortNames)
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click   //apri la connessione
        If ComboBox1.Text <> "" Then  
            Try
                SerialPort1.Encoding = System.Text.Encoding.Default
                SerialPort1.PortName = ComboBox1.Text
                SerialPort1.Open()
                Timer1.Start()
            Catch ex As Exception
                MsgBox("errore:" & ex.Message, MsgBoxStyle.Critical)

            End Try
        End If
    End Sub

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click  //chiudi la connessione
        SerialPort1.Close()
        Timer1.Stop()
        TextBox1.Text = ""

    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 Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        Dim str As String
        str = RiceviDati()
        TextBox1.Text += str

    End Sub

    Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
        TextBox1.Select(TextBox1.TextLength, 0)
        TextBox1.ScrollToCaret()
    End Sub
End Class

vi chiedo se da qui è mpossibile splittare i vari valori che arrivano dalla seriale che in questo momento sono
B:"coordinate" 000.00
P:"valore potenziometro" da 0 a 100
grazie mille
Ultima modifica effettuata da nightwolf 23/03 0:54
aaa
23/03 7:46
Carlo
Si, tutto codice già postato, hai cambiato solo il puntoevirgola con i duepunti, riepiloghiamo:
riposto la function ma con i duepunti
Function RiceviDati() As String
        Dim ricevuti As String
        Try
            ricevuti = SerialPort1.ReadExisting

            If ricevuti = Nothing Then
                return "N:null" ' duepunti al posto del puntovirgola
            else
                Return ricevuti
            End If
 
        Catch ex As Exception
            Return "E:" & ex.Message ' duepunti al posto del puntovirgola
        End Try
End Function


il timer
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    Dim str As String
    str = RiceviDati()
    TextBox1.Text += str ' tuo monitor

    Dim valoriDivisi() As String ' matrice senza dimensione
    valoriDivisi = str.Split(":") ' duepunti separa le stringhe: in valoriDivisi(0) ci va il codice identificativo (B = gradi bussola, P = potenziometro, 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
      ' ******* il codice per far funzionare la bussola, togli i rem quando inseriscie nel definitivo *******
      '  avanzamento = CInt(valoriDivisi(1))
      '  lblgradi.Text = avanzamento.ToString("000°")
      '  Pcboxbussola.Invalidate() ' scatena il paint
    End If

    If valoriDivisi(0) = "P" Then
       ' Il dato in: valoriDivisi(1), è riferito al volume e è una stringa
       ' ******* il codice per far funzionare il volume, togli i rem quando inseriscie nel definitivo *******
       ' media_pleyer.lb_volume.Text = valoriDivisi(1) + "%"
       ' media_pleyer.Volume_control1.value = valoriDivisi(1)
       ' lb_volume.Text = valoriDivisi(1) + "%"
       ' Volume_control1.value = valoriDivisi(1)
       ' 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
    End If
 
    ' possibili usi degli errori ritornati se ometti li ignori
    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


un timer solo....

Ho copiato incollato e corretto, se ci sono sviste scusa.

Mi chiedo, cosa ti ha impedito di farlo da solo? Cosa non avevi capito? Per favore dimmelo. :yup:
Ultima modifica effettuata da Carlo 23/03 7:56
in programmazione tutto è permesso
23/03 8:57
Carlo
Controlla sopra ho risposto alla tua domanda, ora se hai tempo se puoi e se vuoi prova questo codice in arduino e controlla se invia i dati: gradi;volume 000.00;100

#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>
     
// CONFIGURAZIONE
const byte P_LED = 9;
const byte P_SET = 6;
const byte P_RESET = 7;
const byte P_RELE_APRE = 10;    //relè x sbloccare porta
const byte P_RELE_BLOCCA = 11;  //rele x bloccare porta
     
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);  //identifiacativo magnetometro
     
LiquidCrystal_I2C lcd(0x27, 16, 2);  //display lcd x la visualizzazione dell orario
     
RTC_DS3231 rtc;
DateTime now;
     
char str[3];
int stato1 = 0;
int val = 0;
     
int val0 = 0;
     
// Buffer per la composizione delle stringhe da inviare via seriale
char outBuf[20];
     
void setup() {
      Wire.begin();
      Serial.begin(9600);
     
      lcd.backlight();
      lcd.init();
     
      //pulsanti set e reset
      pinMode(P_SET, INPUT);
      pinMode(P_RESET, INPUT);
      pinMode(P_LED, OUTPUT);
      pinMode(P_RELE_APRE, OUTPUT);
      pinMode(P_RELE_BLOCCA, OUTPUT);
      digitalWrite(P_RELE_APRE, HIGH);
      digitalWrite(P_RELE_BLOCCA, HIGH);
     
      if (!rtc.begin()) {  //inizializzo l rtc
        Serial.println("Couldn't find RTC");
        while (true)
          ;
      }
     
      if (!rtc.lostPower()) {
        //Serial.println("RTC is NOT running, let's set the time!");
        rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
      }
      if (!mag.begin())  //inizializzo il magnetometro
      {
        /* There was a problem detecting the HMC5883 ... check your connections */
        Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
        while (1)
          ;
      }
}
     
void loop() {
      MostraOra();
      char outBussola[8]; // conterrà la stringa creata in bussola()
      bussola(outBussola); // richiama la routine che legge i gradi
      if (Serial.available()) {
        // Gestione comandi da VB
        // Per ora leggo solo un singolo carattere per volta
        char comando = Serial.read();
        switch (comando) {
          case 'A':
            digitalWrite(P_RELE_APRE, LOW);
            delay(100);  // attivo o disattivo i rele in base al comando ricevuto da visual basic
            digitalWrite(P_RELE_APRE, HIGH);
            break;
          case 'O':
            digitalWrite(P_RELE_BLOCCA, LOW);
            delay(100);
            digitalWrite(P_RELE_BLOCCA, HIGH);
            break;
          default:
            // Ignoro qualsiasi altro carattere
            break;
        }
      }
      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);  // visualbasic cosi regolerà il volume del player
        
      sprintf(outBuf, "%s;%d", outBussola, val); // concatena i due valori separati da puntovirgola
      Serial.println(outBuf); // invii alla seriale
     
      delay(300); // aggiustare valore per migliori prestazioni tra 50 e 500
}
     
void bussola(char *outBussola) {  //evento bussola per indicare i gradi del magnetometro,
      sensors_event_t event;
      mag.getEvent(&event);
      float heading = atan2(event.magnetic.y, event.magnetic.x);
      float declinationAngle = 0.06;
      heading += declinationAngle;
      if (heading < 0) {
        heading += 2 * PI;
      }
      if (heading > 2 * PI) {
        heading -= 2 * PI;
      }
      float headingDegrees = heading * 180 / M_PI;
      sprintf(outBussola, "%.2f", headingDegrees); // converte in stringa con 2 cifre decimali
      // Serial.println(outBuf); // l'invio avverrà su loop()
      // delay(500); // non serve se non si scrive sulla seriale
}
     
void MostraOra() {
      switch (stato1) {
        case 0:
          displayTime();
          break;
        case 1:
          setHour();
          break;
        case 2:
          setMinute();
          break;
        case 3:
          setSecond();
          break;
        case 4:
          setyear();
          break;
        case 5:
          setmonth();
          break;
        case 6:
          setday();
          break;
      }
}
     
     
    unsigned long t1, dt1;
    bool FIRST = true;
     
void displayTime() {
      if (FIRST) {
        lcd.clear();
        t1 = millis();
        FIRST = false;
      }
     
      dt1 = millis() - t1;
      if (dt1 > 1000) {
        now = rtc.now();
        lcd.setCursor(4, 1);
     
        sprintf(str, "%02d", now.hour());
        lcd.print(str);
        lcd.print(':');
        sprintf(str, "%02d", now.minute());
        lcd.print(str);
        lcd.print(':');
        sprintf(str, "%02d", now.second());
        lcd.print(str);
     
        lcd.setCursor(3, 0);
     
        sprintf(str, "%02d", now.day());
        lcd.print(str);
        lcd.print('/');
        sprintf(str, "%02d", now.month());
        lcd.print(str);
        lcd.print('/');
        sprintf(str, "%02d", now.year());
        lcd.print(str);
     
        t1 = millis();
      }
     
      if (digitalRead(P_SET)) {
        //imposta ora
        stato1 = 1;
        delay(300);
        FIRST = true;
      }
}
     
    int seth = 0;
     
void setHour() {
      if (FIRST) {
        lcd.clear();
        now = rtc.now();
        seth = now.hour();
        lcd.setCursor(0, 0);
        lcd.print("Imposta ora");
        FIRST = false;
      }
      lcd.setCursor(0, 1);
      sprintf(str, "%02d", seth);
      lcd.print(str);
     
      if (digitalRead(P_RESET)) {
        seth++;
        if (seth >= 24) seth = 0;
        delay(200);
      }
      if (digitalRead(P_SET)) {
        //salva ora scelta e passa ai minuti
        rtc.adjust(DateTime(now.year(), now.month(), now.day(), seth, now.minute(), now.second()));
        stato1 = 2;
        FIRST = true;
        delay(200);
      }
}
     
    int setm;
void setMinute() {
      if (FIRST) {
        lcd.clear();
        now = rtc.now();
        setm = now.minute();
        lcd.setCursor(0, 0);
        lcd.print("Imposta minuti");
        FIRST = false;
      }
      lcd.setCursor(0, 1);
      sprintf(str, "%02d", setm);
      lcd.print(str);
     
      if (digitalRead(P_RESET)) {
        setm++;
        if (setm >= 60) setm = 0;
        delay(200);
      }
      if (digitalRead(P_SET)) {
        //salva min scelta e passa ai sec
        rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), setm, now.second()));
        stato1 = 3;
        delay(200);
        FIRST = true;
      }
}
     
    int sets = 0;
     
void setSecond() {
      if (FIRST) {
        lcd.clear();
        now = rtc.now();
        sets = now.second();
        lcd.setCursor(0, 0);
        lcd.print("Imposta sec.");
        FIRST = false;
      }
      lcd.setCursor(0, 1);
      sprintf(str, "%02d", sets);
      lcd.print(str);
     
      if (digitalRead(P_RESET)) {
        sets++;
        if (sets >= 60) sets = 0;
        delay(200);
      }
      if (digitalRead(P_SET)) {
        //salva sec scelta e passa ai minuti
        rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), sets));
        stato1 = 4;
        delay(200);
        FIRST = true;
      }
}
     
    int sety = 0;
     
void setyear() {
      if (FIRST) {
        lcd.clear();
        now = rtc.now();
        sety = now.year();
        lcd.setCursor(0, 0);
        lcd.print("Imposta anno");
        FIRST = false;
      }
      lcd.setCursor(0, 1);
      sprintf(str, "%02d", sety);
      lcd.print(str);
     
      if (digitalRead(P_RESET)) {
        sety++;
        if (sety >= 9999) sety = 0;
        delay(200);
      }
      if (digitalRead(P_SET)) {
        //salva sec scelta e passa ai minuti
        rtc.adjust(DateTime(sety, now.month(), now.day(), now.hour(), now.minute(), now.second()));
        stato1 = 5;
        delay(200);
        FIRST = true;
      }
}
     
    int setmo = 0;
     
void setmonth() {
      if (FIRST) {
        lcd.clear();
        now = rtc.now();
        setmo = now.month();
        lcd.setCursor(0, 0);
        lcd.print("Imposta mese");
        FIRST = false;
      }
      lcd.setCursor(0, 1);
      sprintf(str, "%02d", setmo);
      lcd.print(str);
     
      if (digitalRead(P_RESET)) {
        setmo++;
        if (setmo >= 12) setmo = 0;
        delay(200);
      }
      if (digitalRead(P_SET)) {
        //salva sec scelta e passa ai minuti
        rtc.adjust(DateTime(now.year(), setmo, now.day(), now.hour(), now.minute(), now.second()));
        stato1 = 6;
        delay(200);
        FIRST = true;
      }
}
     
    int setd = 0;
     
void setday() {
      if (FIRST) {
        lcd.clear();
        now = rtc.now();
        setd = now.day();
        lcd.setCursor(0, 0);
        lcd.print("Imposta giorno");
        FIRST = false;
      }
      lcd.setCursor(0, 1);
      sprintf(str, "%02d", setd);
      lcd.print(str);
     
      if (digitalRead(P_RESET)) {
        setd++;
        if (setd >= 32) setd = 0;
        delay(200);
      }
      if (digitalRead(P_SET)) {
        //salva sec scelta e passa ai minuti
        rtc.adjust(DateTime(now.year(), now.month(), setd, now.hour(), now.minute(), now.second()));
        stato1 = 0;
        delay(200);
        FIRST = true;
      }
}


Il codice è il tuo non sono entrato nel merito e non ho cambiato nulla, solo l'invio sulla seriale in un colpo solo.

Con un invio solo puoi ottimizzare il delay e far girare la bussola in modo più fluido riga 102.
Ultima modifica effettuata da Carlo 23/03 10:14
in programmazione tutto è permesso
23/03 13:17
nightwolf
ciao e grazie, il codice in vb.net adesso non si blocca più però non succede niente, non si muve la bussola ne tanto meno il volume, non mi nessun errore, mentre il codice in aurduino dalla seriale esce soltanto ? e i valori del potenziometro, nient altro.
ho fatto come mi hai spiegato ma non succede niente ho fatto anche un video dimostrativo e se riesco lo posto. cmq questo è il codice che mi hai spiegato.
 Function RiceviDati() As String
        Dim ricevuti As String
        Try
            ricevuti = SerialPort1.ReadExisting

            If ricevuti = Nothing Then
                Return "N:null" ' duepunti al posto del puntovirgola
            Else
                Return ricevuti
            End If

        Catch ex As Exception
            Return "E:" & ex.Message ' duepunti al posto del puntovirgola
        End Try
    End Function

    Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
        Dim str As String
        str = RiceviDati()
        TextBox1.Text += str ' tuo monitor

        Dim valoriDivisi() As String ' matrice senza dimensione
        valoriDivisi = str.Split(":") ' due punti separa le stringhe: in valoriDivisi(0) ci va il codice identificativo (B = gradi bussola, P = potenziometro, 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
            ' ******* il codice per far funzionare la bussola, togli i rem quando inseriscie nel definitivo *******
            avanzamento = CInt(valoriDivisi(1))
            lblgradi.Text = avanzamento.ToString("000°")
            Pcboxbussola.Invalidate() ' scatena il paint
        End If

        If valoriDivisi(0) = "P" Then
            ' Il dato in: valoriDivisi(1), è riferito al volume e è una stringa
            ' ******* il codice per far funzionare il volume, togli i rem quando inseriscie nel definitivo *******
            media_pleyer.lb_volume.Text = valoriDivisi(1) + "%"
            media_pleyer.Volume_control1.value = valoriDivisi(1)
            lb_volume.Text = valoriDivisi(1) + "%"
            Volume_control1.value = valoriDivisi(1)
            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
        End If

        ' possibili usi degli errori ritornati se ometti li ignori
        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

    Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
        TextBox1.Select(TextBox1.TextLength, 0)
        TextBox1.ScrollToCaret()
    End Sub

ho disabilitato timer1 per avere un solo timer.
aaa