基于C#的湿度上位机实现方案
基于C#的湿度上位机实现方案,包含实时曲线显示、数据存储和报警功能
一、系统架构
graph TD
A[传感器数据] --> B[串口通信模块]
B --> C[数据处理中心]
C --> D[实时显示模块]
C --> E[历史存储模块]
C --> F[报警管理模块]
D --> G[用户界面]
E --> G
F --> G
二、核心代码
2.1 串口通信模块
using System.IO.Ports;
public class SerialPortManager : IDisposable
{
private SerialPort _port;
private const int BaudRate = 9600;
private const Parity Parity = Parity.None;
private const StopBits StopBits = StopBits.One;
private const int DataBits = 8;
public event Action<byte[]> DataReceived;
public void Connect(string portName)
{
_port = new SerialPort(portName, BaudRate, Parity, DataBits, StopBits);
_port.DataReceived += (s, e) => DataReceived?.Invoke(Encoding.ASCII.GetBytes(_port.ReadExisting()));
_port.Open();
}
public void Disconnect() => _port?.Close();
public void Dispose() => _port?.Dispose();
}
2.2 数据处理模块
public class DataProcessor
{
public (float Temperature, float Humidity)? ParseData(byte[] data)
{
if (data.Length < 6) return null;
// 假设数据格式:温度高字节+温度低字节+湿度高字节+湿度低字节
short tempRaw = (short)(data[0] << 8 | data[1]);
short humiRaw = (short)(data[2] << 8 | data[3]);
float temperature = tempRaw / 10.0f;
float humidity = humiRaw / 10.0f;
return (temperature, humidity);
}
}
2.3 实时曲线显示
using System.Windows.Forms.DataVisualization.Charting;
public class RealTimeChart
{
private Chart _chart;
private Series _tempSeries;
private Series _humiSeries;
private Queue<float> _tempBuffer = new Queue<float>();
private Queue<float> _humiBuffer = new Queue<float>();
private const int MaxPoints = 100;
public RealTimeChart(Chart chart)
{
_chart = chart;
InitializeChart();
}
private void InitializeChart()
{
_tempSeries = new Series("Temperature")
{
ChartType = SeriesChartType.Spline,
Color = Color.Red
};
_humiSeries = new Series("Humidity")
{
ChartType = SeriesChartType.Spline,
Color = Color.Blue
};
_chart.Series.Clear();
_chart.Series.Add(_tempSeries);
_chart.Series.Add(_humiSeries);
_chart.ChartAreas[0].AxisX.Interval = 1;
_chart.ChartAreas[0].AxisY.Interval = 5;
}
public void UpdateChart(float temp, float humi)
{
if (_tempBuffer.Count >= MaxPoints) _tempBuffer.Dequeue();
if (_humiBuffer.Count >= MaxPoints) _humiBuffer.Dequeue();
_tempBuffer.Enqueue(temp);
_humiBuffer.Enqueue(humi);
_tempSeries.Points.Clear();
_humiSeries.Points.Clear();
for (int i = 0; i < _tempBuffer.Count; i++)
{
_tempSeries.Points.AddXY(i, _tempBuffer.ElementAt(i));
_humiSeries.Points.AddXY(i, _humiBuffer.ElementAt(i));
}
}
}
2.4 主程序集成
public partial class MainForm : Form
{
private SerialPortManager _serialManager;
private DataProcessor _dataProcessor;
private RealTimeChart _realTimeChart;
public MainForm()
{
InitializeComponent();
InitializeComponents();
}
private void InitializeComponents()
{
_serialManager = new SerialPortManager();
_dataProcessor = new DataProcessor();
_realTimeChart = new RealTimeChart(chart1);
_serialManager.DataReceived += OnDataReceived;
}
private void OnDataReceived(byte[] data)
{
if (InvokeRequired)
{
Invoke(new Action(() => OnDataReceived(data)));
return;
}
var result = _dataProcessor.ParseData(data);
if (result.HasValue)
{
UpdateUI(result.Value.Temperature, result.Value.Humidity);
}
}
private void UpdateUI(float temp, float humi)
{
lblTemp.Text = $"{temp:F1} °C";
lblHumi.Text = $"{humi:F1} %RH";
_realTimeChart.UpdateChart(temp, humi);
}
private void btnConnect_Click(object sender, EventArgs e)
{
_serialManager.Connect("COM3");
}
}
三、关键功能
3.1 报警功能
public class AlarmManager
{
private const float TempUpper = 30.0f;
private const float TempLower = 10.0f;
private const float HumiUpper = 70.0f;
private const float HumiLower = 30.0f;
public bool CheckAlarm(float temp, float humi)
{
bool tempAlarm = temp > TempUpper || temp < TempLower;
bool humiAlarm = humi > HumiUpper || humi < HumiLower;
if (tempAlarm || humiAlarm)
{
PlayAlertSound();
FlashAlarmLight();
LogAlarm(temp, humi);
return true;
}
return false;
}
private void PlayAlertSound()
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer("alert.wav");
player.Play();
}
private void FlashAlarmLight()
{
panelAlarm.BackColor = panelAlarm.BackColor == Color.Red ? Color.Transparent : Color.Red;
}
private void LogAlarm(float temp, float humi)
{
string log = $"{DateTime.Now}: Alarm! Temp={temp:F1}°C, Humi={humi:F1}%RH";
File.AppendAllText("alarm.log", log);
}
}
3.2 数据存储
public class DataStorage
{
private const string DbPath = "data.sqlite";
private SQLiteConnection _connection;
public DataStorage()
{
_connection = new SQLiteConnection($"Data Source={DbPath};Version=3;");
_connection.Open();
CreateTable();
}
private void CreateTable()
{
string sql = @"CREATE TABLE IF NOT EXISTS measurements (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
temperature REAL,
humidity REAL)";
using (var cmd = new SQLiteCommand(sql, _connection))
{
cmd.ExecuteNonQuery();
}
}
public void SaveData(float temp, float humi)
{
string sql = "INSERT INTO measurements (temperature, humidity) VALUES (@temp, @humi)";
using (var cmd = new SQLiteCommand(sql, _connection))
{
cmd.Parameters.AddWithValue("@temp", temp);
cmd.Parameters.AddWithValue("@humi", humi);
cmd.ExecuteNonQuery();
}
}
}
四、界面设计要点
<!-- 主界面布局示例 -->
<Form>
<GroupBox Text="实时监测" Dock="Top">
<Label x:Name="lblTemp" Text="温度: -- °C" FontSize="20"/>
<Label x:Name="lblHumi" Text="湿度: -- %RH" FontSize="20"/>
<Chart x:Name="chart1" Height="300"/>
</GroupBox>
<GroupBox Text="控制面板" Dock="Bottom">
<Button x:Name="btnConnect" Text="连接设备" Click="btnConnect_Click"/>
<Button Text="导出数据" Click="ExportData"/>
</GroupBox>
<StatusStrip>
<ToolStripStatusLabel Text="状态: 未连接"/>
<ToolStripStatusLabel x:Name="lblAlarmStatus"/>
</StatusStrip>
</Form>
五、性能优化方案
-
数据缓冲机制
private CircularBuffer<float> _buffer = new CircularBuffer<float>(1000); -
双缓冲绘图
protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; // WS_EX_COMPOSITED return cp; } } -
异步数据读取
private async Task ReadDataAsync() { while (true) { await Task.Delay(100); // 数据处理逻辑 } }
参考代码 C#温湿度上位机软件源码 www.youwenfan.com/contentcnj/57308.html
六、调试与测试
-
模拟数据测试
private void GenerateTestData() { Random rand = new Random(); for(int i=0; i<100; i++) { float temp = 20 + rand.NextDouble()*10; float humi = 40 + rand.NextDouble()*20; _realTimeChart.UpdateChart(temp, humi); } } -
性能监控
public void MonitorPerformance() { PerformanceCounter cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total"); PerformanceCounter ramCounter = new PerformanceCounter("Memory", "Available MBytes"); }
七、部署方案
-
安装包制作
- 使用Inno Setup创建安装程序
- 包含依赖项:.NET Framework 4.8、SQLite
-
系统服务化
public class BackgroundService : ServiceBase { protected override void OnStart(string[] args) { // 启动数据采集线程 } }

浙公网安备 33010602011771号