解决方案 »

  1.   

            //陀螺仪数据相关参数初始化
            static double SettedZ = 0;
            static double Zbuffer;
            private List<byte> ReceiveContent = new List<byte>();//保存接收到的串口数据,定义byte元素的泛型接口
            private byte[] Xang = new byte[2], Yang = new byte[2], Zang = new byte[2];        private StringBuilder builder = new StringBuilder();Form Load里面
                //初始化下拉串口名称列表框
                string[] ports = SerialPort.GetPortNames();
                Array.Sort(ports);
                comboPortName.Items.AddRange(ports);
                comboPortName.SelectedIndex = comboPortName.Items.Count > 0 ? 0 : -1;
                comboBaudrate.SelectedIndex = comboBaudrate.Items.IndexOf("9600");            //初始化SerialPort对象
                serialPort1.NewLine = "\r\n";
                serialPort1.RtsEnable = true;            //陀螺仪的串口参数设置
                this.serialPort2.PortName = "COM7";//设置端口名称
                this.serialPort2.BaudRate = 9600;//波特率
                this.serialPort2.DataBits = 8;//数据长度        void comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                int n = serialPort1.BytesToRead;//先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致
                byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据
                serialPort1.Read(buf, 0, n);//读取缓冲数据
                builder.Clear();//清除字符串构造器的内容
                //因为要访问ui资源,所以需要使用invoke方式同步ui。
                this.Invoke((EventHandler)(delegate
                {
                    //直接按ASCII规则转换成字符串
                    builder.Append(Encoding.ASCII.GetString(buf));
                    //追加的形式添加到文本框末端,并滚动到最后。
                    this.box.AppendText(builder.ToString());
                }
                ));        private void open_Click(object sender, EventArgs e)
            {
                //根据当前串口对象,来判断操作
                if (serialPort1.IsOpen)
                {
                    //打开时点击,则关闭串口
                    serialPort1.Close();
                    buttonup.Enabled = false;
                    buttondown.Enabled = false;
                    buttonleft.Enabled = false;
                    buttonright.Enabled = false;
                    buttonadd.Enabled = false;
                    buttondec.Enabled = false;
                    buttonforward.Enabled = false;
                    buttonbackward.Enabled = false;
                    speedup.Enabled = false;
                    speeddown.Enabled = false;                this.open.BackColor = Color.Green;                buttonforward.BackColor = Color.Empty;
                    buttonbackward.BackColor = Color.Empty;
                    speedup.BackColor = Color.Empty;
                    speeddown.BackColor = Color.Empty;
                    buttonadd.BackColor = Color.Empty;
                    buttondec.BackColor = Color.Empty;
                }
                else
                {
                    //关闭时点击,则设置好端口,波特率后打开                try
                    {
                        serialPort1.PortName = comboPortName.Text;
                        serialPort1.BaudRate = int.Parse(comboBaudrate.Text);
                        serialPort1.Open();
                        serialPort1.Write("AT+DMOAUTOPOWCONTR=1\r\n");
                    }
                    catch (Exception ex)
                    {
                        //捕获到异常信息,创建一个新的serialPort1对象,之前的不能用了。
                        serialPort1 = new SerialPort();
                        //显示异常信息给客户。
                        MessageBox.Show(ex.Message);
                    }
                }
                //设置按钮的状态
                open.Text = serialPort1.IsOpen ? "关闭操控" : "打开操控";
                buttonup.Enabled = serialPort1.IsOpen;
                buttondown.Enabled = serialPort1.IsOpen;
            }        //陀螺仪串口打开
            bool imu = true;
            private void button1_Click(object sender, EventArgs e)
            {
                if (imu)
                {
                    if (!this.serialPort2.IsOpen) //检测端口是不是没开
                    {                    try
                        {
                            this.serialPort2.Open();//打开端口
                            setzero.Enabled = true;
                            this.timer2.Interval = 500;//定时器定时
                            this.timer2.Enabled = true;//定时器打开
                        }
                        catch (Exception ex)
                        {
                            //显示异常信息给客户。
                            MessageBox.Show(ex.Message);
                        }
                    }
                    openimu.Text = "关闭陀螺仪";
                    imu = false;
                }
                else
                {
                    if (this.serialPort2.IsOpen)//检测端口是否开着
                    {
                        this.serialPort2.Close();//关闭端口
                        this.timer2.Enabled = false;//关闭定时器
                        this.richTextBox1.Clear();
                        panel2.Refresh();
                    }
                    openimu.Text = "打开陀螺仪";
                    imu = true;
                }
                    
            }        //陀螺仪数据接收串口及显示
            private void serialPort2_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                int ReceiveLength = this.serialPort2.BytesToRead;//引用获取接收缓冲区字节数并赋值
                byte[] TempContent = new byte[ReceiveLength];//实例化tempcontent,以ReceiveLength为元素个数
                this.serialPort2.Read(TempContent, 0, ReceiveLength);//获取读取到的输入缓冲区中的字节
                foreach (byte var in TempContent)//对于每一个TempContent中的元素
                {
                    ReceiveContent.Add(var);//将读取到的临时数据存入全局缓存中,每一个var压入堆栈
                }
                if (ReceiveContent.Count >= 12)
                {
                    int i = 0;
                    while (i < ReceiveContent.Count)
                    {
                        if ((ReceiveContent[i] == 0x55) && (ReceiveContent[i + 1] == 0x53))
                        {
                            if (ReceiveContent.Count - i >= 12)
                            {
                                for (int k = 0; k < 2; k++)
                                {
                                    Xang[k] = ReceiveContent[i + k + 2];
                                    Yang[k] = ReceiveContent[i + k + 4];
                                    Zang[k] = ReceiveContent[i + k + 6];
                                }
                                double Anglex, Angley, Anglez, Pz;
                                Anglex = ((short)(Xang[1] << 8 | Xang[0])) / 32768.0 * 180;
                                Angley = ((short)(Yang[1] << 8 | Yang[0])) / 32768.0 * 180;
                                Anglez = (((short)(Zang[1] << 8 | Zang[0])) / 32768.0 * 180) - SettedZ;
                                Zbuffer = ((short)(Zang[1] << 8 | Zang[0])) / 32768.0 * 180;
                                if (Anglez < -180) Pz = Anglez + 360;
                                else if (Anglez > 180) Pz = Anglez - 360;
                                else Pz = Anglez;
                                this.richTextBox1.Clear();
                                string anglex = Convert.ToDouble(Anglex).ToString("0.000000");
                                string angley = Convert.ToDouble(Angley).ToString("0.000000");
                                string anglez = Convert.ToDouble(Pz).ToString("0.000000");
                                double pi = System.Math.PI;
                                int xpt2x = (int)(Math.Sin((Anglex + 180) * pi / 180) * 70 + 70);
                                int xpt2y = (int)(Math.Cos((Anglex + 180) * pi / 180) * 70 + 70);
                                panel2.Refresh();
                                Graphics xg = panel2.CreateGraphics();
                                Pen xMypen = new Pen(Color.Blue, 5);
                                Point xpt1 = new Point(70, 70);
                                Point xpt2 = new Point(xpt2x, xpt2y);
                                xg.DrawLine(xMypen, xpt1, xpt2);
                                Pen xMypen2 = new Pen(Color.Blue, 1);
                                Rectangle xr = new Rectangle(0, 0, 140, 140);
                                xg.DrawEllipse(xMypen2, xr);
                                xg.DrawLine(xMypen2, 9, 105, 130, 35);
                                xg.DrawLine(xMypen2, 35, 130, 105, 9);
                                xg.DrawLine(xMypen2, 0, 70, 140, 70);
                                xg.DrawLine(xMypen2, 70, 0, 70, 140);
                                xg.DrawLine(xMypen2, 105, 130, 35, 9);
                                xg.DrawLine(xMypen2, 130, 105, 9, 35);
                                Thread.Sleep(200);
                                ReceiveContent.Clear();
                            }
                            else
                            {
                                break;
                            }
                        }
                        i++;
                    }            }
            }
      

  2.   

    打开没有问题。就是同时打开,有一个串口数据收不到,发送还是可以的。而且从串口转usb的指示灯看,确实有发送和接收。只是电脑上没有读取那个串口的数据而已
      

  3.   

    刚调试程序时发现一个情况,如果我先打开串口2,陀螺仪的数据会不断接收,再打开串口1,没有反应,此时关闭串口2,串口1的数据就进来了,并且显示在了textbox中。
      

  4.   

    你两个串口对象是用拖控件的方式拖进窗体里的?
    把属性放出来看
    我很怀疑你两个串口对象指向的同一个物理端口
    比如都是COM1
      

  5.   

    不是,这个我还是弄清了。晚上发现了问题,传感器数据太多,又直接在datareceived的事件中处理,线程被占用了,单独启用一个线程就好了。搞了一晚上。