View  Edit  Attributes  History  Attach  Print  Search

ACCUEIL | ARDUINO > S'INSTALLER > DEBUTER > APPROFONDIR | PROCESSING | MECATRONIQUE | MATERIEL | OUTILS | TESTS | Plus...|
Python > Shell > ATELIERS Python + Qt > PyQt apps > PyQt+Arduino | Mes Robots | RepRap | Mes lib'Arduino | Mes shields Arduino | Mes distros | Les Mini-PC |
ATELIERS ARDUINO| VIDEOS | COMPRENDRE | REFERENCES | CODER | TECHNIQUE | GNU/LINUX | LIENS | Rien à voir |

PYQTLAB

PyQt Lab' : Mini-PC : pcDuino : Le résultat d'une mesure analogique est affiché dans une interface graphique avec un widget "à aiguille"


Par X. HINAULT - Juin 2013 - Testé avec pcDuino et poste fixe + Arduino. Incompatible RaspberryPi (pas d'entrées analogiques)

Ce que l'on va faire ici

  • Dans ce programme PyQt, je montre comment afficher une mesure analogique dans un widget graphique type "à aiguille" au sein d'une interface PyQt.

Pré-requis

Librairie Pyduino

sudo wget -4 -N https://raw.github.com/sensor56/pyDuino/master/pcduino/pyduino.py /usr/lib/python2.7/dist-packages

Librairie graphique PyQwt

  • Il est également nécessaire d'installer le paquet suivant :
$ sudo apt-get install  python-qwt5-qt4

Téléchargement des codes

  • L'archive avec les codes est disponible ici : ..

Matériel nécessaire

  • une plaque d'essai pour montage sans soudures,
  • des straps,
  • une résistance variable,

Instructions de montage

  • Connecter la sortie variable de la résistance variable à la broche A2, la deux autres broches de la résistance variable étant connectées entre le 0V et le 3.3V.

Le montage à réaliser

Le fichier d'interface *.py

  • Fichier obtenu automatiquement avec l'utilitaire pyuic4 à partir du fichier *.ui créé avec QtDesigner :

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file
#
# Created: Sat Sep 21 07:44:37 2013
#      by: PyQt4 UI code generator 4.9.1
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui
from PyQt4.Qwt5 import * # module Qwt

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(464, 276)
        self.qwtDial = QwtDial(Form)
        self.qwtDial.setGeometry(QtCore.QRect(90, 10, 266, 261))
        self.qwtDial.setReadOnly(True)
        self.qwtDial.setLineWidth(5)
        self.qwtDial.setFrameShadow(QwtDial.Sunken)
        self.qwtDial.setMode(QwtDial.RotateNeedle)
        self.qwtDial.setOrigin(90.0)
        self.qwtDial.setWrapping(False)
        self.qwtDial.setObjectName(_fromUtf8("qwtDial"))

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        Form.setWindowTitle(QtGui.QApplication.translate("Form", "PyQt + PyQwt +PyDuino : QwtDial affiche can brute (0-4095)", None, QtGui.QApplication.UnicodeUTF8))


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    Form = QtGui.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

 

Le fichier d'application *Main.py

  • Remarquer comment les fonctions Pyduino sont directement appelées dans le code PyQt : simple et efficace !!

Le code actif nécessaire contenu dans ce fichier est simple et réduit à l'essentiel, et pourtant, il s'agit d'une interface graphique !


#!/usr/bin/python
# -*- coding: utf-8 -*-

# Par X. HINAULT - Tous droits réservés - GPLv3
# Jan 2013 - www.mon-club-elec.fr

# --- importation des modules utiles ---
from PyQt4.QtGui import *
from PyQt4.QtCore import * # inclut Qtimer..

import os,sys

from PyQt4.Qwt5 import * # module Qwt

from pyduino import *

# --- importation du fichier de description GUI ---
from tuto_pyqt_pyduino_pyqwt_qwtdial_can_brutex1 import *

# classe principale contenant le code actif
class myApp(QWidget, Ui_Form): # la classe reçoit le Qwidget principal ET la classe définie dans test.py obtenu avec pyuic4

        # Note : ici self représente la classe

        def __init__(self, parent=None):
                QWidget.__init__(self) # initialise le Qwidget principal
                self.setupUi(parent) # Obligatoire

                # ------ code actif initial ------

                #===== Initialisation QwtDial ========

                #-- définition plage des valeurs du QwtDial
                # void  setRange (double vmin, double vmax, double vstep=0.0, int pagesize=1)
                self.qwtDial.setRange(0, 1023.0)  # modifie la plage de valeurs de l'afficheur


                #-- paramétrage initial du QwtDial --
                self.qwtDial.setOrigin(90.0) # point de référence du tracé - 0°=3H, 90° = 6H, etc..
                #self.qwtDial.setScaleArc(90.0, 270.0) # angle début / angle fin du tracé par rapport à l'origine
                self.qwtDial.setScaleArc(45.0, 315.0) # angle début / angle fin du tracé par rapport à l'origine
                self.qwtDial.setScale(0.0,10.0,100.0) # valeur min/max/pas des graduations de l'échelle - ici pas de 10 avec 10 intermédiaires

                #-- création de l'aiguille et association au QwtDial
                #QwtDialSimpleNeedle    (       Style   style, bool     hasKnob = true, const QColor &          mid = Qt::gray, const QColor &          base = Qt::darkGray )
                aiguille=QwtDialSimpleNeedle(QwtDialSimpleNeedle.Arrow,True,QColor(Qt.red),QColor(Qt.blue)) # défini un QwtDialSimpleNeedle = aiguille simple
                # .Arrow = style aiguille "flèche" | .Ray = style simple ligne
                self.qwtDial.setNeedle(aiguille) # associe l'aiguille au QwtDial

                #-- paramétrage de l'aiguille
                aiguille.setWidth(6.0) # fixe la largeur de l'aiguille

                #=== initialisation Timer ==
                self.timer=QTimer() # déclare un timer Qt
                self.connect(self.timer, SIGNAL("timeout()"), self.timerEvent) # connecte le signal timeOut de l'objet timer à l'appel de la fonction voulue
                self.timer.start(200) # démarre le timer

        #--- les fonctions appelées, utilisées par les signaux
        def timerEvent(self): # fonction appelée lors de la survenue d'un évènement Timer - nom fonction indiférrent
                print("timer") # debug
                self.valeur=analogRead(A2) # mesure analogique
                self.qwtDial.setValue(self.valeur) # fixe la valeur du qwtDial à partir de la valeur reçue sur port série

        # fin def timerEvent
        #--- fonctions actives
        # ...


# fonction principale exécutant l'application Qt                       
def main(args):
        a=QApplication(args) # crée l'objet application
        f=QWidget() # crée le QWidget racine
        c=myApp(f) # appelle la classe contenant le code de l'application
        f.show() # affiche la fenêtre QWidget
        r=a.exec_() # lance l'exécution de l'application
        return r

# pour rendre le fichier *.py exécutable
if __name__=="__main__": # pour rendre le code exécutable
        main(sys.argv) # appelle la fonction main

 

Utilisation

  • Les 2 fichiers suivants sont à enregistrer dans un même répertoire, l'un en nom.py et l'autre en nomMain.py.
  • Puis lancer l'application depuis Geany ou équivalent, en exécutant le fichier nomMain.py
  • Au lancement, la fenêtre graphique doit apparaître avec l'interface graphique intégrant un afficheur LCD : faîtes varier la valeur de la résistance variable pour voir l'aiguille du cadran graphique s'actualiser en temps réel !