On one side, I have an arduino
connected via USB cable. It calls Serial.println("ready")
every 100 miliseconds in an infinite loop.
On another side, I have a powershell script with winforms
gui that has two buttons Click and Close. The script opens serial port and starts listening to DataReceived
event.
Expected behaviour
When an event is received its message is printed to the console.
Actual behaviour
When no actions are performed nothing is printed to the console, but each time I click on the Click button I get the following output:
GOT VALUE FROM READLINE: ready
GOT VALUE FROM READLINE: ready
GOT VALUE FROM READLINE: ready
GOT VALUE FROM READLINE: ready
Click
The same output is produced when I click on the Close button.
Additional info
It's as if the process falls asleep until I do some actions. Upon waking up it spits out everything it had received in its buffer. I think it has something to do with how powershell event queue
works. I'm out of depth here, good sirs.
Code
function main {
begin {
$global:latestPortMessage = ''
$form = createForm
$port = createAndOpenPort
}
process {
subscribeToPortEvents $port
[void]$form.ShowDialog()
}
end {
}
}
##### GUI CREATION HELPERS
function createForm {
Add-Type -AssemblyName System.Windows.Forms
[Windows.Forms.Application]::EnableVisualStyles()
$FormStartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
$form = New-Object system.Windows.Forms.Form
$form.AutoSize = $true
$form.text = "Serial-test"
$form.TopMost = $false
$form.StartPosition = $FormStartPosition
$clickButton = createClickButton
$closeButton = createCloseButton
$form.controls.add($clickButton)
$form.controls.add($closeButton)
$form
}
function createClickButton {
$button = New-Object system.Windows.Forms.Button
$button.BackColor = "#e66b6b"
$button.text = "Click"
$button.width = 100
$button.height = 100
$button.Font = 'Microsoft Sans Serif,10,style=Bold'
$button.margin = 0
$button.Add_Click({ onClickButton })
$button
}
function createCloseButton {
$button = New-Object system.Windows.Forms.Button
$button.BackColor = "#e66b6b"
$button.text = "Close"
$button.width = 100
$button.height = 100
$button.location = '100,0'
$button.Font = 'Microsoft Sans Serif,10,style=Bold'
$button.margin = 0
$button.Add_Click({ onCloseButton })
$button
}
function onClickButton {
Write-Host "Click"
}
function onCloseButton {
closePort
unsubscribeFromPortEvents
$form.close()
}
##### PORT RELATED HELPERS
function createAndOpenPort {
param($portName = 'COM7', $baudRate = 9600)
$port = New-Object System.IO.Ports.SerialPort $portName,$baudRate,None,8,one
$port.open()
$port
}
function subscribeToPortEvents {
param($port)
Register-ObjectEvent -InputObject $port -EventName "DataReceived" -Action {
# $value = $Sender.ReadExisting()
$value = $Sender.ReadLine()
if ($value) {
Write-Host "GOT VALUE FROM READLINE: $value"
$global:latestPortMessage = $value.substring(0, $value.length - 2)
}
} | Out-Null
}
function unsubscribeFromPortEvents {
$subscribers = Get-EventSubscriber
$subscribers | foreach-object {
if ($_.SourceObject.GetType().FullName -eq "System.IO.Ports.SerialPort") {
Unregister-Event -SourceIdentifier $_.SourceIdentifier
}
}
}
function closePort {
try {
if ($port) {
if ($port.isOpen) {
$port.Close()
}
}
} catch {
logError $_
dumpError $_
}
}
. main
What am I missing?