Go Down

Topic: Libreria leggera per utilizzare un display (Read 1 time) previous topic - next topic

fabpolli

Non è tanto la lettura e elaborazione dei dati che devi limitare ma l'aggiornamento dello schermo al solo minimo indispensabile.
Se mett il codice sicuramente qualcuno potrà darti suggerimenti e aiuto

nocentini

#16
Aug 31, 2018, 04:38 pm Last Edit: Aug 31, 2018, 05:02 pm by nocentini
Code: [Select]

  read_mpu_6050_data();   
 //Subtract the offset values from the raw gyro values
  gyro_x -= gyro_x_cal;                                               
  gyro_y -= gyro_y_cal;                                               
  gyro_z -= gyro_z_cal;                                               
         
  //Gyro angle calculations . Note 0.0000611 = 1 / (250Hz x 65.5)
  angle_pitch += gyro_x * 0.0000611;                                   //Calculate the traveled pitch angle and add this to the angle_pitch variable
  angle_roll += gyro_y * 0.0000611;                                    //Calculate the traveled roll angle and add this to the angle_roll variable
  //0.000001066 = 0.0000611 * (3.142(PI) / 180degr) The Arduino sin function is in radians
  angle_pitch += angle_roll * sin(gyro_z * 0.000001066);               //If the IMU has yawed transfer the roll angle to the pitch angel
  angle_roll -= angle_pitch * sin(gyro_z * 0.000001066);               //If the IMU has yawed transfer the pitch angle to the roll angel
 
  //Accelerometer angle calculations
  acc_total_vector = sqrt((acc_x*acc_x)+(acc_y*acc_y)+(acc_z*acc_z));  //Calculate the total accelerometer vector
  //57.296 = 1 / (3.142 / 180) The Arduino asin function is in radians
  angle_pitch_acc = asin((float)acc_y/acc_total_vector)* 57.296;       //Calculate the pitch angle
  angle_roll_acc = asin((float)acc_x/acc_total_vector)* -57.296;       //Calculate the roll angle
 
  angle_pitch_acc -= 0.0;                                              //Accelerometer calibration value for pitch
  angle_roll_acc -= 0.0;                                               //Accelerometer calibration value for roll

  if(set_gyro_angles){                                                 //If the IMU is already started
    angle_pitch = angle_pitch * 0.9996 + angle_pitch_acc * 0.0004;     //Correct the drift of the gyro pitch angle with the accelerometer pitch angle
    angle_roll = angle_roll * 0.9996 + angle_roll_acc * 0.0004;        //Correct the drift of the gyro roll angle with the accelerometer roll angle
  }
  else{                                                                //At first start
    angle_pitch = angle_pitch_acc;                                     //Set the gyro pitch angle equal to the accelerometer pitch angle
    angle_roll = angle_roll_acc;                                       //Set the gyro roll angle equal to the accelerometer roll angle
    set_gyro_angles = true;                                            //Set the IMU started flag
  }
 
  //To dampen the pitch and roll angles a complementary filter is used
  angle_pitch_output = angle_pitch_output * 0.9 + angle_pitch * 0.1;   //Take 90% of the output pitch value and add 10% of the raw pitch value
  angle_roll_output = angle_roll_output * 0.9 + angle_roll * 0.1;      //Take 90% of the output roll value and add 10% of the raw roll value
   Serial.print(" | Angle  = "); Serial.println(angle_pitch_output);

      display.clearDisplay();  // cancello il buffer del display
      display.setFont(&FreeMonoBold9pt7b);  // seleziono il font
      display.setTextSize(1);  // seleziono le dimensioni del testo
      display.setCursor(10, 40);                       // setto il cursore a x=57 e y=27
      display.println(angle_pitch_output);// scrivo nel display l'angolo di incl
      display.display();

 while(micros() - loop_timer < 4000);                                 //Wait until the loop_timer reaches 4000us (250Hz) before starting the next loop
 loop_timer = micros();//Reset the loop timer
}



Sulimarco

Non ha senso aggiornare un display ogni 4mS, serve solo a sovraccaricare la cpu.

Usa millis() ed aggiorna il display ogni 100mS, cioe' 10 aggiornamenti al secondo: bastano e avanzano e la cpu e' molto piu' alleggerita.

Ciao
Marco

nocentini

Scusami ma io e l'istruzione millis() siamo due rette parallele, ho provato a usarlo molte volte ma senza successo..
Potresti farmi un esempio di come poterlo usare nel mio caso? Grazie in anticipo

paulus1969

comunque da una UNO ad una MEGA la potenza di calcolo non cambia...

oltretutto, se devi fare cose come:

Code: [Select]

angle_pitch += angle_roll * sin(gyro_z * 0.000001066);
angle_roll -= angle_pitch * sin(gyro_z * 0.000001066); 
acc_total_vector = sqrt((acc_x*acc_x)+(acc_y*acc_y)+(acc_z*acc_z));
...
angle_pitch_acc = asin((float)acc_y/acc_total_vector)* 57.296;
angle_roll_acc = asin((float)acc_x/acc_total_vector)* -57.296;     


