基于STM32设计的太阳能热水器

发布时间:2023-09-25  

一、概述

本项目使用 STM32F103C8T6 微控制器作为核心处理器,结合多个传感器和执行器,实现了太阳能热水器的自动控制。通过对光照、温度、水位等各种参数的监测和分析,对水泵、电磁阀等设备进行自动控制,从而实现太阳能热水器的高效、安全、可靠运行。

img

二、硬件设计

(1)模块组成

太阳能热水器模块主要由以下几个部分组成:


光敏传感器模块:用于检测阳光强度,反映太阳辐射强度和方向。

温度传感器模块:用于检测太阳能集热器表面和水箱内的温度,并根据温度变化调整水泵、电磁阀等设备的运行状态。

液位传感器模块:用于检测水箱内的液位,并根据液位高低控制水泵和电磁阀的启停。

水泵模块:通过控制水泵的启停,实现水循环流动和充水功能。

电磁阀模块:通过控制电磁阀的开关,实现热水器的放水和接水功能。

(2)硬件连接

其中,光敏传感器模块、温度传感器模块和液位传感器模块通过 ADC 接口与 STM32F103C8T6 微控制器进行连接;水泵模块和电磁阀模块则通过 GPIO 口控制。


连接方式如下:


光敏传感器模块:将光敏传感器输出口与 ADC1 通道10 连接,并用一个电位器调整 ADC 的参考电压,使其范围在 0-3.3V 之间。

温度传感器模块:将 DS18B20 温度传感器数据线与 GPIOA 的 PA8 引脚连接,并将 VCC 和 GND 分别接到 3.3V 和 GND。

液位传感器模块:将液位传感器输出口与 ADC1 通道11 连接,并用一个电位器调整 ADC 的参考电压。

水泵模块:将水泵正极接到 GPIOB 的 PB1 引脚,将负极接到电源的负极。

电磁阀模块:将电磁阀正极接到 GPIOB 的 PB0 引脚,将负极接到电源的负极。

三、软件设计

3.1 任务分配

整个项目采用 FreeRTOS 系统进行开发,实现数数的监测和控制,开发以下几个任务:


光敏传感器任务:定时读取光敏传感器输出口的电压值,并进行数据处理,得到当前的光照强度。

温度传感器任务:定时向 DS18B20 温度传感器发送温度采样请求,接收并解析响应数据,得到当前的太阳能集热器表面温度和水箱内温度。

液位传感器任务:定时读取液位传感器输出口的电压值,并进行数据处理,得到当前的水箱水位高度。

控制任务:根据光照强度、温度和水位高度等参数,决定是否需要启动水泵或电磁阀等设备。

伪代码如下:


void Light_Sensor_Task(void)

 {

     while (1)

     {

         voltage = ADC_Get_Voltage(); // 获取光敏传感器输出电压

         light_intensity = voltage * 100 / 3.3f; // 根据电压计算光照强度

         vTaskDelay(1000); // 延时 1s

     }

 }

 

 void Temperature_Sensor_Task(void)

 {

     while (1)

     {

         DS18B20_Start_Conversion(); // 向温度传感器发送采样请求

         temperature1 = DS18B20_Read_Temperature(); // 读取太阳能集热器表面温度

         temperature2 = DS18B20_Read_Temperature(); // 读取水箱内温度

         vTaskDelay(1000); // 延时 1s

     }

 }

 

 void Water_Level_Sensor_Task(void)

 {

     while (1)

     {

         voltage = ADC_Get_Voltage(); // 获取液位传感器输出电压

         water_level = voltage * 100 / 3.3f; // 根据电压计算水位高度

         vTaskDelay(1000); // 延时 1s

     }

 }

 

 void Control_Task(void)

 {

     while (1)

     {

         if (light_intensity > THRESHOLD && temperature1 > THRESHOLD && water_level > THRESHOLD) // 如果各种参数均符合要求,则启动水泵和电磁阀

         {

             GPIO_SetBits(GPIOB, GPIO_Pin_1); // 启动水泵

             GPIO_ResetBits(GPIOB, GPIO_Pin_0); // 关闭电磁阀

         }

         else // 否则关闭水泵,打开电磁阀,放水

         {

             GPIO_ResetBits(GPIOB, GPIO_Pin_1); // 关闭水泵

             GPIO_SetBits(GPIOB, GPIO_Pin_0); // 启动电磁阀

         }

         vTaskDelay(1000); // 延时 1s

     }

 }

3.2 光敏传感器任务

/* 光敏传感器任务 */

 void Light_Sensor_Task(void *pvParameters)

 {

   uint16_t adc_value;

 

   while (1)

   {

     /* 读取 ADC 值并计算光照强度 */

     if (HAL_ADC_Start(&hadc1) == HAL_OK)

     {

       if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK)

       {

         adc_value = HAL_ADC_GetValue(&hadc1);

         light_intensity = adc_value * 3300 / 4096.0;

       }

     }

 

     vTaskDelay(pdMS_TO_TICKS(1000)); // 延时 1s

   }

 }

在函数中,声明一个变量 adc_value 用于存储读取到的 ADC 值。使用 if 条件语句检查 ADC 是否成功启动,并且使用 HAL_ADC_PollForConversion() 函数判断当前转换是否完成,如果转换完成,就获取 ADC 值,并且通过简单的计算公式将 ADC 值转换为光照强度值,最后将结果存储在 light_intensity 变量中。


3.3 温度传感器任务

/* 温度传感器任务 */

 void Temperature_Sensor_Task(void *pvParameters)

 {

   float temperature;

 

   /* 初始化 DS18B20 */

   DS18B20_Init(&htim2, GPIOA, GPIO_PIN_10);

 

   while (1)

   {

     /* 读取温度值 */

     temperature = DS18B20_Read_Temperature();

 

     /* 将读取到的温度值存储在全局变量中 */

     current_temperature = temperature;

 

     vTaskDelay(pdMS_TO_TICKS(1000)); // 延时 1s

   }

 }

在函数中,声明一个变量 temperature 用于存储读取到的温度值。然后,调用函数 DS18B20_Init() 初始化 DS18B20 温度传感器。使用 DS18B20_Read_Temperature() 函数读取温度值,并且将结果存储在 temperature 变量中。最后,将读取到的温度值存储在全局变量 current_temperature 中。


3.4 液位传感器任务

/* 液位传感器任务 */

 void Liquid_Level_Sensor_Task(void *pvParameters)

 {

   uint16_t adc_value;

   float voltage;

 

   /* 初始化液位传感器 GPIO 口 */

   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);

   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET);

 

   while (1)

   {

     /* 读取 ADC 值并计算电压值 */

     if (HAL_ADC_Start(&hadc1) == HAL_OK)

     {

       if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK)

       {

         adc_value = HAL_ADC_GetValue(&hadc1);

         voltage = adc_value * 3.3 / 4096.0;

       }

     }

 

     /* 根据电压值计算液位高度 */

     if (voltage < 0.5)

     {

       liquid_level = 0.0;

     }

     else if (voltage > 2.5)

     {

       liquid_level = 100.0;

     }

     else

     {

       liquid_level = (voltage - 0.5) * 100.0 / 2.0;

     }

 

     vTaskDelay(pdMS_TO_TICKS(1000)); // 延时 1s

   }

 }

在函数中,声明变量 adc_value 和 voltage,分别用于存储读取到的 ADC 值和计算得到的电压值。使用 HAL_GPIO_WritePin() 函数初始化液位传感器 GPIO 口,将启用传感器的引脚设置为高电平。使用 if 条件语句检查 ADC 是否成功启动,并且使用 HAL_ADC_PollForConversion() 函数判断当前转换是否完成,如果转换完成,就获取 ADC 值,并且通过简单的计算公式将 ADC 值转换为电压值,并将结果存储在 voltage 变量中。


由于需要使用电压值计算液位高度,使用 if 条件语句检查电压是否小于低液位警戒电压 0.5V 或者大于高液位警戒电压 2.5V,如果是则分别将液位高度设置为 0% 或 100%,否则使用简单的线性关系计算液位高度。


3.5 控制任务

/* 控制任务 */

 void Control_Task(void *pvParameters)

 {

   float temperature_setpoint = 25.0; // 设定温度值

   float liquid_level_setpoint = 50.0;  // 设定液位高度值

   float temperature_error, liquid_level_error;

   float temperature_integral, liquid_level_integral;

   float temperature_derivative, liquid_level_derivative;

   float temperature_output, liquid_level_output;

 

   float kp_temperature = 0.5, ki_temperature = 0.1, kd_temperature = 0.05; // 温度 PID 参数

   float kp_liquid_level = 0.2, ki_liquid_level = 0.05, kd_liquid_level = 0.02; // 液位高度 PID 参数

 

   while (1)

   {

     /* 计算温度 PID 控制器输出 */

     temperature_error = temperature_setpoint - current_temperature;

     temperature_integral += temperature_error;

     temperature_derivative = temperature_error - last_temperature_error;

     temperature_output = kp_temperature * temperature_error + ki_temperature * temperature_integral + kd_temperature * temperature_derivative;

     last_temperature_error = temperature_error;

 

     /* 计算液位高度 PID 控制器输出 */

     liquid_level_error = liquid_level_setpoint - liquid_level;

     liquid_level_integral += liquid_level_error;

     liquid_level_derivative = liquid_level_error - last_liquid_level_error;

     liquid_level_output = kp_liquid_level * liquid_level_error + ki_liquid_level * liquid_level_integral + kd_liquid_level * liquid_level_derivative;

     last_liquid_level_error = liquid_level_error;

 

     /* 通过 PWM 控制加热器和水泵电机 */

     if (temperature_output > 0.0)

     {

       HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);

       __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, (uint16_t)(temperature_output * 1000));

     }

     else

     {

       HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);

       __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0);

     }

 

     if (liquid_level_output > 0.0)

     {

       HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);

       __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, (uint16_t)(liquid_level_output * 1000));

     }

     else

     {

       HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);

       __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0);

     }

 

     vTaskDelay(pdMS_TO_TICKS(10)); // 延时 10ms

   }

 }

在函数中:


(1)定义参数和变量,包括设定温度值、设定液位高度值、温度 PID 控制器的参数、液位高度 PID 控制器的参数等。使用 while 循环处理控制逻辑,循环开始时,计算温度 PID 控制器输出。


(2)计算当前误差,并将误差累积到积分项中。计算误差变化率,并使用 PID 参数计算出输出值,将结果存储在 temperature_output 中,并将当前误差存储在 last_temperature_error 中以便于下一次计算,计算液位高度 PID 控制器输出。


(3)根据控制器输出值通过 PWM 控制加热器和水泵电机的运行状态。如果输出值大于 0,则启用电机或加热器并设置对应的 PWM 占空比,否则关闭电机或加热器并将 PWM 占空比设为 0。


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    基于STM32设计的太阳能热水器;一、概述 本项目使用 STM32F103C8T6 微控制器作为核心处理器,结合多个传感器和执行器,实现了太阳能热水器的自动控制。通过对光照、温度、水位......
    产品也不复杂,就是一个太阳能热水器的控制板。 不过一组合起来,功能之间就会相互冲突得很厉害,导致改了这里,那里又出问题。 一出问题所有功能又要重新测一遍。 如果你没经历过这种问题,你不......
    目前单片机市场51系列占主导地位,价格性能比较高,利用8051单片机实现供水系统控制自动化,应用前景广阔。将本文水位控制实例的硬件电路和软编程部分,根据不同的需要,稍作改动,就可用于水井、水塔、锅炉、卫生间冲水和太阳能热水器等其他贮水装置中。 ......
    下降到低位时启动水泵抽水。 5、家用太阳能热水器安装接线图 6、变压......
    来源:通用 VPPs在美国将迎来爆炸性增长,该国在2021年通过了《通货膨胀削减法案》,该法案为电动汽车、电热水器太阳能电池板和其他设备提供或扩大了税收激励措施,以降低对电网的负荷。 RMI估计,到......
    总投资超30亿元!绵阳炘皓新能源将建14GW N型高效电池项目;1月15日,四川省发改委发布关于高效太阳能电池智能制造项目(二期)节能报告的审查意见,原则......
    管线也会带入气体,另外,在发生过停断水区域的管网以及在太阳能热水器和管道末端等也都会留有气体。   措施:   1、加装止回阀   为了防止水压波动对水表计量的影响,在表......
    电机接线方法 3.三相电机接线方法(星形接线/角形接线) 4.太阳能......
    光伏系统的,初始发电效率要求为:采用晶硅组件的应不低于18%,采用薄膜组件的应不低于12%,采用透明幕墙薄膜组件的无初始发电效率要求。采用太阳能热水系统的,太阳能保证率和集热器效率应均不低于50%。采用......
    中国能建牵头编制的我国首部塔式光热电站运行国家标准发布实施;近日,中国能建主导编制的我国首个塔式光热电站运行标准《塔式太阳能光热发电站运行规程》(GB/T44079-2024)正式......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>