[TUTORIAL]Accelerometri e Arduino – Ecco quale scegliere

Tra i dispositivi che possiamo connettere a Arduino, uno che desta sicuramente maggior curiosità è sicuramente l’accelerometro.
Gli accelerometri si trovano ormai a cifre relativamente basse e la scelta si riconduce (per fortuna!) a due principali versioni.
La prima si basa sull’integrato ADXL335, la seconda invece sull’integrato MPU-6050.

LE DIFFERENZE

La principale differenza tra i due accelerometri è nell’uscita. ADXL335 dispone di un’uscita analogica per ogni asse, mentre l’MPU6050 comunica con Arduino attraverso il protocollo I2C. C’è inoltre da dire che l’MPU6050 svolge la funzione di Giroscopio e anche di lettura della temperatura (potrebbe non servirvi a nulla ma c’è).

Di seguito riporto i datasheet per chi volesse saperne di più:

MPU-6050

ADXL335

QUALE SCEGLIERE

Iniziamo con il dire che l’MPU6050 per funzionare ha necessità di meno pin. In particolare utilizza un pin in meno dal momento che per la comunicazione I2C ne sono necessari due, mentre l’ADXL335 dispone di un pin di uscita di segnale per ogni asse.

L’MPU6050 offre anche un range impostabile di sensibilità che va da 2g a 16g, mentre l’ADXL335 ha solo due livelli configurabili attraverso un ingresso digitale (3g o 6g).

Ecco un elenco riassuntivo delle caratteristiche dell’MPU6050

  • 3-Assi
  • Chip con Convertitore AD a 16 bit Integrato
  • Range di misura giroscopio: ±250, 500, 1000 e 2000°/s
  • Range di misura accelerometro: +2, +4 , +8 , +16 g
  • Interfaccia: I²C
  • Alimentazione: da 3 V a 5

Ecco un elenco riassuntivo delle caratteristiche dell’ADXL335

  • 3-Assi
  • Low power – 350 μA (typical)
  • Range di misura accelerometro: +3, +6 g
  • Interfaccia: 3 uscita analogiche
  • Tensione di alimentazione 1.8 V da 3.6 V

Unico punto un cui l’MPU6050 probabilmente è peggiore, è che per leggere tutto le stream dei dati provenienti dal bus I2C è richiesto circa 1 ms, mentre per la lettura dei tre ingressi analogici corrispondenti alle tre uscite del ADXL335, sono necessari circa 300us.

 

Iscriviti al nostro canale YouTube per saperne di più! 🙂

ESEMPI DI CODICE

Utilizzando la libreria  MPU6050_tockn, uno degli esempi più efficaci, semplici e esaustivi che ho trovato è il seguente:

#include <MPU6050_tockn.h>
#include <Wire.h>

MPU6050 mpu6050(Wire);

long timer = 0;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  mpu6050.begin();
  mpu6050.calcGyroOffsets(true);
}

void loop() {
  mpu6050.update();

  if(millis() - timer > 1000){
    
    Serial.println("=======================================================");
    Serial.print("temp : ");Serial.println(mpu6050.getTemp());
    Serial.print("accX : ");Serial.print(mpu6050.getAccX());
    Serial.print("\taccY : ");Serial.print(mpu6050.getAccY());
    Serial.print("\taccZ : ");Serial.println(mpu6050.getAccZ());
  
    Serial.print("gyroX : ");Serial.print(mpu6050.getGyroX());
    Serial.print("\tgyroY : ");Serial.print(mpu6050.getGyroY());
    Serial.print("\tgyroZ : ");Serial.println(mpu6050.getGyroZ());
  
    Serial.print("accAngleX : ");Serial.print(mpu6050.getAccAngleX());
    Serial.print("\taccAngleY : ");Serial.println(mpu6050.getAccAngleY());
  
    Serial.print("gyroAngleX : ");Serial.print(mpu6050.getGyroAngleX());
    Serial.print("\tgyroAngleY : ");Serial.print(mpu6050.getGyroAngleY());
    Serial.print("\tgyroAngleZ : ");Serial.println(mpu6050.getGyroAngleZ());
    
    Serial.print("angleX : ");Serial.print(mpu6050.getAngleX());
    Serial.print("\tangleY : ");Serial.print(mpu6050.getAngleY());
    Serial.print("\tangleZ : ");Serial.println(mpu6050.getAngleZ());
    Serial.println("=======================================================\n");
    timer = millis();
    
  }

}

L’output seriale del programma è il seguente, a intervalli regolari viene inviato un prospetto dello stato di tutte le grandezze del sensore.

=================
0.02
0.98
calculate gyro offsets
DO NOT MOVE A MPU6050…..Done!!!
X : -52.59
Y : -0.47
Z : -0.47
Program will start after 3 seconds=======================================================
temp : 30.91
accX : -0.05 accY : 0.86 accZ : -0.47
gyroX : 0.06 gyroY : 0.07 gyroZ : 0.20
accAngleX : 116.33 accAngleY : 6.70
gyroAngleX : 118.08 gyroAngleY : 7.42 gyroAngleZ : 2.48
angleX : 118.04 angleY : 7.41 angleZ : 2.48
=======================================================

=======================================================
temp : 30.76
accX : -0.04 accY : 0.87 accZ : -0.47
gyroX : 0.54 gyroY : -0.16 gyroZ : -0.24
accAngleX : 116.20 accAngleY : 6.46
gyroAngleX : 118.06 gyroAngleY : 7.41 gyroAngleZ : 2.56
angleX : 118.02 angleY : 7.39 angleZ : 2.56
=======================================================

=======================================================
temp : 30.81
accX : -0.05 accY : 0.87 accZ : -0.46
gyroX : 0.15 gyroY : -0.16 gyroZ : 0.17
accAngleX : 115.46 accAngleY : 7.07
gyroAngleX : 117.95 gyroAngleY : 7.37 gyroAngleZ : 2.48
angleX : 117.90 angleY : 7.36 angleZ : 2.48
=======================================================

Per quanto riguarda invece l’ADXL335, utilizzando la libreria ADXL335, l’esempio più semplice che ho trovato dove viene letta l’accelerazione è il seguente:

#include "ADXL335.h"

ADXL335 accelerometer;
void setup()
{
	Serial.begin(9600);
	accelerometer.begin();
}
void loop()
{
	int x,y,z;
	accelerometer.getXYZ(&x,&y,&z);
	Serial.println("value of X/Y/Z: ");
	Serial.println(x);
	Serial.println(y);
	Serial.println(z);
	float ax,ay,az;
	accelerometer.getAcceleration(&ax,&ay,&az);
	Serial.println("accleration of X/Y/Z: ");
	Serial.print(ax);
	Serial.println(" g");
	Serial.print(ay);
	Serial.println(" g");
	Serial.print(az);
	Serial.println(" g");
	delay(500);
}

L’output seriale relativo a quest’esempio è il seguente:

value of X/Y/Z:
374
334
354
voltage:
1.75
1.69
1.68
accleration of X/Y/Z:
2.13 g
1.88 g
1.74 g
value of X/Y/Z:
335
319
329
voltage:
1.60
1.57
1.56
accleration of X/Y/Z:
1.53 g
1.39 g
1.25 g