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 :
#-------------------------------------------------
#
# Project created by QtCreator 2017-12-04T20:28:55
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = appTC72
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += main.cpp\
cihmapptc72.cpp \
../biblis/cspi.cpp \
ccapteur_spi_tc72_nth.cpp
HEADERS += cihmapptc72.h \
../biblis/cspi.h \
ccapteur_spi_tc72_nth.h
FORMS += cihmapptc72.ui
Le fichier de description de l'IHM cihmapptc72.ui
<ui version="4.0">
<class>CIhmAppTC72</class>
<widget class="QMainWindow" name="CIhmAppTC72">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>256</width>
<height>315</height>
</rect>
</property>
<property name="windowTitle">
<string>CIhmAppTC72</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QPushButton" name="pbId">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>121</width>
<height>29</height>
</rect>
</property>
<property name="text">
<string>id Fabricant</string>
</property>
</widget>
<widget class="QTextEdit" name="textEdit">
<property name="geometry">
<rect>
<x>10</x>
<y>50</y>
<width>231</width>
<height>181</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="pbMesure">
<property name="geometry">
<rect>
<x>140</x>
<y>10</y>
<width>101</width>
<height>29</height>
</rect>
</property>
<property name="text">
<string>Lire Mesure</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>256</width>
<height>26</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
Les fichiers décrivant la classe de gestion du capteur TC72 : ccapteur_spi_tc72_nth.h et ccapteur_spi_tc72_nth.cpp
// contient 0x54
typedef enum {
CONTINUOUS=0,
ONESHOT=0x11
} T_ETAT;
class CCapteur_Spi_TC72_NTh : public QObject
{
Q_OBJECT
public:
explicit CCapteur_Spi_TC72_NTh(QObject *parent = 0, int ce = 0);
~CCapteur_Spi_TC72_NTh();
quint8 getManufacturer();
float getTemperature();
private:
CSpi *m_spi;
int m_ce;
T_ETAT m_etat; // état du capteur
int setMode(T_ETAT etat); // continous ou oneshot
int reset();
quint8 getControleRegister();
int setControleRegister(quint8 val);
signals:
void sigErreur(QString mess);
private slots:
void onErreur(QString mess);
};
// CCAPTEURTEMPSPI_NTH_H
CCapteur_Spi_TC72_NTh::CCapteur_Spi_TC72_NTh(QObject *parent, int ce) :
QObject(parent)
{
m_ce = ce;
m_etat = CONTINUOUS; // eco d'énergie
m_spi = new CSpi(this, m_ce, 5000000, true, SPI_MODE_1);
connect(m_spi, SIGNAL(sigErreur(QString)), this, SLOT(onErreur(QString)));
reset(); // reset soft du capteur
setMode(m_etat); // mode eco par défaut
qDebug() << "Objet CCapteur_Spi_TC72_NTh créé !";
}
CCapteur_Spi_TC72_NTh::~CCapteur_Spi_TC72_NTh()
{
delete m_spi;
qDebug() << "Objet CCapteur_Spi_TC72_NTh détruit !";
}
int CCapteur_Spi_TC72_NTh::setMode(T_ETAT etat)
{
quint8 trame[2];
m_etat = etat;
trame[0]=REG_CTRL|W; // mode écriture
trame[1]=etat;
int nb=m_spi->ecrireNOctets(trame,2);
if (nb != 2) {
emit sigErreur("CCapteur_Spi_TC72_NTh::setMode ERREUR écriture");
} // if nb
QThread::msleep(200);
return nb;
}
int CCapteur_Spi_TC72_NTh::reset()
{
quint8 trame[2];
trame[0]=REG_CTRL|W; // mode écriture
trame[1]=RESET;
int nb=m_spi->ecrireNOctets(trame,2);
if (nb != 2) {
emit sigErreur("CCapteur_Spi_TC72_NTh::reset ERREUR écriture");
} // if nb
QThread::msleep(10);
return nb;
}
float CCapteur_Spi_TC72_NTh::getTemperature()
{
quint8 data[4] = {REG_MSB};
int nb=m_spi->lireEcrire(data,4); // demande lecture
if (nb != 4) {
emit sigErreur("CCapteur_Spi_TC72_NTh::getTemperature ERREUR écriture");
} // if nb
float temp;
temp = (float)data[1]; // partie entière
if (data[2]&0x80==0x80) temp+=0.50; // précision 1/2 degré
if (data[2]&0x40==0x40) temp+=0.25; // précision au 1/4 degré
return temp;
}
quint8 CCapteur_Spi_TC72_NTh::getManufacturer()
{
quint8 data[] = {REG_ID,0};
int nb=m_spi->lireEcrire(data,2); // demande lecture
if (nb != 2) {
emit sigErreur("CCapteur_Spi_TC72_NTh::getManufacturer ERREUR écriture");
} // if nb
// qDebug() << "id=" << QString::number(data[1],16);
return data[1];
}
quint8 CCapteur_Spi_TC72_NTh::getControleRegister()
{
quint8 adr[2] = {REG_CTRL};
int nb=m_spi->ecrireNOctets(adr,1); // demande lecture
if (nb != 1) {
emit sigErreur("CCapteur_Spi_TC72_NTh::getControleRegister ERREUR écriture");
} // if nb
//msleep(100);
quint8 cr;
m_spi->lireNOctets(&cr, 1);
if (nb != 1) {
emit sigErreur("CCapteur_Spi_TC72_NTh::getControleRegister ERREUR lecture");
} // if nb
return cr;
}
int CCapteur_Spi_TC72_NTh::setControleRegister(quint8 val)
{
quint8 trame[2];
trame[0]=REG_CTRL;
trame[1]=val; // val du CR
int nb=m_spi->ecrireNOctets(trame,2);
if (nb != 2) {
emit sigErreur("CCapteur_Spi_TC72_NTh::setControleRegister ERREUR écriture");
} // if nb
return nb;
}
void CCapteur_Spi_TC72_NTh::onErreur(QString mess)
{
emit sigErreur(mess);
}
Les fichiers décrivant le fonctionnement de l'application et l'IHM cihmapptc72.h cihmapptc72.cpp :
namespace Ui {
class CIhmAppTC72;
}
class CIhmAppTC72 : public QMainWindow
{
Q_OBJECT
public:
explicit CIhmAppTC72(QWidget *parent = 0);
~CIhmAppTC72();
private slots:
void on_pbId_clicked();
void on_pbMesure_clicked();
void onErreur(QString mess);
private:
Ui::CIhmAppTC72 *ui;
CCapteur_Spi_TC72_NTh *m_tc72;
};
// CIHMAPPTC72_H
CIhmAppTC72::CIhmAppTC72(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::CIhmAppTC72)
{
ui->setupUi(this);
m_tc72 = new CCapteur_Spi_TC72_NTh(this, '0');
connect(m_tc72, SIGNAL(sigErreur(QString)), this, SLOT(onErreur(QString)));
}
CIhmAppTC72::~CIhmAppTC72()
{
delete m_tc72;
delete ui;
}
void CIhmAppTC72::on_pbId_clicked()
{
quint8 ref;
ref = m_tc72->getManufacturer();
onErreur("Id fabricant (hex) : "+QString::number(ref,16));
}
void CIhmAppTC72::on_pbMesure_clicked()
{
float mesure;
mesure = m_tc72->getTemperature();
onErreur("Mesure : "+QString::number(mesure,'f',1)+" °C");
}
void CIhmAppTC72::onErreur(QString mess)
{
ui->textEdit->append(mess);
}