煙霧,光敏亮度,火焰等傳感器數據的采集,上位機實現窗簾的開關
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
|