Cours:TPgpioQT : Différence entre versions
(→Classe Bouton) |
(→Classe Lampe) |
||
Ligne 134 : | Ligne 134 : | ||
//2ère possibilité on l'indique dans la définition du constructeur | //2ère possibilité on l'indique dans la définition du constructeur | ||
// dans le mainwindow.h | // dans le mainwindow.h | ||
− | #include " | + | #include "lampe.h" |
... | ... | ||
class MainWindow : public QMainWindow | class MainWindow : public QMainWindow |
Version du 19 septembre 2024 à 11:15
Retour à la liste des Tds
Sommaire
GPIO
On dispose d'un connecteur avec un certain nombre de GPIO sur la carte rpi.
Ce sont des broches configurables qui peuvent servir de :
- entrée logique
- sortie logique
- fonction particulière :
- entrée analogique (pas sur les rpi actuelles)
- i2c
- spi
- pwm
- liaison série
- ...
Cartographie GPIO <-> modules
Plusieurs modules sont connectés sur les ports GPIO de la Rpi :
n° GPIO | Module | n° GPIO | Module | n° GPIO | Module |
---|---|---|---|---|---|
5 | Encodeur | 16 | Bouton poussoir 1 (vert?) | 18 | Switch |
6 | Encodeur | 17 | Bouton poussoir 2 (rouge?) | ||
22 | led Rouge | 24 | led Verte |
Préparation du projet
- Créer un nouveau projet de type "Widget application"
- Choisir le kit "Rpi"
- ajouter à la fin du fichier .pro la ligne
LIBS += -lpigpio
- Dans l'arborescence de votre projet,
- Ajouter des fichiers existants
Sorties
Classe Lampe
On utilisera la classe Lampe pour piloter des sorties.
lampe.h #ifndef LAMPE_H
#define LAMPE_H
#include <QObject>
class Lampe : public QObject
{
Q_OBJECT
public:
Lampe(int _broche);
private :
bool etat;
int broche;
signals:
void nouvelEtat(bool etat);
public slots:
void allumer();
void eteindre();
private:
void setValue(bool e);
};
#endif // LAMPE_H
|
lampe.cpp #include "lampe.h"
#include <pigpio.h>
Lampe::Lampe(int _broche) : QObject(),
broche(_broche)
{
gpioInitialise();
setValue(false);
gpioSetMode(broche,PI_OUTPUT);
}
void Lampe::allumer()
{
setValue(true);
}
void Lampe::eteindre()
{
setValue(false);
}
void Lampe::setValue(bool e)
{
gpioWrite(broche,e);
etat = e;
emit nouvelEtat(etat);
}
|
Faire le diagramme de classe d'après le fichier lampe.h
On va instancier la classe Lampe en précisant le numéro de GPIO utilise. Pour cela 2 approches sont possibles :
//1ère possibilité on l'indique dans la déclaration (mainwindow.h)
// ajout d'un attribut dans le header
#include "lampe.h"
...
class MainWindow : public QMainWindow
{
....
Lampe ledRouge{20};
....
}
|
//2ère possibilité on l'indique dans la définition du constructeur
// dans le mainwindow.h
#include "lampe.h"
...
class MainWindow : public QMainWindow
{
....
Lampe ledRouge;
....
}
...
// dans le mainwindow.cpp
....
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
ui(new Ui::MainWindow),ledRouge(16)
{
....
}
|
Instancier la classe Lampe et l'utiliser pour allumer la led verte à l'aide de bouton sur l'interface graphique
Ajout de fonctionnalité à la classe Lampe
On souhaite pouvoir changer l'état d'une lampe (si elle est allumée elle doit s'éteindre et inversement).
Pour ajouter cette fonctionnalité nous devons ajouter une méthode.
Ajouter une méthode changerEtat à la classe Lampe et l'utiliser
Clignotement avec QTimer
On peut facilement faire clignoter une lampe avec un QTimer
:
- on choisit une durée :
monTimer.setInterval(dure_Ms)
; - le signal timeout est émis toutes les duree_Ms
- il faut se connecter sur le signal :
connect(&monTimer,&QTimer::timeout,&maLampe,&Lampe::changerEtat)
;
- on lance le timer :
monTimer.start()
;
Il faut bien entendu ajouter monTimer
comme un attribut de la classe MainWindow
(ajouter #include <QTimer>)
En utilisant un QTimer, faire clignoter la lampe rouge
Cahier des charges
Ecrire un programme qui permet de :
- allumer individuellement chaque led
- éteindre individuellement chaque led
- allumer les 2 leds avec 1 seul bouton
- éteindre les 2 leds avec 1 seul bouton
- mettre en route/arrêter individuellement le clignotement de chaque led (en utilisant un QTimer):
- la led rouge à 1Hz
- la led verte à 5Hz
- quitter l'application
Entrées
Classe Bouton
On donne les fichiers correspondants à la classe Bouton qui va permettre d'observer une entrée logique de type bouton poussoir :
bouton.h #ifndef BOUTON_H
#define BOUTON_H
#include <QObject>
#include <QTimer>
enum EdgeType{ NONE, RISING, FALLING, BOTH };
class Bouton : public QObject
{
Q_OBJECT
public:
explicit Bouton(int _numGpio,EdgeType front,QObject *parent = nullptr);
int getValue();
private:
int numGpio;
int interruptLevel;
QTimer tictocAntiRebond;
void getEvent();
void processAntiRebond();
static void processInterrupt(int gpio, int level, uint32_t tick, void *userdata);
signals:
void change();
void startTimerAntiRebond();
};
#endif // BOUTON_H
|
bouton.cpp #include "bouton.h"
#include <QDebug>
#include <pigpio.h>
Bouton::Bouton(int _numGpio, EdgeType front, QObject *parent) : QObject(parent)
{
numGpio=_numGpio;
gpioInitialise();
gpioSetMode(numGpio,PI_INPUT);
tictocAntiRebond.setInterval(4);
tictocAntiRebond.setSingleShot(true);
connect(&tictocAntiRebond,&QTimer::timeout,
this,&Bouton::processAntiRebond);
connect(this,&Bouton::startTimerAntiRebond,
&tictocAntiRebond,QOverload<>::of(&QTimer::start));
interruptLevel=0;
switch (front)
{
case FALLING: interruptLevel=0;break;
case RISING: interruptLevel=1;break;
case BOTH: interruptLevel=2;break;
default : interruptLevel=-1;
}
if (interruptLevel!=-1)
{
gpioSetISRFuncEx(numGpio,interruptLevel, 0, Bouton::processInterrupt,this);
}
}
int Bouton::getValue()
{
return gpioRead(numGpio);
}
void Bouton::getEvent()
{
if (interruptLevel!=2) emit startTimerAntiRebond();
else emit change();
}
void Bouton::processAntiRebond()
{
if (gpioRead(numGpio)!=interruptLevel) emit change();
}
void Bouton::processInterrupt(int gpio, int level, uint32_t tick, void *userdata)
{
((Bouton *)userdata)->getEvent();
}
|
Ajouter la classe Bouton à votre diagramme de la classe
Instanciation de la classe Bouton
En observant le constructeur de la classe Bouton, ajouter à la classe MainWindow 2 attributs de type Bouton pour gérer les 2 boutons poussoirs
Créer des slots dans votre classe MainWindow et les connecter au signal émis par les objets de type Bouton
Utilisation
Modifier l'application de gestion des lampes pour pouvoir utiliser soit les boutons de l'écran tactile soit les boutons physiques