Example #1
0
        private SerialCommand QueueCommandString(string cmd)
        {
            if (string.IsNullOrEmpty(cmd))
            {
                return(null);
            }

            if (CommandToUpper)
            {
                cmd = cmd.ToUpper();
            }

            cmd = cmd.Replace('\t', ' ');

            var c = new SerialCommand {
                SeqId = _commandSeqId++, CommandText = cmd
            };
            int queueLength;

            lock (_pendingCommands)
            {
                queueLength = _pendingCommands.Count;
                if (queueLength == 0)
                {
                    _autoEvent.Set(); // start Async task now!
                }

                _pendingCommands.Add(c);
                queueLength++;
            }

            Logger?.LogTrace($"Queue: {cmd}");
            OnCommandQueueChanged(new SerialEventArgs(queueLength, c));
            return(c);
        }
Example #2
0
 public SerialEventArgs(SerialCommand cmd)
 {
     Command = cmd;
     if (cmd != null)
     {
         Info  = cmd.CommandText;
         SeqId = cmd.SeqId;
     }
 }
Example #3
0
 public SerialEventArgs(int queueLenght, SerialCommand cmd)
 {
     QueueLenght = queueLenght;
     Command     = cmd;
     if (cmd != null)
     {
         Info  = cmd.CommandText;
         SeqId = cmd.SeqId;
     }
 }
Example #4
0
        private void SendCommand(SerialCommand cmd)
        {
            // SendCommands is called in the async Write thread

            var eventArgs = new SerialEventArgs(cmd);

            OnCommandSending(eventArgs);

            if (eventArgs.Abort || Aborted)
            {
                return;
            }

            lock (_commands)
            {
                if (_commands.Count > MaxCommandHistoryCount)
                {
                    _commands.RemoveAt(0);
                }

                _commands.Add(cmd);
            }

            string commandText = cmd.CommandText;

            const int CRLF_SIZE = 2;

            if (commandText.Length >= ArduinoLineSize + CRLF_SIZE)
            {
                commandText = commandText.Substring(0, ArduinoLineSize - 1 - CRLF_SIZE);
            }

            while (commandText.Length > ArduinoBufferSize - 1)
            {
                // give "control" class the chance to read from arduino to control buffer

                int    firstSize = ArduinoBufferSize * 2 / 3;
                string firstX    = commandText.Substring(0, firstSize);
                commandText = commandText.Substring(firstSize);

                if (!WriteSerial(firstX, false))
                {
                    return;
                }

                Thread.Sleep(250);
            }

            if (WriteSerial(commandText, true))
            {
                cmd.SentTime = DateTime.Now;
                eventArgs    = new SerialEventArgs(cmd);
                OnCommandSent(eventArgs);
            }
        }
Example #5
0
        private IEnumerable <SerialCommand> SplitAndQueueCommand(string line)
        {
            var cmdlist = new List <SerialCommand>();

            string[] cmds = SplitCommand(line);
            foreach (string cmd in cmds)
            {
                SerialCommand pcmd = QueueCommandString(cmd);
                if (pcmd != null)
                {
                    // sending is done in Write-Thread
                    cmdlist.Add(pcmd);
                }
            }
            return(cmdlist);
        }
Example #6
0
        public SerialEventArgs(string info, SerialCommand cmd)
        {
            Command = cmd;
            if (cmd != null && string.IsNullOrEmpty(info))
            {
                Info = cmd.CommandText;
            }
            else
            {
                Info = info;
            }

            if (cmd != null)
            {
                SeqId = cmd.SeqId;
            }
        }
Example #7
0
        /// <summary>
        /// Wait until command queue is empty
        /// </summary>
        /// <param name="maxMilliseconds"></param>
        /// <returns>true = ok, false = timeout or aborting</returns>
        public async Task <bool> WaitUntilQueueEmptyAsync(int maxMilliseconds = DefaultTimeout)
        {
            var sw = Stopwatch.StartNew();

            while (Continue)
            {
                SerialCommand cmd = null;
                lock (_pendingCommands)
                {
                    if (_pendingCommands.Count > 0)
                    {
                        cmd = _pendingCommands[0];
                    }
                }

                if (cmd == null)
                {
                    return(true);
                }

                var eventArgs = new SerialEventArgs(cmd);
                OnWaitCommandSent(eventArgs);
                if (Aborted || eventArgs.Abort)
                {
                    return(false);
                }

                if (_autoEvent.WaitOne(10) == false)
                {
                    await Task.Delay(1);
                }

                if (sw.ElapsedMilliseconds > maxMilliseconds)
                {
                    return(false);
                }
            }

            return(false); // aborting
        }
