Relever des données sur un réseau modbus via vba [Résolu]

Corentinte - 18 nov. 2014 à 08:37 - Dernière réponse :  corentinte
- 4 févr. 2015 à 11:25
Bonjour,

Dans le cadre d'un projet pour mon stage, je dois relever une valeur contenu sur un DIRIS A40 mis en réseau (Protocol Modbus) via un programme en VBA

Je connais l'adresse IP du DIRIS ainsi que l'adresse décimale (50770) et hexa (C652) de la valeur que je dois relever.

Je ne sais pas trop comment commencer...

Comment me "connecter au Diris" ? et ensuite comment relever la valeur ?

Je connais les bases du VBA, j'ai fait quelques programmes, mais je n'ai jamais fait ce genre de programme...

J'ai fait de nombreuses recherche sur internet mais la je suis perdu...

Pourriez-vous me débloquer ? Ou me donner quelques piste au moins pour la "connexion" avec le diris A40 ?

Je reste à votre disposition si vous avez des questions.

Merci d'avance.



Corentin
Afficher la suite 

Votre réponse

34 réponses

NHenry 14275 Messages postés vendredi 14 mars 2003Date d'inscriptionModérateurStatut 20 octobre 2018 Dernière intervention - 18 nov. 2014 à 12:08
0
Merci
Bonjour,

Regardez du côté du controle Winsock pour gérer la connexion TCP/IP.
Pour le protocole, une recherche de la doc de "Modbus TCP" devrait être d'une grande utilité.
Commenter la réponse de NHenry
corentinte - 18 nov. 2014 à 16:47
0
Merci
Merci NHenry,

Cela semble correspondre à ce dont j'ai besoin en particulier le controle Winsock, mais je suis sous excel 10 et je n'ai pas accès a ce "module" dans outil => Reference, je n'ai rien avec le nom Winsock, cela a changé de nom ? Où est ce normal que je n'ai rien sous excel 10 ?

Merci pour tout.
jordane45 22901 Messages postés mercredi 22 octobre 2003Date d'inscriptionModérateurStatut 20 octobre 2018 Dernière intervention - 18 nov. 2014 à 16:54
Commenter la réponse de corentinte
jordane45 22901 Messages postés mercredi 22 octobre 2003Date d'inscriptionModérateurStatut 20 octobre 2018 Dernière intervention - 18 nov. 2014 à 16:53
0
Merci
Discussion déplacée dans VBA
Commenter la réponse de jordane45
0
Merci
Bonjour,

Je suis toujours un peu bloqué...

Je ne comprends pas où est ce que je dois mettre l'adresse decimale de la valeur que je souhaite relever...

Je vous mets le code que j'ai fait, la connection marche, mais la réception ne retourne rien ! Je ne vois pas trop comment continuer...

Merci d'avance.

Function tuto1()
Dim lData As WSADATA
Dim lsock As Long
Dim lname As SOCKADDR
Dim lRet As Long

' Initialisation de Winsock
If WSAStartup(257, lData) = 0 Then
' Création d'une socket
lsock = socket(AF_INET, SOCK_STREAM, 0)
If lsock <> -1 Then
lname.sin_family = AF_INET ' famille "classique"
lname.sin_port(1) = 502 \ 256 ' première partie du port
lname.sin_port(2) = 502 Mod 256 ' deuxième partie du port
lname.sin_addr = addrfromhost("10.100.114.123") ' adresse du serveur

' Connexion
lRet = Connect(lsock, lname, LenB(lname))

'Vérification connexion OK
If lRet = 0 Then

' Réception des données de connexion
lStrToReceive = Space(1024)
lRet = recvstr(lsock, lStrToReceive, Len(lStrToReceive), 0)

If lRet > 0 Then
lStrToReceive = Left(lStrToReceive, lRet)
Debug.Print "Octets reçus : " & lRet & vbCrLf & lStrToReceive
End If
Else
MsgBox "Le code d'erreur est :" & Err.LastDllError
End If

closesocket lsock

End If
WSACleanup
End If
End Function
NHenry 14275 Messages postés vendredi 14 mars 2003Date d'inscriptionModérateurStatut 20 octobre 2018 Dernière intervention - 19 nov. 2014 à 13:42
As-tu regardé la documentation du protocole Modbus TCP ?
oui, j'ai compris que je devais poser une question, mais je ne comprend pas bien comment poser cette question...

