Skip to content

Instantly share code, notes, and snippets.

@freretuc
Created June 11, 2017 10:53
Show Gist options
  • Save freretuc/661fc037b7e33f2baf17a9ccace96d3c to your computer and use it in GitHub Desktop.
Save freretuc/661fc037b7e33f2baf17a9ccace96d3c to your computer and use it in GitHub Desktop.
Functions to convert byte to object or objects to byte (Snap7 VB.NET)
Module modPLCFunctions
' Converti depuis C#
' https://github.com/mesta1/Sharp7-example/blob/master/Sharp7Library/Sharp7.cs
' "decimicros" between 0001-01-01 00:00:00 and 1970-01-01 00:00:00
Private bias As Int64 = 621355968000000000
Public Function ConvertBCDtoByte(ByVal B As Byte) As Integer
Return ((B >> 4) * 10) + (B And &HF)
End Function
Public Function ConvertBytetoBCD(ByVal value As Integer) As Byte
Return CByte((((value / 10) << 4) Or (value Mod 10)))
End Function
Public Function BufferGetBit(ByVal Buffer As Byte(), ByVal BytePosition As Integer, ByVal BitPosition As Integer) As Boolean
Dim Mask As Byte() = {&H1, &H2, &H4, &H8, &H10, &H20, &H40, &H80}
If BitPosition < 0 Then BitPosition = 0
If BitPosition > 7 Then BitPosition = 7
Return CBool(Buffer(BytePosition) And Mask(BitPosition))
End Function
Public Function BufferSetBit(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal BitPosition As Integer, ByVal Value As Boolean)
Dim Mask As Byte() = {&H1, &H2, &H4, &H8, &H10, &H20, &H40, &H80}
If BitPosition < 0 Then BitPosition = 0
If BitPosition > 7 Then BitPosition = 7
If Value Then
Buffer(BytePosition) = CByte(Buffer(BytePosition) Or Mask(BitPosition))
Else
Buffer(BytePosition) = CByte(Buffer(BytePosition) And Not Mask(BitPosition))
End If
End Function
Public Function BufferGetSInt(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As Integer
Dim Value As Integer = Buffer(BytePosition)
If Value < 128 Then
Return Value
Else
Return CInt(Value - 256)
End If
End Function
Public Function BufferSetSInt(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As Integer)
If Value < -128 Then Value = -128
If Value > 127 Then Value = 127
Buffer(BytePosition) = CByte(Value)
End Function
Public Function BufferGetInt(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As Int16
Return CShort((Buffer(BytePosition) << 8) Or (Buffer(BytePosition + 1)))
End Function
Public Function BufferSetInt(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As Integer)
Buffer(BytePosition) = CByte(Value >> 8)
Buffer(BytePosition + 1) = CByte(Value And &HFF)
End Function
Public Function BufferGetDInt(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As Int32
Dim Result As Int32
Result = Buffer(BytePosition)
Result <<= 8
Result += Buffer(BytePosition + 1)
Result <<= 8
Result += Buffer(BytePosition + 2)
Result <<= 8
Result += Buffer(BytePosition + 3)
Return Result
End Function
Public Function BufferSetDInt(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As Integer)
Buffer(BytePosition + 3) = CByte(Value And &HFF)
Buffer(BytePosition + 2) = CByte((Value >> 8) And &HFF)
Buffer(BytePosition + 1) = CByte((Value >> 16) And &HFF)
Buffer(BytePosition) = CByte((Value >> 24) And &HFF)
End Function
Public Function BufferGetLInt(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As Int64
Dim Result As Int64
Result = Buffer(BytePosition)
Result <<= 8
Result += Buffer(BytePosition + 1)
Result <<= 8
Result += Buffer(BytePosition + 2)
Result <<= 8
Result += Buffer(BytePosition + 3)
Result <<= 8
Result += Buffer(BytePosition + 4)
Result <<= 8
Result += Buffer(BytePosition + 5)
Result <<= 8
Result += Buffer(BytePosition + 6)
Result <<= 8
Result += Buffer(BytePosition + 7)
Return Result
End Function
Public Function BufferSetLInt(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As Int64)
Buffer(BytePosition + 7) = CByte(Value And &HFF)
Buffer(BytePosition + 6) = CByte((Value >> 8) And &HFF)
Buffer(BytePosition + 5) = CByte((Value >> 16) And &HFF)
Buffer(BytePosition + 4) = CByte((Value >> 24) And &HFF)
Buffer(BytePosition + 3) = CByte((Value >> 32) And &HFF)
Buffer(BytePosition + 2) = CByte((Value >> 40) And &HFF)
Buffer(BytePosition + 1) = CByte((Value >> 48) And &HFF)
Buffer(BytePosition) = CByte((Value >> 56) And &HFF)
End Function
Public Function BufferGetUSInt(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As Byte
Return Buffer(BytePosition)
End Function
Public Function BufferSetUSInt(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As Byte)
Buffer(BytePosition) = Value
End Function
Public Function BufferGetUInt(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As UInt16
Return (Buffer(BytePosition) << 8) Or (Buffer(BytePosition + 1))
End Function
Public Function BufferSetUInt(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As UInt16)
Buffer(BytePosition) = CByte(Value >> 8)
Buffer(BytePosition + 1) = CByte(Value And &HFF)
End Function
Public Function BufferGetUDInt(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As UInt32
Dim Result As UInt32
Result = Buffer(BytePosition)
Result <<= 8
Result += Buffer(BytePosition + 1)
Result <<= 8
Result += Buffer(BytePosition + 2)
Result <<= 8
Result += Buffer(BytePosition + 3)
Return Result
End Function
Public Function BufferSetUDInt(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As UInt32)
Buffer(BytePosition + 3) = CByte(Value And &HFF)
Buffer(BytePosition + 2) = CByte((Value >> 8) And &HFF)
Buffer(BytePosition + 1) = CByte((Value >> 16) And &HFF)
Buffer(BytePosition) = CByte((Value >> 24) And &HFF)
End Function
Public Function BufferGetULInt(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As UInt64
Dim Result As UInt64
Result = Buffer(BytePosition)
Result <<= 8
Result += Buffer(BytePosition + 1)
Result <<= 8
Result += Buffer(BytePosition + 2)
Result <<= 8
Result += Buffer(BytePosition + 3)
Result <<= 8
Result += Buffer(BytePosition + 4)
Result <<= 8
Result += Buffer(BytePosition + 5)
Result <<= 8
Result += Buffer(BytePosition + 6)
Result <<= 8
Result += Buffer(BytePosition + 7)
Return Result
End Function
Public Function BufferSetULInt(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As UInt64)
Buffer(BytePosition + 7) = CByte(Value And &HFF)
Buffer(BytePosition + 6) = CByte((Value >> 8) And &HFF)
Buffer(BytePosition + 5) = CByte((Value >> 16) And &HFF)
Buffer(BytePosition + 4) = CByte((Value >> 24) And &HFF)
Buffer(BytePosition + 3) = CByte((Value >> 32) And &HFF)
Buffer(BytePosition + 2) = CByte((Value >> 40) And &HFF)
Buffer(BytePosition + 1) = CByte((Value >> 48) And &HFF)
Buffer(BytePosition) = CByte((Value >> 56) And &HFF)
End Function
Public Function BufferGetByte(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As Byte
Return Buffer(BytePosition)
End Function
Public Function BufferSetByte(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As Byte)
Buffer(BytePosition) = Value
End Function
Public Function BufferGetWord(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As UInt16
Return BufferGetUInt(Buffer, BytePosition)
End Function
Public Function BufferSetWord(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As UInt16)
BufferSetUInt(Buffer, BytePosition, Value)
End Function
Public Function BufferGetDWord(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As UInt32
Return BufferGetUDInt(Buffer, BytePosition)
End Function
Public Function BufferSetDWord(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As UInt32)
BufferSetUDInt(Buffer, BytePosition, Value)
End Function
Public Function BufferGetLWord(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As UInt64
Return BufferGetULInt(Buffer, BytePosition)
End Function
Public Function BufferSetLWord(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As UInt64)
BufferSetULInt(Buffer, BytePosition, Value)
End Function
Public Function BufferGetReal(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As Single
Dim Value As UInt32 = BufferGetUDInt(Buffer, BytePosition)
Dim bytes As Byte() = BitConverter.GetBytes(Value)
Return BitConverter.ToSingle(bytes, 0)
End Function
Public Function BufferSetReal(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As Single)
Dim FloatArray As Byte() = BitConverter.GetBytes(Value)
Buffer(BytePosition) = FloatArray(3)
Buffer(BytePosition + 1) = FloatArray(2)
Buffer(BytePosition + 2) = FloatArray(1)
Buffer(BytePosition + 3) = FloatArray(0)
End Function
Public Function BufferGetLReal(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As Double
Dim Value As UInt64 = BufferGetULInt(Buffer, BytePosition)
Dim bytes As Byte() = BitConverter.GetBytes(Value)
Return BitConverter.ToDouble(bytes, 0)
End Function
Public Function BufferSetLReal(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As Double)
Dim FloatArray As Byte() = BitConverter.GetBytes(Value)
Buffer(BytePosition) = FloatArray(7)
Buffer(BytePosition + 1) = FloatArray(6)
Buffer(BytePosition + 2) = FloatArray(5)
Buffer(BytePosition + 3) = FloatArray(4)
Buffer(BytePosition + 4) = FloatArray(3)
Buffer(BytePosition + 5) = FloatArray(2)
Buffer(BytePosition + 6) = FloatArray(1)
Buffer(BytePosition + 7) = FloatArray(0)
End Function
' Fonction S7 DATE_AND_TIME
Public Function BufferGetDateTime(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As DateTime
Dim Year, Month, Day, Hour, Min, Sec, MSec As Integer
Year = ConvertBCDtoByte(Buffer(BytePosition))
If Year < 90 Then
Year += 2000
Else
Year += 1900
End If
Month = ConvertBCDtoByte(Buffer(BytePosition + 1))
Day = ConvertBCDtoByte(Buffer(BytePosition + 2))
Hour = ConvertBCDtoByte(Buffer(BytePosition + 3))
Min = ConvertBCDtoByte(Buffer(BytePosition + 4))
Sec = ConvertBCDtoByte(Buffer(BytePosition + 5))
MSec = (ConvertBCDtoByte(Buffer(BytePosition + 6)) * 10) + (ConvertBCDtoByte(Buffer(BytePosition + 7)) / 10)
Try
Return New DateTime(Year, Month, Day, Hour, Min, Sec, MSec)
Catch ex As System.ArgumentOutOfRangeException
Return New DateTime(0)
End Try
End Function
Public Function BufferSetDateTime(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As DateTime)
Dim Year As Integer = Value.Year
Dim Month As Integer = Value.Month
Dim Day As Integer = Value.Day
Dim Hour As Integer = Value.Hour
Dim Min As Integer = Value.Minute
Dim Sec As Integer = Value.Second
Dim Dow As Integer = CInt(Value.DayOfWeek + 1)
Dim MSecH As Integer = Value.Millisecond / 10
Dim MSecL As Integer = Value.Millisecond Mod 10
If Year > 1999 Then
Year -= 2000
End If
Buffer(BytePosition) = ConvertBytetoBCD(Year)
Buffer(BytePosition + 1) = ConvertBytetoBCD(Month)
Buffer(BytePosition + 2) = ConvertBytetoBCD(Day)
Buffer(BytePosition + 3) = ConvertBytetoBCD(Hour)
Buffer(BytePosition + 4) = ConvertBytetoBCD(Min)
Buffer(BytePosition + 5) = ConvertBytetoBCD(Sec)
Buffer(BytePosition + 6) = ConvertBytetoBCD(MSecH)
Buffer(BytePosition + 7) = ConvertBytetoBCD(MSecL * 10 + Dow)
End Function
' Fonction S7 DATE
Public Function BufferGetDate(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As DateTime
Try
Return New DateTime(1990, 1, 1).AddDays(BufferGetInt(Buffer, BytePosition))
Catch ex As System.ArgumentOutOfRangeException
Return New DateTime(0)
End Try
End Function
Public Function BufferSetDate(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As DateTime)
BufferSetInt(Buffer, BytePosition, CInt((Value - New DateTime(1990, 1, 1)).Days))
End Function
' Fonction S7 TIME_OF_DAY
Public Function BufferGetTOD(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As DateTime
Try
Return New DateTime(0).AddMilliseconds(BufferGetDInt(Buffer, BytePosition))
Catch ex As System.ArgumentOutOfRangeException
Return New DateTime(0)
End Try
End Function
Public Function BufferSetTOD(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As DateTime)
Dim Time As TimeSpan = Value.TimeOfDay
BufferSetDInt(Buffer, BytePosition, CInt(Math.Round(Time.TotalMilliseconds)))
End Function
' Fonction S7 1500 LONG_TIME_OF_DAY
Public Function BufferGetLTOD(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As DateTime
Try
Return New DateTime(Math.Abs(BufferGetLInt(Buffer, BytePosition) / 100))
Catch ex As System.ArgumentOutOfRangeException
Return New DateTime(0)
End Try
End Function
Public Function BufferSetLTOD(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As DateTime)
Dim Time As TimeSpan = Value.TimeOfDay
BufferSetLInt(Buffer, BytePosition, Time.Ticks * 100)
End Function
' S7 1500 LONG_DATE_AND_TIME
Public Function BufferGetLDT(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As DateTime
Try
Return New DateTime((BufferGetLInt(Buffer, BytePosition) / 100) + bias)
Catch ex As System.ArgumentOutOfRangeException
Return New DateTime(0)
End Try
End Function
Public Function BufferSetLDT(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As DateTime)
BufferSetLInt(Buffer, BytePosition, (Value.Ticks - bias) * 100)
End Function
' Fonction S7 1200/1500 DTL DateAndTime
Public Function BufferGetDTLA(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As DateTime
Dim Year, Month, Day, Hour, Min, Sec, MSec As Integer
Year = Buffer(BytePosition) * 256 + Buffer(BytePosition + 1)
Month = Buffer(BytePosition + 2)
Day = Buffer(BytePosition + 3)
Hour = Buffer(BytePosition + 5)
Min = Buffer(BytePosition + 6)
Sec = Buffer(BytePosition + 7)
MSec = BufferGetUDInt(Buffer, BytePosition + 8) / 1000000
Try
Return New DateTime(Year, Month, Day, Hour, Min, Sec, MSec)
Catch ex As System.ArgumentOutOfRangeException
Return New DateTime(0)
End Try
End Function
Public Function BufferSetDTLA(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As DateTime)
Dim Year As Short = CShort(Value.Year)
Dim Month As Byte = CByte(Value.Month)
Dim Day As Byte = CByte(Value.Day)
Dim Hour As Byte = CByte(Value.Hour)
Dim Min As Byte = CByte(Value.Minute)
Dim Sec As Byte = CByte(Value.Second)
Dim Dow As Byte = CByte(Value.DayOfWeek + 1)
Dim NanoSecs As Int32 = Value.Millisecond * 1000000
Dim bytes_short As Byte() = BitConverter.GetBytes(Year)
Buffer(BytePosition) = bytes_short(1)
Buffer(BytePosition + 1) = bytes_short(0)
Buffer(BytePosition + 2) = Month
Buffer(BytePosition + 3) = Day
Buffer(BytePosition + 4) = Dow
Buffer(BytePosition + 5) = Hour
Buffer(BytePosition + 6) = Min
Buffer(BytePosition + 7) = Sec
BufferSetDInt(Buffer, BytePosition + 8, NanoSecs)
End Function
' Fonction S7 STRING
Public Function BufferGetString(ByVal Buffer As Byte(), ByVal BytePosition As Integer) As String
Return System.Text.Encoding.UTF8.GetString(Buffer, BytePosition + 2, CInt(Buffer(BytePosition + 1)))
End Function
Public Function BufferSetString(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As String, ByVal MaxLength As Integer)
Buffer(BytePosition) = CByte(MaxLength)
Buffer(BytePosition + 1) = CByte(Value.Length)
System.Text.Encoding.UTF8.GetBytes(Value, 0, Value.Length, Buffer, BytePosition + 2)
End Function
' Fonction S7 ARRAY_OF_CHARS
Public Function BufferGetChars(ByVal Buffer As Byte(), ByVal BytePosition As Integer, ByVal Size As Integer) As String
Return System.Text.Encoding.UTF8.GetString(Buffer, BytePosition, Size)
End Function
Public Function BufferSetChars(ByRef Buffer As Byte(), ByVal BytePosition As Integer, ByVal Value As String)
Dim MaxLength As Integer = Buffer.Length - BytePosition
If MaxLength > Value.Length Then MaxLength = Value.Length
System.Text.Encoding.UTF8.GetBytes(Value, 0, MaxLength, Buffer, BytePosition)
End Function
End Module
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment