Bonjour à toutes et à tous,

J'ai developpé un programme pour la communication série entre un PC et un automate via Qt avec une IHM. Ce programme me permet aussi (afin de vérifier la bonne communication) d'allumer et d'éteindre des LEDs sur les sorties TOR de cet automate.
Actuellement, j'ai trois fichiers .cpp (et deux fichiers .h) pour réaliser mon programme:
-mon main.cpp
-un fichier nommé mainwindow.ccp (et mainwindow.h) qui s'occupe de créer et gérer la communication série et d'allumer/éteindre les LEDs sur les sorties TOR (le nom du fichier n'est pas judicieux, je sais)
-un fichier nommé SingleApplication.cpp (et SingleApplication.h) qui me permet de n'avoir qu'une seule instance de mon programme lancé à la fois.


Je veux maintenant pouvoir commander mon automate de n'importe quel PC: j'ai donc choisi une solution client/serveur.
Dans mon idée, je crée un nouveau fichier que je nommerai "serveur.cpp" (et serveur.h) qui me permettra de créer un serveur en récupérant l'adresse IP de mon PC et en spécifiant un port de connexion. Ce serveur va recevoir les ordres en provenance de mon application client.

Pour mon application client, je souhaite conserver mon IHM déjà créée (je ne ferai que rajouter les différents widgets dont j'aurais besoin pour la connexion) et je veux que lorsque j'appuie sur un bouton de cette IHM, cela envoie un ordre au serveur.

Par exemple dans mon programme j'ai un slot pour allumer la LED1 qui s'appelle "on_pushButton_LED1_clicked", en gros ce que je veux faire:

J'appuie sur le bouton LED1 de mon interface client => cela envoie l'ordre au serveur d'allumer la led1 => le serveur lance le slot on_pushButton_LED1_clicked

est-ce que vous pouvez m'aider à réaliser ceci (surtout la partie client) ?

Actuellement, pour la partie serveur, j'ai repris le serveur créer dans le TP tchat . Je me doute bien que je vais devoir modifier des choses là deussus mais pour l'instant, je souhaite me concentrer le l'application client

Je ne poste pas de code ici parce que je e sais pas ce qui être vous être utile mais si besoin je l'ai posterai en réponse. Je ne mettrais ici que le code qui me permet la communication série et allumer/éteindre les leds (côté serveur donc) dont je voudrais me servir de base, car mon IHM client sera exactement comme celle de mon application serveur (avec en plus les widgets pour la connexion).

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
#include "mainwindow.h"
#include "SingleApplication.h"
#include "ui_mainwindow.h"
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
 
    initialisation();
    detectionPortCOM();
 
    connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(selectPort(QString)));    //sélection du port COM
    connect(this,SIGNAL(workReady()),this,SLOT(configurationPort()));                   //lancement de la configuration du port série
    connect(timerRepet, SIGNAL(timeout()), this, SLOT(timerRepetTicks()));              //timeout du timer d'envoi de trame
    connect(timerRecep, SIGNAL(timeout()), this, SLOT(timerRecepTicks()));              //timeout du timer de réception de trame
    connect(timerChenillard, SIGNAL(timeout()), this, SLOT(timerChenillardTicks()));    //timeout du timer de changement d'état du chenillard
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
void MainWindow::initialisation()
{
    /*============================
     * Description : Initialisation et declaration des composants
     *               de l'application
     *
     * Created     : 25/09/2013 - 16:20
     *
     *===========================*/
 
    //Initialisation
 
    ui->pushButton_DebutCommunication->setEnabled(false);
    ui->pushButton_LireTrame->setEnabled(false);
    ui->pushButton_Chenillard->setEnabled(false);
    ui->pushButton_StopChenillard->setEnabled(false);
    ui->pushButton_LED1->setEnabled(false);
    ui->pushButton_LED2->setEnabled(false);
    ui->pushButton_LED3->setEnabled(false);
    ui->pushButton_LED4->setEnabled(false);
    ui->pushButton_LED5->setEnabled(false);
    ui->pushButton_LED6->setEnabled(false);
    ui->pushButton_LED7->setEnabled(false);
    ui->pushButton_LED8->setEnabled(false);
 
 
    flagComStarted = false;
    indiceSortieTOR = 0;
    valueTimer = 50;
    for(int i = 0; i < 8; i++)
    {
        sortieTOR[i] = false;
    }
 
    //Declaration
    signalMapper = new QSignalMapper(this);
    serialPort = new QextSerialPort();
 
    //Declaration et definition des timers
    timerRepet = new QTimer(this);
    timerRepet->setSingleShot(false);
    timerRepet->setInterval(1000);
 
    timerRecep = new QTimer(this);
    timerRecep->setSingleShot(false);
    timerRecep->setInterval(10000);
 
    timerChenillard = new QTimer(this);
    timerChenillard->setSingleShot(false);
    timerChenillard->setInterval(20 * valueTimer);      // Choix de la durée du Timeout du timer de changement d'état du chenillard
 
}
 
void MainWindow::detectionPortCOM()
{
    /*=========================================
     * Description : Détection automatique des ports et création des menus
     *               au lancement du programme
     * Created     : 25/09/2013 - 17:00
     * Notes       :
     *=========================================*/
 
    int i = 0;
    ports = QextSerialEnumerator::getPorts();      //recuperation de l'ensemble des ports COM dans une liste
        if(ports.isEmpty())
        {
            ui->menuSelection_portCOM->addMenu("Pas de Port Disponible");
        }
        else
        {
            foreach(QextPortInfo port, ports)          // création d'un lien entre chaque port et une action dans le menu
            {
                QAction *action = new QAction(port.portName, this);
 
                action->setCheckable(true);
                ui->menuSelection_portCOM->addAction(action);
 
                signalMapper->setMapping(action, port.portName);
                connect(action, SIGNAL(triggered()), signalMapper, SLOT(map()));
 
                actions.append(action);
 
                i++;
                nombreTotPortCOM = i;
            }
        }
}
 
void MainWindow::selectPort(QString name)
{
/*=========================================
 * Description : Sélection du port
 * Created     : 25/09/2013 - 17:03
 * Notes       :
 *=========================================*/
    if(!actions.isEmpty())                          // lors d'un clic sur un choix de port, celui-ci est marqué par un tick
    {
        ui->pushButton_Connexion->setEnabled(true);
        foreach (QAction *act, actions)
        {
            act->setChecked(false);
            if(act->text() == name)
            {
                portCOMName = name;
                act->setChecked(true);
            }
        }
    }
}
 
 
 
/*====================================================================================================================================================
 *
 * Partie Gestion des Timers
 *
 *
 *===================================================================================================================================================*/
 
void MainWindow::timerRepetTicks()
{
/*=========================================
 * Description : Traitement à faire lors du timeout du Timer : lancement
 *               de l'envoi des data.
 *
 * Created     : 25/09/2013 - 17:05
 * Notes       :
 *=========================================*/
    if(flagComStarted)
    {
        timerRecep->stop();
        on_pushButton_DebutCommunication_clicked();
        timerRecep->start();
    }
}
 
void MainWindow::timerRecepTicks()
{
/*=========================================
 * Description : Traitement à faire lors du timeout du Timer : lancement
 *               de la lecture des data.
 *
 * Created     : 25/09/2013 - 17:07
 * Notes       :
 *=========================================*/
    if(serialPort->bytesAvailable())
    {
        timerRepet->stop();
        onDataAvailable();
        timerRepet->start();
    }
}
 
void MainWindow::timerChenillardTicks()
{
/*=========================================
 * Description : Traitement à faire lors du timeout du Timer : gestion
 *               des LEDs du Chenillard.
 *
 * Created     : 25/09/2013 - 17:10
 *
 * Notes       :
 *=========================================*/
    sortieTOR[indiceSortieTOR] = !sortieTOR[indiceSortieTOR];           // on fait une séquence de chenillard via cet ensemble de ligne de code
    indiceSortieTOR++;
    if(indiceSortieTOR == 8)
    {
        indiceSortieTOR = 0;
    }
 
    //Affichage de l'etat des LEDs sur un QLabel pour une verification depuis l'IHM
    if(sortieTOR[0]==1)
    {
        ui->label_LED1->setText("LED1 allumée");
    }
    else
    {
        ui->label_LED1->setText("LED1 éteinte");
    }
    if(sortieTOR[1]==1)
    {
        ui->label_LED2->setText("LED2 allumée");
    }
    else
    {
        ui->label_LED2->setText("LED2 éteinte");
    }
    if(sortieTOR[2]==1)
    {
        ui->label_LED3->setText("LED3 allumée");
    }
    else
    {
        ui->label_LED3->setText("LED3 éteinte");
    }
    if(sortieTOR[3]==1)
    {
        ui->label_LED4->setText("LED4 allumée");
    }
    else
    {
        ui->label_LED4->setText("LED4 éteinte");
    }
    if(sortieTOR[4]==1)
    {
        ui->label_LED5->setText("LED5 allumée");
    }
    else
    {
        ui->label_LED5->setText("LED5 éteinte");
    }
    if(sortieTOR[5]==1)
    {
        ui->label_LED6->setText("LED6 allumée");
    }
    else
    {
        ui->label_LED6->setText("LED6 éteinte");
    }
    if(sortieTOR[6]==1)
    {
        ui->label_LED7->setText("LED7 allumée");
    }
    else
    {
        ui->label_LED7->setText("LED7 éteinte");
    }
    if(sortieTOR[7]==1)
    {
        ui->label_LED8->setText("LED8 allumée");
    }
    else
    {
        ui->label_LED8->setText("LED8 éteinte");
    }
}
 
/*====================================================================================================================================================
 *
 * Partie Gestion des bouton poussoir present sur l'IHM
 *
 *
 *===================================================================================================================================================*/
 
 
void MainWindow::on_pushButton_DetectionPortCOM_clicked()
{
/*==============================
* Description : Fonction qui permet de savoir quel port peuvent être utiliser pour
*               la communication serie, donne differentes informations
*
* Created     : 25/09/2013 - 16:30
*
* Notes       : Cette fonction (premiere partie) n'a pas été réalisé par moi, ceci est un simple
*               copier/coller d'une fonction exemple que vous pourrez trouvez
*               a cette adresse: C:\Qt\Qt5.1.1\5.1.1\mingw48_32\examples\serialport\enumerator
*               (exemple pour l'utilisation de QSerialPort)
*=============================*/
 
    //Premiere partie
    QWidget *FenetreDetectionPort = new QWidget;
    FenetreDetectionPort->setWindowTitle(QObject::tr("Info about all available serial ports."));
    QVBoxLayout *layout = new QVBoxLayout;
 
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        QString s = QObject::tr("Port: ") + info.portName() + "\n"
                    + QObject::tr("Location: ") + info.systemLocation() + "\n"
                    + QObject::tr("Description: ") + info.description() + "\n"
                    + QObject::tr("Manufacturer: ") + info.manufacturer() + "\n"
                    + QObject::tr("Vendor Identifier: ") + (info.hasVendorIdentifier() ? QString::number(info.vendorIdentifier(), 16) : QString()) + "\n"
                    + QObject::tr("Product Identifier: ") + (info.hasProductIdentifier() ? QString::number(info.productIdentifier(), 16) : QString()) + "\n"
                    + QObject::tr("Busy: ") + (info.isBusy() ? QObject::tr("Yes") : QObject::tr("No")) + "\n";
 
        QLabel *label = new QLabel(s);
        layout->addWidget(label);
    }
 
    FenetreDetectionPort->setLayout(layout);
    FenetreDetectionPort->show();
}
 
 
 
