'This code is for the DwyerController and its modbus interconnection
'The Dwyer controller responds immediately to the command
'Each command is provided with a key that allows the gating of the returned Information
' Data transmission is from a serial out of an ESP32 via a MAX 3486
' Data is read back on the same serial
Sub Process_Globals
'Set commands
'Get_MV Gets the measured value
'Set_SV Sents the SV, you have to Add_CRC_Values
'Set_Run Sets the controller to run
'Set_Stop Stops the controller
Dim Get_MV(8) As Byte = Array As Byte(0x01,0x03,0x10,0x00,0x00,0x01,0x80,0xCA)
Dim Set_SV(8) As Byte = Array As Byte(0x01,0x06,0x10,0x01,0x00,0x00,0x00,0x00) '' add data 2 bytes, setting unit 0.1, add CRC
Dim Set_Run(8) As Byte = Array As Byte(0x01,0x05,0x08,0x14,0xFF,0x00,0xCE,0x5E) '1,5,8,20,255,0,206,94
Dim Set_Stop(8) As Byte = Array As Byte(0x01,0x05,0x08,0x14,0x00,0x00,0x8F,0xAE) '1,5,8,20,00,143,174
End Sub
'-----------------------------------------------------------------
' This function extracts the reading returned in a 03 call
' The function checks that the returned function has 03 as
' the second location and that the CRC is correct ( I did not implement this here)
' It then extracts the value read and returns the amswer
' It will only return up To three bytes of information
' This is based on knowing the length of the return from
' the number of bytes in buf[2]
'-----------------------------------------------------------------
Sub Extract_RX_Value (Buf() As Byte) As Int ' extracts the value
'Log("Extact MV value ")
Dim Val As Int
' Dim CRC_Calc As UInt=0
' Dim CRC_Return As UInt=0
' CRC_Return = Bit.Or(Bit.ShiftLeft(Buf(4+Buf(2)),8), Buf(3+Buf(2))) ' the last two bytes (reversed)
' Dim x As Int = 3+Buf(2)
' CRC_Calc = CRC16_2(Buf,x) ' 3+the value buf[2] gives the length
' If Buf(1) = 0x03 And CRC_Return=CRC_Calc Then ' ensures that buf[1]==command 0x03
If Buf(1) = 0x03 Then
Select Buf(2)
Case 1
Val = Buf(3)
Case 2
Val = Bit.Or(Bit.ShiftLeft(Buf(3),8),Buf(4))
Case 3
Val = Bit.Or(Bit.ShiftLeft(Buf(3),16), Bit.ShiftLeft(Buf(4),8))
Val = Bit.Or(Val,Buf(5))
End Select
If Val<30000 And Val>0 Then
Return Val/10+1 ' this Controller sends temp x 10
Else
Return 9999
End If
Else
Return 9999 ' error in message(FC Or CRC)
End If
End Sub
'----------------------------------------------------------------------
' Returns the CRC For a selection of bytes
' buf is the Array the Information is in
' length is the number of bytes in the Array To
' use For the CRC calculation
'----------------------------------------------------------------------
Sub CRC16_2(Buf() As Byte, len As Int) As UInt
Dim CRC2 As UInt = 0xFFFF
For pos = 0 To len-1
CRC2=Bit.XOR(CRC2,Buf(pos))
For i = 8 To 1 Step -1
If Bit.And(CRC2,0x0001) <> 0 Then
CRC2=Bit.ShiftRight(CRC2,1) ' Shift CRCright And XOR 0xA001
CRC2=Bit.XOR(CRC2, 0xA001)
Else ' Else LSB is Not set
CRC2=Bit.ShiftRight(CRC2,1)
End If
Next
Next
Return CRC2
End Sub
'-----------------------------------------------------------------
' This adds the two CRC values in the correct location
' at the end of the Buf file (locations 6 and 7)
' The Buf file has to have two extra locations for the
' addition. len is the same call As the CRC
' calculate value
'-----------------------------------------------------------------
Sub Add_CRC_Values(CRC2 As UInt, len As Int)
Set_SV(len) = Bit.And(CRC2,0x00FF)
Set_SV(len+1) = Bit.And(Bit.ShiftRight(CRC2,8), 0x00FF)
End Sub
'-----------------------------------------------------------------
'Returns True if two arrays are identical, used to ensure
'send and recieve are the same
'-----------------------------------------------------------------------
Sub Array_Test(Buf1() As Byte, Buf2() As Byte) As Boolean
'Log("AddTest1")
Dim Test As Boolean= True
If Buf1.Length<>Buf2.Length Then
Test = False
Return Test
End If
For pos = 0 To Buf1.Length-1
If Buf1(pos) <> Buf2(pos) Then
Test=False
End If
Next
Return Test
End Sub
'-----------------------------------------------------------------
'Send an Array To the Controller via a serial RTX2 via a MAX 3486
'The change of the Mod Read/Write pin timing is quite sensitive as the
'Dywer return is very fast and you can miss it
'-----------------------------------------------------------------
Sub Send_To_Controller(Buf() As Byte)
'log("Send to Controller")
Main.ModbusPin.DigitalWrite(True) 'sets Max3485 To transmit
Delay(15) 'settle time
Main.SendRTX2(Buf)
Delay(10) 'settle time
Main.ModbusPin.DigitalWrite(False) 'sets Max3485 To recieve
End Sub
'-----------------------------------------------------------------
'Send temperature setpoint to Controller
' The send stream has to be adjusted by the temperature SP required
'-----------------------------------------------------------------
Sub SendSP(SPTemp As Int)
Log ("SendingSP ", SPTemp )
SPTemp = SPTemp*10 ' Controller setting is in 0.1 degrees
Set_SV(4) = Bit.And(Bit.ShiftRight(SPTemp,8),0xFF) ' add hex value To transmit file
Set_SV(5) = Bit.And(SPTemp,0xFF) ' add hex value To transmit file
Add_CRC_Values(CRC16_2(Set_SV,6),6) ' Calculates the CRC And appends To end of the control file
Send_To_Controller(Set_SV) ' send the SV To the Controller.
End Sub
'-----------------------------------------------------------------
' Sends RunSignal to Controller
'-----------------------------------------------------------------
Sub SendStartSignal
Log ("Control-Sending Start Signal")
Send_To_Controller(Set_Run) ' Sends a start Signal
End Sub
'-----------------------------------------------------------------
' Sends the SP to the Controller
'-----------------------------------------------------------------
Sub SendSPValue(SP As Int)
Log ("Control -Sending SV Value")
SendSP(SP)
End Sub
'-----------------------------------------------------------------
' Responds To what is returned from the modbus recieve
' The response should be the same as the send got the run/stop/SV commmands
' The response is gated by the number of the Control sent
' Control numbers
' 1 Get the MV
' 2 Run Signal Sent
' 3 Stop Signal Sent
' 4 SV Sent
'-----------------------------------------------------------------
Sub Check_ControlRX(Buffer() As Byte, ControlNo As Int)
Select ControlNo
Case 1
Dim x As Int = Extract_RX_Value(Buffer)
If x =9999 Then 'checks For error
Log("Current MV error")
Else
Main.CurrentMV=x
Log("Current MV is : ",Main.CurrentMV)
End If
Case 2
If Array_Test(Set_Run, Buffer) Then
Log("Controller Running")
End If
Case 3
If Array_Test(Set_Stop, Buffer) Then
Log("Controller Stopped")
End If
Case 4
If Array_Test(Set_SV, Buffer) = True Then
Log( "SV sent to controller")
End If
End Select
End Sub