基于STM32的智慧农业项目(物联网专业毕设)附送源码和文档材料+学习路线

文章目录

    • 概要
    • 整体架构流程
    • 硬件选型
    • 软件总体框架
    • 技术细节
    • 实现效果
    • 小结

概要

传统农业存在着产量受到环境因素影响较大的问题,现有的农业监测系统数据太过简单、太过理想化。而随着现代科学的持续发展,一个精准化、自动化的现代智能农产品管理系统将在农业生产中起着日益关键的角色。
本项目立足于温室大棚,设计一个能够智能控制和远程监控的智慧农业监测系统,实现了感知节点数据采集、上传,以及接收小程序发来的指令,控制水泵、排风扇、暖灯、蜂鸣器等。本系统主要采用低功率单片机stm32f103作为主控芯片,使用DHT11、MQ-2、XH-M214土壤湿度传感器、BH1750光照强度模块,采集温室大棚环境数据,esp8266作为通讯模块,上传至搭建好的MQTT服务器中。利用串口屏可以进行数据的实时显示和控制。小程序基于mpvue框架进行开发,实现了数据显示、命令下发、账户注册、账户登陆功能。使得温室大棚的环境参数能够可视化,并且能远程控制温室大棚内部的执行器。本项目解决了一些农业中信息闭塞,决策迟缓不科学的问题。可以大大提高农业生产效率,增加农业产量。推动地区温室大棚农业经济蓬勃发展。

整体架构流程

本系统基于stm32单片机和微信小程序,其主要功能包括大棚内部温度、空气湿度、光照强度、大棚内二氧化碳浓度等数据的采集、上传和显示。水泵,风扇,暖灯,报警开关的远程控制。主要模块包含:硬件系统设计(传感器数据的采集、上传、逻辑控制,液晶屏数据显示),软件系统设计(MQTT服务器使用、服务器配置、界面设计)、系统功能实现、系统测试。本系统采用使用stm32单片机和微信小程序,设计包括硬件和软件的智慧农业检测系统。基于传感器、通信、自动化等技术,对农业生产的环境参数和设备进行实时监控。
在这里插入图片描述

硬件选型

软件总体框架

在这里插入图片描述

在这里插入图片描述

技术细节