void MainWindow::on_pushButton_Connexion_clicked()
{
/*=========================================
 * Description : Traitement à faire lors d'un click sur le bouton : activation
 *               des boutons et émission d'un Signal de connexion
 *
 * Created     : 26/09/2013 - 08:23
 * Notes       :
 *=========================================*/
 
    ui->pushButton_DebutCommunication->setEnabled(true);
    ui->pushButton_LireTrame->setEnabled(true);
    ui->pushButton_Chenillard->setEnabled(true);
    ui->pushButton_StopChenillard->setEnabled(true);
    ui->pushButton_LED1->setEnabled(true);
    ui->pushButton_LED2->setEnabled(true);
    ui->pushButton_LED3->setEnabled(true);
    ui->pushButton_LED4->setEnabled(true);
    ui->pushButton_LED5->setEnabled(true);
    ui->pushButton_LED6->setEnabled(true);
    ui->pushButton_LED7->setEnabled(true);
    ui->pushButton_LED8->setEnabled(true);
    emit workReady();
}
 
 
void MainWindow::on_pushButton_DebutCommunication_clicked()
{
/*=========================================
 * Description : Traitement à faire lors d'un click sur le bouton : activation
 *               des boutons et émission d'un Signal de connexion
 *
 * Created     : 26/09/2013 - 08:45
 * Notes       :
 *=========================================*/
    if(!flagComStarted)
    {
        startCom();
        timerRepet->start();
        timerRecep->start();
    }
    else
    {
        Tableau *bufferEmission = configurationPortCheckBox();
    }
}
 
