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 : Pyduino + PyQt : Interface graphique de contrôle de 8 sorties numériques ON/OFF.


Par X. HINAULT - Juillet 2013

Capture du bureau du pcDuino en accès distant par VNC, webcam branchée !

Ce que l'on va faire ici

  • Dans ce programme PyQt, je montre comment contrôler 8 LED à partir d'une interface graphique basique, ici 8 boutons graphiques. Le simple clic sur un bouton va allumer/éteindre la LED.

Tout l'intérêt de ce programme est de montrer avec quelle simplicité il est facile de coupler l'utilisation de la librairie Pyduino avec une interface PyQt : l'accès aux fonctions Pyduino se fait directement dans le code PyQt !! Une chose tout simplement impossible à partir de l'IDE Arduino ! A partir du moment où il est possible d'utiliser les instructions Pyduino au sein même d'un code d'interface graphique, je vous laisse imaginer la suite...

  • Truc d'utilisation : En accédant au mini-PC par accès distant VNC via une tablette graphique ou un smartphone, vous contrôlez la LED à distance et sans fil ! Imaginez que ce ne soit pas une LED... mais tout autre dispositif de votre choix : çà donne des idées non ?

Pré-requis

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

Téléchargement des codes

Matériel nécessaire

  • une plaque d'essai pour montage sans soudures,
  • des straps,
  • 8 x LED rouge 5mm,
  • 8 x résistance 1/4w de 270 Ohms environ,

