Yindow

【红色飓风Nano二代测评】上位机显示

0
阅读(3009)

前面的博客已将底层的东西准备好了,现在就开始做上位机。我用的是C#,刚开始接触这个C#没多久,有什么表达不当的欢迎拍砖哦。

首先上位机这边最主要的就是接受串口的数据,我们先声明一个串口:

SerialPort sp = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);

然后给串口初始化:

private void UartInit()

        {

            sp.ReadBufferSize = 1024;

            sp.WriteBufferSize = 1024;

            sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);

 

            sp.Open();

            sp.ReceivedBytesThreshold = 1;

            sp.DiscardInBuffer();

            sp.DiscardOutBuffer();

        }


 

在这里我们创建了一个事件,只要是收到一个字节的数据,程序就会跳转到这个事件中处理。我们底层的数据格式是0xAA,(4个字节组成的32位编码器数据),0x55.此时我们需要将0xAA0x55之间的数据截取出来。怎么拼接这4个字节呢?我想了好多的方法,要是FPGA处理这个东西那就相当的简单了,后来发现可以用类似的方法,那就是使用联合共用体。

    //定义一个联合共用体

    [StructLayout(LayoutKind.Explicit)]

    public struct TestUnion

    {

        [FieldOffset(0)]

        public int encoder;

        [FieldOffset(0)]

        public Byte encoder0;

        [FieldOffset(1)]

        public Byte encoder1;

        [FieldOffset(2)]

        public Byte encoder2;

        [FieldOffset(3)]

        public Byte encoder3;

    }


 

这个代码就是定义一个共用体,可以看到encoder是一个32位的变量,下面的是4个八位的变量,可以看到这四个八位的变量有不同的偏移量,这样就拼接成了一个32位的变量了。只要我们给这个4个八位的变量分别赋值(串口接收到的数据),那么我们从encoder中就可以读取所需要的值了。

在串口接事件中代码如下:

void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)

        {

            Byte read = (Byte) sp.ReadByte();

            if (start)

            {

                readdata[count] = read;

                count++;

                if (count >= 5)

                {

                    count = 0;

                    start = false;

                    if (readdata[4] != 0x55)

                    {

                        return;

                    }

                    tu.encoder0 = readdata[3];

                    tu.encoder1 = readdata[2];

                    tu.encoder2 = readdata[1];

                    tu.encoder3 = readdata[0];

 

                    lednumshow.LEDText = tu.encoder.ToString();

                }

            }

            if (read == 0xAA)

            {

                start = true;

            }

        }


 

现在我想在屏幕上将编码器的值显示出来,我这把调用的是LEDNumber.dllZedGraphControl.dll这两个库。大家可以在网上搜索这两个库,LEDNumber.dll这个使用起来相当的简单,我们只要将数值赋值过去就可以了:

lednumshow.LEDText = tu.encoder.ToString();

ZedGraphControl.dll这个库使用起来有些纠结哦,首先我们需要设置一个集合:

//设置图像显示集合

     ZedGraph.PointPairList listV = new ZedGraph.PointPairList();
创建图像:

private void GreateGraph(ZedGraph.ZedGraphControl zgc)

        { 

            //获取GraphPane的引用

            ZedGraph.GraphPane myPane = zgc.GraphPane;

 

            //设置标题

            myPane.Title.Text = "nano测评---旋转编码器状态图";

            myPane.XAxis.Title.Text = "X----时间轴";

            myPane.YAxis.Title.Text = "Y----转速";

 

            ZedGraph.LineItem myCurve1 = myPane.AddCurve("V", listV, Color.Black, ZedGraph.SymbolType.None);

        }


 

剩下的就是给刚才创建的集合赋值,赋值函数写在定时器中:

private void timer1_Tick(object sender, EventArgs e)

        {

            xTime = xTime + 0.5;

            nowDat = tu.encoder;

            //lednumshow.LEDText = ((nowDat - lastDat)/100).ToString();

            zedGraphControl1.GraphPane.XAxis.Scale.Max = xTime;

            zedGraphControl1.GraphPane.XAxis.Scale.Min = xTime - 200;

            listAdd(xTime, nowDat - lastDat, 500);//

            zedGraphControl1.AxisChange();

            zedGraphControl1.Refresh();

            lastDat = nowDat;

        }

 

private void listAdd(double x, double w, int fifo)

        {

            listV.Add(x, w);

            if (listV.Count > fifo)

            {

                listV.Remove(listV[0]);

            }

        }


 

几个主要的函数就在这里了,下面我们看看效果吧,如下图1所示

为整体平台显示。

 

整体框架

当转动旋转编码器时,上位机界面显示如下图2所示,数码管中显示的是当前编码器的脉冲数。曲线显示的是编码器的转速。

 

图2 上位机界面1

如下图3所示,为动态图

 

动态效果

东西基本上做完了,好像似乎有些东西没有忘了,哦现在可以将底层的数据采集通过上位机显示,上位机的指令也要传达下去哦。我们创建8CheckBox控件,在事件中创建一个CheckedChanged的事件,然后将LED1-LED7CheckedChanged全部指向LED0CheckedChanged事件。然后添加如下代码:

private void LED0_CheckedChanged(object sender, EventArgs e)

        {

            LED[0] = 0x00;

            if (LED0.Checked) LED[0] |= 0x01;

            else LED[0] &= 0xFE;

            if (LED1.Checked) LED[0] |= 0x02;

            else LED[0] &= 0xFD;

            if (LED2.Checked) LED[0] |= 0x04;

            else LED[0] &= 0xFB;

            if (LED3.Checked) LED[0] |= 0x08;

            else LED[0] &= 0xF7;

            if (LED4.Checked) LED[0] |= 0x10;

            else LED[0] &= 0xEF;

            if (LED5.Checked) LED[0] |= 0x20;

            else LED[0] &= 0xDF;

            if (LED6.Checked) LED[0] |= 0x40;

            else LED[0] &= 0xBF;

            if (LED7.Checked) LED[0] |= 0x80;

            else LED[0] &= 0x7F;

 

            sp.Write(LED, 0, 1);

        }


 

如下图4所示,上位机这边勾选了LED0LED3LED4LED6LED7这几个选项。


 

图4 上位机指令界面

如下图5所示,为开发板LED显示效果。

 

图5 开发板显示效果