Traitements parallèles avec les threads

Question

Je vous propose de créer une application permettant de lire la valeur du bouton poussoir connecté à la GPIO22 de la carte fille d'étude.

Un thread effectuera la lecture permanente (mode pooling) de la valeur du bouton. En cas de changement d'état, un signal sera émis en direction de l'IHM.

L'IHM affichera l'état du bouton.

Indice

Créer une classe CBoutonPoussoir qui hérite de QThread.

Surcharger la méthode run() pour lire en continu (boucle) la valeur du bouton poussoir sur la GPIO. Vous aurez besoin de la classe CGpio étudiée précédemment.

La classe CBoutonPoussoir doit prévoir 1 signal véhiculant la valeur du bouton poussoir (1 ou 0).

La classe CIhmAppThread doit disposer d'un slot pour recevoir le signal.

Solution

La classe CBoutonPoussoir
1
#ifndef CBOUTONPOUSSOIR_H
2
#define CBOUTONPOUSSOIR_H
3
4
#include <QThread>
5
#include "/home/pi/devQt/biblis/cgpio.h"
6
7
class CBoutonPoussoir : public QThread
8
{
9
    Q_OBJECT
10
public:
11
    explicit CBoutonPoussoir(QObject *parent = 0, int noGpio = 22);
12
    ~CBoutonPoussoir();
13
    bool m_fin;
14
15
private:
16
    CGpio *m_gpio;
17
    void run();
18
    int m_valMem;  // état mémoire
19
20
signals:
21
    void sigEtatBouton(bool etat);
22
    void sigErreur(QString mess);
23
24
private slots:
25
    void onErreur(QString mess);
26
27
};
28
29
#endif // CBOUTONPOUSSOIR_H
1
#include "cboutonpoussoir.h"
2
3
CBoutonPoussoir::CBoutonPoussoir(QObject *parent, int noGpio) :
4
    QThread(parent)
5
{
6
    m_gpio = new CGpio(this, noGpio, IN);
7
    connect(m_gpio, SIGNAL(sigErreur(QString)), this, SLOT(onErreur(QString)));
8
    m_valMem = false;
9
    m_fin=false;
10
    qDebug() << "Démarrage de l'objet CBoutonPoussoir";
11
}
12
13
CBoutonPoussoir::~CBoutonPoussoir()
14
{
15
    delete m_gpio;
16
    qDebug() << "Objet CBoutonPoussoir détruit !";
17
}
18
19
void CBoutonPoussoir::run()
20
{
21
    int etat;
22
23
    while(!m_fin) {
24
        etat = m_gpio->lire();
25
        if (etat != m_valMem) {
26
            m_valMem = etat;
27
            emit sigEtatBouton(m_valMem);
28
//            qDebug() << "etat bouton : " << m_valMem;
29
        } // if
30
        usleep(50000);
31
    } // wh
32
}
33
34
void CBoutonPoussoir::onErreur(QString mess)
35
{
36
    emit sigErreur(mess);
37
}

La classe hérite de QThread.

Elle peut émettre 2 signaux :

  • sigEtatBouton(bool etat) pour transmettre à l'IHM la valeur de l'état du bouton.

  • sigErreur(QString mess) pour transmettre une erreur.

Dans le constructeur de la classe, on prévoit de connecter le signal sigErreur(QString) de l'objet m_gpio au slot onErreur(QString) afin de faire suivre une éventuelle erreur survenue dans l'objet m_gpio (le signal sigErreur(QString mess) sera émis).

La méthode run() lit toutes les 50ms l'état du bouton sur la GPIO (22 par défaut).

Le signal sigEtatBouton(m_valMem) n'est émis que lorsque l'état du bouton change.

Je vous laisse réaliser la partie affichage à votre convenance.