using System; using System.Collections.Generic; using System.Text; using System.IO.Ports; using System.Threading; namespace Robotics.Serial { class SerialCom { public delegate void BotEventHandler(object sender, EventArgs ev); public static event BotEventHandler BotEvent; public string ComPort = "COM1"; public static SerialPort serialPort1;// = new SerialPort(); public bool isOpen = false; // --------------------------------------------------------------------------- /// /// Decode Message from the Roboboard /// /// /// // --------------------------------------------------------------------------- public static string DecodeMessage(string command) { string message = command.Substring(0, command.Length - 2); string target = ""; target += (char)command[command.Length - 2]; target += (char)command[command.Length - 1]; //----------------------------------------------------------- // check CRC Int16 tmpcrc = 0; for (int i = 0; i < message.Length; i++) { tmpcrc += (Int16)message[i]; } tmpcrc %= 4096; string crc = ""; crc += (char)((byte)'=' + (tmpcrc / 64)); crc += (char)((byte)'=' + (tmpcrc % 64)); if (crc != target) return ""; //----------------------------------------------------------- // decode message target = ""; message = command.Substring(3, command.Length - 5); int index = 0; uint a, b, c, d; uint x, y, z; int len = message.Length; message = message + "====="; while (index <= len) { a = (uint)message[index++] - '='; b = (uint)message[index++] - '='; c = (uint)message[index++] - '='; d = (uint)message[index++] - '='; x = (a << 2) | (b >> 4); y = ((b & 0x0f) << 4) | (c >> 2); z = ((c & 0x03) << 6) | d; target += (char)x; target += (char)y; target += (char)z; } return target; } // --------------------------------------------------------------------------- /// /// Encode Message to send to the Board /// /// /// // --------------------------------------------------------------------------- public static string EncodeMessage(string message) { string target = ""; byte a, b, c; int len = message.Length; int ptr = 0; while (len > 0) { if (len > 0) { a = (byte)message[ptr++]; len--; } else a = 0; if (len > 0) { b = (byte)message[ptr++]; len--; } else b = 0; if (len > 0) { c = (byte)message[ptr++]; len--; } else c = 0; target += (char)((a >> 2) + (byte)'='); target += (char)((((a & 0x03) << 4) | ((b & 0xf0) >> 4)) + (byte)'='); target += (char)((((b & 0x0f) << 2) | ((c & 0xc0) >> 6)) + (byte)'='); target += (char)((c & 0x3f) + (byte)'='); } return target; } // --------------------------------------------------------------------------- /// /// Creates a complete message including the command and the address byte /// header. It calls thr EncodeMessage function to encode the message body. /// command and adress byte will not be encoded. An additional 2 Byte CRC will /// be added at the end of the message /// /// /// /// /// // --------------------------------------------------------------------------- public string CreateMessage(char cmd, char adr, string message) { string target = ""; target += '#'; target += adr; target += cmd; target += EncodeMessage(message); //----------------------------------------------------------- //add CRC Int16 tmpcrc = 0; for (int i = 0; i < target.Length; i++) { tmpcrc += (Int16)target[i]; } tmpcrc %= 4096; target += (char)((byte)'=' + (tmpcrc / 64)); target += (char)((byte)'=' + (tmpcrc % 64)); //----------------------------------------------------------- target += (char)'\r'; return target; } // --------------------------------------------------------------------------- /// /// Initialize the COM Port. ComPort must be set before calling this function /// /// // --------------------------------------------------------------------------- public int InitPort() { serialPort1 = new SerialPort(); serialPort1.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(serialPort1_DataReceived); try { serialPort1.PortName = ComPort; serialPort1.BaudRate = 57600; serialPort1.DataBits = 8; serialPort1.Open(); serialPort1.DiscardInBuffer(); serialPort1.DiscardOutBuffer(); isOpen = true; } catch { isOpen = false; return 1; } return 0; } // --------------------------------------------------------------------------- /// /// Writes a string to the Com Port /// /// // --------------------------------------------------------------------------- public void SerialWrite(string data) { serialPort1.Write(data); } // --------------------------------------------------------------------------- /// /// Writes a string to the comport and adds a CR/LF at the end /// /// // --------------------------------------------------------------------------- public void SerialWriteLine(string data) { serialPort1.WriteLine(data); } // --------------------------------------------------------------------------- /// /// colse the COm port if open /// // --------------------------------------------------------------------------- public void ClosePort() { if (isOpen) { serialPort1.Close(); } } // --------------------------------------------------------------------------- /// /// Message functions /// // --------------------------------------------------------------------------- public string GetLastMessage() { if (messagevalid == true) { return botmessage; } else return ""; } public bool IsMessageValid() { return messagevalid; } public bool IsMessageError() { return messageerror; } public bool IsMessageOverrun() { return messageoverrun; } public void InvalidateMessage() { messagevalid = false; messageerror = false; messageoverrun = false; } public char GetMessageCmd() { return message_cmd; } public char GetMessageAdr() { return message_adr; } public string MessageAddByte(byte value, string command) { command = command + (char)value; return command; } public string MessageAddInt16(Int16 value, string command) { byte s = 0; s = (byte)value; command = command + (char)s; Int16 value1 = (Int16)(value >> 8); s = (byte)value1; command = command + (char)s; return command; } public string MessageAddInt32(Int32 value, string command) { byte s = 0; s = (byte)value; command = command + (char)s; Int32 value1 = (Int32)(value >> 8); s = (byte)value1; command = command + (char)s; value1 = (Int32)(value >> 8); s = (byte)value1; command = command + (char)s; value1 = (Int32)(value >> 8); s = (byte)value1; command = command + (char)s; return command; } public byte MessageReadByte(string command) { byte bvalue = (byte)command[0]; return bvalue; } public Int16 MessageReadInt16(string command) { int index = 0; Int16 tmp2; Int16 result; Int16 tmp; tmp2 = (Int16)command[index++]; result = (Int16)command[index++]; result = (Int16)(result << 8); result += (Int16)tmp2; return result; } public Int32 MessageReadInt32(string command) { int index = 0; Int32 tmp0; Int32 tmp1; Int32 tmp2; Int32 result; Int16 tmp; tmp0 = (Int32)command[index++]; tmp1 = (Int32)command[index++]; tmp2 = (Int32)command[index++]; result = (Int32)command[index++]; result = (Int32)(result << 8); result += (Int32)tmp2; result = (Int32)(result << 8); result += (Int32)tmp1; result = (Int32)(result << 8); result += (Int32)tmp0; return result; } // --------------------------------------------------------------------------- /// /// serial data receive message handler. /// /// /// // --------------------------------------------------------------------------- private static string command; private static bool messagevalid = false; private static bool messageerror = false; private static bool messageoverrun = false; private static char message_cmd = (char)0; private static char message_adr = (char)0; private static int receiver_status = 0; private static string botmessage; private static void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { int data; EventArgs ev = new EventArgs(); while (serialPort1.BytesToRead > 0) { data = serialPort1.ReadChar(); //Console.Write((char)data); switch (receiver_status) { case 0: if (data.CompareTo('#') == 0) { command = "#"; receiver_status++; } break; case 1: message_adr = (char)data; command = command + (char)data; receiver_status++; break; case 2: message_cmd = (char)data; command = command + (char)data; receiver_status++; break; case 3: if ((data.CompareTo(13) != 0) && (data.CompareTo(10) != 0)) { command = command + (char)data; if (command.Length > 350) { command = ""; serialPort1.DiscardInBuffer(); } } else { if (messagevalid == true) { messageoverrun = true; } else { botmessage = DecodeMessage(command); if (botmessage == "") { messageerror = true; } else { messagevalid = true; } } BotEvent(sender, ev); receiver_status = 0; command = ""; } break; } } } } }