Hi everybody. I am having problems reading serial data that includes 0x02 and 0x03 ‘characteres’ (STX and ETX).
SerialPort.Read truncates the data at the 0x02 position and I only get the data before the 0x02. I verified that using a Y serial cable connected to my G80 COM3 and to Hyperterminal in parallel. Hyperterm shows all the data, but SerialRead stops reading when it finds a 0x02. If I check for data using SerialPort.BytesToRead after that, it says there is no further data to read.
This is the code:
public static SerialPort COM3 = new SerialPort("COM3");
...
public static void COM3_init() {
COM3.BaudRate=2400;
COM3.ReadTimeout = 0;
COM3.Handshake = Handshake.None;
COM3.Open();
}
...
public static void Thread_Read_COM3() {
while(true) {
if (COM3.BytesToRead > 0)
{
Thread.Sleep(my_wait); // I've tried even with my_wait=3000 to give it time
msg3len = COM3.BytesToRead;
COM3.Read(bCOM3rcv, 0, COM3.BytesToRead);
// At this point I get only the bytes BEFORE the 0x02
// I added this to check again in case the rest of the data is available after reading the first part
Thread.Sleep(my_wait);
if (COM3.BytesToRead > 0) {
// I check for more bytes to read, but there are no more.
}
...
}
Thread.Sleep(100);
}
}
Thanks a lot for your help.
JCP
i belive this code could help you
https://www.ghielectronics.com/docs/15/uart-serial
i am also using TinyCLR ports 0.5.0 and have no problem with handle of this two bytes with [RDM6300 RFID CODE] (https://github.com/valoni/TinyCLR_Drivers/tree/master/TinyCLR%20Os%20Examples/RDM6300/)
1 Like
Thanks a lot for sharing your code and . There must be something I’m doing wrong. I’ll look at your code and try to figure out where my mistakes are.
Have a look at this code. It is running quite happily in many installations of our system in EU hospitals environments.
using System.IO.Ports;
using System.Threading;
namespace PPlusApplicatorID
{
internal class InterfaceIO
{
private readonly SerialPort port;
private readonly byte[] inBuffer = new byte[32];
private readonly byte[] outBuffer = new byte[32];
private readonly Globals g;
private int i;
private int inByte;
private int waitLoop = 100;
private const byte Enq = 0x05;
private const byte Stx = 0x02;
private const byte Etx = 0x03;
public enum Commands : byte
{
GetStatus = 0,
ClearStatusCodes
}
public InterfaceIO(Globals value)
{
this.g = value;
// Instance IO and open the port
this.port = new SerialPort("COM1");
this.port.BaudRate = 9600;
this.port.Parity = Parity.None;
this.port.DataBits = 8;
this.port.StopBits = StopBits.One;
this.port.Handshake = Handshake.None;
this.port.ReadTimeout = Timeout.Infinite;
this.port.Open();
// Clear the buffers down
this.ClearBytes(inBuffer);
this.ClearBytes(outBuffer);
}
public void ClearBytes(byte[] bytes)
{
for (i = 0; i < bytes.Length; i++) // Clear the byte block
{
bytes[i] = 0;
}
}
public void PerformIo()
{
while (true)
{
this.ClearBytes(inBuffer);
this.port.DiscardInBuffer();
inByte = this.port.ReadByte();
g.Led.Flash();
switch (inByte)
{
case Enq: // Get current status
this.ClearBytes(outBuffer);
// Command
this.outBuffer[0] = (byte)Commands.GetStatus;
// Temperature
this.outBuffer[1] = (byte)(this.g.Temperature & 0xFF);
// Applicator 1
this.outBuffer[2] = (byte)(this.g.Applicator1 & 0xFF);
// Applicator 2
this.outBuffer[3] = (byte)(this.g.Applicator2 & 0xFF);
// Filter
this.outBuffer[4] = (byte)(this.g.Filter & 0xFF);
// Status
this.outBuffer[5] = (byte)(this.g.Status);
// Versions
this.outBuffer[6] = this.g.VerMajor;
this.outBuffer[7] = this.g.VerMinor;
// CRC8
this.outBuffer[8] = this.g.Crc8.DoCrc8(this.outBuffer, 8);
this.port.WriteByte(Stx);
this.port.Write(this.outBuffer, 0, 9);
this.port.WriteByte(Etx);
break;
case Stx: // Start a command
this.port.Read(this.inBuffer, 0, 1);
this.ProcessCommand(inBuffer[0]);
break;
default: // Ignore all else
break;
}
Thread.Sleep(10);
}
}
private void ProcessCommand(byte p)
{
waitLoop = 100; // 100 * 10ms = 1 second
switch (p)
{
case (byte)Commands.ClearStatusCodes:
while (this.port.BytesToRead < 3 && --waitLoop > 0)
{
Thread.Sleep(10);
}
if (waitLoop > 0)
{
try
{
this.port.Read(this.inBuffer, 1, 3);
if (this.g.Crc8.CrcCheck(this.inBuffer, 2) && (this.inBuffer[3] == Etx)) // Command was well formed
{
this.g.Status = ErrorFlags.NoError;
this.ClearBytes(outBuffer);
this.outBuffer[0] = (byte)Commands.ClearStatusCodes;
this.outBuffer[1] = (byte)(this.g.Status);
this.outBuffer[2] = this.g.Crc8.DoCrc8(this.outBuffer, 2);
this.port.WriteByte(Stx);
this.port.Write(this.outBuffer, 0, 3);
this.port.WriteByte(Etx);
}
}
catch
{
/* ignore the whole command */
}
}
break;
default:
// Ignore the command
break;
}
}
}
}
1 Like
Perhaps it’s the ReadTimeOut = 0;
The read time-out value was originally set at 500 milliseconds in the Win32 Communications API. This property allows you to set this value. The time-out can be set to any value greater than zero, or set to InfiniteTimeout, in which case no time-out occurs.InfiniteTimeout is the default.
1 Like
Thank you RoSchmi and Ariane_Medical. I try ReadTimeout=Timeout.Infinite;
Regards, JCP
To avoid characters to be interpreted as control characters you can wrap your file or data as base64 string:
byte[] textAsBytes = encoding.GetBytes(text);
encodedText = Convert.ToBase64String(textAsBytes);
2 Likes