Neste projeto divertido, você vai conectar um sensor de cor TCS3200D/TCS230 a um ESP32 e enviar as cores detectadas para um navegador web em tempo real. A página web tem um Minion animado e divertido, cuja cor da pele muda ao vivo conforme o que o sensor enxerga. Para simplificar a criação da interface web e o gerenciamento da comunicação WebSocket, este projeto usa a biblioteca DIYables ESP32 WebApps.
Veja um resumo do que acontece:
O ESP32 lê os dados de cor RGB do sensor TCS3200D/TCS230
Ele converte os valores RGB em um código de cor HEX (por exemplo, #FF8000)
O código HEX é enviado ao navegador web por WebSocket
Um Minion animado na página muda na hora a cor do corpo, dos braços e das pálpebras para combinar
Um passo a passo em vídeo também está disponível no final deste tutorial.
Divulgação: Alguns dos links desta seção são links de afiliado da Amazon. Podemos receber uma comissão pelas compras feitas por meio desses links, sem custo adicional para você. Agradecemos o seu apoio.
Pré-requisitos
Se você é iniciante no sensor de cor TCS3200D/TCS230 ou no DIYables ESP32 WebApps, estes tutoriais vão ajudar você a se atualizar:
O diagrama abaixo mostra como ligar o sensor de cor TCS3200 a um ESP32:
Sensor de Cor TCS3200
ESP32
VCC
5V (VIN)
GND
GND
S0
GPIO 17
S1
GPIO 16
S2
GPIO 18
S3
GPIO 5
OUT
GPIO 19
This image is created using Fritzing. Click to enlarge image
Se você não sabe como alimentar o ESP32 e outros componentes, veja as instruções no tutorial a seguir: Como alimentar o ESP32.
Como Funciona
Este é o fluxo passo a passo deste projeto:
A cada segundo, o ESP32 lê o sensor de cor alternando entre os filtros vermelho, verde e azul com os pinos de controle S2/S3 e medindo a largura de pulso no pino OUT.
Os valores brutos de largura de pulso são convertidos em valores RGB de 0 a 255 usando os dados de calibração (obtidos na etapa de calibração do sensor).
Os valores RGB são formatados em uma string de cor HEX, como #FF8000.
Essa string de cor é enviada a todos os navegadores conectados por WebSocket, por meio da biblioteca DIYables ESP32 WebApps.
Na página web, o JavaScript recebe a cor e a aplica na hora ao corpo, aos braços e às pálpebras do personagem Minion.
Código ESP32 - Aplicativo Web Minion com Sensor de Cor
Este projeto tem 4 arquivos:
ColorSensorESP32.ino - Sketch principal: inicializa o sensor, lê as cores e as envia para a página web
CustomWebApp.h - Arquivo de cabeçalho: declara a classe da página do aplicativo web personalizado
CustomWebApp.cpp - Arquivo de implementação: gerencia as mensagens WebSocket usando o identificador "Color sensor:"
custom_page_html.h - Página web: o Minion animado feito com HTML/CSS/JavaScript que reage às cores recebidas
ColorSensorESP32.ino
/* * Este código de ESP32 foi desenvolvido por pt.newbiely.com * Este código de ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/esp32/esp32-color-sensor-via-web*/#include <DIYables_ESP32_Platform.h>#include <DIYablesWebApps.h>#include"CustomWebApp.h"// CHANGE THESE TO YOUR WIFI DETAILSconstchar WIFI_SSID[] = "YOUR_WIFI_SSID";constchar WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";// Configure TCS3200 pins for ESP32constint S0 = 17;constint S1 = 16;constint S2 = 18;constint S3 = 5;constint sensorOut = 19;// Create server and pagesESP32ServerFactory serverFactory;DIYablesWebAppServerwebAppsServer(serverFactory, 80, 81);DIYablesHomePage homePage;CustomWebAppPage customPage;unsignedlong lastColorRead = 0;voidsetup() {Serial.begin(9600);delay(1000);Serial.println("Starting Custom WebApp...");// Initialize TCS3200 pinspinMode(S0, OUTPUT);pinMode(S1, OUTPUT);pinMode(S2, OUTPUT);pinMode(S3, OUTPUT);pinMode(sensorOut, INPUT);// Set frequency scaling to 20%digitalWrite(S0, HIGH);digitalWrite(S1, LOW);// Add pages to serverwebAppsServer.addApp(&homePage);webAppsServer.addApp(&customPage);// Start WiFi and web serverif (!webAppsServer.begin(WIFI_SSID, WIFI_PASSWORD)) {while (1) {Serial.println("Failed to connect to WiFi!");delay(1000); } }Serial.println("Custom WebApp ready!"); customPage.sendToWeb("Arduino is ready!");}voidloop() {// Handle web serverwebAppsServer.loop();// Send sensor data every 1 secondif (millis() - lastColorRead > 1000) {// Read Red colordigitalWrite(S2, LOW);digitalWrite(S3, LOW);int r = map(pulseIn(sensorOut, LOW), 31, 150, 255, 0);// Read Green colordigitalWrite(S2, HIGH);digitalWrite(S3, HIGH);int g = map(pulseIn(sensorOut, LOW), 35, 180, 255, 0);// Read Blue colordigitalWrite(S2, LOW);digitalWrite(S3, HIGH);int b = map(pulseIn(sensorOut, LOW), 30, 150, 255, 0);// Convert to HEX color and send to Webchar hexColor[8]; sprintf(hexColor, "#%02X%02X%02X", constrain(r, 0, 255), constrain(g, 0, 255), constrain(b, 0, 255)); customPage.sendToWeb(String(hexColor));Serial.println("Sent to Minion: " + String(hexColor)); lastColorRead = millis(); }}
CustomWebApp.h
/* * Este código de ESP32 foi desenvolvido por pt.newbiely.com * Este código de ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/esp32/esp32-color-sensor-via-web*/#ifndef CUSTOM_WEBAPP_H#define CUSTOM_WEBAPP_H#include <DIYablesWebApps.h>/** * Simple Custom WebApp Page * * This is a template for creating your own custom web applications. * It provides basic controls like buttons and sliders that communicate * with your Arduino in real-time. */class CustomWebAppPage : public DIYablesWebAppPageBase {private:// WebSocket message identifier for this custom appstaticconstString APP_IDENTIFIER;public: CustomWebAppPage();// ========================================// REQUIRED METHODS - USED BY LIBRARY - DON'T CHANGE THESE!// ========================================void handleHTTPRequest(IWebClient& client) override;void handleWebSocketMessage(IWebSocket& ws, const char* message, uint16_tlength) override;const char* getPageInfo() constoverride;String getNavigationInfo() constoverride;// ========================================// YOUR METHODS - USE THESE IN YOUR CODE!// ========================================void onCustomMessageReceived(void (*callback)(const String& payload));void sendToWeb(const String& message);};#endif
CustomWebApp.cpp
/* * Este código de ESP32 foi desenvolvido por pt.newbiely.com * Este código de ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/esp32/esp32-color-sensor-via-web*/#include"CustomWebApp.h"#include"custom_page_html.h"// Define the static member - WebSocket message identifier for this custom appconstString CustomWebAppPage::APP_IDENTIFIER = "Color sensor:";// Callback function for handling messages from web browservoid (*customMessageCallback)(const String& payload) = nullptr;CustomWebAppPage::CustomWebAppPage() : DIYablesWebAppPageBase("/custom") {}void CustomWebAppPage::handleHTTPRequest(IWebClient& client) {// Send the HTML page to web browser sendHTTPHeader(client); client.print(CUSTOM_PAGE_HTML);}void CustomWebAppPage::handleWebSocketMessage(IWebSocket& ws, const char* message, uint16_tlength) {String messageStr = String(message, length);Serial.print("Color sensor WebApp received: ");Serial.println(messageStr);// Only handle messages that start with our app identifierif (messageStr.startsWith(APP_IDENTIFIER)) {String payload = messageStr.substring(APP_IDENTIFIER.length()); // Remove identifier// Call your callback function with the payloadif (customMessageCallback) { customMessageCallback(payload); } }}void CustomWebAppPage::onCustomMessageReceived(void (*callback)(const String& payload)) { customMessageCallback = callback;}void CustomWebAppPage::sendToWeb(const String& message) {// Send message to web browser with app identifierString fullMessage = APP_IDENTIFIER + message; broadcastToAllClients(fullMessage.c_str());}const char* CustomWebAppPage::getPageInfo() const {return"🔧 Color sensor WebApp";}String CustomWebAppPage::getNavigationInfo() const {String result = "<a href=\""; result += getPagePath(); result += "\" class=\"app-card custom\" style=\"background: linear-gradient(135deg, #007bff 0%, #0056b3 100%);\">"; result += "<h3>🔧 Color sensor WebApp</h3>"; result += "<p>Simple template for your own apps</p>"; result += "</a>";return result;}
Troque os valores de calibração nas chamadas de map() dentro de loop() pelos números que você anotou durante a calibração. Por exemplo, se a sua calibração deu redMin = 42, redMax = 210, greenMin = 55, greenMax = 185, blueMin = 60, blueMax = 172, atualize as linhas para:
int r = map(pulseIn(sensorOut, LOW), 42, 210, 255, 0);int g = map(pulseIn(sensorOut, LOW), 55, 185, 255, 0);int b = map(pulseIn(sensorOut, LOW), 60, 172, 255, 0);
Clique no botão Upload para gravar o código no ESP32.
Abra o Serial Monitor. Você deve ver algo assim:
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
Starting Custom WebApp...
Custom WebApp ready!
INFO: Added app /
INFO: Added app /custom
DIYables ESP32 WebApp Library
Network connected!
IP address: 192.168.0.5
HTTP server started on port 80
WebSocket server started on port 81
==========================================
DIYables WebApp Ready!
==========================================
📱 Web Interface: http://192.168.0.5
🔗 WebSocket: ws://192.168.0.5:81
📋 Available Applications:
🏠 Home Page: http://192.168.0.5/
🔧 Color sensor WebApp: http://192.168.0.5/custom
==========================================
Sent to Minion: #FFD200
Sent to Minion: #00C832
Sent to Minion: #0028FF
Ln 11, Col 1
ESP32 Dev Module on COM15
2
Se nada aparecer, tente apertar o botão de reset do ESP32.
Copie o endereço IP mostrado no Serial Monitor e abra-o em um navegador web no seu celular ou computador.
Por exemplo: http://192.168.0.5
Na página inicial, toque no cartão Color sensor WebApp para abrir a página do Minion.
Ou, se preferir, vá direto para http://[IP_ADDRESS]/custom.
Você verá o Minion animado e sorridente na sua tela.
Segure um objeto colorido perto do sensor TCS3200 — a cor da pele do Minion vai mudar na hora para refletir a cor detectada!
Você pode seguir o guia passo a passo em vídeo abaixo.
Entendendo o Código
Lado do ESP32 (ColorSensorESP32.ino)
O sketch principal faz estas tarefas:
Configura o sensor TCS3200: Configura S0/S1 para escala de frequência de 20% e prepara S2/S3 para a seleção do filtro.
Lê a cor uma vez por segundo: Dentro de loop(), o ESP32 percorre os filtros de cor vermelho, verde e azul, mede a largura de pulso com pulseIn() e converte cada leitura em um valor de 0 a 255 usando map() com os seus dados de calibração.
Formata como HEX: Os três valores RGB são combinados em uma string HEX (por exemplo, #FF8000) usando sprintf() e constrain().
Envia aos navegadores: A cor HEX é transmitida a todos os clientes web conectados por meio de customPage.sendToWeb().
Lado da Página Web (custom_page_html.h)
O arquivo HTML contém:
Um Minion animado só com CSS: O personagem tem olhos que piscam, uma boca rindo com a língua balançando e pupilas que se movem de forma aleatória — tudo com animações CSS e um pequeno intervalo em JavaScript.
Ouvinte de WebSocket: O JavaScript abre uma conexão persistente com o servidor WebSocket do ESP32 na porta 81 e processa as mensagens de cor recebidas.
Aplicação da cor ao vivo: Cada cor HEX recebida é aplicada suavemente ao corpo, aos braços e às pálpebras do Minion, usando uma transition do CSS para um efeito visual fluido.
Reconexão automática: Se o WebSocket se desconectar, a página tenta reconectar a cada 2 segundos, sem precisar de ação do usuário.
Layout responsivo: O Minion se ajusta automaticamente a qualquer tamanho de tela, de celulares a desktops.
Protocolo de Mensagens
Este projeto segue o framework de aplicativos personalizados do DIYables ESP32 WebApps. As mensagens são marcadas com o identificador "Color sensor:":
O ESP32 envia: Color sensor:#FF8000 (prefixo identificador + valor de cor HEX)
O navegador recebe: O JavaScript remove o prefixo Color sensor: e aplica o restante #FF8000 ao Minion
Fique à vontade para compartilhar o link deste tutorial. Porém, por favor, não use nosso conteúdo em outros sites. Investimos muito esforço e tempo para criar este conteúdo, por favor respeite nosso trabalho!