基于物联网的智能植物养护系统的设计与实现

2024-01-25 06:04

本文主要是介绍基于物联网的智能植物养护系统的设计与实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

基于物联网的智能植物养护系统的设计与实现

系统简介

        由于大多数人喜欢花草却不会照料,买了花草之后却没有时间照顾,从而导致花草枯萎。本设计利用wifi传输设定植物的适当光照强度,适当的土壤温湿度。然后根据温湿度传感器及光照传感进行实时监测。当温度,湿度高于适当温湿度时,采取措施降低温湿度。当温度,湿度低于适当温度时,采取措施升高温湿度。当光照太强时,适当遮挡,降低光照强度;当光照强度太弱时,开灯增强光照强度。总之给植物一个适宜的生长环境。

材料

  • 正点原子战舰V3开发板
  • 连接到电脑的T口线
  • DHT11温湿度模块
  • 整点原子3.4寸TFT显示屏

展示视频

基于物联网的智能植物养护系统下位机演示视频

基于物联网的智能植物养护系统上位机演示视频

制作

        下位机使用的芯片是STM32F103ZET6,软件使用的是Keil,语言是C。
        上位机软件用的是VS2017,语言是C#。
        硬件连接:插上战舰板子就行了。

下位机制作

led灯会根据光照传感器检测光强自动调节亮度;
还有一个IO口我也用pwm做好了,连接上马达,就可以根据温度自动调整转速;
目前没有湿度补充,我打的是风扇转速的数据;

主函数

 int main(void){	 u8 Light ;u16 led0pwmval=0;u8 dir=1;	vu8 key=0;int i;u8 t=0;		u16 len;		 u8 temperature;  	    u8 humidity;    	   u16 temp_sup=25,humi_sup=35,light_sup=0;KEY_Init();delay_init();	    	 //延时函数初始化	  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级uart_init(115200);	 	//串口初始化为115200LED_Init();		  		//初始化与LED连接的硬件接口TIM4_PWM_Init(899,0);TIM3_PWM_Init(899,0);LCD_Init();			   	//初始化LCD  Lsens_Init();POINT_COLOR=RED;		//设置字体为红色 display0();while(DHT11_Init())	//DHT11初始化	{LCD_ShowString(30,100,200,16,16,"DHT11 Error");delay_ms(200);LCD_Fill(30,130,239,130+16,WHITE);delay_ms(200);}			POINT_COLOR=BLUE;//设置字体为蓝色display1(); display2();while(1){	  POINT_COLOR=RED; 	    Light=Lsens_Get_Val();LCD_ShowxNum(35,130,Light,2,24,0);				//显示ADC的值 t++;if(t%10==0)			//每100ms读取一次{									  DHT11_Read_Data(&temperature, &humidity);	//读取温湿度值LCD_ShowNum(100,130,temperature,2,24);		//显示温度LCD_ShowNum(165,130,humidity,2,24);			//显示湿度LCD_ShowNum(120,190,light_sup,4,16);		//显示湿度LCD_ShowNum(120,230,humi_sup,4,16);			//显示湿度LCD_ShowNum(120,270,temp_sup,4,16);			//显示湿度POINT_COLOR=BLUE;printf("温度%2d",temperature);delay_ms(10);printf("湿度%2d",humidity);delay_ms(10);printf("光强%2d",Light);delay_ms(10);}USART_SendData(USART1, temperature*16);light_sup = 300-(Light*3);humi_sup = temp_sup = (temperature-24)*60;TIM_SetCompare1(TIM4,humi_sup);TIM_SetCompare2(TIM3,light_sup);}
}

显示函数

void display2()
{LCD_ShowChinese(90,110,0,16,1);		 	//温度:LCD_ShowChinese(108,110,2,16,1);	LCD_ShowChinese(126,110,12,16,1);LCD_ShowChinese(155,110,1,16,1);		//湿度:LCD_ShowChinese(173,110,2,16,1);		LCD_ShowChinese(191,110,12,16,1);LCD_ShowChinese(30,110,13,16,1);		//光强LCD_ShowChinese(48,110,14,16,1);LCD_ShowChinese(66,110,12,16,1);LCD_ShowString(126,137,200,16,16,"C");LCD_ShowString(191,137,200,16,16,"%");LCD_ShowString(60,137,200,16,16,"cd");
}

上位机制作

数据可以同下位机实时更新;
用的是串口1,有线,蓝牙还没有回来;
产生的折线图只有温度的;
折线图快捷键可以使用。**

主窗口函数

