标题:
ZigBee智能家居的C#上位机源码
[打印本页]
作者:
silicon
时间:
2022-5-4 17:19
标题:
ZigBee智能家居的C#上位机源码
烟雾,光敏亮度,火焰等传感器数据的采集,上位机实现窗帘的开关
51hei.png
(77.85 KB, 下载次数: 93)
下载附件
2022-5-5 04:02 上传
C#源程序如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
namespace smartLed
{
public partial class FormMain : Form
{
private SerialPort sp = new SerialPort(); //串口类
private bool isOpen = false; //打开串口的标志位
private bool usart_closing = false; //是否正在关闭串口
private bool usart_listening = false; //监听是否在执行串口
private List<byte> buffer = new List<byte>(4096); //分配1页内存
private long SendCount = 0;
private long ReceiveCount = 0;
//串口窗体初始化
private void SerialSettingInit()
{
for (int i = 0; i < 32; i++)
{
cboxCOM.Items.Add("COM" + (i + 1).ToString());
}
cboxCOM.SelectedIndex = 0;
//列出波特率
cboxBaudRate.Items.Add("1200");
cboxBaudRate.Items.Add("2400");
cboxBaudRate.Items.Add("4800");
cboxBaudRate.Items.Add("9600");
cboxBaudRate.Items.Add("19200");
cboxBaudRate.Items.Add("38400");
cboxBaudRate.Items.Add("43000");
cboxBaudRate.Items.Add("56000");
cboxBaudRate.Items.Add("57600");
cboxBaudRate.Items.Add("115200");
cboxBaudRate.SelectedIndex = 9;
//列出停止位
cboxStopBits.Items.Add("0");
cboxStopBits.Items.Add("1");
cboxStopBits.Items.Add("1.5");
cboxStopBits.Items.Add("2");
cboxStopBits.SelectedIndex = 1;
//列出数据位
cboxDataBits.Items.Add("8");
cboxDataBits.Items.Add("7");
cboxDataBits.Items.Add("6");
cboxDataBits.Items.Add("5");
cboxDataBits.SelectedIndex = 0;
//列出奇偶校验位
cboxParity.Items.Add("无");
cboxParity.Items.Add("奇校验");
cboxParity.Items.Add("偶校验");
cboxParity.SelectedIndex = 0;
countClear();
}
//检测可用串口
private void buttonCheck_Click(object sender, EventArgs e)
{
bool comExistence = false; //有可用串口标志位
cboxCOM.Items.Clear(); //清除串口号中所有串口
for (int i = 0; i < 32; i++)
{
try
{
SerialPort sp = new SerialPort("COM" + (i + 1).ToString());
sp.Open();
sp.Close();
cboxCOM.Items.Add("COM" + (i + 1).ToString());
comExistence = true;
}
catch (Exception)
{
continue;
}
}
if (comExistence)
{
cboxCOM.SelectedIndex = 0; //使ListBox显示
}
else
{
MessageBox.Show("没有找到可用串口!", "错误提示");
}
}
//检测串口设置
private bool CheckPortSetting()
{
if (cboxCOM.Text.Trim() == "") return false;
if (cboxBaudRate.Text.Trim() == "") return false;
if (cboxDataBits.Text.Trim() == "") return false;
if (cboxParity.Text.Trim() == "") return false;
if (cboxStopBits.Text.Trim() == "") return false;
return true;
}
//开启串口按键响应
private void buttonOpen_Click(object sender, EventArgs e)
{
if (isOpen == false)
{
if (CheckPortSetting())
{
sp.PortName = cboxCOM.Text.Trim();//设置串口名
sp.BaudRate = Convert.ToInt32(cboxBaudRate.Text.Trim());//设置串口的波特率
float f = Convert.ToSingle(cboxStopBits.Text.Trim());//设置停止位
if (f == 0)
{
sp.StopBits = StopBits.None;
}
else if (f == 1.5)
{
sp.StopBits = StopBits.OnePointFive;
}
else if (f == 1)
{
sp.StopBits = StopBits.One;
}
else if (f == 2)
{
sp.StopBits = StopBits.Two;
}
else
{
sp.StopBits = StopBits.One;
}
sp.DataBits = Convert.ToInt16(cboxDataBits.Text.Trim());//设置数据位
string s = cboxParity.Text.Trim(); //设置奇偶校验位
if (s.CompareTo("无") == 0)
{
sp.Parity = Parity.None;
}
else if (s.CompareTo("奇校验") == 0)
{
sp.Parity = Parity.Odd;
}
else if (s.CompareTo("偶校验") == 0)
{
sp.Parity = Parity.Even;
}
else
{
sp.Parity = Parity.None;
}
}
else
{
return;
}
//设置超时读取时间
sp.ReadTimeout = -1;
sp.RtsEnable = true;
//定义DataReceived 事件,当串口收到数据后触发事件
sp.DataReceived -= new SerialDataReceivedEventHandler(sp_DataReceived);
sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
try//打开串口
{
sp.Open();
isOpen = true;
buttonOpen.Text = "关闭串口";
//串口打开后则相关的串口设置按钮便不可再用
cboxCOM.Enabled = false;
cboxBaudRate.Enabled = false;
cboxStopBits.Enabled = false;
cboxDataBits.Enabled = false;
cboxParity.Enabled = false;
buttonCheck.Enabled = false;
}
catch (Exception)
{
//打开串口失败后,相应标志位取消
isOpen = false;
MessageBox.Show("串口无效或已被占用!", "错误提示");
}
}
else
{
try//关闭串口
{
usart_closing = true;//告诉Invoke串口正在关闭
while (usart_listening) Application.DoEvents();//等待到Invoke执行完
sp.Close();
usart_closing = false;//以上代码旨在防止关闭串口时发生锁死现象
isOpen = false;
buttonOpen.Text = "打开串口";
//串口打开后则相关的串口设置按钮便不可再用
cboxCOM.Enabled = true;
cboxBaudRate.Enabled = true;
cboxStopBits.Enabled = true;
cboxDataBits.Enabled = true;
cboxParity.Enabled = true;
buttonCheck.Enabled = true;
countClear();
}
catch (Exception)
{
//打开串口失败后,相应标志位取消
isOpen = false;
MessageBox.Show("关闭串口时发生错误!", "错误提示");
}
}
}
//串口发送字符串
private void UartSend(String str)
{
if (isOpen == true)
{
try
{
sp.Write(str);
SendCount += Encoding.Default.GetBytes(str).Length;
refreshSendCount();
}
catch
{
PortErrorDeal();
}
}
else
{
MessageBox.Show("串口未打开!", "错误提示");
}
}
//发送数组
private void UartSend(byte[] buf, int len)
{
if (isOpen == true)
{
try
{
sp.Write(buf, 0, len);
SendCount += len;
refreshSendCount();
}
catch
{
PortErrorDeal();
}
}
else
{
MessageBox.Show("串口未打开!", "错误提示");
}
}
//发送数组
private void UartSend(byte[] buf)
{
UartSend(buf, buf.Length);
}
//串口接收事件
private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (usart_closing)
{
return;
}
else
{
usart_listening = true;
}
//this.Invoke跨线程访问ui
try
{
this.Invoke((EventHandler)(delegate
{
int Bytes_n = sp.BytesToRead; //避免缓存不一致
Byte[] ReceivedDatabuf = new Byte[Bytes_n]; //创建接收字节数组
sp.Read(ReceivedDatabuf, 0, Bytes_n); //读取所接收到的数据
buffer.AddRange(ReceivedDatabuf); //缓存数据
ReceiveCount += Bytes_n;
refreshReceiveCount();
}));
}
catch
{
PortErrorDeal();
}
finally
{
usart_listening = false;
}
}
//串口出错处理
private void PortErrorDeal()
{
MessageBox.Show("串口断开或者拔下!", "错误提示");
try
{
sp.Close();
}
catch
{
}
isOpen = false;
buttonOpen.Text = "打开串口";
//串口打开后则相关的串口设置按钮便不可再用
cboxCOM.Enabled = true;
buttonCheck.Enabled = true;
}
//刷新接收计数
private void refreshReceiveCount()
{
labReiveCount.Text = "接收:" + ReceiveCount.ToString();
}
//刷新发送计数
private void refreshSendCount()
{
labSendCount.Text = "发送:" + SendCount.ToString();
}
//计数值清零
private void countClear()
{
SendCount = 0;
ReceiveCount = 0;
refreshReceiveCount();
refreshSendCount();
}
//发送数据变化
private void labSendCount_TextChanged(object sender, EventArgs e)
{
}
//接收数据变化
private void labReiveCount_TextChanged(object sender, EventArgs e)
{
if (ReceiveCount == 0)
{
buffer.Clear();
}
else
{
recevivedData();
}
}
/*@end Serial Base*********************************************/
/*@start command Base******************************************/
private string createCommand(string comm, int param)
{
return (comm + param.ToString() + "\r\n");
}
private string createCommand(string comm, string param)
{
return (comm + param + "\r\n");
}
private int getCommand(string source, string comm, out int param)
{
int commPos = source.IndexOf(comm);
int endPos = source.IndexOf("\r\n");
int valueLen = endPos - commPos - comm.Length;
if (commPos > -1 && endPos > -1 && valueLen > 0)
{
string value = source.Substring(endPos - valueLen, valueLen);
try
{
param = int.Parse(value);
return getFirstEndFlag();
}
catch
{
}
}
param = 0;
return -1;
}
private int getCommand(string source, string comm, out string param)
{
int commPos = source.IndexOf(comm);
int endPos = source.IndexOf("\r\n");
int valueLen = endPos - commPos - comm.Length;
if (commPos > -1 && endPos > -1 && valueLen > 0)
{
param = source.Substring(endPos - valueLen, valueLen);
return getFirstEndFlag();
}
param = "";
return -1;
}
private int getFirstEndFlag()
{
int i = buffer.IndexOf((byte)'\r');
int j = buffer.IndexOf((byte)'\n');
if (i > -1)
{
if (j == (i + 1))
{
return i;
}
else
{
buffer.RemoveRange(0, i + 1);
return getFirstEndFlag();
}
}
return -1;
}
private void recevivedData()
{
if (getFirstEndFlag() > -1)
{
analysisData();
}
}
/*
* 作用:解析串口接收过来的数据,根据字符标志位进行数据截取到对应的显示地方
*/
private void analysisData()
{
bool getDataFlag = false;
{//光敏亮度显示
string source = System.Text.Encoding.Default.GetString(buffer.ToArray());
string param;
int dataLen = getCommand(source, LIGHT, out param);
if (dataLen > 0)
{
label_light.Text = "LIGHT\r\n" + param[1] + param[2] + param[3];
buffer.RemoveRange(0, dataLen + 2);
if (param[1] >= '6') //当亮度大于600时,关闭灯光
{
for (int i = 0; i < 10; i++)
{
UartSend(createCommand(LIGHT, "0"));
}
}
else //否则,灯光一直显示亮起
{
for (int i = 0; i < 10; i++)
{
UartSend(createCommand(LIGHT, "1"));
}
}
getDataFlag = true;
}
}
{//火焰显示
string source = System.Text.Encoding.Default.GetString(buffer.ToArray());
string param;
int dataLen = getCommand(source, FIRE, out param);
if (dataLen > 0)
{
label_fire.Text = "FIRE\r\n" + param[2] + param[3];
if (param[3] == '1') //当检测到火焰气体 param[3] == '1' 时,发出警报1
{
for (int i = 0; i < 10; i++)
{
UartSend(createCommand(FIRE, "1"));
}
}
else //此时若没监测火焰气体 param[3] == '0',关闭警报2,也可以在上位机的按钮关掉
{
for (int i = 0; i < 10; i++)
{
UartSend(createCommand(FIRE, "0"));
}
}
buffer.RemoveRange(0, dataLen + 2);
getDataFlag = true;
}
}
{//烟雾显示
string source = System.Text.Encoding.Default.GetString(buffer.ToArray());
string param;
int dataLen = getCommand(source, SMOKE, out param);
if (dataLen > 0)
{
label_smoke.Text = "SMOKE\r\n" + param[2] + param[3];
buffer.RemoveRange(0, dataLen + 2);
getDataFlag = true;
}
}
{//人体显示
string source = System.Text.Encoding.Default.GetString(buffer.ToArray());
string param;
int dataLen = getCommand(source, HUMAN, out param);
if (dataLen > 0)
{
label_human.Text = "HUMAN\r\n" + param[2] + param[3];
if (param[3] == '1') //当检测到人体 param[3] == '1' 时,发出警报2
{
for (int i = 0; i < 10; i++)
{
UartSend(createCommand(HUMAN, "1"));
}
}
else //此时若没监测到人体 param[3] == '0',关闭警报2,也可以在上位机的按钮关掉
{
for (int i = 0; i < 10; i++)
{
UartSend(createCommand(HUMAN, "0"));
}
}
buffer.RemoveRange(0, dataLen + 2);
getDataFlag = true;
}
}
{//PM2.5显示
string source = System.Text.Encoding.Default.GetString(buffer.ToArray());
string param;
int dataLen = getCommand(source, PM, out param);
if (dataLen > 0)
{
label_pm.Text = "PM2.5\r\n" + param[2] + param[3];
buffer.RemoveRange(0, dataLen + 2);
getDataFlag = true;
}
}
{//温度显示
string source = System.Text.Encoding.Default.GetString(buffer.ToArray());
string param;
int dataLen = getCommand(source, TEMPERATURE, out param);
if (dataLen > 0)
{
label_temperature.Text = "温度\r\n" + param[0] + param[1] + "°C";
label_humidity.Text = "湿度\r\n" + param[3] + param[4] + "%";
buffer.RemoveRange(0, dataLen + 2);
getDataFlag = true;
}
}
//如果还存在结束符
int endPos = getFirstEndFlag();
if (endPos > -1)
{
if (!getDataFlag)
{
buffer.RemoveRange(0, endPos + 2);
}
analysisData();
}
}
/*@end command Base********************************************/
public FormMain()
{
InitializeComponent();
}
private void FormMain_Load(object sender, EventArgs e)
{
SerialSettingInit();
//gboxSwithSetting.Enabled = false;
//gboxSwith2Setting.Enabled = false;
//gboxSwith3Setting.Enabled = false;
}
/*
* 作用:定义数据标志位,进而获取对应终端节点的数据
*/
private const string LIGHT = "L"; //光敏亮度
private const string HUMAN = "H"; //人体感应
private const string FIRE = "F"; //火焰
private const string SMOKE = "S"; //烟雾
private const string PM = "P"; //PM2.5
private const string CURTAIN = "C"; //窗帘
private const string TEMPERATURE = "T"; //温度
private const string HUMIDITY = "D"; //湿度
private void txtThreshol_KeyPress(object sender, KeyPressEventArgs e)
{
if ((e.KeyChar < 48 || e.KeyChar > 57) && (e.KeyChar != 8))
{
e.Handled = true;
}
base.OnKeyPress(e);
}
/*
* 作用:下发数据命令进行终端节点的控制,“L1”,“L0”,“S1”,“S0”
*/
//
private void button1_Click_1(object sender, EventArgs e)
{
UartSend(createCommand(HUMAN, "1"));
}
//关警报2
private void button2_Click(object sender, EventArgs e)
{
UartSend(createCommand(HUMAN, "0"));
}
//
private void button3_Click(object sender, EventArgs e)
{
UartSend(createCommand(FIRE, "1"));
}
//关警报1
private void button4_Click(object sender, EventArgs e)
{
UartSend(createCommand(FIRE, "0"));
}
//开风扇
private void button5_Click(object sender, EventArgs e)
{
UartSend(createCommand(SMOKE, "1"));
}
//关风扇
private void button6_Click(object sender, EventArgs e)
{
UartSend(createCommand(SMOKE, "0"));
}
//开窗帘
private void button7_Click_1(object sender, EventArgs e)
{
UartSend(createCommand(CURTAIN, "1"));
}
//关窗帘
private void button8_Click(object sender, EventArgs e)
{
UartSend(createCommand(CURTAIN, "0"));
}
//开灯
private void button9_Click(object sender, EventArgs e)
{
UartSend(createCommand(LIGHT, "1"));
}
//关灯
private void button10_Click(object sender, EventArgs e)
{
UartSend(createCommand(LIGHT, "0"));
}
复制代码
C#代码下载:
智能家居(上位机).7z
(703.6 KB, 下载次数: 89)
2022-5-5 04:04 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
longlian123
时间:
2022-11-24 09:13
现在正在学习这个,谢谢了。
作者:
gb1106026240
时间:
2023-1-12 16:37
您好,我想请教一下 下位机如何处理上位机发送的指令L0、L1的
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1