Optimize Greenhouse Environment with Modbus-Based Remote Monitoring and Control System
This example shows you how to optimize plant growth conditions, ensure crop health, and maximize yield by continuously monitoring and controlling various environmental parameters in a greenhouse.
You can use sensors to monitor environmental parameters critical to plant growth, such as temperature, humidity, and soil moisture. To collect real-time data on environmental parameters, distribute sensors throughout the greenhouse. MATLAB® receives this sensor data that is transmitted over a Modbus network through a Programmable Logic Controller (PLC).
For this example, consider that all the sensors are connected to CLICK Ethernet Standard PLC with IP Address 172.19.134.93. MATLAB processes the data, logs the environmental conditions, and generates control signals based on user-defined thresholds to maintain an optimum greenhouse environment. For instance, if the temperature read by the sensor is not within the preferred range, the system automatically generates a control signal to activate the heating or cooling mechanisms. This action maintains the temperature of the greenhouse environment in the preferred optimum range.
Connect to PLC Using Modbus TCP/IP
Connect to the PLC using modbus
function.
plcIP = "172.19.134.93"'; % Replace with the IP address of your PLC plcPort = 502; % Replace with Port to which your PLC is Connected modbusObj = modbus("tcpip",plcIP,plcPort)
modbusObj = Modbus TCPIP with properties: DeviceAddress: '172.19.134.93' Port: 502 Status: 'Connected' NumRetries: 1 Timeout: 10 (seconds) ByteOrder: 'big-endian' WordOrder: 'big-endian'
Schedule periodic data collection using timer
function.
t = timer(TimerFcn=@(myTimerObj, thisEvent)readAndControl(modbusObj), ... Period=30,ExecutionMode="fixedRate",TasksToExecute=10); start(t);
To stop the timer during execution, enter stop(t)
in the command window.
Read Data from PLC and Generate Control Actions
Use the readAndControl
callback function to monitor the greenhouse environment and generate appropriate control actions to maintain optimum conditions.
function readAndControl(modbusObj)
Monitor Environment Parameters of Greenhouse Through Modbus Server
Retrieve sensor data from multiple sensors connected to a PLC using the read
function. This data can be of various data types. The sensor addresses in this example are configured to suit the example's use case. Based on your use case, adjust the sensor addresses to enable data reading and writing to your PLC.
fprintf("Green House Parameter Readings at %s\n", string(datetime));
Read a value from the temperature sensor connected to the holding register at address 1101. The sensor measures the temperature in Celsius and returns a double-precision value. The double-precision value is stored as four uint16
values starting at register address 1101.
tempSensorAddress = 1101; temperature = read(modbusObj,"holdingregs",tempSensorAddress,1,"double"); fprintf("Temperature: %f\n", temperature);
Read a value from the humidity sensor connected to the holding register at address 2101. The sensor measures the relative humidity in percentage and returns a single-precision value. The single-precision value is stored as two uint16
values starting at register address 2101.
humiditySensorAddress = 2101; relativeHumidity = read(modbusObj,"holdingregs",humiditySensorAddress,1,"single"); fprintf("Humidity: %f\n", relativeHumidity);
Read a value from the soil moisture sensor connected to the holding register at address 101. The sensor measures the moisture content in percentage and returns a single-precision value.
soilMoistureSensorAddress = 101; soilMoisture = read(modbusObj,"holdingregs",soilMoistureSensorAddress,1,"single"); fprintf("Soil Moisture: %f\n", soilMoisture);
Read a value from the smoke detector sensor connected to the discrete input register at address 501. The sensor returns a bit value which is stored in a single register.
smokeSensorAddress = 501;
smokeDetected = read(modbusObj,"inputs",smokeSensorAddress,1);
Read a value from the water flow sensor connected to the holding register at address 2501. The sensor measures flow in liters/min and returns a double-precision value.
waterFlowSensorAddress = 2501; currentWaterFlow = read(modbusObj,"holdingregs",waterFlowSensorAddress,1,"double");
Control Environmental Parameters of Greenhouse Through Modbus Server
Send appropriate control signals to the PLC using the write
function. You can remotely regulate the environment with these control signals that trigger environment regulators as outlined in the code.
% Define the optimal range for different environmental parameters in the greenhouse. temperatureRange = struct("Min",20,"Max",40); % Temperature range in Celsius humidityRange = struct("Min",40,"Max",70); % Relative humidity range in percentage soilMoistureRange = struct("Min",40,"Max",80); % Moisture content in percentage disp(newline);
If smoke is detected inside the greenhouse, activate the safety system connected to the coil register at address 1.
safetySystemAdress = 1; if smokeDetected write(modbusObj,"coils",safetySystemAdress,1); fprintf("Smoke detected. Safety system activated.\n"); end
If the read temperature is not within the optimal range, activate the heating or cooling system to increase or decrease the temperature, respectively.
if temperature < temperatureRange.Min % This will turn on the heating system which consists of 4 heaters connected to coil registers at addresses 10, 11, 12, 13 heatingSystemAddress = 10; write(modbusObj,"coils",heatingSystemAddress,[1 1 1 1]); fprintf("Temperature below optimal range. Heating system activated.\n"); elseif temperature > temperatureRange.Max % This will turn on the cooling system connected to coil register at address 20 coolingSystemAddress = 20; write(modbusObj,"coils",coolingSystemAddress,1); fprintf("Temperature above optimal range. Cooling system activated.\n"); end
If the read soil moisture percentage is not within the optimum range, increase or decrease the water flow by 20% to restore optimal conditions.
if soilMoisture < soilMoistureRange.Min newWaterFlow = currentWaterFlow + (0.2*currentWaterFlow); fprintf("Soil moisture below optimal range. Water flow increased to: %f\n", newWaterFlow); elseif soilMoisture > soilMoistureRange.Max newWaterFlow = currentWaterFlow - (0.2*currentWaterFlow); fprintf("Soil moisture above optimal range. Water flow decreased to: %f\n", newWaterFlow); end write(modbusObj,"holdingregs",waterFlowSensorAddress,newWaterFlow,"double");
If the read humidity percentage is not within the optimum range, activate the dehumidifier or humidifier linked to coil addresses 201 and 202, respectively.
if relativeHumidity < humidityRange.Min humidifierAddress = 201; write(modbusObj,"coils",humidifierAddress,1); fprintf("Humidity below optimal range. Humidifier activated.\n"); elseif relativeHumidity > humidityRange.Max dehumidifierAddress = 202; write(modbusObj,"coils",dehumidifierAddress,1); fprintf("Humidity above optimal range. Dehumidifier activated.\n"); end disp(newline); end % readAndControl function ends here