FastBond3挑战部分-基于C52单片机的智能浇灌完成
该项目使用了kicad,实现了基于C52单片机的智能浇灌创框图的设计,它的主要功能为:解放人工以实现智能浇灌。
标签
KiCad
Fast Bond第三季
智能浇灌
zhang_jing_yuan
更新2024-11-04
70

一.项目和创意方向介绍

本项目旨在开发一款基于STC89C52单片机的智能浇灌装置,以提升植物生长环境的监测与控制能力。通过结合现代蓝牙通信技术、土壤湿度传感器与模数转换芯片ADC0832,本装置能实时监测土壤湿度,帮助用户智能调节浇水策略,从而实现高效的水资源管理和植物生长优化。该系统的创意方向在于通过应用先进的技术手段实现农业的可持续发展,减少化学品使用及水资源浪费,同时保护土壤生态环境。

二.项目设计思路及实现方法

智能浇灌系统的设计思路是将多种传感器与控制模块相结合,通过智能算法实时分析土壤湿度数据,并通过蓝牙模块与用户设备进行通信,提供可视化的监测和控制界面。实现方法包括以下几步:

  1. 需求分析:明确系统的功能需求,包括自动浇水、湿度监测、远程控制等。
  2. 硬件选型:根据功能需求选择适合的硬件组件,如STC89C52单片机、FC-28土壤湿度传感器、ADC0832模数转换芯片等。
  3. 电路设计:使用工具设计电路原理图,将各模块进行连接,并确保信号稳定与电源安全。
  4. 软件开发:编写单片机控制程序,实现传感器数据采集、数据处理、蓝牙通信等功能。同时开发手机应用界面,方便用户操作。
  5. 系统调试:进行整合测试,确保各个模块协同工作,并调试软件,以解决可能出现的问题。

三.项目方案框图和原理图介绍

本次我使用的是digkey的官网的Scheme-it在线工具。

这是我在KiCad中所绘制的原理图。

大致的介绍就是:

  • STC89C52单片机作为控制核心,连接各种模块。
  • 土壤湿度传感器(FC-28)负责获得土壤湿度信息。
  • ADC0832进行信号的模数转换后馈送给单片机。
  • 蓝牙模块(HC-05或HC-06)负责数据的无线传输。
  • 继电器来控制浇水设备的启动与停止。
  • LCD1602用于实时显示湿度和设定的上下限。

四.设计中用到的指定厂商元器件及介绍

  • 继电器:TE Connectivity 提供广泛的连接解决方案,包括我所需要的DC5V继电器来控制水泵。
  • 蜂鸣器:Microchip 提供广泛的电子解决方案,包括各种传感器和驱动器件,有可能包括有源 蜂鸣器驱动器
  • 电阻:可以选择的方案有许多,本次我选择的是NXP Semiconductors公司的

在设计智能浇灌系统时,选择合适的元器件至关重要。TE Connectivity 的DC5V继电器能够有效地控制水泵,确保水资源的合理使用;Microchip 的有源蜂鸣器可以提供音效反馈,提醒用户浇水状态或故障;NXP的电阻则是电路设计中不可或缺的基础元件,确保电路的稳定性和安全性。通过合理搭配这些元器件,可以实现一个高效且可靠的智能浇灌装置。

五.PCB设计介绍及遇到的问题和解决方法

这个就是我通过原理图来制作的一个PCB,可以看到我是将他们进行了模块化布局的,将每一部分都是通过电路连接的一个走线进行排布的,本次我所遇到的问题主要有以下这几方面,只接一个电源时,发现电源无法正常的驱动继电器,以及蜂鸣器未响应,还有按键无法正常控制,解决方法:经过我一段时间的排查以及在网上查找资料之后,我在继电器部分多加了一个电源口,单独为进行一个供电猜测可能就是因为单电源无法给继电器正常的供五伏电以及电流,才导致了一个问题,然后蜂鸣器应该是没有加限流电阻,还有上拉,加上了之后就差不多可以正常工作了,以及按键是没有加电阻。

六.关键代码及说明

蓝牙代码:#include <regx51.h>

#define uchar unsigned char
#define uint unsigned char

void uart_init();

void uart_tx_string(uchar *str);

void uart_tx_byte(uchar str);

void Delayms(unsigned int n);

void Delayus(unsigned int n);

unsigned char rec;







/*********************************************************

函数名:串口中断

*********************************************************/

void uart_timer() interrupt 4

{

if(RI)

{

RI=0;

rec=SBUF;

uart_tx_byte('&');

Delayms(2);

uart_tx_byte(rec);

Delayms(2);

uart_tx_byte('&');

}

}



/*********************************************************

函数名:串口初始化

波特率:9600

晶振:11.059M

*********************************************************/

void uart_init()

{

TMOD=TMOD&0x0F;

TMOD=0x20;

TH1=0xFD;

TL1=0xFD;

TR1=1;

SCON=SCON&0x0F;

SCON=0x50;

EA=1;

ES=1;

}



/*********************************************************

函数名:串口发送一个字节

*********************************************************/

void uart_tx_byte(uchar str)

{

SBUF=str;

while(!TI);

}



/*********************************************************

函数名:串口发送一个字符串

*********************************************************/

void uart_tx_string(uchar *str)

{

while(*str!='\0')

{

uart_tx_byte(*str++);

Delayms(2);

}

}



/*********************************************************

函数名:延时函数

*********************************************************/

void Delayms(unsigned int n)

{

unsigned int i,j;

for(j=n;j>0;j--)

for(i=112;i>0;i--);

}

void Delayus(unsigned int n)

{

while(n--);

}

/*********************************************************

函数名:主函数

*********************************************************/

void bluetooth()

{

int v=4;

uart_init() ;

P3_2 = 0 ;

Delayms(1) ;

uart_tx_string("hello buletooch car!\n");

while(1)

{

switch(rec)

{

case 0:P3_2 = 0 ;Delayus(v); break;

case 1:P3_2 = 1 ;Delayus(v); break;

}

}

}

该代码实现的是一个基本的蓝牙通信系统,能够接收来自蓝牙模块的数据信号(字符0或1),并根据接收到的信号控制某个外部设备的状态。同时,它还通过串口发送信息,反馈接收的数据。

#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int

sbit SCL=P1^4;
sbit DO=P1^5;
sbit CS=P1^3;
sbit beep = P3^3;
uint temperature, s_temp;
uchar shidu;
uchar s_high = 70, s_low = 25;
sbit jidianqi = P3^2;
bit flag_300ms;
uchar key_can;
uchar menu_1;

sbit rs=P1^0;
sbit rw=P1^1;
sbit e =P1^2;
uchar code table_num[]="0123456789abcdefg";

void delay_uint(uint q)
{
while(q--);
}

void write_com(uchar com)
{
e=0;
rs=0;
rw=0;
P0=com;
delay_uint(3);
e=1;
delay_uint(25);
e=0;
}

void write_data(uchar dat)
{
e=0;
rs=1;
rw=0;
P0=dat;
delay_uint(3);
e=1;
delay_uint(25);
e=0;
}

void write_sfm2(uchar hang, uchar add, uint date)
{
if(hang==1)
write_com(0x80+add);
else
write_com(0x80+0x40+add);
write_data(0x30+date/10%10);
write_data(0x30+date%10);
}

void write_string(uchar hang, uchar add, uchar *p)
{
if(hang==1)
write_com(0x80+add);
else
write_com(0x80+0x40+add);
while(1)
{
if(*p == '\0') break;
write_data(*p);
p++;
}
}

void init_1602()
{
write_com(0x38);
write_com(0x38);
write_com(0x0c);
write_com(0x06);
delay_uint(1000);
write_string(1,0," SD:00% ");
write_string(2,0," SH:00% SL:00% ");
write_sfm2(2,4,s_high);
write_sfm2(2,12,s_low);
}

void delay_1ms(uint q)
{
uint i,j;
for(i=0;i<q;i++)
for(j=0;j<120;j++);
}

unsigned int Adc0832(unsigned char channel)
{
uchar i=0;
uchar j;
uint dat=0;
uchar ndat=0;
uchar Vot=0;

if(channel==0)channel=2;
if(channel==1)channel=3;
DO=1;
_nop_();
_nop_();
CS=0;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
SCL=1;
DO=channel&0x1;
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
SCL=1;
DO=(channel>>1)&0x1;
_nop_();
_nop_();
SCL=0;
DO=1;
_nop_();
_nop_();
dat=0;
for(i=0;i<8;i++)
{
dat|=DO;
SCL=1;
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
dat<<=1;
if(i==7)dat|=DO;
}
for(i=0;i<8;i++)
{
j=0;
j=j|DO;
SCL=1;
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
j=j<<7;
ndat=ndat|j;
if(i<7)ndat>>=1;
}
CS=1;
SCL=0;
DO=1;
dat<<=8;
dat|=ndat;

return(dat);
}

uchar key_can;

void key()
{
static uchar key_new;
key_can = 20;
P3 |= 0xf0;
if((P3 & 0xf0) != 0xf0)
{
delay_1ms(1);
if(((P3 & 0xf0) != 0xf0) && (key_new == 1))
{
key_new = 0;
switch(P3 & 0xf0)
{
case 0xd0: key_can = 3; break;
case 0xb0: key_can = 2; break;
case 0x70: key_can = 1; break;
}
}
}
else
key_new = 1;
}

void key_with()
{
if(key_can == 1)
{
menu_1++;
if(menu_1 >= 3)
{
menu_1 = 0;
init_1602();
}
}
if(menu_1 == 1)
{
if(key_can == 2)
{
s_high++;
if(s_high > 99)
s_high = 99;
}
if(key_can == 3)
{
s_high--;
if(s_high <= s_low)
s_high = s_low + 1;
}
write_sfm2(2,4,s_high);
write_sfm2(2,12,s_low);
write_com(0x80+0x40+4);
write_com(0x0f);
}
if(menu_1 == 2)
{
if(key_can == 2)
{
s_low++;
if(s_low >= s_high)
s_low = s_high - 1;
}
if(key_can == 3)
{
s_low--;
if(s_low <= 1)
s_low = 1;
}
write_sfm2(2,4,s_high);
write_sfm2(2,12,s_low);
write_com(0x80+0x40+12);
write_com(0x0f);
}
}

void clock_h_l()
{
static uchar value,value1;
if(shidu <= s_low)
{
value++;
if(value >= 2)
{
value = 10;
beep = ~beep;
jidianqi = 0;
}
}
else
beep = 1;

if(shidu >= s_high)
{
value1++;
if(value1 >= 2)
{
value1 = 10;
beep = 1;
jidianqi = 1;
}
}
else
value1 = 0;
}
sbit led1 = P3^2;
int pass = 0;

void UART_init()
{
TMOD = 0X21;
TH1 = 0xfd;
TL1 = 0xfd;
SM0 = 0;
SM1 = 1;
REN = 1;
TR1 = 1;
ES = 1;
TR0 = 1;
ET0 = 1;
}

void ly()
{
while(1)
{
if(pass == 0x31)
{
led1 = 0;
break;
}
if(pass == 0x41)
{
led1 = 1;
break;
}
break;
}
}

void choushui()
{
init_1602();
UART_init();
while(1)
{
key();
if(key_can < 10)
{
key_with();
}
if(flag_300ms == 1)
{
flag_300ms = 0;
clock_h_l();
if(beep == 1)
{
shidu = Adc0832(0);
shidu = 99 - shidu * 99 / 255;
}
if(menu_1 == 0)
{
write_sfm2(1,9,shidu);
}
}
ly();
delay_1ms(1);
}
}

void time0_int() interrupt 1
{
static uchar value;
TH0 = 0x3c;
TL0 = 0xb0;
value++;
if(value % 6 == 0)
{
flag_300ms = 1;
value = 0;
}
}

void UART_INTERRUPT() interrupt 4
{
pass = SBUF;
RI = 0;
SBUF = pass;
while(!TI);
TI = 0;
}

这段代码是针对单片机的程序,主要功能是实现一个基于ADC0832传感器的湿度监测和控制系统,并通过1602液晶显示屏(LCD)显示相关信息,以及通过串行通信与其他设备(如蓝牙模块)进行数据交互。以下是详细的解释:

  1. 数据类型定义和引脚设置
    • 使用 #define 定义了 uchar  uint,分别用于表示unsigned char(0255)和unsigned int(065535)。
    • 使用 sbit 定义了多个IO口引脚,用于控制ADC0832(模数转换器)和1602 LCD。
  2. 全局变量
    • 定义了用于存储温度、湿度、上下限的变量,以及控制LED和蜂鸣器的状态。
  3. LCD控制函数
    • write_com(uchar com):用于向LCD发送命令。
    • write_data(uchar dat):用于向LCD发送数据。
    • write_sfm2(uchar hang, uchar add, uint date):用于LCD的特定行特定地址写入数值。
    • init_1602():初始化1602 LCD,配置显示内容。
  4. ADC0832读取函数
    • Adc0832(unsigned char channel):通过与ADC0832的SPI接口通信,获取指定通道的模拟输入(如湿度数据),并返回转换后的数字值。
  5. 按键处理
    • key() 函数用于检测按键输入并更新 key_can 变量的值。
    • key_with() 函数根据按键输入更新设置,并相应调整显示的湿度阈值。
  6. 报警和读数判断
    • clock_h_l():根据湿度值与上下限进行比较,控制蜂鸣器和其它报警设备的状态。
  7. 串口通信
    • UART_init():设置串口初始化参数,为与电脑或蓝牙模块的通信做准备。
    • UART_INTERRUPT():串口中断处理函数,用于接收和发送数据。
  8. 主循环
    • choushui() 函数为系统主循环,周期性地读取湿度数据并更新LCD显示,同时处理按键输入。
  9. 定时器中断
    • time0_int() 函数设置一个定时器中断,用于生成定时任务。

七.功能展示图及说明

通过开发手机应用,用户可以实时查看土壤湿度、设置上下限,并根据反馈信息调整浇水参数。应用的主界面设计简洁明了,包括湿度实时展示、设置按钮和浇水操作指示。

八.心得体会

参与本项目的设计和实施,让我深刻认识到理论与实践的结合是多么重要。通过实际操作,我发现许多理论知识在应用中会遇到各种各样的挑战。智能浇灌系统的设计与实现让我了解了更多关于硬件与软件结合的奥秘,并激发了我对未来智能农业解决方案的思考。希望在今后的工作与学习中,能够继续深入这方面的探索与实践。

附件下载
温湿度.zip
代码
浇灌.kicad_sch
原理图文件
浇灌.kicad_pcb
PCB文件
团队介绍
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号