Autor: Oscar Gonzalez
Tiempo de lectura: 2 minutos
Simple lámpara RGB impresa en 3D controlada con ESP8266
Si te gusta imprimir en 3D y te gustan los proyectos con LEDS, estás en el sitio adecuado!
Ésta es una simple lámpara RGB controlada con ESP8266 que permite establecer el color que quieras y también tiene algunos efectos de luz pre establecidos.
El cuerpo está impreso en 3D y se imprime sin soportes.
Si te gusta éste tipo de proyectos y la electrónica, tenemos una lista de correo donde comparto muchos trucos e historias que estoy seguro que te gustarán.
Con tan solo apuntarte a la lista, podrás acceder al enlace para descargar los archivos STL de la lámpara y además entrarás a formar parte de la comunidad de cientos de personas que cada día se divierten y aprenden en nuestra lista.
Lo pasaremos bien, ¡te lo aseguro!
La lámpara necesita de muy poco para funcionar y aquí abajo encontrarás la lista de componentes que necesitas.
Recuerda que la lámpara necesita una alimentación externa de 5V de al menos 2A para funcionar. De 1A tambien puede valer, pero siempre es mejor que sobre un poco.
Placa NodeMCU Wifi para desarrollo IoT basada en ESP8266 / CH340G
3,95€
Tira de LED RGB indexable de alta densidad con chip SK6812 resistente al agua
31,95€
Bobina de filamento PLA INGEO 850 de 1.75 mm de alta calidad. Sakata 3D
17,60€
Bobina de filamento PLA INGEO 850 de 1.75 mm de alta calidad. Sakata 3D
17,60€
El código fuente es muy sencillo y está basado en el típico ejemplo de Webserver de Arduino. Lo que hace es generar una página web que permite mediante unos sliders establecer el color que quieras.
Ten en cuenta que la lámpara debe estar conectada a tu red wifi primero para que funcione.
Utilicé un pequeño truco ya que aprovechando la conexión a Internet, el código genera una página web utilizando Bootstrap (un conjunto de CSS) para hacerla un poco más atractiva.
Tanto Bootstrap como alguna librería de Javascript la pilla de una CDN para ahorrar espacio de memoria. Eso quiere decir que para que todo funcione, imperativamente la lámpara debe tener conexión a Internet.
El control se realiza mediante llamadas asíncronas (AJAX) para que sea lo más responsiva posible. La página web se acopla a diferentes resoluciones de pantalla en función del dispositivo que utilices.
El código está embebido directamente en el código y ocupa entorno a 3kb de memoria. Por lo que si haces alguna modificación, hay que prestar atención de no pasarse mucho para no saturar la memoria.
El código lo puedes encontrar al completo aquí abajo y verás que es muy sencillo. Necesitarás tener instaladas éstas librerías:
Si no tienes claro cómo hacerlo, no te pierdas mi tutorial sobre cómo instalar librerías en Arduino donde te lo explico todo.
/*************************************************************
NodeLamp
Oscar Gonzalez - Abril 2020
www.BricoGeek.com
*************************************************************/
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <FastLED.h>
#define NUM_LEDS 72
#define DATA_PIN 4
CRGB leds[NUM_LEDS];
ESP8266WebServer server ( 80 );
int current_mode = 0;
int color_red=0;
int color_green=0;
int color_blue=0;
uint8_t gHue = 0; // rotating "base color" used by many of the patterns
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YOU_WIFI_SSID";
char pass[] = "MEGA_SECRET_PASSWORD";
void handleRoot() {
char temp[2900];
int sec = millis() / 1000;
int min = sec / 60;
int hr = min / 60;
snprintf ( temp, 2900,
"<html lang="en">
<head>
<meta charset="utf-8">
<title>NodeHuePlay Lamp</title>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<link href="http://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<script src="http://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"crossorigin="anonymous"></script>
<style>
body { text-align:center; background-color: #fff; font-family: Arial, Helvetica, Sans-Serif; Color: #000; }
.slidecontainer{width:100%%}.slider{-webkit-appearance:none;width:100%%;height:13%%;background:#d3d3d3;outline:0;opacity:.7;-webkit-transition:.2s;transition:opacity .2s}.slider:hover{opacity:1}.slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:10%%;height:100%%;background:#4caf50;cursor:pointer}.slider::-moz-range-thumb{width:65px;height:65px;background:#4caf50;cursor:pointer}
</style>
</head>
<body>
<div class="container text-center">
<h1 class="display-1"id="t">NodeHuePlay Lamp</h1>
<h2>www.BricoGeek.com</h2>
<div class="slidecontainer">
<p><input type="range" min="0" max="254" value="%02d" class="slider" id="slider_r"></p>
<p><input type="range" min="0" max="254" value="%02d" class="slider" id="slider_g"></p>
<p><input type="range" min="0" max="254" value="%02d" class="slider" id="slider_b"></p>
<p><span id="rgbvalue"></span></p>
</div>
<a onClick="return setmode(0);" href="#" class="btn btn-warning btn-lg btn-block">Manual RGB</a> <a onClick="return setmode(1);" href="#" class="btn btn-primary btn-lg btn-block">Random</a> <a onClick="return setmode(2);" href="#" class="btn btn-success btn-lg btn-block">Rainbow</a> <a onClick="return setmode(3);" href="#" class="btn btn-info btn-lg btn-block">Lava</a>
</div>
<script>
var r=0;var g=0;var b=0;
$('#slider_r').on('touchend', function(){
r = $(this).val();$.ajax({url: '/set/?r=' r '&g=' g '&b=' b, success: function(result){upd(r, g, b);}});
});
$('#slider_g').on('touchend', function(){
g = $(this).val();$.ajax({url: '/set/?r=' r '&g=' g '&b=' b, success: function(result){upd(r, g, b);}});
});
$('#slider_b').on('touchend', function(){
b = $(this).val();$.ajax({url: '/set/?r=' r '&g=' g '&b=' b, success: function(result){upd(r, g, b);}});
});
function setmode(n) { $.ajax({url: '/set/?mode=' n, success: function(result){ }}); return false; }
function upd(r, g, b) { $('#rgbvalue').html('RED: ' r ' GREEN: ' g ' BLUE: ' b); $('#t').css('background', 'rgb(' r ',' g ',' b ')'); };
</script>
</body>
</html>",
color_red, color_green, color_blue
);
server.send ( 200, "text/html", temp );
}
void handleNotFound() {
String message = "File Not Foundnn";
message = "URI: ";
message = server.uri();
message = "nMethod: ";
message = ( server.method() == HTTP_GET ) ? "GET" : "POST";
message = "nArguments: ";
message = server.args();
message = "n";
for ( uint8_t i = 0; i < server.args(); i ) {
message = " " server.argName ( i ) ": " server.arg ( i ) "n";
}
server.send ( 404, "text/plain", message );
}
void clearLeds()
{
for (int i=0 ; i<NUM_LEDS ; i ) { leds[i] = CRGB::Black; }
FastLED.show();
}
void setFullColor(int r, int g, int b)
{
for (int i=0 ; i<NUM_LEDS ; i ) { leds[i] = CRGB(r,g,b); }
FastLED.show();
}
void setup()
{
// Debug console
Serial.begin(9600);
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
clearLeds();
//leds[3] = CRGB(0,255,0);
FastLED.show();
delay(50);
// Start Wifi
WiFi.mode ( WIFI_STA );
WiFi.begin ( ssid, pass );
Serial.println ( "" );
// Wait for connection
int nled = 0;
while ( WiFi.status() != WL_CONNECTED ) {
leds[nled] = CRGB(0,255,0);
FastLED.show();
Serial.print ( "." );
delay ( 10 );
nled ;
if (nled > NUM_LEDS) { nled=0; }
}
clearLeds();
FastLED.show();
Serial.println ( "" );
Serial.print ( "Connected to " );
Serial.println ( ssid );
Serial.print ( "IP address: " );
Serial.println ( WiFi.localIP() );
if ( MDNS.begin ( "nodehuelamp" ) ) {
Serial.println ( "MDNS responder started" );
}
// Start Webserver
server.on ( "/", handleRoot );
// Update LED colors
server.on ( "/set/", []() {
Serial.println("* SET");
String message = "Number of args received:";
message = server.args();
for (int i = 0; i < server.args(); i ) {
if (server.argName(i) == "r") { color_red = server.arg(i).toInt(); current_mode=0; }
if (server.argName(i) == "g") { color_green = server.arg(i).toInt(); current_mode=0; }
if (server.argName(i) == "b") { color_blue = server.arg(i).toInt(); current_mode=0; }
if (server.argName(i) == "mode") { current_mode = server.arg(i).toInt(); }
}
Serial.print("MODE: ");
Serial.println(current_mode);
server.send ( 200, "text/plain", message );
setFullColor(color_red, color_green, color_blue);
} );
server.onNotFound ( handleNotFound );
server.begin();
Serial.println ( "HTTP server started" );
}
void loop()
{
server.handleClient();
int pos=0;
switch (current_mode)
{
case 0: // Manual RGB
setFullColor(color_red, color_green, color_blue);
break;
case 1: // Random
// random colored speckles that blink in and fade smoothly
fadeToBlackBy( leds, NUM_LEDS, 10);
pos = random16(NUM_LEDS);
leds[pos] = CHSV( gHue random8(64), 200, 255);
break;
case 2: // Rainbow
EVERY_N_MILLISECONDS( 20 ) { gHue ; }
fill_rainbow( leds, NUM_LEDS, gHue, 7);
break;
case 3: // Lava
// a colored dot sweeping back and forth, with fading trails
fadeToBlackBy( leds, NUM_LEDS, 20);
pos = beatsin16( 13, 0, NUM_LEDS-1 );
leds[pos] = CHSV( gHue, 255, 192);
break;
}
// Update leds
FastLED.show();
FastLED.delay(1000 / 100); // 100 Hz
}
Si te ha gustado el proyecto y montas una, no dudes en enviarnos unas fotos!