为什么串口事件$event.messageData为空?

问题描述 投票:0回答:2

我试图通过“DataReceived”事件从Arduino异步接收串行数据,但$event.messageData始终为空。

这是我到目前为止的代码:

$port = New-Object System.IO.Ports.SerialPort COM7,9600,None,8,one
$port.Open()
$port | Format-List -Property *
Register-ObjectEvent -InputObject $port -EventName "DataReceived" -Action {
  $event | Format-List -Property * | Out-Host
}

这是输出:

PORT

BaseStream             : System.IO.Ports.SerialStream
BaudRate               : 9600
BreakState             : False
BytesToWrite           : 0
BytesToRead            : 0
CDHolding              : False
CtsHolding             : False
DataBits               : 8
DiscardNull            : False
DsrHolding             : False
DtrEnable              : False
Encoding               : System.Text.ASCIIEncoding
Handshake              : None
IsOpen                 : True
NewLine                :

Parity                 : None
ParityReplace          : 63
PortName               : COM7
ReadBufferSize         : 4096
ReadTimeout            : -1
ReceivedBytesThreshold : 1
RtsEnable              : False
StopBits               : One
WriteBufferSize        : 2048
WriteTimeout           : -1
Site                   :
Container              :

EVENT

ComputerName     :
RunspaceId       : 67c40d50-5a9b-4022-974e-0a6a6518c2af
EventIdentifier  : 11
Sender           : System.IO.Ports.SerialPort
SourceEventArgs  : System.IO.Ports.SerialDataReceivedEventArgs
SourceArgs       : {COM7, System.IO.Ports.SerialDataReceivedEventArgs}
SourceIdentifier : 26c24bdb-8085-4e88-828e-44cb7897e416
TimeGenerated    : 6/16/2019 12:52:39 AM
MessageData      :

在arduino端,代码是:

Serial.printlf("ready")

当我使用同步方法时,一切正常

$port = New-Object System.IO.Ports.SerialPort COM7,9600,None,8,one
$port.Open()
$port.ReadLine()

输出

ready
ready
ready
...

请帮忙!

powershell arduino
2个回答
4
投票

$event.MessageData
不是要查询的正确属性 - 它包含通过
-MessageData
cmdlet 引发 custom 事件时传递到
New-Event
参数的自定义数据。

对于 .NET 发起的事件,通常是包含事件特定数据的自动

$EventArgs
变量。

然而,在

[System.IO.Ports.SerialPort]
类型的
DataReceived
事件的特定情况下,似乎数据实际上并未作为事件 argument 传递,您必须使用
$Sender
对象来访问发起
[System.IO.Ports.SerialPort]
实例以调用其
.ReadExisting()
方法,根据官方文档中的 示例代码判断:

$eventJob = 
  Register-ObjectEvent -InputObject $port -EventName "DataReceived" -Action {
    $Sender.ReadExisting() | Out-Host
  }

0
投票

Register-ObjectEvent
有很多缺陷。在 Powershell ISE 中工作,复制粘贴到 powershell 中,但不是作为普通脚本。我的结果和你的一样奇怪。 可能相关:https://github.com/PowerShell/PowerShell/issues/13999。 解决方案:此使用场景请勿使用
Register-ObjectEvent
。 这里是我通过 RS485 读取 Growatt MIC 系列“当前瓦特”的示例,无需 Register-ObjectEvent - 尽管发送和获取二进制数据,而不是字符串。

$Timeout = 4

# Modbus command for "give me your data"
[byte[]]$GetGrowattStatus=(0x01,0x04,0x0b,0xb8,0x00,0x7d,0xb2,0x2a)

$port = New-Object System.IO.Ports.SerialPort "COM3",9600,None,8,one
$port.Open()
$port.Write($GetGrowattStatus,0,$GetGrowattStatus.Count)
# Response is not fast, but wait no more than $Timeout seconds
for ($i=0;$i -lt $Timeout*4;$i++) {
    Start-Sleep -Milliseconds 250
    if ($port.BytesToRead -gt 0) {
        #Write-Verbose $i -Verbose
        $Data=@()
        while ($port.BytesToRead -gt 0) {
           $Data += [byte]$port.ReadByte()
        }
        $GrowattWatt = ($Data[7] * 256 + $Data[8])/10
        $i=[int]::MaxValue
    }
}
$port.Close()
$GrowattWatt
© www.soinside.com 2019 - 2024. All rights reserved.