ArduFarmBot Parte 2: Estación de Control IoT Remota para Cultivos
Componentes y suministros
| Componente | Descripción | Cantidad |
|---|---|---|
| Arduino Nano R3 | Controlador principal. | 1 |
| ESP8266 ESP-01 | Módulo WiFi para conectividad IoT. | 1 |
| Sensor DHT22 | Temperatura y humedad aire. | 1 |
| Sensor luminosidad KY-018 (LDR) | Nivel de luz. | 1 |
| Sensor humedad suelo (higrómetro) | td>Humedad del sustrato.1 | |
| Módulo relé 5V | Control bomba y lámpara. | 2 |
| LCD I2C 20x4 | Visualización local. | 1 |
| Pulsadores membrana (4 teclas) | Control manual local. | 3 |
| LEDs genéricos | Indicadores de estado. | 3 |
| Resistencias: 10k, 2.2k, 1k, 220Ω | Divisores de tensión, pull-up, LEDs. | Varias |
| Shield Arduino Nano (Funduino) | Facilita conexiones. | 1 |
Aplicaciones y servicios
- ThingSpeak API (almacenamiento en la nube y control remoto)
Sobre el proyecto
Continuación de ArduFarmBot: Controlando cultivo de tomates con Arduino e IoT. La Parte 1 implementó estación local con control automático/manual de riego (bomba) y calefacción (lámpara). En esta Parte 2 se añade control remoto vía Internet usando ESP8266 y ThingSpeak.
Arquitectura: Arduino Nano lee sensores → envía datos a ThingSpeak → Página web remota muestra datos y permite activar bomba/lámpara escribiendo en campos 7 y 8 de ThingSpeak → Arduino lee esos campos periódicamente y actúa.
Paso 1: Lista de materiales (BOM)
- Arduino Nano ($7.50)
- DHT22/DHT11 ($3.66)
- Módulo LDR AD-018 ($0.71)
- 2x Sensor humedad suelo ($1.99 c/u)
- LCD I2C 20x4 ($13.99)
- ESP8266 ESP-01 ($5.96)
- 2x Módulo relé 5V ($11.60)
- Teclado membrana 4 teclas ($6.65)
- Shield Funduino ($7.28)
- Caja plástica, resistencias, cables, zumbador
Paso 2: Hardware adicional
Solo se añade el ESP8266 a la estación local. Diagrama de bloques muestra conexiones pines. Importante: ESP8266 trabaja a 3.3V; el pin Rx no debe conectarse directo a Tx Nano (5V). Usar divisor de tensión (2.2kΩ + 1kΩ). Conexión: ESP Tx → Nano D2 (SoftSerial Rx), ESP Rx → Nano D3 a través de divisor.

Paso 3: Conexión ESP8266
Reset del módulo (pin CH_PD), conexión WiFi (credenciales en código), modo Estación (CWMODE=1). Funciones auxiliares: reset8266(), connectWiFi(), sendData() para comandos AT.
Paso 4: Almacenamiento en nube - ThingSpeak
Datos subidos a canal ThingSpeak gratuito. Función updateDataThingSpeak() envía 6 campos: temp, humedad, luz, humedad suelo, estado bomba, estado lámpara. Comunicación TCP puerto 80 con AT+CIPSTART y AT+CIPSEND.
Paso 5: Control actuadores desde web
Campos 7 y 8 en ThingSpeak como comandos remotos:
- Campo 7: 1=Bomba ON, 0=Bomba OFF
- Campo 8: 1=Lámpara ON, 0=Lámpara OFF
Función readLastDataField7() lee último valor vía GET /channels/CHANNEL_ID/fields/7/last. Función receiveCommands() obtiene ambos campos y actualiza actuadores. Sincronización con comandos locales actualizando campos 7/8 tras pulsación botones.
Paso 6: Página web dedicada
Interfaz amigable alojada en Byethost (gratuita). HTML5/CSS3/JS interactúa con ThingSpeak: lee campos 1-6 (sensores/actuadores), escribe campos 7-8 (comandos), muestra clima local (Yahoo). Código fuente incluido en archivos del proyecto.

Paso 7: Matriz Sensor-Actuador
Enfoque matricial para decisiones complejas. Array booleano SDf[18][10] codifica 18 combinaciones de condiciones de sensores (suelo: seco/medio/húmedo; luz: oscuro/claro; temp: baja/media/alta) → acciones (bomba, lámpara). Función defSensorStatus() evalúa fila a fila y ejecuta acciones correspondientes.
Paso 8: Optimización de código
- Pantalla LCD apagada por defecto; botón "Sensores" enciende/apaga (toggle).
- Setup inicial muestra parámetros configurables (temp frío, suelo seco/húmedo, luz oscura, tiempo bomba, intervalo escaneo, versión SW). Pulsa "Sensores" para iniciar.
- Registro LOG en EEPROM: cada ciclo guarda estado 8 sensores + bomba + lámpara (bits).
- Código modularizado en varios archivos .ino. Uso de
PROGMEMpara constantes (ahorra SRAM).
Paso 9: Cultivo real MJRovai
Secuencia fotográfica de dos plantaciones de tomate controladas por ArduFarmBot: desde siembra, selección de mejores plantas, trasplante, hasta producción.
Paso 10: Conclusión y libro
Proyecto completo documentado en "ArduFarmBot, the Book!" (Amazon.com). Tres partes: 1) Local con Arduino Nano, 2) Remoto con ESP8266-01 + ThingSpeak, 3) Versión avanzada con NodeMCU ESP8266-12E + Blynk. Incluye diagramas Fritzing, código en GitHub, videos YouTube.

