您的位置:首页 > 其它

上位机如何显示波形

2018-02-10 21:05 302 查看
本人代码新手,为了完成毕业设计需要用上位机做波形显示,然而作为一个生物狗,可是吃了不少苦头的,所以这里把自己的过程尽可能详细的写出,方便其他新人查阅。
我这里用的是C#做的winform,原理各平台基本相通。不考虑数据的接收及处理,只是画图的话大致分为以下步骤:
①在内存中新建一个区域(Bitmap)用于缓冲,通俗点讲,就是把屏幕当作桌子,而你在内存中先放一块画布,等画完后再贴到桌子上,有效的防止图像在屏幕上不断的刷新闪烁。
②将数据,也就是一个个点,放在显示区域的正确位置,再用合适的画笔将点连接起来。
③画完后把Bitmap画到屏幕上,再把所有数据点平移,重复上述步骤即可。
效果如下:


我这里绘图用的是Panel控件,以下为相应代码:

①绘制背景。本质上就是把Panel背景色调为黑色,再画上白色轴线
//背景色设为黑色
panel1.BackColor = Color.Black;
//轴线颜色(白色)
private Pen AxlePen = new Pen(Color.FromArgb(0xff, 0xff, 0xff)); //单位格长度 const int UnitLength = 30; //起始点偏移量 const int StartPoint = 0;
//纵向线数量
const int VertLine = 14;
//横向线数量
const int HoriLine = 9;
private void panel1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics; //纵向轴绘制
for (int i = 0; i <= VertLine; i++)
{
g.DrawLine(AxlePen, StartPoint + i * UnitLength, StartPoint, StartPoint + i * UnitLength, (HoriLine+1) * UnitLength);//画线
} //横向轴绘制
for (int i = 0; i <= HoriLine; i++)
{
g.DrawLine(AxlePen, StartPoint, i * UnitLength, StartPoint + (VertLine + 1) * UnitLength, i * UnitLength);//画线
}
g.Dispose();
}
②数据绘制。数据来源有很多,可以通过串口,云端,本地等各种方式,我这里采用的是本地文件,使用定时时间,1ms显示一个数据的方式来显示动态的波形,各位看客自己根据实际情况选择。
//这样才可以跨进程访问windows控件
Control.CheckForIllegalCrossThreadCalls = false;
//波形颜色(红色)
private Pen LinesPen = new Pen(Color.FromArgb(0xff, 0x00, 0x00));

//定时事件
System.Timers.Timer readTime;
//定时事件设为1ms触发一次
readTime = new System.Timers.Timer(1);
readTime.Elapsed += new ElapsedEventHandler(PaintWave);

private void PaintWave(object source,ElapsedEventArgs e)
{
Bitmap bmp = new Bitmap(450, 300);
Graphics g = Graphics.FromImage(bmp);
//通过Panel句柄创建一个Graphics对象
//如直接用Graphics gp = this.panel1.CreateGraphics()
//会出现窗体关闭时出现“访问已释放句柄“的异常
Graphics gp = Graphics.FromHwnd(panel1.Handle);

//先绘制轴线,代码省略
//………………

//开始绘制波形
//DataListTest为一个数组
//其存储着所使用的数据
//每过1ms通过处理方法使数据平移一位
//这里不予展示
for (int i = 0; i < DataListTest.Count - 1; i++)
{
g.DrawLine(LinesPen, DataListTest.Count - i, 300 - DataListTest[i], DataListTest.Count + 1 - i, 300 - DataListTest[i + 1]);
}
//将Bitmap刷新至控件Panel上
gp.DrawImage(bmp, 0, 0);
//释放资源
g.Dispose();
gp.Dispose();
}

//按键点击事件
private void button1(object sender, EventArgs e)
{
//定时开始
readTime.Start();
}

值得注意的是我这里是通过”Control.CheckForIllegalCrossThreadCalls = false“来关闭多线程UI检测的,这才使得其他进程可以调用panel进行绘图,仅可用来体验结果,更加妥当的方法请参照:marshal-m的博客
    以上便是原生控件进行绘图的方法,都是通过像素一个一个的进行绘制,也可以借助第三方控件进行绘图,如果有好的第三方控件希望您能够分享哦。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: