Coordinate con magnetometro

buonasera a tutti, ho ritoccato ancora una volta il codice di arduino perchè come era scritto mi dava problemi con visual basic, potete spiegarmi perchè al posto dei gradi della bussola sulla seriale mi compare un ?
la stringa dovrebbe essere gradi bussola;valore potenziometro
es: 320.20;28
questo è il codice modificato

#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;
      }
}

Tu fai questo:

      float headingDegrees = heading * 180 / M_PI;
      sprintf(outBussola, "%.2f", headingDegrees); // converte in stringa con 2 cifre decimali

Quale parte di "Non puoi usare su Arduino la sprintf() per i float " non era chiara?
Dato che vuoi il valore intero, usa un intero e quindi "outBussola" conterrà la stringa corrispondente:

      int headingDegrees = heading * 180 / M_PI;
      sprintf(outBussola, "%d", headingDegrees); // converte in stringa

Ma fare questo è inutile, ti basterebbe rendere globale la variabile intera "headingDegrees" spostandola fuori dalla funzione, e poi la usi qui:

      sprintf(outBuf, "%d;%d", headingDegrees, val); // concatena i due valori separati da puntovirgola

Poi non ha neanche senso che tu definisca "outBussola" locale dentro al loop per poi passarla alla funzione "bussola(outBussola)" tramite puntatore. Definiscila globale (sposta "char outBussola[8];" fuori dal loop) e puoi usarla nella funzione senza dover passare nulla.
Avrei anche altre modifiche da suggerirti, ma per ora è sufficiente così. :wink:

grazie mille non mi ero accorto,
ho sistemato così

float headingDegrees = heading * 180 / M_PI;
      dtostrf(headingDegrees, 6, 2, outBussola); 

Ok! Comunque avevi detto che i decimali non ti interessavano.. :wink:

si lo so, ma ho provato a modificare mettendo int, ma mi dava errore e allora ho lasciato perdere

Se il valore è intero, nella sprintf() non puoi usare il formato "%.2f", devi usare "%d".
E come modificare il tutto in int te l'ho scritto.

ho spostato la variabile

char outBussola[8];

fuori dal loop
ho provato a mettere

  sprintf(outBuf, "%d;%d", headingDegrees, val);

ma mi da errore cosi ho sostiruito la scritta

sprintf(outBuf, "%s;%d", outBussola, val);

ma ci sono sempre i decimali, mentre se metto

sprintf(outBuf, "%d;%d", outBussola, val);

dalla seriale esce sempre
551;valore del potenziometro, ma il 551 non si muove e poi è fuori range, che è sto 551?

Io leggo 3.44;50 dove 3,44 è il valore di headingDegrees.

Si, ma se sostituisco %s;%d con %d;%d sulla seriale esce 551

outBussola è una stringa, cioè caratteri, mentre %d significa decimale!

Perdonami, ma che sono queste prove "alla cieca"? O cerchi di capire cosa fanno certe istruzioni e funzioni, oppure non puoi pensare di far andare un motore mettendo il carburatore al posto della batteria...
Leggi bene il mio post #43, poi per le modifiche che ti consigliavo erano queste, che devi provare:

...
// Lettura corrente del magnetometro 
// (spostata qui come variabile globale intera)
int headingDegrees;
     
void setup() {
  Wire.begin();
...

void loop() {
  MostraOra();
  //char outBussola[8];
  bussola(); // richiama la routine che legge i gradi
...
  sprintf(outBuf, "%d;%d", headingDegrees, 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() {  //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;
  }
  headingDegrees = heading * 180 / M_PI;
}
...

grazie mille, ma facevo confusione sulla variabile da spostare fuori il loop, dopo avevo capito che era headingdegrees, ma adesso tra vb e arduino ho una confusione che neanche immagini.
grazie ancora, adesso sto codice non si ritocca più, adesso è il far funzionare vb con la ricezione della seriale.

piccola domanda, perche sulla seriale il valore del potenziometro si azzera anzicchè mantenere il valore della posizione?
questo è il codice

#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];
int headingDegrees;
     
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];
      bussola(); // 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, "%d;%d", headingDegrees, val); // concatena i due valori separati da puntovirgola
  Serial.println(outBuf); // invii alla seriale
     
      delay(1000); // aggiustare valore per migliori prestazioni tra 50 e 500
}
     
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;
      }
      headingDegrees = heading * 180 / M_PI;
}
     
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;
      }
}

non riesco a trovare dove azzera il valore del potenziometro

Spiega meglio cosa intendi: parli del simulatore o del circuito reale? E si azzera (ossia sulla seriale leggi uno zero), ma quando, alla partenza o mentre gira il codice (ed in tal caso è una cosa "random" o in qualche modo regolare)?

Mi spego meglio, carico lo sketch su arduino e dalla seriale ho ad esempio
300;0
Se aziono il potenziometro questo mi fa vedere la posizione attuale ad esempio
300;50
Dopo se non lo tocco più il potenziometro ritorna a zero
300;0 e cosi lo fa sempre, mi fa vedere il valore solo se lo aziono, ma cosi facendo in vb il volume mi da il valore appena lo tocco ma dopo leggendo zero non si sente niente.
Non so se questo avviene anche al simulatore, perche si, funziona il volume ma il magnetometro non da valori o meglio non so co.e farlo muovere e leggere i gradi


301;0
300;70
301;75
301;0
301;0

Credo che sia perché tu qui definisci una variabile locale "val" che però ha lo stesso nome di quella che hai già messo globale:

...
int val = 0;
...
      int val = 0;
      // Somma tre letture consecutive
      for (int i = 0; i < 3; ++i)
          val += analogRead(A0);

Prova a togliere "int" per usare sempre e solo quella globale:

      val = 0;
      // Somma tre letture consecutive
      for (int i = 0; i < 3; ++i)
          val += analogRead(A0);