使用信号量等待回答时,C#串口无法正确读取

时间:2016-12-20 14:17:26

标签: c# semaphore

首先,我在MS Visual Community 2015中运行C#。 以下问题:

我有一个连接到控制板的步进电机。该板接受通过USB连接发送的9字节阵列命令。我通过C#中的SerialPort发送这些命令。每个字节都有一定的含义(板号,电机号,命令号,0字节,以十六进制字节表示的4字节,校验和)

每个命令发送都会使板发出一个9字节的数组答案,我会在DataReceived Handle中找到它。

在程序中,当用户按下按钮时,我想要执行后续操作:

  1. 电机启动旋转(特殊命令)
  2. 程序记录压力传感器的其他输入
  3. 电机停止转动(特殊指令)
  4. 保存电机的位置。 (命令“请求位置”发送,答案包含位置,前面提到的4字节值)
  5. 现在,当我在单个按钮上发送多个命令,并且我读到DataReceived启动一个新线程时,我遇到了使用信号量等待我的DataReceive Handle收集完整答案的解决方案。我也有关于单独按钮的所有方法进行测试。

    现在的问题是如果我在一个按钮上运行所有内容,我的位置总是变化大约130-140步到实际位置(我从单按钮测试得到)。

    以下是该计划的摘录:

     class Motor
    {
        public static readonly Motor Instance = new Motor();
        USBSerialTest.Motorsbefehle MB = new Motorsbefehle();
        byte[] PermaSave = new byte[9];
        byte[] buf = new byte[9];
        Semaphore _sync = new Semaphore(0, 1);
    
        private Motor()
        {
            MotorPort = new SerialPort();
            MotorPort.PortName = "COM6";
            MotorPort.Handshake = Handshake.RequestToSendXOnXOff;
            MotorPort.ReceivedBytesThreshold = 9;
            MotorPort.DataReceived += new SerialDataReceivedEventHandler(dataRecievedHandler);
            MotorPort.Open();
        }
    
        private void dataRecievedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            int bytes = MotorPort.BytesToRead;
            byte[] buffer = new byte[bytes];
            sp.Read(buffer, 0, bytes);
            buf = buffer;
            _sync.Release();
        }
    
        public SerialPort MotorPort { get; private set; }
    
        public void StartRotate(string speed)
        {
            var commandBytes = MB.TMCL_RMR(speed);
            MotorPort.Write(commandBytes, 0, commandBytes.Length);
            _sync.WaitOne();
        }
    
        public void StopRotate()
        {
            var commandBytes = MB.TMCL_MST();
            MotorPort.Write(commandBytes, 0, commandBytes.Length);
            _sync.WaitOne();
    
        }
    
        public void RequestPosition()
        {
            var commandbytes = MB.GET_POSI();
            MotorPort.Write(commandbytes, 0, commandbytes.Length);
            _sync.WaitOne();
        }
    
        public string SavePosition()
        {
            PermaSave = buf;
            string hex = BitConverter.ToString(buf);
            hex.Replace(",", "-");
            return hex;
        }
    

    字节数组的外观示例(这将是停止电机命令)

        public byte[] TMCL_MST()
        {
            return new byte[] { 0x1, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4 };          
        }
    

    我在我的表格中这样称呼它:

    private void button13_Click(object sender, EventArgs e)
        {
            string speed = textBox4.Text;
            Motor.Instance.StartRotate(speed);
    
            keyance2.SendCommand();
            decimal caliber = keyance2.GetDecimalOutput();
            decimal actualValue = 0;
            do
            {
                keyance2.SendCommand();
                actualValue = keyance2.GetDecimalOutput();
            }
            while (actualValue <= caliber);
    
            Motor.Instance.StopRotate();
            Motor.Instance.RequestPosition();
            string hex = Motor.Instance.SavePosition();
            textBox5.Text = hex;
        }
    

    如上所述,这一按钮推送解决方案产生的结果与我在电机停止转动后按下单独按钮时执行Motor.Instance.RequestPosition();Motor.Instance.SavePosition();时得到的结果不同(我获得的值)这与我从电路板制作软件得到的相同,所以正确的值)。不是很多,我想知道我的错误可能在哪里。任何帮助将不胜感激。

0 个答案:

没有答案