主函数代码

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "dht11.h"
#include "beep.h"
#include "esp8266.h"
#include "onenet.h"
#include "stdio.h"
#include "bh1750.h"
#include "adc.h"
#include "timer.h"
#include "mq2.h"
#include "relay.h"
#include "fs.h"
#include "pump.h"
/************************************************
参考正点原子工程建立的代码
************************************************/u8 humidityH;	  //湿度整数部分
u8 humidityL;	  //湿度小数部分
u8 temperatureH;   //温度整数部分
u8 temperatureL;   //温度小数部分
u8 alarmFlag = 0;//是否报警的标志
u8 alarm_is_free = 10;//报警器是否被手动操作,如果被手动操作即设置为0
u8 ESP8266_INIT_OK = 0;//esp8266初始化完成标志
u8 Led_Status = 0;//led状态
//u16 adcx=0;//adc的初始值
u16 adcx1;
u16 shidu;
char PUB_BUF[256];//上传数据的buf
unsigned char HDMI_BUF[64];//HDMI发送数据buf
float Light = 0; //光照度
float co2 = 0; //二氧化碳浓度
float temp = 0;
float hum = 0;
const char* devSubTopic[] = {"/mysmartfarm/sub"};
const char devPubTopic[] = "/mysmartfarm/pub";
int main(void)
{unsigned short timeCount = 0;	//发送间隔变量unsigned char* dataPtr = NULL;delay_init();	    //延时函数初始化LED_Init();		  	//初始化与LED连接的硬件接口DHT11_Init();//DHT11初始化BEEP_Init();//蜂鸣器初始化RELAY_Init();//继电器初始化BH1750_Init();//光照传感器初始化Adc_Init();//adc初始化Adc2_Init();//adc2初始化Usart1_Init(115200);//串口初始化Usart2_Init(115200);//esp8266通讯串口初始化Usart3_Init(9600);//HDMI串口屏初始化ESP8266_Init();//esp8266初始化fs_Init();pump_Init();HMISendstart();//HDMI清空NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级TIM3_Int_Init(4999, 7199); //10Khz的计数频率,计数到5000为500mswhile(OneNet_DevLink())delay_ms(500);// BEEP=0;//鸣叫表示接入成功// delay_ms(250);// BEEP=1;OneNet_Subscribe(devSubTopic, 1);while(1){
//			delay_ms(100);adcx1 = Get_Adc_Average(ADC_Channel_10, 10);shidu = ((4095 - adcx1) * 100) / 3292;
//		UsartPrintf(USART1,"adcx1:%d",adcx1);
//		UsartPrintf(USART1,"shidu: %d",shidu);DHT11_Read_Data(&humidityH, &humidityL, &temperatureH, &temperatureL);temp = temperatureH + temperatureL * 0.01;sprintf((char*)HDMI_BUF, "page0.t0.txt=\"%.1f\"", temp);HMISends((char*)HDMI_BUF);HMISendb(0xff);sprintf((char*)HDMI_BUF, "page0.t2.txt=\"%d\"", shidu);HMISends((char*)HDMI_BUF);HMISendb(0xff);Light = LIght_Intensity();sprintf((char*)HDMI_BUF, "page0.t1.txt=\"%.1f\"", Light);HMISends((char*)HDMI_BUF);HMISendb(0xff);co2 = MQ2_GetPPM();sprintf((char*)HDMI_BUF, "page0.t3.txt=\"%.1f\"", co2);HMISends((char*)HDMI_BUF);HMISendb(0xff);if(++timeCount >= 200)									//发送间隔5s{Led_Status = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5); //读取LED0的状态// hum=humidityH+humidityL*0.01;////			UsartPrintf(USART1,"湿度高位:%d",humidityH);
//		UsartPrintf(USART1,"湿度低位:%d",humidityL);
//		UsartPrintf(USART1,"湿度:%.1f",hum);//adcx=Get_Adc_Average(ADC_Channel_1,10);UsartPrintf(USART1, "湿度:%d温度:%d.%d 光照强度:%.1f ppm值:%.1f", shidu, temperatureH, temperatureL, Light, co2); //c格式化字符串UsartPrintf(USART_DEBUG, "OneNet_Publish\r\n");sprintf(PUB_BUF, "{\"Hum\":%d,\"Temp\":%d.%d,\"Light\":%.1f,\"Co2\":%.1f,\"Led\":%d,\"Beep\":%d}",shidu, temperatureH, temperatureL, Light, co2, Led_Status ? 0 : 1, alarmFlag);//OneNet_Publish("pcTopic", "MQTT Publish Test");
//OneNet_Publish(devPubTopic, PUB_BUF);timeCount = 0;ESP8266_Clear();}
//dataPtr = ESP8266_GetIPD(3);if(dataPtr != NULL)OneNet_RevPro(dataPtr);}
}

各种传感器驱动文件
在这里插入图片描述
接收平台发送的数据


//==========================================================
//	函数名称:	OneNet_RevPro
//
//	函数功能:	平台返回数据检测
//
//	入口参数:	dataPtr:平台返回的数据 也就是*cmd
//
//	返回参数:	无
//
//	说明:		
//==========================================================
void OneNet_RevPro(unsigned char *cmd)
{MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0};								//协议包char *req_payload = NULL;char *cmdid_topic = NULL;unsigned short topic_len = 0;unsigned short req_len = 0;unsigned char type = 0;unsigned char qos = 0;static unsigned short pkt_id = 0;short result = 0;char *dataPtr = NULL;char numBuf[10];int num = 0;cJSON *json , *json_value;type = MQTT_UnPacketRecv(cmd);switch(type){case MQTT_PKT_CMD:															//命令下发result = MQTT_UnPacketCmd(cmd, &cmdid_topic, &req_payload, &req_len);	//解出topic和消息体if(result == 0){DEBUG_LOG("cmdid: %s, req: %s, req_len: %d\r\n", cmdid_topic, req_payload, req_len);MQTT_DeleteBuffer(&mqttPacket);									//删包}break;case MQTT_PKT_PUBLISH:														//接收的Publish消息result = MQTT_UnPacketPublish(cmd, &cmdid_topic, &topic_len, &req_payload, &req_len, &qos, &pkt_id);if(result == 0){DEBUG_LOG("topic: %s, topic_len: %d, payload: %s, payload_len: %d\r\n",cmdid_topic, topic_len, req_payload, req_len);// 对数据包req_payload进行JSON格式解析json = cJSON_Parse(req_payload);//if (!json)UsartPrintf(USART_DEBUG,"Error before: [%s]\n",cJSON_GetErrorPtr());//	if(json)//{json_value = cJSON_GetObjectItem(json , "target");UsartPrintf(USART_DEBUG,"json_value: [%s]\n",json_value->string);//输出是什么键UsartPrintf(USART_DEBUG,"json_value: [%s]\n",json_value->valuestring);//输出是什么值if(strstr(json_value->valuestring,"BEEP") != NULL){json_value = cJSON_GetObjectItem(json , "value");if(json_value->valueint){alarmFlag = 1;BEEP=1;}//打开报警器else {alarmFlag = 0;//关闭报警器alarm_is_free=0;BEEP=0;}//上位机控制跟手动控制具有一样的优先级 优先于自动控制,因此要把alarm_is_free 归0}if(strstr(json_value->valuestring,"LED") != NULL){json_value = cJSON_GetObjectItem(json , "value");if(json_value->valueint){//	while(1)//{LED0 = 0;//开灯// pump=1;	//水泵打开RELAY=0;	//继电器打开delay_ms(20);//	}}							else {LED0 = 1;//关灯//pump=0;RELAY=1;delay_ms(20);}}if(strstr(json_value->valuestring,"Pump") != NULL){json_value = cJSON_GetObjectItem(json , "value");if(json_value->valueint){LED0 = 0;//开灯pump=1;	//水泵打开//delay_ms(1000);}							else {LED0 = 1;//关灯pump=0;//水泵关闭//delay_ms(1000);}}if(strstr(json_value->valuestring,"Fs") != NULL){json_value = cJSON_GetObjectItem(json , "value");if(json_value->valueint){//LED0 = 0;//开灯fs=1;	//风扇打开//delay_ms(1000);}							else {//LED0 = 1;//关灯fs=0;//风扇关闭//delay_ms(1000);}}//					if(json_value->valueint)//json_value > 0且为整形
//					{
//						LED0 = 0;//打开LED0 
//					}
//					else
//					{
//						LED0 = 1;//关闭LED0 
//					}//	}cJSON_Delete(json);}break;case MQTT_PKT_PUBACK:														//发送Publish消息,平台回复的Ackif(MQTT_UnPacketPublishAck(cmd) == 0)DEBUG_LOG("Tips:	MQTT Publish Send OK\r\n");break;case MQTT_PKT_PUBREC:														//发送Publish消息,平台回复的Rec,设备需回复Rel消息if(MQTT_UnPacketPublishRec(cmd) == 0){DEBUG_LOG("Tips:	Rev PublishRec\r\n");if(MQTT_PacketPublishRel(MQTT_PUBLISH_ID, &mqttPacket) == 0){DEBUG_LOG("Tips:	Send PublishRel\r\n");ESP8266_SendData(mqttPacket._data, mqttPacket._len);MQTT_DeleteBuffer(&mqttPacket);}}break;case MQTT_PKT_PUBREL:														//收到Publish消息,设备回复Rec后,平台回复的Rel,设备需再回复Compif(MQTT_UnPacketPublishRel(cmd, pkt_id) == 0){DEBUG_LOG("Tips:	Rev PublishRel\r\n");if(MQTT_PacketPublishComp(MQTT_PUBLISH_ID, &mqttPacket) == 0){DEBUG_LOG("Tips:	Send PublishComp\r\n");ESP8266_SendData(mqttPacket._data, mqttPacket._len);MQTT_DeleteBuffer(&mqttPacket);}}break;case MQTT_PKT_PUBCOMP:														//发送Publish消息,平台返回Rec,设备回复Rel,平台再返回的Compif(MQTT_UnPacketPublishComp(cmd) == 0){DEBUG_LOG("Tips:	Rev PublishComp\r\n");}break;case MQTT_PKT_SUBACK:														//发送Subscribe消息的Ackif(MQTT_UnPacketSubscribe(cmd) == 0)DEBUG_LOG("Tips:	MQTT Subscribe OK\r\n");elseDEBUG_LOG("Tips:	MQTT Subscribe Err\r\n");break;case MQTT_PKT_UNSUBACK:														//发送UnSubscribe消息的Ackif(MQTT_UnPacketUnSubscribe(cmd) == 0)DEBUG_LOG("Tips:	MQTT UnSubscribe OK\r\n");elseDEBUG_LOG("Tips:	MQTT UnSubscribe Err\r\n");break;default:result = -1;break;}ESP8266_Clear();									//清空缓存if(result == -1)return;dataPtr = strchr(req_payload, '}');					//搜索'}'if(dataPtr != NULL && result != -1)					//如果找到了{dataPtr++;while(*dataPtr >= '0' && *dataPtr <= '9')		//判断是否是下发的命令控制数据{numBuf[num++] = *dataPtr++;}num = atoi((const char *)numBuf);				//转为数值形式}if(type == MQTT_PKT_CMD || type == MQTT_PKT_PUBLISH){MQTT_FreeBuffer(cmdid_topic);MQTT_FreeBuffer(req_payload);}}

