samedi 17 janvier 2015

Accéléromètre MMA7455 et Raspberry Pi (python)

Il y a quelques semaines, j'avais utilisé mon accéléromètre MMA7455 avec un Arduino.  Grâce à une bibliothèque réalisée par Moritz Kemper, le processus s'était révélé relativement simple.

Pour le raspberry Pi, je n'ai pas trouvé de bibliothèque python spécifique au MMA7455.  Quelques articles m'ont servi de point de départ (en particulier celui-ci), mais j'ai dû apporter pas mal de modifications au script pour qu'il se comporte comme je le désirais.

1)  Activation du protocole I2C

D'abord, si ce n'est pas déjà fait, il faut activer l'I2C sur le Raspberry Pi.  Ça tombe bien:  j'ai justement publié un article à ce sujet.

2)  Branchements du breakout MMA7455

J'espère que votre accéléromètre MMA7455 se trouve sur un breakout facile à brancher, comme celui qui est représenté sur la photo ci-contre.  Sinon, il est possible de faire des soudures sur le minuscule circuit intégré (comme dans ce projet), mais il faut être diablement habile!

Comme pour tous les périphériques utilisant le protocole I2C, vous devez branchez la pin SDA ("serial data") de l'accéléromètre à la pin 3 (BOARD) / GPIO 2 (BCM) du Raspberry Pi, et la pin SCL ("serial clock") de l'accéléromètre à la pin 5 (BOARD) / GPIO 3 (BCM) du Raspberry Pi.


De plus, il faut alimenter notre accéléromètre en branchant sa pin VCC à une des pins de 3,3 V du Rasbperry Pi, et la pin GND de l'accéléromètre à une des pins GND du Raspberry Pi.

En principe, les périphérique I2C nécessitent une résistance de tirage entre SDA et 3,3 V, et une autre résistance de tirage entre SCL et 3,3 V, mais je n'ai pas eu besoin d'en mettre.



3)  Programme en python

Le script ci-dessous mesure les composantes x, y et z de l'accélération.  Puisque l'accéléromètre a été réglé à une résolution lui permettant de mesurer des valeurs étalées entre -2g et +2g, une accélération de -2g retourne une valeur brute de -127, une accélération nulle retourne 0, et une accélération de +2g retourne 127.

Attention:  l'accéléromètre ne fait aucune différence entre une accélération et la gravité:  si votre accéléromètre est immobile, la force gravitationnelle provoquera une mesure de 63, qui est la valeur qui correspond à 1g (alors que si votre accéléromètre est en chute libre, vous devriez mesurer une valeur de 0 sur tous les axes).

Donc, si votre accéléromètre immobile et horizontal, bien à plat sur une table, vous devriez mesurer une valeur de 0 selon x, 0 selon y et 63 selon z (à cause de la gravité).  Si ce n'est pas le cas, modifiez les valeurs des variables ajustx, ajusty et ajustz.

Le script applique également le théorème de Pythagore afin d'afficher la grandeur de l'accélération totale.

De plus, il affiche l'inclinaison de l'accéléromètre:   l'angle en degrés que fait son axe des x par rapport à l'horizontale, l'angle que fait l'axe des y par rapport à l'horizontale, et l'angle que fait l'axe des z par rapport à la verticale.

#!/usr/bin/env python
# -*- coding: latin-1 -*-
'''
Accéléromètre MMA7455 branché à un Raspberry Pi.
C'est un périphérique I2C, donc on le branche à SCL et SDA, et s'assurer
que l'i2C a été préalablement paramétré sur le Raspbery Pi.
Pour plus d'infos:
http://electroniqueamateur.blogspot.com/2015/01/accelerometre-mma7455-et-raspberry-pi.html
'''
import smbus
import time
import os
import math
import RPi.GPIO as GPIO
# Valeurs à ajouter à chaque mesure pour calibrer votre MMA7455
# Ajustez ces valeurs pour que ça donne x = 0, y = 0 et z = 63 quand
# l'accéléromètre est immobile, à plat sur une table.
ajustx = 10; # car j'obtenais -10 à la place de 0
ajusty = 19; # car j'obtenais -19 à la place de 0
ajustz = -6; # car j'obtenais 69 à la place de 63
# Définition d'une classe associée au capteur
class MMA7455():
bus = smbus.SMBus(1)
def __init__(self):
# Réglage de de la définition. Le 3e parametre est 0x05 pour mesurer de -2g a +2g, 0x09 de -4g a +4g, 0x01 de -8g a +8g
self.bus.write_byte_data(0x1D, 0x16, 0x05)
# lecture des valeurs en x, y et z.
def getValueX(self):
return self.bus.read_byte_data(0x1D, 0x06) + ajustx
def getValueY(self):
return self.bus.read_byte_data(0x1D, 0x07) + ajusty
def getValueZ(self):
return self.bus.read_byte_data(0x1D, 0x08) + ajustz
mma = MMA7455()
# on répète la mesure 1000 fois avant de s'arrêter
for a in range(1000):
x = mma.getValueX()
if (x > 127): # les valeurs se trouvent entre 0 et 255,
x = x - 255 # alors qu'on les veut entre -127 et 127
y = mma.getValueY()
if (y > 127):
y = y - 255
z = mma.getValueZ()
if (z > 127):
z = z - 255
# valeur totale de l'accélération, peu importe l'orientation
total = math.sqrt(x*x+y*y+z*z);
# calcul des angles et conversion en degrés
angleX = round(math.asin(x/ total )*180.0/3.1416)
angleY = round(math.asin(y/ total )*180.0/3.1416)
angleZ = round(math.acos(z/ total )*180.0/3.1416)
total = round (total)
print ('x = {0} y = {1} z = {2} total = {3} anglex = {4} deg angley = {5} deg anglex = {6} deg'.format(x,y,z,total,angleX,angleY,angleZ))
time.sleep(0.2) # pour que l'écriture à l'écran ne soit pas exagérément rapide.
view raw MMA7455.py hosted with ❤ by GitHub



Yves Pelletier   (Twitter:  @ElectroAmateur)

Aucun commentaire:

Enregistrer un commentaire