Wi-Fi Control of Intelligent LED's With a Web Page. [Make Some Rainbows]
by Palingenesis in Circuits > Arduino
1356 Views, 20 Favorites, 0 Comments
Wi-Fi Control of Intelligent LED's With a Web Page. [Make Some Rainbows]
I did a similar instructable: Wi-Fi Control of a Motor With Quadrature Feedback : 9 Steps (with Pictures) - Instructables
This instructable follows on from that one and will show you how to control those colourful LED strip's.
- The ones that can be lit with all the colours of the rainbow.
- The video is a bit long, but I was trying to get a lot into it.
I will be using the same microcontroller, the ESP8566. This time I will also show how it can connect to your local Wi-Fi.
You will have the choice to connect the sever on the ESP2866 as a/an:
- Access Point without a password. (You connect your device to the ESP2866 server)
- Access Point with a password. (You connect your device to the ESP2866 server)
- A Station. (The ESP2866 server connects to your local Wi-Fi network, you can use any device on your network to connect to the ESP2866 Server)
I will be using two web pages, so you will see how to put multiple web pages onto the ESP2866 Server.
- The web pages will be stored on the ISPFFS with an image.
- So the web pages can be stored as Web Page files on the ISPFFS.
- The <ESP8266WiFi.h> has a function that will allow the call of files directly from the ISPFFS. (I will not be streaming them as before).
Basically this instructable has some improvements from the last one.
- It should show the similarities' between the two to give you more understanding how easily you can change things to suit your own project.
Assumption's
I assume you are familiar to some degree with the Arduino architecture and IDE also HTML and JavaScript.
Supplies
An ESP8266
- I am using a "New NodeMCU v3" breakout board. (Not sure about the new, it's what is printed on it)
- Other microprocessors can be used as long as Wi-Fi, enough Memory and ISPFFS capabilities.
A strip of 5V LED Strip RGB
- I have a strip of 30, the number can be changed in the code.
Cables will be needed to connect it all together.
- I have used Solderless Breadboard and cables.
A 5 volts and 3.3 volts DC Power Supply.
- I have a bench power supply.
- I have used a power adapter that fits to the breadboard.
- Any adapter will do with the correct voltages, also a battery pack.
- The 5 volt LEDs can use quite a bit of current when lit full.
To make the voltage smooth and able to get a strong signal to the end of the strip, I have added a big capacitor.
- The bigger the better. When doing flashing sequences there could be current surges.
- I am using a 16v 10000uF I had a few for something.
As the ESP8266 Logic Level is 3.3 volt. I am using a Logic Level voltage converter.
- The data signal may work with 3.3v, but to make sure the signal is strong, I am using a Logic Level converter so that it is using the LED supply voltage.
A resistor for the connection to the Data Pin.
- About a 470 ohm will be fine. Something close will do.
As usual I cant upload the files needed here.
- The files needed are in this zip on my Google Drive: Tims_Wi_Fi_RGB_Control.zip
The Circuit
The circuit is a fairly simple one.
- Just copy the Fritzing diagram.
- Note there is a resistor in series with the Data connection.
- Note that D1 is actually GPIO5, In the Arduino sketch 5 is the value used to define the pin.
If using the Breadboard power supply.
- It uses voltage regulators to set the voltage in the power rails.
- There is usually a voltage drop when using solid state components.
- It is best to use a voltage in between 7 and 12 volts.
- I usually input 10 volts, on the Power in.
Code
The full code file is in the zip file I put on my Google Drive.
As before I have put lots of comments in the code file, you can download it to view the whole thing.
- Here I will just put the important snippets.
- As before you can use this code as a template and will be able to use this to modify it and create your own projects.
- Most of the code can be copied and edited to do you own tasks.
If you just want to do this project as an exercise:
- Download the and extract the file from the zip file.
- Change a few lines as I have instructed.
- Upload to the ESP8266.
- Have fun.
Arduino IDE
The Arduino IDE can be downloaded from the Arduino Site. I am using the Legacy IDE (1.8.X) version
- Just download and follow instruction.
- I prefer this version as I use Microsoft Visual Studio for most of my editing anyways. (I also made the style/colour match)
You will need to add the Libraries for the ESP8266 using the Boards Manager.
- To do this you need to tell the Arduino IDE where to look for them.
- You need to add the address of the URL: https://arduino.esp8266.com/stable/package_esp8266com_index.json to the "Additional Boards Manager URLs:" in the Arduino IDs Preferences.
- In the Arduino IDE go: File => Preferences. This opens anew window.
- At the end of the URL text is a button, this makes it easier to add more URL's.
- Each URL is on a separate line.
- More info here: esp8266/Arduino: ESP8266 core for Arduino (github.com)
You will also need to add the Arduino ESP8266 filesystem uploader.
- All the information for adding the Addon is here: esp8266/arduino-esp8266fs-plugin: Arduino plugin for uploading files to ESP8266 file system (github.com)
LED Library
For this project I am using Adafruit Library <Adafruit_NeoPixel.h>
- This library will need to be installed through the Arduino IDE Library Manager.
- To open the Library Manager, click: "Sketch" => "Include Library" => " Manage Libraries..."
- Install "Adafruit NeoPixel". I have installed version 1.11.0
- Adafruit libraries are known by the Arduino IDE, so you don't have to tell it where they are like you did with the microcontroller.
Note!
With my previous Instructable I installed an earlier version of the Boards Managers files for the ESP8266.
- This time I am using the latest version for for the ESP8266, version 3.1.2
- There examples that are included with the NeoPixel library, you can use them with theESP8266, BUT, you will not be able to use them with the server. The examples would need to be converted to JavaScript and put on the client side.
Server Connection
The first thing to do to the code is enter you own credentials for connection to your local network.
- Remove the text "#include "Credentials.h"" from line 62. (Leave the line so that the line numbering remans the same)
- Uncomment the lines 114 and 115.
- Replace the text "Your local network name" with your own local network name, on line 114.
- Replace the text "Your local network password" with your own local network password, on line 115.
The reason I have my credentials in a separate header file is so I don't accidentally show them to the whole world.
- I don't want everyone connecting to my network ha-ha.
- I have the lines 114 and 115 in a header file called Credentials.h
There are three ways in which we can connect to the sever, "Access Point", "Access Point with password" or "Station".
"Access Point (AP) mode"
- This is not connected to your local network, you connect to the Network of the ESP8266.
- This means you can connect to it with your Mobile Phone anywhere you are.
- You change the Wi-Fi your Phone is connected to, to the ESP8266 Wi-Fi.
- Then open browser to the IP of the ESP8266 control page. (we will be setting it to 192.168.50.10)
- Have your serial monitor connected when you re-set the module to confirm correct IP Address.
"Access Point with Password (AP) mode"
This is same as above, but you need a password to connect to the Wi-Fi. (it currently is: 12345678)
"Station (STA) mode"
In STA mode, the ESP8266 connects to an existing Wi-Fi network created by your wireless router.
- You will need to set the access credentials for your local network.
To chose which mode you want to connect the ESP8266 server, I have written the code so that it can easily be changed.
- Uncomment line 87 if you want "Access Point (AP) mode"
87 #define ACCESS_POINT
- Uncomment line 88 if you want "Access Point with Password (AP) mode"
88 #define ACCESS_POINT_PW
- Uncomment line 89 if you want "Station (STA) mode"
89 #define ACCESS_POINT_STA
Only one of these three lines should un-commented.
Access Point Mode
Lines 106 and 107 can be change to your own preferences.
- The name (SSID {Service Set Identifier}) you see on the network can be changed.
- The password you use can be changed, note it must be at least 6 characters long.
106 const char* ESP8266_SSID_AP = "Tims Wi-Fi RGB Control";
107 const char* ESP8266_PASSWORD_AP = "12345678";
Also Line 119 can be altered if you want to make several, each with there own IP Address.
- Just change the last number for each.
119 IPAddress local_ip(192, 168, 50, 10); /* IP for AP mode */
Station Mode
Lines 114 and 115 can be change to your own preferences.
- The name (SSID {Service Set Identifier}) you see on the network can be changed.
- The password you use can be changed, note it must be at least 6 characters long.
114 const char* LOCAL_SSID_STA = "Your local network name"; /* Your local network name. */
115 const char* LOCAL_PASSWORD_STA = "Your local network password"; /* Your local network password. */
What does un-commenting only one of the connection choices do?
Code can be separated in a certain way so that the compiler will miss chunks of code out when compiling the code.
- If we look at lines 360 to 407, we can see that some code is enclosed in Definition if's. (#ifdef)
- If something has been defined the that part of the code will be live and compiled when the compiler reads the code.
- Those choices that are commented out, means those choice have not been defined, so that part of the code will not be read by the compiler.
360 /* Connect to ESP8266 Wi-Fi network with no password. */
361 #ifdef ACCESS_POINT
362 WiFi.mode(WIFI_AP);
363 Serial.println("ESP8266 in AP mode");
364 WiFi.softAPConfig(local_ip, gateway, subnet);
365 Serial.println("Setting AP (Access Point)");
366 WiFi.softAP(ESP8266_SSID_AP);
367 Serial.print("Connect you device to network '");
368 Serial.print(ESP8266_SSID_AP);
369 Serial.println("'\r\nThere is no Password.");
370 Serial.print("Open browser to ");
371 Serial.println(WiFi.softAPIP());
372
373 #endif // ACCESS_POINT
374
375 /* Connect to ESP8266 Wi-Fi network with a password. */
376 #ifdef ACCESS_POINT_PW
377 WiFi.mode(WIFI_AP);
378 Serial.println("ESP8266 in AP mode with password");
379 WiFi.softAPConfig(local_ip, gateway, subnet);
380 Serial.println("Setting AP (Access Point)");
381 WiFi.softAP(ESP8266_SSID_AP, ESP8266_PASSWORD_AP);
382 Serial.print("Connect you device to network '");
383 Serial.print(ESP8266_SSID_AP);
384 Serial.println("'");
385 Serial.print("Use password '");
386 Serial.print(ESP8266_PASSWORD_AP);
387 Serial.println("'");
388 Serial.print("Open browser to ");
389 Serial.println(WiFi.softAPIP());
390
391 #endif // ACCESS_POINT_PW
392
393 /* Connect to your local Wi-Fi network with a password. */
394 #ifdef ACCESS_POINT_STA
395 WiFi.mode(WIFI_STA);
396 Serial.println("ESP8266 in STA mode");
397 WiFi.begin(LOCAL_SSID_STA, LOCAL_PASSWORD_STA);
398 Serial.print("Connecting ");
399 while (WiFi.status() != WL_CONNECTED) {
400 delay(500);
401 Serial.print(".");
402 }
403 Serial.println("");
404 Serial.println("WiFi connected");
405 Serial.print("IP address: ");
406 Serial.println(WiFi.localIP());
407 #endif
The basic differences here are the:
WiFi.mode(??);
And which address and password is used.
Also in: "WiFi.mode(WIFI_STA);" mode.
- Once connected we need to get the IP address that has been allocated to the server.
Number of LED's
Another part of the code may need altering, line 138 defines the number of LED's on the strip.
- It is currently set at 30 LED's
138 #define NUMBER_OF_LEDS 30
Server Side
In the "void setup(){.....}" we can tell the server what to look out for and what to do when it sees what we told it to look out for.
Client = the remote device = the web page a user is looking at.
There are two ways we can tell the server to do something when is see something we tolled it to look for from a client:
421 server.serveStatic("/", SPIFFS, WEB_PAGE, "text/html");
422 server.serveStatic("/My_Image", SPIFFS, IMAGE_FILE, "image/png");
423 server.serveStatic("/Rainbow_Chase", SPIFFS, WEB_PAGE_LED_CHASE, "text/html");
The "server.serveStatic();" function has four arguments.
- server.serveStatic("What to look for", Where to find it, What to send, "The type of file it is");
- "What to look for". This is the text the client sends in the XMLHttpRequest.
- Where to find it. The location the data is found, in this case we are storing the files in the SPIFFS.
- What to send. Here I am using Definitions I have made of the path/file name of the file I want to send from the SPIFFS. For example: WEB_PAGE = "/index.html".
- "The type of file it is". In the case of WEB_PAGE, it is text coded in HTML. In the case of IMAGE_FILE, it is an image saved in the format of a PNG (Portable Network Graphics) file.
425 server.on("/Get_Total_Number_Of_LEDs", HTTP_GET, Handle_Get_Total_Number_Of_LEDs);
426 server.on("/LED_Show", HTTP_GET, Handle_LED_Show);
427 server.on("/LED_SetPixelColor", HTTP_GET, Handle_LED_SetPixelColor);
428 server.on("/LED_Fill", HTTP_GET, Handle_LED_Fill);
429 server.on("/LED_Clear", HTTP_GET, Handle_LED_Clear);
430 server.on("/LED_SetBrightness", HTTP_GET, Handle_LED_SetBrightness);
431 server.on("/Get_Value", Handle_Value);
The "server.on();" function has three arguments.
- server.on("What to look for", The type of request, The routine it calls);
- "What to look for". This is the text the client sends in the XMLHttpRequest.
- The type of request. The type of XMLHttpRequest that was called by the client.
- The routine it calls. This a function you created to do something. void Do_Somthing(){...}.
There is also something if what ever is sent by the client that the server does not know what to do with.
433 server.onNotFound(Handle_Not_Found);
Once we have created all the calls on what do do when something is received by the server we can start it.
server.begin();
General
When ever a client sends a Request to the server, the client expects a reply.
- So at some point in the code, after receiving a Request from the client we must confirm to the client that the Request has been received.
We do this by sending:
server.send(200, "text/plain", "OK");
- 200 is a code to say all is good.
- "text/plain" is saying the type of data we are returning.
- "OK" is some text we are sending back.
The last two argument could be something else, you may want the client to receive something different.
- As long as all went well, the 200 code number is the important part.
As this is a simple view of things I am not going any further than that, things can be add to take care of other scenarios, but as this is not open to www, there is no need to complicate things,
Client Side
This time I have not made the HTML files as header files, the HTML file are save to the SPIFFS on the ESP8266 as HTML files.
- So these files can be edited with any preferred HTML editor.
There are two web pages because in this instructable I wanted to show that more than one web page can be put on your ESP8266 Server.
General
A web page is DOM (Document Object Model) made up of elements to represent the parts of the page.
- The files name has an extension (.suffix) HTML on the end so web browsers know how to interoperate the document.
- I recommend W3Schools Online Web Tutorials to find more on making your own web pages.
An element in a web page that we want to have interaction with (input) will have some typical elements, here is an example of a button:
<button class="button" onclick="Make_Rainbow_Colours();">
Make Rainbow Colours
</button>
You will se that there is an onclick="Make_Rainbow_Colours(); This is calling a function in the section <script></script>
- The section inside <script></script> is where we write all our code to send/receive data and make the web page change.
This time there are three types of request from the client.
- One that sends data for a value. All data is sent as text, I will show how several integers (Numbers) are sent later.
- One that request files.
- One that request a web page.
Send Data to the Server
333 /*
334 Change individual LED to a colour.
335 */
336 function LED_SetPixelColor(position, colour) {
337
338 let xhr = new XMLHttpRequest();
339 xhr.open("GET", "/LED_SetPixelColor?value=" + position + "," + colour, true);
340 xhr.send();
341 return xhr.responseText;
342 }
This is a typical function where I am sending two values.
- position a Number and colour another Number.
Lets say colour is 205 and colour is 8454144.
what will be sent to the server is: "/LED_SetPixelColor?value=205,8454144" all as text.
- You will see that I have put a comma "," in-between the two numbers.
- We could send more numbers with this message, as long as we separate them with commas ",".
- The comas "," will be used at the server side to separate the Numbers and convert the to integers.
Receive Data from the Server
316 /*
317 Get Length Of LED Strip.
318 The number of LEDs.
319 */
320 function Get_Total_Number_Of_LEDs() {
321
322 let xhr = new XMLHttpRequest();
323 xhr.onreadystatechange = function () {
324 if (this.readyState == 4 && this.status == 200) {
325
326 Total_Number_Of_LEDs = this.responseText;
327 document.getElementById("numberOfLEDs").innerHTML = Total_Number_Of_LEDs;
328 }
329 }
330 xhr.open("GET", "/Get_Total_Number_Of_LEDs", true);
331 xhr.send();
332 }
This is a typical function where I want to receive some data.
Before the XMLHttpRequest is sent, we need to tell the XMLHttpRequest what to do when it receives a reply.
- xhr.onreadystatechange. here we are say wait until the server is ready to receive the XMLHttpRequest.
- The if (this.readyState == 4 && this.status == 200) {....... basically saying if the transaction went ok do whatever is in the "if" statement.
- We the open and send the XMLHttpRequest.
In the "if" statement the variable Total_Number_Of_LEDs is assigned the value of this.responseText
Change the Web-Page
523 /*
524 Show the 7 colours of a rainbow
525 Shows the 7 colours of the rainbow chasing along the strip.
526
527 (This one I have changed the web page.)
528 */
529 function Rainbow_Chase() {
530 window.location.href = "/Rainbow_Chase";
531 }
Inside this function you will see window.location.href = "/Rainbow_Chase";
- The window.location.href is the important bit, it is saying that what is returned is a new Web-Page.
- "/Rainbow_Chase". Is telling the Server which Web-Page to send back.
SPIFFS
SPIFFS (Serial Peripheral Interface Flash File System)
A Few Notes!
- All the information for adding the Addon is here: esp8266/arduino-esp8266fs-plugin: Arduino plugin for uploading files to ESP8266 file system (github.com)
- Remember to set the correct settings under tools in the Arduino IDE.
- You upload changes to files saved in the SPIFFS using the SPIFFS addon.
- You upload changes to the *.ino file using the Upload Button.
- If you upload the changes to the *.ino file with the wrong settings you may erase you SPIFFS files.
- Make sure you don't make the size of the files you are saving to the SPIFFS bigger than the space you have allocated.
- A tip on images, you can make them a low resolution, you only need high resolution images for printing photo quality images.
- If you want to use vector graphic type images, use SVG images, these are DOM files just like web-pages.
Summary
Hopefully this will also help those that want to make and design there own projects.
- You can use this as a template and edit it to suit your own needs.
- I have put a coloured filter over the picture of the the LED, to show the emulation of the light from the LED. Check out that part of the code.
- Sliders are just user input boxes that take a value from the user, but have been made to resemble a slide. This makes it difficult to make them vertical, you may want to look at the CSS for these sliders. What makes it hard is making it compatible with all makes of web-browser.
- The "LED_Chase.html" is a little more complicated than the "index.html".
- The "LED_Chase.html" has nested XMLHttpRequest, where it waits for commands to be executed before the next XMLHttpRequest is sent.
- JavaScript likes to do everything at once, so when you write code, it is not always as simple as putting one command after another, some times you have to tell it when and what to do.
I would also like to mention that technologies are moving forward.
- I got lazy with the "LED_Chase.html" I started the code using: "the new Bing Your AI-powered copilot for the web" :)
I may not of covered every part of the code, I hope it is enough to continue you on the route of controlling things on the web.
- I may have mentioned more in the video, it ended up a bit long.
Any Practicalities for this project?
Yes, I think so:
- If your house has intelligent LEDs lighting the rooms of your house.
- You could attach these cheap modules to each light.
- Connect them all to you home network.
- Control them from one web-page on your PC or Phone.
**Oh wait its been done but you have to pay and subscribe to all involved. Sign on to there servers so they can record your use, then maybe they pass that data on to logistics companies to predict power usage in your are. ha-ha.
**<Only kidding, or . . . am I?>