Ceci est une ancienne révision du document !
Lampe géodésique pilotable avec le WIFI de votre mobile !
L'idée de départ est de réutiliser une ampoule cassée pour en faire une lampe en utilisant des LEDs. On trouve facilement des exemples d'ampoules de ce type dans le commerce !
Je récupère une ampoule cassée et je découpe le culot. J'ajoute des LEDs bleues à l'intérieur.
Je calcule les dimensions d'une structure géodésique en barreau de bois avec le site internet https://www.simplydifferently.org/Geodesic_Dome_Notes?page=3#2V/L2%20Icosahedron%20Dome
Pour le socle, je m'inspire de la montagne du destin (Mount Doom) décrite dans le roman le Seigneur des Anneaux de J. R. R. Tolkien (Sauron forge l'anneau unique dans les flammes de la montagne de feux, au Mordor ). Dans la trilogie cinématographique de Peter Jackson adaptée du Seigneur des Anneaux, le mont Ngauruhoe, un volcan de Nouvelle-Zélande, est choisi pour représenter la montagne du destin.
J'utilise ce tutoriel pour créer le socle de la lampe : https://johnflower.org/tutorial/make-mountains-blender-heightmaps et je découpe cette simulation 3D en tranche comme ce que j'ai déjà utilisé dans d'autres projet (T-REX Ball).
Et je modélise un culot pour assembler le tout !
Voici la simulation de l'assemblage sur Blender !
Intégration de la partie électrique dans le socle de la lampe !
Récupération d'une ampoule cassée et découpage du culot https://www.youtube.com/watch?v=KHANh7x2XtM.
Découpe à la découpeuse laser du socle .
Découpe à la découpeuse laser des barres géodésiques .
Impression 3D du culot culot.stl
Coller l'ampoule au culot en PLA !
Assembler le tout avec 5 vis M4 dans le culot, 8 vis et 8 écrous M4 pour le socle (méthode “Sandwich” superposition de couche).
S’équiper d'un circuit ESP8266 (https://fr.aliexpress.com/item/32779189539.html) et de guirlande LED (https://fr.aliexpress.com/item/32799804772.html)
Voici un tuto pour comprendre les grandes lignes de la programmation de l'ESP8266 : https://f-leb.developpez.com/tutoriels/arduino/esp8266/debuter/
Le programme pour ce projet :
progng-20220805-vitrinecn2.ino
// Program for "LampeNG" made by Go2 on 2022/08/05 // Load Wi-Fi library #include <ESP8266WiFi.h> // Set web server port number to 80 WiFiServer server(80); // Variable to store the HTTP request String header; // Auxiliar variables to store the current output state String ONOFFState = "ON"; String GlittersState = "ON"; String FadeState = "OFF"; String GlittersSpeed = "2"; String FadeSpeed = "1"; int TimeTempo = 30; int count = 0; int brightness1 = 0; // how bright the LED is int brightness2 = 0; // how bright the LED is int brightness3 = 0; // how bright the LED is int brightness4 = 0; // how bright the LED is int fadeAmount1 = 10; // Set the amount to fade I usually do 5, 10, 15, 20, 25 etc even up to 255. int fadeAmount2 = 20; // how many points to fade the LED by int fadeAmount3 = 30; // how many points to fade the LED by int fadeAmount4 = 40; // how many points to fade the LED by static unsigned long lastTimeItHappened = 0; void setup() { Serial.begin(115200); // Initialize the output variables as outputs pinMode(D5, OUTPUT); // Initialize the D5 pin as an output pinMode(D6, OUTPUT); // Initialize the D6 pin as an output pinMode(D7, OUTPUT); // Initialize the D7 pin as an output pinMode(D8, OUTPUT); // Initialize the D8 pin as an output delay(2000); // 2 second delay for recovery // WIFI ACCESS POINT // ================= WiFi.mode(WIFI_AP); //Our ESP8266-12E is an AccessPoint WiFi.softAP("Go2design"); // Provide the SSID server.begin(); // Start the HTTP Server IPAddress HTTPS_ServerIP= WiFi.softAPIP(); // Obtain the IP of the Server Serial.print("Server IP is: "); // 192.168.4.1 Serial.println(HTTPS_ServerIP); } void loop(){ WiFiClient client = server.available(); // Listen for incoming clients // Call the current pattern function once, updating the 'leds' array if (millis() - lastTimeItHappened >= 1000) { // Ten seconds or more since it last happened lastTimeItHappened = millis(); count++; } if (count >= 115) // Reinit every 2mn (115 for execution of program) { ONOFFState = "ON"; GlittersState = "ON"; FadeState = "OFF"; TimeTempo = 30; count = 0; } if (count >= 1000) {count = 1;} // Reinit for limit of variable if (GlittersState == "ON") {Glitters(TimeTempo);} if (FadeState == "ON") {Fade(TimeTempo);} if (client) { // If a new client connects, Serial.println("New Client."); // print a message out in the serial port String currentLine = ""; // make a String to hold incoming data from the client while (client.connected()) { // loop while the client's connected if (client.available()) { // if there's bytes to read from the client, char c = client.read(); // read a byte, then Serial.write(c); // print it out the serial monitor header += c; if (c == '\n') { // if the byte is a newline character // if the current line is blank, you got two newline characters in a row. // that's the end of the client HTTP request, so send a response: if (currentLine.length() == 0) { // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) // and a content-type so the client knows what's coming, then a blank line: client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println("Connection: close"); client.println(); count = 0 ; // turns the variable // push on MARCHE adress is ONOFF/off if (header.indexOf("GET /ONOFF/off") >= 0) { Serial.println("ONOFF off"); ONOFFState = "OFF"; GlittersState = "ON"; FadeState = "ON"; TimeTempo = 0; } else if (header.indexOf("GET /ONOFF/on") >= 0) { Serial.println("ONOFF on"); ONOFFState = "ON"; GlittersState = "ON"; FadeState = "OFF"; TimeTempo = 30; } else if (header.indexOf("GET /Glitters/on") >= 0) { Serial.println("Glitters on"); GlittersState = "OFF"; FadeState = "OFF"; TimeTempo = 0; } else if (header.indexOf("GET /Glitters/1") >= 0) { Serial.println("Glitters 1"); GlittersSpeed = "1"; TimeTempo = 10; } else if (header.indexOf("GET /Glitters/2") >= 0) { Serial.println("Glitters 2"); GlittersSpeed = "2"; TimeTempo = 30; } else if (header.indexOf("GET /Glitters/3") >= 0) { Serial.println("Glitters 3"); GlittersSpeed = "3"; TimeTempo = 60; } else if (header.indexOf("GET /Glitters/4") >= 0) { Serial.println("Glitters 4"); GlittersSpeed = "4"; TimeTempo = 90; } else if (header.indexOf("GET /Glitters/off") >= 0) { Serial.println("Glitter off"); ONOFFState = "ON"; GlittersState = "ON"; FadeState = "OFF"; GlittersSpeed = "2"; TimeTempo = 30; } else if (header.indexOf("GET /Fade/on") >= 0) { Serial.println("Fade on"); GlittersState = "OFF"; FadeState = "OFF"; Glitters(0); } else if (header.indexOf("GET /Fade/1") >= 0) { Serial.println("Fade 1"); FadeSpeed = "1"; TimeTempo = 30; } else if (header.indexOf("GET /Fade/2") >= 0) { Serial.println("Fade 2"); FadeSpeed = "2"; TimeTempo = 60; } else if (header.indexOf("GET /Fade/3") >= 0) { Serial.println("Fade 3"); FadeSpeed = "3"; TimeTempo = 90; } else if (header.indexOf("GET /Fade/off") >= 0) { Serial.println("Fade off"); ONOFFState = "ON"; GlittersState = "OFF"; FadeState = "ON"; FadeSpeed = "1"; TimeTempo = 30; } // Display the HTML web page client.println("<!DOCTYPE html><html>"); client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"); client.println("<link rel=\"icon\" href=\"data:,\">"); // CSS to style the on/off buttons // Feel free to change the background-color and font-size attributes to fit your preferences client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}"); client.println("body {background-color: darkblue;}"); client.println("h1 {font-family: Georgia, serif; color: white;}"); client.println("p {text-shadow: 1px 1px Gray; color: white;}"); client.println(".buttonON { background-color: #0B610B; border: none; color: white; padding: 16px 40px; border-radius: 8px; box-shadow: 0 4px 12px 0 rgba(0,0,0,1), 0 4px 20px 0 rgba(0,0,0,0.19); text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer; text-shadow: #000444}"); client.println(".buttonOFF { background-color: #B40404; border: none; color: white; padding: 16px 40px; border-radius: 8px; box-shadow: 0 4px 12px 0 rgba(0,0,0,1), 0 4px 20px 0 rgba(0,0,0,0.19); text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer; text-shadow: #000444;}"); client.println(".buttonGlitters { background-image: linear-gradient(90deg, grey 0%, white 15%, grey 30%, white 45%, grey 60%, white 75%, grey 90%, white 100%); border: none; color: black; padding: 15px 32px; border-radius: 8px; box-shadow: 0 2px 8px 0 rgba(0,0,0,1), 0 4px 20px 0 rgba(0,0,0,0.19); font-family: Times, Times New Roman, serif; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}"); client.println(".buttonGlittersoff { background-color: #000000; border: none; color: white; padding: 15px 32px; box-shadow: 0 2px 8px 0 rgba(0,0,0,1), 0 4px 20px 0 rgba(0,0,0,0.19); text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer; border-radius: 12px;}"); client.println(".buttonFade { background-image: linear-gradient(to right, #0b2742 0%, #296bab 30%, #00dbde 51%, #296bab 70%, #0b2742 100%); border: none; color: black; padding: 15px 32px; box-shadow: 0 2px 8px 0 rgba(0,0,0,1), 0 4px 20px 0 rgba(0,0,0,0.19);text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer; font-family:Impact, times, serif; border-radius: 12px;}"); client.println(".buttonFadeoff { background-color: #000000; border: none; color: white; padding: 15px 32px; box-shadow: 0 2px 8px 0 rgba(0,0,0,1), 0 4px 20px 0 rgba(0,0,0,0.19); text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer; border-radius: 12px;}"); client.println(".buttonspeed { background-color: #4CAF50; border: none; color: black; padding: 15px 15px; text-align: center; text-decoration: none; display: inline-block; font-size: 15px; font-weight: bold; margin: 4px 2px; cursor: pointer; border-radius: 50%; border: 2px solid black; box-shadow: 0 4px 12px 0 rgba(0,0,0,1), 0 4px 20px 0 rgba(0,0,0,0.19);}"); client.println(".buttonspeedoff { background-color: #f44336; border: none; color: black; padding: 15px 15px; text-align: center; text-decoration: none; display: inline-block; font-size: 15px; font-weight: bold; margin: 4px 2px; cursor: pointer; border-radius: 50%; border: 2px solid black; box-shadow: 0 4px 12px 0 rgba(0,0,0,1), 0 4px 20px 0 rgba(0,0,0,0.19);}"); client.println("</style></head>"); // Web Page Heading client.println("<body><h1>NG by Go²</h1>"); if (ONOFFState=="OFF") { client.println("<p><a href=/ONOFF/on><button class=buttonOFF>ARRET</button></a></p>"); } else if (ONOFFState=="ON"){ client.println("<p><a href=/ONOFF/off><button class=buttonON>MARCHE</button></a></p>"); if (GlittersState=="OFF") { client.println("<p><a href=\"/Glitters/off\"><button class=buttonGlittersoff>Glitters</button></a></p>"); } else { client.println("<p><a href=\"/Glitters/on\"><button class=buttonGlitters>Glitters</button></a></p>"); if (GlittersSpeed=="1") { client.println("<a href=\"/Glitters/1\"><button class=buttonspeed>1</button></a>"); client.println("<a href=\"/Glitters/2off\"><button class=buttonspeedoff>2</button></a>"); client.println("<a href=\"/Glitters/3off\"><button class=buttonspeedoff>3</button></a>"); client.println("<a href=\"/Glitters/4off\"><button class=buttonspeedoff>4</button></a>"); } else if (GlittersSpeed=="2") { client.println("<a href=\"/Glitters/1off\"><button class=buttonspeedoff>1</button></a>"); client.println("<a href=\"/Glitters/2\"><button class=buttonspeed>2</button></a>"); client.println("<a href=\"/Glitters/3off\"><button class=buttonspeedoff>3</button></a>"); client.println("<a href=\"/Glitters/4off\"><button class=buttonspeedoff>4</button></a>"); } else if (GlittersSpeed=="3") { client.println("<a href=\"/Glitters/1off\"><button class=buttonspeedoff>1</button></a>"); client.println("<a href=\"/Glitters/2off\"><button class=buttonspeedoff>2</button></a>"); client.println("<a href=\"/Glitters/3\"><button class=buttonspeed>3</button></a>"); client.println("<a href=\"/Glitters/4off\"><button class=buttonspeedoff>4</button></a>"); } else if (GlittersSpeed=="4") { client.println("<a href=\"/Glitters/1off\"><button class=buttonspeedoff>1</button></a>"); client.println("<a href=\"/Glitters/2off\"><button class=buttonspeedoff>2</button></a>"); client.println("<a href=\"/Glitters/3off\"><button class=buttonspeedoff>3</button></a>"); client.println("<a href=\"/Glitters/4\"><button class=buttonspeed>4</button></a>"); } } if (FadeState=="OFF") { client.println("<p><a href=\"/Fade/off\"><button class=buttonFadeoff>Fade</button></a></p>"); } else { client.println("<p><a href=\"/Fade/on\"><button class=buttonFade>Fade</button></a></p>"); if (FadeSpeed=="1") { client.println("<a href=\"/Fade/1\"><button class=buttonspeed>1</button></a>"); client.println("<a href=\"/Fade/2off\"><button class=buttonspeedoff>2</button></a>"); client.println("<a href=\"/Fade/3off\"><button class=buttonspeedoff>3</button></a>"); } else if (FadeSpeed=="2") { client.println("<a href=\"/Fade/1off\"><button class=buttonspeedoff>1</button></a>"); client.println("<a href=\"/Fade/2\"><button class=buttonspeed>2</button></a>"); client.println("<a href=\"/Fade/3off\"><button class=buttonspeedoff>3</button></a>"); } else if (FadeSpeed=="3") { client.println("<a href=\"/Fade/1off\"><button class=buttonspeedoff>1</button></a>"); client.println("<a href=\"/Fade/2off\"><button class=buttonspeedoff>2</button></a>"); client.println("<a href=\"/Fade/3\"><button class=buttonspeed>3</button></a>"); } } } client.println("</body></html>"); // The HTTP response ends with another blank line client.println(); // Break out of the while loop break; } else { // if you got a newline, then clear currentLine currentLine = ""; } } else if (c != '\r') { // if you got anything else but a carriage return character, currentLine += c; // add it to the end of the currentLine } } } // Clear the header variable header = ""; // Close the connection client.stop(); Serial.println("Client disconnected."); Serial.println(""); } } void Glitters (int TimeTempo) { if (TimeTempo > 0) { digitalWrite(D5, HIGH); // Turn the LED on (Note that LOW is the voltage level // but actually the LED is on; this is because // it is active low on the ESP-01) delay(TimeTempo); // Wait for a second digitalWrite(D5, LOW); // Turn the LED off by making the voltage HIGH delay(TimeTempo); // Wait for two seconds (to demonstrate the active low LED) digitalWrite(D6, HIGH); // Turn the LED on (Note that LOW is the voltage level // but actually the LED is on; this is because // it is active low on the ESP-01) delay(TimeTempo); // Wait for a second digitalWrite(D6, LOW); // Turn the LED off by making the voltage HIGH delay(TimeTempo); // Wait for two seconds (to demonstrate the active low LED) digitalWrite(D7, HIGH); // Turn the LED on (Note that LOW is the voltage level // but actually the LED is on; this is because // it is active low on the ESP-01) delay(TimeTempo); // Wait for a second digitalWrite(D7, LOW); // Turn the LED off by making the voltage HIGH delay(TimeTempo); // Wait for two seconds (to demonstrate the active low LED) digitalWrite(D8, HIGH); // Turn the LED on (Note that LOW is the voltage level // but actually the LED is on; this is because // it is active low on the ESP-01) delay(TimeTempo); // Wait for a second digitalWrite(D8, LOW); // Turn the LED off by making the voltage HIGH delay(TimeTempo); // Wait for two seconds (to demonstrate the active low LED) } else { digitalWrite(D5, LOW); // Turn the LED off by making the voltage HIGH digitalWrite(D6, LOW); // Turn the LED off by making the voltage HIGH digitalWrite(D7, LOW); // Turn the LED off by making the voltage HIGH digitalWrite(D8, LOW); // Turn the LED off by making the voltage HIGH } } void Fade(int TimeTempo) { if (TimeTempo > 0) { analogWrite(D5, brightness1); // change the brightness for next time through the loop: brightness1 = brightness1 + fadeAmount1; if (brightness1 <= 0 || brightness1 >= 255) { fadeAmount1 = -fadeAmount1; } // wait to see the dimming effect delay(TimeTempo); analogWrite(D6, brightness2); // change the brightness for next time through the loop: brightness2 = brightness2 + fadeAmount2; if (brightness2 <= 0 || brightness2 >= 255) { fadeAmount2 = -fadeAmount2; } // wait to see the dimming effect delay(TimeTempo); analogWrite(D7, brightness3); // change the brightness for next time through the loop: brightness3 = brightness3 + fadeAmount3; if (brightness3 <= 0 || brightness3 >= 255) { fadeAmount3 = -fadeAmount3; } // wait to see the dimming effect delay(TimeTempo); analogWrite(D8, brightness4); // change the brightness for next time through the loop: brightness4 = brightness4 + fadeAmount4; if (brightness4 <= 0 || brightness4 >= 255) { fadeAmount4 = -fadeAmount4; } // wait to see the dimming effect delay(TimeTempo); } else { digitalWrite(D5, LOW); // Turn the LED off by making the voltage HIGH digitalWrite(D6, LOW); // Turn the LED off by making the voltage HIGH digitalWrite(D7, LOW); // Turn the LED off by making the voltage HIGH digitalWrite(D8, LOW); // Turn the LED off by making the voltage HIGH } }
Malheuresement après avoir transporté plusieurs fois à vélo la Lampe NG durant l'épisode du Covid19, l'ampoule s'est décollé… J'ai du recoller cette ampoule mais comme le nouveau cordon de colle dépassait l'ancienne position d'origine cela n'était plus esthetique. J'ai donc rusé en ajoutant un bague supplémentaire à l'image des bruleurs d'ancienne lampe à pétrole. La difficulté est que la partie haute de la LampeNG est indémontable donc j'ai du modéliser, imprimer et monter une bague en plusieurs parties pour la coller à travers les barres géodésiques.
Inspiration : https://blendswap.com/blend/6355
Inspiration : https://dimensiva.com/3dmodels/armchair-daw-by-vitra-eames/ & https://www.designconnected.com/fr/category/Tables/E-Volved-table_p3882
Cette documentation est en cours de rédaction !
Cette documentation est en cours de rédaction !