Many plants need a warm and humid environment to grow well, e.g. mushrooms, seasonal vegetables, fruits, etc.
To increase the productivity of agricultural crops, we need to provide them with a suitable environment in unfavorable weather conditions (cold, frost, storms, high temperatures, etc.).
Farmers usually grow these crops in greenhouses so that they grow well and produce a large harvest.
With the Hexabitz modules, we can easily provide the right environment and control the temperature and humidity in the greenhouse.
Steps:💡First : Planning
To control the temperature, we need a heater that works with a voltage of 220 AC, and for the humidity we need a fan, as shown in the picture.
To control the electric heater, we need to change the RMS value of the voltage, which is easy to do with the H0FR6 module.
We can also switch the fan on and off with the H0FR1 module.
The modules can be used to connect loads, as shown in figure (3).
Temperature and humidity measurements can be carried out with the H0AR9 module (Sensor Hub).
We can add H01R0x is a smart RGB LED module to our project to indicate the working status of the electric heater and the current temperature.
To install our module array with the housing, we can use T00R1x, a module with triangular mounting hole that supports M2 and M2.5 screw sizes, and H00R1x-H, a module with semi-hexagonal mounting hole, as shown in the pictures.
For programming STM32 microcontrollers (Hexabitz modules and other MCUs), we can use H40Rx, a programming module that includes STLINK-V3MODS standalone debugging and programming.
To For more information about the modules, please visit the following link: Modules – Hexabitz
🛠 Second: Assemble
After we have completed the planning of the project idea, we can now assemble and weld the modules as follows:
⚙️Third: Programming
After we have assembled the modules, we form an array and place the RGB module in the center.
We will number the modules from 1 to 5 to create a file with a fixed topology and upload code to the processors so that they can communicate with each other and know their neighbors.
After numbering them, we will enter the fixed topology to create a code and use STM32CubeIDE software.
#ifndef __topology_H
#define __topology_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32g0xx_hal.h"
#define __N 5 // Number of array modules
// Array modules
#define _mod1 1<<3
#define _mod2 2<<3
#define _mod3 3<<3
#define _mod4 4<<3
#define _mod5 5<<3
// Topology
static uint16_t array[__N ][7] ={
{_H01R0,_mod5 | P3, 0, 0, _mod3 | P3, _mod4 | P4,_mod2 | P6}, // Module 1
{_H0AR9,_mod4 | P3, 0, 0, 0, _mod5 | P4,_mod1 | P6}, // Module 2
{_H0FR1,0, _mod4 | P5,_mod1 | P4, 0, 0, 0}, // Module 3
{_H0FR6,0, 0,_mod2 | P1, _mod1 | P5, _mod3 | P2, 0}, // Module 4
{_H3BR6,0, 0,_mod1 | P1, _mod2 | P5, 0, 0}, // Module 5
};
Now that we have numbered the array modules, we will configure the serial duplex ports in the sam file (topology.h).
#if ( _module == 1 )
#define H01R0 1
#define _P1pol_normal 1
#define _P2pol_normal 1
#define _P3pol_normal 1
#define _P4pol_normal 1
#define _P5pol_normal 1
#define _P6pol_normal 1
#endif
#if ( _module == 2 )
#define H0AR9 1
#define _P1pol_reversed 1
#define _P2pol_normal 1
#define _P3pol_normal 1
#define _P4pol_normal 1
#define _P5pol_normal 1
#define _P6pol_reversed 1
#endif
#if ( _module == 3 )
#define H0FR1 1
#define _P1pol_normal 1
#define _P2pol_normal 1
#define _P3pol_reversed 1
#define _P4pol_normal 1
#define _P5pol_normal 1
#define _P6pol_normal 1
#endif
#if ( _module == 4 )
#define H0FR6 1
#define _P1pol_normal 1
#define _P2pol_normal 1
#define _P3pol_normal 1
#define _P4pol_reversed 1
#define _P5pol_reversed 1
#define _P6pol_normal 1
#endif
#if ( _module == 5 )
#define H3BR6 1
#define _P1pol_normal 1
#define _P2pol_normal 1
#define _P3pol_reversed 1
#define _P4pol_reversed 1
#define _P5pol_normal 1
#define _P6pol_normal 1
#endif
For more information on how to create a fixed topology, you can always visit
Make a Pre-built Array Topology File – Hexabitz
Now we can write our main program file (main.c). Before we talk about our basic programming, we will introduce some features of the PID controller.
🕹The PID controller is widely used in the application of control theories and industrial applications due to its simplicity and clear physical principle. It can be used in dozens of applications in industrial processes to achieve the desired operating point by changing the output of the control system. The PID controller continuously calculates the error value as the difference between the reference signal and the measured process output. Then the output is adjusted to minimize the error.
PID controller is given by the equation:
Where e(t)=r(t)-y(t) is the error equation, Kp, TI and Td are the proportional gain, integral time constant and differential time constant respectively.
There are a number of methods for tuning a PID controller, some of which are based on time response (transient), the best known are Ziegler-Nichols, Cohen-Coon, trial-and-error method (manual calibration), and some are based on frequency analysis, and in this project we will use the manual calibration method.
For more information about PID controller, please visit:
We can write a function to calculate the error equation for the PID controller in the main.c as follows:
double Kp =20.0;
double Ki =0.01;
float setpoint =24.5; // We set the desired temperature value in Celsius
float dt =0.1; // Sampling time for the control loop
double pid_output;
float error;
/* Private function prototypes -----------------------------------------------*/
uint8_t pid_controller(float setpoint,float temper);
uint8_t pid_controller(float setpoint,float temper){
float integral_error, mx_val;
// Calculate error
error =setpoint - temper;
// Calculate integral error
integral_error +=error * dt;
// saturation for integral_error
mx_val =50;
if(integral_error > mx_val)
integral_error =mx_val;
if(integral_error < -mx_val)
integral_error =-mx_val;
// Calculate PID output
pid_output =Kp * error + Ki * integral_error;
// saturation for output PID we set a maximum value 100% and minimum value 0%
if(pid_output > 100){
pid_output =100;
}
if(pid_output <= 0){
pid_output =0;
}
return pid_output;
}
As can be seen above, there is a saturation for the output of the function, since this value represents the PWM for the H0FR6 module, we can call this function -pid_controller()- within the main() function.
After we have finished writing the PID function, we will move on to writing the main function.
To get filtered and calibrated values for temperature (Celsius) and humidity (%) from the sensor hub, we can call this API
float temper;
float humidity;
while(1){
// sampling reading from sensors
SampleHumidity(&humidity);
SampleTemperature(&temper);
Now we can complete the program and write instructions to control the operation of LED module H01R0, SSR module (H0FR6) and SPDT module (H0FR1) according to the temperature and humidity.
if(pid_controller(setpoint,temper) == 0){
SendMessageToModule(4,CODE_H0FR6_OFF,0);
messageParams[0] =0;
messageParams[1] =BLUE;
messageParams[2] =100;
SendMessageToModule(1,CODE_H01R0_COLOR,3);
}
else{
// setting a percent value to moudel H0FR6x (SSR) from output pid
messageParams[0] =pid_controller(setpoint,temper);
SendMessageToModule(4,CODE_H0FR6_PWM,1);
messageParams[0] =0;
messageParams[1] =GREEN;
messageParams[2] =pid_controller(setpoint,temper);
SendMessageToModule(1,CODE_H01R0_COLOR,3);
}
// on and off moudel H0FR1x (SPDT) relay
if((temper >= 30 && pid_controller(setpoint,temper) == 0) || (humidity >= 75 && humidity <= 95)){
float timeout =0xFFFFFFFF;
memcpy(&messageParams[0],&timeout,4);
SendMessageToModule(3,CODE_H0FR1_ON,4);
}
else{
SendMessageToModule(3,CODE_H0FR1_OFF,0);
}
We can also print the value of temperature and humidity on the seven-segment module H3BR6.
// printing value of temperature and humidity on seven segment
memcpy(&messageParams[0],&temper,4);
messageParams[4] =3;
messageParams[5] ='c';
messageParams[6] =0;
SendMessageToModule(5,CODE_H3BR6_SevenDisplayQuantities,7);
Delay_ms(700);
memcpy(&messageParams[0],&humidity,4);
messageParams[4] =3;
messageParams[5] ='H';
messageParams[6] =0;
SendMessageToModule(5,CODE_H3BR6_SevenDisplayQuantities,7);
Delay_ms(700);
}
}
For more information about how to write API and massge, you can always visit:
Fourth: Testing
After writing the program and uploading it to the modules, we can test the project, monitor the system output and set the parameters of the controller according to the error signal.
References:[1]: Hexabitz – Better prototypes. Faster.
[2]: Wiki – Hexabitz
[3]: Temperature, Humidity, Light, Color, and Motion Sensor Hub (H0AR9x) – Hexabitz
[4]: 6 Digit Seven Segment (H3BR6x) – Hexabitz
[5]: 600V / 1.2A Solid State Relay (H0FR6x) – Hexabitz
[6]: SPDT Mechanical DC Relay (H0FR1x) – Hexabitz
[7]: RGB LED (H01R0x) – Hexabitz
[8]: STLINK-V3MODS Programmer (H40Rx) – Hexabitz
Comments
Please log in or sign up to comment.