基于STM32单片机的智能鱼缸控制系统原理图PCB

功能介绍:
0.本系统采用STM32F103C8T6作为单片机
1.采用DS1302时钟芯片可实时显示时间,通过四个功能按键可设置投喂等操作定时时间
2.具有WiFi模块可以与手机进行数据传输通信
3.采用防水型的DS18B20传感器可以测量水温
4.采用DC002作为电源接口可直接输入5V给整个系统供电
5.水位传感器可以测量水位的实时情况
6.具备水泵控制电路,根据水位传感器数据判断是否加水;具备加热和投食控制电路。

原理图:
在这里插入图片描述
在这里插入图片描述

PCB:
在这里插入图片描述

主程序:

#define __MIAN_C
#include "main.h"


// 局部变量,用于保存转换计算后的电压值
CreatByte volatile Flag;
enum _MODE_DF_ dispMode;

char dis[16];
volatile u8 setIndex = 0;
volatile u8 feedTime[2] = {18, 0}; //投喂时间18:00
volatile u16 totalFeedTime[3] = {0, 0}; //投喂时间18:00
volatile u8 feedLevel = 1; //投喂量等级
volatile u16 amountOfFeed = 0;
volatile u16 feedDelay = 0; //喂食延迟
uint16_t tempBuf = 0;
float f_temp = 0.0;
volatile uint16_t tempMin = 25; //最低温度
volatile uint16_t tempMax = 40; //最高温度
uint16_t waterLevel = 0;
volatile uint16_t waterLevelLow = 25; //最低水位
volatile uint16_t waterLevelHigh = 35; //最高水位
char command = NULL;

int main(void)
{

    // 使用HSI,SYSCLK = 4M * RCC_PLLMul_x, x:[2,3,...16],最高是64MH
    HSI_SetSysClock(RCC_PLLMul_2); //使用内部8MHz晶振,并设置PLL输出为8MHz

    // 端口初始化
    GENERAL_TIM_Init();
    GPIO_Config();
    DS1302_Init();
    USART_Config();
    ADCx_Init();

    DelayMs(1000);
	printf("AT+CIPMUX=1\r\n"); //打开多连接
	DelayMs(1000);
	printf("AT+CIPSERVER=1,8080\r\n"); //建立服务 端口号为8080
	DelayMs(1000);

    Key_GPIO_Config();
    DelayMs(200);

    LCD_GPIO_Init();
    LCD_Init();
    LCD_DispStr(0, 0, "    Welcome!    ");
    DelayMs(200);
    DelayMs(200);
    DelayMs(200);
    LCD_Clear();
    DelayMs(200);

    while (1)
    {

        if (sendFlag == 1)
        {
            sendFlag = 0;
            SendData();
        }
        
        if (refreshFlag == 1)
        {
            refreshFlag = 0;
            if (dispMode == NORMAL)
            {
                DispNormal();
            }

            if (waterLevel <= waterLevelLow) //水位低于最低水位值,启动水泵继电器
            {
                RELAY_WATER_ON;
            }
            else if (waterLevel >= waterLevelHigh) //水位高于最高水位值,关闭水泵继电器
            {
                RELAY_WATER_OFF;
            }

            if (f_temp <= tempMin) //温度低于最低温度值,启动加热继电器
            {
                RELAY_HEAT_ON;
            }
            else if (f_temp >= tempMax) //温度高于最高温度值,关闭加热继电器
            {
                RELAY_HEAT_OFF;
            }

            if (timeBufDec[4] == feedTime[0] && timeBufDec[5] == feedTime[1] && timeBufDec[6] == 0) //到达喂食时间
            {
                feedDelay = feedLevel * 5; //feedLevel * 1s * 5
            }

            if (feedDelay > 0) //启动喂食
            {
                feedDelay--;
                amountOfFeed = amountOfFeed + 5; //喂食总量加5g
                totalFeedTime[2]++; //秒钟加
                if (totalFeedTime[2] == 60)
                {
                    totalFeedTime[2] = 0;
                    totalFeedTime[1]++;
                    if (totalFeedTime[1] == 60)
                    {
                        totalFeedTime[1] = 0;
                        totalFeedTime[0]++;
                    }
                }
                RELAY_FOOD_ON;
            }
            else
            {
                RELAY_FOOD_OFF;
            }
        }


        
        KeyProcess();
    }
}

void DispNormal(void)
{
    TIM_ITConfig(GENERAL_TIM2, TIM_IT_Update, DISABLE);
    DS1302_ReadTime();
    TIM_ITConfig(GENERAL_TIM2, TIM_IT_Update, ENABLE);
    sprintf(dis, "%02d/%02d/%02d", (int)timeBufDec[1], (int)timeBufDec[2], (int)timeBufDec[3]);
    // sprintf(dis, "%02d/%02d/%02d", timeBufDec[1], timeBufDec[2], timeBufDec[3]);
    LCD_DispStr(0, 0, dis);
    switch (timeBufDec[7])
    {
        case 0: LCD_DispStr(10, 0, " Sun."); break;
        case 1: LCD_DispStr(10, 0, " Sun."); break;
        case 2: LCD_DispStr(10, 0, " Mon."); break;
        case 3: LCD_DispStr(10, 0, " Tue."); break;
        case 4: LCD_DispStr(10, 0, " Wed."); break;
        case 5: LCD_DispStr(10, 0, "Thur."); break;
        case 6: LCD_DispStr(10, 0, " Fri."); break;
        case 7: LCD_DispStr(10, 0, " Sat."); break;
        default: break;
    }
    TIM_ITConfig(GENERAL_TIM2, TIM_IT_Update, DISABLE);
    DS18B20_GetTemp(&tempBuf); //采集温度
    f_temp = tempBuf * 0.0625; //温度转换
    TIM_ITConfig(GENERAL_TIM2, TIM_IT_Update, ENABLE);

    waterLevel = ADC_ConvertedValue; //检测水位值
    waterLevel = waterLevel * 100 / 4096;

    // sprintf(dis, "%02d:%02d %5.1f", (int)timeBufDec[4], (int)timeBufDec[5], f_temp);
    sprintf(dis, "%02d:%02d:%02d %4.1f", (int)timeBufDec[4], (int)timeBufDec[5], (int)timeBufDec[6], f_temp);
    LCD_DispStr(0, 1, dis);

//    LCD_DispOneChar(11, 1, 0xdf); //摄氏度右上角的°
//    LCD_DispOneChar(12, 1, 'C'); //摄氏度右上角的°

    sprintf(dis, " %02d", waterLevel);
    LCD_DispStr(13, 1, dis);
}

void DispSetRealTime(u8 setIndex)
{
    sprintf(dis, "%02d/%02d/%02d", (unsigned int)timeBufDec[1], (unsigned int)timeBufDec[2], (unsigned int)timeBufDec[3]);
    LCD_DispStr(0, 0, dis);
    switch (timeBufDec[7])
    {
        case 1: LCD_DispStr(10, 0, " Sun."); break;
        case 2: LCD_DispStr(10, 0, " Mon."); break;
        case 3: LCD_DispStr(10, 0, " Tue."); break;
        case 4: LCD_DispStr(10, 0, " Wed."); break;
        case 5: LCD_DispStr(10, 0, "Thur."); break;
        case 6: LCD_DispStr(10, 0, " Fri."); break;
        case 7: LCD_DispStr(10, 0, " Sat."); break;
        default: break;
    }
    sprintf(dis, "    %02d:%02d:%02d    ", (unsigned int)timeBufDec[4], (unsigned int)timeBufDec[5], (unsigned int)timeBufDec[6]);
    LCD_DispStr(0, 1, dis);

    switch (setIndex)
    {
        case 1: LCD_SetCursor(1, 0, 1); break;
        case 2: LCD_SetCursor(4, 0, 1); break;
        case 3: LCD_SetCursor(7, 0, 1); break;
        case 4: LCD_SetCursor(14, 0, 1); break;
        case 5: LCD_SetCursor(5, 1, 1); break;
        case 6: LCD_SetCursor(8, 1, 1); break;
        case 7: LCD_SetCursor(11, 1, 1); break;
        default:break;
    }
}


void DispSetWaterLevel(u8 setIndex)
{
    LCD_DispStr(0, 0, " Set WaterLevel ");
    sprintf(dis, "   H:%2d%% L:%2d%%  ", waterLevelHigh, waterLevelLow);
    LCD_DispStr(0, 1, dis);
    
    switch (setIndex)
    {
        case 1: LCD_SetCursor(6, 1, 1); break;
        case 2: LCD_SetCursor(12, 1, 1); break;
        default:;
    } 
}

void DispSetTemp(u8 setIndex)
{

    LCD_DispStr(0, 0, "Set Temperature ");
    sprintf(dis, "   H:%3d L:%3d  ", tempMax, tempMin);
    LCD_DispStr(0, 1, dis);
    
    switch (setIndex)
    {
        case 1: LCD_SetCursor(7, 1, 1); break;
        case 2: LCD_SetCursor(13, 1, 1); break;
        default:;
    } 
}

void DispSetFeed(u8 setIndex)
{
    sprintf(dis, "FeedTime: %02d:%02d ", (unsigned int)feedTime[0], (unsigned int)feedTime[1]);
    LCD_DispStr(0, 0, dis);
    sprintf(dis, "FeedLevel: %2d   ", (unsigned int)feedLevel);
    LCD_DispStr(0, 1, dis);
    
    switch (setIndex)
    {
        case 1: LCD_SetCursor(11, 0, 1); break;
        case 2: LCD_SetCursor(14, 0, 1); break;
        case 3: LCD_SetCursor(12, 1, 1); break;
        default:break;
    } 
}

void DispSetTotalFeed(u8 setIndex)
{
    sprintf(dis, "Total:  %02d:%02d:%02d", (unsigned int)totalFeedTime[0], (unsigned int)totalFeedTime[1], (unsigned int)totalFeedTime[2]);
    LCD_DispStr(0, 0, dis);
    sprintf(dis, "TotalFeed: %4dg", (unsigned int)amountOfFeed);
    LCD_DispStr(0, 1, dis);
    
    switch (setIndex)
    {
        case 1: LCD_SetCursor(15, 0, 1); break;
        case 2: LCD_SetCursor(14, 1, 1); break;
        default: break;
    } 
}

void SendData(void)
{
    printf("AT+CIPSEND=0,29\r\n"); //发送29位数据
    DelayMs(100);
    printf("Water Level:%2d%% Temp:%5.1f'C\r\n", waterLevel, f_temp); //串口发送
    DelayMs(100);
}

/*********************************************END OF FILE**********************/

实物演示视频:
https://www.bilibili.com/video/BV1UU4y117K1/

  • 2
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值