【发布时间】:2019-07-28 07:52:54
【问题描述】:
我正在尝试与接受/发送 16 位值的 PLC 通信,每个位都允许检查是否发生。
为此,我一直在尝试使用 .Net BitArray,但结果并不成功。
底层结构由两个字节的数组组成,两个字节都用值 0 初始化。
当我使用这些字节之一创建一个新的位数组时,我希望得到一个将 8 个值设置为 false 的数组。 情况并非如此。
如果字节值为 0,则位数组的长度和计数也为零。虽然我可以假设前导零被丢弃,但这似乎非常违反直觉。
当我使用值为 200 的字节创建位数组时,我希望得到一个包含 8 个值的数组(True、True、False、False、True、False、False、False) .但是,我得到一个长度和计数为 200?
的位数组代码目前是这样的:
Private FaultBits as Byte = 0
Public Sub SetBitValue(index As Integer, value As Boolean)
Try
If index < 0 Then
Throw New Exception("Index is below zero!")
End If
If index > 7 Then
Throw New Exception("Index out of bounds! Maximum allowed index value is 7")
End If
'If BitConverter.IsLittleEndian Then
'ToDo
'End If
Dim bitArray_Section As BitArray = Nothing
bitArray_Section = New BitArray(FaultBits)
'bitArray_Section.Length = 8 'Truncates incorrectly
bitArray_Section.Item(index) = value 'Set the individual bit
FaultBits = ConvertToByte(bitArray_Section) 'Set back to byte
Catch ex As Exception
Throw New Exception("clsFaultBits : SetBitValue : w. Index " & index & " : Exception : " & ex.Message())
End Try
End Sub
还有 get 等价物:
Public Function GetBitValue(index As Integer) As Boolean
Try
If index < 0 Then
Throw New Exception("Index is below zero!")
End If
If index > 7 Then
Throw New Exception("Index out of bounds! Maximum allowed index value is 7")
End If
Dim bitArray_Section As BitArray = Nothing
bitArray_Section = New BitArray(FaultBits)
'bitArray_Section.Length = 8
Return bitArray_Section.Item(index)
Catch ex As Exception
Throw New Exception("clsFaultBits : GetBitValue : w. Index " & index & " : Exception : " & ex.Message())
End Try
End Function
转换函数,我认为它的长度是 8,这是错误的:
Public Function ConvertToByte(bits As BitArray) As Byte
Try
If bits.Count <> 8 Then
Throw New Exception("Invalid amount of bits!")
End If
Dim returnbyte(1) As Byte
bits.CopyTo(returnbyte, 0)
Return returnbyte(0)
Catch ex As Exception
Throw New Exception("clsFaultBits : ConvertToByte : Exception : " & ex.Message())
End Try
End Function
ByteValue :: BitarrayLength / Count
0 :: 0 / 0
200 :: 200 / 200
10 :: 10 / 10
我想完成什么:
接收一个字节(1-0-0-1-0-0-1-0)
通过读取各个位来启用程序中的布尔值: 检查1、检查4、检查7
设置从 0-0-0-0-0-0-0-0 开始的输出字节的各个位
开启 5 : 0-0-0-0-1-0-0-0
开启 2 : 0-1-0-0-1-0-0-0
发送字节
我是否完全滥用了 BitArray 类?我究竟做错了什么? 什么可以让我更改单个位值而不会陷入这种混乱?
为什么BitArray的长度/计数与Byte的值相同,而不是Byte由多少位组成?
我知道代码尚未考虑字节序。
提前致谢,
已解决:
我没有意识到向 BitArray 发送非数组字节会将其隐式转换为整数,因此 它会创建一个 长度/计数相等的 BitArray字节的值。现在完全说得通了。
这也让我意识到我的编译器警告不会触发隐式转换,因为字节到整数不被视为隐式,因为每当发生隐式转换时我通常都会收到通知。
感谢您的帮助!
【问题讨论】:
-
PLC的API接受什么数据类型?您可以链接到在线文档吗?
-
@djv PLC 接受通过 TCP/IP 发送的字节,它没有直接连接到系统,所以我不知道确切的类型,我可以与它通信并成功接收/发送字节。问题不仅仅是我无法将字节拆分为 8 个布尔值集,我需要知道它试图告诉我什么。 BitArray 类看起来像我需要的,但在这方面它似乎不起作用。
-
那么要检查一个数字中是否设置了某个位,你可以这样做:
Dim nThBitSet As Boolean = (number And n) = n