EmoPot: Maceta Inteligente que Visualiza la Salud de tu Planta
Componentes y suministros
| Arduino Nano R3 | × | 1 |
| DFRobot Gravity: Sensor de Humedad de Suelo Analógico para Arduino | × | 1 |
| Pantalla OLED I2C 0.96" | × | 1 |
Herramientas y máquinas necesarias
- Soldador (genérico)
- Impresora 3D (genérica)
Aplicaciones y servicios en línea
- Arduino IDE
Sobre este proyecto
En este proyecto, he hecho una maceta inteligente que puede mostrar la emoción de una planta😜. Usa un sensor de humedad de suelo para monitorizar la humedad y luego muestra una expresión emocional para ese nivel de humedad. Como sabemos que la planta necesita agua para estar viva y es como comida para ellas, así que podemos decir que tiene sentido😋. Es un pequeño proyecto divertido para hacer una maceta inteligente y monitorizar visualmente el nivel de humedad en la maceta.
Esta maceta muestra diferentes expresiones emocionales para diferentes niveles de agua.
Después de hacer este proyecto aprenderás-
- Cómo usar sensor de humedad de suelo y leer datos analógicos con ADC de Arduino
- Cómo mostrar fotos en OLED
- Cómo hacer animación y mostrarla en OLED usando Arduino
Parte Hardware
Para hacer este proyecto primero necesitamos una maceta. Diseñé la maceta con un compartimento para electrónica usando Fusion 360. Si tienes impresora 3D puedes imprimirla tú mismo. Si no tienes impresora 3D, ¡no hay problema! puedes usar cualquier maceta y hacer una caja para la electrónica.







Para la parte electrónica conecta-
- Arduino A5 a OLED SCL
- Arduino A4 a OLED SDA
- Arduino A0 a Sensor humedad suelo Ao
Programación
El código parece desordenado pero es muy simple. Al principio del código, incluyo algunas librerías (puedes tener que descargarlas):
- Adafruit_GFX.h
- Adafruit_SSD1306.h
Después de añadir esas librerías creo funciones para cada frame de animación para cada expresión emocional(Créeme que lleva una eternidad). En la sección setup, inicializo el display. Y en la sección loop, leo el valor del sensor analógicamente sensorValue = analogRead(A0); y luego hago condiciones para diferentes niveles de humedad y muestro los frames para esa expresión emocional.
Aquí hay algunos vídeos para diferentes expresiones emocionales para diferentes niveles de humedad
Código
Código EmoPot (Arduino)
#include
#include
#include
#include
#include
#define OLED_RESET 0
Adafruit_SSD1306 display(OLED_RESET);
int sensorValue = 0;
int xx = 40;
/******************************************SAD****************************************************/
// Frames de animación para expresión triste (frame01 a frame121)
// Arrays PROGMEM con datos bitmap 48x48 para cada frame
// ... (arrays de frames omitidos por brevedad, están en el código original)
/*************************************************SMILE*************************************************/
// Frames de animación para expresión feliz (frame02 a frame132)
// ... (arrays de frames omitidos por brevedad)
/**************************************neutral**************************************************/
// Frame para expresión neutral
const unsigned char PROGMEM frame03[] = { /* datos bitmap */ };
const unsigned char PROGMEM frame013[] = { /* datos bitmap */ };
const unsigned char PROGMEM frame23[] = { /* datos bitmap */ };
const unsigned char PROGMEM frame33[] = { /* datos bitmap */ };
const unsigned char PROGMEM frame43[] = { /* datos bitmap */ };
const unsigned char PROGMEM frame53[] = { /* datos bitmap */ };
const unsigned char PROGMEM frame63[] = { /* datos bitmap */ };
const unsigned char PROGMEM frame73[] = { /* datos bitmap */ };
const unsigned char PROGMEM frame83[] = { /* datos bitmap */ };
/***************************************blasing**************************************************************/
// Frames para expresión "blasing" (frame04 a frame94)
// ... (arrays de frames omitidos por brevedad)
/****************************************************CRYING**********************************************/
// Frames para expresión llorando (frame05 a frame95)
// ... (arrays de frames omitidos por brevedad)
const unsigned char PROGMEM framec[] = { /* frame confuso */ };
/********************************************************************************************************************************/
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setFont(&FreeSans9pt7b);
display.setTextColor(WHITE);
display.setCursor(0,0);
}
void loop() {
sensorValue = analogRead(A0); // lectura analógica del sensor
if(sensorValue >= 80 && sensorValue < 250) {
// smile - animación feliz
display.clearDisplay(); display.drawBitmap(xx, 0, frame012, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame22, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame32, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame42, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame52, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame62, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame72, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame82, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame92, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame102, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame112, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame122, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame132, 48, 48, 1); display.display(); delay(30);
}
else if(sensorValue >= 250 && sensorValue < 350) {
// blased - animación "aburrida"
display.clearDisplay(); display.drawBitmap(xx, 0, frame04, 48, 48, 1); display.display(); delay(50);
display.clearDisplay(); display.drawBitmap(xx, 0, frame14, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame24, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame34, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame44, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame54, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame64, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame74, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame84, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame94, 48, 48, 1); display.display(); delay(70);
}
else if(sensorValue >= 350 && sensorValue < 550) {
// neutral
display.clearDisplay(); display.drawBitmap(xx, 0, frame03, 48, 48, 1); display.display(); delay(60);
display.clearDisplay(); display.drawBitmap(xx, 0, frame013, 48, 48, 1); display.display(); delay(60);
display.clearDisplay(); display.drawBitmap(xx, 0, frame23, 48, 48, 1); display.display(); delay(60);
display.clearDisplay(); display.drawBitmap(xx, 0, frame33, 48, 48, 1); display.display(); delay(60);
display.clearDisplay(); display.drawBitmap(xx, 0, frame43, 48, 48, 1); display.display(); delay(60);
display.clearDisplay(); display.drawBitmap(xx, 0, frame53, 48, 48, 1); display.display(); delay(60);
display.clearDisplay(); display.drawBitmap(xx, 0, frame63, 48, 48, 1); display.display(); delay(60);
display.clearDisplay(); display.drawBitmap(xx, 0, frame73, 48, 48, 1); display.display(); delay(60);
display.clearDisplay(); display.drawBitmap(xx, 0, frame83, 48, 48, 1); display.display(); delay(500);
}
else if(sensorValue >= 550 && sensorValue < 700) {
// sad - animación triste
display.clearDisplay(); display.drawBitmap(xx, 0, frame011, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame21, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame31, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame41, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame51, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame61, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame71, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame81, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame91, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame101, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame111, 48, 48, 1); display.display(); delay(70);
display.clearDisplay(); display.drawBitmap(xx, 0, frame121, 48, 48, 1); display.display(); delay(100);
}
else if(sensorValue >= 700 && sensorValue < 800) {
// crying - animación llorando
display.clearDisplay(); display.drawBitmap(xx, 0, frame05, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame15, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame25, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame35, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame45, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame55, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame65, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame75, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame85, 48, 48, 1); display.display(); delay(30);
display.clearDisplay(); display.drawBitmap(xx, 0, frame95, 48, 48, 1); display.display(); delay(70);
}
else {
display.clearDisplay(); display.drawBitmap(xx, 0, framec, 48, 48, 1); display.display(); delay(30);
}
}
Partes personalizadas y envoltorios
Esquemáticos

Proceso de manufactura
- Central nuclear Susquehanna completa mantenimiento programado y restablece operación de Unidad 2
- Excavadoras Explicadas: Tipos, Usos y Cómo Elegir la Adecuada para tu Proyecto
- Señales Esenciales de que sus Punzones y Matrices Deben Reemplazarse
- 10 proyectos DIY de código abierto innovadores que aprovechan la impresión 3D
- Tecnología de reloj atómico reduce robo de paquetes en entregas online
- Detección de olores impulsada por IA: La tecnología de Aryballe revolucionando negocios y cadenas de suministro
- 7 señales clave de que es hora de actualizar su generador
- Factores Críticos que Influyen en los Costos de Fabricación CNC – Parte II
- Industrias que Prosperan con Mecanizado CNC de 5 Ejes: Eficiencia y Precisión
- Prevenga Accidentes con Montacargas: Consejos Esenciales para Cero Vuelcos
- Por qué las piezas mecanizadas a medida superan a las de fábrica en 4 áreas clave