void MainWindow::on_pushButton_Chenillard_clicked()
{
/*=========================================
 * Description : Traitement à faire lors d'un click sur le bouton : lance
 *               le timer contrôlant le chenillard
 *
 * Created     : 26/09/2013 - 08:48
 * Notes       :
 *=========================================*/
    timerChenillard->start();                           // démarrage du timer du chenillard
}
 
void MainWindow::on_pushButton_StopChenillard_clicked()
{
/*=========================================
 * Description : Traitement à faire lors d'un click sur le bouton : arrete
 *               le timer contrôlant le chenillard
 *
 * Created     : 26/09/2013 - 15:42
 * Notes       :
 *=========================================*/
    timerChenillard->stop();                           // arret du timer du chenillard
}
 
void MainWindow::on_pushButton_LireTrame_clicked()
{
/*=========================================
* Description : Traitement à faire lors d'un click sur le bouton : lance
*               la lecture des données
*
* Created     : 26/09/2013 - 08:50
* Notes       :
*=========================================*/
        onDataAvailable();
 
}
 
void MainWindow::on_pushButton_Quitter_clicked()
{
/*=========================================
 * Description : Traitement à faire lors d'un click sur le bouton : quitte
 *               l'application
 *
 * Created     : 26/09/2013 - 08:53
 * Notes       :
 *=========================================*/
    serialPort->close();
    qApp->quit();
}
 
