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 :

Carte_thermo.png

L'interface graphique de la version simplifiée du logiciel sous Linux :

thermo.png

...et celle de la version 2 :

Thermometre_V2.png

Une vidéo de démonstration : (captures réalisées avec Vokoscreen ; montage avec OpenShot Video Editor ; conversion avec Winff).

Chargement de la vidéo... Si vous voyez ce message, c'est que le lecteur Flash n'est pas installé.
  1. #!/usr/bin/python
  2. #-*- coding: iso-8859-15 -*-
  3.  
  4. # Copyright 2014 Vincent LE MIEUX
  5.  
  6. # Contact : vlemieux@laboiteaphysique.fr
  7.  
  8. # La version la plus récente de ce programme se trouve
  9. # sur le site de l'auteur : www.laboiteaphysique.fr
  10.  
  11. # Ce programme est un logiciel libre ; vous pouvez le redistribuer ou le modifier suivant
  12. # les termes de la GNU General Public License telle que publiée par la Free Software Foundation ;
  13. # soit la version 3 de la licence, soit (à votre gré) toute version ultérieure.
  14.  
  15. # Ce programme est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE ;
  16. # sans même la garantie tacite de QUALITÉ MARCHANDE ou d'ADÉQUATION à UN BUT PARTICULIER.
  17. # Consultez la GNU General Public License pour plus de détails.
  18.  
  19. # Vous devez avoir reçu une copie de la GNU General Public License en même temps que ce programme ;
  20. # si ce n'est pas le cas, consultez <http://www.gnu.org/licenses>.
  21.  
  22. from gi.repository import Gtk, GObject
  23.  
  24. import os, sys
  25. from time import sleep
  26. import usb.core
  27. import usb.util
  28.  
  29. import xlwt
  30. from xlwt import Workbook
  31.  
  32.  
  33. class THERMOMETRE(Gtk.Window):
  34. def __init__(self):
  35.  
  36. self.builder = Gtk.Builder()
  37. self.builder.add_from_file("thermometre2.glade")
  38.  
  39. #recuperation des widgets utilises par le programme :
  40.  
  41. self.lbA = self.builder.get_object("lbA")
  42. self.swAcq = self.builder.get_object("swAcq")
  43. self.bt_Quitter = self.builder.get_object("bt_Quitter")
  44. self.bt_Save = self.builder.get_object("bt_Save")
  45. self.bt_Effacer = self.builder.get_object("bt_Effacer")
  46. self.sb_timer = self.builder.get_object("sb_timer")
  47. self.textview = self.builder.get_object("textview")
  48. self.textbuffer = self.builder.get_object("textbuffer")
  49. self.scrolledwindow1 = self.builder.get_object("scrolledwindow1")
  50.  
  51. self.filechooserdialog = self.builder.get_object("filechooserdialog")
  52. self.cb_Filtre = self.builder.get_object("cb_Filtre")
  53.  
  54. self.builder.connect_signals(self)
  55.  
  56. window = self.builder.get_object('window')
  57. window.show_all()
  58.  
  59. #initialisations :
  60.  
  61. self.delai = 1000
  62. self.i = 0
  63. self.texte = ""
  64. self.cb_Filtre.set_active(0)
  65.  
  66. self.texte = 't(s)' + '\t' + 'T(' + u"°C" +')' + '\r' + '\n'
  67. self.textbuffer.set_text("")
  68.  
  69.  
  70.  
  71. #création d'un classeur pour le tableur :
  72. global classeur
  73. classeur = Workbook()
  74. self.feuille1 = classeur.add_sheet("Mesures", cell_overwrite_ok=True)
  75. self.feuille1.write(0,0,'t(s)',xlwt.easyxf("align: horiz center"))
  76. self.feuille1.write(0,1,'T(' + u"°C" +')',xlwt.easyxf("align: horiz center"))
  77.  
  78. thermo = usb.core.find(idVendor=0x0C70, idProduct = 0xF0A3)
  79.  
  80. if thermo is None:
  81. 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 ..."
  82. dialog = Gtk.MessageDialog(None, 0, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, msg)
  83. # Montre le dialog
  84. dialog.run()
  85. # Destruction du dialog
  86. dialog.destroy()
  87.  
  88. config = thermo.get_active_configuration()
  89. interface = config[(0,0)]
  90.  
  91. self.ep_out = usb.util.find_descriptor(interface, custom_match = lambda e: usb.util.endpoint_direction(e.bEndpointAddress)==usb.util.ENDPOINT_OUT)
  92. self.ep_in = usb.util.find_descriptor(interface, custom_match = lambda e: usb.util.endpoint_direction(e.bEndpointAddress)==usb.util.ENDPOINT_IN)
  93.  
  94. self.pour_rien()
  95. self.affiche()
  96. self.timer_afficheur = GObject.timeout_add(300, self.affiche)
  97.  
  98. def pour_rien(self):
  99. self.ep_out.write('M')
  100. sleep(0.02)
  101. pour_rien = self.ep_in.read(1)
  102. sleep(0.02)
  103. self.ep_out.write('M')
  104. sleep(0.02)
  105. pour_rien = self.ep_in.read(1)
  106.  
  107.  
  108. def affiche(self):
  109. self.ep_out.write('M')
  110. temp_affiche = self.ep_in.read(1)
  111. self.lbA.set_text(str("{:.1f}".format ( temp_affiche[0]*0.5)) + u" °C")
  112. return True
  113.  
  114. def mesure(self):
  115. if self.i < 65536 :
  116. self.ep_out.write('M')
  117. temperature = self.ep_in.read(1)
  118. self.texte +=(str(self.i*self.delai/1000) + '\t' + str("{:.1f}".format (temperature[0]*0.5)).replace('.', ',') + '\r' + '\n' )
  119. self.textbuffer.set_text(self.texte)
  120. adjustment = self.scrolledwindow1.get_vadjustment()
  121. adjustment.set_value(adjustment.get_upper())
  122.  
  123. self.feuille1.write(self.i+1,0,self.i*self.delai/1000,xlwt.easyxf("align: horiz center"))
  124. self.feuille1.write(self.i+1,1,float(str("{:.1f}".format (temperature[0]*0.5))),xlwt.easyxf("align: horiz center"))
  125. self.i = self.i + 1
  126. return True
  127.  
  128. def on_sb_timer_value_changed(self,widget):
  129. self.delai = int(1000*self.sb_timer.get_value())
  130.  
  131. def on_swAcq_button_press_event(self,widget,event):
  132. if widget.get_active()==False :
  133. self.pour_rien()
  134. self.effacer()
  135. self.mesure()
  136. self.timer_id = GObject.timeout_add(self.delai, self.mesure)
  137.  
  138. self.bt_Quitter.set_sensitive(False)
  139. self.bt_Effacer.set_sensitive(False)
  140. self.bt_Save.set_sensitive(False)
  141. self.sb_timer.set_sensitive(False)
  142.  
  143. else:
  144. GObject.source_remove(self.timer_id)
  145. self.bt_Quitter.set_sensitive(True)
  146. self.bt_Effacer.set_sensitive(True)
  147. self.bt_Save.set_sensitive(True)
  148. self.sb_timer.set_sensitive(True)
  149.  
  150. def effacer(self):
  151. self.texte = ' '
  152. self.texte = 't(s)' + '\t' + 'T(' + u"°C" +')' + '\r' + '\n'
  153. self.textbuffer.set_text(self.texte)
  154. for j in range (self.i) :
  155. self.feuille1.write(j+1,0,'')
  156. self.feuille1.write(j+1,1,'')
  157. self.i = 0
  158.  
  159. def on_bt_Effacer_clicked(self,widget) :
  160. self.effacer()
  161.  
  162. def on_bt_Save_clicked(self,widget):
  163. reponse = self.filechooserdialog.run()
  164. if reponse == 1:
  165. nom = self.filechooserdialog.get_filename()
  166. # Enregistrement format Calc :
  167. if self.cb_Filtre.get_active() ==0 :
  168. if not nom.endswith('.ods'):
  169. fichier_ods = nom + '.ods'
  170. else :
  171. fichier_ods = nom
  172. with open(fichier_ods, 'w') :
  173. classeur.save(fichier_ods)
  174.  
  175. # Enregistrement au format Gnumeric :
  176. if self.cb_Filtre.get_active() == 1 :
  177. if not nom.endswith('.gnumeric'):
  178. fichier_gnum = nom + '.gnumeric'
  179. else :
  180. fichier_gnum = nom
  181. with open(fichier_gnum, 'w') :
  182. classeur.save(fichier_gnum)
  183. self.filechooserdialog.hide()
  184.  
  185. def on_bt_Quitter_clicked(self,widget):
  186. Gtk.main_quit()
  187.  
  188. def on_window_destroy(self,widget):
  189. GObject.source_remove(self.timer_id)
  190. GObject.source_remove(self.timer_afficheur)
  191. Gtk.main_quit()
  192.  
  193. def destroy(window, self):
  194. GObject.source_remove(self.timer_id)
  195. GObject.source_remove(self.timer_afficheur)
  196. Gtk.main_quit()
  197.  
  198. def main():
  199. app = THERMOMETRE()
  200. Gtk.main()
  201.  
  202.  
  203.  
  204. if __name__ == "__main__":
  205.  
  206. sys.exit(main())
  207.  

This site uses cookies. Some of the cookies we use are essential for parts of the site to operate and have already been set. You may delete and block all cookies from this site, but parts of the site will not work.