Bonjour à tous, je vous expose mon probleme :
Je suis en train de réaliser un programme en C/C++ sous linux avec kate, permettant l'envoi de trames Modbus au format RTU a un MeshGate, relié en liaison RS232 à mon PC.
Ce MeshGate est lui-meme en communication avec des "noeuds" par onde radio-électriques, qui mesurent la consommation électrique de divers équipements : Energie active, réactive et apparente ainsi que la tension et l'intensité.
Tout ce que je souhaite c'est envoyer des trames a cet équipement, ce que je n'arrive pas bien entendu... Les trames sont en hexadecimal, du type suivant
F7 03 00 01 00 01 90 3C avec
F7 -> Adresse du peripherique
03 -> Read/Write
00 01 -> Registre a interroger
00 05 -> Longueur
90 3C -> CRC
Quelques renseignements sur le matos ici---> http://www.lem.com/hq/fr/content/view/276/304/
J'utilise une classe RS232 pour la communication qui est deja faite, et dieu sait que c'est bien ennuyeux d'utiliser un source fait par une autre personne que soit
J'ai bien configuré le port avec minicom aux memes parametres que le peripherique.
Voici ma classe :
Ainsi que mes fonctions :
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 //---------------------------------------------------------------------------- #ifndef RS232_H #define RS232_H //---------------------------------------------------------------------------- #include <stdlib.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <termios.h> #include <string.h> #include <time.h> //---------------------------------------------------------------------------- #define COM1 "/dev/ttyS0" #define COM2 "/dev/ttyS1" //---------------------------------------------------------------------------- #define BPS9600 9600 #define BPS19200 19200 #define BPS57600 57600 #define BPS115200 115200 //---------------------------------------------------------------------------- #define BIT8 8 #define BIT7 7 //---------------------------------------------------------------------------- #define STOP1 1 #define STOP2 2 //---------------------------------------------------------------------------- #define PAS_DE_PARITE -1 #define PARITE_PAIRE 0 #define PARITE_IMPAIRE 1 //---------96------------------------------------------------------------------- #define AVEC_FINAL 0 #define SANS_FINAL 1 //---------------------------------------------------------------------------- #define AVEC_TIME_OUT true #define SANS_TIME_OUT false //---------------------------------------------------------------------------- #define OK 0 #define ERREUR -1 #define TIMEOUT -2 #define RIEN_RECU 1 //---------------------------------------------------------------------------- class tRS232 { private: termios Config; char MessageConfigurer[30]; int fd; //Descripteur de fichier int Configurer(const char* pPort,int Vitesse,int NbBits,int Parite,int NbStop); //------------------------------ public: tRS232(void); tRS232(const char* pPort,int Vitesse,int NbBits,int Parite,int NbStop); ~tRS232(); void AfficherMessageConfigurer(); int EnvoyerOctet(unsigned char Car); int Envoyer(char* pChaine); // Recevoir Nb caracteres int Recevoir(int Nb,char* pChaine); // Recevoir une chaine se terminant par un caractere donne // (\r, \n ou autre) // avec ou sans time out int Recevoir(char Fin, char* pChaine, int Mode); int Recevoir(char Fin, char* pChaine,int Mode, int Attente); // Recevoir une série de caractees avec time out int RecevoirCaractere(unsigned char* Caractere, int Attente); int returnfd(); } ; #endif
Ainsi que mon main :
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 #include "tRs232.h" //----------------------------------------------------------------------------- int tRS232::Configurer(const char* pPort,int Vitesse,int NbBits,int Parite,int NbStop) { int Res; //Ouverture du port série if(!strcmp(pPort, "COM1")) fd = open("/dev/ttyS0",O_RDWR);// | O_NONBLOCK); else if(!strcmp(pPort, "COM2")) fd = open("/dev/ttyS1",O_RDWR );//| O_NONBLOCK); if (fd == -1) { strcpy(MessageConfigurer, "Erreur lors de l'ouverture du port !"); exit (-1); } else { strcpy(MessageConfigurer, "Ouverture du port reussie."); // Suppression de l'echo Config.c_lflag &= ~(ECHO) ; Config.c_iflag = IGNBRK | IGNPAR; Config.c_oflag = 0; Config.c_cflag = CREAD | CLOCAL; // Vitesse switch (Vitesse) { case BPS9600: Config.c_cflag |= B9600;break; case BPS19200: Config.c_cflag |= B19200;break; case BPS57600: Config.c_cflag |= B57600;break; case BPS115200: Config.c_cflag |= B115200;break; default: //fprintf(stderr,"Vitesse non utilisable\n"); strcpy(MessageConfigurer, "Vitesse non utilisable !\n"); exit (-1); } // Taille data switch (NbBits) { case BIT8: Config.c_cflag |= CS8;break; case BIT7: Config.c_cflag |= CS7;break; default: strcpy(MessageConfigurer, "Taille de donnee non conforme !\n"); exit (-1); } // Parite switch (Parite) { case PARITE_PAIRE : Config.c_cflag |= PARENB; break; case PARITE_IMPAIRE : Config.c_cflag |= (PARODD | PARENB);break; default : break; } // Nombre de bits de stop switch(NbStop) { case STOP2 : Config.c_cflag |= CSTOPB;break; } // Application de la configuration Res = tcsetattr(fd, TCSANOW, &Config); if (Res == -1) { strcpy(MessageConfigurer, "Erreur lors de l'application de la configuration\n"); exit (-1); } tcflush(fd, TCIFLUSH); tcflush(fd, TCOFLUSH); } return 0; } //---------------------------------------------------------------------------- void tRS232::AfficherMessageConfigurer() { printf("%s\n\n", MessageConfigurer); } //---------------------------------------------------------------------------- tRS232::tRS232(const char* pPort, int Vitesse, int NbBits, int Parite, int NbStop) { Configurer(pPort,Vitesse,NbBits,Parite,NbStop); } //---------------------------------------------------------------------------- tRS232::tRS232(void) { Configurer(COM1,BPS9600,BIT8,PAS_DE_PARITE,STOP1); } //---------------------------------------------------------------------------- tRS232::~tRS232() { close(fd); } //---------------------------------------------------------------------------- int tRS232::EnvoyerOctet(unsigned char Car) { int Res = write (fd, &Car, 1); return (Res); } //---------------------------------------------------------------------------- int tRS232::Envoyer(char* pChaine) { int Res = write (fd, pChaine, strlen(pChaine)); return (Res); } //---------------------------------------------------------------------------- int tRS232::Recevoir(int Nb, char* pChaine) { int i = 0; char Car; int Res; do { Res = read (fd, &Car, 1); if (Res > 0) { pChaine[i] = Car; i++; } } while (i < Nb); pChaine[i] = '\0'; return i; } //---------------------------------------------------------------------------- int tRS232::Recevoir(char Fin, char* pChaine, int Mode) { int i = 0; char Car = 0x00; int Res; do { Res = read(fd, &Car, 1); if (Res > 0) { pChaine[i] = Car; i++; } } while (Car != Fin); if (Mode == SANS_FINAL) i--; pChaine[i] = '\0'; tcflush(fd, TCIFLUSH); return i; } //---------------------------------------------------------------------------- int tRS232::Recevoir(char Fin, char* pChaine, int Mode, int Attente) { int i = 0; char Car = 0x00; int Res; time_t TimeRef; time_t Time; TimeRef = time(&TimeRef); do { Res = read(fd, &Car, 1); if (Res > 0) { TimeRef = time(&TimeRef); pChaine[i] = Car; i++; } Time = time(&Time); if ((Time - TimeRef) >= Attente) { pChaine[i] = '\0'; return TIMEOUT; } } while (Car != Fin); if (Mode == SANS_FINAL) i--; pChaine[i] = '\0'; tcflush(fd, TCIFLUSH); return i; } //---------------------------------------------------------------------------- int tRS232::RecevoirCaractere(unsigned char* Caractere, int Attente) { int Res; unsigned char Car; time_t TimeRef; time_t Time; TimeRef = time(&TimeRef); do { Time = time(&Time); Res = read (fd, &Car, 1); } // while(Res == -1); while((Res <1) && ((Time - TimeRef) < Attente)); if (Res > 0) { *Caractere = Car; return OK; } // return TIMEOUT; return Res; } //----------------------------------------------------------------------------- int tRS232::returnfd() { return fd; }
Voici le resultat dans mon terminal, le programme reste dans mon while, il ne recoit apparament rien sur le port serie :
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 #include <stdio.h> #include <unistd.h> #include "tRs232.h" #include <iostream> using namespace std; int main(void) { int b,c,res; tRS232* instance = new tRS232("COM1", BPS115200, BIT8, PAS_DE_PARITE, STOP1); instance -> AfficherMessageConfigurer(); unsigned char chaine[8] = {0xF7, 0x03, 0x00, 0x01, 0x00, 0x01, 0x90, 0x9C}; unsigned char chaine2[8]=" "; char chaine3[8]=" "; /* int f=open("trame.bin",O_RDWR|O_CREAT,0x777); cout << "envoi..."<<endl; write(f,chaine,8); close(f); */ for (int i=0; i<8; i++) { cout <<"octet "<<i<<" :"<< instance->EnvoyerOctet(chaine[i])<<endl; // if (res!=) break; } cout << "reception ..."<<endl; for(int a=0; a<8; a++) { b = instance->RecevoirCaractere(chaine2+a, 36000000 ); } cout << "resultat : " << b <<endl; for ( int i=0; i<7; i++) { printf("%x ",chaine2[i]); } return 0; }
Je remercie d'avance toute personne qui se penchera sur ce probleme. Je vais bientot etre en vacances, et je ne pourrai pas à nouveau disposer du matériel avant le 5 mai
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 Ouverture du port reussie. octet 0 :1 octet 1 :1 octet 2 :1 octet 3 :1 octet 4 :1 octet 5 :1 octet 6 :1 octet 7 :1 reception ...
Nous avons donc du temps pour reflechir ensemble a plusieurs solutions a mon probleme.
Merci d'avoir pris le temps de lire ce post, si vous avez de la doc a me passer sur ce type de liaison modbus, n'importe quoi, je suis preneur !
Encore merci
Partager