Jewelry Box: Components Complete
There are two factors to making this sketch complete:
- if it isn’t broken, don’t fix it, and
- don’t reinvent the wheel, if all you need is new tread
The example sketches provide much of what I want to do, and they work in the way I need for my jewelry box; refer back to the two points! With the exception of a few changes to function calls, and minor code addition, the majority of the sketch is a copy/paste from example sketches.
Piecing it Together
SSD1306 128×64 OLED Display
This display is a 2-part setup, in which some of the content will be static, and the other is dynamic, based on the date. Because of the content refresh for the dynamic portion, I put everything in the loop function, always clearing the whole screen, and display the message content. One potential drawback is that it doesn’t update the time until the end of the picture loop. Each picture is displayed for 4 seconds, then it checks the time, and processes the picture loop again. This means that the display time may be off by a few seconds, maybe even minutes, depending on the amount of pictures. It takes approximately 1.2 seconds to display the picture, and then stays for 4 seconds; approximately 5.2 seconds per picture. I can update the sketch to check the time after every image, but the time really only matters at midnight, when the day changes. It’s not often, if ever, that the jewelry box will be used at midnight, but it’s also not a time piece.
For this part of the sketch, I used the excerpt from Adafruit’s SSD1306 example, ssd1306_128x64_i2c, which displays text. Manipulating the part that clears the screen, and displaying text, I used it to display the 2-line static message in the yellow text area, followed by the dynamic counter information in the blue text area. For the heart icon, I used “char(0x03)” in the print statement.
DS3231 Real-Time Clock (RTC)
Regarding the time change at midnight, I had to update my sketch from my midnight (Pacific Time), to GMT. When the RTC is configured with my time, it doesn’t take a time zone. This means that it takes the date and time as GMT. To compensate for this setting, or lack thereof, I subtracted 25,200 seconds (60s X 60m X 7h = 25,200 seconds) from my counter:
display.println((now.unixtime() - 1468713600) / 86400L);
In addition to displaying the annual anniversary, or defaulting to a day counter, I’ve added a counter of months, if it is the 17th, but not July. Similarly, I used the example sketch from Adafruit, RTClib, and used the output to perform the mathematical calculations in day counting. It wasn’t until I was testing at midnight, that I noticed the day counter wasn’t updating. Further testing the output from “now.unixtime()” showed me the discrepancy in time, and adjusted accordingly. A new test at midnight showed me the expected change in time.
ILI9341 2.8″ TFT Display
No surprise here: using the spitftbitmap example to display my pictures on the TFT display. Using this example, I will need to update the sketch every time I add new pictures, so I can call the bmpDraw() function on every image that I add to the microSD card. The output it provides is useful for testing the image displayed. If I’m not looking to ever attach this back to a computer, I can take out all of the ‘Serial.print()’ and ‘Serial.println()’ entries in the function, but it does provide some useful information to the Serial Monitor, if I decide to connect, and take a look at the images being displayed.
Automation means not having to go back to your sketch to keep updating, with the exception of maintenance. In the current build of the sketch, I’m needing to go in and update the sketch every time I add an image to the microSD card on the display. This can only go so far, before I reach the “last image” that I can put into the sketch, and run out of space. Fortunately, there is already a built-in example sketch I can use to call upon every file.
SD Library to List Files
The SD library contains an example sketch, listfiles, which will list all of the files found in the root directory of the microSD card. As I’m storing all of the pictures of the root directory, and the example sketch shows me all of the images, I can use this to my benefit. Instead of displaying all the data from the file, as performed by listfiles, I can update the sketch to use this method for calling upon the bmpDraw() function.
Every image is displayed, however, that’s it. Even if I put this in the loop() function, that isn’t enough. Once the sketch is done reading the contents of the root directory, that’s all there is to it. To keep this going, as expected in looping behavior, I need to add an entry to go back to the start, once there aren’t any further files to display:
if (!entry) {
dir.rewindDirectory();
break;
}
Why do I need a “break;” entry in the sketch? Without it, the sketch will continue looping on the file list, and never move on to the next thing: obtaining the date from the DS3231 RTC module, and passing it to the SSD1306 OLED display.
Once it reaches the last file, it goes to the start of the directory listing, and goes through the list again. This will perform the action I need to continue looping the images on the microSD card, and not have to list every file individually, in the bmpDraw() function. If I add a new bitmap file, I don’t have to re-write or update my sketch, as this will already be resolved by the “listfiles” example sketch:
while (true) {
File entry = dir.openNextFile();
if (!entry) {
dir.rewindDirectory();
break;
}
bmpDraw(entry.name(), 0, 0);
delay(4000);
entry.close();
}
Piecing it together, the electronics are done. Next, placing the electronics in the physical jewelry box. This works on its own, running on a 9v battery, but putting it together in the jewelry box will require proper layout planning, and ensuring the ideas and paperwork actually function in practice.