Communication avec un capteur sur le bus SPI

Question

Concevez une application graphique Qt permettant d'afficher la température et l'ID fabricant du capteur (0x54).

Le capteur de température TC72 est celui connecté au bus SPI (voir schéma structurel).

L'affichage de la température se fera à l'écran en utilisant le widget LCD Number.

Indice

Widget LCD Number : Son fonctionnement est très simple. La méthode display() permet de définir l'affichage.

Utilisez la classe CSpi vue précédemment.

Il sera utile de concevoir une classe pour le capteur contenant les méthodes getTemperature() et getManufacturer().

Solution

Sources de l'application exemple

Cette solution n'utilise qu'un QTextEdit pour l'affichage.

Le fichier du projet apptc72.pro :

1
#-------------------------------------------------
2
#
3
# Project created by QtCreator 2017-12-04T20:28:55
4
#
5
#-------------------------------------------------
6
7
QT       += core gui
8
9
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
10
11
TARGET = appTC72
12
TEMPLATE = app
13
14
# The following define makes your compiler emit warnings if you use
15
# any feature of Qt which as been marked as deprecated (the exact warnings
16
# depend on your compiler). Please consult the documentation of the
17
# deprecated API in order to know how to port your code away from it.
18
DEFINES += QT_DEPRECATED_WARNINGS
19
20
# You can also make your code fail to compile if you use deprecated APIs.
21
# In order to do so, uncomment the following line.
22
# You can also select to disable deprecated APIs only up to a certain version of Qt.
23
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
24
25
26
SOURCES += main.cpp\
27
        cihmapptc72.cpp \
28
    ../biblis/cspi.cpp \
29
    ccapteur_spi_tc72_nth.cpp
30
31
HEADERS  += cihmapptc72.h \
32
    ../biblis/cspi.h \
33
    ccapteur_spi_tc72_nth.h
34
35
FORMS    += cihmapptc72.ui

Le fichier de description de l'IHM cihmapptc72.ui

1
<?xml version="1.0" encoding="UTF-8"?>
2
<ui version="4.0">
3
 <class>CIhmAppTC72</class>
4
 <widget class="QMainWindow" name="CIhmAppTC72">
5
  <property name="geometry">
6
   <rect>
7
    <x>0</x>
8
    <y>0</y>
9
    <width>256</width>
10
    <height>315</height>
11
   </rect>
12
  </property>
13
  <property name="windowTitle">
14
   <string>CIhmAppTC72</string>
15
  </property>
16
  <widget class="QWidget" name="centralWidget">
17
   <widget class="QPushButton" name="pbId">
18
    <property name="geometry">
19
     <rect>
20
      <x>10</x>
21
      <y>10</y>
22
      <width>121</width>
23
      <height>29</height>
24
     </rect>
25
    </property>
26
    <property name="text">
27
     <string>id Fabricant</string>
28
    </property>
29
   </widget>
30
   <widget class="QTextEdit" name="textEdit">
31
    <property name="geometry">
32
     <rect>
33
      <x>10</x>
34
      <y>50</y>
35
      <width>231</width>
36
      <height>181</height>
37
     </rect>
38
    </property>
39
   </widget>
40
   <widget class="QPushButton" name="pbMesure">
41
    <property name="geometry">
42
     <rect>
43
      <x>140</x>
44
      <y>10</y>
45
      <width>101</width>
46
      <height>29</height>
47
     </rect>
48
    </property>
49
    <property name="text">
50
     <string>Lire Mesure</string>
51
    </property>
52
   </widget>
53
  </widget>
54
  <widget class="QMenuBar" name="menuBar">
55
   <property name="geometry">
56
    <rect>
57
     <x>0</x>
58
     <y>0</y>
59
     <width>256</width>
60
     <height>26</height>
61
    </rect>
62
   </property>
63
  </widget>
64
  <widget class="QToolBar" name="mainToolBar">
65
   <attribute name="toolBarArea">
66
    <enum>TopToolBarArea</enum>
67
   </attribute>
68
   <attribute name="toolBarBreak">
69
    <bool>false</bool>
70
   </attribute>
71
  </widget>
72
  <widget class="QStatusBar" name="statusBar"/>
73
 </widget>
74
 <layoutdefault spacing="6" margin="11"/>
75
 <resources/>
76
 <connections/>
77
</ui>

