OK d'accord.
Regarde du côté de ce post, quelqu'un avait eu les même problèmes que toi sur le port série...
OK d'accord.
Regarde du côté de ce post, quelqu'un avait eu les même problèmes que toi sur le port série...
Attention, Wireshark c'est pour les connexions réseaux.
Dans ce post, on voit surtout que le PC ne sait pas gérer du RS485, du coup le gars a acheté un adaptateur RS485 -> RS232... Normal que tu vois rien avec ton hyperterminal !
J'ai pourtant une carte spécialement conçu pour la RS485, une carte ISA équipé de deux ports COM RS485.
Donc l'adaptateur est cette carte dans mon cas non ?
En effet, si tu as les bons pilotes !
Oui les pilotes étaient livrés avec la carte
Donc j'ai mis Hyperterminal sur le port COM respectif.
Mais j'ai du mal à interroger le module via RS485 (c'est du Modbus). Il me faut une réponse du module, et donc un logiciel capable d'écouter sur le port adéquat.
pas évident
Voilà le logiciel adéquat pour écouter ou "sniffer" les ports COM de son PC :
Portmon
C'est simple et efficace comme software
J'ai fais un nouveau petit programme dont je vais vous donner le morceau principal :
J'ai voulu respecter ceci :
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 /* Déclaration des variables */ unsigned char buffer; DWORD nb; unsigned char tab[8]; unsigned int CRC,CRC_MSB,CRC_LSB; int i,k,l; char R; /* Fin déclaration des variables */ /* Constitution de la trame */ tab[0] = 0x01; // adresse de l'esclave tab[1] = 0x06; // code fonction tab[2] = 0x31; // adresse haute tab[3] = 0x30; // adresse basse tab[4] = 0x00; // nombre de mots PF / valeur du mot tab[5] = 0x02; // nombre de mots pf / valeur du mot -> écriture du mot 0A h CRC=0xFFFF; // calcul du CRC for(k=0;k<5;k++) { CRC=tab[k]^CRC; for(l=0;l<7;l++) { R=CRC%2; CRC=CRC>>1; CRC=CRC/2; if(R=1) { CRC=CRC^0xA001; } } } CRC_MSB=CRC_MSB>>CRC; CRC_MSB=CRC_MSB/256; CRC_LSB=CRC_LSB&255; tab[6] = CRC_MSB; //insertion du CRC dans la trame tab[7] = CRC_LSB; cout<<tab[6]<<" "<<tab[7]<<endl; //system("pause"); /* Fin de constitution de la trame */ /* Envoi de la trame */ for(i=0;i<8;i++) { cout<<tab[i]<<endl; buffer=tab[i]; WriteFile(SPort,&buffer,1,&nb,0); } /* Fin d'envoi de la trame */
source
Je veux interroger l'esclave : lecture du mot au registre 30h (en hexa donc), d'une longueur maximal de deux mots 02 h.
Je dois donc recevoir une réponse de l'esclave, ce qui n'est pas le cas malheureusement.
Un problème de CRC ?
Autres choses ?
Dites moi tout ce qui pourrait vous sembler bon à essayer SVP.
Merci d'avance, c'est très important car je coince dessus depuis deux semaines déjà
Est ce qu'il y a un autre moyen d'envoyer une trame, que faire un tableau et de l'incrémenter en envoyant les données une par une ?
Je ne pense pas que ce soit la solution idéale, car le module ne comprend strictement rien à la trame (par tableau) que je lui envoi.
La trame MODbus est-elle pas plus compact que ça ? envoi d'un bloc et non de plusieurs données une par une ?
Merci pour votre aide.
J'ai pas regardé ton code en détail, mais perso je ferai ça avec Boost.Asio.
Tu trouveras un exemple d'implémentation dans les mails de boost ici.
C'est très simple ( celà requiert boost ), et compact.
Evidemment, ce n'est pas la réponse que tu attendais j'imagine, mais je suis prêt à t'aider dans cette tentative.
A voir, je ne sais pas trop encore
Sa traite les ports COM, et le protocole RS485 aussi ?
Je vois que ça peut contrôler les réseau TCP/UDP.
Les ports COM, oui. RS485, je dirai a priori oui. Enfin je vois pas de raisons pour qe ça ne marche pas...
-> http://www.boost.org/doc/libs/1_38_0...rial_port.html
Après, chacun fait comme il veut. C'était juste une suggestion, ou une information...
Autrement, tu peux me remontrer ton code actuel ?
Alors j'ai voulu tester la trame en un bloc, mais je n'arrive pas à compiler :
Déclaration et initialisation du port COM :
Création et envoi de la trame en question :
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 /**************************************************\ * PROGRAMME ECRITURE - LECTURE VIA RS485 * * * \**************************************************/ #include <windows.h> // déclaration des librairies #include <iostream> using namespace std; int main(void) // programme principal { /*************************************************** * INITIALISATION & OUVERTURE PORT COM * * * ***************************************************/ // On crée un handle que l'on initialise à NULL. HANDLE SPort=NULL; DWORD Event; COMMCONFIG tR; // Sport est un handle ( identifiant ) // Pour mieux comprendre les paramètre passés // consultez la fonction CreateFile(); SPort = CreateFile("COM4", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); // Le handle sera le lien entre notre apllication // et le port série. // Ici ce sera le port indiquédans le tableau COM déclaré au début qui sera ouvert. if ( SPort == INVALID_HANDLE_VALUE ) { cout << "Le port selectionne ne peut etre ouvert ou l'est deja"<<endl ; MessageBox(0,"Le port selectionne ne peut etre ouvert ou l'est deja","Erreur",MB_OK); system( "pause" ); } // Vérification de parité désactivée tR.dcb.fParity=NOPARITY; // La taille du mot donnée est de tR.dcb.ByteSize=8; // Un bit de stop tR.dcb.StopBits=ONESTOPBIT; // désactive les Xon-Xoff tR.dcb.fInX=FALSE; tR.dcb.fOutX=FALSE; // Configuration du BaudRate tR.dcb.BaudRate= CBR_9600; // Enregistrer les modifications apportées // au paramètres Xon-Xoff SetCommConfig(SPort, &tR, sizeof(tR)); // On remplit la strucuture COMMTIMEOUTS COMMTIMEOUTS tMyTimeOuts = { 100, 0, 0, 1000, 1000 }; //Enregistre les modifications concernant le CommTimeouts if (!SetCommTimeouts(SPort, &tMyTimeOuts) ) { MessageBox(0,"Erreur de configuration","Erreur",MB_OK); system( "pause" ); } /************* FIN déclaration port COM et Initialisation *************/
erreur : C:\Users\...\rs485_v4\main.cpp|86|error: invalid conversion from `const char*' to `long int'|
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 unsigned char buffer; DWORD nb; long int a; a="010631300002"; buffer=a; WriteFile(SPort,&buffer,12,&nb,0); cout<<endl<<"Trame envoyee..."<<endl; cout<<"Fin de programme"<<endl; Sleep(500); return 0; // Fin de programme }
Je n'arrive pas à compiler du à la variable "a" mal déclarée. Comment la déclarer idéalement ?
Je veux envoyer la trame de cette façon, en un bloc : a="010631300002";
au lieu d'utiliser un tableau pour chaque données.
Est ce une bonne idée ?
Ah, je viens de m'apercevoir que je pouvais passer la ligne suivante :
a="010631300002";
en
a='010631300002';
Cependant, je suis pas sure que ce soit la même chose au bout du compte sur ma liaison série je test ça...
Non, c'est pas la même chose du tout. ' ' retourne la valeur ASCII.
De plus, un unsigned char permet de coder entre 0 et 255 seulement...
Si on regarde la doc de WriteFile, le 2ème paramètre est l'adresse du buffer.
Dès lors, pourquoi ne pas lui donner directement l'adresse d'un buffer valide et complet ?
Ah d'accord, oui c'est bien ce qu'il me semblais. A la limite, ce n'est pas top grave en soit. Je peux faire ma trame sous deux formats aux choix : ASCII ou RTU ( hexadécimale).
Je ne vois pas ce que tu veux dire par là ?
Comment déclariez vous une chaine de caractère de ce format là : 010631300002 ?
Toujours pour envoyer la tram en un bloc, sans utiliser de tableau.
Merci
Si c'est grave !
Ce petit programme m'affiche 925906480. Ce qui n'a rien à voir attention !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 #include <iostream> int main() { int a = '2065406847060'; std::cout << a; return 0; }
IL faut utiliser un tableau, mais pas comme tu 'as fait !
Ca ressemblerait à un truc comme ça :
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 std::vector<unsigned char> tab(12); tab[0] = 0x30; tab[1] = 0x34; tab[2] = 0x30; tab[3] = 0x33; tab[4] = 0x30; tab[5] = 0x32; tab[6] = 0x30; tab[7] = 0x31; tab[8] = 0x32; tab[9] = 0x35; tab[10] = 0x43; tab[11] = 0x41; WriteFile(SPort,&tab, tab.size() ,&nb,0);
Ah, voilà, très bien, je vais tester ça, très bonne idée !
Merci
Je te tiens au courant ...
en déclaration :
unsigned char tab[12];
DWORD nb;
Est ce correct ?
J'ai les erreurs suivantes :
C:\Users\...\rs485_v4\main.cpp|82|error: `vector' is not a member of `std'|
C:\Users\...\rs485_v4\main.cpp|82|error: expected `;' before "tab"|
C:\Users\...\rs485_v4\main.cpp|96|error: request for member `size' in `tab', which is of non-class type `unsigned char[12]'|
Je ne comprend pas vraiment la syntaxe utilisée poukill
Peux tu m'expliquer en quelques mots, ça peut éventuellement m'aider.
J'en suis pas loin là de ma tram
Merci
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager