0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于STM32设计的智能灌溉控制系统

DS小龙哥-嵌入式技术 来源:DS小龙哥-嵌入式技术 作者:DS小龙哥-嵌入式技 2023-05-17 09:25 次阅读

一、项目介绍

随着现代农业的发展,人们对于水资源的合理利用越来越重视。而传统的灌溉方式往往存在着浪费水资源、劳动力投入大、效率低等问题。因此,设计一款智能灌溉控制系统,可以实现对灌溉水量的精准控制,增加水资源利用率,提高农业生产效率,具有广泛的应用前景。

当前文章介绍一款高性能的智能灌溉控制系统的开发过程,可自动采集电压、电流、累计用水量,并根据用户需要实现自动灌溉、定时灌溉、周期灌溉和手动灌溉等多种模式,同时具备中控室控制、手机短信、现场遥控及现场手动等多种方式控制功能。该系统可以对现场温湿度限值进行设置和修改,并通过控制器或后台监控系统完成灌溉起始时间、停止时间、喷灌时间等参数设置。系统显示功能包括液晶屏以中文菜单方式显示现场采集数据以及后台监控系统配大屏幕显示器,图形、表格等多种形式动态显示整个灌溉区运行情况。同时,在电压、电流或者流量出现异常时,系统可以及时报警。该系统供电为220VAC,流量计量误差精度为2级,使用二维码或卡实现预付费功能,通讯使用4G与云平台连接。

image-20230427151119821

二、设计功能

本系统采用STM32作为主控芯片,并通过AD模块采集电压、电流和流量等数据。同时,通过继电器控制灌溉设备的启停,使用PWM控制阀门的开合程度,从而实现精确控制灌溉水量。通信模块则采用4G模块与云平台连接,实现远程监控及控制功能。预付费模块则使用二维码或卡实现预付费功能,用户需在充值后才能使用该系统进行灌溉操作。

系统软件设计包括采集程序、控制程序、前端程序和后台程序。其中,采集程序主要负责采集电压、电流、流量等数据,并将采集到的数据上传到云平台;控制程序主要负责控制灌溉设备的启停和阀门的开合程度,从而实现灌溉控制;前端程序主要负责实现中文菜单方式显示现场采集数据,并提供灌溉模式选择、参数设置等功能;后台程序主要负责实现大屏幕显示器、图形、表格等多种形式动态显示整个灌溉区运行情况。

【1】硬件部分

  1. MCU:本系统采用STM32作为主控芯片,其具有高性能、低功耗等优点,可满足该系统的高要求。
  2. 数据采集模块:本系统通过AD模块采集电压、电流和流量等数据,然后使用MCU进行处理,并将采集到的数据存储到Flash中。
  3. 控制模块:本系统通过继电器控制灌溉设备的启停,同时使用PWM控制阀门的开合程度,从而实现精确控制灌溉水量。
  4. 通信模块:本系统采用4G模块与云平台连接,实现远程监控及控制功能。
  5. 预付费模块:本系统使用二维码或卡实现预付费功能,用户需在充值后才能使用该系统进行灌溉操作。

【2】软件部分

  1. 采集程序:本系统的采集程序主要负责采集电压、电流、流量等数据,并将采集到的数据上传到云平台。
  2. 控制程序:本系统的控制程序主要负责控制灌溉设备的启停和阀门的开合程度,从而实现灌溉控制。
  3. 前端程序:本系统的前端程序主要负责实现中文菜单方式显示现场采集数据,并提供灌溉模式选择、参数设置等功能。
  4. 后台程序:本系统的后台程序主要负责实现大屏幕显示器、图形、表格等多种形式动态显示整个灌溉区运行情况。

三、系统实现

具体实现过程如下:

(1)采集程序

采集程序主要由AD模块和STM32芯片完成。AD模块采集电压、电流和流量等数据,经过滤波和放大处理后,传输到STM32芯片上。STM32芯片通过串口将采集到的数据上传到云平台,并存储在Flash中。

(2)控制程序

控制程序主要由继电器和PWM模块完成。继电器用于控制灌溉设备的启停,PWM模块则用于控制阀门的开合程度,从而实现精确控制灌溉水量。控制程序通过读取Flash中存储的参数,确定灌溉起始时间、停止时间、喷灌时间等操作流程,并根据实时采集到的数据进行动态调整,保证灌溉操作的准确性和稳定性。

(3)前端程序

前端程序主要是通过液晶屏以中文菜单方式显示现场采集数据,并提供灌溉模式选择、参数设置等功能。用户可以通过按键或触摸屏来进行操作,并实时查看灌溉操作的运行情况。此外,用户还可以通过手机短信、现场遥控或现场手动等方式对灌溉操作进行控制。

(4)后台程序

后台程序主要负责实现大屏幕显示器、图形、表格等多种形式动态显示整个灌溉区运行情况,同时还能够将采集到的数据进行分析和统计,为灌溉管理提供决策参考。

四、核心代码

【1】电机控制代码

以下是STM32F103ZET6通过PWM控制直流电机转速的代码,并封装成子函数调用的示例:

首先,需要在STM32CubeMX中配置TIM定时器和GPIO引脚,以及将PWM模式设置为嵌套边沿对齐模式,然后生成代码,并在main.c文件中添加以下代码:

#include "main.h"
#include "stm32f1xx_hal.h"
​
/* TIM handle structure */
TIM_HandleTypeDef htim;
​
/* Function prototypes */
void PWM_Init(TIM_HandleTypeDef *htim, uint32_t channel);
void Set_Motor_Speed(TIM_HandleTypeDef *htim, uint32_t channel, uint16_t speed);
​
int main(void)
{
 /* Initialize the HAL Library */
 HAL_Init();
​
 /* Initialize TIM2 PWM with a frequency of 10 kHz */
 PWM_Init(&htim2, TIM_CHANNEL_1);
​
 /* Set the motor speed to 50% */
 Set_Motor_Speed(&htim2, TIM_CHANNEL_1, 5000);
​
 while (1)
  {
  /* Infinite loop */
  }
}
​
/**
 * @brief  Initializes PWM output on specified TIM channel.
 * @param  htim: TIM handle structure.
 * @param  channel: TIM channel to be used for PWM output.
 * @retval None
 */
void PWM_Init(TIM_HandleTypeDef *htim, uint32_t channel)
{
 TIM_OC_InitTypeDef sConfigOC = {0};
​
 /* Configure PWM output on specified TIM channel */
 sConfigOC.OCMode    = TIM_OCMODE_PWM1;
 sConfigOC.Pulse    = 0;
 sConfigOC.OCPolarity  = TIM_OCPOLARITY_HIGH;
 sConfigOC.OCFastMode  = TIM_OCFAST_DISABLE;
 HAL_TIM_PWM_ConfigChannel(htim, &sConfigOC, channel);
​
 /* Start PWM output */
 HAL_TIM_PWM_Start(htim, channel);
}
​
/**
 * @brief  Sets the motor speed on specified TIM channel.
 * @param  htim: TIM handle structure.
 * @param  channel: TIM channel to be used for PWM output.
 * @param  speed: Motor speed in units of 1/10,000th of the maximum speed.
 *         For example, a speed of 5000 would set the motor speed to 50%.
 * @retval None
 */
void Set_Motor_Speed(TIM_HandleTypeDef *htim, uint32_t channel, uint16_t speed)
{
 uint16_t max_speed = htim->Init.Period;
​
 /* Ensure that speed is within range */
 if (speed > max_speed)
  speed = max_speed;
​
 /* Update PWM duty cycle */
 __HAL_TIM_SET_COMPARE(htim, channel, speed);
}

在以上代码中,定义了两个函数:PWM_Init和Set_Motor_Speed。PWM_Init用于初始化TIM定时器的PWM输出,并设置指定通道的PWM模式和默认占空比为0。Set_Motor_Speed用于设置电机的转速,其接收三个参数:TIM句柄结构体,指定的通道,以及电机的转速(单位为1/10,000最大速度)。该函数会将电机的转速转换为PWM占空比,并通过__HAL_TIM_SET_COMPARE函数更新PWM占空比。

最后,可以按照以下步骤将代码封装成子函数调用:

  1. 将以上代码复制到单独的.c文件中,并包含必要的头文件。
  2. 在该文件中定义一个名为Motor_Control的函数,该函数接收三个参数:TIM句柄结构体,指定的通道,以及电机的转速。
  3. 在Motor_Control函数中调用PWM_Init和Set_Motor_Speed函数,并传递相应的参数。
  4. 在main函数中调用Motor_Control函数,传递相应的参数。

以下是Motor_Control函数的示例代码:

#include "motor_control.h"
​
void Motor_Control(TIM_HandleTypeDef *htim, uint32_t channel, uint16_t speed)
{
 /* Initialize PWM output on specified TIM channel */
 PWM_Init(htim, channel);
​
 /* Set the motor speed */
 Set_Motor_Speed(htim, channel, speed);
}

在以上示例中,将PWM的初始化和设置电机转速的函数封装成了一个名为Motor_Control的函数。可以在需要控制电机转速的其他地方调用Motor_Control函数即可。

注意,在调用Motor_Control函数之前,需要先定义并初始化TIM句柄结构体,并确保GPIO引脚已经正确配置为TIM模式。此外,如果需要控制多个电机,可以在Motor_Control函数中增加参数以区分不同的电机通道。

以下是motor_control.h头文件的示例代码:

cCopy Code#ifndef __MOTOR_CONTROL_H__
#define __MOTOR_CONTROL_H__
​
#include "stm32f1xx_hal.h"
​
/* Function prototypes */
void PWM_Init(TIM_HandleTypeDef *htim, uint32_t channel);
void Set_Motor_Speed(TIM_HandleTypeDef *htim, uint32_t channel, uint16_t speed);
void Motor_Control(TIM_HandleTypeDef *htim, uint32_t channel, uint16_t speed);
​
#endif /* __MOTOR_CONTROL_H__ */

在以上头文件中,声明了三个函数:PWM_Init,Set_Motor_Speed和Motor_Control,并包含必要的头文件。

【2】电压、电流采集

为了采集220V抽水电机的用电量和当前电压,当前使用STM32F103ZET6的ADC模数转换器)来测量电压和电流,并通过乘法器计算电功率和电能。

下面是实现方案和实现代码:

  1. 选择合适的传感器: 为了测量电压,可以使用AC-AC变压器将220V交流电压降至低电平,再使用电阻分压器将电压信号调整在ADC的输入范围内。 为了测量电流,可以使用霍尔传感器或者电阻式传感器,将电流信号转换成电压信号,然后通过电阻分压器调整信号范围。
  2. 配置ADC: 使用STM32CubeMX软件选择相应的引脚和配置ADC模块,设置采样频率、参考电压等参数。需要注意的是,ADC模块只能同时转换一路模拟信号,因此需要轮流采样电压和电流信号。
  3. 计算电流、电压、功率和能量: 将电压和电流信号转换成数字值后,可以使用下面的公式计算电流、电压、功率和能量:
Copy Code电流 = AD值 / 灵敏度
电压 = AD值 / 分压比
功率 = 电压 * 电流
能量 = 功率 * 时间

其中,灵敏度是传感器的转换系数,分压比是电阻分压器的比值,时间可以通过定时器计算。

  1. 输出数据: 将测量的电流、电压、功率和能量输出到串口或者LCD显示屏上。可以设置一个定时器,在一定时间间隔内输出一次数据。

实现代码:

#include "stm32f1xx_hal.h"
​
ADC_HandleTypeDef hadc1;
TIM_HandleTypeDef htim2;
​
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_TIM2_Init(void);
​
uint16_t ad_val_ch1, ad_val_ch2;
float voltage, current, power, energy;
​
int main(void)
{
 HAL_Init();
 SystemClock_Config();
 MX_GPIO_Init();
 MX_ADC1_Init();
 MX_TIM2_Init();
​
 while (1)
  {
  // ADC采样电压信号
  HAL_ADC_Start(&hadc1);
  HAL_ADC_PollForConversion(&hadc1, 100);
  ad_val_ch1 = HAL_ADC_GetValue(&hadc1);
  voltage = ad_val_ch1 * 3.3 / 4096 * 10; // 假设分压比为10
​
  // ADC采样电流信号
  HAL_TIM_Base_Start(&htim2);
  HAL_ADC_Start(&hadc1);
  HAL_ADC_PollForConversion(&hadc1, 100);
  ad_val_ch2 = HAL_ADC_GetValue(&hadc1);
  current = ad_val_ch2 * 3.3 / 4096 * 50; // 假设灵敏度为50mV/A
​
  // 计算功率和能量
  power = voltage * current;
  energy += power * 0.1; // 假设定时器时间间隔为100ms
​
  // 输出测量结果
  printf("Voltage: %.2f Vrn", voltage);
  printf("Current: %.2f Arn", current);
  printf("Power: %.2f Wrn", power);
  printf("Energy: %.2f Jrn", energy);
​
  HAL_Delay(1000); // 假设数据输出间隔为1s
  }
}
​
void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
​
 __HAL_RCC_PWR_CLK_ENABLE();
 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
​
 RCC_OscInitStruct.OscillatorType = RCCRCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
​
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
​
static void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
​
__HAL_RCC_ADC1_CLK_ENABLE();
​
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
​
sConfig.Channel = ADC_CHANNEL_0; // 假设测量电压的ADC通道为0
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
​
sConfig.Channel = ADC_CHANNEL_1; // 假设测量电流的ADC通道为1
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
​
static void MX_TIM2_Init(void)
{
__HAL_RCC_TIM2_CLK_ENABLE();
​
htim2.Instance = TIM2;
htim2.Init.Prescaler = 7200 - 1;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 10000 - 1; // 假设定时器时间间隔为100ms
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
}
​
void Error_Handler(void)
{
while (1)
{
}
}
​
#ifdef USE_FULL_ASSERT
​
void assert_failed(char *file, uint32_t line)
{
}
​
#endif
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6012

    文章

    44171

    浏览量

    624576
  • 控制系统
    +关注

    关注

    41

    文章

    6246

    浏览量

    109670
  • 4G
    4G
    +关注

    关注

    15

    文章

    5417

    浏览量

    117585
  • STM32
    +关注

    关注

    2251

    文章

    10731

    浏览量

    350601
收藏 人收藏

    评论

    相关推荐

    ZigBee节水灌溉控制系统有什么功能?

    成本,不便于扩展,而且给农田耕作带来不便。因此,设计一种基于无线传感器网络的节水灌溉控制系统,该系统主要由低功耗无线传感网络节点通过ZigBee自组网方式构成,从而避免了布线的不便、灵活性较差的缺点
    发表于 10-08 09:13

    智能机井控制器助力农业灌溉

    耕地面积。机井裸露,存在安全隐患。“农田机井智能灌溉控制系统”有效解决了此问题。  该系统通过IC卡机井灌溉
    发表于 09-09 21:30

    STM32智能温室控制系统

    STM32智能温室控制系统
    发表于 09-28 15:05 74次下载
    <b class='flag-5'>STM32</b>的<b class='flag-5'>智能</b>温室<b class='flag-5'>控制系统</b>

    自动灌溉控制系统

                               自动灌溉控制系统 公司产品主要有:滴灌智能控制系统,大田智能
    发表于 12-15 10:37 2538次阅读

    基于FDRE的节水灌溉智能控制系统

    基于FDRE的节水灌溉智能控制系统
    发表于 06-29 14:28 26次下载

    单片机控制系统课程设计《基于单片机的大棚智能灌溉控制系统

    单片机控制系统课程设计《基于单片机的大棚智能灌溉控制系统
    发表于 03-07 10:37 51次下载

    智慧农业灌溉控制系统

    应用在花卉灌溉、绿化工程等场景下,实现了手机一键远程控制灌溉。 智慧农业灌溉控制系统,由管理云平台软件,配合
    的头像 发表于 11-09 16:08 1989次阅读

    智能灌溉控制系统

    在现代化技术的支撑下,农业灌溉作业也实现了自动化控制,不仅节省了人工灌溉成本,还大大提高了水资源利用效率。慢慢被运用在园林绿化、果蔬种植、菌菇栽培、花园草坪等场景中。 智能
    的头像 发表于 11-09 16:23 1664次阅读

    景观绿化智能灌溉控制系统

    灌溉作业。 智能灌溉控制系统方案,基于灌溉区域的实际情况、种植作物的生理状态,在线获取灌区的气象数据、土壤墒情,自动执行云平台设定的
    的头像 发表于 11-10 15:20 1227次阅读

    花卉智能灌溉控制系统

    在农业物联网系统的应用中,智能灌溉控制系统应用广泛,在花卉种植、大田农业、绿化草坪等场景中都有用武之地。 节水灌溉是在低限的用水量下获得大产
    的头像 发表于 12-05 16:14 1248次阅读

    组成灌溉智能控制系统设备

    会在土壤中腐烂。 如果水太低,将无法提供植物生长所需的水。灌溉是在适合植物生长的范围内,最大限度地增加土壤水分的过程。实现灌溉智能化的前提,是灌溉
    发表于 12-29 16:47 304次阅读

    大田智能灌溉控制系统

    ,不仅仅是浪费人力,而且人工灌溉不能准确地把握土壤墒情多少,导致了不同程度上的灌溉不均匀和水资源的浪费,且灌溉效率低,一旦遇到上千亩、上万亩的灌溉农田时,显然就无法应对了。
    的头像 发表于 02-06 15:16 1112次阅读

    大田农业灌溉控制系统

    模式,结合物联网、移动互联网、云计算技术,诞生了农业灌溉控制系统解决方案,采用高精度环境信息采集设备、灌溉用水量智能决策、远程/自动控制
    的头像 发表于 03-03 15:22 467次阅读

    基于ARM9内核的智能灌溉控制系统的设计

    电子发烧友网站提供《基于ARM9内核的智能灌溉控制系统的设计.pdf》资料免费下载
    发表于 10-12 09:47 0次下载
    基于ARM9内核的<b class='flag-5'>智能</b><b class='flag-5'>灌溉</b><b class='flag-5'>控制系统</b>的设计

    农业智能灌溉控制系统

    ,农业发达国家除普遍采用喷灌、微灌等节水灌溉技术外,还应用了智能控制技术,也就是农业智能灌溉控制系统
    的头像 发表于 12-01 17:48 813次阅读