Ho costruito una riproduzione del reattore arc come un dispositivo compatibile Alexa.
Il cuore di tutto è l’anello a led WS2812 che viene controllato attraverso un Wemos D1 mini lite ESP8266, il quale si collega alla rete wifi domestica eseguendo i comandi pronunciati per Alexa. Non servono account e servizi in cloud!
Qui sotto potete vedere il video che ho pubblicato sul mio canale youtube.
Veniamo al dunque e scopriamo come poterlo realizzare. Ecco la lista della spesa:
- Wemos ESP8266: https://amzn.to/2Y1C1oK
- Anello Led WS2812: https://amzn.to/3bZJRYe
- Kit saldatore: https://amzn.to/3bSHBlo
- Stampante Anicubic i3 Mega: https://amzn.to/3sIH1wy
- Pla Fluorescente: https://amzn.to/3sK5zW4
- Pla Silver: https://amzn.to/2KyRDwF
- Alexa Echo Dot: https://amzn.to/39M8ZPg
In qualità di Affiliato Amazon io ricevo un guadagno dagli acquisti idonei. A voi non costerà nulla di più e avrete modo di supportare il mio lavoro.
L’elettronica
Qui sotto lo schema elettrico:

Per questo progetto non ho saldato lo zoccolo sulla scheda Wemos, questo per ridurre al minimo gli ingombri.
Lo schema è molto semplice, ho saldato il pin D4 del wemos al pin D0 dell’anello, D3 alla resistenza che va all’anodo del diodo led, il suo cadoto al GND.

La struttura
Cercando sempre sul mio portale preferito, ho trovato il progetto 3D del reattore che faceva a caso mio, ed ho effettuato le stampe dei pezzi.
Ho postato la stampa del reattore Arc anche su thingiverse.
Ho usato stucco spray riempitivo come fondo per tutti i pezzi, successivamente strati sottili di vernice spray argento e oro.
L’anello che contiene i led non deve essere ricoperto altrimenti la luce non si potrebbe diffondere!



