"L'USB pour tous"
Vincent Le Mieux - ETSF
Historique
A partir de 1997 j'ai commencé à écrire des articles dans le magazine "Electronique Pratique" puis dans son Hors Série "Interfaces PC". A cette époque, la communication entre le PC et du matériel externe se faisait essentiellement par le port série ou le port parallèle. (Une autre solution existait : celle d'utiliser un slot ISA libre sur la carte mère, mais cette possibilité était difficile à mettre en oeuvre au niveau amateur en raison des contraintes qui s'imposaient à la réalisation du circuit imprimé)
En 1996 parait la première version de l'USB. Seules les dernières versions de Windows 95 allaient supporter cette norme (encore fallait-il disposer d'un PC ayant des connecteurs USB !).
Le véritable envol de l'USB va se faire à partir de 1998 : sortie de la révision 1.1 de l'USB et du système d'exploitation Windows 98 qui supportera cette norme.
Si l'arrivée de l'USB va simplifier la vie de l'utilisateur (alimentation du matériel directement par l'USB, possibilité de brancher plusieurs matériels par l'ajout d'un "hub", pas de réglages à faire du genre choix de port COM1 ou 2 etc...) elle va par contre considérablement compliquer la tâche du concepteur : au delà de la difficulté de compréhension de la norme USB, réussir à trouver une embase USB à souder sur un circuit imprimé n'était pas une mince affaire !
Après quelques articles écrits dans Electronique Pratique, il s'est avéré nécessaire de rassembler ces premières études dans un ouvrage ayant une flèche directrice générale.
C'est ainsi qu'est apparue la première édition de "L'USB pour tous"
Voici des extraits de l'avant-propos en page IX du livre :
"L'USB (Universal Serial Bus) a pris son envol grand public avec l'arrivée de Windows 98. Les nouveaux périphériques qui apparaissent sur le marché sont le plus souvent de type USB et nos bon vieux ports séries et parallèles désertent progressivement les cartes mères.
Pour pouvoir continuer à piloter des montages par ordinateur, en tant qu'amateur, ou pour des nécessités commerciales, nous sommes donc nombreux à vouloir maîtriser cette nouvelle technologie.
Les passionnés d'électronique et d'informatique qui souhaitent ajouter une corde à leur arc de compétences auront à coeur de vouloir réaliser et même concevoir des montages USB. Cet ouvrage est fait pour eux. [...]
[...] le choix pédagogique de l'auteur a été de distiller tout au long de cet ouvrage les informations nécessaires à la maîtrise progressive de l'USB.[...]
Le but avoué de l'auteur est d'amener le lecteur à l'écriture complète d'une application USB : ceci se réalisera dans les derniers chapitres."
Lors de mes premièrs travaux sur l'USB, deux voies de travail s'ouvraient :
- l'utilisation d'un circuit de conversion USB - RS232 tel que ceux lancés sur le marché par la société FTDI.
- la mise en oeuvre d'un montage à partir d'un microcontrôleur disposant de ressources USB.
Chacune de ces possibilités ayant ses avantages et inconvénients, je n'ai pas voulu en délaisser une pour privilégier l'autre. On retrouvera donc ces deux techniques dans cet ouvrage.
Description
Les logiciels accompagnant l'ouvrage (sur un CD-ROM dans la première édition, en téléchargement sur le site de l'éditeur pour la deuxième) ont été écrits en Visual Basic pour le système d'exploitation Windows XP.
A cause de problèmes liés au driver utilisé, non supporté par les nouvelles versions de Windows, plusieurs des montages décrits ne peuvent plus être utilisés au delà de la vesion Windows XP.
Microsoft ayant décidé de ne plus suivre la version XP, il était temps pour l'auteur de réagir !
Ayant abandonné depuis quelques années l'utilisation de ce système d'exploitation (sauf pour obligation professionnelle) au profit de GNU/Linux, l'auteur a décidé de réécrire les logiciels pour pouvoir utiliser les montages sous Linux.
Tous les logiciels proposés ont été vérifiés sous la distribution Debian.
L'auteur vous invite à oublier Microsoft et à vous tourner vers une distribution Linux !
Vous trouverez sur ce site le code source des logiciels nécessaire au fonctionnement des montages proposés dans le livre. Ils ont été écrits en Python.
Ce que vous ne trouverez pas :
- les schémas théoriques et pratiques des montages ainsi que leur description
- les codes sources des logiciels à implanter dans les microcontrôleurs utilisés dans les montages
Ces informations sont bien sûr présentes dans l'ouvrage "L'USB pour tous"
Conversion RS232-USB
Si l'on maitrise le protocole de communication RS232 entre un appareil et le PC, utiliser un module électronique de conversion USB - RS232 reste le moyen le plus simple pour accéder à la communication via USB.
On retrouve cependant les inconvénients du protocole série, à savoir l'adéquation nécessaire entre les réglages matériels et logiciels (vitesse de communication, parité ...)
L'ajout d'un tel module eprésente aussi un surcoût au niveau du montage.
Carte 4 jauges analogiques :
C'est le premier montage décrit dans la deuxième édition :
Il permet la mesure de quatre tensions (ayant une masse commune) et comprises entre 0 et 3,3V.
Une communication de type RS232 est installée entre le microcontrôleur (qui intègre un convertisseur analogique-numérique 8 bits) et le PC par le biais d'un module de conversion USB-RS232.
Deux Leds permettent de visualiser les échanges de données entre la carte et le PC.
Le logiciel sous Linux :
Chacune des voies est activable individuellement.
Télécharger le fichier Quatre_jauges.zip , puis le décompresser dans le dossier de son choix. (Voir également les explications similaires concernant le logiciel AL991S.)
Le logiciel pilotant l'alimentation AL991S et la carte Quatre Jauges (connectée aux trois sorties A,B et C de l'alimentation) fonctionnant simultanément. Troies voies de mesure sont utilisées sur la carte (E0,E1,E2) pour mesurer respectivement les tensions présentes sur les sorties A, B et C de l'alimentation AL991S :
Ci-dessous le code du logiciel à faire trouner sur le PC :
Avec un microcontrôleur
Montages à base de 68HC908
Le 68HC908JB8 est un microcontrôleur du fabricant Freescale ( Motorola) disposant des ressources nécessaires pour faire de la communication USB. On réduit alors notablement le coût de la réalisation par rapport à l'utilisation d'un module de conversion USB-série. Peu de composants suffisent à son fonctionnement :
Présentation
Les logiciels (initialement en Visual Basic sous Windows) ont été réécrits en Python. Ils utilisent le module PyUSB, module lui-même basé sur la libusb (Bibliothèque pour programmer des applications USB sans connaissances des mécanismes internes du noyau Linux).
Oubliez la fastidieuse installation des drivers (pilotes) sous Windows : l'utilisation de cette bibliothèque rend la vie simple à l'utilisateur. Nous n'aurons que quatre choses à faire, une fois pour toutes (pour l'intégralité des montages) :
1- Installer la libusb
2- Installer le module Python s'appuyant sur cette bibliothèque
3- Enregistrer, sur le système, en une seule fois l'intégralité des VID/PID des différents montages USB utilisés.
4- Appartenir au groupe d'utilisateurs autorisés à utiliser ces montages USB connectés sur le système
1- Installation de la Libusb :
On va commencer par vérifier si cette bibliothèque est installée :
A l'aide du gestionnaire de paquets, vérifier la présence de la libusb-1 ; l'installer si ce n'est déjà fait. (Rque : la présence de la version précédente (version 0.1) n'est pas gênante.
On doit finir par obtenir ceci (ici avec le gestionnaire de paquets Synaptic) :
2- Installation du module python PyUSB :
On installera la dernière version de ce module.
Faire le téléchargement ( https://github.com/walac/pyusb )
Puis :
- décompresser ce zip dans le dossier de votre choix
- Ouvrir une fenêtre du Terminal et se déplacer dans ce dossier
- taper la commande sudo python setup.py install :
3- Inscription des couples VID/PID :
L'inscription de tous ces couples VID/PID (Cf livre pages 22 et 34) se fait sous Linux à l'aide d'un fichier de "règles" à déposer dans etc/udev/rules.d
L'accès à ce dossier étant protégé, on pourra utiliser la technique suivante :
- dans un Terminal, taper la commande gksudo nautilus
- on se retrouve dans l'explorateur de fichiers Nautilus mais on dispose de droits pour modifier le contenu de tous les dossiers
- Aller dans Système de Fichiers -> etc -> udev -> rules.d
- Y copier le fichier 20-usb-pour-tous.rules
Détail du fichier 20-usb-pour-tous.rules :
# USB pour Tous - V.Le Mieux - Editions Dunod
# ID 0c70:f0a1 Carte E/S numeriques
SUBSYSTEM=="usb", ATTRS{idVendor}=="0c70", ATTRS{idProduct}=="f0a1", GROUP="dialout", MODE="0660"
# ID 0c70:f0a2 Dongle USB
SUBSYSTEM=="usb", ATTRS{idVendor}=="0c70", ATTRS{idProduct}=="f0a2", GROUP="dialout", MODE="0660"
# ID 0c70:f0a3 carte_CAN 8 bits
SUBSYSTEM=="usb", ATTRS{idVendor}=="0c70", ATTRS{idProduct}=="f0a3", GROUP="dialout", MODE="0660"
# ID 0c70:f0a4 carte_relais
SUBSYSTEM=="usb", ATTRS{idVendor}=="0c70", ATTRS{idProduct}=="f0a4", GROUP="dialout", MODE="0660"
# ID 0c70:f0a5 carte_CAN 12 bits
SUBSYSTEM=="usb", ATTRS{idVendor}=="0c70", ATTRS{idProduct}=="f0a5", GROUP="dialout", MODE="0660"
# ID 0c70:f0a6 Reference de tension
SUBSYSTEM=="usb", ATTRS{idVendor}=="0c70", ATTRS{idProduct}=="f0a6", GROUP="dialout", MODE="0660"
4- S'inscrire au groupe Dialout :
On remarquera que l'on a lié tous ces VID/PID au groupe "dialout".
Seuls les utilisateurs appartenant à ce groupe pourront donc utiliser les montages.
Pour savoir à quels groupes on appartient, entrer dans un terminal la commande :
groups
Un exemple de retour (réalisé sur une distribution Debian toute neuve dans une VirtualBox) :
On voit que l'utilisateur "vincent" n'appartient pas au group "dialout"
Appartenir au groupe "dialout" :
Pour que cet utilisateur "vincent" puisse appartenir au groupe "dialout", entrer les commandes suivantes dans un Terminal :
su ( il faudra ensuite entrer son mot de passe administrateur)
usermod -a -G dialout vincent (remplacer bien sûr l'utilisateur "vincent" par le vôtre !)
Voici l'ensemble de la séquence (à remarquer : la commande groups réitérée après usermod ne montre pas l'appartenance de l'utilisateur "vincent" au groupe "dialout". Il faudra faire un redémarrage pour que cela soit pris en compte :
Après redémarrage :
Remarque : l'ensemble des groupes disponibles se trouve dans le fichier etc/group. On aurait pu le lire avec gedit par exemple, voire même le modifier directement (en mode superutilisateur ... mais attention à ne pas faire d'erreurs !) :
Référence de tension
L'USB pour tous (2ème édition) - logiciels sous Linux
Carte "Sources de tension programmable" (page 113)
Cette carte permet de disposer de deux références de tension programmables par l'USB.
Les deux tensions générées sont indépendantes l'une de l'autre mais ont néanmoins leur masse commune.
La carte réalisée :
L'interface graphique du logiciel sous Linux :
Le code (téléchargeable ici), écrit en Python utilise un module nommé "bitstring" qui simplifie le travail avec les données binaires.
Il faudra installer ce module :
- le télécharger (https://pypi.python.org/pypi/bitstring/)
- le décompresser dans le dossier de son choix (l'auteur l'a placé dans Documents/Ajouts_Debian/ )
- entrer dans le dossier bitstring(dans mon cas : cd Documents/Ajouts_Debian/bitstring-3.1.3 )
et l'installer par la commande sudo python setup.py install :
Le code source du logiciel :
#!/usr/bin/python
#-*- coding: iso-8859-15 -*-
from gi.repository import Gtk, GObject
import os, sys
from bitstring import BitArray #ce module rend aisé le retournement de l'octet
import usb.core
import usb.util
class REF_TENSION:
def __init__(self):
self.builder = Gtk.Builder()
self.builder.add_from_file("reference_tension.glade")
#recuperation des widgets utilises par le programme :
self.lbA = self.builder.get_object("lbA")
self.lbB = self.builder.get_object("lbB")
self.scaleA = self.builder.get_object("scaleA")
self.scaleB = self.builder.get_object("scaleB")
self.builder.connect_signals(self)
window = self.builder.get_object('window')
window.show_all()
#initialisations :
ref_tension = usb.core.find(idVendor=0x0C70, idProduct = 0xF0A6)
if ref_tension is None:
msg = "Carte Référence de tension non détectée : vérifier qu'elle est bien branchée sur un port USB, et bien alimentée ! Ce programme va se refermer ..."
dialog = Gtk.MessageDialog(None, 0, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, msg)
# Montre le dialog
dialog.run()
# Destruction du dialog
dialog.destroy()
config = ref_tension.get_active_configuration()
interface = config[(0,0)]
self.ep_out = usb.util.find_descriptor(interface, custom_match = lambda e: usb.util.endpoint_direction(e.bEndpointAddress)==usb.util.ENDPOINT_OUT)
# mise à 0 des deux voies
self.ep_out.write(chr(0) + chr(0))
def on_scaleA_value_changed(self,widget):
self.lbA.set_text(str("{:.2f}".format(self.scaleA.get_value()*3.3/256)))
codeA = BitArray(uint=int(self.scaleA.get_value()), length=8)
codeA.reverse()
codeB = BitArray(uint=int(self.scaleB.get_value()), length=8)
codeB.reverse()
data = codeA.bytes + codeB.bytes
self.ep_out.write(data)
def on_scaleB_value_changed(self,widget):
self.lbB.set_text(str("{:.2f}".format(self.scaleB.get_value()*3.3/256)))
codeA = BitArray(uint=int(self.scaleA.get_value()), length=8)
codeA.reverse() # retournement de l'octet
codeB = BitArray(uint=int(self.scaleB.get_value()), length=8)
codeB.reverse() # retournement de l'octet
data = codeA.bytes + codeB.bytes
self.ep_out.write(data)
def on_bt_Quitter_clicked(self,widget):
self.ep_out.write(chr(0) + chr(0)) #remise à 0 des deux voies
Gtk.main_quit()
def on_window_destroy(self,widget):
self.ep_out.write(chr(0) + chr(0)) #remise à 0 des deux voies
Gtk.main_quit()
def destroy(window, self):
Gtk.main_quit()
def main():
app = REF_TENSION()
Gtk.main()
if __name__ == "__main__":
sys.exit(main())
Carte 8 relais
L'USB pour tous (2ème édition) - logiciels sous Linux
Carte "8 Relais" (page 95)
Cette carte permet de disposer de 8 relais activables par l'USB.
La carte réalisée :
L'interface graphique du logiciel sous Linux :
Le code source du logiciel :
#!/usr/bin/python
#-*- coding: iso-8859-15 -*-
from gi.repository import Gtk, GObject
import os, sys
import usb.core
import usb.util
class RELAIS:
def __init__(self):
self.builder = Gtk.Builder()
self.builder.add_from_file("carte_relais.glade")
#recuperation des widgets utilises par le programme :
self.switch0 = self.builder.get_object("switch0")
self.switch1 = self.builder.get_object("switch1")
self.switch2 = self.builder.get_object("switch2")
self.switch3 = self.builder.get_object("switch3")
self.switch4 = self.builder.get_object("switch4")
self.switch5 = self.builder.get_object("switch5")
self.switch6 = self.builder.get_object("switch6")
self.switch7 = self.builder.get_object("switch7")
self.bt_raz = self.builder.get_object("bt_raz")
self.builder.connect_signals(self)
window = self.builder.get_object('window')
window.show_all()
#initialisations :
carte_relais = usb.core.find(idVendor=0x0C70, idProduct = 0xF0A4)
if carte_relais is None:
msg = "Carte_relais non détectée : vérifier qu'elle est bien branchée sur un port USB, et bien alimentée ! Ce programme va se refermer ..."
dialog = Gtk.MessageDialog(None, 0, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, msg)
# Montre le dialog
dialog.run()
# Destruction du dialog
dialog.destroy()
config = carte_relais.get_active_configuration()
interface = config[(0,0)]
self.ep_out = usb.util.find_descriptor(interface, custom_match = lambda e: usb.util.endpoint_direction(e.bEndpointAddress)==usb.util.ENDPOINT_OUT)
self.r0 = 0
self.r1 = 0
self.r2 = 0
self.r3 = 0
self.r4 = 0
self.r5 = 0
self.r6 = 0
self.r7 = 0
self.r = 0
self.raz()
def on_switch0_button_press_event(self,widget,event):
if self.switch0.get_active():
self.r0 = 0
else:
self.r0 = 1
self.envoyer_ordre()
def on_switch1_button_press_event(self,widget,event):
if self.switch1.get_active():
self.r1 = 0
else:
self.r1 = 2
self.envoyer_ordre()
def on_switch2_button_press_event(self,widget,event):
if self.switch2.get_active():
self.r2 = 0
else:
self.r2 = 4
self.envoyer_ordre()
def on_switch3_button_press_event(self,widget,event):
if self.switch3.get_active():
self.r3 = 0
else:
self.r3 = 8
self.envoyer_ordre()
def on_switch4_button_press_event(self,widget,event):
if self.switch4.get_active():
self.r4 = 0
else:
self.r4 = 16
self.envoyer_ordre()
def on_switch5_button_press_event(self,widget,event):
if self.switch5.get_active():
self.r5 = 0
else:
self.r5 = 32
self.envoyer_ordre()
def on_switch6_button_press_event(self,widget,event):
if self.switch6.get_active():
self.r6 = 0
else:
self.r6 = 64
self.envoyer_ordre()
def on_switch7_button_press_event(self,widget,event):
if self.switch7.get_active():
self.r7 = 0
else:
self.r7 = 128
self.envoyer_ordre()
def envoyer_ordre(self):
r = self.r0 + self.r1 + self.r2 + self.r3 + self.r4 + self.r5 + self.r6 + self.r7
self.ep_out.write(chr(r))
def bt_raz_clicked(self,widget):
self.raz()
def raz(self):
#Reouverture de tous les relais
self.switch0.set_active(False)
self.switch1.set_active(False)
self.switch2.set_active(False)
self.switch3.set_active(False)
self.switch4.set_active(False)
self.switch5.set_active(False)
self.switch6.set_active(False)
self.switch7.set_active(False)
self.r0 = 0
self.r1 = 0
self.r2 = 0
self.r3 = 0
self.r4 = 0
self.r5 = 0
self.r6 = 0
self.r7 = 0
self.ep_out.write(chr(0))
def on_bt_Quitter_clicked(self,widget):
self.raz()
Gtk.main_quit()
def on_window_destroy(self,widget):
self.raz()
Gtk.main_quit()
def destroy(window, self):
Gtk.main_quit()
def main():
app = RELAIS()
Gtk.main()
if __name__ == "__main__":
sys.exit(main())
Thermomètre
L'USB pour tous (2ème édition) - logiciels sous Linux
Carte "Thermomètre" (page 157)
Cette carte permet de faire des mesures de température et de les transmettre en temps réel via l'USB.
La carte réalisée :
L'interface graphique de la version simple du logiciel sous Linux :
...et celle de la version 2 :
Cette deuxième version permet l'enregistrement des données et l'export vers un tableur.
#!/usr/bin/python
#-*- coding: iso-8859-15 -*-
# Copyright 2014 Vincent LE MIEUX
# Contact : vlemieux@laboiteaphysique.fr
# La version la plus récente de ce programme se trouve
# sur le site de l'auteur : www.laboiteaphysique.fr
# Ce programme est un logiciel libre ; vous pouvez le redistribuer ou le modifier suivant
# les termes de la GNU General Public License telle que publiée par la Free Software Foundation ;
# soit la version 3 de la licence, soit (à votre gré) toute version ultérieure.
# Ce programme est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE ;
# sans même la garantie tacite de QUALITÉ MARCHANDE ou d'ADÉQUATION à UN BUT PARTICULIER.
# Consultez la GNU General Public License pour plus de détails.
# Vous devez avoir reçu une copie de la GNU General Public License en même temps que ce programme ;
# si ce n'est pas le cas, consultez <http://www.gnu.org/licenses>.
from gi.repository import Gtk, GObject
import os, sys
from time import sleep
import usb.core
import usb.util
import xlwt
from xlwt import Workbook
class THERMOMETRE(Gtk.Window):
def __init__(self):
self.builder = Gtk.Builder()
self.builder.add_from_file("thermometre2.glade")
#recuperation des widgets utilises par le programme :
self.lbA = self.builder.get_object("lbA")
self.swAcq = self.builder.get_object("swAcq")
self.bt_Quitter = self.builder.get_object("bt_Quitter")
self.bt_Save = self.builder.get_object("bt_Save")
self.bt_Effacer = self.builder.get_object("bt_Effacer")
self.sb_timer = self.builder.get_object("sb_timer")
self.textview = self.builder.get_object("textview")
self.textbuffer = self.builder.get_object("textbuffer")
self.scrolledwindow1 = self.builder.get_object("scrolledwindow1")
self.filechooserdialog = self.builder.get_object("filechooserdialog")
self.cb_Filtre = self.builder.get_object("cb_Filtre")
self.builder.connect_signals(self)
window = self.builder.get_object('window')
window.show_all()
#initialisations :
self.delai = 1000
self.i = 0
self.texte = ""
self.cb_Filtre.set_active(0)
self.texte = 't(s)' + '\t' + 'T(' + u"°C" +')' + '\r' + '\n'
self.textbuffer.set_text("")
#création d'un classeur pour le tableur :
global classeur
classeur = Workbook()
self.feuille1 = classeur.add_sheet("Mesures", cell_overwrite_ok=True)
self.feuille1.write(0,0,'t(s)',xlwt.easyxf("align: horiz center"))
self.feuille1.write(0,1,'T(' + u"°C" +')',xlwt.easyxf("align: horiz center"))
thermo = usb.core.find(idVendor=0x0C70, idProduct = 0xF0A3)
if thermo is None:
msg = "Carte thermometre non détectée : vérifier qu'elle est bien branchée sur un port USB, et bien alimentée ! Ce programme va se refermer ..."
dialog = Gtk.MessageDialog(None, 0, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, msg)
# Montre le dialog
dialog.run()
# Destruction du dialog
dialog.destroy()
config = thermo.get_active_configuration()
interface = config[(0,0)]
self.ep_out = usb.util.find_descriptor(interface, custom_match = lambda e: usb.util.endpoint_direction(e.bEndpointAddress)==usb.util.ENDPOINT_OUT)
self.ep_in = usb.util.find_descriptor(interface, custom_match = lambda e: usb.util.endpoint_direction(e.bEndpointAddress)==usb.util.ENDPOINT_IN)
self.pour_rien()
self.affiche()
self.timer_afficheur = GObject.timeout_add(300, self.affiche)
def pour_rien(self):
self.ep_out.write('M')
sleep(0.02)
pour_rien = self.ep_in.read(1)
sleep(0.02)
self.ep_out.write('M')
sleep(0.02)
pour_rien = self.ep_in.read(1)
def affiche(self):
self.ep_out.write('M')
temp_affiche = self.ep_in.read(1)
self.lbA.set_text(str("{:.1f}".format ( temp_affiche[0]*0.5)) + u" °C")
return True
def mesure(self):
if self.i < 65536 :
self.ep_out.write('M')
temperature = self.ep_in.read(1)
self.texte +=(str(self.i*self.delai/1000) + '\t' + str("{:.1f}".format (temperature[0]*0.5)).replace('.', ',') + '\r' + '\n' )
self.textbuffer.set_text(self.texte)
adjustment = self.scrolledwindow1.get_vadjustment()
adjustment.set_value(adjustment.get_upper())
self.feuille1.write(self.i+1,0,self.i*self.delai/1000,xlwt.easyxf("align: horiz center"))
self.feuille1.write(self.i+1,1,float(str("{:.1f}".format (temperature[0]*0.5))),xlwt.easyxf("align: horiz center"))
self.i = self.i + 1
return True
def on_sb_timer_value_changed(self,widget):
self.delai = int(1000*self.sb_timer.get_value())
def on_swAcq_button_press_event(self,widget,event):
if widget.get_active()==False :
self.pour_rien()
self.effacer()
self.mesure()
self.timer_id = GObject.timeout_add(self.delai, self.mesure)
self.bt_Quitter.set_sensitive(False)
self.bt_Effacer.set_sensitive(False)
self.bt_Save.set_sensitive(False)
self.sb_timer.set_sensitive(False)
else:
GObject.source_remove(self.timer_id)
self.bt_Quitter.set_sensitive(True)
self.bt_Effacer.set_sensitive(True)
self.bt_Save.set_sensitive(True)
self.sb_timer.set_sensitive(True)
def effacer(self):
self.texte = ' '
self.texte = 't(s)' + '\t' + 'T(' + u"°C" +')' + '\r' + '\n'
self.textbuffer.set_text(self.texte)
for j in range (self.i) :
self.feuille1.write(j+1,0,'')
self.feuille1.write(j+1,1,'')
self.i = 0
def on_bt_Effacer_clicked(self,widget) :
self.effacer()
def on_bt_Save_clicked(self,widget):
reponse = self.filechooserdialog.run()
if reponse == 1:
nom = self.filechooserdialog.get_filename()
# Enregistrement format Calc :
if self.cb_Filtre.get_active() ==0 :
if not nom.endswith('.ods'):
fichier_ods = nom + '.ods'
else :
fichier_ods = nom
with open(fichier_ods, 'w') :
classeur.save(fichier_ods)
# Enregistrement au format Gnumeric :
if self.cb_Filtre.get_active() == 1 :
if not nom.endswith('.gnumeric'):
fichier_gnum = nom + '.gnumeric'
else :
fichier_gnum = nom
with open(fichier_gnum, 'w') :
classeur.save(fichier_gnum)
self.filechooserdialog.hide()
def on_bt_Quitter_clicked(self,widget):
Gtk.main_quit()
def on_window_destroy(self,widget):
GObject.source_remove(self.timer_id)
GObject.source_remove(self.timer_afficheur)
Gtk.main_quit()
def destroy(window, self):
GObject.source_remove(self.timer_id)
GObject.source_remove(self.timer_afficheur)
Gtk.main_quit()
def main():
app = THERMOMETRE()
Gtk.main()
if __name__ == "__main__":
sys.exit(main())
Baromètre
L'USB pour tous (2ème édition) - logiciels sous Linux
Carte "Baromètre" (page 175)
Cette carte permet de faire des mesures de pression et de les transmettre en temps réel via l'USB.
La carte réalisée :
Vue sur le capteur de pression :
Le capteur de pression peut être utilisé comme sur la photo, auquel cas c'est la pression de l'air ambiant qui est mesurée. La carte fonctionne alors comme un "baromètre".
Mais on peut aussi relier la canule du capteur de pression à un tuyau souple relié à une enceinte contenant un gaz pour en mesurer la pression, ou plongeant dans un liquide. La carte est alors utilisée en "pressiomètre".
Le logiciel, avec en fond d'écran un site donnant la pression atmosphérique en temps réel dans quelques grandes villes :
Une deuxième application (téléchargeable ici) a été créée pour faire fonctionner simultanément la carte thermomètre et la carte baromètre avec enregistrement des données et export possible vers un tableur (Calc de LibreOffice ou Gnumeric) :