Site : tvaira.free.fr

Mise en oeuvre d’un port série sous Qt

Présentation Qt

Qt est une bibliothèque logicielle orientée objet développée en C++ par Qt Development Frameworks, filiale de Digia.

Qt est une plateforme de développement d’interfaces graphiques (GUI - Graphical User Interface) fournie à l’origine par la société norvégienne Troll Tech, rachetée par Nokia en février 2008 puis cédée intégralement en 2012 à Digia (www.qt.io).

Qt permet la portabilité des applications (qui n’utilisent que ses composants) par simple recompilation du code source. Les environnements supportés sont les Unix (dont Linux) qui utilisent le système graphique X Window System, Windows et Mac OS X.

Qt est principalement dédiée au développement d’interfaces graphiques en fournissant des éléments prédéfinis appelés widgets (pour windows gadgets) qui peuvent être utilisés pour créer ses propres fenêtres et des boîtes de dialogue complètement prédéfinies (ouverture / enregistrement de fichiers, progression d’opération, etc). Qt dispose d’un moteur de rendu graphique 2D performant.

Qt fournit également un ensemble de classes décrivant des éléments non graphiques : accès aux données, connexions réseaux (socket), gestion des fils d’exécution (thread), analyse XML, etc.

La dernière version est Qt 5.0 qui est sorti le 19 décembre 2012. Bien que marquant des changements majeurs sur bien des points, le passage de Qt4 à Qt5 casse au minimum la compatibilité au niveau des sources.

Version de Qt

Vous pouvez vérifier la version installée sur votre poste :

$ dpkg-query -l | grep qt[0-9]
...
ii  libqt4-xmlpatterns:i386 4:4.8.1-0ubuntu4.9 Qt 4 XML patterns module
ii  qt4-demos               4:4.8.1-0ubuntu4.9 Qt 4 examples and demos
ii  qt4-designer            4:4.8.1-0ubuntu4.9 graphical designer for Qt 4 applications
ii  qt4-dev-tools           4:4.8.1-0ubuntu4.9 Qt 4 development tools
ii  qt4-doc                 4:4.8.1-0ubuntu4.9 Qt 4 API documentation
ii  qt4-linguist-tools      4:4.8.1-0ubuntu4.9 Qt 4 Linguist tools
ii  qt4-qmake               4:4.8.1-0ubuntu4.9 Qt 4 qmake Makefile generator tool
...

On utilisera donc Qt4 !

Qt4 sépare sa bibliothèque en modules :

  • QtCore : pour les fonctionnalités non graphiques utilisées par les autres modules ;
  • QtGui : pour les composants graphiques, maintenant QtWidgets (qt5);
  • QtNetwork : pour la programmation réseau ;
  • etc …

Mais ici pour une prise en main minimale de Qt, nous n’utiliserons pas de modules spécifiques de Qt.

Environnement de Développement Intégré (EDI)

Qt Creator est l’environnement de développement intégré dédié à Qt et facilite la gestion d’un projet Qt. Son éditeur de texte offre les principales fonctions que sont la coloration syntaxique, le complètement, l’indentation, etc… Qt Creator intègre en son sein les outils Qt Designer et Qt Assistant. Il intègre aussi un mode débuggage.

Remarque : même si Qt Creator est présenté comme l’environnement de développement de référence pour Qt, il existe des modules Qt pour les environnements de développement Eclipse et Visual Studio. Il existe d’autres EDI dédiés à Qt et développés indépendamment de Nokia, comme QDevelop et Monkey Studio.

Mais ici pour une prise en main minimale de Qt, nous n’utiliserons pas Qt Creator.

Structure générale des classes Qt

L’API Qt est constituée de classes aux noms préfixés par Q et dont chaque mot commence par une majuscule (QString, QObject, …). Il faut savoir que la classe QObject est la classe mère de toutes les classes Qt.

Par exemple, la classe QString est une classe Qt pour manipuler les chaînes de caractères. Pour pouvoir utiliser une classe Qt, il ne faudra oublier d’inclure son fichier de déclaration :

#include <QString>

...

QString myString;

qmake

Qt se voulant un environnement de développement portable, il a été nécessaire de concevoir un moteur de production spécifique. C’est ainsi qu’est conçu le programme qmake.

Ce dernier prend en entrée un fichier (avec l’extension .pro) décrivant le projet (liste des fichiers sources, dépendances, paramètres passés au compilateur, etc…) et génère un fichier de projet spécifique à la plateforme. Ainsi, sous les systèmes UNIX/Linux, qmake produira un Makefile.

