Introduction: Cordel
Cordel is a Brazilian literature form that is marked by inexpensive, small booklets usually sold by street vendors attached to strings ("cordas"). These books are a very rich form of the Brazilian culture and come with almost any type of content, from children-oriented texts to popular culture to poems to pamphlets... They are usually printed using back ink, with a colorful cover. Besides the rich content, cordel books are very fine decoration objects! If you want to learn more about them, take a look at the Wikipedia.
This project is about the construction of a small structure with strings to display a small library of cordel books, adding some colorful lights to please our eyes. The lights will be handled wirelessly by a mobile devices (let's mix modern culture to the traditional one!). Besides cordel books, the structure can also be used to display any sort of magazines or lightweight publications.
During the process we'll be working with some wood, 3D print, circuit development and coding. Exciting, isn't it?
This project is built using the instructions for creating a webserver using an ESP8266 microcontroller (https://www.instructables.com/id/ESP8266-Basic-Server/). Check out the "parent" projectfor further information.
Supplies
This project will require some assembly for the structure, but we'll make it simple ;-) The materials you'll need are:
- 4 wood sticks for the board - the ones used here have 120cm x 2cm x 2cm
- 3.5mm x 16mm screws
- heat-shrink tubes
- strings (rustic ones looks better for this project)
PLA filament for 3D printing (you may order the printing if you does not have access to a 3D printer - the models for it will be provided)
The necessary circuit will be built using an ESP8266 board and some leds. Here's what you'll need:
- board with ESP8266 microcontroller - the one used here is the Wemos D1 R1, a very inexpensive one
- 10 RGB WS2812 5050 leds compatible with the NeoPixel library
- wires - lots of them!
- 2 standard leds with different colors
- 2 10kohm resistors
- a power supply
Besides these supplies, you'll need some tools like an electric screw driver (very recommened) and soe hot glue.
Step 1: 3D Printing
We'll start by creating the joints of our board and the other side pieces used to attach the strings and cover the leds. Here's what we'll need to print:
- 4 corner joints
- 4 top/bottom parts
- 6 side parts
This project used standard PLA filament, and the parts were printed with 0.1mm resolution. The white color were chosen to avoid a "color conflict" with the leds.
You may download the models directly from Thingiverse and start printing right now if your wooden parts have the same dimensions as the ones used here (120cm x 2cm x 2cm). The link is:
https://www.thingiverse.com/thing:3982973
However, if you're using different wooden parts or if you want to customize your 3D parts, you may want to access the project at Tinkercad. Check out the link:
https://www.tinkercad.com/things/fVzIeK1zD8B-cordel-3d-parts/
Step 2: Initial Assembly
Now, let's take a look at our wooden parts. They are 4 sticks of 120cm x 2cm x 2cm. Prefer some soft wood like pine for this setup. You can easily find this sort of cheap wooden stick at common home centers.
The first step will be marking the sticks using the 3D printed parts. Check out the scheme and the pictures: we'll need to drill the wood before actually attach the parts. If we fail to do so, the sticks may sag when screwed... A very thin drill will do the job.
While marking down the spots you'll notice that the printed parts are larger than the sticks. This is intended to leave room behind the board to pass the wires.
After drilling the marks for all 3D parts (a total of 36 points), lets screw only the corner joints for now. Check out the pictures to see our board taking shape.
Step 3: Preparing the Circuit
Now, let's take some time to discover how our circuit will work. We'll be using some RGB leds on it. Since we want individual color control, the WS2812 5050 addressable leds are a good choice! Using a single pin of our board we'll be able to handle all the leds individually. Magic! Ok, not that much: the Adafruit NeoPixel library is our friend and will handle the led colors for us (we'll discuss this later while checking out our project code).
These leds usually come attached to each other. Split them to single units and check them out: they come with 6 connectors for welding, 3 on each side (input and output). For the input side, two of the connectors are intended for power supply: 5V and ground. The last one will be connected to a digital pin of our board for controlling. The output connectors make the work with these leds a breeze: connect them to the next led and so on. This is nice for our 10 led setup, but remember the power limitations while making your own projects with tons of leds...
Our job now is to check out the required size of our wires so we can place leds at our board. They will be fixed below the side and top/bottom printed 3D parts, so we need the wires to go all around the board, connection them. Check out at the pictures a view from behind the structure with placed leds.
The next step will be the welding the leds. Some of us (like me) have some trouble while doing this, but don't worry! You can find some good tips at YouTube, and remember: use the soldering flux!
Well, the rest of the circuit is much simpler. We'll be adapting this other instructable for our project, so we'll need to attach two leds and two resistors. We won't be using the button found at the original project here.
Step 4: Further Assembly
Now that we have our leds wired, let's fix them at the structure. Hot glue may sound so gimmick... but that's a good way to do it. Just place them at the previously marked points.
Now, to get a polished look, a good trick will be encapsulating those color wires inside white heat-shrink tubes. Just cut them at the appropriate sizes, them cut them along their width to put the colored wires inside them. They should hold the wires nicely, but if you want to secure them, just use some white tape to close the cuts.
The next step will be screwing the remaining 3D printed parts to the board, covering the leds. Then, we can go ahead and tie the strings to the side 3D parts (they have some pins for it).
This part of the construction is ready!
Step 5: Controlling the Leds
For this project we'll borrow some code from another instructable: ESP8266 Basic Server. This will enable us to add support for a mobile device to easily change the color of individual leds of our structure. This is a nice touch since we may change the cordel books or magazines from time to time and may want to adjust the background lights to better fit the new setup.
We'll check out the code of our project in a moment, but for now let's take a closer look at the controlling interface. It will be done using simple HTML pages, CSS and some javascript (using jQuery) loaded at the device's web browser (no apps required). The user will be presented with a graphic schema of the board and will be able to select the leds/colors to change. There will also be a simple interface to change the way mobile devices will use to reach this content (connection to the board access point or from the user router, as explained at the ESP8266 Basic Server project page).
The pictures show this simple interface. It was designed to be very simple so we won't need deep explanations: select the leds to change, set the color and touch the ok (check) button. All the required files (html/css/js) are bundled with this project's code that will be explained in some moments. Just check the html folder of the download. Besides the jQuery, we'll be using the nice Colorwheel and Raphael libraries, both licensed under MIT terms (and included at the code download).
Step 6: Prepare for Coding
As said before, the electronics of this project are inspired by this one: ESP8266 Basic Server. You won't need to be downloading the code for the ESP Server, but check out the parent project description to learn how to set up your Arduino IDE environment properly.
The cordel project code is provided at the link below. Go ahead and download it. It's a standard Arduino IDE project.
https://github.com/lujunq/cordel
Besides preparing the IDE for the ESP8266 microcontroller, you'll need to add two Arduino libraries. This is simple: look for the Tools menu at the IDE and select the library manager. There, search for these two ones and add them:
- Adafruit NeoPixel
- ArduinoJson (by Benoit Blanchon)
That's it. We're ready to check out the downloaded code.
Step 7: Coding
Now that our coding environment is ready, let's have a deep look at the project we downloaded. The cordel.ino file starts with the usual library imports.
#include <FS.h> #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #include <ArduinoJson.h> #include <Adafruit_NeoPixel.h>
The first 5 ones are all about the ESP web server, while the last 2 enables us to handle JSON data and our RGB leds. Then, we'll see some configuring for the web server (check out the parent project to learn more about them). Starting at the // led display line, we configure our colorful lights, assigning the controller pin and the total number of leds we'll be using. Than, a curious line appears:
StaticJsonDocument<800> ledInfo;
We'll be storing our led color configuration as a JSON object (if you're not familiar with this, check out the Wikipedia). It enables us to handle and store complex data in a simple way. For this project we'll be using the ArduinoJson library and, since the kind of microcontroller we're using have limited resources, our JSON object initialization must be highly optimized. That's why we need to provide the memory it'll use. For this project needs, 800 is enough, but for your own creations, check out this nice tool the library developers provide.
Next, we'll initialize the leds!
Adafruit_NeoPixel pixels(totalLed, rgbLed, NEO_GRB + NEO_KHZ800);
This one was easy: we just need to provide the number of leds, the controller pin and some other info you'll find at the library GitHub page. As said before, our 10 led setup is very easy to assembly, but as the number of lights increase at your own projects, you'll need to handle the power supply, and also remember that each led consumes memory on your limited system...
Now we can move on to the sketch setup method. We'll be skipping the initialization of the ESP8266 server, ok? First, we call the getLedInfo method to load JSON-encoded text from a file at our filesystem:
void getLedInfo() { // does the led color file exist? if (SPIFFS.exists("/ledconf/colors")) { // get saved led configuration Serial.println("Led configuration file found... "); File fl = SPIFFS.open("/ledconf/colors", "r"); String ledLoaded = fl.readString(); fl.close(); // try to parse loaded string DeserializationError error = deserializeJson(ledInfo, ledLoaded); if (error) { Serial.println("Error on led configuration file... all white! "); initLed(); } else { Serial.println("Led configuration file sucessfully loaded!"); } } else { // leds all white Serial.println("No led configuration file found... "); initLed(); } }
At this fucntion we'll check if a file named ledconf/colors exists. If so, we read its contents and deserialize (parse) the data into the global ledInfo variable. If not found (or if we face deserialization problems) the initLed method is called just to create an initial all-white setup.
void initLed() { String ledLoaded = "{\"mode\":\"ind\",\"led\": [{\"r\": 255,\"g\":255,\"b\":255},{\"r\": 255,\"g\":255,\"b\":255},{\"r\": 255,\"g\":255,\"b\":255},{\"r\": 255,\"g\":255,\"b\":255},{\"r\": 255,\"g\":255,\"b\":255},{\"r\": 255,\"g\":255,\"b\":255},{\"r\": 255,\"g\":255,\"b\":255},{\"r\": 255,\"g\":255,\"b\":255},{\"r\": 255,\"g\":255,\"b\":255},{\"r\": 255,\"g\":255,\"b\":255}]}"; deserializeJson(ledInfo, ledLoaded); File fl = SPIFFS.open("/ledconf/colors", "w+"); fl.println(ledLoaded); fl.close(); Serial.println("Led configuration file reset!"); }
Now that we know the color of each led, we move back to the setup method. Let's take a look at the // initializing leds section:
Serial.println("Starting led display..."); Serial.print("Mode: "); String dmode = ledInfo["mode"]; Serial.println(dmode); pixels.begin(); showLed(); Serial.println("");
Besides serial printing, what we do here is to initialize the global pixels variable we defined early and call the showLed method, described below.
void showLed() { // clear previous display setup pixels.clear(); // get each led setup Serial.println("Changing led colors:"); String ledset = ""; int lcolor; for (counter = 0; counter < totalLed; counter++) { ledset = ""; pixels.setPixelColor(counter, pixels.Color(ledInfo["led"][counter]["r"], ledInfo["led"][counter]["g"], ledInfo["led"][counter]["b"])); ledset.concat(counter); ledset.concat(" => "); lcolor = ledInfo["led"][counter]["r"]; ledset.concat(lcolor); ledset.concat(", "); lcolor = ledInfo["led"][counter]["g"]; ledset.concat(lcolor); ledset.concat(", "); lcolor = ledInfo["led"][counter]["b"]; ledset.concat(lcolor); Serial.println(ledset); } // apply defined setup pixels.show(); Serial.println("Led display updated!"); }
This function is quite simple: first, it clears the previous led configuration, then it goes, led by led, checking out the color set and assiginig it. It finished by turning on the lights again (pixels.show). We'll be calling this function every time we change the led color to update our display.
The rest of the setup method just finishes the ESP server initialization. We'll have two routes with custom actions: the /wifi.html (as used at the ESP8266 server project) and the /index.html one that we'll check out in deep:
void onIndex() { // receiving post info? if (server.arg("ac") == "setcolor") { Serial.println("Receiving led setup."); // checking colors int red = server.arg("red").toInt(); int green = server.arg("green").toInt(); int blue = server.arg("blue").toInt(); // setting each led for (int i=0; i<totalLed; i++) { if (server.arg("led" + String(i)) == "1") { ledInfo["led"][i]["r"] = red; ledInfo["led"][i]["g"] = green; ledInfo["led"][i]["b"] = blue; } } // saving led setup String jsonText; serializeJson(ledInfo, jsonText); File fl = SPIFFS.open("/ledconf/colors", "w+"); fl.println(jsonText); fl.close(); Serial.println("New led setup saved. Applying now!"); // showing new led setup showLed(); } // resetting board? if (server.arg("ac") == "reset") { resetFunc(); } // finally, send the index file sendFile("/index.html"); }
The index.html file of our project comes with a form for sending the values received at the function above. Check it out:
<form id="ledform" method="post"> <input type="hidden" name="ac" value="setcolor" /> <input type="hidden" name="led0" id="fled0" value="0" /> <input type="hidden" name="led1" id="fled1" value="0" /> <input type="hidden" name="led2" id="fled2" value="0" /> <input type="hidden" name="led3" id="fled3" value="0" /> <input type="hidden" name="led4" id="fled4" value="0" /> <input type="hidden" name="led5" id="fled5" value="0" /> <input type="hidden" name="led6" id="fled6" value="0" /> <input type="hidden" name="led7" id="fled7" value="0" /> <input type="hidden" name="led8" id="fled8" value="0" /> <input type="hidden" name="led9" id="fled9" value="0" /> <input type="hidden" name="red" id="fred" value="255" /> <input type="hidden" name="green" id="fgreen" value="255" /> <input type="hidden" name="blue" id="fblue" value="255" /> </form>
This form has one variable for each led that receives the valeus 0 or 1, and one for red, green and blue values that it recovers from the colorwheel. When posted, the onIndex function of the sketch receives these color values and assign them to the active leds (with value 1 from the form). The further steps are serializing the ledInfo variable into a JSON and save it to the filesystem and finally call showLed again. By saving the led state we guarantee that when we turn on our cordel board it'll show the last colors set.
We won't be taking a deep look at the HTML/CSS/CSS file of our project, but this may be a good time to check them out. We just create a graphical interface using jQuery and the Colorwheel library, using them to set values and posting the above form. As used at our parent project, the text files are gzipped for server optimizing.
Finally, the loop method of the sketch is preety like the one from the ESP server. We just removed the physical reset button and moved it to our index.html file.
And... that's all folks! At least for the code part.
Step 8: A Case for Our Circuit
For a final touch, let's create a case for our circuit. At these pictures we can see a 3D printed box that fits the Wemos board used. You may need to adjust it if you're using another ESP8266 board. The two holes at the case front are intended to display the mode leds (access point/router connection). A nice further touch would be printting some connection instructions to fix on it ;-)
If you're using the same board, you may download this package ready to print:
https://www.thingiverse.com/thing:3987925
Or, if you want to make some adjustements:
https://www.tinkercad.com/things/fJ6rv59OUlW-cordel-circuit-case/
Finally, one may notice at the pictures that the board can be easily removed form the case. A good way to repair (or reuse) it.
Hope you have enjoyed this project ;-)