1

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. enter image description here

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?

manidos
  • 3,244
  • 4
  • 29
  • 65
  • This discussion is related https://stackoverflow.com/questions/7414187/powershell-job-event-action-with-form-not-executed – manidos Jun 30 '19 at 18:02

1 Answers1

0

I've got a solution to my problem, but it feels very hacky. I simply added System.Windows.Forms.Timer. It fires every 1ms and executes a handler that processes serial port input data and updates GUI if necessary.

Screenshot:

enter image description here

Code

Github

manidos
  • 3,244
  • 4
  • 29
  • 65