public void InputProcess(Object stateInfo) { if (Monitor.TryEnter(_serialPort)) { try { AutoResetEvent autoEvent = (AutoResetEvent)stateInfo; if (!_serialPort.IsOpen) { // Signal the waiting thread we are done autoEvent.Set(); return; } if (_serialPort.BytesToRead == 0) { return; } int inputData = _serialPort.ReadByte(); int command; if (_parsingSysex) { if (inputData == Arduino.END_SYSEX) { _parsingSysex = false; if (_sysexBytesRead > 5 && _storedInputData[0] == Arduino.I2C_REPLY) { byte[] i2cReceivedData = new byte[(_sysexBytesRead - 1) / 2]; for (int i = 0; i < i2cReceivedData.Count(); i++) { i2cReceivedData[i] = (byte)(_storedInputData[(i * 2) + 1] | _storedInputData[(i * 2) + 2] << 7); } _arduino.callDidI2CDataReveive(i2cReceivedData[0], i2cReceivedData[1], i2cReceivedData.Skip(2).ToArray()); } if (_storedInputData[0] == Arduino.SYSEX_SUB_STRING) { // byte[] dummy = new byte[(_sysexBytesRead - 1) / 2]; for (int i = 0; i < dummy.Count(); i++) { dummy[i] = (byte)(_storedInputData[(i * 2) + 1] | _storedInputData[(i * 2) + 2] << 7); } string sDummy = System.Text.Encoding.UTF8.GetString(dummy, 0, dummy.Length); } _sysexBytesRead = 0; } else { _storedInputData[_sysexBytesRead] = inputData; _sysexBytesRead++; } } else if (_waitForData > 0 && inputData < 128) { _waitForData--; _storedInputData[_waitForData] = inputData; if (_executeMultiByteCommand != 0 && _waitForData == 0) { //we got everything switch (_executeMultiByteCommand) { case Arduino.DIGITAL_MESSAGE: int currentDigitalInput = (_storedInputData[0] << 7) + _storedInputData[1]; for (int i = 0; i < 8; i++) { if (((1 << i) & (currentDigitalInput & 0xff)) != ((1 << i) & (_arduino._digitalInputData[_multiByteChannel] & 0xff))) { if ((((1 << i) & (currentDigitalInput & 0xff))) != 0) { _arduino.callDigitalPinUpdated((byte)(i + _multiByteChannel * 8), Arduino.HIGH); } else { _arduino.callDigitalPinUpdated((byte)(i + _multiByteChannel * 8), Arduino.LOW); } } } _arduino._digitalInputData[_multiByteChannel] = (_storedInputData[0] << 7) + _storedInputData[1]; break; case Arduino.ANALOG_MESSAGE: _arduino._analogInputData[_multiByteChannel] = (_storedInputData[0] << 7) + _storedInputData[1]; _arduino.callAnalogPinUpdated(_multiByteChannel, (_storedInputData[0] << 7) + _storedInputData[1]); break; case Arduino.REPORT_VERSION: this._majorVersion = _storedInputData[1]; this._minorVersion = _storedInputData[0]; break; } } } else { if (inputData < 0xF0) { command = inputData & 0xF0; _multiByteChannel = inputData & 0x0F; switch (command) { case Arduino.DIGITAL_MESSAGE: case Arduino.ANALOG_MESSAGE: case Arduino.REPORT_VERSION: _waitForData = 2; _executeMultiByteCommand = command; break; } } else if (inputData == 0xF0) { _parsingSysex = true; // commands in the 0xF* range don't use channel data } } } finally { Monitor.Exit(_serialPort); } } }
public void ProcessInput(Object stateInfo) { if (Monitor.TryEnter(_serialPort)) { try { try { AutoResetEvent areProcessingFinished = (AutoResetEvent)stateInfo; if (!_serialPort.IsOpen) { // Signal the waiting thread we are done areProcessingFinished.Set(); return; } int bytesToRead = _serialPort.BytesToRead; if (bytesToRead == 0) { return; } byte[] serialData = new byte[bytesToRead]; _serialPort.Read(serialData, 0, bytesToRead); foreach (byte inputData in serialData) { byte command; if (_parsingSysex) { if (inputData == Arduino.END_SYSEX) { _parsingSysex = false; if (_sysexBytesRead > 5 && _storedInputData[0] == Arduino.I2C_REPLY) { byte[] i2cReceivedData = new byte[(_sysexBytesRead - 1) / 2]; for (int i = 0; i < i2cReceivedData.Count(); i++) { i2cReceivedData[i] = (byte)(_storedInputData[(i * 2) + 1] | _storedInputData[(i * 2) + 2] << 7); } _arduino.callDidI2CDataReceive(i2cReceivedData[0], i2cReceivedData[1], i2cReceivedData.Skip(2).ToArray()); } else if (_sysexBytesRead > 5 && _storedInputData[0] == Arduino.STRING_DATA) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < (_sysexBytesRead - 1) / 2; i++) { sb.Append((char)(_storedInputData[(i * 2) + 1] | _storedInputData[(i * 2) + 2] << 7)); } _arduino?.callFirmataMessageHandler(sb.ToString()); } _sysexBytesRead = 0; } else { _storedInputData[_sysexBytesRead] = inputData; _sysexBytesRead++; } } else if (_waitForData > 0 && inputData < 128) { _waitForData--; _storedInputData[_waitForData] = inputData; if (_executeMultiByteCommand != 0 && _waitForData == 0) { //we got everything switch (_executeMultiByteCommand) { case Arduino.DIGITAL_MESSAGE: int currentDigitalInput = (_storedInputData[0] << 7) + _storedInputData[1]; for (int i = 0; i < 8; i++) { if (((1 << i) & (currentDigitalInput & 0xff)) != ((1 << i) & (_arduino._digitalInputData[_multiByteChannel] & 0xff))) { if ((((1 << i) & (currentDigitalInput & 0xff))) != 0) { _arduino.callDigitalPinUpdated((byte)(i + _multiByteChannel * 8), Arduino.HIGH); } else { _arduino.callDigitalPinUpdated((byte)(i + _multiByteChannel * 8), Arduino.LOW); } } } _arduino._digitalInputData[_multiByteChannel] = (_storedInputData[0] << 7) + _storedInputData[1]; break; case Arduino.ANALOG_MESSAGE: _arduino._analogInputData[_multiByteChannel] = (_storedInputData[0] << 7) + _storedInputData[1]; _arduino.callAnalogPinUpdated(_multiByteChannel, (_storedInputData[0] << 7) + _storedInputData[1]); break; case Arduino.REPORT_VERSION: this._majorVersion = _storedInputData[1]; this._minorVersion = _storedInputData[0]; break; } } } else { if (inputData < 0xF0) { command = (byte)(inputData & 0xF0); #region Debug print received message //FirmataMessages fmsg = FirmataMessages.UNKNOWN_MASSAGE; //if (Enum.IsDefined(typeof(FirmataMessages), (int)command)) fmsg = (FirmataMessages)(int)command; //Debug.WriteLine(string.Format("Command received : {0}", fmsg)); #endregion _multiByteChannel = inputData & 0x0F; switch (command) { case Arduino.DIGITAL_MESSAGE: case Arduino.ANALOG_MESSAGE: case Arduino.REPORT_VERSION: _waitForData = 2; _executeMultiByteCommand = command; break; } } else if (inputData == Arduino.START_SYSEX) { _parsingSysex = true; // commands in the 0xF* range don't use channel data } } } } catch (Exception Ex) { Debug.WriteLine("Error in ProcessInput : " + Ex.Message); } } finally { Monitor.Exit(_serialPort); } } }