Il existe plusieurs modules python dédiés à la gestion des entrées sorties et bus de communication (I2C, SPI), parmi ces modules, on trouve :
Pour les exemples, on utilise les mêmes GPIOs que ceux du chapitre précédent, ainsi que les mêmes capteur I2C et SPI.
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
kernedID du GPIO | 26 | 19 | 13 | 6 | 5 | 22 | 27 | 17 |
Notez que je décline toutes responsabilités quant aux conséquences que pourraient avoir l'utilisation des programmes présentés. Ceux-ci pourraient être erronés ou obsolètes.
Ce module fournit un ensemble de fonction de configuration et d'accès aux GPIOs, après avoir importé le module avec :
import RPi.GPIO as GPIO
On peut utiliser les fonctions :
import RPi.GPIO as GPIO
from time import sleep
gpios=( 17 , 27, 22 , 5 , 6 , 13 , 19 , 26 )
def initGPIOS(gpios):
GPIO.setmode(GPIO.BCM)
for i in range(8):
GPIO.setup(gpios[i], GPIO.OUT)
def EcrirePort(gpios,valeur):
masque = 1 ;
for i in range(8):
GPIO.output(gpios[i], masque & valeur)
masque <<= 1
def main(args):
ch_val=args[1]
valeur = int(ch_val,0)
initGPIOS(gpios)
EcrirePort(gpios,valeur)
sleep(1)
GPIO.cleanup(gpios)
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
La liste des gpios utilise une liste non modifiable.
Pour affecter la valeur de chaque bit de l'octet à chaque sortie, on utilise un masque que l'on décale d'un bit à chaque itération. Cela permet de tester chaque bit de l'octet et de positionner la sortie en fonction de l'état de ce bit.
La valeur de l'octet à écrire est transmis en ligne de commande, puis convertie en entier, Le deuxième paramètre indique la base de conversion, 0 signifie que la base est automatiquement détectée. Un chaîne qui commence par 0x indique une notation hexadécimale, par 0 indique une notation octale, sinon c'est la base 10 qui est utilisée.
La fonction sleep permet de maintenir le résultat avant de tout éteindre en désactivant les GPIOs. Elle est utile pour ce programme de test. Elle est importée à partir du module time
Ce module fournit un ensemble de fonction de configuration et d'accès aux GPIOs, après avoir importé le module avec :
from gpiozero import LED
On peut utiliser les GPIOs en sortie avec les fonctions :
En utilisant le module
from gpiozero import Button
On peut utiliser les GPIOs en entrée avec les fonctions :
from gpiozero import LED
from time import sleep
gpios=( 17 , 27, 22 , 5 , 6 , 13 , 19 , 26 )
def initLEDS(gpios):
led=[]
for i in range(8):
led.append(LED(gpios[i]))
return led
def EcrirePort(led,valeur):
masque = 1;
for i in range(8):
led[i].value = valeur & masque
masque <<= 1
def main(args):
ch_val=args[1]
valeur=int(ch_val,0)
led=initLEDS(gpios)
EcrirePort(led,valeur)
sleep(1)
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
Lors de l'initialisation, on crée le tableau des objets GPIOs de type LED pour des sorties. Pour créer ce tableau d'objets LED, on crée d'abord un tableau vide, puis on ajoute chaque objet LED avec la méthode append.
Pour affecter chaque bit de l'entier, on procède comme précédemment avec un masque qui permet de sélectionner chaque bit.
La fonction sleep permet de maintenir le résultat avant de tout éteindre en désactivant les GPIOs, lors de la destruction implicite de l'objet lorsque le programme se termine.
Ce module est un client du serveur pigpiod qu'il faut démarrer avant d'utiliser ce module avec la commande en mode root :
systemctl start pigpiod
On importe le module avec, par exemple :
import pigpio as PIGPIO
Ensuite on peut utiliser les fonctions :
Enfin, si le serveur n'est plus utilisé par d'autres applications, on pourra l'arrêter avec la commande en root :
systemctl stop pigpiod
import pigpio as PIGPIO
gpios=( 17 , 27, 22 , 5 , 6 , 13 , 19 , 26 )
def initGPIOS(pi,gpios):
for i in range(8):
pi.set_mode(gpios[i], PIGPIO.OUTPUT)
def EcrirePort(pi,gpios,valeur):
masque = 1
for i in range(8):
bit = bool(valeur & masque)
pi.write(gpios[i],bit)
masque <<= 1
def main(args):
ch_val=args[1]
valeur = int(ch_val,0)
pi = PIGPIO.pi()
if not pi.connected:
print("Erreur connexion")
return -1
pi = initGPIOS(pi,gpios)
EcrirePort(pi,gpios,valeur)
pi.stop()
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
Lors de l'établissement de la connexion, il convient de vérifier si la connexion a bien été établie avant de continuer. En cas de problème de connexion on termine le programme avec un code d'erreur.
La valeur transmise, après avoir appliqué le masque pour sélectionner un bit de l'octet, doit être convertie en booléen pour être acceptée par la fonction d'écriture.
Après déconnexion au serveur les GPIOs restent en l'état.
Ce module utilise le descripteur /dev/gpiochip0 du système. Après avoir importer le module :
from periphery import GPIO
on peut utiliser les fonctions :
from periphery import GPIO
gpios=( 17 , 27, 22 , 5 , 6 , 13 , 19 , 26 )
def initLEDS(gpios):
leds=[]
for i in range(8):
led = GPIO("/dev/gpiochip0", gpios[i], "out")
leds.append(led)
return leds
def EcrirePort(led,valeur):
masque = 1
for i in range(8):
bit = bool(valeur & masque)
led[i].write(bit)
masque <<= 1
def closeLEDS(led):
for i in range(8):
led[i].close()
def main(args):
ch_val=args[1]
valeur=int(ch_val,0)
led=initLEDS(gpios)
EcrirePort(led,valeur)
closeLEDS(led)
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
Ici on utilise le mode PWM matériel des broches GPIOs qui supportent cette fonction, on choisit le GPIO de kernelId 18.
A partir du module
import RPi.GPIO as GPIO
Il suffit d'utiliser les fonctions spécifiques au mode PWM
import RPi.GPIO as GPIO
from time import sleep
def main(args):
ch_val=args[1]
valeur = float(ch_val)
GPIO.setmode(GPIO.BCM)
GPIO.setup(18,GPIO.OUT)
pwm = GPIO.PWM(18, 100)
pwm.start(valeur)
sleep(1)
pwm.stop()
GPIO.cleanup()
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
Le rapport cyclique est transmis en ligne de commande et converti en entier.
On importe PWMLED du module gpiozero
from gpiozero import PWMLED
on utilise les fonctions
from gpiozero import PWMLED
from time import sleep
def main(args):
ch_val=args[1]
valeur=float(ch_val)
pwm = PWMLED(18)
pwm.value=valeur
sleep(1)
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
L'argument transmis en ligne de commande est converti en nombre réel qui doit être compris entre 0 et 1.
L'objet est détruit en fin de programme, la fonction sleep permet de maintenir l'affichage pour visualiser le résultat.
Ce module est un client du serveur pigpiod qu'il faut démarrer avant d'utiliser ce module avec la commande en mode root :
systemctl start pigpiod
On importe le module avec, par exemple :
import pigpio as PIGPIO
Ensuite on peut utiliser les fonctions :
import pigpio as PIGPIO
def initPWM(pi):
pi.set_mode(18, PIGPIO.ALT2)
pi.set_PWM_range(18, 100)
pi.set_PWM_frequency(18,1000)
def EcrireValeur(pi,valeur):
pi.set_PWM_dutycycle(18,valeur)
def main(args):
ch_val=args[1]
valeur = int(ch_val,0)
pi = PIGPIO.pi()
if not pi.connected:
print("Erreur connexion")
return -1
initPWM(pi)
EcrireValeur(pi,valeur)
pi.stop()
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
Dans la fonction initPWM, on définit le PWM0 de la broche 18 en mode PWM en utilisant la fonction ALT2 du GPIO. Ensuite on définit une plage de réglage du rapport cyclique enter 0 et 100. Enfin on définit la fréquence à 1000Hz.
Le rapport cyclique est défini par l'argument transmis en ligne de commande.
Ce module utilise l'overlay pwm qu'il faut installer en mode root
dtoverlay pwm
C'est l'installation par défaut qui définit le PWM0 du GPIO 18.
Après avoir importer le module :
from periphery import PWM
on peut utiliser les fonctions :
Après les test si le mode pwm n'est plus utilisé, il peut désinstaller en mode root
dtoverlay -r pwm
from periphery import PWM
from time import sleep
def initPWM():
pwm= PWM(0, 0)
pwm.frequency = 100
pwm.duty_cycle = 0.5
pwm.enable()
return pwm
def EcrireValeur(pwm,valeur):
pwm.duty_cycle = valeur
def main(args):
ch_val=args[1]
valeur=float(ch_val)
pwm = initPWM()
EcrireValeur(pwm,valeur)
sleep(1)
pwm.close()
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
Lors de l'initialisation le PWM est défini avec une fréquence de 100Hz et un rapport cyclique de 1/2.
On reprend la carte capteur de luminosité équipée du capteur bh1745 étudiée dans le chapitre précédent.
On adapte le fichier de définitions des registres au python sous la forme d'attributs statiques (ou attributs de classe). On va également écrire un programme de test du capteur qui ne dépend pas du module utilisé mais seulement d'une classe de gestion du capteur, classe qui, elle, est dépendante du module utilisé.
Classe de définitions des registres
class BH1745_defs():
I2CADR = 0x38
SYSTEM_CTRL = 0x40
CTRL1 = 0x41
CTRL2 = 0x42
CTRL3 = 0x44
RED_LSB = 0x50
RED_MSB = 0x51
GREEN_LSB = 0x52
GREEN_MSB = 0x53
BLUE_LSB = 0x54
BLUE_MSB = 0x55
CLEAR_LSB = 0x56
CLEAR_MSB = 0x57
DINT_LSB = 0x58
DINT_MSB = 0x59
INTERRUPT = 0x60
PERSISTENCE = 0x61
TH_LSB = 0x62
TH_MSB = 0x63
TL_LSB = 0x64
TL_MSB = 0x65
ID = 0x92
MANUFACTURER_ID = 0xE0
SYSCTRL_SW_RST = 0x80
SYSCTRL_INT_RST = 0x40
CTRL1_160ms = 0x00
CTRL1_320ms = 0x01
CTRL1_640ms = 0x02
CTRL1_1280ms = 0x03
CTRL1_2560ms = 0x04
CTRL1_5120ms = 0x05
CTRL2_VALID = 0x80
CTRL2_RGBC_EN = 0x10
CTRL2_ADC_G_1 = 0x00
CTRL2_ADC_G_2 = 0x01
CTRL2_ADC_G_16 = 0x02
CTRL3_VALUE = 0x02
INTERRUPT_STATUS = 0x80
INTERRUPT_LATCH = 0x10
INTERRUPT_SOURCE = 0xC0
INTERRUPT_ENABLE = 0x01
LED_ON = 1
LED_OFF = 0
Programme de test du capteur
from bh1745_defs import BH1745_defs
from bh1745 import BH1745
def main(args):
bh1745 = BH1745(1)
bh1745.device_init()
identifiant = bh1745.manutactureId()
print(hex(identifiant))
pret = bh1745.Pret()
while (not pret):
pret = bh1745.Pret()
red = bh1745.lire(BH1745_defs.RED_LSB);
green = bh1745.lire(BH1745_defs.GREEN_LSB);
blue = bh1745.lire(BH1745_defs.BLUE_LSB);
clear = bh1745.lire(BH1745_defs.CLEAR_LSB);
print(f"valeurs {red};{green};{blue};{clear}");
bh1745.device_close()
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
Ce programme utilise la classe BH1745_defs et la classe BH1745. Cette classe offre les fonctionnalités suivantes
On utilise le module smBus en important
from smbus import SMBus
Après on peut utiliser les fonctions
from bh1745_defs import BH1745_defs
from smbus import SMBus
class BH1745():
def __init__(self,numero=0):
self.numport = numero
self.i2c = SMBus(numero)
def device_init(self):
self.i2c.write_byte_data(BH1745_defs.I2CADR, BH1745_defs.SYSTEM_CTRL , BH1745_defs.SYSCTRL_SW_RST)
self.i2c.write_byte_data(BH1745_defs.I2CADR, BH1745_defs.SYSTEM_CTRL , 0 )
self.i2c.write_byte_data(BH1745_defs.I2CADR, BH1745_defs.CTRL1 , BH1745_defs.CTRL1_640ms)
self.i2c.write_byte_data(BH1745_defs.I2CADR, BH1745_defs.CTRL2 , BH1745_defs.CTRL2_RGBC_EN | BH1745_defs.CTRL2_ADC_G_2)
self.i2c.write_byte_data(BH1745_defs.I2CADR, BH1745_defs.CTRL3 , BH1745_defs.CTRL3_VALUE)
def device_close(self):
self.i2c.close()
def manutactureId(self):
valeur = self.i2c.read_byte_data(BH1745_defs.I2CADR, BH1745_defs.ID)
return valeur
def Mesure(self):
self.i2c.write_byte_data(BH1745_defs.I2CADR, BH1745_defs.CTRL3 , BH1745_defs.CTRL3_VALUE )
def Pret(self):
valeur = self.i2c.read_byte_data(BH1745_defs.I2CADR, BH1745_defs.CTRL2)
return bool(valeur & BH1745_defs.CTRL2_VALID)
def lire(self,LSBReg):
lsb = self.i2c.read_byte_data(BH1745_defs.I2CADR, LSBReg)
msb = self.i2c.read_byte_data(BH1745_defs.I2CADR, LSBReg + 1)
valeur = lsb + (msb << 8);
return valeur
La méthode de calcul de la valeur à partir du msb et lsb ne fonctionne que pour des valeurs positives en python.
On utilise le module pigpio en important
import pigpio as PIGPIO
Après on peut utiliser les fonctions
from bh1745_defs import BH1745_defs
import pigpio as PIGPIO
class BH1745():
def __init__(self,numero=0):
self.numport = numero
self.pi = PIGPIO.pi()
self.i2c = self.pi.i2c_open(numero, BH1745_defs.I2CADR)
def device_init(self):
self.pi.i2c_write_byte_data(self.i2c, BH1745_defs.SYSTEM_CTRL , BH1745_defs.SYSCTRL_SW_RST)
self.pi.i2c_write_byte_data(self.i2c, BH1745_defs.SYSTEM_CTRL , 0 )
self.pi.i2c_write_byte_data(self.i2c, BH1745_defs.CTRL1 , BH1745_defs.CTRL1_640ms)
self.pi.i2c_write_byte_data(self.i2c, BH1745_defs.CTRL2 , BH1745_defs.CTRL2_RGBC_EN | BH1745_defs.CTRL2_ADC_G_2)
self.pi.i2c_write_byte_data(self.i2c, BH1745_defs.CTRL3 , BH1745_defs.CTRL3_VALUE)
def device_close(self):
self.pi.i2c_close(self.i2c)
self.pi.stop()
def manutactureId(self):
valeur = self.pi.i2c_read_byte_data(self.i2c, BH1745_defs.ID)
return valeur
def Mesure(self):
self.pi.i2c_write_byte_data(self.i2c, BH1745_defs.CTRL3 , BH1745_defs.CTRL3_VALUE )
def Pret(self):
valeur = self.pi.i2c_read_byte_data(self.i2c, BH1745_defs.CTRL2)
return valeur & BH1745_defs.CTRL2_VALID
def lire(self,LSBReg):
lsb = self.pi.i2c_read_byte_data(self.i2c, LSBReg)
msb = self.pi.i2c_read_byte_data(self.i2c, LSBReg + 1)
valeur = lsb + (msb << 8);
return valeur
On importe le module :
from periphery import I2C
on peut utiliser les fonctions :
from bh1745_defs import BH1745_defs
from periphery import I2C
class BH1745():
def __init__(self,numero=0):
self.numport = numero
self.i2c = I2C("/dev/i2c-" + str(numero))
def device_init(self):
self.i2c.transfer(BH1745_defs.I2CADR, [ I2C.Message([ BH1745_defs.SYSTEM_CTRL , BH1745_defs.SYSCTRL_SW_RST ]) ])
self.i2c.transfer(BH1745_defs.I2CADR, [ I2C.Message([ BH1745_defs.SYSTEM_CTRL , 0 ])])
self.i2c.transfer(BH1745_defs.I2CADR, [ I2C.Message([ BH1745_defs.CTRL1 , BH1745_defs.CTRL1_640ms ])])
self.i2c.transfer(BH1745_defs.I2CADR, [ I2C.Message([ BH1745_defs.CTRL2 , BH1745_defs.CTRL2_RGBC_EN | BH1745_defs.CTRL2_ADC_G_2 ])])
self.i2c.transfer(BH1745_defs.I2CADR, [ I2C.Message([ BH1745_defs.CTRL3 , BH1745_defs.CTRL3_VALUE ])])
def device_close(self):
self.i2c.close()
def manutactureId(self):
msg = [ I2C.Message([ BH1745_defs.ID] ) , I2C.Message([0x00], read=True) ]
self.i2c.transfer(BH1745_defs.I2CADR, msg )
return msg[1].data[0]
def Mesure(self):
self.i2c.transfer(BH1745_defs.I2CADR,[ I2C.Message([ BH1745_defs.CTRL3 , BH1745_defs.CTRL3_VALUE ]) ] )
def Pret(self):
msg = [ I2C.Message([ BH1745_defs.CTRL2]) , I2C.Message([0x00], read=True) ]
self.i2c.transfer(BH1745_defs.I2CADR, msg )
return (msg[1].data[0]) & BH1745_defs.CTRL2_VALID
def lire(self,LSBReg):
msg = [ I2C.Message([ LSBReg ] ) , I2C.Message([0x00], read=True)]
self.i2c.transfer(BH1745_defs.I2CADR, msg )
lsb = msg[1].data[0]
msg = [ I2C.Message([ LSBReg + 1 ]) , I2C.Message([0x00], read=True)]
self.i2c.transfer(BH1745_defs.I2CADR, msg )
msb = msg[1].data[0]
valeur = lsb + (msb << 8);
return valeur
En écriture on crée une liste qui contient un seul message de deux valeurs qui sont le registre et la valeur à écrire
En lecture on crée une liste de deux message, le premier message contient le registre, le deuxième message contient 0 avec le paramètre read à True. Ceci pour indiquer une écriture suivi d'une lecture. La réponse est stockée dans le deuxième message qui contient un octet ce qui donne msg[1].data[0]
On utilise la carte acceléromètre/magnétomètre équipée du capteur LSM303D étudiée dans le chapitre précédent.
Comme pour le capteur précédent, on adapte le fichier de définitions des registres au python sous la forme d'attributs statiques (ou attributs de classe). On va également écrire un programme de test du capteur qui ne dépend pas du module utilisé mais seulement d'une classe de gestion du capteur, classe qui, elle, est dépendante du module utilisé.
Classe de définitions des registres
class LSM303D_defs():
DIV_2 = 16384
TEMP_OUT_L = 0x05
TEMP_OUT_H = 0x06
STATUS_M = 0x07
OUT_X_L_M = 0x08
OUT_X_H_M = 0x09
OUT_Y_L_M = 0x0A
OUT_Y_H_M = 0x0B
OUT_Z_L_M = 0x0C
OUT_Z_H_M = 0x0D
WHO_AM_I = 0x0F
CTRL_0 = 0x1F
CTRL_1 = 0x20
CTRL_2 = 0x21
CTRL_3 = 0x22
CTRL_4 = 0x23
CTRL_5 = 0x24
CTRL_6 = 0x25
CTRL_7 = 0x26
STATUS_A = 0x27
OUT_X_L_A = 0x28
OUT_X_H_A = 0x29
OUT_Y_L_A = 0x2A
OUT_Y_H_A = 0x2B
OUT_Z_L_A = 0x2C
OUT_Z_H_A = 0x2D
STATUS_M_ZXYMOR = 0x80
STATUS_M_ZMOR = 0x40
STATUS_M_YMOR = 0x20
STATUS_M_XMOR = 0x10
STATUS_M_ZYXMDA = 0x08
STATUS_M_ZMDA = 0x04
STATUS_M_YMDA = 0x02
STATUS_M_XMDA = 0x01
STATUS_A_ZXYAOR = 0x80
STATUS_A_ZAOR = 0x40
STATUS_A_YAOR = 0x20
STATUS_A_XAOR = 0x10
STATUS_A_ZYXADA = 0x08
STATUS_A_ZADA = 0x04
STATUS_A_YADA = 0x02
STATUS_A_XADA = 0x01
CTRL_0_BOOT = 0x80
CTRL_0_FIFO_EN = 0x40
CTRL_0_FTH_EN = 0x20
CTRL_0_HP_CLICK = 0x04
CTRL_0_HPIS1 = 0x02
CTRL_0_HPIS2 = 0x01
CTRL_1_AODR_MASK = 0xF0
CTRL_1_AODR_3 = 0x80
CTRL_1_AODR_2 = 0x40
CTRL_1_AODR_1 = 0x20
CTRL_1_AODR_0 = 0x10
CTRL_1_BDU = 0x08
CTRL_1_AZEN = 0x04
CTRL_1_AYEN = 0x02
CTRL_1_AXEN = 0x01
CTRL_2_ABW_1 = 0x80
CTRL_2_ABW_0 = 0x40
CTRL_2_AFS_2 = 0x20
CTRL_2_AFS_1 = 0x10
CTRL_2_AFS_0 = 0x08
CTRL_2_AST = 0x02
CTRL_2_SIM = 0x01
CTRL_5_TEMP_EN = 0x80
CTRL_5_M_RES_1 = 0x40
CTRL_5_M_RES_0 = 0x20
CTRL_5_M_ODR_2 = 0x10
CTRL_5_M_ODR_1 = 0x08
CTRL_5_M_ODR_0 = 0x04
CTRL_5_LIR2 = 0x02
CTRL_5_LIR1 = 0x01
CTRL_6_MFS1 = 0x40
CTRL_6_MFS0 = 0x20
CTRL_7_AHPM_1 = 0x80
CTRL_7_AHPM_0 = 0x40
CTRL_7_AFDS = 0x20
CTRL_7_T_ONLY = 0x10
CTRL_7_MLP = 0x04
CTRL_7_MD_1 = 0x02
CTRL_7_MD_0 = 0x01
Programme de test du capteur
from lsm303d_defs import LSM303D_defs
from lsm303d import LSM303D
import math
def main(args):
lsm303d = LSM303D(0)
lsm303d.Init()
identifiant = lsm303d.LireReg(LSM303D_defs.WHO_AM_I)
print(f"ID = {hex(identifiant)}")
ax = lsm303d.LireAxe(LSM303D_defs.OUT_X_L_A)
ay = lsm303d.LireAxe(LSM303D_defs.OUT_Y_L_A)
az = lsm303d.LireAxe(LSM303D_defs.OUT_Z_L_A)
rax = ax / LSM303D_defs.DIV_2
ray = ay / LSM303D_defs.DIV_2
raz = az / LSM303D_defs.DIV_2
mx = lsm303d.LireAxe(LSM303D_defs.OUT_X_L_M)
my = lsm303d.LireAxe(LSM303D_defs.OUT_Y_L_M)
mz = lsm303d.LireAxe(LSM303D_defs.OUT_Z_L_M)
rmx = mx / LSM303D_defs.DIV_2
rmy = my / LSM303D_defs.DIV_2
rmz = mz / LSM303D_defs.DIV_2
mm = math.sqrt(rmx*rmx+rmy*rmy+rmz*rmz)
print(f"x={rax:.3f} m/s2,y={ray:.3f} m/s2,z={raz:.3f} m/s2 x={rmx:.3f} g,y={rmy:.3f} g,z={rmz:.3f} g, M={mm:.3f}")
lsm303d.device_close()
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
Ce programme utilise la classe LSM303D_defs pour la définition des registres et la classe LSM303D pour l'accès aux registres du capteur. Cette dernière fournit les fonctionnalités de gestion du capteur :
On importe le module
import spidev
qui fournit les fonctions
from lsm303d_defs import LSM303D_defs
import spidev
class LSM303D():
def __init__(self,numero=0):
self.numport = numero
self.spi = spidev.SpiDev(0,numero)
self.spi.max_speed_hz = 1000000
self.spi.mode = 0
def device_close(self):
self.spi.close()
def EcrireReg(self,registre,valeur):
self.spi.xfer([registre , valeur])
def LireReg(self,registre):
datas = self.spi.xfer([(registre | 0x80) ,0])
return datas[1]
def Init(self):
self.EcrireReg(LSM303D_defs.CTRL_1,LSM303D_defs.CTRL_1_AZEN|LSM303D_defs.CTRL_1_AYEN|LSM303D_defs.CTRL_1_AXEN | LSM303D_defs.CTRL_1_AODR_0)
self.EcrireReg(LSM303D_defs.CTRL_2,0)
self.EcrireReg(LSM303D_defs.CTRL_3,0)
self.EcrireReg(LSM303D_defs.CTRL_4,0)
self.EcrireReg(LSM303D_defs.CTRL_5,0)
self.EcrireReg(LSM303D_defs.CTRL_6,0)
self.EcrireReg(LSM303D_defs.CTRL_7,0)
def AccPret(self):
valeur = self.LireReg(LSM303D_defs.STATUS_A)
bitpret = valeur & LSM303D_defs.STATUS_A_ZYXADA
return bitpret == LSM303D_defs.STATUS_A_ZYXADA
def LireAxe(self,regbase):
lsb = self.LireReg(regbase)
msb = self.LireReg(regbase+1)
resultat = int.from_bytes([msb, lsb],byteorder='big',signed=True)
return resultat
La conversion des deux octets qui composent le lsb et msb d'un entier signé 16 bits, ne peuvent plus être convertis avec un simple décalage. Il faut donc utiliser la méthode from_bytes de l'objet int en précisant l'ordre des octets ainsi que le type signé ou non signé.
On utilise le module pigpio en important
import pigpio as PIGPIO
Après on peut utiliser les fonctions
from lsm303d_defs import LSM303D_defs
import pigpio as PIGPIO
class LSM303D():
def __init__(self,numero=0):
self.numport = numero
self.pi = PIGPIO.pi()
self.spi = self.pi.spi_open(numero, 100000, 0)
def device_close(self):
self.pi.spi_close(self.spi)
self.pi.stop()
def EcrireReg(self,registre,valeur):
(count, rx_data) = self.pi.spi_xfer(self.spi, [ registre , valeur])
return count
def LireReg(self,registre):
(count, rx_data) = self.pi.spi_xfer(self.spi, [ (registre | 0x80), 0])
return rx_data[1]
def Init(self):
self.EcrireReg(LSM303D_defs.CTRL_1,LSM303D_defs.CTRL_1_AZEN|LSM303D_defs.CTRL_1_AYEN|LSM303D_defs.CTRL_1_AXEN | LSM303D_defs.CTRL_1_AODR_0)
self.EcrireReg(LSM303D_defs.CTRL_2,0)
self.EcrireReg(LSM303D_defs.CTRL_3,0)
self.EcrireReg(LSM303D_defs.CTRL_4,0)
self.EcrireReg(LSM303D_defs.CTRL_5,0)
self.EcrireReg(LSM303D_defs.CTRL_6,0)
self.EcrireReg(LSM303D_defs.CTRL_7,0)
def AccPret(self):
valeur = self.LireReg(LSM303D_defs.STATUS_A)
bitpret = valeur & LSM303D_defs.STATUS_A_ZYXADA
return bitpret == LSM303D_defs.STATUS_A_ZYXADA
def LireAxe(self,regbase):
lsb = self.LireReg(regbase)
msb = self.LireReg(regbase+1)
resultat = int.from_bytes([msb, lsb],byteorder='big',signed=True)
return resultat