using System.IO;
using System.IO.Ports;
属性 | 介绍 |
---|---|
BaudRate | 波特率 |
DataBits | 数据位 |
Parity | 奇偶校验位 |
PortName | 端口号 |
StopBits | 停止位 |
ByteToRead | 获取输入缓冲区的 |
IsOpen | 获取是否开启串口 |
事件 | 介绍 |
---|---|
DataReceived | 串口接收函数 |
ErrorReceived | 串口数据接收错误 |
PinChanged | 串口号发生改变 |
由图可以看出正常温度区间设置的是20-25度之间,测试温度的过程中温度曲线黄色的为正常的曲线,红色的曲线为温度异常。温度刷新,温度曲线重新读取画线
在窗体上添加4个Groupbox控件
第一个:串口设置
第二的:接收数据
第三个:发送数据
第四个:温度曲线显示
private void button_open_Click(object sender, EventArgs e)
{
// if(Button_on == 1)
if (!serialPort1.IsOpen)//如果串口是开
{
serialPort1.PortName = comboBox1.Text;//端口号
serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text, 10);//波特率
float f = Convert.ToSingle(comboBox3.Text.Trim());//trim去除字符串前后的空格
if (f == 0)//设置停止位
serialPort1.StopBits = StopBits.None;
else if (f == 1.5)
serialPort1.StopBits = StopBits.OnePointFive;
else if (f == 1)
serialPort1.StopBits = StopBits.One;
else if (f == 2)
serialPort1.StopBits = StopBits.Two;
else
serialPort1.StopBits = StopBits.One;
//设置数据位
serialPort1.DataBits = Convert.ToInt32(comboBox4.Text.Trim());
//设置奇偶校验位
string s = comboBox5.Text.Trim();
if (s.CompareTo("无") == 0)
serialPort1.Parity = Parity.None;
else if (s.CompareTo("奇校验") == 0)
serialPort1.Parity = Parity.Odd;
else if (s.CompareTo("偶校验") == 0)
serialPort1.Parity = Parity.Even;
else
serialPort1.Parity = Parity.None;
try
{
serialPort1.Open(); //打开串口
button_open.Text = "关闭串口";
comboBox1.Enabled = false;//关闭使能
comboBox2.Enabled = false;
comboBox3.Enabled = false;
comboBox4.Enabled = false;
comboBox5.Enabled = false;
comboBox6.Enabled = false;
comboBox7.Enabled = false;
}
catch
{
MessageBox.Show("串口打开失败!");
}
}
else//如果串口是打开的则将其关闭
{
serialPort1.Close();
button_open.Text = "打开串口";
comboBox1.Enabled = true;//使能配置
comboBox2.Enabled = true;
comboBox3.Enabled = true;
comboBox4.Enabled = true;
comboBox5.Enabled = true;
comboBox6.Enabled = true;
comboBox7.Enabled = true;
}
}
using System.Drawing;
using System.Drawing.Drawing2D;
graphics是抽象函数不能实例化,并且画线的时候编辑器是以左上角为坐标原点画的,想要把它改成左下角,只能自己计算坐标点,根据自己的需求把它画成称自己想要的,如上图我把(50,218)这个坐标表示成原点
注意:Graphics是在控件Groupbox控件下事件Paint下写的
private void groupBox4_Paint(object sender, PaintEventArgs e)
{
FontFamily family = new FontFamily("Arial");//实例化字体的类型
int fontstyle = (int)FontStyle.Italic;//设置字体的样式
GraphicsPath gp = new GraphicsPath();
string Str;
//Draw y纵向轴绘制
for (int i = 0; i <= 14; i++)
{
e.Graphics.DrawLine(TablePen, StartPrint + i * Unit_length, StartPrint - 32, StartPrint + i * Unit_length, 10 * Unit_length + 18);//画线
gp.AddString((i * 10).ToString(), family, fontstyle, 8, new RectangleF(StartPrint + i * Unit_length - 7, 10 * Unit_length + 18 + 4, 400, 50), null);//添加文字
}
gp.AddString("时间(s)", family, fontstyle, 12, new RectangleF(groupBox4.ClientRectangle.Width / 2 , 9 * Unit_length + 55, 400, 50), null);
////Draw X 横向轴绘制
for (int i = 0; i <= 10; i++)
{
e.Graphics.DrawLine(TablePen, StartPrint, i * Unit_length + 18, StartPrint + 14 * Unit_length, i * Unit_length + 18);//画线
Str = Convert.ToString((10 - i) * 5);
if (i == 0)
Str = "50";
if (i == 10)
break;
gp.AddString(Str, family, fontstyle, 8, new RectangleF(20, i * Unit_length +16, 400, 50), null);//添加文字
}
gp.AddString("温", family, fontstyle, 12, new RectangleF(0, groupBox4.ClientRectangle.Height / 2 - StartPrint, 400, 50), null);
gp.AddString("度", family, fontstyle, 12, new RectangleF(0, groupBox4.ClientRectangle.Height / 2 + 18 - StartPrint, 400, 50), null);
gp.AddString("°C", family, fontstyle, 12, new RectangleF(0, groupBox4.ClientRectangle.Height / 2 + 32 - StartPrint, 400, 50), null);
e.Graphics.DrawPath(Pens.White, gp);//写文字
}
pen:定义线条的宽度、颜色、样式
画线由(x1,y1)向(x2,y2)画
public void AddString(string s, FontFamily family, int style, float emSize, RectangleF layoutRect, StringFormat format);
s:绘制的字符
family:绘制的字体类型
style:字体的样式
emsize:方形块的高度
layoutRect:文本的矩形
format:文本格式设置信息
public static void Delay(int milliSecond)
{
int start = Environment.TickCount;
while (Math.Abs(Environment.TickCount - start) < milliSecond)//毫秒
{
Application.DoEvents();//可执行某无聊的操作
}
}
关于Math.Abs():
Environment.TickCount,内部API是用DWORD GetTickCount()来实现的,该属性的值从系统计时器派生,并以 32 位有符号整数的形式存储。因此,如果系统连续运行,TickCount 将在约 24.9 天内从零递增至 Int32. MaxValue ,然后跳至 Int32. MinValue (这是一个负数),再在接下来的 24.9 天内递增至零。DWORD是无符号的,而 Environment.TickCount属性返回的值是有符号的,所以有一半的值用负数表示!
private void button_send_Click(object sender, EventArgs e)
{//发送数据
if(serialPort1.IsOpen)
{//如果串口开启
if (textBox_send.Text.Trim() != "")//如果框内不为空则
{
serialPort1.Write(textBox_send.Text.Trim());//写数据
}
else
{
MessageBox.Show("发送框没有数据");
}
}
else
{
MessageBox.Show("串口未打开");
}
}
private void post_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
float Up, Dw,t;
Graphics graphics = groupBox4.CreateGraphics();
if (!radioButton1.Checked)
{
string str = serialPort1.ReadExisting();//字符串方式读
if(!radioButton3.Checked)
{
//提取字符串中的数字
string result = System.Text.RegularExpressions.Regex.Replace(str, @"[^0-9]+", "");
Console.WriteLine(result);
//设置正常温度上限下限
Dw = Convert.ToSingle(comboBox6.Text);
Up = Convert.ToSingle(comboBox7.Text);
if(Dw=Up&&dstr2<=Dw)
{
graphics.DrawLine(LinesPen, Origin_x + i * Unit_length, dstr1, Origin_x + (i+0.1f) * Unit_length, Origin_y - dstr2 * 4);
}
else//异常温度的曲线
{
graphics.DrawLine(LinesEpen, Origin_x + i * Unit_length, dstr1, Origin_x + (i + 0.1f) * Unit_length, Origin_y - dstr2 * 4);
}
i += 0.1f;
dstr1 = Origin_y - dstr2 * 4;
Delay(1000);//不延时的话不显示
//textBox_T.Clear();无所谓
}
else
{
textBox_receive.AppendText(str);
}
}
else
{
byte data;
data = (byte)serialPort1.ReadByte();
string str = Convert.ToString(data, 16).ToUpper();//
textBox_receive.AppendText("0x" + (str.Length == 1 ? "0" + str : str) + " ");
}
}