DarkMatter
DarkMatter

Reputation: 51

Serial Port communication using PowerShell

I am trying to set up serial port communication with a ViewSonic Display using PowerShell. I send a request for the display status either on or off and should get a 9 digit reply Either 56 48 49 114 108 48 48 49 13 reply for on Or 56 48 49 114 108 48 48 48 13 reply for off When I run the code, I only get a one-digit reply When I add a second read, I get the remaining 8 But when I add a break point and step through it using the debugger, I get all 9 on the first read. Any ideas what could be causing this odd behavior? Any suggestions on any better ways to do this? See code and results below.

PS C:\Users\james\Desktop>  [Byte[]] $request = 0x38, 0x30, 0x31, 0x67, 0x6C, 0x30, 0x30, 0x30, 0x0D
$portreturn = [System.Byte[]]::CreateInstance([System.Byte], 9)
$port = new-Object System.IO.Ports.SerialPort COM3, 9600, None, 8, one
$port.Open()
$port.Write($request, 0, $request.Count)
$port.Read($portreturn, 0, $portreturn.Length)
Write-Host "portreturn1" $portreturn -foreground black -BackgroundColor white
$port.Read($portreturn, 0, $portreturn.Length)
Write-Host "portreturn2" $portreturn -foreground black -BackgroundColor white
$port.Close()

1 portreturn1 56 0 0 0 0 0 0 0 0

8 portreturn2 48 49 114 108 48 48 49 13 0

PS C:\Users\james\Desktop> C:\Users\james\Desktop\VStest2a.ps1

Hit Line breakpoint on 'C:\Users\james\Desktop\VStest2a.ps1:4' [DBG]: PS C:\Users\james\Desktop>>

[DBG]: PS C:\Users\james\Desktop>>

[DBG]: PS C:\Users\james\Desktop>> 9

[DBG]: PS C:\Users\james\Desktop>> portreturn1 56 48 49 114 108 48 48 49 13

[DBG]: PS C:\Users\james\Desktop>>

Picture for clarity: screen shot

Upvotes: 3

Views: 3944

Answers (1)

kunif
kunif

Reputation: 4350

It's not odd behavior, it can happen normally if you use the Read() method on the serial port.

The serial port communicates in 1-byte units at a minimum. There is no concept of packets like TCP/IP.
You need to get and save the data and size of the Read() result and add a process to check if all the data was received normally.
Perhaps by adjusting the value of the ReadTimeout property, it may be possible to finish Read() after receiving all the data.
However, since the initial value should be InfiniteTimeout, changing the value cannot be expected to have any effect.

Alternatively, if all the data you receive is a string, ending in 13(carriage return=\r) and it doesn't appear in the middle of the data, you can use the ReadTo() method.
Or, you could get similar results by calling the ReadLine() method with the NewLine property set to 13(carriage return=\r) in a similar way.

Please try various things.

For example, if the end of the data is 10(line feed=\n), you can call it like this article.
Writing and Reading info from Serial Ports

Upvotes: 1

Related Questions