namespace Drawer
{public delegate void ShowWindow();public delegate void HideWindow();public delegate void OpenPort();public delegate void ClosePort();public delegate Point GetMainPos();public delegate int GetMainWidth();public partial class Form1 : Form{Drawer Displayer;public Form1(){InitializeComponent();System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;serialPort1.Encoding = Encoding.GetEncoding("GB2312");                                  //串口接收编码this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(Form1_FormClosing);}private void Form1_FormClosing(object sender, EventArgs e){try { serialPort1.Close(); }catch { }}public void ClosePort()//关闭串口,供委托调用{try{serialPort1.Close();}catch (System.Exception){}}private Point GetMyPos()//供委托调用{return this.Location;}public void OpenPort()//打开串口,供委托调用{try{serialPort1.Open();}catch (System.Exception){MessageBox.Show("串口打开失败,请检查", "错误");}}public void ShowMe()//供委托调用{this.Show();}public void HideMe()//供委托调用{this.Hide();}private void Form1_Load(object sender, EventArgs e){for (int i = 0; i < 20; i++){try{serialPort1.PortName = "COM" + i;serialPort1.Open();toolStripComboBox1.Items.Add(serialPort1.PortName);serialPort1.Close();if (toolStripComboBox1.Text == "")toolStripComboBox1.Text = serialPort1.PortName;}catch { }timer1.Start();}}private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e){try{textBox7.Text = serialPort1.ReadExisting();byte[] data = new byte[serialPort1.BytesToRead];  //定义缓冲区,因为串口事件触发时有可能收到不止一个字节serialPort1.Read(data, 0, data.Length);if (Displayer != null)                            //Displayer就是波形绘制窗口的一个对象  就是那个窗口Displayer.AddData(data);if (textBox7.Text.Contains("温度"))textBox1.Text = textBox7.Text.Substring(2, 2);else if (textBox7.Text.Contains("湿度"))textBox2.Text = textBox7.Text.Substring(2, 2);else if (textBox7.Text.Contains("光强"))textBox3.Text = textBox7.Text.Substring(2, 2);//foreach (byte Member in data)                                                   //遍历用法//{//    string str = Convert.ToString(Member, 16).ToUpper();//    textBox8.AppendText("0x" + (str.Length == 1 ? "0" + str : str) + " ");//}textBox4.Text = (300 - (Convert.ToInt16(textBox3.Text) * 3)).ToString();textBox5.Text = textBox6.Text = ((Convert.ToInt16(textBox1.Text) - 24) * 60).ToString();}catch { }}private void CreateNewDrawer()//创建ADC绘制窗口{Displayer = new Drawer();//创建新对象Displayer.ShowMainWindow = new ShowWindow(ShowMe);//初始化类成员委托Displayer.HideMainWindow = new HideWindow(HideMe);Displayer.GetMainPos = new GetMainPos(GetMyPos);Displayer.CloseSerialPort = new ClosePort(ClosePort);Displayer.OpenSerialPort = new OpenPort(OpenPort);Displayer.GetMainWidth = new GetMainWidth(GetMyWidth);Displayer.Show();//显示窗口}int GetMyWidth()//供委托调用{return this.Width;}private void CreateDisplayer(){this.Left = 0;CreateNewDrawer();Rectangle Rect = Screen.GetWorkingArea(this);Displayer.SetWindow(Rect.Width - this.Width, new Point(this.Width, this.Top));//设置绘制窗口宽度,以及坐标}private void timer1_Tick(object sender, EventArgs e){label1.Text = DateTime.Now.ToString();}private void 打开串口ToolStripMenuItem_Click(object sender, EventArgs e){if (打开串口ToolStripMenuItem.Text == "打开串口"){try{serialPort1.PortName = toolStripComboBox1.Text;serialPort1.Open();打开串口ToolStripMenuItem.Text = "关闭串口";}catch{MessageBox.Show("端口错误!请检查端口,或重启软件!", "错误!");}}else{serialPort1.Close();打开串口ToolStripMenuItem.Text = "打开串口";}}private void 变化曲线ToolStripMenuItem_Click(object sender, EventArgs e){if (serialPort1.IsOpen){if (Displayer == null)//第一次创建Displayer = null{CreateDisplayer();}else{if (Displayer.IsDisposed)//多次创建通过判断IsDisposed确定串口是否已关闭,避免多次创建{CreateDisplayer();}}}elseMessageBox.Show("请打开串口!", "。。。是不是没打开串口!");}}
}

总结

项目本身功能简单,但是包含内容还是挺多的,扩展的话也比较容易。

项目地址:https://download.csdn.net/download/weixin_42320020/88779084

这篇关于基于物联网的智能植物养护系统的设计与实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/642291

相关文章

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

MySQL双主搭建+keepalived高可用的实现

《MySQL双主搭建+keepalived高可用的实现》本文主要介绍了MySQL双主搭建+keepalived高可用的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、测试环境准备二、主从搭建1.创建复制用户2.创建复制关系3.开启复制,确认复制是否成功4.同

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义