void MainWindow::on_pushButton_LED1_clicked()
{
/*=========================================
* Description : Lorsque l'on appuie sur le pushButon LED1, la LED
*               doit s'allumer ou s'éteindre
*
* Created     : 26/09/2013 - 16:00
* Notes       :
*=========================================*/
 
    sortieTOR[0] = !sortieTOR[0];
    if(sortieTOR[0]==1)
    {
        ui->label_LED1->setText("LED1 allumée");
    }
    else
    {
        ui->label_LED1->setText("LED1 éteinte");
    }
}
 
void MainWindow::on_pushButton_LED2_clicked()
{
/*=========================================
* Description : Lorsque l'on appuie sur le pushButon LED2, la LED
*               doit s'allumer ou s'éteindre
*
* Created     : 26/09/2013 - 16:00
* Notes       :
*=========================================*/
 
    sortieTOR[1] = !sortieTOR[1];
    if(sortieTOR[1]==1)
    {
        ui->label_LED2->setText("LED2 allumée");
    }
    else
    {
        ui->label_LED2->setText("LED2 éteinte");
    }
}
 
void MainWindow::on_pushButton_LED3_clicked()
{
/*=========================================
* Description : Lorsque l'on appuie sur le pushButon LED3, la LED
*               doit s'allumer ou s'éteindre
*
* Created     : 26/09/2013 - 16:00
* Notes       :
*=========================================*/
 
    sortieTOR[2] = !sortieTOR[2];
    if(sortieTOR[2]==1)
    {
        ui->label_LED3->setText("LED3 allumée");
    }
    else
    {
        ui->label_LED3->setText("LED3 éteinte");
    }
}
 
void MainWindow::on_pushButton_LED4_clicked()
{
/*=========================================
* Description : Lorsque l'on appuie sur le pushButon LED4, la LED
*               doit s'allumer ou s'éteindre
*
* Created     : 26/09/2013 - 16:00
* Notes       :
*=========================================*/
 
    sortieTOR[3] = !sortieTOR[3];
    if(sortieTOR[3]==1)
    {
        ui->label_LED4->setText("LED4 allumée");
    }
    else
    {
        ui->label_LED4->setText("LED1 éteinte");
    }
}
 
