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);
                }
            }
        }
Example #2
0
        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);
                }
            }
        }