EmoPot: Vaso Inteligente que Visualiza a Saúde da Sua Planta
Componentes e Materiais
| Componente | Quantidade |
|---|---|
| Arduino Nano R3 | 1 |
| DFRobot Gravity: Sensor Analógico de Umidade do Solo para Arduino | 1 |
| Display OLED I2C 0.96" | 1 |
Ferramentas e Máquinas Necessárias
- Ferro de solda (genérico)
- Impressora 3D (genérica)
Aplicativos e Serviços Online
- Arduino IDE
Sobre o Projeto
Neste projeto, fiz um vaso de planta inteligente que pode mostrar a emoção de uma planta😜. Ele usa um sensor de umidade do solo para monitorar a umidade e depois mostra uma expressão emocional para aquele nível de umidade. Como sabemos que a planta precisa de água para estar viva e é como comida para elas, então podemos dizer que faz sentido😋. É um pequeno projeto divertido para fazer um vaso inteligente e monitorar visualmente o nível de umidade no vaso.
Este vaso mostra diferentes expressões emocionais para diferentes níveis de água.
Após fazer este projeto você aprenderá-
- Como usar sensor de umidade do solo e ler dados analógicos pelo ADC do Arduino
- Como exibir fotos no OLED
- Como fazer animação e exibi-la no OLED usando Arduino
Parte de Hardware
Para fazer este projeto, primeiro precisamos de um vaso de planta. Projetei o vaso com um compartimento para eletrônica usando Fusion 360. Se você tem uma impressora 3D, pode imprimi-lo você mesmo. Se não tem impressora 3D, sem problema! Você pode usar qualquer vaso de planta e fazer uma caixa para a eletrônica.