实现效果

在这里插入图片描述 在这里插入图片描述
在这里插入图片描述 在这里插入图片描述

小结

以下是源码资料,如果小伙伴需要一些文档材料可以关注私聊我,小程序是参考B站教程。
链接:https://pan.baidu.com/s/18KGgCLT6FTjoIHZArUDtVw
提取码:sfav
–来自百度网盘超级会员V5的分享
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/196478.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

个人Windows电脑通过Cloudreve+Cpolar搭建PHP云盘系统公网可访问

文章目录 1、前言2、本地网站搭建2.1 环境使用2.2 支持组件选择2.3 网页安装2.4 测试和使用2.5 问题解决 3、本地网页发布3.1 cpolar云端设置3.2 cpolar本地设置 4、公网访问测试5、结语 1、前言 自云存储概念兴起已经有段时间了&#xff0c;各互联网大厂也纷纷加入战局&#…

⭐ Unity + ARKIT 介绍 以及 平面检测的实现

在AR插件中&#xff0c;ARKIT是比较特殊的一个&#xff0c;首先他在很多追踪上的效果要比其他的AR插件要好&#xff0c;但是只能在IOS系统设备上运行。 1.首先ARKIT在最新版Unity已经集成在AR Foundation中&#xff0c;那我们就需要ARSession 和ARSessionOrigin这两个重要组件…

netcore swagger 错误 Failed to load API definition

后端接口报错如下&#xff1a; 前端nswag报错如下&#xff1a; 根据网上查询到的资料说明&#xff0c;说一般swagger这种错误都是控制器里有接口代码异常造成的&#xff0c;通常是接口没有加属性Attribute&#xff0c; 比如[HttpPost("Delete")]、[HttpGet("Del…

chown和chmod

chown和chmod都是在Linux和Unix系统中用于设置文件和文件夹权限的命令&#xff0c;但它们的功能和用途有所不同。 功能&#xff1a;chown主要用于修改文件或文件夹的所有者和所属组&#xff0c;而chmod则主要用于修改文件或文件夹的读写执行权限。用途&#xff1a;如果想要授权…

Vue3 组合式实现 带连接线的Tree型 架构图(一级树形图)

创建组件名称 TreeNodeView.vue <template><div class"tree-node"><div class"node">{{ rootNodeName }}</div><div class"children" :style"childrenLineStyle"><div class"child-node"…

12月4日作业

完成沙发床的多继承 #include <iostream>using namespace std;class Sofa { private:string sit;int *price; public:Sofa() {cout << "Sofa::无参构造函数" << endl;}Sofa(string sit,int price):sit(sit),price((new int(price))){cout <<…

AutoHotKey-study

目录 使用编辑器脚本注意函数解释信息调试方法键盘获取方法脚本练习 最近发现常用键盘的上下左右箭头去操作输入输出问题感觉很不是滋味&#xff0c;不像Linux那样&#xff0c;有vim的使用&#xff0c;就想着有没有什么方法更快捷&#xff0c;更方便的去使用电脑键盘&#xff0…

分享80个菜单导航JS特效,总有一款适合您

分享80个菜单导航JS特效&#xff0c;总有一款适合您 80个菜单导航JS特效下载链接&#xff1a;https://pan.baidu.com/s/1NgNc759Kg1of_8vR7kaj6A?pwd6666 提取码&#xff1a;6666 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;…

pip的基本命令和使用

