前端时间不是要做一个STM32的甲醛测量仪嘛,然后因为各种因素,我后来重新打板了(这两天发现那个板子也有一个错误),制作的时候着急了,当时看手册没看仔细,因为那天刚拿到这个传感器取完快递的时候,结果在路上就丢了,这个传感器应该是5V的,毕竟上面标注的也是5V作为供电电压。然后里面肯定是有一块单片机作为主控的,但是由于丝印看不清楚,因此不知道具体型号,不过大部分5V单片机都支持在3.3V的条件下工作。当然我也没有具体研究过工作原理,3.3V的工作条件是否会造成测量信号的不准确等等问题。
但是传感器到都到了,于是决定先设计一套C#的上位机来测试一下,本来是问客服有没有上位机的,但是客服说没有对应的上位机,于是就只能自己做一下。
- ** 模块介绍 **
这里不是打广告嗷 单纯是比较了几家,他家的文档看的顺眼,有几家的参考文档看的我感觉和吃了shi一样难受!!
这个装置其实说来也简单,因为是串口协议的,所以只需要将模块连到CH340转TTL模块即可连到电脑即可。
由于之前我们将我们的串口抽象成了一个单独的类供我们使用,因此其实开发速度非常的快。
在此之前,我们先来分析一下我们收到的数据格式。
根据手册的规定,我们收到的串口数据流格式如上图。
这些数据分别对于着:模块地址:2C,E4
TVOC,CH2O,CO2的数据高八位和低八位以及最后的校验和,这个用起来还是非常简单的。
但是很难受的就是,不知道是我使用的原因还是模块的特性,他断电之后需要一段时间的预热。
- ** 程序实现 **
在界面方面,主要有三个部分:
- 首先是串口选择,选择我们的和模块通讯的串口号。
- 其次是三个数据的标签显示。
- 最后是一个图形化数据显示。
主要代码也是非常的简单。 包括:初始化串口对象,初始化图标对象添加对应曲线,为收到的数据添加回调函数,为按钮添加回调函数。以及最后的收到数据处理。
UARTTool uart = new UARTTool();
public VCOV() { InitializeComponent(); LoadAll(); }
void LoadAll() { DataChart.Series.Clear(); //折线 DataChart.Series.Add("TVOC"); DataChart.Series["TVOC"].ChartType = SeriesChartType.Line; DataChart.Series["TVOC"].Color = Color.Red; //粗度 DataChart.Series["TVOC"].BorderWidth = 4;
DataChart.Series.Add("CH2O"); DataChart.Series["CH2O"].ChartType = SeriesChartType.Line; DataChart.Series["CH2O"].Color = Color.Green; DataChart.Series["CH2O"].BorderWidth = 4;
DataChart.Series.Add("CO2"); DataChart.Series["CO2"].BorderWidth = 4; DataChart.Series["CO2"].ChartType = SeriesChartType.Line; DataChart.Series["CO2"].Color = Color.Blue;
for (int i = 0; i<uart.PortName.Length; i++) { PortNames.Items.Add(uart.PortName[i]); } if (PortNames.Items.Count > 0) { PortNames.SelectedIndex = 0; }
}
private void button1_Click(object sender, EventArgs e) { if (Start.Text == "开始测量") { Start.Text = "停止测量"; uart.Open(PortNames.SelectedItem.ToString(), 9600); uart.MessageEvent += Uart_MessageReceived; } else { Start.Text = "开始测量"; uart.Close(); } }
private void Uart_MessageReceived(object sender, string message, Byte[] data) { if (RecieveBox.InvokeRequired) { // 使用委托将调用封送到 UI 线程 RecieveBox.Invoke(new Action(() => AppendTextSafe(message, data))); } else { AppendTextSafe(message, data); } }
private void AppendTextSafe(string message, Byte[] data) { if (data[0] == 0x2C) { //TVOC int tvoc = (data[2] << 8) + data[3]; DataChart.Series["TVOC"].Points.AddXY(DataChart.Series["TVOC"].Points.Count, tvoc); //CH2O int ch2o = (data[4] << 8) + data[5]; DataChart.Series["CH2O"].Points.AddXY(DataChart.Series["CH2O"].Points.Count, ch2o); //CO2 int co2 = (data[6] << 8) + data[7]; DataChart.Series["CO2"].Points.AddXY(DataChart.Series["CO2"].Points.Count, co2);
float tvoc_f = (float)(tvoc*1.0 / 1000); float ch2o_f = (float)(ch2o*1.0 / 1000); float co2_f = (float)(co2*1.0 / 1000); //UI界面更新标签 TVOCLabel.Text = "TVOC:" + tvoc_f.ToString("F2") + " ppb"; CH2OLabel.Text = "CH2O:" + ch2o_f.ToString("F2") + " ppb"; CO2Label.Text = "CO2:" + co2_f.ToString("F2") + " ppm";
}
}