Para a parte eletrônica conecte-
- Arduino A5 ao OLED SCL
- Arduino A4 ao OLED SDA
- Arduino A0 ao Sensor de umidade do solo Ao
Codificação
O código parece bagunçado, mas é muito simples! No início do código, incluo algumas bibliotecas- (Você pode ter que baixar essas bibliotecas)
- Adafruit_GFX.h
- Adafruit_SSD1306.h
Após adicionar essas bibliotecas, crio funções para cada quadro de animação para cada expressão emocional (Acredite, leva uma eternidade). Na seção setup, inicializo o display. E na seção loop, faço leitura analógica do valor do sensor sensorValue = analogRead(A0); e então faço algumas condições para diferentes níveis de umidade e exibo os quadros para aquela expressão emocional.
Aqui estão alguns vídeos para diferentes expressões emocionais para diferentes níveis de umidade
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;
/****************************************** TRISTE ****************************************************/
// Arrays de frames para animação "triste" (frame01, frame011, frame21, frame31, frame41, frame51, frame61, frame71, frame81, frame91, frame101, frame111, frame121)
// ... (arrays de bytes omitidos por brevidade, mas incluídos no código original)
/************************************************* SORRISO *************************************************/
// Arrays de frames para animação "sorriso" (frame02, frame012, frame22, frame32, frame42, frame52, frame62, frame72, frame82, frame92, frame102, frame112, frame122, frame132)
// ... (arrays de bytes omitidos por brevidade)
/************************************** NEUTRO ***************************************************/
// Arrays de frames para animação "neutro" (frame03, frame013, frame23, frame33, frame43, frame53, frame63, frame73, frame83)
// ... (arrays de bytes omitidos por brevidade)
/*************************************** FELIZ/EXCITADO **************************************************************/
// Arrays de frames para animação "feliz" (frame04, frame14, frame24, frame34, frame44, frame54, frame64, frame74, frame84, frame94)
// ... (arrays de bytes omitidos por brevidade)
/**************************************************** CHORANDO ***********************************************/
// Arrays de frames para animação "chorando" (frame05, frame15, frame25, frame35, frame45, frame55, frame65, frame75, frame85, frame95)
// ... (arrays de bytes omitidos por brevidade)
// Confuso
const unsigned char PROGMEM framec[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFC,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x07, 0xE0, 0x00, 0x00, 0x0F,
0x00, 0x00, 0xF0, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x78, 0x00, 0x00, 0x1E, 0x00,
0x00, 0xE0, 0x10, 0x00, 0x07, 0x00, 0x01, 0xC1, 0xF8, 0x00, 0x03, 0x80, 0x03, 0x87, 0xF0, 0x00,
0x01, 0xC0, 0x03, 0x0F, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x1C, 0x00, 0x1E, 0x00, 0xE0, 0x0E, 0x38,
0x00, 0x0F, 0xC0, 0x70, 0x0C, 0x30, 0x00, 0x01, 0xFC, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x3C, 0x30,
0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x01, 0xC0, 0x03,
0x80, 0x18, 0x30, 0x03, 0xE0, 0x07, 0xC0, 0x0C, 0x30, 0x07, 0xE0, 0x07, 0xC0, 0x0C, 0x30, 0x07,
0xE0, 0x07, 0xE0, 0x0C, 0x30, 0x03, 0xE0, 0x07, 0xC0, 0x0C, 0x30, 0x01, 0xC0, 0x03, 0x80, 0x0C,
0x30, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x30, 0x00, 0x00, 0x00,
0x00, 0x0C, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x30,
0x0C, 0x00, 0x00, 0x7F, 0x80, 0x30, 0x0E, 0x00, 0x03, 0xFF, 0xC0, 0x60, 0x07, 0x00, 0xBF, 0x80,
0x80, 0xE0, 0x03, 0x01, 0xFE, 0x00, 0x00, 0xC0, 0x01, 0x80, 0x40, 0x00, 0x01, 0x80, 0x01, 0xC0,
0x00, 0x00, 0x03, 0x80, 0x00, 0xE0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x78, 0x00, 0x00, 0x1E, 0x00,
0x00, 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x03, 0xE0, 0x0F,
0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/********************************************************************************************************************************/
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setFont(&FreeSans9pt7b);
display.setTextColor(WHITE);
display.setCursor(0, 0);
}
void loop() {
sensorValue = analogRead(A0); // leitura analógica do sensor
if(sensorValue >= 80 && sensorValue < 250) { // sorriso
//display.clearDisplay();
//display.drawBitmap(xx, 0, frame02, 48, 48, 1);
//display.display();
delay(30);
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) { // feliz/excitado
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) { // neutro
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) { // triste
//display.clearDisplay();
//display.drawBitmap(xx, 0, frame01, 48, 48, 1);
//display.display();
delay(50);
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);
//display.clearDisplay();
//display.drawBitmap(xx, 0, frame131, 48, 48, 1);
//display.display();
//delay(50);
}
else if(sensorValue >= 700 && sensorValue < 800) { // chorando
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);
}
}
Peças Personalizadas e Caixas
Arquivos de design 3D disponíveis no repositório do projeto.
Esquemáticos

Processo de manufatura
- Usina Nuclear Susquehanna Conclui Manutenção Programada e Restaura Operação da Unidade 2
- Prevenir Acidentes com Empilhadeiras: Dicas Essenciais para Zero Tombamentos
- Tecnologia de Relógio Atômico Reduz Roubo de Encomendas em Entregas Online
- Detecção de Odor por IA: Tecnologia da Aryballe Revolucionando Negócios e Cadeias de Suprimentos
- Fatores Críticos Que Influenciam Custos de Fabricação CNC – Parte II
- 7 Indicadores-Chave de que é Hora de Atualizar seu Gerador
- Por Que Peças Usinadas Sob Medida Superam Peças de Fábrica em 4 Áreas-Chave
- 10 Projetos DIY Open-Source Inovadores Aproveitando a Impressão 3D
- Escavadeiras Explicadas: Tipos, Usos e Como Escolher a Certa para Seu Projeto
- Indústrias que Prosperam com Usinagem CNC de 5 Eixos: Aumente Eficiência e Precisão