Skip to content

Instantly share code, notes, and snippets.

@ChrisMoney
Created June 29, 2016 14:29
Show Gist options
  • Save ChrisMoney/66f532c8852e87b611fb04d9dc1d44a8 to your computer and use it in GitHub Desktop.
Save ChrisMoney/66f532c8852e87b611fb04d9dc1d44a8 to your computer and use it in GitHub Desktop.
C# - Read Command Bytes
void IMD1000A.Process(Command cmd, System.IO.Ports.SerialPort _serialPort)
{
try
{
if (!_serialPort.IsOpen)
_serialPort.Open();
LastError = CommandErrorCode.OK;
byte[] cmdPacket = cmd.CommandPacket;
int MAXRETRY = 2;
int respCode = 0;
int retryCount = 0;
CommandState state = CommandState.TryCommand;
while (retryCount < MAXRETRY && state != CommandState.Complete)
{
switch (state)
{
case CommandState.TryCommand:
_serialPort.Write(cmdPacket, 0, cmdPacket.Length);
// get response from dispenser
try { respCode = _serialPort.ReadByte(); }
catch (TimeoutException) { respCode = -1; }
// if enquiry fails, try again
if (respCode == -1 || respCode == NAK)
retryCount++;
else if (respCode != ACK)
throw new Exception("Unexpected response value: " + respCode);
else
{
state = CommandState.TryEnq;
retryCount = 0;
}
continue;
case CommandState.TryEnq:
// try enquiry
_serialPort.BaseStream.WriteByte(ENQ);
try { respCode = _serialPort.ReadByte(); }
catch (TimeoutException) { respCode = -1; }
if (respCode == -1)
retryCount++;
else if (respCode != STX)
throw new Exception("Unexpected response value: " + respCode);
else
{
state = CommandState.ReadResponse;
retryCount = 0;
}
continue;
// read response
case CommandState.ReadResponse:
try
{
byte lenHi = (byte)_serialPort.ReadByte();
byte lenLo = (byte)_serialPort.ReadByte();
// command expected back
byte expectedBcc = (byte)(STX ^ lenLo ^ lenHi ^ ETX);
byte[] arr = new byte[lenHi << 8 | lenLo];
for (int i = 0; i < arr.Length; i++)
{
byte b = (byte)_serialPort.ReadByte();
arr[i] = b;
expectedBcc ^= b;
}
byte etx = (byte)_serialPort.ReadByte();
if (etx != ETX)
throw new Exception("Unexpected value at ETX: " + etx);
byte bcc = (byte)_serialPort.ReadByte();
if (bcc != expectedBcc || arr[1] != cmd.CM || arr[2] != cmd.PM)
{
state = CommandState.TryEnq;
retryCount++;
continue;
}
if (arr[0] != 'P' && arr[0] != 'N')
throw new Exception("Unexpected Command success byte: " + arr[0]);
cmd.IsSuccessful = (arr[0] == 'P');
if (cmd.IsSuccessful)
{
cmd.DataOut = new byte[arr.Length - 3];
Array.Copy(arr, 3, cmd.DataOut, 0, cmd.DataOut.Length);
}
else
{
LastError = (CommandErrorCode)arr[3];
cmd.ErrorCode = LastError;
}
state = CommandState.Complete;
continue;
}
catch (TimeoutException)
{
state = CommandState.TryEnq;
retryCount++;
continue;
}
}
}
if (retryCount >= MAXRETRY)
{
_serialPort.BaseStream.WriteByte(ENQ);
try
{
respCode = _serialPort.ReadByte();
throw new TimeoutException();
}
catch (TimeoutException)
{
throw;
}
}
}
finally
{
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment