基于STM32的智能喂养系统
系统简介
- 自动检测环境温湿度,当温湿度低于阈值时自动打开加湿器;
- 自动检测水位,当水位低于阈值时自动加水;
- 自动检测有害气体,当检测到有害气体时自动打开风扇;
- 同步状态到微信小程序,微信小程序可以控制风扇,加湿器,水泵开关。
系统
有单片机主控负责检测各种信号量,将信息显示到屏幕上,采集信息后判断,并作出相应的动作。
系统框图
框图描述:相关传感器采集水位、温度、湿度、气体成分等信息传给主控,主控将处理之后的信息分别显示出来和发送到云端,主控可以控制相关设备进行加水、排气、报警、加湿等操作。相关模块独立供电。
系统所需器件
- STM32F103RCT6最小系统板(系统主控)
- ESP8266(WiFi通信模块)
- 0.94寸OLED屏(显示模块)
- DHT11(温湿度检测模块)
- SPG30(二氧化碳检测模块)
- HCSR-04(超声波模块)
- 有源蜂鸣器
- 5V继电器
- LED灯若干
系统流程图
框图描述:下位机硬件驱动初始化,软件联网初始化,初始化完成后采集各个传感器数据进行处理、显示和上报,然后系统判断是否超过阈值,超过阈值之后控制相应器件进行相关操作;上位机初始化之后,接收下位机发来的数据进行显示,并且可以下发命令到下位机执行相关的操作。
硬件组成
硬件选型
- 系统采用STM32F103RCT6最小系统板作为系统主控,32单片机,满足此系统所有要求,便宜,淘宝容易获得。
- ESP8266作为WiFi通信模块和小程序通信,将采集的信息发送给小程序,同时接受小程序的命令。
- 显示采用0.94寸的OLED模块,足够显示所有信息,采用IIC通信。
- 采用SPG30模块检测二氧化碳浓度。该模块灵敏,采用IIC通信。
- 用HCSR-04超声波模块检测水位。
- 有源蜂鸣器作为提醒单元。
- 若干发光二极管作为光信号。
- 5V继电器驱动风机和加湿器。
- 5V驱动的风机
- 5V驱动的加湿器。
- 一组3.3V电源,一组5V电源。(充电宝即可)
硬件原理图
硬件PCB图
板子正面
板子反面
硬件实物图
软件组成
软件描述:软件由Keil5编写,用的是C语言。
下位机
程序流程图
程序
//系统初始化
void System_Init(void)
{
u8 i = 0;
BEEP_Init();
SysInit_GPIO();
delay_init(); //延时函数初始化
I2C_Configuration();
OLED_Init(); //初始化OLED
NVIC_Config();
SysInit_TIM();
Adc_Init();
Hcsr04Init();//超声波初始化
OLED_CLS();
OLED_ShowStr1(0, 0, (char*)"OLED Ready", 1);
if(DHT11_Init()) //DHT11初始化
{
OLED_ShowStr1(0, 1, (char*)"DHT11 Error", 1);
delay_ms(200);
DHT11_Init();
}
else
OLED_ShowStr1(0, 1, (char*)"DHT11 Ready", 1);
Usart1_Init(115200); //串口初始化为9600
OLED_ShowStr1(0, 2, (char*)"UART1 Ready", 1);
UsartPrintf(USART_DEBUG, "串口1初始化成功\r\n");
Usart2_Init(115200);//8266通讯串口
UsartPrintf(USART_DEBUG, "串口2初始化成功!\n");
OLED_ShowStr1(0, 3, (char*)"UART2 OK", 1);
//SGP30模块开机需要一定时间初始化,在初始化阶段读取的CO2浓度为400ppm,TVOC为0ppd且恒定不变,因此上电后每隔一段时间读取一次
//SGP30模块的值,如果CO2浓度为400ppm,TVOC为0ppd,发送“正在检测中...”,直到SGP30模块初始化完成。
//初始化完成后刚开始读出数据会波动比较大,属于正常现象,一段时间后会逐渐趋于稳定。
//气体类传感器比较容易受环境影响,测量数据出现波动是正常的,可自行添加滤波函数。
SGP30_Init(); //初始化SGP30
SGP30_Write(0x20, 0x08);
sgp30_dat = SGP30_Read();//读取SGP30的值
CO2Data = (sgp30_dat & 0xffff0000) >> 16;
TVOCData = sgp30_dat & 0x0000ffff;
OLED_ShowStr1(0, 4, (char*)"SGP30 Ready", 1);
}
int main(void)
{
const char* topics[] = {"/123/123/123"};
unsigned short timeCount = 0; //发送间隔变量
unsigned char* dataPtr = NULL;
System_Init(); //系统初始化
ESP8266_Init();//8266初始化
while(OneNet_DevLink())//接入onenet
delay_ms(500);
OLED_CLS();
BuzzerShortBi();
OneNet_Subscribe(topics, 1);
while(1)
{
if(timeCount % 40 == 0) //1000毫秒/完成一次25ms=40 一秒执行一次(有一点点误差)
{
distance = Hcsr04GetLength();
}
if(++timeCount >= 120) //发送间隔5s,也就是5s上传一次数据,3000/25=120
{
timeCount = 0;
}
TimerDeal();
OLED_ShowStr1(0, 0, (char*)"OLED Ready", 1);
dataPtr = ESP8266_GetIPD(3);//完成需要15个毫秒,三次循环,一次5个毫秒
if(dataPtr != NULL)
OneNet_RevPro(dataPtr);
}
}
连接WiFi需要周围有一个
账号:aoteman,密码:88888888
的热点。
微信小程序
// 事件处理函数
onLoad() {
this.connectmqtt()
},
connectmqtt:function(){
var that=this
const options={
connectTimeout:4000,
clientId:Math.random().toString(36).substr(2),
port:8084,
username:'f22dfaf7d27fced36f716e2533f6c48f',
password:'123123'
}
client=mqtt.connect('wxs://t.yoyolife.fun/mqtt',options)
client.on('connect',(e)=>{
console.log('服务器连接成功')
client.subscribe('/iot/3051/cc',{qos:0},function(err){
if(!err)
{console.log('订阅成功')}
})
})
//信息监听事件
client.on('message',function(topic,message){
let tem={}
tem=JSON.parse(message)
that.setData({
tempo:tem.temp,
hum:tem.humi,
lx:tem.lengtn,
co2:tem.co2,
shuiwei:tem.shuiwei,
})
console.log(tem)
console.log('收到'+message.toString())
})
client.on('reconnect',(error)=>{
console.log('正在重新连接',error)
})
client.on('error',(error)=>{
console.log('连接失败',error)
})
},
onledchange:function(event){
console.log(event.detail)
let sw=event.detail.value
console.log(event.detail.value)
if(sw)
{
client.publish('/123/123/123','{"target":"led","value":1}',function(err){
if(!err)
{
console.log('成功发送指令-开')
}
})
}
else
{
client.publish('/123/123/123','{"target":"led","value":0}',function(err){
if(!err)
{
console.log('成功发送指令-关')
}
})
}
},
onbeepchange:function(event){
console.log(event.detail)
let sw=event.detail.value
console.log(event.detail.value)
if(sw)
{
client.publish('/123/123/123','{"target":"beep","value":1}',function(err){
if(!err)
{
console.log('成功发送指令-开')
}
})
}
else
{
client.publish('/iot/3051/wsy','{"target":"beep","value":0}',function(err){
if(!err)
{
console.log('成功发送指令-关')
}
})
}
}
})
最后就是发布小程序了。可以自行百度。
实物操作视频
哎,我还没录。
总结
此项目还是比较完整的,最终连机调试的时候需要细心慢慢调试。
v:shiboven