protected virtual void OnDataAvailable(string data) { //If we didn't get any data, just return if (string.IsNullOrEmpty(data)) { return; } //Log each message from the arduino if we want to see its raw output //mLogger.LogMessage(ProsthesisCore.Utility.Logger.LoggerChannels.Arduino, data); var idType = new { ID = "none" }; idType = JsonConvert.DeserializeAnonymousType(data, idType); switch (idType.ID) { case ArduinoMessageValues.kTelemetryID: OnTelemetryReceive(data); break; case ArduinoMessageValues.kAcknowledgeID: //Echo ACKS for now if (mLogger != null) { mLogger.LogMessage(ProsthesisCore.Utility.Logger.LoggerChannels.Arduino, string.Format("{0}", JsonConvert.DeserializeObject <ArduinoToggleResponse>(data))); } break; case ArduinoMessageValues.kDeviceStateChange: ArduinoDeviceStateChange changed = JsonConvert.DeserializeObject <ArduinoDeviceStateChange>(data); if (mLogger != null) { mLogger.LogMessage(ProsthesisCore.Utility.Logger.LoggerChannels.Arduino, string.Format("{0}", changed)); } if (StateChanged != null) { StateChanged(this, changed.FR, changed.TO); } mDeviceState = changed.TO; break; case ArduinoMessageValues.kHeartbeatEnableValue: if (mHeartbeatTimer != null) { mHeartbeatTimer.Stop(); mHeartbeatTimer.Start(); mNumMissedHeartbeatDeadlines = 0; } break; default: if (mLogger != null) { mLogger.LogMessage(ProsthesisCore.Utility.Logger.LoggerChannels.Arduino, string.Format("Unrecognized JSON message from {0} on port {1}: \"{2}\"", ArduinoID, mPortName, data)); } break; } }
public void StopArduinoComms(bool disableBeforeStop) { if (mDeviceState == ProsthesisCore.Telemetry.ProsthesisTelemetry.DeviceState.Disconnected) { return; } if (mWorkerThread != null) { mWorkerThread = null; } if (mHeartbeatTimer != null) { mHeartbeatTimer.Stop(); } mTelemetryToggled = false; mDeviceState = ProsthesisCore.Telemetry.ProsthesisTelemetry.DeviceState.Disconnected; if (mPort != null) { SerialPort port = mPort; if (mLogger != null) { mLogger.LogMessage(ProsthesisCore.Utility.Logger.LoggerChannels.Arduino, string.Format("Closing Arduino comms on port {0} for AID {1}", mPortName, ArduinoID)); } TelemetryToggle(0); ToggleArduinoState(false); ToggleHeartbeat(false, 0, 0); //Set a time out so our thread wakes up and exits mPort.ReadTimeout = 1; mPort = null; try { port.Dispose(); } //Eat this exception since we may have had a strange OS disposal catch (System.IO.IOException) {} } if (Disconnected != null) { Disconnected(this); } }
public bool StartArduinoComms() { if (mWorkerThread != null) { mWorkerThread.Abort(); mWorkerThread = null; } string[] ports = GetPortNames(); bool foundCorrectArduino = false; var idPacket = new ArduinoMessageBase(); idPacket.ID = ArduinoMessageValues.kIdentifyValue; string jsonOutput = Newtonsoft.Json.JsonConvert.SerializeObject(idPacket); foreach (string port in ports) { SerialPort serialPort = new SerialPort(port, kArduinoCommsBaudRate); if (mLogger != null) { mLogger.LogMessage(ProsthesisCore.Utility.Logger.LoggerChannels.Arduino, string.Format("Now checking Arduino on port {0}", port)); } //Only check unopened ports if (!serialPort.IsOpen) { try { serialPort.Open(); } //Port is already open in another context, or Arduino. In any case, skip this one catch (UnauthorizedAccessException) { if (mLogger != null) { mLogger.LogMessage(ProsthesisCore.Utility.Logger.LoggerChannels.Arduino, string.Format("Unable to open port {0} because of unauthorized access exception", port)); } continue; } //Wait for the Arduino to boot once we've opened the port System.Threading.Thread.Sleep(kArduinoBootloaderDelayMilliseconds); //Disable telemtry just incase var toggle = new { ID = ArduinoMessageValues.kTelemetryEnableValue, EN = false }; string disableTelem = Newtonsoft.Json.JsonConvert.SerializeObject(toggle); serialPort.Write(disableTelem); var toggleHB = new { ID = ArduinoMessageValues.kHeartbeatEnableValue, EN = false }; string disableHB = Newtonsoft.Json.JsonConvert.SerializeObject(toggleHB); serialPort.Write(disableHB); //Discard any built up data serialPort.DiscardInBuffer(); serialPort.Write(jsonOutput); serialPort.ReadTimeout = kIDTimeoutMilliseconds; string response = string.Empty; for (int i = 0; i < kNumRetries; ++i) { try { response = ReadLine(serialPort); break; } //Catch case where the serial port is unavailable. MOve to next port catch (TimeoutException) { if (mLogger != null) { mLogger.LogMessage(ProsthesisCore.Utility.Logger.LoggerChannels.Arduino, string.Format("Port {0} timed out. Attempt {1} of {2}", port, i + 1, kNumRetries)); } continue; } } if (!string.IsNullOrEmpty(response)) { try { ArduinoIDAckMessage msg = Newtonsoft.Json.JsonConvert.DeserializeObject <ArduinoIDAckMessage>(response); if (msg.ID == ArduinoMessageValues.kAcknowledgeID && msg.AID == mArduinoID) { mTelemetryToggled = msg.TS; mDeviceState = msg.DS; if (mLogger != null) { mLogger.LogMessage(ProsthesisCore.Utility.Logger.LoggerChannels.Arduino, string.Format("Got the arduino we're looking for on port {0} with AID {1}. Telemetry is {2} and the device's state is {3}", port, mArduinoID, msg.TS, msg.DS)); } mPort = serialPort; //Don't timeout anymore. Our worker thread will yield while it waits for data mPort.ReadTimeout = -1; mWorkerThread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(ReadSerialDataFromPort)); mWorkerThread.Name = string.Format("Arduino IO worker for AID {0}", mArduinoID); mPort.Disposed += new EventHandler(OnPortDisposed); mPortName = port; foundCorrectArduino = true; //Start our worker mWorkerThread.Start(); } else if (mLogger != null) { mLogger.LogMessage(ProsthesisCore.Utility.Logger.LoggerChannels.Arduino, string.Format("Found a Prosthesis Arduino, but not the arduino we're looking for on port {0} with AID {1}", port, mArduinoID)); } } //Catch malformed JSON response, if there is one at all catch (Newtonsoft.Json.JsonSerializationException) { if (mLogger != null) { mLogger.LogMessage(ProsthesisCore.Utility.Logger.LoggerChannels.Arduino, string.Format("Malformed response. Ignoring port {0}", port)); } } catch (Newtonsoft.Json.JsonReaderException) { if (mLogger != null) { mLogger.LogMessage(ProsthesisCore.Utility.Logger.LoggerChannels.Arduino, string.Format("Malformed response. Ignoring port {0}", port)); } } } else if (mLogger != null) { mLogger.LogMessage(ProsthesisCore.Utility.Logger.LoggerChannels.Arduino, string.Format("Serial port {0} doesn't have an arduino", port)); } if (!foundCorrectArduino) { serialPort.Close(); serialPort.Dispose(); } else { //We've found our Arduino, no need to continue checking break; } } } return(foundCorrectArduino); }
private void OnArduinoStateChange(ArduinoCommunicationsLibrary.ArduinoCommsBase arduino, ProsthesisCore.Telemetry.ProsthesisTelemetry.DeviceState from, ProsthesisCore.Telemetry.ProsthesisTelemetry.DeviceState to) { if (to == ProsthesisCore.Telemetry.ProsthesisTelemetry.DeviceState.Fault) { RaiseFault(string.Format("AID {0} reported a fault.", arduino.ArduinoID)); } }