Piloter une balance
Le code ci-dessous permet le pilotage d'une balance via le port RS232
Auteur :
Jean-Yves GROSEIL
Société R:SOFT
Boulogne-Billancourt (92)
JYGros(at)aol.com
Pour pouvoir piloter une sortie série RS232 il faut :
- Disposer de l'ActiveX : MSComm32.ocx (Microsoft Communications Controls 6.0) se trouvant en principe dans WindowsSystem32
- Enregistrer le contrôle dans la base de registre à l'aide de Outils / Contrôles ActiveX du menu principal de MS Access. Le contrôle est alors visible si on clique sur l'icône ActiveX de la boite à outils d'un formulaire ouvert en mode création.
- Placer le contrôle sur le formulaire (bouton avec un téléphone)
- Dans le module du formulaire (ou un autre module) créer une référence sur : « Microsoft Comm Control » (Pour pouvoir utiliser les constantes liées à MSComm32)
ATTENTION :
Si vous ne disposez pas d'un produit développeur de Microsoft (Visual Basic, Visual Studio) vous ne pourrez pas faire le point [3]. En effet si vous recopiez un fichier MSComm32.ocx téléchargé sur le site de Microsoft ou d'ailleurs, la licence d'utilisation de celui n'est pas enregistrée dans votre base de registre et le point [3] provoque une erreur.
Solution :
Demandez à un ami qui dispose de VB et de Access de faire les opérations [2] + [3] + [4] sur son système et de vous transmettre le formulaire ainsi que MSComm32.ocx si vous ne le possédez pas. Vous pourrez alors, après avoir recopier MSComm32.ocx dans WindowsSystem32, piloter l'objet RSComm à partir de votre système. En effet il faut une licence pour placer l'objet mais pas pour l'utiliser. N'oubliez pas de faire les points [2] et [4] sur votre système.
Dans notre exemple l'objet de type MSComm placé sur le formulaire s'appelle RS232 et on pilote une balance Sartorius qui envoie des messages de 14 caractères.
Le principe est le suivant :
- Initialisation de l'objet RS232 (sur Open du formulaire par exemple) : InitBalance(). Vous devez disposer de la documentation du périphérique pour paramétrer correctement l'objet RS232
- Attendre que l'événement OnComm du contrôle RS232 se produise. Il se produit dès que RS232 a reçu le nombre de caractères paramétré en [1] avec la propriété : Rthreshold
- Traitement du message reçu : TraitReçu(PoidsBalance)
- Fermeture de la liaison : FermeBalance() (sur close du formulaire par exemple)
- Dans notre exemple on reçoit des messages de longueur fixe et le traitement est extrêmement simple. Si le nombre de caractères est variable (Lecture de codes barres par exemple) il faut régler la propriété Rthreshold sur 1 caractère et écrire un programme de traitement TraitReçu (Caractère) qui stocke les données reçues dans une variable Buffer (Utilisation d'une variable Static recommandée : Static Buffer as string, puis Buffer = Buffer & Caractère) et recherche dans Buffer un caractère de fin de message.
EXEMPLE de CODE (embarqué dans le formulaire)
Public Sub KillProcess(NameProcess As String)
Const PROCESS_ALL_ACCESS = 0
Const PROCESS_TERMINATE = (&H1)
Const TH32CS_SNAPPROCESS As Long = 2&
Dim uProcess As PROCESSENTRY32
Dim RProcessFound As Long
Dim hSnapshot As Long
Dim SzExename As String
Dim ExitCode As Long
Dim MyProcess As Long
Dim AppKill As Boolean
Dim AppCount As Integer
Dim i As Integer
Dim WinDirEnv As String
If NameProcess <> "" Then
AppCount = 0
uProcess.dwSize = Len(uProcess)
hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
RProcessFound = ProcessFirst(hSnapshot, uProcess)
Do
i = InStr(1, uProcess.szexeFile, Chr(0))
SzExename = LCase$(Left$(uProcess.szexeFile, i - 1))
WinDirEnv = Environ("Windir") + "\"
WinDirEnv = LCase$(WinDirEnv)
If Right$(SzExename, Len(NameProcess)) = LCase$(NameProcess) Then
AppCount = AppCount + 1
MyProcess = OpenProcess(PROCESS_TERMINATE, False, uProcess.th32ProcessID)
AppKill = TerminateProcess(MyProcess, ExitCode)
Call CloseHandle(MyProcess)
End If
RProcessFound = ProcessNext(hSnapshot, uProcess)
Loop While RProcessFound
Call CloseHandle(hSnapshot)
End If
End Sub
Private Sub RS232_OnComm()
' OnComm est déclenché quand la balance a envoyé N caractères
' N correspond à la propriété [RThreshold] de l'objet MSComm
Dim OK As Boolean, Statut As Long, Reçu As Variant
Dim PoidsBalance As Long, MsgErr As String
Statut = Me![RS232].CommEvent
' La balance a envoyé 14 caractères : [BB] [PPPPPPP] [ ] [C] [E] [CR+LF]
' [PPPPPPP] correspond au poids sous la forme 99999.9
Reçu = Me![RS232].Input
PoidsBalance = Mid(Reçu, 3, 7) ' [PPPPPPP]
If Statut = comEvReceive Then
TraitReçu PoidsBalance
Else
'MSComm a détecté une erreur
MsgErr = "ERREUR N° " & Statut & " : "
Select Case Statut
Case comEventBreak
MsgErr = MsgErr & "Break signal received"
Case comEventDCB
MsgErr = MsgErr & "Unexpected error retrieving Device Control Block (DCB)"
Case comEventFrame
MsgErr = MsgErr & "Framing error"
Case comEventOverrun
MsgErr = MsgErr & "Port overrun"
Case comEventRxOver
MsgErr = MsgErr & "Receive buffer overflow"
Case comEventRxParity
MsgErr = MsgErr & "Parity error"
Case comEventTxFull
MsgErr = MsgErr & "Transmit buffer full"
Case Else
MsgErr = MsgErr & "???"
End Select
MsgBox MsgErr, vbExclamation
End If
' On vide le buffer avant le prochain événement OnCom
' En effet, si passage de produits pendant l'affichage
' d'un message d'erreur, l'événement OnComm n'est pas
' exécuté puisqu'il est déjà en cours d'exécution et
' pendant ce temps là le buffer se remplit
' Remarque :
' il faut que le traitement de OnComm soit assez rapide
' pour se terminer avant un nouvel événement OnComm
Me![RS232].InBufferCount = 0
End Sub
Private Sub TraitReçu(PoidsBalance As Long)
' Traitement d'une pesée
Dim DB As Database, RS As Recordset
Set DB = CurrentDb()
Set RS = DB.OpenRecordset("SARTORIUS", dbOpenDynaset)
RS.AddNew
RS![Poids] = PoidsBalance
RS.Update
End Sub
Private Sub FermeBalance()
If Me![RS232].PortOpen = True Then
Me![RS232].PortOpen = False
End If
End Sub