Shade net automation using a light sensor and motor for a greenhouse provides precise control of sunlight levels, protecting crops from high-intensity radiation while maximising photosynthesis during optimal light periods. Manual shade net operation is labour-intensive and inconsistent — automated systems driven by BH1750 light sensors and 12V DC motors ensure crops always receive ideal light conditions. This guide covers building a complete automated shade net retraction system with ESP32.
Table of Contents
- Why Shade Net Automation Matters
- Crop Light Requirements and Shade Net Specifications
- Components Required
- Circuit and Motor Control Design
- ESP32 Shade Net Controller Code
- Safety Features and Wind Override
- Indian Greenhouse Applications
- Frequently Asked Questions
Why Shade Net Automation Matters
Shade nets are used extensively across Indian horticulture to manage light intensity and reduce heat stress. Manual operation challenges include:
- Labour cost: Shade net deployment/retraction takes 30-90 minutes for a large greenhouse — 2-3 times daily
- Timing errors: Nets deployed too late on clear mornings cause early heat stress; retracted too early in evening wastes potential photosynthesis time
- Night deployment: Nets left closed on clear nights reduce dew absorption on foliage and can damage sensitive crops in cold weather
- Storm response: Manual retraction during sudden wind gusts is dangerous and often impossible in time — damage to nets and structures occurs
Automated shade net systems save 1-2 labour hours daily and improve crop light interception uniformity by 20-35% compared to manual operation.
Crop Light Requirements and Shade Net Specifications
| Crop | Optimal Light (lux) | Shade Level | Open Net Above (lux) |
|---|---|---|---|
| Capsicum/Pepper | 30,000-50,000 | 35% | 75,000 |
| Cucumber | 30,000-60,000 | 25-35% | 80,000 |
| Leafy greens | 15,000-25,000 | 50% | 40,000 |
| Tomato (fruiting) | 30,000-70,000 | 25% | 90,000 |
| Orchids | 10,000-20,000 | 65-75% | 25,000 |
Note: 1 lux = 0.0079 W/m2 (for daylight). Full summer sunlight in India = 100,000-120,000 lux. Common shade nets: 25%, 35%, 50%, 65%, 75% shading factors (HDPE knitted nets).
Components Required
Sensors from Zbotic
- GY-BME280 3.3V Sensor — temperature monitoring alongside light control (shade reduces temperature too)
- 5V/12V Relay Control Module — for motor direction control relay logic
- Raindrops Detection Sensor Module — auto-retract net in rain to prevent waterlogging on net surface
Full system components:
- ESP32 WROOM-32
- BH1750 digital light intensity sensor (0-65535 lux, I2C)
- BME280 temperature and humidity sensor
- Rain sensor module (for emergency retract)
- Wind speed sensor (anemometer, for storm protection)
- 12V DC gearbox motor (5-15 RPM, torque-rated for net weight and span)
- L298N H-bridge motor driver (or 2x relay for simple direction control)
- Limit switches (2x end-of-travel, to prevent motor overrun)
- 12V 10A power supply (motor is primary load)
- Rope and pulley system or roller tube for net deployment
Circuit and Motor Control Design
Using L298N H-bridge for motor direction control:
- L298N IN1 -> ESP32 GPIO26, IN2 -> GPIO27 (direction control)
- L298N ENA -> GPIO25 (PWM speed control, optional)
- L298N OUT1/OUT2 -> DC motor terminals
- Limit switch 1 (net fully open) -> GPIO14 (pulled HIGH, LOW = triggered)
- Limit switch 2 (net fully closed) -> GPIO12 (pulled HIGH, LOW = triggered)
- BH1750 SDA -> GPIO21, SCL -> GPIO22
- BME280 SDA -> GPIO21, SCL -> GPIO22 (I2C shared)
- Rain sensor DOUT -> GPIO13
Motor sizing: For a 10m span shade net, a 12V 10Nm gearbox motor at 5-10 RPM is sufficient. Calculate required torque = (net weight kg x span/2 m) + 30% safety margin for friction. Stainless steel guide wires prevent net sag.
ESP32 Shade Net Controller Code
#include <Wire.h>
#include <BH1750.h>
#include <Adafruit_BME280.h>
#include <WiFi.h>
#include <WebServer.h>
BH1750 lightSensor;
Adafruit_BME280 bme;
WebServer server(80);
// Motor control
#define MOTOR_IN1 26
#define MOTOR_IN2 27
#define LIMIT_OPEN 14 // Low = net is fully open
#define LIMIT_CLOSE 12 // Low = net is fully closed
#define RAIN_SENSOR 13
// Light thresholds
const float LUX_OPEN_THRESHOLD = 80000; // Deploy net above this (lux)
const float LUX_CLOSE_THRESHOLD = 50000; // Retract net below this (lux)
const float TEMP_OPEN_THRESHOLD = 35.0; // Deploy net above this temperature
// States
enum NetState { NET_OPEN, NET_CLOSED, NET_MOVING, NET_MANUAL };
NetState netState = NET_CLOSED;
bool netOpen = false; // Approximate state (between limits)
bool rainActive = false;
float currentLux = 0;
float currentTemp = 0;
void motorOpen() {
if (digitalRead(LIMIT_OPEN) == LOW) { motorStop(); return; } // Already at limit
digitalWrite(MOTOR_IN1, HIGH);
digitalWrite(MOTOR_IN2, LOW);
netState = NET_MOVING;
Serial.println("Motor: Opening net");
}
void motorClose() {
if (digitalRead(LIMIT_CLOSE) == LOW) { motorStop(); return; }
digitalWrite(MOTOR_IN1, LOW);
digitalWrite(MOTOR_IN2, HIGH);
netState = NET_MOVING;
Serial.println("Motor: Closing net");
}
void motorStop() {
digitalWrite(MOTOR_IN1, LOW);
digitalWrite(MOTOR_IN2, LOW);
if (digitalRead(LIMIT_OPEN) == LOW) {
netState = NET_OPEN;
Serial.println("Net: OPEN (limit reached)");
} else if (digitalRead(LIMIT_CLOSE) == LOW) {
netState = NET_CLOSED;
Serial.println("Net: CLOSED (limit reached)");
} else {
netState = NET_MANUAL;
}
}
String buildDashboard() {
String html = "<!DOCTYPE html><html><head><title>Shade Net Control</title>";
html += "<meta name='viewport' content='width=device-width,initial-scale=1'>";
html += "<meta http-equiv='refresh' content='15'></head><body style='font-family:sans-serif;text-align:center'>";
html += "<h1>Shade Net Controller</h1>";
html += "<p>Light: <b>" + String(currentLux, 0) + " lux</b></p>";
html += "<p>Temperature: <b>" + String(currentTemp, 1) + " C</b></p>";
html += "<p>Rain: " + String(rainActive ? "Yes - net deployed" : "No") + "</p>";
String stateStr = (netState == NET_OPEN) ? "OPEN" : (netState == NET_CLOSED) ? "CLOSED" : "MOVING";
html += "<p>Net Status: <b>" + stateStr + "</b></p>";
html += "<a href='/open'><button style='padding:12px 24px;margin:8px'>Open Net</button></a>";
html += "<a href='/close'><button style='padding:12px 24px;margin:8px'>Close Net</button></a>";
html += "<a href='/stop'><button style='padding:12px 24px;margin:8px;background:red;color:white'>STOP</button></a>";
html += "</body></html>";
return html;
}
void setup() {
Serial.begin(115200);
Wire.begin(21, 22);
lightSensor.begin();
bme.begin(0x76);
pinMode(MOTOR_IN1, OUTPUT); digitalWrite(MOTOR_IN1, LOW);
pinMode(MOTOR_IN2, OUTPUT); digitalWrite(MOTOR_IN2, LOW);
pinMode(LIMIT_OPEN, INPUT_PULLUP);
pinMode(LIMIT_CLOSE, INPUT_PULLUP);
pinMode(RAIN_SENSOR, INPUT_PULLUP);
WiFi.begin("FarmWiFi", "farmpassword");
while (WiFi.status() != WL_CONNECTED) { delay(500); }
Serial.println("IP: " + WiFi.localIP().toString());
server.on("/", []() { server.send(200, "text/html", buildDashboard()); });
server.on("/open", []() { motorOpen(); server.sendHeader("Location", "/"); server.send(302); });
server.on("/close", []() { motorClose(); server.sendHeader("Location", "/"); server.send(302); });
server.on("/stop", []() { motorStop(); server.sendHeader("Location", "/"); server.send(302); });
server.begin();
}
void loop() {
server.handleClient();
static unsigned long lastCheck = 0;
if (millis() - lastCheck > 30000) { // Check every 30 seconds
lastCheck = millis();
currentLux = lightSensor.readLightLevel();
currentTemp = bme.readTemperature();
rainActive = (digitalRead(RAIN_SENSOR) == LOW);
// Stop motor immediately if limit reached
if (digitalRead(LIMIT_OPEN) == LOW && netState == NET_MOVING) motorStop();
if (digitalRead(LIMIT_CLOSE) == LOW && netState == NET_MOVING) motorStop();
// Auto control logic (only when not in manual override)
if (netState != NET_MANUAL) {
if (rainActive && netState != NET_OPEN) {
motorOpen(); // Open net in rain (prevents waterlogging on net surface)
} else if ((currentLux > LUX_OPEN_THRESHOLD || currentTemp > TEMP_OPEN_THRESHOLD)
&& netState == NET_CLOSED) {
motorOpen(); // High light or temperature: deploy shade net
} else if (currentLux < LUX_CLOSE_THRESHOLD && !rainActive
&& netState == NET_OPEN && currentTemp < TEMP_OPEN_THRESHOLD) {
motorClose(); // Light dropped: retract shade net
}
}
Serial.printf("Lux:%.0f T:%.1fC Rain:%s Net:%sn",
currentLux, currentTemp, rainActive?"Yes":"No",
netState==NET_OPEN?"OPEN":"CLOSED");
}
delay(100);
}
Safety Features and Wind Override
Critical safety features for outdoor shade net systems:
- Limit switches: Mechanical stop prevents motor overrun at both ends of travel — most important safety feature
- Motor timeout: If motor runs for more than 3 minutes without reaching a limit switch, stop immediately (net jam or obstruction)
- Wind speed cutoff: Above 40 km/h wind, retract shade net immediately (unloaded net acts as a sail, damaging structure)
- Rain retract logic: Open (retract) shade net during heavy rain — closed nets accumulate water weight causing structural damage
- Manual override button: Emergency stop accessible from inside greenhouse
- Power failure protection: On power restoration, read limit switches to determine actual net position before any movement
Indian Greenhouse Applications
Shade net automation is particularly impactful across India:
- Floriculture (Bengaluru, Pune, Delhi NCR): Rose, gerbera, and chrysanthemum exports require tight light control. Automated systems allow night staff reduction.
- Capsicum (Maharashtra, Karnataka): 35% shade net deployment at PAR above 1200 umol/m2/s prevents sun scald on fruits.
- Ornamental nurseries (Kolkata, Chennai): Shade-loving indoor plants (peace lily, dracaena) require 65-75% shade year-round.
- Strawberry (Mahabaleshwar, Himachal): Clear UV-blocking nets allow full light but reduce UV stress on berries, improving colour and shelf life.
Frequently Asked Questions
What motor torque do I need for a 10-metre shade net span?
For a 10m x 30m HDPE shade net (weight approximately 2 kg/m2 x 300 m2 = 600 kg for a full structure), the deployment mechanism works on half the span (5m moment arm) with friction reduction from guide wires. A 12V 20-30 Nm gearbox motor at 5 RPM is sufficient for most polyhouse shade net systems. Always oversize by 50% for reliability.
Can I use this system for motorised privacy screens or awnings?
Yes, the same circuit and logic applies to any motorised fabric system. Adjust the light thresholds to suit your application — for privacy screens, add a manual-only mode that ignores light sensor readings.
How do I calibrate the BH1750 sensor for shade level measurement?
The BH1750 measures lux accurately (within 5%) without calibration. For shade level mapping, take readings simultaneously inside and outside the shade net during clear sky conditions. Shade percentage = (1 – indoor lux/outdoor lux) x 100. Verify against the manufacturer-stated shade factor of your specific net.
What shade net percentage is best for Indian summer conditions?
For most vegetable crops in India (March-June), 35-50% shade nets are optimal. Above 50%, CO2 assimilation drops significantly due to light limitation. Below 35%, heat stress occurs despite ventilation in plains regions above 35 degrees C ambient. For coastal and hill regions, 25% shade is often sufficient due to naturally lower radiation levels.
Add comment