本文主要实现读取温度测试
一、页面按键功能布局
1.一个标签温度描述,一个空白标签显示温度
2.三个功能按钮,对应打开风扇开关,打开灯光开关,读取温度按钮
二、温度代码的编写
1.在项目程序中新建一个类,用来存放我们的功能模块
声明一个委托,用来发送数据,定义一个事件,发生该事件时需要将原始数据发出去,定义温度变量,串口协议的解析状态,创建一个泛型集合用来接收有效数据。
定义常量,帧头1、2,帧头,用来验证数据是否准确,数据方向上位机发送命令,下位机接收命令,设备类型LED、风扇、温度传感器。
public delegate void SendData(byte[] data);
public event SendData RequestSendData;
private int temperature;
private int pharse_state = 0;
private List<byte> data_obejct = new List<byte>();
const byte FRAME_HEAD1 = 0XAA; //帧头1
const byte FRAME_HEAD2 = 0X55; //帧头2
const byte FRAME_END = 0X0D; //帧尾
const byte FRAME_DIR_CMD = 0X01; //数据方向 上位机发送命令
const byte FRAME_DIR_REC = 0X81; //数据方向 下位机接收命令
const byte FRAME_DATA_NUM = 3; //有效的数据长度
const byte DEVICE_LED = 0X01; //设备类型 LED
const byte DEVICE_FAN = 0X02; //设备类型 风扇
const byte DEVICE_TEMP = 0X03; //设备类型 温度传感器
2.定义一个方法,对数据进行验证
事件发送我们数组数据,遍历数据的每一个数据,从第一开始验证,如果是对应帧头1,继续跳转到第二个数据验证,第二数据对应是帧头2,继续跳转验证,第三位有效数据对应下位机接收命令,把原先的数据先清除,继续跳转验证,再把新获取到的数据添加进来,如果下位机接收大于或等于我们的有效数据长度3位,则跳转到最后的帧尾验证,在转到有效数据方法进行解析。
public void ReceivedRawData(byte[] data)
{
foreach (byte b1 in data)
{
switch (pharse_state)
{
case 0:
if (b1 == FRAME_HEAD1)
pharse_state = 1;
break;
case 1:
if (b1 == FRAME_HEAD2)
pharse_state = 2;
else
pharse_state = 0;
break;
case 2:
if (b1 == FRAME_DIR_REC)
{
pharse_state = 3;
data_obejct.Clear();
}
else
pharse_state = 0;
break;
case 3:
data_obejct.Add(b1);
if(data_obejct.Count >= FRAME_DATA_NUM)
pharse_state = 4;
break;
case 4:
if (b1 == FRAME_END)
PhraseValidData(data_obejct);
pharse_state = 0;
break;
}
}
}
3.有效数据方法解析代码
如果选择是温度传感器,对温度的2个十六进制转十进制
private void PhraseValidData(List<byte> data_list)
{
switch (data_list[0])
{
case DEVICE_TEMP: //判断是否是03温度传感器
temperature = data_list[1] * 256 + data_list[2];
sema.Release();//退出信号量,并返回前一个计数
break;
}
}
4.读取温度方法
定义字节数组存放数据,对应接收原始数据方法,如果数据不为空,就把数据发出去,并设置一个信号量,阻止当前线程,直到受到信号量,然后返回读取的温度值。否则返回一个错误值。
Semaphore sema = new Semaphore(0, 1);
public int ReadTemperature()
{
byte[] data = new byte[7];
data[0] = FRAME_HEAD1;
data[1] = FRAME_HEAD2;
data[2] = FRAME_DIR_CMD;
data[3] = DEVICE_TEMP;
data[4] = 0;
data[5] = 0;
data[6] = FRAME_END;
if (RequestSendData != null)
{
RequestSendData(data);
}
if (sema.WaitOne(5000) == true)
{
return temperature;
}
else
{
return 0xFFFF;
}
}
三、读取温度按钮
将温度强制转换为浮点型,能够显示我们的小数位度数
private void btnReadTemperature_Click(object sender, EventArgs e)
{
float temp = ((float)greenHouse.ReadTemperature()) / 10;
label4.Text = temp.ToString() + "℃";
label4.ForeColor = Color.Red;
}
效果图:
在打开串口后就直接读取当前温度值,然后手指捏住温度传感器,使温度上升