Les fichiers décrivant la classe de gestion du capteur TC72 : ccapteur_spi_tc72_nth.h et ccapteur_spi_tc72_nth.cpp

1
#ifndef CCAPTEUR_SPI_TC72_NTH_H
2
#define CCAPTEUR_SPI_TC72_NTH_H
3
4
#include <QObject>
5
#include <QThread>
6
7
#include "/home/pi/devQt/biblis/cspi.h"
8
9
#define ADRESSE 0x80
10
#define REG_CTRL 0x00
11
#define REG_LSB 0x01
12
#define REG_MSB 0x02
13
#define REG_ID 0x03   // contient 0x54
14
#define W 0x80
15
#define RESET 0xfe
16
17
typedef enum {
18
    CONTINUOUS=0,
19
    ONESHOT=0x11
20
} T_ETAT;
21
22
class CCapteur_Spi_TC72_NTh : public QObject
23
{
24
    Q_OBJECT
25
26
public:
27
    explicit CCapteur_Spi_TC72_NTh(QObject *parent = 0, int ce = 0);
28
    ~CCapteur_Spi_TC72_NTh();
29
    quint8 getManufacturer();
30
    float getTemperature();
31
32
private:
33
    CSpi *m_spi;
34
    int m_ce;
35
    T_ETAT m_etat;   // état du capteur
36
37
    int setMode(T_ETAT etat); // continous ou oneshot
38
    int reset();
39
    quint8 getControleRegister();
40
    int setControleRegister(quint8 val);
41
42
signals:
43
    void sigErreur(QString mess);
44
45
private slots:
46
    void onErreur(QString mess);
47
48
};
49
50
#endif // CCAPTEURTEMPSPI_NTH_H
1
#include "ccapteur_spi_tc72_nth.h"
2
3
CCapteur_Spi_TC72_NTh::CCapteur_Spi_TC72_NTh(QObject *parent, int ce) :
4
    QObject(parent)
5
{
6
    m_ce = ce;
7
    m_etat = CONTINUOUS;  // eco d'énergie
8
9
    m_spi = new CSpi(this, m_ce, 5000000, true, SPI_MODE_1);
10
    connect(m_spi, SIGNAL(sigErreur(QString)), this, SLOT(onErreur(QString)));
11
    reset();  // reset soft du capteur
12
    setMode(m_etat);  // mode eco par défaut
13
    qDebug() << "Objet CCapteur_Spi_TC72_NTh créé !";
14
15
}
16
17
CCapteur_Spi_TC72_NTh::~CCapteur_Spi_TC72_NTh()
18
{
19
    delete m_spi;
20
    qDebug() << "Objet CCapteur_Spi_TC72_NTh détruit !";
21
}
22
23
int CCapteur_Spi_TC72_NTh::setMode(T_ETAT etat)
24
{
25
    quint8 trame[2];
26
    m_etat = etat;
27
    trame[0]=REG_CTRL|W;  // mode écriture
28
    trame[1]=etat;
29
    int nb=m_spi->ecrireNOctets(trame,2);
30
    if (nb != 2) {
31
         emit sigErreur("CCapteur_Spi_TC72_NTh::setMode ERREUR écriture");
32
    } // if nb
33
    QThread::msleep(200);
34
    return nb;
35
}
36
37
int CCapteur_Spi_TC72_NTh::reset()
38
{
39
    quint8 trame[2];
40
    trame[0]=REG_CTRL|W;  // mode écriture
41
    trame[1]=RESET;
42
    int nb=m_spi->ecrireNOctets(trame,2);
43
    if (nb != 2) {
44
         emit sigErreur("CCapteur_Spi_TC72_NTh::reset ERREUR écriture");
45
    } // if nb
46
    QThread::msleep(10);
47
    return nb;
48
}
49
50
float CCapteur_Spi_TC72_NTh::getTemperature()
51
{
52
    quint8 data[4] = {REG_MSB};
53
    int nb=m_spi->lireEcrire(data,4); // demande lecture
54
    if (nb != 4) {
55
         emit sigErreur("CCapteur_Spi_TC72_NTh::getTemperature ERREUR écriture");
56
    } // if nb
57
    float temp;
58
    temp = (float)data[1];  // partie entière
59
    if (data[2]&0x80==0x80) temp+=0.50;  // précision 1/2 degré
60
    if (data[2]&0x40==0x40) temp+=0.25;  // précision au 1/4 degré
61
    return temp;
62
}
63
64
quint8 CCapteur_Spi_TC72_NTh::getManufacturer()
65
{
66
    quint8 data[] = {REG_ID,0};
67
    int nb=m_spi->lireEcrire(data,2); // demande lecture
68
    if (nb != 2) {
69
         emit sigErreur("CCapteur_Spi_TC72_NTh::getManufacturer ERREUR écriture");
70
    } // if nb
71
//    qDebug() << "id=" << QString::number(data[1],16);
72
    return data[1];
73
}
74
75
quint8 CCapteur_Spi_TC72_NTh::getControleRegister()
76
{
77
    quint8 adr[2] = {REG_CTRL};
78
    int nb=m_spi->ecrireNOctets(adr,1); // demande lecture
79
    if (nb != 1) {
80
         emit sigErreur("CCapteur_Spi_TC72_NTh::getControleRegister ERREUR écriture");
81
    } // if nb
82
    //msleep(100);
83
    quint8 cr;
84
    m_spi->lireNOctets(&cr, 1);
85
    if (nb != 1) {
86
         emit sigErreur("CCapteur_Spi_TC72_NTh::getControleRegister ERREUR lecture");
87
    } // if nb
88
    return cr;
89
}
90
91
int CCapteur_Spi_TC72_NTh::setControleRegister(quint8 val)
92
{
93
    quint8 trame[2];
94
    trame[0]=REG_CTRL;
95
    trame[1]=val;  // val du CR
96
    int nb=m_spi->ecrireNOctets(trame,2);
97
    if (nb != 2) {
98
         emit sigErreur("CCapteur_Spi_TC72_NTh::setControleRegister ERREUR écriture");
99
    } // if nb
100
    return nb;
101
}
102
103
void CCapteur_Spi_TC72_NTh::onErreur(QString mess)
104
{
105
   emit sigErreur(mess);
106
}

