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 |
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