io andrei su una Teensy 3.6 piuttosto che su una Mega


Patrick_M

* 0.000001066

infatti dal reference:
Floats have only 6-7 decimal digits of precision. That means the total number of digits, not the number to the right of the decimal point.

quindi quel numero sopra viene troncato in:
0.00000(1)
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

nocentini

Di che si tratta, io sono ignorante in materia

Patrick_M

#22
Sep 01, 2018, 12:53 pm Last Edit: Sep 01, 2018, 12:58 pm by Patrick_M
come dice il reference il tipo di variabili float (cioè con la virgola) su arduino hanno solo 6-7 decimali di precisione, ma conprendendo nei 6-7 anche le cifre prima della virgola, quindi nel calcolo che riporti nel tuo programma
Code: [Select]

angle_pitch += angle_roll * sin(gyro_z * 0.000001066);
angle_roll -= angle_pitch * sin(gyro_z * 0.000001066); 

gyro_z moltiplicato per 0.000001066 calcolando 6 cifre da come risultato zero, calcolandone 7 da 1 milionesimo. Le altre cifre (066) non vengono considerate
quindi se la precisione di calcolo è determinante per il corretto funzionamento.... devi cambiare piattaforma
inoltre questo tipo di calcoli (tra float) sono impegnativi anche come tempo di esecuzione
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

Sulimarco

Dichiara queste due variabli globali, prima del setup:

unsigned long Millis;
unsigned long PreviousDislayTime;

inizializza PreviousDisplayTime alla fine del setup in questo modo:

PreviousDisplayTime = millis();

quando scrivi sul display fai cosi:

Code: [Select]
  Millis = millis();
  if (Millis - PreviousDisplayTime) >= 100)
  {
      PreviousDisplayTime = Millis;
     
      display.clearDisplay();                          // cancello il buffer del display
      display.setFont(&FreeMonoBold9pt7b);  // seleziono il font
      display.setTextSize(1);                         // seleziono le dimensioni del testo
      display.setCursor(10, 40);                    // setto il cursore a x=57 e y=27
      display.println(angle_pitch_output);      // scrivo nel display l'angolo di incl
      display.display();
  } 



Ciao
Marco

nocentini

Okay grazie mille, ho testato il tutto e funziona alla perfezione

Sulimarco

Se scrivi solo quello sul display le istruzioni:



Code: [Select]
      display.setFont(&FreeMonoBold9pt7b);  // seleziono il font
      display.setTextSize(1);                         // seleziono le dimensioni del testo
      display.setCursor(10, 40);                    // setto il cursore a x=57 e y=27



puoi scriverle anche solo una volta nel setup.


Ciao
Marco

Sulimarco


@Patrik_M


0.000001066  e' rappresentato senza troncamenti dal formato Single precision floating point , quello usato da Arduino, ed in questo post e' spiegato il perche':


Wrong. Digits precision is counting across all(!) digits, starting with the first non-zero digit in the number:

First non-zero digit in number 0003.14159 is the digit "3", so there is one digit before and 5 digits after the decimal point = total of "six significant digits", and that's pretty much all which the 'float' type can provide in decimal number precision.
Decimal digits of precision


Ciao
Marco

gpb01

#27
Sep 01, 2018, 05:20 pm Last Edit: Sep 01, 2018, 05:21 pm by gpb01
>Sulimarco: ... chiarimemto necessario ed estremamente utile infatti, la classica frase che si trova nel "reference" :

Quote
Floats have only 6-7 decimal digits of precision. That means the total number of digits, not the number to the right of the decimal point. Unlike other platforms, where you can get more precision by using a double (e.g. up to 15 digits), on the Arduino, double is the same size as float.
... è estremamente fuorviante e sembra dire che, tra parte intera e parte decimale, comunque si hanno 6-7 digit.

In realtà questo, come hai specificato, è vero ha partire da primo digit NON zero !

Quindi, anche un numero tipo 0.0000000000123 viene correttamente memorizzato. :)

Bello anche il link, inserito in quella discussione, che porta alla pagina dove "giocare" con la precisione dei float ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

gpb01

io andrei su una Teensy 3.6 piuttosto che su una Mega
Di che si tratta, io sono ignorante in materia
Mah ... senza scomodare le Teensy, probabilmente basterebbe, restando in ambito totalmente Arduino, o una Arduino M0 o una delle varie schede della serie MKRxxxx, tutte basate su MCU ARM a 32 bit.

Guglielmo
Search is Your friend ... or I am Your enemy !

Patrick_M

>Sulimarco: ... chiarimemto necessario ed estremamente utile infatti, la classica frase che si trova nel "reference" :
... è estremamente fuorviante e sembra dire che, tra parte intera e parte decimale, comunque si hanno 6-7 digit.

In realtà questo, come hai specificato, è vero ha partire da primo digit NON zero !

Quindi, anche un numero tipo 0.0000000000123 viene correttamente memorizzato. :)

Bello anche il link, inserito in quella discussione, che porta alla pagina dove "giocare" con la precisione dei float ;)

Guglielmo
verificato....
letto
capito
grazie
:)
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

Go Up