Código (fragmentos clave)
Reset y conexión ESP8266
void reset8266() { pinMode(CH_PD, OUTPUT); digitalWrite(CH_PD, LOW); delay(300); digitalWrite(CH_PD, HIGH); Serial.print("8266 reset OK"); }
void connectWiFi() { sendData("AT+RST\r\n",2000,DEBUG); sendData("AT+CWJAP=\"USER\",\"PASS\"\r\n",2000,DEBUG); delay(3000); sendData("AT+CWMODE=1\r\n",1000,DEBUG); sendData("AT+CIFSR\r\n",1000,DEBUG); }
String sendData(String cmd, const int timeout, boolean debug) { String resp=""; esp8266.print(cmd); long t=millis(); while((t+timeout)>millis()){ while(esp8266.available()){ char c=esp8266.read(); resp+=c; } } if(debug) Serial.print(resp); return resp; }
Envío a ThingSpeak
void updateDataThingSpeak() { startThingSpeakCmd(); cmd = msg; cmd += "&field1=" + tempDHT + "&field2=" + humDHT + "&field3=" + lumen + "&field4=" + soilMoist + "&field5=" + pumpStatus + "&field6=" + lampStatus + "\r\n"; sendThingSpeakCmd(); }
void startThingSpeakCmd() { cmd = "AT+CIPSTART=\"TCP\",\""; cmd += IP; cmd += "\",80"; esp8266.println(cmd); delay(2000); if(esp8266.find("Error")) return; }
String sendThingSpeakCmd() { esp8266.print("AT+CIPSEND="); esp8266.println(cmd.length()); if(esp8266.find(">")){ esp8266.print(cmd); /* leer respuesta */ } else { esp8266.println("AT+CIPCLOSE"); /* reintentar */ } }
Comandos remotos y bucle principal
int readLastDataField7() { startThingSpeakCmd(); cmd = msgReadLastDataField7 + "\r\n"; String msg = sendThingSpeakCmd(); return msg[7]-48; }
void receiveCommands() { field7Data = readLastDataField7(); if(field7Data==1){ digitalWrite(PUMP_PIN,HIGH); pumpStatus=1; } else { digitalWrite(PUMP_PIN,LOW); pumpStatus=0; } showDataLCD(); delay(500); /* similar campo 8 */ }
void aplyCmd() { if(field7Data==1) digitalWrite(PUMP_PIN,HIGH); else digitalWrite(PUMP_PIN,LOW); if(field8Data==1) digitalWrite(LAMP_PIN,HIGH); else digitalWrite(LAMP_PIN,LOW); }
long sampleTimingSeconds = 75, poolingRemoteCmdSeconds = 20;
void loop() {
elapsedRemoteCmdTime = millis()-startRemoteCmdTiming;
elapsedTime = millis()-startTiming;
readLocalCmd(); showDataLCD();
if(elapsedRemoteCmdTime > poolingRemoteCmdSeconds*1000){ receiveCommands(); updateDataThingSpeak(); startRemoteCmdTiming=millis(); }
if(elapsedTime > sampleTimingSeconds*1000){ readSensors(); autoControlPlantation(); updateDataThingSpeak(); startTiming=millis(); }
}
Matriz decisión y LOG EEPROM
boolean SDf[18][10] = {{1,0,0,0,1,0,0,1,1,0}, ...}; // 18 filas, 8 sensores + 2 actuadores
void storeDataLogEEPROM() { for(int i=0;i<8;i++) logData = logData + (snsSts[i]<<1); EEPROM.write(memoAddr, logData); memoAddr++; logData = pumpStatus<<1 | lampStatus; EEPROM.write(memoAddr, logData); EEPROM.write(0, memoAddr+1); if(memoAddr+1==1023) memoAddr=1; else memoAddr++; }
Esquemático

Repositorio GitHub: https://github.com/Mjrovai/ArduFarmBot
Proceso de manufactura
- Estación de Mezcla de Cócteles "6-Shooter" con Arduino: Construye tu Propio Barman Automático
- Sistema de Sensor de Temperatura Multiposición para Integración en Hogar Inteligente
- MotionSense: Detección inteligente de intrusos con Arduino y ESP8266
- Prevención de Incendios en Impresoras 3D: Sistema de Seguridad con Sensor Inteligente
- Crear un medidor IoT web con Arduino, Yaler e IFTTT
- Levitación magnética repulsiva con Arduino: Circuito simple y guía DIY
- Robot pinza controlado remotamente para manipulación de precisión
- Registrador de Datos de Alto Rendimiento para Globo Meteorológico con Arduino
- Estación Meteorológica Portátil Arduino por $10 – Nano, DHT22, BMP180 y LCD
- CoroFence: Detector Térmico Avanzado con Sensor PIR e Integración IoT
- Tendencias emergentes en implementación IoT: Insights y estrategias