pip 简介 pip是Python官方的包管理器&#xff0c;可以方便地安装、升级和卸载Python包。 pip 常用命令 显示版本和路径 pip --version获取帮助 pip --help升级pip和升级包 pip install --upgrade pip # Linux/macOS pip install -U pip # windowspip install…

【Cesium】模型平面裁切

const scene viewer.scene;let tileset; let targetY 400.0; let planeEntities []; let selectedPlane; // 选择的切面 let clippingPlanes; // 切面属性// 当鼠标点击切面时&#xff0c;修改相关属性 const downHandler new Cesium.ScreenSpaceEventHandler(viewer.sce…

表达式二叉树的中序遍历:2017年408算法题

算法思想 表达式二叉树的中序遍历即中缀表达式除了根节点和叶结点&#xff0c;遍历到其他结点时在遍历其左子树前加上左括号&#xff0c;在遍历完右子树后加上右括号 算法实现 //中序遍历&#xff0c;deep从1开始&#xff0c;即根节点的深度为1 void midOrder(BTree T,int …

作业12.4

1.沙发床的多继承 #include <iostream>using namespace std; class Sofa { private:string sit; public://无参构造Sofa(){}//有参构造Sofa(string sit):sit(sit){}//拷贝构造Sofa(const Sofa &other):sit(other.sit){}//拷贝赋值Sofa &operator (const Sofa &…

【数据分享】2015-2023年我国区县逐月二手房房价数据(Excel/Shp格式)

房价是一个城市发展程度的重要体现&#xff0c;一个城市的房价越高通常代表这个城市越发达&#xff0c;对于人口的吸引力越大&#xff01;因此&#xff0c;房价数据是我们在各项城市研究中都非常常用的数据&#xff01;之前我们分享过2015-2023年我国地级市逐月房价数据&#x…

基于姿态估计的3D动画生成

在本文中&#xff0c;我们将尝试通过跟踪 2D 视频中的动作来渲染人物的 3D 动画。 在 3D 图形中制作人物动画需要大量的运动跟踪器来跟踪人物的动作&#xff0c;并且还需要时间手动制作每个肢体的动画。 我们的目标是提供一种节省时间的方法来完成同样的任务。 我们对这个问题…

MATLAB学习QPSK之QPSK_MOD_DEMOD_SALIMup分析

学习的背景说明 因为在学习5G物理层&#xff0c;一直很忙&#xff0c;没有时间。最近稍有一点空闲&#xff0c;所以&#xff0c;学习一下算法。 QPSK的算法&#xff0c;虽然说我没有完全学透&#xff0c;大致还是懂的。只能一直没时间用MATLAB来研究一下。 然后看到这个实例&…

YITH WooCommerce Social Login跨境电商网站社交登录高级版插件

点击阅读YITH WooCommerce Social Login跨境电商网站社交登录高级版插件原文 YITH WooCommerce Social Login跨境电商网站社交登录高级版插件让您的用户节省时间并通过他们的社交资料之一登录或注册网站。 您如何从中受益&#xff1a; 用户无需填写表格、插入个人数据&#…

【数据分享】我国12.5米分辨率的地形粗糙度(起伏度)数据(免费获取)

地形数据&#xff0c;也叫DEM数据&#xff0c;是我们在各项研究中最常使用的数据之一。之前我们分享过源于NASA地球科学数据网站发布的12.5米分辨率DEM地形数据&#xff01;基于该数据我们处理得到12.5米分辨率的坡度数据、坡向数据、山体阴影数据&#xff08;均可查看之前的文…

基于Python的6+1号码生成器

&#x1f388; 博主&#xff1a;一只程序猿子 &#x1f388; 博客主页&#xff1a;一只程序猿子 博客主页 &#x1f388; 个人介绍&#xff1a;爱好(bushi)编程&#xff01; &#x1f388; 创作不易&#xff1a;如喜欢麻烦您点个&#x1f44d;或者点个⭐&#xff01; &#x1f…

(C++)盛水最多的容器--双指针法

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://le…

掌握排序的艺术:Python中sorted()函数全面解析!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 1. 引言 排序在编程中是一个基本且重要的操作&#xff0c;而 Python 中的 sorted() 函数则为我们提供了强大的排序能力。在本篇文章中&#xff0c;我们将深入研究不同排序算法、sorted() 函数的灵活性&#xff…