j'ai cru comprendre que la question devais commencer par le numero visé donc je pense 50770 mais ensuite je ne comprend pas du tout comment relever cette valeur !
NHenry 14275 Messages postés vendredi 14 mars 2003Date d'inscriptionModérateurStatut 20 octobre 2018 Dernière intervention - 19 nov. 2014 à 19:42
Le protocole Modbus est un protocole multipoint, un maitre et plusieurs esclaves.

Il y a donc le numéro d'esclave pour dire à qui tu t'adresses et un code fonction pour dire ce que tu veux lui demander.
Et le l'adresse que tu as sert à dire à quel offset chercher les données.

https://en.wikipedia.org/wiki/Modbus
Oui, j'ai bien compris cela.

Ce que je ne comprends pas c'est que :

je me connecte à l'exclave (via le vba)

 ' Connexion           
lRet = Connect(lsock, lname, LenB(lname))


Et ensuite, je n'ai qu'un seul exclave, et je n'ai pas de numéro d'exclave...
Du coup je suis incapable de creer le code à envoyer car celui ci commence par le numéro d'exclave.

Ensuite j'ai compris que je dois envoyer 1 car je cherche une lecture, puis l'adresse C652. Ensuite je doit mettre un mot de controle et celui ci non plus je ne sais pas à quoi il correspond...

donc pour récapituler je dois envoyer XXX.C652.1.XXX

Voici le code où je suis arrivé.

Function tuto1()
Dim lData As WSADATA
Dim lsock As Long
Dim lname As SOCKADDR
Dim lRet As Long

' Initialisation de Winsock
If WSAStartup(257, lData) = 0 Then
' Création d'une socket
lsock = socket(AF_INET, SOCK_STREAM, 0)
If lsock <> -1 Then
lname.sin_family = AF_INET ' famille "classique"
lname.sin_port(1) = 502 \ 256 ' première partie du port
lname.sin_port(2) = 502 Mod 256 ' deuxième partie du port
lname.sin_addr = addrfromhost("10.100.114.123") ' adresse du serveur

' Connexion
lRet = Connect(lsock, lname, LenB(lname))

'Vérification connexion OK
If lRet = 0 Then

If lRet = 0 Then

' Envoi des données
lStrToSend = "XXX.01.C652.XXX" & vbCrLf
lRet = sendstr(lsock, lStrToSend, Len(lStrToSend), 0)
Debug.Print "Octets envoyés : " & lRet & " / " & Len(lStrToSend) & vbCrLf & lStrToSend

' Réception des données
lStrToReceive = Space(1024)
lRet = recvstr(lsock, lStrToReceive, Len(lStrToReceive), 0)

If lRet > 0 Then

lStrToReceive = Left(lStrToReceive, lRet)
Debug.Print "Octets reçus : " & lRet & vbCrLf & lStrToReceive

End If


Else
Debug.Print "Erreur de connexion n° " & Err.LastDllError
End If

closesocket lsock

End If
WSACleanup
End If
End If
End Function



J'ai aussi une autre petite question,

En ce qui concerne le port, est ce bien 502 ? Comment être sur car l'absence de réponse pourrais aussi venir de là ?!
Commenter la réponse de corentinte
corentinte - 20 nov. 2014 à 14:42
0
Merci
Voilà ce que j'ai trouvé sur internet.

j'en conclu donc que je doit envoyer : "03 00050770 00000001"

Mais cela ne fonctionne pas... Je ne reçoit pas de réponse...

Quelqu'un sait où je me serais trompé ?

Ethernet TCP/IP - Protocole Modbus TCPLecture d'une suite de plusieurs registres (Code Fonction 3)

? Requête :
Octet 0 : Code Fonction = 03
Octets 1-2 : Numéro de référence cible (offset)
Octets 3-4 : Nombre de mots à lire (1-125)

? Réponse :
Octet 0 : Code Fonction = 03
Octet 1: Byte count de la réponse (B=2 x Nb de mots)
Octets 2 à(B+1):Valeurs des registres

? Réponse d'exception :
Octet 0 : Code Fonction = 83 (hexa)
Octet 1 : Code d'exception = 01 ou 02
NHenry 14275 Messages postés vendredi 14 mars 2003Date d'inscriptionModérateurStatut 20 octobre 2018 Dernière intervention - 20 nov. 2014 à 18:40
Il te manquue encore des champs :
Identifiant de requête (Déclinaison TCP de Modbus)
Longueur de requête (Déclinaison TCP de Modbus)
Numéro d'esclave (Générique modbus)

