基于ZigBee的水质监测系统设计

编程入门 行业动态 更新时间:2024-10-20 16:02:41

基于ZigBee的<a href=https://www.elefans.com/category/jswz/34/1745487.html style=水质监测系统设计"/>

基于ZigBee的水质监测系统设计

1  适用场景


        河流、游泳池、水池、鱼塘、生活用水、工业用水等水质监测场景。


2  开发环境


        下位机开发环境:IAR embedded Workbench

        上位机开发环境:Visual Studio 2022

       小鱼儿电子设计微信号:IOTElectronics


3  硬件元件(可考虑加PH或电导率传感器)


        ZigBee网关节点(芯片型号为CC2530单片机)、ZigBee采集节点(芯片型号为CC2530单片机)、DS18B20温度传感器(防水型)、水位传感器、浊度传感器、蜂鸣器、按键模块、USB转TTL-CH340模块、OLED显示幕、USB充电线


4  功能


  •     实时监测:实时监测水温、水位、浊度,并显示到OLED屏幕上。
  •     异常报警:当水温、水位、浊度未处于设定阈值范围,自动进行声光报警提醒。
  •     上位机监测:在上位机端可以实时查看水温值、水位值、浊度值,设置水温值、水位值、浊度值的阈值。
  •     数据库:可以查看历史的水温、水位、浊度的实时值及参数发生异常的状态。

5  下位机实物图



6  上位机 



6  数据库 



7  上位机相关源码 


//物联网电子设计微信:IOTElectronics 
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 ZigBeeApp
{public partial class FormMain : Form{/*@start Serial Base*********************************************/private SerialPort sp = new SerialPort();//声明一个串口类private bool isOpen = false;//打开串口标志位private bool usart_closing = false;//是否正在关闭串口,执行Application.DoEvents,阻止再次进入invokeprivate bool usart_listening = false;//监听是否在执行串口invoke相关操作private List<byte> buffer = new List<byte>(4096);//默认分配1页内存,并始终限制不允许超过private long SendCount = 0;private long ReceiveCount = 0;//串口窗体初始化private void SerialSettingInit(){//最大支持到串口32,可根据自己需求增加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 显示第1 个添加的索引}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;                       //执行Invoke开始,ui不可以关闭串口了}//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);         //读取所接收到的数据ReceiveCount += Bytes_n;buffer.AddRange(ReceivedDatabuf);             //1.缓存数据 refreshReceiveCount();}));}catch{PortErrorDeal();}finally{usart_listening = false;//执行完Invoke了,ui可以关闭串口了}}//串口出错处理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();}}
}

更多推荐

基于ZigBee的水质监测系统设计

本文发布于:2024-03-10 20:23:47,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1728947.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:水质   监测系统   ZigBee

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!