Instructions de montage

  • Connecter sur les broches 0 à 7 (configurée en sortie) une LED et sa résistance (270 Ohms) en série connectée au 0V
  • Note technique : chaque broche va fournir (3.3-1.5)/270 = 6,66 mA soit au total 8 x 6,66mA... soit 53mA au plus, ce qui semble tout à fait acceptable pour ne pas risquer d'endommager le mini-PC.

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: Tue Jul 30 11:30:47 2013
#      by: PyQt4 UI code generator 4.9.1
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

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(569, 92)
        self.pushButton_7 = QtGui.QPushButton(Form)
        self.pushButton_7.setGeometry(QtCore.QRect(5, 15, 66, 56))
        self.pushButton_7.setCheckable(True)
        self.pushButton_7.setChecked(False)
        self.pushButton_7.setAutoDefault(False)
        self.pushButton_7.setFlat(False)
        self.pushButton_7.setObjectName(_fromUtf8("pushButton_7"))
        self.pushButton_6 = QtGui.QPushButton(Form)
        self.pushButton_6.setGeometry(QtCore.QRect(75, 15, 66, 56))
        self.pushButton_6.setCheckable(True)
        self.pushButton_6.setChecked(False)
        self.pushButton_6.setObjectName(_fromUtf8("pushButton_6"))
        self.pushButton_5 = QtGui.QPushButton(Form)
        self.pushButton_5.setGeometry(QtCore.QRect(145, 15, 66, 56))
        self.pushButton_5.setCheckable(True)
        self.pushButton_5.setChecked(False)
        self.pushButton_5.setObjectName(_fromUtf8("pushButton_5"))
        self.pushButton_4 = QtGui.QPushButton(Form)
        self.pushButton_4.setGeometry(QtCore.QRect(215, 15, 66, 56))
        self.pushButton_4.setCheckable(True)
        self.pushButton_4.setChecked(False)
        self.pushButton_4.setObjectName(_fromUtf8("pushButton_4"))
        self.pushButton_3 = QtGui.QPushButton(Form)
        self.pushButton_3.setGeometry(QtCore.QRect(285, 15, 66, 56))
        self.pushButton_3.setCheckable(True)
        self.pushButton_3.setChecked(False)
        self.pushButton_3.setObjectName(_fromUtf8("pushButton_3"))
        self.pushButton_2 = QtGui.QPushButton(Form)
        self.pushButton_2.setGeometry(QtCore.QRect(355, 15, 66, 56))
        self.pushButton_2.setCheckable(True)
        self.pushButton_2.setChecked(False)
        self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
        self.pushButton_1 = QtGui.QPushButton(Form)
        self.pushButton_1.setGeometry(QtCore.QRect(425, 15, 66, 56))
        self.pushButton_1.setCheckable(True)
        self.pushButton_1.setChecked(False)
        self.pushButton_1.setObjectName(_fromUtf8("pushButton_1"))
        self.pushButton_0 = QtGui.QPushButton(Form)
        self.pushButton_0.setGeometry(QtCore.QRect(495, 15, 66, 56))
        self.pushButton_0.setCheckable(True)
        self.pushButton_0.setChecked(False)
        self.pushButton_0.setObjectName(_fromUtf8("pushButton_0"))

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

    def retranslateUi(self, Form):
        Form.setWindowTitle(QtGui.QApplication.translate("Form", "PyQt : pushButton On/Off x 8", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_7.setText(QtGui.QApplication.translate("Form", "E/S n°7", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_6.setText(QtGui.QApplication.translate("Form", "E/S n°6", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_5.setText(QtGui.QApplication.translate("Form", "E/S n°5", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_4.setText(QtGui.QApplication.translate("Form", "E/S n°4", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_3.setText(QtGui.QApplication.translate("Form", "E/S n°3", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_2.setText(QtGui.QApplication.translate("Form", "E/S n°2", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_1.setText(QtGui.QApplication.translate("Form", "E/S n°1", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_0.setText(QtGui.QApplication.translate("Form", "E/S n°0", 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 !!

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

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

# modules a importer
from PyQt4.QtGui import *
from PyQt4.QtCore import *  # inclut QTimer..
import os,sys

from pyduino import * # pour accès aux fonctions "arduino-like"


from tuto_pyqt_pyduino_bases_button_toggle_x8 import * # fichier obtenu à partir QtDesigner et pyuic4

# +/- variables et objets globaux

class myApp(QWidget, Ui_Form): # la classe reçoit le Qwidget principal ET la classe définie dans test.py obtenu avec pyuic4
        def __init__(self, parent=None):
                QWidget.__init__(self) # initialise le Qwidget principal
                self.setupUi(parent) # Obligatoire

                # --- Variables de classe

                # --- Paramétrage des widgets de l'interface GUI si nécessaire ---

                # --- Connexions entre signaux des widgets et fonctions
                # connecte chaque signal utilisé des objets à l'appel de la fonction voulue

                self.connect(self.pushButton_0, SIGNAL("clicked()"), self.pushButton_0Clicked)
                self.connect(self.pushButton_1, SIGNAL("clicked()"), self.pushButton_1Clicked)
                self.connect(self.pushButton_2, SIGNAL("clicked()"), self.pushButton_2Clicked)
                self.connect(self.pushButton_3, SIGNAL("clicked()"), self.pushButton_3Clicked)
                self.connect(self.pushButton_4, SIGNAL("clicked()"), self.pushButton_4Clicked)
                self.connect(self.pushButton_5, SIGNAL("clicked()"), self.pushButton_5Clicked)
                self.connect(self.pushButton_6, SIGNAL("clicked()"), self.pushButton_6Clicked)
                self.connect(self.pushButton_7, SIGNAL("clicked()"), self.pushButton_7Clicked)

                # --- Code actif initial  ---

                # configuration des broches E/S
                for pin in range(0,8):
                        pinMode(pin,OUTPUT) # met broche en sortie
                        digitalWrite(pin,LOW) # met broche au niveau bas

        # --- les fonctions appelées, utilisées par les signaux des widgets ---

        # pushButton
        def pushButton_0Clicked(self):
                print("Bouton 0 clique")
                if self.pushButton_0.isChecked()==True:
                        print("Etat bouton = enfonce")
                        digitalWrite(0,HIGH)
                else:
                        print("Etat bouton = relache")
                        digitalWrite(0,LOW)

        def pushButton_1Clicked(self):
                print("Bouton 1 clique")
                if self.pushButton_1.isChecked()==True:
                        print("Etat bouton = enfonce")
                        digitalWrite(1,HIGH)
                else:
                        print("Etat bouton = relache")
                        digitalWrite(1,LOW)

        def pushButton_2Clicked(self):
                print("Bouton 2 clique")
                if self.pushButton_2.isChecked()==True:
                        print("Etat bouton = enfonce")
                        digitalWrite(2,HIGH)
                else:
                        print("Etat bouton = relache")
                        digitalWrite(2,LOW)

        def pushButton_3Clicked(self):
                print("Bouton 3 clique")
                if self.pushButton_3.isChecked()==True:
                        print("Etat bouton = enfonce")
                        digitalWrite(3,HIGH)
                else:
                        print("Etat bouton = relache")
                        digitalWrite(3,LOW)

        def pushButton_4Clicked(self):
                print("Bouton 4 clique")
                if self.pushButton_4.isChecked()==True:
                        print("Etat bouton = enfonce")
                        digitalWrite(4,HIGH)
                else:
                        print("Etat bouton = relache")
                        digitalWrite(4,LOW)

        def pushButton_5Clicked(self):
                print("Bouton 5 clique")
                if self.pushButton_5.isChecked()==True:
                        print("Etat bouton = enfonce")
                        digitalWrite(5,HIGH)
                else:
                        print("Etat bouton = relache")
                        digitalWrite(5,LOW)

        def pushButton_6Clicked(self):
                print("Bouton 6 clique")
                if self.pushButton_6.isChecked()==True:
                        print("Etat bouton = enfonce")
                        digitalWrite(6,HIGH)
                else:
                        print("Etat bouton = relache")
                        digitalWrite(6,LOW)

        def pushButton_7Clicked(self):
                print("Bouton 7 clique")
                if self.pushButton_7.isChecked()==True:
                        print("Etat bouton = enfonce")
                        digitalWrite(7,HIGH)
                else:
                        print("Etat bouton = relache")
                        digitalWrite(7,LOW)

        # --- les fonctions appelées, utilisées par les signaux hors widgets ---

        # --- fonctions de classes autres---    

# -- Autres Classes utiles --

# -- Classe principale (lancement)  --
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

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 les boutons graphiques gérant les 8 sorties numériques 0 à 7 :
    • cliquer dessus : la LED correspondante s'éteint
    • cliquer à nouveau dessus : la LED correspondante s'allume