Les fichiers décrivant le fonctionnement de l'application et l'IHM cihmapptc72.h cihmapptc72.cpp :

1
#ifndef CIHMAPPTC72_H
2
#define CIHMAPPTC72_H
3
4
#include <QMainWindow>
5
#include <QDebug>
6
#include "/home/pi/devQt/biblis/cspi.h"
7
#include "ccapteur_spi_tc72_nth.h"
8
9
namespace Ui {
10
class CIhmAppTC72;
11
}
12
13
class CIhmAppTC72 : public QMainWindow
14
{
15
    Q_OBJECT
16
17
public:
18
    explicit CIhmAppTC72(QWidget *parent = 0);
19
    ~CIhmAppTC72();
20
21
private slots:
22
    void on_pbId_clicked();
23
    void on_pbMesure_clicked();
24
    void onErreur(QString mess);
25
26
private:
27
    Ui::CIhmAppTC72 *ui;
28
    CCapteur_Spi_TC72_NTh *m_tc72;
29
};
30
31
#endif // CIHMAPPTC72_H
1
#include "cihmapptc72.h"
2
#include "ui_cihmapptc72.h"
3
4
CIhmAppTC72::CIhmAppTC72(QWidget *parent) :
5
    QMainWindow(parent),
6
    ui(new Ui::CIhmAppTC72)
7
{
8
    ui->setupUi(this);
9
    m_tc72 = new CCapteur_Spi_TC72_NTh(this, '0');
10
    connect(m_tc72, SIGNAL(sigErreur(QString)), this, SLOT(onErreur(QString)));
11
}
12
13
CIhmAppTC72::~CIhmAppTC72()
14
{
15
    delete m_tc72;
16
    delete ui;
17
}
18
19
void CIhmAppTC72::on_pbId_clicked()
20
{
21
    quint8 ref;
22
23
    ref  = m_tc72->getManufacturer();
24
    onErreur("Id fabricant (hex) : "+QString::number(ref,16));
25
}
26
27
void CIhmAppTC72::on_pbMesure_clicked()
28
{
29
    float mesure;
30
31
    mesure = m_tc72->getTemperature();
32
    onErreur("Mesure : "+QString::number(mesure,'f',1)+" °C");
33
}
34
35
void CIhmAppTC72::onErreur(QString mess)
36
{
37
 ui->textEdit->append(mess);
38
}