Le fichier de projet est fait pour être très facilement éditable par un développeur. Il consiste en une série d’affectations de variables.

La génération d’une application se fait en plusieurs étapes :

  • création d’un répertoire et des sources (cela pourra dépendre de l’EDI utilisé) : le nom initial du répertoire détermine le nom du projet et donc de l’exécutable qui sera produit (par défaut)

  • générer un fichier .pro qui décrit comment générer un Makefile pour compiler ce qui est présent dans le dossier courant : $ qmake -project

  • générer un Makefile à partir des informations du fichier .pro : $ qmake

  • fabriquer l’application en appelant l’outil make : $ make

Remarque : on exécute la commande qmake seulement si le fichier .pro est modifié

Le port série virtuel

Un port série virtuel est une solution logicielle qui émule un port série standard.

Cela permet généralement :

  • d’augmenter le nombre de ports série (sans installation de matériel supplémentaire mais dans les limites des ressources disponibles)
  • de partager les données en provenance d’un périphérique entre plusieurs applications
  • de raccorder un périphérique série standard (RS232, …) sur un port USB avec un adaptateur (manque ou absence de ports série physiques disponibles)

Pour établir une communication effective via un port série physique (RS-232) ou virtuel, il est nécessaire de définir le protocole utilisé : notamment, le débit de la transmission (en bits/s), le codage utilisé, le découpage en trame, etc. La norme RS-232 laisse ces points libres, mais en pratique on utilise souvent des trames d’un caractère ainsi constituées :

  • 1 bit de départ (START)
  • 7 à 8 bit de données
  • 1 bit de parité optionnel (aucune, paire ou impaire)
  • 1 ou plusieurs bits d’arrêt (STOP)

Gestion du port série sous Qt

Malheureusement, la version 4 de Qt ne fournit pas de classes pour gérer un port série nativement. On va donc devoir utiliser une bibliothèque logicielle externe à Qt.

Remarque : le problème n’existe plus en Qt5 car on dispose alors de la classe QSerialPort !

On va utiliser la classe QextSerialPort disponible ici.

On crée un nouveau répertoire et on se déplace à l’intérieur :

$ mkdir mo-qt-1

$ cd mo-qt-1/

On télécharge l’archive :

$ wget http://qextserialport.googlecode.com/files/qextserialport-1.2rc.zip

On décompresse l’archive téléchargée :

$ unzip qextserialport-1.2rc.zip

On déplace les sources et on renomme le répertoire :

$ mv qextserialport-1.2rc/src ./qextserialport

On peut maintenant supprimer l’archive téléchargée :

$ rm -f qextserialport-1.2rc.zip

On crée un nouveau fichier de projet :

$ vim mo-qt-1.pro
include(qextserialport/qextserialport.pri)

TEMPLATE = app
TARGET = 
DEPENDPATH += .
INCLUDEPATH += .

OBJECTS_DIR = ./tmp
MOC_DIR = ./tmp
DESTDIR = ./bin

# Input
SOURCES += main.cpp

On crée maintenant un programme de test du port série :

$ vim main.cpp
#include "qextserialport.h"

#define PORT "/dev/ttyACM0"

// Mode débuggage
#define DEBUG

#ifdef DEBUG
#include <QDebug>
#endif

int main()
{
    QextSerialPort *port;
    
    // création du port en mode asynchrone -> QextSerialPort::Polling
    port = new QextSerialPort(QLatin1String(PORT), QextSerialPort::Polling);
    
    // TODO : paramètrer le port (débit, ...)
    
    // ouverture du port
    port->open(QIODevice::ReadWrite | QIODevice::Unbuffered);
    #ifdef DEBUG
    qDebug("<debug> etat ouverture port : %d", port->isOpen());
    #endif
    
    // TODO : réceptionner des données
    
    // fermeture du port
    port->close();
    #ifdef DEBUG
    qDebug("<debug> etat ouverture port : %d", port->isOpen());
    #endif
    
    delete port;
    
    return 0;
}

On fabrique et on exécute le programme de test du port série :

$ qmake

$ make

$ ./bin/mo-qt-1
<debug> etat ouverture port : 1
<debug> etat ouverture port : 0

Le paramétrage du port série se fait avec les méthodes suivantes :

  • setBaudRate()
  • setParity()
  • setDataBits()
  • setStopBits()
  • … voir la documentation

Et pour les opération de lecture et d’écriture, on utilisera les méthodes read() et write().

Code source : test-mo-port.zip

Retour au sommaire