Aiuto per Snellire il codice - RISOLTO

Salve a tutti,
come da titolo ho dei problemi a far girare correttamente uno sketch su Mega2650.
Il progetto in questione prevede l'uso del sensore MPU6050 abbinato ad un servo.
Il servo funziona da indicatore analogico ad ago, mentre del sensore MPU6050 ho necessità di estrapolare il solo valore di accelerazione G su asse X.
Tutto sembrerebbe funzionare, (il codice è basato al 99% su quello d'esempio MPU6050) ma dopo qualche secondo il sistema sembra andare in tilt, come ci fossero troppi dati da gestire (o forse valori fuori scala)... e si resetta.


#include "Wire.h"
#include <MPU6050_light.h>
#include <Servo.h>

MPU6050 mpu(Wire);

long timer = 0;
int val;
int pos = 0; 
Servo myservo;   


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

  byte status = mpu.begin();
  Serial.print(F("MPU6050 status: "));
  Serial.println(status);
  while(status!=0){ } // Ferma se MPU6050 non è connesso
  
  Serial.println(F("Calculating offsets, do not move MPU6050"));
  delay(1000);
  mpu.calcOffsets(true,true);             // Avvio Giroscopio e Accelerometro
  Serial.println("Done!\n");

     myservo.attach(9);                   // Servo su Pin 9
   for (pos = 0; pos <= 170; pos += 1) {  // Da 0° a 170° *** TEST SERVO ***
    // in steps of 1 degree
    myservo.write(pos);                  
    delay(15);                            // Tempo tra uno scatto e l'altro
  }  
   for (pos = 170; pos >= 90; pos -= 1) { // Da 170° a 90°
    myservo.write(pos);                   
    delay(15);                            // Tempo tra uno scatto e l'altro 
  }
}

void loop() {
  mpu.update();

  if(millis() - timer > 250){                                           // Stampa valori ogni 1/4 di secondo
    Serial.print(F("TEMPERATURE: "));Serial.println(mpu.getTemp());     // Temperatura
    Serial.print(F("ACCELERO  X: "));Serial.print(mpu.getAccX());   // Acc asse X   *** MI SERVE SOLO QUESTO ***
    Serial.print("\tY: ");Serial.print(mpu.getAccY());                  // Acc asse Y
    Serial.print("\tZ: ");Serial.println(mpu.getAccZ());                // Acc asse Z
 
    Serial.print(F("GYRO      X: "));Serial.print(mpu.getGyroX());      // Giroscopio X
    Serial.print("\tY: ");Serial.print(mpu.getGyroY());                 // Giroscopio Y
    Serial.print("\tZ: ");Serial.println(mpu.getGyroZ());               // Giroscopio Z
  
    Serial.print(F("ACC ANGLE X: "));Serial.print(mpu.getAccAngleX());   // Acc Angolare X
    Serial.print("\tY: ");Serial.println(mpu.getAccAngleY());            // Acc Angolare Y
    
    Serial.print(F("ANGLE     X: "));Serial.print(mpu.getAngleX());      // Angolo X
    Serial.print("\tY: ");Serial.print(mpu.getAngleY());                 // Angolo y
    Serial.print("\tZ: ");Serial.println(mpu.getAngleZ());               // Angolo Z

    Serial.println(F("=====================================================\n"));

          val = (mpu.getAccX());                      // Acquisizione dati Acc X      
          val = map(val, -4, 4, 170, 10);          // Map dei valori Acc X compresi tra -4 e +4  
          myservo.write(val);                          // Trasmissione valori al Servo
    
    timer = millis();
  }
}

Premesso che non ho provato il tuo codice (anche perché non ho un MPU6050), ma intanto anche se non penso che possa dare problemi dopo "qualche secondo", direi che per i valori di millis() bisogna usare "unsigned long" non solo "long", io lo correggerei per sicurezza.
Questa cosa è tra l'altro presente anche nel codice di esempio della libreria (così come l'#include "Wire.h" non è necessario perché già lo fa la MPU6050.h).

Per quanto riguarda i valori "fuori scala" invece quando questo accade, sulla seriale quali valori compaiono per le letture?

E comunque se a te interessa solo mpu.getAccX() leggi una volta e scrivi solo quello, togli tutto quello che non ti serve. Inoltre, non so se questo sia voluto, ma la conversione in int del float restituito da mpu.getAccX() ti tronca tutti i decimali, quindi se poi fai la map() da -4 a 4 avresti solo 9 possibili valori (-4, -3, -2, -1, 9, 1, 2, 3, 4) che diventano solo 9 valori tra 170 e 10 e quindi solo 9 posizioni fisse.
Quindi direi di provare una cosa del genere:

  if(millis() - timer > 250){                                           // Stampa valori ogni 1/4 di secondo
    // Leggo il valore e lo converto in decimi di accelerazione che quindi 
    // andrà tra -40 e +40, ossia 81 intervalli di valori
    val = mpu.getAccX()* 10.0; 
    val = constrain(val, -40, 40); // Mi assicuro che i valori siano entro il range
    Serial.print("X: ");Serial.print(mpu.getAccX());
    Serial.print(" = "); Serial.print(val);
    val = map(val, -40, 40, 170, 10);
    Serial.print(" ("); Serial.print(val); Serial.println(")");
    myservo.write(val);                          // Trasmissione valori al Servo
    timer = millis();
  }

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.