void MainWindow::on_pushButton_LED5_clicked()
{
/*=========================================
* Description : Lorsque l'on appuie sur le pushButon LED5, la LED
*               doit s'allumer ou s'éteindre
*
* Created     : 26/09/2013 - 16:00
* Notes       :
*=========================================*/
 
    sortieTOR[4] = !sortieTOR[4];
    if(sortieTOR[4]==1)
    {
        ui->label_LED5->setText("LED5 allumée");
    }
    else
    {
        ui->label_LED5->setText("LED5 éteinte");
    }
}
 
void MainWindow::on_pushButton_LED6_clicked()
{
/*=========================================
* Description : Lorsque l'on appuie sur le pushButon LED6, la LED
*               doit s'allumer ou s'éteindre
*
* Created     : 26/09/2013 - 16:00
* Notes       :
*=========================================*/
 
    sortieTOR[5] = !sortieTOR[5];
    if(sortieTOR[5]==1)
    {
        ui->label_LED6->setText("LED6 allumée");
    }
    else
    {
        ui->label_LED6->setText("LED6 éteinte");
    }
}
 
void MainWindow::on_pushButton_LED7_clicked()
{
/*=========================================
* Description : Lorsque l'on appuie sur le pushButon LED7, la LED
*               doit s'allumer ou s'éteindre
*
* Created     : 26/09/2013 - 16:00
* Notes       :
*=========================================*/
 
    sortieTOR[6] = !sortieTOR[6];
    if(sortieTOR[6]==1)
    {
        ui->label_LED7->setText("LED7 allumée");
    }
    else
    {
        ui->label_LED7->setText("LED7 éteinte");
    }
}
 
void MainWindow::on_pushButton_LED8_clicked()
{
/*=========================================
* Description : Lorsque l'on appuie sur le pushButon LED8, la LED
*               doit s'allumer ou s'éteindre
*
* Created     : 26/09/2013 - 16:00
* Notes       :
*=========================================*/
 
    sortieTOR[7] = !sortieTOR[7];
    if(sortieTOR[7]==1)
    {
        ui->label_LED8->setText("LED8 allumée");
    }
    else
    {
        ui->label_LED8->setText("LED8 éteinte");
    }
}
 
 
/*====================================================================================================================================================
 *
 * Partie Gestion des Ports: Configuration, Lecture, Ecriture
 *
 *
 *===================================================================================================================================================*/
 
void MainWindow::configurationPort()
{
    /*=========================================
     * Description : Configure et ouvre la liaison série
     *
     * Created     : 26/09/2013 - 08:56
     *
     * Notes       :
     *=========================================*/
 
    // Configuration de la liaison série
        PortSettings settings;
        settings.BaudRate = BAUD38400;
        settings.DataBits = DATA_8;
        settings.FlowControl = FLOW_OFF;
        settings.StopBits = STOP_1;
        settings.Parity = PAR_NONE;
        settings.Timeout_Millisec = 1000;
 
    // Ouverture de la liaison série et vérification qu'elle est bien ouverte
        serialPort = new QextSerialPort(settings,QextSerialPort::Polling);
        serialPort->setPortName(portCOMName);
        if(!serialPort->open(QIODevice::ReadWrite))
        {
            QMessageBox::critical(this,"erreur","pas moyen d'ouvrir la connexion");
            etatConnexion = "False";
            ui->label->setText(etatConnexion);
        }
        else
        {
            //QMessageBox::information(this,"info","connexion ouverte");
            etatConnexion = "True";
            ui->label->setText(etatConnexion);
        }
}
 
 
 
