Machsupport Forum

Mach Discussion => VB and the development of wizards => Topic started by: mjzrpr on March 10, 2025, 03:55:23 PM

Title: please help for modbus in macro
Post by: mjzrpr on March 10, 2025, 03:55:23 PM
hi
how to use write button in macro?
i can send hex value with this screen. but i can not send value in macro. please help me. :( :( :( :( :( :( :(

- Attachments and other options
Title: Re: please help for modbus in macro
Post by: mjzrpr on March 10, 2025, 04:00:09 PM
also by modbus poll software its works fine.
Title: Re: please help for modbus in macro
Post by: Peter Homann on March 10, 2025, 06:07:29 PM
Hi,

Have a look at this article I wrote.
https://www.homanndesigns.com/pdfs/Using_Modbus_with_Mach3.pdf

Cheers

Peter.
Title: Re: please help for modbus in macro
Post by: mjzrpr on March 11, 2025, 02:35:17 AM
hello peter
I hope you well.
thanks for help.
I do your guidance pdf.
when test window is same attached picture the write button work fine. but its dont work.
the io bord have 8 out put. get a integer value from 1 to 256. value 4 means 3th output. value 5 means output1+output3.
Title: Re: please help for modbus in macro
Post by: mjzrpr on March 11, 2025, 02:37:16 AM
dear mr peter
why we can not use a simple code in macro such as: sendmodbus(coil,adress, . ., value)
whit out brain.
Title: Re: please help for modbus in macro
Post by: mjzrpr on March 11, 2025, 02:50:51 AM
I want just send integer value 0 to 255 can you tell me whats is correct  for this picture (modbus configuration window)?
the io bord work fine with test window (modbus serial control manitor window)
Title: Re: please help for modbus in macro
Post by: mjzrpr on March 11, 2025, 02:53:51 AM
I want use this io bord
Title: Re: please help for modbus in macro
Post by: mjzrpr on March 11, 2025, 03:13:30 AM
when I use sendserial("test") in macro. mach3 can send data to serial port. but it can just send string not hex.
if I can send hex (01 06 00 01 00 04 D9 C9) its means value 4 in modbus and the output 3 is actived.
can you help me to send hex to serial port?
Title: Re: please help for modbus in macro
Post by: Graham Waterworth on March 12, 2025, 12:56:00 PM
Have you tried it this way :-

sendserial("test" & Chr(D9))

Title: Re: please help for modbus in macro
Post by: mjzrpr on March 13, 2025, 07:53:21 AM
dear Graham Waterworth

thanks for comment. chr(D9) do not add any think to serial port .
Title: Re: please help for modbus in macro
Post by: mjzrpr on March 13, 2025, 12:58:59 PM
dear Graham Waterworth
can you help to send hex 00 (chr(nul)) in serial port?
for example: 01 06 00 08 00 DE 88 50
Title: Re: please help for modbus in macro
Post by: Graham Waterworth on March 13, 2025, 01:06:24 PM
From the Mach3 manual

SendSerial
Sub SendSerial(Data As String)
This function send the String Data to the serial port specified in the Config-
>GeneralConfig serial port configuration. This provides transmit-only capability, at any
supported BAUD rate.
Arguments:
String message to be sent to configured serial device
Return Value:
None
Example:
‘ Send “Hello, world!” to serial device
SendSerial(“Hello, world!” & chr(10) & char(13))
Title: Re: please help for modbus in macro
Post by: TPS on March 14, 2025, 12:47:38 PM
from the VBScript_Command manual:

Chr Function
   Chr(int)

so if you want to send a Hex D9 it must be:

Chr(217)

Hex D9 -> Int 217

just to give the Chr function a real chance
 
Title: Re: please help for modbus in macro
Post by: TPS on March 14, 2025, 01:05:00 PM
if you prefere your Hex values you can also try this:
Code: [Select]
sendbyte1 = &H01
sendbyte2 = &H06
sendbyte3 = &H00
sendbyte4 = &H01
sendbyte5 = &H00
sendbyte6 = &H04
sendbyte7 = &HD9
sendbyte8 = &HC9

SendSerial Chr(sendbyte1)+ _
Chr(sendbyte2)+ _
Chr(sendbyte3)+ _
Chr(sendbyte4)+ _
Chr(sendbyte5)+ _
Chr(sendbyte6)+ _
Chr(sendbyte7)+ _
Chr(sendbyte8)


just one way of thousand's
Title: Re: please help for modbus in macro
Post by: mjzrpr on April 01, 2025, 03:13:18 AM
if you prefere your Hex values you can also try this:
Code: [Select]
sendbyte1 = &H01
sendbyte2 = &H06
sendbyte3 = &H00
sendbyte4 = &H01
sendbyte5 = &H00
sendbyte6 = &H04
sendbyte7 = &HD9
sendbyte8 = &HC9

SendSerial Chr(sendbyte1)+ _
Chr(sendbyte2)+ _
Chr(sendbyte3)+ _
Chr(sendbyte4)+ _
Chr(sendbyte5)+ _
Chr(sendbyte6)+ _
Chr(sendbyte7)+ _
Chr(sendbyte8)


just one way of thousand's

Dear TPS
thanks so much
the hex byte "00" is not write on port monitor (its ignored). according to attached picture, Also, instead of D9 and C9 characters, 55 and 45 were sent to port.
Is this solvable or not?  Thank you very much for your answer.
thanks and regards
Title: Re: please help for modbus in macro
Post by: TPS on April 01, 2025, 07:01:52 AM
ok, had to dig a bit deeper, this sendserial function look's like to be a bit bugy.
copy the attached DLL file to C:\Mach3 and use this code:
Code: [Select]

' *****************************************************************************************************
'
' Mach3 / Cypress Enable script code to use the ELEKTOR Serial.dll Dynamic Link Library for serial port
' communication and control from a Mach3 script.
'
' *****************************************************************************************************


' Pass in the portnumber to open (1 for COM1, 2 for COM2 etc). Get the port number in return if successfull.
Declare Function OpenCOM Lib "Serial.dll" (ByVal Port As Integer) As Integer

' Closes the opened port, no parameters to pass. Always returns 0.
Declare Function CloseCOM Lib "Serial.dll" As Integer

' Gets the Windows handle.
Declare Function GetHandle Lib "Serial.dll" As Integer

' Pass in a character to be sent. Datatype was declared as Char but no such type exists in Cypress, Integer seems to work if handled properly.
Declare Function SendCharCOM Lib "Serial.dll" (ByVal ch As Integer) As Integer

' Function expects an Integer sent as ByRef ("pointer to an integer") and returns TRUE if data is available
Declare Function ReadCharCOM Lib "Serial.dll" (ByRef ch As Integer) As Boolean

' Returns true if a COM port with the passed in number exists and is free to use.
Declare Function COMPortExists Lib "Serial.dll" (ByVal Port As Integer) As Integer

' Gets the port number of the currently opend port, zero if no port is opened (?)
Declare Function GetPortNr Lib "Serial.dll" As Integer

' 0=None, 1=odd, 2=even, 3=mark 4=space?????
Declare Function ParitySet Lib "Serial.dll"(ByVal par As Integer) As Boolean

' 4-8 are valid
Declare Function BitsPerByteSet Lib "Serial.dll" (ByVal pbp As Integer) As Boolean

' Any baudrate is valid, returns false if not possible.
Declare Function BaudRateSet Lib "Serial.dll" (ByVal BaudRate As Long) As Boolean

' 0=1 stopbit, 1=1.5 stopbit, 2=2 stopbits. (1.5 may not be valid on all hardware)
Declare Function StopBitsSet Lib "Serial.dll" (ByVal stp As Integer) As Boolean

' ************************** End of function declaration for the Serial.dll library ***********************************


Sub Main
On Error GoTo HandleIt

Dim TxChar   As Integer
Dim TxString As String
Dim ComPort As Integer

ComPort =1

sendbyte1 = &H01
sendbyte2 = &H06
sendbyte3 = &H00
sendbyte4 = &H01
sendbyte5 = &H00
sendbyte6 = &H04
sendbyte7 = &HD9
sendbyte8 = &HC9

'try to open the Comport
If OpenCom(ComPort) <> ComPort Then ' Open COM port
MsgBox("Couldn't open COM port!!")
Result = CloseCom() ' Close the port.
Exit Sub ' Nothing left to do, exit
End If

ParitySet(0) ' Set parity to NONE
BitsPerByteSet(8) ' Set databits to 8
StopBitsSet(0) ' Set stopbits to 1
BaudrateSet(9600) ' Set baudrate to 9600

'send the byte's
SendCharCOM(Asc(Chr(sendbyte1)))
SendCharCOM(Asc(Chr(sendbyte2)))
SendCharCOM(Asc(Chr(sendbyte3)))
SendCharCOM(Asc(Chr(sendbyte4)))
SendCharCOM(Asc(Chr(sendbyte5)))
SendCharCOM(Asc(Chr(sendbyte6)))
SendCharCOM(Asc(Chr(sendbyte7)))
SendCharCOM(Asc(Chr(sendbyte8)))

Result = CloseCom() ' Close the port.

Exit Sub

' *************************************************************************************************************************
HandleIt:
' If an error occurs we must close the port or it will be left open and unusable.
MsgBox("An unexpected error occured. Closing comport and Exiting" & CloseCom())
Exit Sub
' *************************************************************************************************************************
 
End Sub       




Title: Re: please help for modbus in macro
Post by: mjzrpr on April 03, 2025, 02:18:18 AM
dear TPS
thanks for answer. now it can send hex 00 but it send line by line. is it possible for you to solve how to send in single line?

I trying below but not working:
Code: [Select]
'send the byte's
SendCharCOM Asc(Chr(sendbyte1))+ _
                        Asc(Chr(sendbyte2))+ _
                        Asc(Chr(sendbyte3))
thanks and regards
Title: Re: please help for modbus in macro
Post by: TPS on April 03, 2025, 04:57:42 AM
can't get what you mean line by line.

if i trace data here i can see that the raw data is ok, and no aditional between the single bytes.
Title: Re: please help for modbus in macro
Post by: TPS on April 03, 2025, 05:08:13 AM
made a second test with a real serial link to a second PC and using an other serial port monitor.
same result.
Title: Re: please help for modbus in macro
Post by: mjzrpr on April 03, 2025, 07:11:41 AM
Dear TPS
thanks for answer. attached pic show line by line output vs single line.
I use vb script windows in mach3 for testing code and serial port monitor.
when the hex data send line by line the receiver side don't receive command. when use Modbus pull software its work correctly because it can be send hex in single line.
thanks
Title: Re: please help for modbus in macro
Post by: TPS on April 03, 2025, 09:44:06 AM
ok, here a solution by usig directly Win API

Code: [Select]
'---------------BEGIN-OF-DECLARATIONS------------------------------------------------------------------------------
Private Type DCB
  DCBlength As Long
  BaudRate As Long
  fBitFields As Long
  wReserved As Integer
  XonLim As Integer
  XoffLim As Integer
  ByteSize As Integer
  Parity As Integer
  StopBits As Integer
  XonChar As Integer
  XoffChar As Integer
  ErrorChar As Integer
  EofChar As Integer
  EvtChar As Integer
  wReserved1 As Integer
End Type

' The structure of the fBitFields field.
' FieldName             Bit #     Description
' -----------------     -----     ------------------------------
' fBinary                 1       Windows does not support nonbinary mode transfers, so this member must be =1.
' fParity                 2       If =1, parity checking is performed and errors are reported
' fOutxCtsFlow            3       If =1 and CTS is turned off, output is suspended until CTS is sent again.
' fOutxDsrFlow            4       If =1 and DSR is turned off, output is suspended until DSR is sent again.
' fDtrControl             5,6     DTR flow control (2 bits)
' fDsrSensitivity         7       The driver ignores any bytes received, unless the DSR modem input line is high.
' fTXContinueOnXoff       8       XOFF continues Tx
' fOutX                   9       If =1, TX stops when the XoffChar character is received and starts again when the XonChar character is received.
' fInX                   10       Indicates whether XON/XOFF flow control is used during reception.
' fErrorChar             11       Indicates whether bytes received with parity errors are replaced with the character specified by the ErrorChar.
' fNull                  12       If =1, null bytes are discarded when received.
' fRtsControl            13,14    RTS flow control (2 bits)
' fAbortOnError          15       If =1, the driver terminates all I/O operations with an error status if an error occurs.
' fDummy2                16       reserved

'---------fBitFields-------------
Const F_BINARY = 1
Const F_PARITY = 2
Const F_OUTX_CTS_FLOW = 4
Const F_OUTX_DSR_FLOW = 8

' DTR Control Flow Values.
Const F_DTR_CONTROL_ENABLE = &H10
Const F_DTR_CONTROL_HANDSHAKE = &H20

Const F_DSR_SENSITIVITY = &H40
Const F_TX_CONTINUE_ON_XOFF = &H80
Const F_OUT_X = &H100
Const F_IN_X = &H200
Const F_ERROR_CHAR = &H400
Const F_NULL = &H800

' RTS Control Flow Values
Const F_RTS_CONTROL_ENABLE = &H1000
Const F_RTS_CONTROL_HANDSHAKE = &H2000
Const F_RTS_CONTROL_TOGGLE = &H3000

Const F_ABORT_ON_ERROR = &H4000

'---------Parity flags--------
Const EVENPARITY = 2
Const MARKPARITY = 3
Const NOPARITY = 0
Const ODDPARITY = 1
Const SPACEPARITY = 4

'---------StopBits-----------
Const ONESTOPBIT = 0
Const ONE5STOPBITS = 1
Const TWOSTOPBITS = 2

'-----------------------------------------------------------------------------------------------
Private Type COMMTIMEOUTS
  ReadIntervalTimeout As Long
  ReadTotalTimeoutMultiplier As Long
  ReadTotalTimeoutConstant As Long
  WriteTotalTimeoutMultiplier As Long
  WriteTotalTimeoutConstant As Long
End Type
'-----------------------------------------------------------------------------------------------

' Constants for the dwDesiredAccess parameter of the CreateFile() function
Const GENERIC_READ = &H80000000
Const GENERIC_WRITE = &H40000000

' Constants for the dwShareMode parameter of the CreateFile() function
Const FILE_SHARE_READ = &H1
Const FILE_SHARE_WRITE = &H2

' Constants for the dwCreationDisposition parameter of the CreateFile() function
Const CREATE_NEW = 1
Const CREATE_ALWAYS = 2
Const OPEN_EXISTING = 3

' Constants for the dwFlagsAndAttributes parameter of the CreateFile() function
Const FILE_ATTRIBUTE_NORMAL = &H80
Const FILE_FLAG_OVERLAPPED = &H40000000

'-----------------------------------------------------------------------------------------------
' Error codes reported by the CreateFile().
' More error codes with descriptions are available at MSDN
Const ERROR_FILE_NOT_FOUND = 2
Const ERROR_ACCESS_DENIED = 5
Const ERROR_INVALID_HANDLE = 6


Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, _
        ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, _
        ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, _
        ByVal hTemplateFile As Long) As Long

Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function SetCommState Lib "kernel32" (ByVal hFile As Long, lpDCB As DCB) As Long
Private Declare Function GetCommState Lib "kernel32" (ByVal hFile As Long, lpDCB As DCB) As Long

Private Declare Function SetCommTimeouts Lib "kernel32" (ByVal hFile As Long, _
        lpCommTimeouts As COMMTIMEOUTS) As Long

Private Declare Function GetCommTimeouts Lib "kernel32" (ByVal hFile As Long, _
        lpCommTimeouts As COMMTIMEOUTS) As Long

Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, _
         ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) _
         As Long

Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, _
         ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, _
         ByVal lpOverlapped As Long) As Long

'---------------END-OF-DECLARATIONS------------------------------------------------------------------------------

Public Sub Init_Com()
    Dim rc As Long
   
    Dim h As Long
    h = CreateFile("\\.\COM1", GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
    ' For serial port numbers higher than 9, see this HOWTO

    If h = -1 Then
'        rc = Err.LastDllError
        Select Case rc ' Two typical error codes when trying to open a serial port:
         Case ERROR_ACCESS_DENIED  ' - The serial port opened by another application
           MsgBox "The serial port is used by another program"
         Case ERROR_FILE_NOT_FOUND ' - The serial port does not exist, check the port name specified in the CreateFile()
           MsgBox "The serial port does not exist"
         Case Else
           MsgBox "CreateFile failed, the error code is " & Str(rc)
        End Select
        Exit Sub
    End If

    Dim d As DCB ' The DCB structure and the SetCommState() function allow to set the baud rate and the byte size of the serial port.
    rc = GetCommState(h, d)
    d.ByteSize = 8
    d.BaudRate = 9600
    d.fBitFields = F_BINARY ' Windows does not support non-binary data transfers so the flag must always be set in the DCB structure.

    ' Another example how to set some flags in the DCB:
    ' d.fBitFields = F_BINARY Or F_PARITY Or F_RTS_CONTROL_ENABLE

    d.StopBits = ONESTOPBIT
    d.Parity = NOPARITY
    rc = SetCommState(h, d)
    If rc = 0 Then
      rc = Err.LastDllError
      MsgBox "SetCommState failed, the error code is " & Str(rc)
    End If


    Dim timeouts As COMMTIMEOUTS ' Because we don't want communication timeouts to hang the VB code,
    rc = GetCommTimeouts(h, timeouts)  ' we need to specify the maximum time Windows will wait for incoming data
    timeouts.ReadIntervalTimeout = 3  ' The max. time in milliseconds between arrival of any two bytes
    timeouts.ReadTotalTimeoutConstant = 20 ' The max. time the ReadFile() function will wait for data.
    timeouts.ReadTotalTimeoutMultiplier = 0
    rc = SetCommTimeouts(h, timeouts)
    If rc = 0 Then
      rc = Err.LastDllError
      MsgBox "SetCommTimeouts failed, the error code is " & Str(rc)
      GoTo close_and_exit
    End If

   
    ' Sending an array of 8 bytes to a remote device.

    Dim bWrite(1 To 4) As Integer
    bWrite(1) = &H0601
    bWrite(2) = &H0100
    bWrite(3) = &H0400
    bWrite(4) = &HC9D9
   
   
   
    Dim wr As Long
    rc = WriteFile(h, bWrite(1), 8, wr, 0) ' The wr indicates how many bytes were went to the port.
    If rc = 0 Then
      rc = Err.LastDllError
      MsgBox "WriteFile failed, the error code is " & Str(rc)
      GoTo close_and_exit
    End If
   

close_and_exit:
    rc = CloseHandle(h) ' In VBA, always execute this call. Or you will receive the ERROR_ACCESS_DENIED next time when opening the port
                        ' and you will need to reload Word/Excel/Access to free the port.
End Sub



Title: Re: please help for modbus in macro
Post by: mjzrpr on April 03, 2025, 11:56:17 AM
Dear TPS
thanks so mush for your great help. now its work correctly. 
best regards
Title: Re: please help for modbus in macro
Post by: Peter Homann on April 03, 2025, 06:59:49 PM
Hi,

I just realised  that you were still working on this.
Why didn't you use the Modbus plugin to set up the communications with the DK16SPR. The article I wrote and referenced explains how to do this?
http://www.homanndesigns.com/pdfs/Using_Modbus_with_Mach3.pdf

Cheers,

Peter
Title: Re: please help for modbus in macro
Post by: TPS on April 04, 2025, 12:33:05 AM
Hi,

I just realised  that you were still working on this.
Why didn't you use the Modbus plugin to set up the communications with the DK16SPR. The article I wrote and referenced explains how to do this?
http://www.homanndesigns.com/pdfs/Using_Modbus_with_Mach3.pdf

Cheers,

Peter

i realy don't know, just helped to send some hex vaules via serial port.
Title: Re: please help for modbus in macro
Post by: vonswarrior on April 09, 2025, 07:19:31 AM
Hi, how do you activate a signal in vbscript macro to enable a output signal in modbus
Title: Re: please help for modbus in macro
Post by: TPS on April 09, 2025, 12:29:05 PM
SetOutBit (addr, bit)
ResetOutBit(addr, bit)