private ROVMessage ReceiveHelper() { ROVMessage msg = new ROVMessage(); while (ReadByte() != 0x42) { ; //read in until header byte reached } msg.command = (byte)ReadByte(); msg.data = new byte[ReadByte()]; byte calculatedChecksum = (byte)msg.data.Length; //start calculating a checksum for (int i = 0; i < msg.data.Length; i++) { //read in bytes one by one, calculating checksum as we go msg.data[i] = (byte)ReadByte(); calculatedChecksum ^= msg.data[i]; } byte actualChecksum = (byte)ReadByte(); if (calculatedChecksum != actualChecksum) //see if received checksum matches calculated one { throw new Exception(string.Format("Received corrupted data (Calculated checksum" + " of {0} did not match received {1})", calculatedChecksum, actualChecksum)); } return(msg); }
//custom code for rov serial comms public void TransmitRequestOrCommand(ROVMessage msg) { //assemble header, command, length bytes at front of message byte[] temp = new byte[msg.data.Length + 4]; temp[0] = (byte)0x42; temp[1] = msg.command; temp[2] = (byte)msg.data.Length; //checksum starts as msg length byte calculatedChecksum = (byte)msg.data.Length; //add all message data in for (int i = 0; i < msg.data.Length; i++) { temp[i + 3] = msg.data[i]; calculatedChecksum ^= msg.data[i]; } //add checksum temp[temp.Length - 1] = calculatedChecksum; //send it off Write(temp, 0, temp.Length); }
//handles communication and processing of queue private void BackgroundLoop() { long prevTime = DateTime.Now.Ticks; int thousandCount = 0; int fiftyCount = 0; while (!shuttingDown) { if (linkActive) { try { //update all queued devices while (devices.Count > 0) { //send the request or command devices.TryDequeue(out GenericAbstractDevice device); port.TransmitRequestOrCommand(device.GetMessage()); //if it's a sensor and needs a reply if (device.NeedsResponse) { //get the reply ROVMessage msg = port.WaitReceiveData(1000); //update the device's data on UI thread device.Invoke(new Action(() => device.UpdateData(msg))); } //redraw the device on UI thread device.Invoke(new Action(device.UpdateControls)); } } catch (Exception ex) { if (ex.GetType().IsAssignableFrom(typeof(System.Threading.ThreadAbortException))) { //log history before exception for debugging Logger.LogString("Start Communication Log Dump\n" + port.GetHistory() + "\nEnd Communication Log Dump"); Logger.LogException(ex); //cease communication LinkActive = false; //show exception dialog if (CommunicationException != null) { CommunicationException(this, ex); } } } //fire timers if necessary if ((DateTime.Now.Ticks - prevTime) > 10 * TimeSpan.TicksPerMillisecond) { //System.Diagnostics.Debug.WriteLine(DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond); //System.Diagnostics.Debug.WriteLine(devices.Count); prevTime = DateTime.Now.Ticks; thousandCount++; fiftyCount++; if (thousandCount > 100) { thousandCount = 0; if (ThousandElapsed != null) { ThousandElapsed(this, null); } } else if (fiftyCount > 5) { fiftyCount = 0; if (FiftyElapsed != null) { FiftyElapsed(this, null); } } else { if (TenElapsed != null) { TenElapsed(this, null); } } } } else { Thread.Sleep(100); } } }