void MainWindow::onDataAvailable()
{
/*=========================================
 * Description : Lecture du port série et écriture de la sortie dans
 *               un fichier texte
 *
 * Created     : 26/09/2013 - 09:03
 *
 * Notes       :
 *=========================================*/
 
    QByteArray data = serialPort->readAll();    // lit le port RS485
    QString stringData(data.toHex());           // transforme la donnée lue en une string de nombre hexadécimaux
 
// Vérification de la présence de données lues
    if(!data.isEmpty())
    {
        QFile file("TramesLues.txt");
// Ouverture du fichier dans lequel les données lues seront stockées
        if(!file.open(QIODevice::WriteOnly))
        {
            QMessageBox::information(this,"erreur","pas moyen d'ouvrir le fichier");
        }
        else
        {
            qint64 tailleEcrit;                                                                 // variable de vérification pour l'écriture dans le fichier
            //QMessageBox::information(this,"info","fichier ouvert");
            tailleEcrit = file.write(stringData.toStdString().c_str());                         // transforme la string d'hexa et const char* pouvant être écrit dans un fichier
            //QMessageBox::information(this,"info","écrit : " + QString::number(tailleEcrit));
            file.close();
        }
    }
}
 
void MainWindow::startCom()
{
/*=========================================
 * Description : Débute la communication avec l'automate
 *
 * Created     : 26/09/2013 - 09:09
 *
 * Notes       :
 *=========================================*/
    Tableau *testModbus = new Tableau(6);               // création d'un tableau contenant 'MODBUS'
    testModbus->elements[0] = 'M';
    testModbus->elements[1] = 'O';
    testModbus->elements[2] = 'D';
    testModbus->elements[3] = 'B';
    testModbus->elements[4] = 'U';
    testModbus->elements[5] = 'S';
 
    sendTrameWriteModBus(2, 16, 2000, 6, testModbus);   //envoi d'une trame ModBUS, demandant à l'esclave 2 d'écrire 6 mots consécutifs à partir de l'adresse 2000
    flagComStarted = true;
}
 
 
void MainWindow::sendTrameWriteModBus(char adrSlave, char CodeCommande, int adresseData, int nbrData, Tableau *tableau)
{
/*=========================================
 * Description : Formate la trame ModBus et envoi la trame creee
 *
 * Created     :
 *
 * Notes       :
 *=========================================*/
    int variableLocale;
    qint64 nombreOctetsEcris;                                                   // variable de vérification pour l'écriture sur le port
    Tableau *bufferEmissionModBus = new Tableau((tableau->longueur * 2) + 9);   // + 9 car : 7 octets d'entêtes MODBUS, 2 octets de CRC
 
    bufferEmissionModBus->elements[0] = adrSlave;
    bufferEmissionModBus->elements[1] = CodeCommande;
    bufferEmissionModBus->elements[2] = adresseData / 256;
    bufferEmissionModBus->elements[3] = adresseData & 255;
    bufferEmissionModBus->elements[4] = nbrData / 256;
    bufferEmissionModBus->elements[5] = nbrData & 255;
    bufferEmissionModBus->elements[6] = nbrData * 2;
 
    variableLocale = 7;
    for(int i = 0; i < tableau->longueur; i++)
    {
        bufferEmissionModBus->elements[variableLocale] = tableau->elements[i] / 256;
        variableLocale++;
        bufferEmissionModBus->elements[variableLocale] = tableau->elements[i] & 255;
        variableLocale++;
    }
 
    addCRC16(bufferEmissionModBus,bufferEmissionModBus->longueur - 2);          // ajout du CRC sur les deux derniers octets du tableau 'bufferEmissionModBUS'
 
    nombreOctetsEcris = serialPort->write(bufferEmissionModBus->elements, bufferEmissionModBus->longueur);  // écriture sur le port série
 
    tableauEnvoye = bufferEmissionModBus;                                       //variable à utiliser pour vérifier que l'esclave répond correctement (non implémenté)
    //QMessageBox::information(this,"Ecriture Trame MODBUS", QString::number(nombreOctetsEcris) + " octets ont été écris\nNombre d octet a envoyer : " + QString::number(bufferEmissionModBus->longueur));
}
 
 
Tableau* MainWindow::configurationPortCheckBox()
{
/*=========================================
 * Description : Prépare et envoi la trame de contrôle (allumage ou
 *               extinction) des LEDs de l'automate
 *
 * Created     : 26/09/2013 - 11:43
 *
 * Notes       :
 *=========================================*/
    Tableau *bufferEmissionPrepare = new Tableau(1);
 
    bufferEmissionPrepare->elements[0] = 0;
 
    if(sortieTOR[0] == true) bufferEmissionPrepare->elements[0] = bufferEmissionPrepare->elements[0] | 1;
    if(sortieTOR[1] == true) bufferEmissionPrepare->elements[0] = bufferEmissionPrepare->elements[0] | 2;
    if(sortieTOR[2] == true) bufferEmissionPrepare->elements[0] = bufferEmissionPrepare->elements[0] | 4;
    if(sortieTOR[3] == true) bufferEmissionPrepare->elements[0] = bufferEmissionPrepare->elements[0] | 8;
    if(sortieTOR[4] == true) bufferEmissionPrepare->elements[0] = bufferEmissionPrepare->elements[0] | 16;
    if(sortieTOR[5] == true) bufferEmissionPrepare->elements[0] = bufferEmissionPrepare->elements[0] | 32;
    if(sortieTOR[6] == true) bufferEmissionPrepare->elements[0] = bufferEmissionPrepare->elements[0] | 64;
    if(sortieTOR[7] == true) bufferEmissionPrepare->elements[0] = bufferEmissionPrepare->elements[0] | 128;
 
    //QMessageBox::information(this,"etat checkbox",QString::number(bufferEmissionPrepare->elements[0]));
 
    sendTrameWriteModBus(2, 16, 0, 1, bufferEmissionPrepare);           //une fois le tableau créé on doit le formater selon le protocole ModBUS
 
    return bufferEmissionPrepare;                                       //retour d'un tableau, peut être utile durant le débug
}
 
 
/*====================================================================================================================================================
 *
 * Partie Gestion CRC16
 *
 *
 *===================================================================================================================================================*/
 
