参考WinForm做Win8 MetroLoad效果的项目做的。
串口数据格式是固定的,16进制CSV格式,别的不行。
代码挺乱的,初学者。
Communicate.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;
namespace MagicCubeView {
class Communicate {
#region 常量
/// <summary>
/// 最大数据长度
/// </summary>
const int _MAX_LENGTH = 2000;
/// <summary>
/// 串口读取超时ms
/// </summary>
const int _TIMEOUT = 20;
#endregion
#region 变量
/// <summary>
/// 串口
/// </summary>
SerialPort _sp = null;
List<Frame> _data = null;
/// <summary>
/// 通讯线程
/// </summary>
Thread _CoreThread = null;
/// <summary>
/// 已连接
/// </summary>
bool _Link = false;
#endregion
#region 公共
public List<Frame> Data {
get { return _data; }
}
/// <summary>
/// 构造
/// </summary>
/// <param name="ComName"></param>
public Communicate(string ComName) {
if (_sp != null) {
if (_sp.IsOpen == true) {
_sp.Close();
}
_sp = null;
}
_sp = new SerialPort();
_sp.PortName = ComName;
_sp.BaudRate = 115200; //波特率
_sp.DataBits = 8; //数据位
_sp.StopBits = StopBits.One; //停止位
_sp.Parity = Parity.None; //校验位
_sp.ReadTimeout = _TIMEOUT;
_sp.Open();
if (_CoreThread != null) {
if ((_CoreThread.ThreadState == ThreadState.Unstarted) || (_CoreThread.ThreadState == ThreadState.Stopped)) {
} else {
throw new Exception("\r\n错误!线程正在运行." + _CoreThread.ThreadState);
}
}
_CoreThread = new Thread(Run);
_CoreThread.Name = "串口线程";
_CoreThread.IsBackground = true;
_CoreThread.Start();
_data = new List<Frame>();
}
/// <summary>
/// 断开连接
/// </summary>
public void DisLink() {
_Link = false;
}
/// <summary>
/// 枚举串口
/// </summary>
/// <returns></returns>
public static string[] GetPortName() {
return SerialPort.GetPortNames();
}
#endregion
#region 运行
/// <summary>
/// 字符串解析
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
Frame makeFrame(string s) {
Frame f = null;
string[] ss = s.Split(',');
if (ss.Length == 6) {
f = new Frame();
f.a = Convert.ToInt32(ss[0], 16);
f.b = Convert.ToInt32(ss[1], 16);
f.c = Convert.ToInt32(ss[2], 16);
f.d = Convert.ToInt32(ss[3], 16);
f.e = Convert.ToInt32(ss[4], 16);
f.f = Convert.ToInt32(ss[5].TrimEnd('\r').TrimEnd('\n'), 16);
} else {
Console.WriteLine("ss.Length != 6");
}
return f;
}
void Run() {
_Link = true;
for (; ; ) {
try {
string s = _sp.ReadLine();
try {
if(_data.Count >= _MAX_LENGTH){
_data.RemoveAt(0);
}
Frame f = makeFrame(s);
if (f != null) {
_data.Add(f);
}
}catch(Exception ex){
Console.WriteLine(ex.Message);
}
} catch{
}
if(_Link == false){
_sp.Close();
break;
}
}
}
#endregion
}
}
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Collections;
namespace MagicCubeView {
public partial class Form1 : Form {
#region 字段
/// <summary>
/// 绘图tmr
/// </summary>
private System.Windows.Forms.Timer _graphicsTmr;
/// <summary>
/// 通讯
/// </summary>
Communicate comm = null;
#endregion 字段
#region 参数
/// <summary>
/// 绘制间隔
/// </summary>
private const int DRAW_INTERVAL = 5;
private const int PEN_SIZE = 2;
private int WIDTH = 1600;
private int HEIGTH = 800;
/// <summary>
/// X轴间隔(几个点数一格)
/// </summary>
private int FRAME_GAP = 50;
/// <summary>
/// 屏幕上的可显示的点数
/// </summary>
private int FRAME_COUNT = 1000;
private int VALUE_GAP = 5000;
private int MAX_VALUE = 70000;
private int MIN_VALUE = 0;
private int FIX = 30000;
private int FIX1 = -20000;
private int FIX2 = 0;
private int FIX3 = 41000;
private int FIX4 = 40000;
private int FIX5 = 42000;
private int ShowCharUpdateCnt = 0;
private UInt16 RedChar = 0;
private UInt16 GreenChar = 0;
private UInt16 YellowChar = 0;
private UInt16 RedCharFix = 0;
private UInt16 GreenCharFix = 0;
private UInt16 YellowCharFix = 0;
private bool show1 = true;
private bool show2 = true;
private bool show3 = true;
private bool show4 = true;
private bool show5 = true;
private bool show6 = true;
#endregion 参数
#region 构造
public Form1() {
InitializeComponent();
//双缓冲,禁擦背景
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
SizeReDifine();
//初始化绘图timer
_graphicsTmr = new System.Windows.Forms.Timer();
_graphicsTmr.Interval = DRAW_INTERVAL;
_graphicsTmr.Tick += (sender1, e1) => this.pictureBox1.Invalidate(false);
_graphicsTmr.Start();
MJ();
UpdateParamBack();
UpdateParamBackFix();
}
/// <summary>
/// 枚举串口
/// </summary>
void MJ() {
string[] ss = Communicate.GetPortName();
this.comboBox1.Items.Clear();
foreach (string s in ss) {
this.comboBox1.Items.Add(s);
}
if (ss.Length > 0) {
this.comboBox1.SelectedIndex = 0;
}
}
#endregion 构造
#region 事件处理
/// <summary>
/// 数值转Y坐标
/// </summary>
/// <param name="Value"></param>
/// <returns></returns>
float PositionY(int Value) {
return (float)HEIGTH - (float)HEIGTH * ((float)Value - (float)MIN_VALUE) / ((float)MAX_VALUE - (float)MIN_VALUE);
}
//重绘
private void pictureBox1_Paint(object sender, PaintEventArgs e) {
//抗锯齿
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
using (Bitmap bmp = new Bitmap(WIDTH, HEIGTH)) {
//缓冲绘制
using (Graphics bufferGraphics = Graphics.FromImage(bmp)) {
//抗锯齿
bufferGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
LinearGradientBrush linGrBrush = new LinearGradientBrush(//背景
new Point(0, 0),
new Point(0, HEIGTH),
Color.FromArgb(255, 0, 0, 0), // Opaque red
Color.FromArgb(255, 0, 0, 60));