Dans un précédent billet, on a vu comment s'interfacer avec l'afficheur LCD 2x16 caractères depuis un code écrit en C. On va maintenant s'intéresser à un module python pour afficher des informations sur l'afficheur.
L'un des principaux avantages du python par rapport au langage C est que l'on a pas besoin de compiler le code pour le lancer sur la raspberry pi, donc moins galère pour faire du prototypage.
La base de l'environnement embarqué de travail est :
- buildroot-2013.08.1
- kernel 3.12.0
- chaîne de compilation croisée : buildroot-uclibc
Installation de python 3
Tant qu'à faire, autan utiliser la dernière version de python. :)
Le package python 3 est déjà présent sur l'environnement buildroot, il faut simplement le sélectionner dans via le menu et le tour est joué.
# make menuconfig
Puis de lancer la compilation avec la commande make :
# make
Modification d'un package buildroot
Pour s'interfacer avec le bus I2C via un module python, on va utiliser le package i2c-tools version 3.1.0 déjà présent dans les packages buildroot, mais la librairie python smbus n'est pas compilée par défaut, il va falloir l'activer et modifier le makefile pour faire fonctionner tout ça.
Tout d'abord télécharger les fichiers correctifs (i2c-tools.tar.gz) à désarchiver et à insérer dans le dossier package/i2c-tools :
# rm package/i2c-tools # tar i2c-tools.tar.gz -C package # ls package/i2c-tools Config.in i2c-tools-001-smbusmodule.patch i2c-tools.mk
Cette archive comprend :
- Config.in : Le fichier de configuration pour le menu buildroot
- i2c-tools-001-smbusmodule.patch : Un patch du fichier source smbusmodule.c pour faire fonctionner smbus avec python 3
- i2c-tools.mk : Le fichier de fabrication des exécutables pour jouer avec les ports I2C présents et du module python.
#################################################################### # # i2c-tools # #################################################################### I2C_TOOLS_VERSION = 3.1.0 I2C_TOOLS_SOURCE = i2c-tools-$(I2C_TOOLS_VERSION).tar.bz2 I2C_TOOLS_SITE = http://dl.lm-sensors.org/i2c-tools/releases I2C_TOOLS_DEPENDENCIES = python3 host-python3 # LDSHARED and PYTHON VAR ENV from $(HOST_DIR)/usr/bin/python3 -m sysconfig define I2C_TOOLS_BUILD_CMDS $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(@D) (cd $(@D)/py-smbus; \ PYTHONXCPREFIX="$(STAGING_DIR)/usr" \ CC="$(TARGET_CC)" \ CFLAGS="-fno-strict-aliasing -pthread -Wno-unused-result -DNDEBUG -g -fwrapv -O3 -Wall -O2 -I$(STAGING_DIR)/usr/include/python3.3m $(CFLAGS)" \ CPPFLAGS="$(CPPFLAGS) -I../include" \ LDFLAGS="-L$(STAGING_DIR)/lib -L$(STAGING_DIR)/usr/lib" \ LDSHARED="$(TARGET_CC) -pthread -shared $(LDFLAGS) -Wl,-rpath,-L$(STAGING_DIR)/usr/lib" \ $(HOST_DIR)/usr/bin/python3 setup.py build) endef define I2C_TOOLS_INSTALL_TARGET_CMDS for i in i2cdump i2cget i2cset i2cdetect; \ do \ $(INSTALL) -m 755 -D $(@D)/tools/$$i $(TARGET_DIR)/usr/bin/$$i; \ done (cd $(@D)/py-smbus; \ PYTHONPATH="$(TARGET_DIR)/usr/lib/python3.3/site-packages" \ $(HOST_DIR)/usr/bin/python3 setup.py install --prefix=$(TARGET_DIR)/usr) endef $(eval $(generic-package))
Une fois la modification faite, il suffit de selectionner le package i2c-tools dans le menu de buildroot grâce à la commande :
# make menuconfig
Puis de lancer la commande :
# make
Normalement, sur le système de fichiers, vous devriez avoir les fichiers dans le dossier /usr/lib/python3.3/site-packages :
- smbus.cpython-33m.so : La librairie compilée
- smbus-1.1-py3.3.egg-info : Le module python smbus
Python 3 et module I2C
Pour pouvoir utiliser le nouveau module fraîchement installé, il faut activer le module i2c sur la raspberry pi, pour ceci, la commande modprobe va nous permettre de lancer les modules :
# modprobe -a i2c-bcm2708 i2c-dev
Ce qui va permettre de créer les nœuds /dev/i2c-0 et /dev/i2c-1.
# i2cdetect -y 0 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- 76 --
Notre module LCD est bien vu par la raspberry pi à l'adresse 0x76 sur le bus 0
L'utilisation du module est simple, voici un premier exemple :
#!/usr/bin/python3 from smbus import SMBus # Adresse de notre module LCD lcd_addr = 0x76 # Utilisation du bus 0 bus = SMBus(0) # Clear LCD display bus.write_i2c_block_data(lcd_addr, 0x01, 0x02)
Suivant la messagerie codée sur le micro-contrôleur PIC pour la gestion de l'écran LCD, j'ai codé cette petite librairie permettant d'avoir accès aux fonctionnalités.
fichier i2c_lib.py :
############################################################# # Importation de modules externes : import smbus from time import * ############################################################# # Class et Methods : class i2c_device: """ I2C Class interface """ def __init__(self, addr, port=0): self.addr = addr self.bus = smbus.SMBus(port) def write_cmd(self, cmd): """ Write a single command """ self.bus.write_byte(self.addr, cmd) sleep(0.01) def write_cmd_arg(self, cmd, data): """ Write a command and argument """ self.bus.write_byte_data(self.addr, cmd, data) sleep(0.01) def write_block_data(self, cmd, data): """ Write a block of data """ self.bus.write_block_data(self.addr, cmd, data) sleep(0.01) def write_i2c_datas(self, cmd, datas): """ Write datas """ if isinstance(datas, list) and isinstance(cmd, int): self.bus.write_i2c_block_data(self.addr, cmd, datas) sleep(0.01) def read(self): """ Read a single byte """ return self.bus.read_byte(self.addr) def read_data(self, cmd): """ Read """ return self.bus.read_byte_data(self.addr, cmd) def read_block_data(self, cmd): """ Read a block of data """ return self.bus.read_block_data(self.addr, cmd)
fichier lcd_2x16.py :
############################################################# # Importation de modules externes : import sys sys.path.append(".") from i2c_lib import i2c_device ############################################################# # Class et Methods : class lcd_2x16: """ Classe de contrôle de l'affichage de l'écran alpha 2x16 caractères via le bus i2c ------------------------------//------- | Frame Id | Frame Size | Frame datas | ------------------------------//------- Identifiants : -------------- 0x01 : Clear Display 0x02 : Return home 0x03 : Set Cursor 0x04 : Put character 0x05 : Put string 0x06 : Control Display """ LCD_ID_CLEAR_DISPLAY = 0x01 LCD_ID_RETURN_HOME = 0x02 LCD_ID_SET_CURSOR = 0x03 LCD_ID_PUT_CHAR = 0x04 LCD_ID_PUT_STR = 0x05 LCD_ID_CONTROL_DISPLAY = 0x06 def __init__(self, addr=0x76, port=0): self.i2c_lib_obj = i2c_device(addr, port) def clear_display(self): """ Efface les informations ecrites sur l'écran LCD """ self.i2c_lib_obj.write_i2c_datas(self.LCD_ID_CLEAR_DISPLAY, [0x02]) def return_home(self): """ Retourne le curseur à la position Row = 1, column = 1 """ self.i2c_lib_obj.write_i2c_datas(self.LCD_ID_RETURN_HOME, [0x02]) def set_cursor(self, row, column): """ Deplace le curseur à la position souhaitée """ self.i2c_lib_obj.write_i2c_datas(self.LCD_ID_SET_CURSOR, [0x04, row, column]) def put_char(self, char): """ Insert un caractère à la position courante du curseur """ if isinstance(char, str) and len(char) is 1: self.i2c_lib_obj.write_i2c_datas(self.LCD_ID_PUT_CHAR, [0x03, ord(char)]) else: print('Error with argument ...') def put_str(self, string): """ Insert une chaîne de caractères à la position courante du curseur """ if isinstance(string, str) and len(string) <= 16: str_len = 2 + len(string) lst_str = [ord(char) for char in string] lst_str.insert(0, len(string) + 2) self.i2c_lib_obj.write_i2c_datas(self.LCD_ID_PUT_STR, lst_str) def control_display(self, display, cursor, blink): """ Change les paramètres de l'écran """ self.i2c_lib_obj.write_i2c_datas(self.LCD_ID_CONTROL_DISPLAY, [0x05, display, cursor, blink])
Il suffit d'importer le module lcd_2x16.py dans vos sources et d'instancier la classe lcd_2x16 pour interagir avec l'écran LCD.
Amusez-vous bien ...
Aucun commentaire:
Enregistrer un commentaire