void MainWindow::addCRC16(Tableau *tableau, int longueur)
{
/*=========================================
 * Description : Prend en entrée un Tableau
 *               Calcul et ajoute à ce tableau deux octets de CRC16
 *
 *               Je n'ai pas créé cette fonction, je ne saurais dire comment elle fonctionne
 * Created     :
 * Notes       :
 *=========================================*/
    long crc16 = 0;
    int boucle1 = 0, boucle2 = 0;
    unsigned char valeurCourante = 0, retenue = 0;
 
    crc16 = 65535;
    for(boucle1 = 0; boucle1 < longueur; boucle1++)
    {
        valeurCourante = tableau->elements[boucle1];
        crc16 = crc16 ^ valeurCourante;
 
        for(boucle2 = 0; boucle2 < 8; boucle2++)
        {
            retenue = crc16 % 2;
            crc16 = crc16 / 2;
            if(retenue == 1)
            {
                crc16 = crc16 ^ 40961;
            }
        }
    }
    tableau->elements[longueur] = crc16 % 256;
    tableau->elements[longueur + 1] = crc16 / 256;
}
 
bool MainWindow::testCRC16(Tableau *tableau, int longueur)
{
/*=========================================
 * Description : Vérifie que le CRC16 reçu dans le tableau est conforme
 *               au contenu du tableau
 *
 *               Je n'ai pas créé cette fonction
 *               Je ne saurais dire comment elle fonctionne
 * Created     :
 * Notes       :
 *=========================================*/
    long crc16 = 0;
    char crc16calcule[2];
    int boucle1 = 0, boucle2 = 0;
    char valeurCourante = 0, retenue = 0;
 
    crc16 = 65535;
    for(boucle1 = 0; boucle1 < longueur; boucle1++)
    {
        valeurCourante = tableau->elements[boucle1];
        crc16 = crc16 ^ valeurCourante;
 
        for(boucle2 = 0; boucle2 < 8; boucle2++)
        {
            retenue = crc16 % 2;
            crc16 = crc16 / 2;
            if(retenue == 1)
            {
                crc16 = crc16 ^ 40961;
            }
        }
    }
    crc16calcule[0] = crc16 % 256;
    crc16calcule[1] = crc16 / 256;
 
    if((crc16calcule[0] == tableau->elements[longueur]) && (crc16calcule[1] == tableau->elements[longueur + 1]))
    {
        return true;
    }
    else
    {
        return false;
    }
 
}