Les données sont à coder en binaire, si c'est du modbus TCP ASCII, le binaire doit être transformé en chaine HEXA (sans préfixe no séparateur de groupe)
Merci beaucoup, ton aide m'aide à bien avancer !

Je vais poser deux questions qui vont sans doute parraitre débile, mais je ne comprend pas :
-Comment connaitre le numéro d'esclave ? J'ai beau chercher je ne vois pas où je peux trouver ce numéro...
-Identifiant de requête, ce n'est pas le 03 que j'ai mis au début ?
NHenry 14275 Messages postés vendredi 14 mars 2003Date d'inscriptionModérateurStatut 20 octobre 2018 Dernière intervention - 22 nov. 2014 à 20:16
Bonsoir,

N° esclave : de base, c'est souvent le numéro 1, mais ça peut changer, voir la doc de ton équipement.
L'id requête : c'est le premier champ numérique d'une requête Modbus, il sert à identifier quelle réponse va avec quelle requête, car il est possible en modbus TCP d'envoyer plusieurs requête avant d'avoir reçu la première réponse.

Le code 03 est le code pour la fonction de lecture de mots.
Commenter la réponse de corentinte
corentinte - 16 déc. 2014 à 09:50
0
Merci
Bonjour,

Dans un premier temps merci pour ton aide.

Je suis toujours bloqué mais j'ai bien avancé enfin du moins je pense que ce que j'ai fait avant fonctionne.

Actuellement j'ai donc réussi à me connecter et j'envoie une trame.

Mais je ne reçois rien... enfin si 1024 espace

voici la ligne de code et en dessous le rapport debug.print

'Envoi des données
lStrToSend = Chr(2) + Chr(1) + Chr(3) + Chr(C6) + Chr(52) + Chr(0) + Chr(1) + vbCrLf
lret = sendstr(lsock, lStrToSend, Len(lStrToSend), 0)
Debug.Print "Octets envoyés : " & lret & " / " & Len(lStrToSend) & vbCrLf & lStrToSend
' Réception des données
Sleep 200
lStrToReceive = Space(1024)
lret = recvstr(lsock, lStrToReceive, Len(lStrToReceive), 0)
If lret > 0 Then
'lStrToReceive = Left(lStrToReceive, lRet)
Debug.Print "Octets reçus : " & lret & lStrToReceive
End If



Octets envoyés : 9 / 9
 4 

Octets reçus : 9


J'ai mis un tempo de 200ms pour attendre la réponse mais rien ne viens.... Est ce un problème de tram d'envoi, un problème de reception ou autre ? Je dois avouer que là je suis bloqué... Je cherche depuis plusieurs jours, mais rien...
D'accord,
Je vais continuer de chercher...

Ce que je est ce possible que je lise des parasites où quelque chose comme cela ou est ce que c'est forcément le Diris qui me répond ?

J'ai remarqué que quelque soit le message que j'envoie, systématiquement les 4 premiers caractères me sont retourné à l'identique et la suite est différente...

Je continue de creuser.
Bonjour, j'ai réussi à obtenir quelques documents constructeur qui me manquait.
Je pense que l'erreur viens du code d'envoi, ou de réception.

Y a t il une autre solution que via http://arkham46.developpez.com/articles/office/officeweb/?page=page_8


Est il d'utiliser Winsock avec excel 2010 ?
NHenry 14275 Messages postés vendredi 14 mars 2003Date d'inscriptionModérateurStatut 20 octobre 2018 Dernière intervention - 3 févr. 2015 à 22:40
N'ayant jamais eu besoin de ce composant en VBA (uniquement VB6, en .NET, il y a une implémentation plus complète directement dans le framework), je ne saurais te répondre clairement.
Le tutoriel semble bon.

Sinon, pourquoi te forcer à faire du VBA ? (Oui, je ne me pose la question que maintenant)
Si c'est pour sa "gratuité" (oui, il faut payer Office), il y a des versions express de Visual Studio qui sont disponible gratuitement.
D'accord, Merci pour ton aide !

Je suis contraint d'utiliser VBA car c'est le logiciel seul que j'ai à ma disposition. Je suis dans une grosse société et l'installation de nouveau logiciel m'est interdite...
Bonjour,

Grande nouvelle ! le programme fonctionne désormais !

une petite erreur dans la trame et une dans le code d'envoie!

Je ne peux pas le mettre en ligne car c'est un programme entreprise, mais je suis ok pour répondre aux questions pour ceux qui aurait un programme similaire !

Un grand merci à NHenry pour ton aide !
Commenter la réponse de corentinte

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.