Il software
Il progetto dell’utente mdegrazia comprende l’uso di un’altra scheda, di due cerchi a led e non comprende l’integrazione con Alexa.
Ho ignorato il suo codice e ho preferito dedicarmi alla creazione di uno nuovo che vedremo tra poco.
In questo mio articolo avevo già spiegato come Alexa poteva riconoscere il Wemos D1 mini esp8266 come un normale dispositivo compatibile grazie l’utilizzo della libreria fauxmoESP. Rispetto a quell’articolo bisogna solamente avere l’accortezza di usare l’ultima versione della libreria che ad oggi è la 3.4 del 03/04/2021.
Possiamo creare un progetto compatibile con Alexa velocemente e senza spendere altri soldi per servizi di terze parti.
Per la stesura dello sketch mi sono basato rispettivamente su due codici di esempio:
- “fauxmoESP_External_Server” per la comunicazione con Alexa
- “Adafruit NeoPixel” per la gestione dell’anello a led WS2812
creando poi uno nuovo sketch con tutte le funzioni necessarie.
Qui vi riporto i punti di maggiore interesse:
- Inserire i dati della vostra rete domestica in:
#define WIFI_SSID "NomeVostraReteWifi"
#define WIFI_PASS "PasswordVostraReteWifi"
- Inserire il nome del device che verrà poi utilizzato da Alexa (l’ho chiamato reattore nel mio caso)
fauxmo.addDevice("reattoreVerde");
fauxmo.addDevice("reattoreRosso");
fauxmo.addDevice("reattore");
fauxmo.addDevice("reattoreBianco");
- I parametri del colore con cui la striscia si dovrà illuminare (0,0,127 è blu)
accendi(strip.Color( 0, 0, 127), 50);
Dopo la realizzazione del video su youtube ho modificato il codice dello sketch in modo da poter scegliere quale colore far assumere al reattore.
Per questo ho creato altri device “virtuali” chiamandoli “reattoreVerde, reattoreRosso, reattoreBianco” i quali accenderanno la striscia a led con il relativo colore. Questo programma vi potrà essere utile come base anche per altri progetti: la stessa scheda può essere chiamata con diversi nomi di device che hanno funzioni differenti.
Qui sotto vi metto il codice dello sketch, per poterlo incollare sull’ide di arduino, qui trovate una guida su come configurarlo
https://www.lutritech.it/come-programmare-esp8266-con-lide-di-arduino/
Vi darà errore: levate il commento per le righe del WIFI_SSID e WIFI_PASS per inserire i vostri dati.
Lo sketch
//Visita il mio sito web: www.lutritech.it
//il video di questo progetto https://youtu.be/njgMLa4FpM8
#include <Arduino.h>
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#elif defined(ESP32)
#include <WiFi.h>
#endif
#include <ESPAsyncWebServer.h>
#include "fauxmoESP.h"
#include <Adafruit_NeoPixel.h>
//inserisci le credenziali della rete wifi
//#define WIFI_SSID "NomeVostraReteWifi"
//#define WIFI_PASS "PasswordVostraReteWifi"
fauxmoESP fauxmo;
AsyncWebServer server(80);
// -----------------------------------------------------------------------------
#define SERIAL_BAUDRATE 115200
#define centralLed D3 //pin per led centrale
//declare switching pins
#define RGBCTL D4 //pin di controllo anello led
int numPixels = 24;
int i; // i=1 verde, i=2 rosso, i=3 blu, i=4 bianco
int brightness = 5;
// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(numPixels, RGBCTL, NEO_GRB + NEO_KHZ800);
// -----------------------------------------------------------------------------
// Wifi
// -----------------------------------------------------------------------------
void wifiSetup()
{
// Set WIFI module to STA mode
WiFi.mode(WIFI_STA);
// Connect
Serial.printf("[WIFI] Connecting to %s ", WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASS);
// Wait
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(100);
}
Serial.println();
// Connected!
Serial.printf("[WIFI] STATION Mode, SSID: %s, IP address: %s\n", WiFi.SSID().c_str(), WiFi.localIP().toString().c_str());
}
void serverSetup()
{
// Custom entry point (not required by the library, here just as an example)
server.on("/index.html", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send(200, "text/plain", "Hello, world");
});
// These two callbacks are required for gen1 and gen3 compatibility
server.onRequestBody([](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) {
if (fauxmo.process(request->client(), request->method() == HTTP_GET, request->url(), String((char *)data))) return;
// Handle any other body request here...
});
server.onNotFound([](AsyncWebServerRequest * request) {
String body = (request->hasParam("body", true)) ? request->getParam("body", true)->value() : String();
if (fauxmo.process(request->client(), request->method() == HTTP_GET, request->url(), body)) return;
// Handle not found request here...
});
// Start the server
server.begin();
}
void setup()
{
// Init serial port and clean garbage
Serial.begin(SERIAL_BAUDRATE);
Serial.println();
Serial.println();
pinMode(LED_BUILTIN, OUTPUT);
pinMode(centralLed, OUTPUT);
// Wifi
wifiSetup();
// Web server
serverSetup();
// Set fauxmoESP to not create an internal TCP server and redirect requests to the server on the defined port
// The TCP port must be 80 for gen3 devices (default is 1901)
// This has to be done before the call to enable()
fauxmo.createServer(false);
fauxmo.setPort(80); // This is required for gen3 devices
// You have to call enable(true) once you have a WiFi connection
// You can enable or disable the library at any moment
// Disabling it will prevent the devices from being discovered and switched
fauxmo.enable(true);
// You can use different ways to invoke alexa to modify the devices state:
// "Alexa, turn kitchen on" ("kitchen" is the name of the first device below)
// "Alexa, turn on kitchen"
// "Alexa, set kitchen to fifty" (50 means 50% of brightness)
// Add virtual devices
fauxmo.addDevice("reattoreVerde");
fauxmo.addDevice("reattoreRosso");
fauxmo.addDevice("reattore");
fauxmo.addDevice("reattoreBianco");
strip.begin();
strip.show();
strip.setBrightness(5);
i = 0;
digitalWrite(LED_BUILTIN, HIGH); //spengo il led di bordo
// You can add more devices
//fauxmo.addDevice("light 3");
fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) {
// Callback when a command from Alexa is received.
// You can use device_id or device_name to choose the element to perform an action onto (relay, LED,...)
// State is a boolean (ON/OFF) and value a number from 0 to 255 (if you say "set kitchen light to 50%" you will receive a 128 here).
// Just remember not to delay too much here, this is a callback, exit as soon as possible.
// If you have to do something more involved here set a flag and process it in your main loop.
// if (0 == device_id) digitalWrite(RELAY1_PIN, state);
// if (1 == device_id) digitalWrite(RELAY2_PIN, state);
// if (2 == device_id) analogWrite(LED1_PIN, value);
Serial.printf("[MAIN] Device #%d (%s) state: %s value: %d\n", device_id, device_name, state ? "ON" : "OFF", value);
// For the example we are turning the same LED on and off regardless fo the device triggered or the value
//------------------------------------------------------------------------------
//Switching action on detection of device name
//------------------------------------------------------------------------------
if ( (strcmp(device_name, "reattoreVerde") == 0) ) {
Serial.println("Hai detto reattoreVerde");
if (state) {
i = 1;
brightness = value;
Serial.println("Alexa mi passa come brightness:");
Serial.println(brightness);
}
else {
allOff();
i = 0;
}
}
if ( (strcmp(device_name, "reattoreRosso") == 0) ) {
Serial.println("Hai detto reattoreRosso");
if (state) {
i = 2;
brightness = value;
Serial.println("Alexa mi passa come brightness:");
Serial.println(brightness);
}
else {
allOff();
i = 0;
}
}
if ( (strcmp(device_name, "reattore") == 0) ) {
Serial.println("Hai detto reattore");
if (state) {
i = 3;
brightness = value;
Serial.println("Alexa mi passa come brightness:");
Serial.println(brightness);
}
else {
allOff();
i = 0;
}
}
if ( (strcmp(device_name, "reattoreBianco") == 0) ) {
Serial.println("Hai detto reattoreBianco");
if (state) {
i = 4;
brightness = value;
Serial.println("Alexa mi passa come brightness:");
Serial.println(brightness);
}
else {
allOff();
i = 0;
}
}
});
}
void loop() {
// fauxmoESP uses an async TCP server but a sync UDP server
// Therefore, we have to manually poll for UDP packets
fauxmo.handle();
startShow(i);
// This is a sample code to output free heap every 5 seconds
// This is a cheap way to detect memory leaks
static unsigned long last = millis();
if (millis() - last > 5000) {
last = millis();
//Serial.printf("[MAIN] Free heap: %d bytes\n", ESP.getFreeHeap());
ESP.getFreeHeap();
}
}
//Case per i colori da utilizzare
void startShow(int i)
{
switch (i)
{
case 0: colorWipe(strip.Color(0, 0, 0), 50); // spento
Serial.println("son spento");
break;
case 1: colorWipe(strip.Color(0, 255, 0), 50); // verde
Serial.println("son verde");
break;
case 2: colorWipe(strip.Color(255, 0, 0), 50); // rosso
Serial.println("son rosso");
break;
case 3: accendi(strip.Color( 0, 0, 127), 50); // blu
Serial.println("son blu");
break;
case 4: colorWipe(strip.Color(255, 255, 255), 50); // bianco
Serial.println("son bianco");
break;
}
}
// accendi reattore
void accendi(uint32_t c, uint8_t wait)
{
if (brightness > 254) brightness = 254;
analogWrite(centralLed, brightness);
//Serial.println("Passo alla striscia come brightness:");
//Serial.println(brightness);
strip.setBrightness(brightness);
for (uint16_t i = 0; i < strip.numPixels(); i++)
{
strip.setPixelColor(i, c);
strip.show();
//delay(wait);
}
}
// accendi un led alla volta
void colorWipe(uint32_t c, uint8_t wait)
{
if (brightness > 254) brightness = 254;
strip.setBrightness(brightness);
for (uint16_t i = 0; i < strip.numPixels(); i++)
{
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
//spegni tutti i led
void allOff()
{
for ( int i = 0; i < numPixels; i++ )
{
strip.setPixelColor(i, 0, 0, 0 );
}
strip.show();
analogWrite(centralLed, 0);
}
Siamo arrivati fine della guida, hai visto come ho costruito il reattore compatibile con Alexa.
Qui sotto puoi vedere un paio di foto del lavoro finito:

