Machine Vachette : Différence entre versions
(→Programmation sous QT Creator) |
|||
Ligne 40 : | Ligne 40 : | ||
=Programmation sous QT Creator= | =Programmation sous QT Creator= | ||
+ | ==Réalisation de l'interface graphique via RaspBerry Pi== | ||
+ | Pour simplifier l'utilisation de la machine, on a crée une interface graphique qui permet d'interagir avec la machine. | ||
+ | ===configuration raspberry=== | ||
+ | Branchez le câble ethernet sur la raspberry avant de l'allumer.Ensuite sur qt creator,en créant votre application avec widget, ajouter dans le management des kits la raspberry.Il faut la configurer avec son adresse IP apparaissant sur l'écran lié à la raspberry (c'est pour cela qu'il faut brancher le câble ethernet avant d'allumer la raspberry). Une fois l'adresse IP repéré, la rentrer de cette manière:<br> | ||
+ | [[Fichier:Capture d’écran 2021-04-11 à 11.39.40.png|vignette|centré|configuration Raspberry]]<br> | ||
+ | Puis appuyez sur '''test'''. Si tout est correct, vous aurez un message en bleu vous disant que le Raspberry est bien connecté. | ||
+ | |||
+ | ===création du code=== | ||
+ | pour référence, voici le dossier contenant le code effectué dont vous pouvez vous en inspirer : [[Fichier:Comm_nanopi_to_rpi.zip]]<br> | ||
+ | |||
+ | Les parties importantes qu'il faut à tout prix dans le code était tout d'abord d'installer la librairie mqtt. Ce qui nous permettra depuis le code de souscrire ou de publier sur un topic particulier.<br> | ||
+ | Lorsque vous créerez votre fichier qt, il faudra rajouter dans le fichier .pro la ligne 8:<br> | ||
+ | [[Fichier:Capture d’écran 2021-04-10 à 16.56.08.png|vignette|centré|ligne dans le fichier .pro]]<br> | ||
+ | Ensuite dans le fichier mainwindow.h ajoutez les classes suivantes:<br> | ||
+ | [[Fichier:Capture d’écran 2021-04-10 à 20.45.59.png|vignette|centré|les classes à rajouter]]<br> | ||
+ | |||
+ | Etant donné que le code est assez conséquent et que vous avez le dossier à disposition, on va juste regarder les fonctions importantes:<br> | ||
+ | {{boîte déroulante/début|titre=ligne de connexion au broker}} | ||
+ | <source lang=cpp> | ||
+ | #include "mainwindow.h" | ||
+ | #include "ui_mainwindow.h" | ||
+ | #include <QDebug> | ||
+ | #include <QMessageBox> | ||
+ | |||
+ | MainWindow::MainWindow(QWidget *parent) : | ||
+ | QMainWindow(parent), | ||
+ | ui(new Ui::MainWindow) | ||
+ | { | ||
+ | ui->setupUi(this); | ||
+ | |||
+ | //liaison MQTT | ||
+ | client.setHostname("10.98.9.20"); | ||
+ | client.setPort(1883); | ||
+ | client.connectToHost(); | ||
+ | </source> | ||
+ | {{boîte déroulante/fin}}<br> | ||
+ | Les lignes essentiels dans ce code sont les lignes concernant l'objet client de la classe mqtt (on peut retrouver la déclaration de cette objet dans le fichier mainwindow.h), elles permettent au raspberry de se connecter au broker mosquitto, tout comme les nanopi précedemment.<br> | ||
+ | {{boîte déroulante/début|titre=fonction connecte}} | ||
+ | <source lang=cpp> | ||
+ | //description pour liaison MQTT | ||
+ | void MainWindow::connecte() | ||
+ | { | ||
+ | qDebug() <<"i'm connected"; | ||
+ | qDebug() <<"current state flick= "<<flick; | ||
+ | |||
+ | //topic auquel vous êtes souscrit | ||
+ | subscription = client.subscribe(QLatin1String("cptE15")); | ||
+ | if(!subscription) | ||
+ | { | ||
+ | QMessageBox::critical(this,"error","failed to connect to broker"); | ||
+ | return; | ||
+ | } | ||
+ | ui->tabWidget->setCurrentIndex(0); | ||
+ | } | ||
+ | </source> | ||
+ | {{boîte déroulante/fin}}<br> | ||
+ | Pour cette fonction, la ligne interessante est la ligne de '''subscription=...''', c'est le '''"cptE15"''' où l'on peut mettre le topic auquel on veut que la raspberry s'abonne.Ici c'est '''cptE15''' car on faisait des tests de reception des infos d'un capteur sur la machine, et cela a fonctionné : on recevait bien les infos de la machine. On le savait grâce à ce bout de code:<br> | ||
+ | {{boîte déroulante/début|titre=fonction messageRecu}} | ||
+ | <source lang=cpp> | ||
+ | void MainWindow::messageRecu(const QByteArray &message, const QMqttTopicName &topic) | ||
+ | { | ||
+ | qDebug() << QDateTime::currentDateTime().toString() << topic.name() << message; | ||
+ | |||
+ | trmt=!trmt; | ||
+ | qDebug() << trmt; | ||
+ | emit valueChanged(trmt); | ||
+ | monTimer.setInterval(1000); | ||
+ | monTimer.start(); | ||
+ | connect(&monTimer,SIGNAL(timeout()),this,SLOT(relaisOFF())); | ||
+ | //monTimer.stop(); | ||
+ | } | ||
+ | </source> | ||
+ | {{boîte déroulante/fin}}<br> | ||
+ | Ici c'est lorsqu'on a le message affichant l'heure actuelle à laquelle par exemple sur le topic '''cptE15''', un message a été publié, que l'on sait que la raspberry a bien reçu les données envoyées sur le topic. Passons au prochain code:<br> | ||
+ | {{boîte déroulante/début|titre=exemple d'une fonction actionneur : le moteur du convoyeur principal}} | ||
+ | <source lang=cpp> | ||
+ | void MainWindow::convoyeurOFF() | ||
+ | { | ||
+ | qDebug() <<"arrêt convoyeur"; | ||
+ | QByteArray message = "1"; | ||
+ | quint8 qos = 1; | ||
+ | client.publish(QLatin1String("relais"),message,qos); | ||
+ | flick=false; | ||
+ | qDebug() << "flick = "<< flick; | ||
+ | |||
+ | if(flick == false){ | ||
+ | ui->enArret->setStyleSheet("background-color:red"); | ||
+ | ui->enMarche->setStyleSheet("background-color:"); | ||
+ | ui->posteAuto->setStyleSheet("background-color:"); | ||
+ | |||
+ | } | ||
+ | } | ||
+ | |||
+ | void MainWindow::convoyeurON() | ||
+ | { | ||
+ | |||
+ | qDebug() <<"demarrage convoyeur"; | ||
+ | QByteArray message = "0"; | ||
+ | quint8 qos = 1; | ||
+ | client.publish(QLatin1String("relais"),message,qos); | ||
+ | flick=true; | ||
+ | qDebug() << "flick = " << flick; | ||
+ | |||
+ | if(flick == true){ | ||
+ | ui->enMarche->setStyleSheet("background-color:green"); | ||
+ | ui->enArret->setStyleSheet("background-color:"); | ||
+ | ui->posteAuto->setStyleSheet("background-color:orange"); | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | {{boîte déroulante/fin}}<br> | ||
+ | Le Raspberry agira cette fois-ci comme celui qui publie, et ce sont les actionneurs de la carte actionneurs qui seront souscrit au topic de votre choix. Ici j'ai pris comme exemple la fonction permettant de piloter le moteur depuis l'interface par le biais des cartes électroniques reliées aux actionneurs dont on a besoin sur la machine. Bien sûr que la plupart des fonctions du code pilotant les actionneurs ont le même algorithme, seul le nom des topics est différent.<br> | ||
+ | il suffit de changer le nom du topic dans la ligne '''client.publish(QLatin1String("relais"),message,qos)''' le nom du topic ici est '''relais'''. Pour plus de renseignement sur le qos, se renseigner sur le lien dans la partie mqtt.<br> | ||
+ | |||
+ | ===création de l'interface graphique=== | ||
+ | Vous pourrez accéder et voir par vous même l'interface graphique ainsi que les différents panels proposés:<br> | ||
+ | - une 1ère page qui pourra servir de dépannage pour les différents capteurs et actionneurs<br> | ||
+ | Il y a une fonction dépannage existant qui servira à cela. Il suffira de changer que le topic où l'on veut vérifier.Voici les deux fonctions concernant le dépannage des actionneurs par exemple:<br> | ||
+ | {{boîte déroulante/début|titre=exemple d'une fonction actionneur : fonction dépannage actionneurs}} | ||
+ | <source lang=cpp> | ||
+ | //DEPANNAGE | ||
+ | void MainWindow::DepActON() | ||
+ | { | ||
+ | qDebug() <<"publication topic relais à l'état 1"; | ||
+ | QByteArray message = "0"; | ||
+ | quint8 qos = 1; | ||
+ | client.publish(QLatin1String("relaisDep"),message,qos); | ||
+ | flick=true; | ||
+ | qDebug() << "flick = " << flick; | ||
+ | |||
+ | if(flick == true){ | ||
+ | ui->enMarche->setStyleSheet("background-color:green"); | ||
+ | ui->enArret->setStyleSheet("background-color:"); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void MainWindow::DepActOFF() | ||
+ | { | ||
+ | qDebug() <<"publication topic relais à l'état 0"; | ||
+ | QByteArray message = "1"; | ||
+ | quint8 qos = 1; | ||
+ | client.publish(QLatin1String("relaisDep"),message,qos); | ||
+ | flick=false; | ||
+ | qDebug() << "flick = "<< flick; | ||
+ | |||
+ | if(flick == false){ | ||
+ | ui->enArret->setStyleSheet("background-color:red"); | ||
+ | ui->enMarche->setStyleSheet("background-color:"); | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | {{boîte déroulante/fin}}<br> | ||
+ | |||
+ | Pour le dépannage des capteurs, le plus simple est de modifier le topic dans la fonction capteur, puis de vérifier si le voyant '''info capteur reçu''' s'allume en orange. Voici à quoi ressemble la 1ère page:<br> | ||
+ | [[Fichier:Capture d’écran 2021-04-11 à 08.03.57.png|vignette|centré]]<br> | ||
+ | |||
+ | - une 2ème page montre des icones représentant la machine.Lorsqu'il y a un moteur d'un des postes manuels et/ou le convoyeur automatique:<br> | ||
+ | [[Fichier:Capture d’écran 2021-04-11 à 08.23.04.png|vignette|centré|représentation sur interface machine transfert]]<br> | ||
+ | Les icônes s'allumeront en orange lorsqu'un moteur était actif.<br> | ||
+ | |||
+ | - la 3ème page était celle qui permet de démarrer le convoyeur:<br> | ||
+ | [[Fichier:Capture d’écran 2021-04-11 à 08.32.13.png|vignette|centré|interface démarrage moteur]]<br> | ||
+ | |||
+ | Chaque boutons '''moteur convoyeur ON''' et '''moteur convoyeur OFF''' sont reliés à des fonctions avec des publications sur des topic dès qu'on appuie sur le bouton.<br> | ||
+ | |||
+ | - Les 3 dernières sont consacrées aux différents postes. Pour ce semestre, on s'est concentré sur le poste 3, c'est pour cela qu'il y a certains actionneurs qui peuvent être pilotés manuellement. Le principe est le même que les boutons pour le convoyeur (une fonction qui comporte une publication de topic avec un bouton. En allant à la page '''poste 3''', vous verrez différents actionneurs qui peuvent être actionnés depuis l'interface.<br> |
Version du 17 avril 2021 à 16:33
Sommaire
Présentation
Objectif : Restauration d’une ancienne machine de transfert “Vachette”
L’objectif de notre projet est de remettre en état une ancienne machine de chaîne d'automatisme de la marque "Vachette", en y ajoutant une touche de "modernité". Cette machine était supposément prévu pour de la serrurerie, avec un poste centrale automatique et trois postes manuels. Cependant, la machine a été modifié afin de convenir à une utilisation plus scolaire. Seul les postes restent, avec les différents capteurs et actionneurs intactes, toute la machinerie a été retiré.
Le but étant de faire marcher la machine à nouveau, plusieurs installations ont été réalisés au fil des années. En passant d'un automate pour aujourd'hui arriver à ce que nous avons réalisé :
Un système de carte électroniques alimentés par des cartes nanoPI et tout le système géré à distance, en réseau grâce à "MQTT" et Node-red, par une raspberryPI avec interface graphique. Sur cette page nous allons expliquer comment nous avons réalisés les cartes et comment nous avons mis en place le réseau capable de faire fonctionner la machine.
Réalisation des cartes
Recherche et développement
Avant de remettre en marche la machine de transfert nous avons dû tester quels capteurs influent sur quels actionneurs en se basant sur les projets réalisés les années précédentes, ainsi que les plans qui ont été réalisés et récupérés par l’IUT.
Pour arriver à nos fins, plusieurs étapes clés se sont poser à nous :
1 - Récupérer les signaux analogiques 24v -> 3.3v
2 - Conversion des signaux numérique/analog 3.3v en 24v
3 - Mise en réseaux des capteurs et actionneurs (Nano pi + Node-red)
4 - Création d’une interface principale sur une RaspberryPI (codage en QT)
Réalisation technique
Afin de convertir les signaux, nous avons dû réaliser des cartes électroniques. Cependant, afin d’optimiser et de simplifier l'utilisation ainsi que la complexité de cette dite carte, nous avons réalisé 3 modèles différents :
Un adaptateur pour faire fonctionner le protocole I2C. Une carte dédiée à la captation de signaux analogiques: 24v -> 3.3v Une carte dédiée à l’activation d'actionneurs (relais par exemples) : 3.3v -> 24V
Réalisation des cartes : Cartes capteurs : Opto Coupleurs 24v -> 3.3v Cartes actionneurs : Opto Coupleurs 3.3v -> 24v
Réseau (MQTT et Node-red)
Programmation sous QT Creator
Réalisation de l'interface graphique via RaspBerry Pi
Pour simplifier l'utilisation de la machine, on a crée une interface graphique qui permet d'interagir avec la machine.
configuration raspberry
Branchez le câble ethernet sur la raspberry avant de l'allumer.Ensuite sur qt creator,en créant votre application avec widget, ajouter dans le management des kits la raspberry.Il faut la configurer avec son adresse IP apparaissant sur l'écran lié à la raspberry (c'est pour cela qu'il faut brancher le câble ethernet avant d'allumer la raspberry). Une fois l'adresse IP repéré, la rentrer de cette manière:
Puis appuyez sur test. Si tout est correct, vous aurez un message en bleu vous disant que le Raspberry est bien connecté.
création du code
pour référence, voici le dossier contenant le code effectué dont vous pouvez vous en inspirer : Fichier:Comm nanopi to rpi.zip
Les parties importantes qu'il faut à tout prix dans le code était tout d'abord d'installer la librairie mqtt. Ce qui nous permettra depuis le code de souscrire ou de publier sur un topic particulier.
Lorsque vous créerez votre fichier qt, il faudra rajouter dans le fichier .pro la ligne 8:
Ensuite dans le fichier mainwindow.h ajoutez les classes suivantes:
Etant donné que le code est assez conséquent et que vous avez le dossier à disposition, on va juste regarder les fonctions importantes:
ligne de connexion au broker
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//liaison MQTT
client.setHostname("10.98.9.20");
client.setPort(1883);
client.connectToHost();
Les lignes essentiels dans ce code sont les lignes concernant l'objet client de la classe mqtt (on peut retrouver la déclaration de cette objet dans le fichier mainwindow.h), elles permettent au raspberry de se connecter au broker mosquitto, tout comme les nanopi précedemment.
fonction connecte
//description pour liaison MQTT
void MainWindow::connecte()
{
qDebug() <<"i'm connected";
qDebug() <<"current state flick= "<<flick;
//topic auquel vous êtes souscrit
subscription = client.subscribe(QLatin1String("cptE15"));
if(!subscription)
{
QMessageBox::critical(this,"error","failed to connect to broker");
return;
}
ui->tabWidget->setCurrentIndex(0);
}
Pour cette fonction, la ligne interessante est la ligne de subscription=..., c'est le "cptE15" où l'on peut mettre le topic auquel on veut que la raspberry s'abonne.Ici c'est cptE15 car on faisait des tests de reception des infos d'un capteur sur la machine, et cela a fonctionné : on recevait bien les infos de la machine. On le savait grâce à ce bout de code:
fonction messageRecu
void MainWindow::messageRecu(const QByteArray &message, const QMqttTopicName &topic)
{
qDebug() << QDateTime::currentDateTime().toString() << topic.name() << message;
trmt=!trmt;
qDebug() << trmt;
emit valueChanged(trmt);
monTimer.setInterval(1000);
monTimer.start();
connect(&monTimer,SIGNAL(timeout()),this,SLOT(relaisOFF()));
//monTimer.stop();
}
Ici c'est lorsqu'on a le message affichant l'heure actuelle à laquelle par exemple sur le topic cptE15, un message a été publié, que l'on sait que la raspberry a bien reçu les données envoyées sur le topic. Passons au prochain code:
exemple d'une fonction actionneur : le moteur du convoyeur principal
void MainWindow::convoyeurOFF()
{
qDebug() <<"arrêt convoyeur";
QByteArray message = "1";
quint8 qos = 1;
client.publish(QLatin1String("relais"),message,qos);
flick=false;
qDebug() << "flick = "<< flick;
if(flick == false){
ui->enArret->setStyleSheet("background-color:red");
ui->enMarche->setStyleSheet("background-color:");
ui->posteAuto->setStyleSheet("background-color:");
}
}
void MainWindow::convoyeurON()
{
qDebug() <<"demarrage convoyeur";
QByteArray message = "0";
quint8 qos = 1;
client.publish(QLatin1String("relais"),message,qos);
flick=true;
qDebug() << "flick = " << flick;
if(flick == true){
ui->enMarche->setStyleSheet("background-color:green");
ui->enArret->setStyleSheet("background-color:");
ui->posteAuto->setStyleSheet("background-color:orange");
}
}
Le Raspberry agira cette fois-ci comme celui qui publie, et ce sont les actionneurs de la carte actionneurs qui seront souscrit au topic de votre choix. Ici j'ai pris comme exemple la fonction permettant de piloter le moteur depuis l'interface par le biais des cartes électroniques reliées aux actionneurs dont on a besoin sur la machine. Bien sûr que la plupart des fonctions du code pilotant les actionneurs ont le même algorithme, seul le nom des topics est différent.
il suffit de changer le nom du topic dans la ligne client.publish(QLatin1String("relais"),message,qos) le nom du topic ici est relais. Pour plus de renseignement sur le qos, se renseigner sur le lien dans la partie mqtt.
création de l'interface graphique
Vous pourrez accéder et voir par vous même l'interface graphique ainsi que les différents panels proposés:
- une 1ère page qui pourra servir de dépannage pour les différents capteurs et actionneurs
Il y a une fonction dépannage existant qui servira à cela. Il suffira de changer que le topic où l'on veut vérifier.Voici les deux fonctions concernant le dépannage des actionneurs par exemple:
exemple d'une fonction actionneur : fonction dépannage actionneurs
//DEPANNAGE
void MainWindow::DepActON()
{
qDebug() <<"publication topic relais à l'état 1";
QByteArray message = "0";
quint8 qos = 1;
client.publish(QLatin1String("relaisDep"),message,qos);
flick=true;
qDebug() << "flick = " << flick;
if(flick == true){
ui->enMarche->setStyleSheet("background-color:green");
ui->enArret->setStyleSheet("background-color:");
}
}
void MainWindow::DepActOFF()
{
qDebug() <<"publication topic relais à l'état 0";
QByteArray message = "1";
quint8 qos = 1;
client.publish(QLatin1String("relaisDep"),message,qos);
flick=false;
qDebug() << "flick = "<< flick;
if(flick == false){
ui->enArret->setStyleSheet("background-color:red");
ui->enMarche->setStyleSheet("background-color:");
}
}
Pour le dépannage des capteurs, le plus simple est de modifier le topic dans la fonction capteur, puis de vérifier si le voyant info capteur reçu s'allume en orange. Voici à quoi ressemble la 1ère page:
- une 2ème page montre des icones représentant la machine.Lorsqu'il y a un moteur d'un des postes manuels et/ou le convoyeur automatique:
Les icônes s'allumeront en orange lorsqu'un moteur était actif.
- la 3ème page était celle qui permet de démarrer le convoyeur:
Chaque boutons moteur convoyeur ON et moteur convoyeur OFF sont reliés à des fonctions avec des publications sur des topic dès qu'on appuie sur le bouton.
- Les 3 dernières sont consacrées aux différents postes. Pour ce semestre, on s'est concentré sur le poste 3, c'est pour cela qu'il y a certains actionneurs qui peuvent être pilotés manuellement. Le principe est le même que les boutons pour le convoyeur (une fonction qui comporte une publication de topic avec un bouton. En allant à la page poste 3, vous verrez différents actionneurs qui peuvent être actionnés depuis l'interface.