Example #8
0
        private void MessageReceived(string message)
        {
            SerialCommand cmd = null;

            lock (_pendingCommands)
            {
                if (_pendingCommands.Count > 0)
                {
                    cmd = _pendingCommands[0];
                }
            }

            if (string.IsNullOrEmpty(message) == false)
            {
                Logger?.LogTrace($"Read: {message.Replace("\n", @"\n").Replace("\r", @"\r").Replace("\t", @"\t")}");

                bool endCommand = false;

                message = message.Trim();

                if (cmd != null)
                {
                    SetSystemKeepAlive();

                    string result = cmd.ResultText;
                    if (string.IsNullOrEmpty(result))
                    {
                        result = message;
                    }
                    else
                    {
                        result = result + "\n" + message;
                    }

                    cmd.ResultText        = result;
                    cmd.ReplyReceivedTime = DateTime.Now;
                }

                OnReplyReceived(new SerialEventArgs(message, cmd));

                if (message.StartsWith(OkTag))
                {
                    endCommand = true;
                    if (cmd != null)
                    {
                        cmd.ReplyType |= EReplyType.ReplyOK;
                    }

                    OnReplyDone(new SerialEventArgs(message, cmd));
                }
                else if (message.StartsWith(ErrorTag, StringComparison.OrdinalIgnoreCase))
                {
                    if (ErrorIsReply)
                    {
                        endCommand = true;
                    }

                    if (cmd != null)
                    {
                        cmd.ReplyType |= EReplyType.ReplyError;
                    }

                    OnReplyError(new SerialEventArgs(message, cmd));
                }
                else if (message.StartsWith(InfoTag, StringComparison.OrdinalIgnoreCase))
                {
                    if (cmd != null)
                    {
                        cmd.ReplyType |= EReplyType.ReplyInfo;
                    }

                    OnReplyInfo(new SerialEventArgs(message, cmd));
                }
                else
                {
                    if (cmd != null)
                    {
                        cmd.ReplyType |= EReplyType.ReplyUnknown;
                    }

                    OnReplyUnknown(new SerialEventArgs(message, cmd));
                }

                if (endCommand && cmd != null)
                {
                    int queueLength;
                    lock (_pendingCommands)
                    {
                        if (_pendingCommands.Count > 0) // may cause because of a reset
                        {
                            _pendingCommands.RemoveAt(0);
                        }

                        queueLength = _pendingCommands.Count;
                        _autoEvent.Set();
                    }

                    OnCommandQueueChanged(new SerialEventArgs(queueLength, cmd));

                    if (queueLength == 0)
                    {
                        OnCommandQueueEmpty(new SerialEventArgs(queueLength, cmd));
                        ClearSystemKeepAlive();
                    }
                }
            }
        }
Example #9
0
        private void Write()
        {
            Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;

            // Async write thread to send commands to the arduino

            while (Continue)
            {
                SerialCommand nextCmd         = null;
                int           queuedCmdLength = 0;

                // commands are sent to the arduino until the buffer is full
                // In the _pendingCommand list also the commands are still stored with no reply.

                lock (_pendingCommands)
                {
                    foreach (SerialCommand cmd in _pendingCommands)
                    {
                        if (cmd.SentTime.HasValue)
                        {
                            queuedCmdLength += cmd.CommandText.Length;
                            queuedCmdLength += 2; // CRLF
                        }
                        else
                        {
                            nextCmd = cmd;
                            break;
                        }
                    }
                }

                // nextCmd			=> next command to be sent
                // queuedCmdLength	=> length of command in the arduino buffer

                if (nextCmd != null && (!Pause || SendNext))
                {
                    if (queuedCmdLength == 0 || queuedCmdLength + nextCmd.CommandText.Length + 2 < ArduinoBufferSize)
                    {
                        // send everything if queue is empty
                        // or send command if pending commands + this fit into arduino queue
                        SendCommand(nextCmd);
                        SendNext = false;
                    }
                    else
                    {
                        var eventArgs = new SerialEventArgs(nextCmd);
                        OnWaitForSend(eventArgs);
                        if (Aborted || eventArgs.Abort)
                        {
                            return;
                        }

                        lock (_pendingCommands)
                        {
                            if (_pendingCommands.Count > 0 && _pendingCommands[0].SentTime.HasValue)
                            {
                                _autoEvent.Reset(); // expect an answer
                            }
                        }

                        _autoEvent.WaitOne(10);
                    }
                }
                else
                {
                    _autoEvent.WaitOne(100); // no command in queue => wait => CreateCommand(...) will set AutoEvent
                }
            }
        }