mayojiko
Messages postés1Date d'inscriptionmercredi 2 décembre 2009StatutMembreDernière intervention 3 mai 2010
-
3 mai 2010 à 09:15
zoic21
Messages postés1Date d'inscriptionmardi 8 juin 2010StatutMembreDernière intervention29 juin 2010
-
29 juin 2010 à 14:53
Bonjour à tous,
J'effectue dans le cadre de mon BTS un projet portant sur ModBus.
Le but est de codé un module de communication avec un Automate de type Twido de la marque Télémécanique, J'utilise le protocole ModBus TCP afin de dialoguer entre mon PC(sous Windows XP) et l'automate. Le Twido est relié à une panoplie de capteurs il effectue des relevés seul et constamment, mon but est d'interrogé l'automate afin de récupérer les résultats, ou changé l'état d'un registre.
Mon problème est le suivant :
J'arrive à envoyer une trame à l'automate, j'utilise un analyseur de réseaux afin de le vérifier. Cependant je ne réussi pas à réceptionné les trames de l'automate.
J'ai testé plusieurs solution, et cherché un bon moment, mais je n'y arrive pas.
Le principe de mon programme est simple :
- on a une petite fenêtre permettant la connexion à l'automate par TCP
- on rempli des champs permettant de choisir les paramètres de la trame désiré
- puis un bouton d'envoi.
- après l'envoi de la trame un slot recherche une réponse de l'automate
- lorsqu'une réponse est trouvé on la stock dans une variable
- et enfin on traite la réponse.
Voici quelque partis de code portant sur l'envoi et la réception.
// Code du fichier source
#include "modbus.h"
#include "ui_modbus.h"
// CONSTRUCTEUR DU MODBUS
ModBus::ModBus(QWidget *parent)
: QMainWindow(parent), ui(new Ui::ModBus)
{
ui->setupUi(this);
header[0]=00; // Reset des identifiant de transaction.
header[1]=01;
ModBus::connect(&Socket,SIGNAL(readyRead()),this,SLOT(recept())); // Detecte les réponses de l'automate
}
// FONCTION DE CONSTRUCTION DE LA TRAME MODBUS
void ModBus::constTrame()
{
header[2]=00; // Protocol ModBus.
header[3]=00;
header[4]=00; // Longueur de trame de requête.
header[5]=06;
pdu[0]=01; // Identifiant de l'esclave, vu qu'il n'y a que 1 esclave : egale à 1.
switch(ui->Cb_fonction->currentIndex())
{
case 0:{pdu[1]=01;} // Fonction lecture coil
break;
case 1:{pdu[1]=03;} // Fonction lecture registre
break;
case 2:{pdu[1]=05;} // Fonction ecriture coil
break;
case 3:{pdu[1]=06;} // Fonction ecriture registre
break;
default :{qDebug()<<"Mauvaise fonction choisis"<<endl;}
break;
}
// Adresse
pdu[2]=ui->Sb_adress->value()>>8;
pdu[3]=ui->Sb_adress->value()&0x00ff;
// Donnee
pdu[4]=ui->Sb_data->value()>>8;
pdu[5]=ui->Sb_data->value()&0x00ff;
}
// SLOT D'ENVOI DE LA TRAME
void ModBus::on_Bt_Send_clicked()
{
QDataStream out(&Socket);
constTrame();
qDebug()<<"Envoie d'une trame ModBus"<<endl;
qDebug()<<" - envoi de l'header"<<endl; // Ecriture dans le debug
for(int i=0;i<6;i++){
out<<header[i]; // Envoi de la trame
}
qDebug()<<" - envoi du pdu"<<endl; // Ecriture dans le debug
for(int i=0;i<6;i++){
out<>rcvTrame;
bool *ok;
if(rcvTrame!="")
{
for(int i=0;i<6;i++)
{
//header[i]=rcvTrame.toUInt(*ok,10);
}
qDebug()<<" - copie de l'header"<<endl;
for(int i=6;i<rcvTrame.size();i++)
{
pdu[i]=rcvTrame[i];
}
qDebug()<<" - copie du pdu"<<endl;
qDebug()<<" - fin de reponse"<<endl;
}else{
qDebug()<<"erreur : réponse vide"<<endl;;
}
}
// Code du fichier d'entête
#ifndef MODBUS_H
#define MODBUS_H
#include <QtGui/QMainWindow>// Utiliser pour défnir la fenêtre
#include <QTcpSocket> // Utilisation des socket TCP
#include <QDataStream> // Utilisation des data stream pour envoyer les data et en recevoir
#include <QString> // Utilisation des chaines de caractère version Qt
#include <QBitArray> // Utilisation des tableaux d'octects.
#include <QDebug> // Utilisation d'une console de debugage
namespace Ui
{
class ModBus;
}
class ModBus : public QMainWindow
{
Q_OBJECT
public:
ModBus(QWidget *parent = 0);
~ModBus();
private:
Ui::ModBus *ui;
QTcpSocket Socket; // socket TCP utiliser pour la connection
quint8 header[6]; // Contient l'header TCP utiliser pour la trame ModBus
quint8 pdu[6]; // Contient les information de la trame ModBus
quint8 headerR[]; // Contient l'header TCP de réponse de l'automate
quint8 pduR[];// Contient les information de réponse de la trame ModBus, sa longueur peut varier
QByteArray rcvTrame;
// Lié à l'interface
private slots:
void on_Bt_Send_clicked(); // Slot du bouton d'envoie de trame
void constTrame(); // Fonction de construction de la trame
void recept(); // Fonction de reception des données envoyer par l'automate
};
#endif // MODBUS_H
J'ai essayer le QBitArray / QByteArray / QString cependant cela n'a rien données, il est possible que je les ai mal utilisé. Je cherche des piste pour savoir comment réceptionné ses trames ou alors des exemples.
zoic21
Messages postés1Date d'inscriptionmardi 8 juin 2010StatutMembreDernière intervention29 juin 20101 29 juin 2010 à 14:53
Bonjour,
Je suis aussi dans le même cas que vous. J'ai un automate TWIDO et je dois lui envoyer et recevoir des infos de celui-ci. J'ai tester un soft en C# (le langage que j'utilise pour mon projet) mais lors de la connection celui-ci m'envoi un illegal data adresse..... J'aimerais donc savoir si l'un de vous à avancer ou aurai des pistes à me conseiller