
My project is called Horizonte, a horizon clock that adjusts it’s color and light patterns in real-time according to its location and the current time of day. The clock itself is a device that provides a WiFi access point for remote configuration, and an autonomous network-based update feature, which allows the user to customize the clock’s parameters. I wanted to stray away from the sense of being precise, a rather lazy, and non-invasive way of letting you know what part of the day it is. The clock gradually shifts from one stage of the day to the next, taking around 5- 20 minutes to shift depending on the event, location, and date.
The project uses an API that is based on the SuncalcJS library to acquire the time for each particular ‘sun event’ in the day, such as Dawn, Sunset, etc… For this particular project, at this stage at least, I am dealing with events that happen between Dawn and Dusk. Why? These are the first and last stages of sunlight, and if you are a fan of ” From Dusk till Dawn”, those are vampire-safe times.
Hardware Used
- Arduino MKR 1010
- HW-125 SD Card reader
- LEDs – Neopixel Strip x 2
- DS3231 Precision RTC
- Epilogue Mini Laser Cutter
Power requirements
- I used a 5V, 10A power supply for both the Arduino and the lights. Same as this one.
Software
- Arduino IDE
- NodeJS
- Suncalc
- Blender
- Illustrator
- Unreal Engine 4 (for visualizations)
Initial Proposal
User Interaction

UI Re-design
WiFi Login UI Color Picker UI
FULL PROCESS
I mainly focused on gradients, however I also tried different approaches, as you can also see below.
I quickly found myself struggling to acquire the control I needed, and after a week or two of trying to make my own gradients based off of Adafruit’s limited examples, I was running out of time to get the other things going. After looking for a while I ran into FastLED, a Neopixel control library developed for Arduino which boasts to be better than the original library. Their examples were very varied, complete, and allowed me to find a couple of useful scripts which I took apart to make my own. Specifically, I heavily relied on the ColorPalette example and the nblendPaletteTowardPalette
function found in the docs. The code implemented in the clock goes through nine different gradients, transitioning in and out of them during the day.
The main function takes the following parameters:
- A current time measure in order to determine which sun event should be activated
- The start time for the current day loop. It resets at midnight.
- each of the sun events in millis().
void ChangePalettePeriodically_bottom(unsigned long startMillis,
unsigned long currentMillis,
long interval1,
long interval2,
long interval3,
long interval4,
long interval5,
long interval6,
long interval7,
long interval8,
long interval9
) {


In terms of wiring and connections, it was pretty straightforward. I used an Arduino MKR 1010 since it had an esp32. From previous research, I knew it had more ram than the Arduino Nano, which was my other option. I hooked a couple of 470-ohm resistances to the input line of each Neopixel Strip. I also added two 470 microfarads capacitors in series. The Adafruit Uberguide for powering Neopixels suggests a 1000 microfarad capacitor, however, I did not have one. All of this was powered by a 5V, 10A power supply. Here’s the schematic below.

Color

In order to represent the horizon, or at least my view of it, I would have to decide on a color palette to use. I started out doing something like the image below, which gave me a general sense of where to go.

The API, the request, the data
After having seen Tom Igoe’s Connected Devices and Networked Interaction class last semester, I felt fairly confident that making my own API was the way to go in order to access the data at any given time from any device and also to control it. Manipulating the data and processing it before sending it to any device was a priority. I decided to make it in NodeJS since I wanted to keep the possibility of incorporating JS into the web client open. I also mounted it on Heroku, which probably isn’t the best option for continuous communication such as WebSockets but works fine for HTTP requests. As I said before, even though my idea was to keep it as real-time as possible the idea of being a couple of seconds or even minutes off track didn’t mean much. The API consists of two routes: /sun
and /now
. /sun
ill return all of the times for each sun event according to UTC. /now
will return the current time.
The data is presented as a JSON file. So everytime we make a request, the server writes an updated JSON file which is sent to the Arduino. You can see the JSON formatted below.


To made the request to the server I used the WiFi Web Client
example from the Arduino IDE, and later saved it as a JSON using the ArduinoJson
library.

This allowed me to access each key-value in the JSON easily, and save it to set the parameters in our Neopixels lights function. Below you can see a glimpse of how it went for saving the data for Dawn. I later expanded this to include an SD card in order to save the dat and access it later in case I did not have an internet connection. Mostly as a fail-proof asset.
int dawnR, dawnG, dawnB;
long dawnMillis;
JSONVar myDataObject;
JSONVar apiSunTimesRequest(JSONVar myDataObject) {
// assemble the path for the GET message:
String path = "/sun";
// send the GET request
Serial.println("making GET request");
httpclient.get(path);
// read the status code and body of the response
int statusCode = httpclient.responseStatusCode();
String response = httpclient.responseBody();
Serial.print("Status code: ");
Serial.println(statusCode);
Serial.print("/sun Response: ");
Serial.println(response);
//Write the Data to the SD Card
writeToSD(response);
// parse the string into a JSONVar object:
myDataObject = JSON.parse(response);
dawnMillis = myDataObject["dawn"]["time"]["ms"];
// Set the color for each event
dawnR = myDataObject["dawn"]["color1"]["r"];
dawnG = myDataObject["dawn"]["color1"]["g"];
dawnB = myDataObject["dawn"]["color1"]["b"];
return myDataObject;
}
}
apiSunTimesRequest(myDataObject);
Form
I went though several iterations in order to get to a form which satisfied my thirst for a minimal horizon representation. I used blender in order to get a dimensionality and feel for what a wanted, and later used Illustrator in order to create the necessary shapes to later cut the shape with wood.




I quickly discarded the circle idea, and rather went for a more “horizon” kind of look. Such as this one taken by NASA:

When I was satisfied with my 3D model, I decided to makes some illustrator sketches to start building the form . The construction would consist of several wooden layers attached together to achieve the required volume. The ‘Front Side’ , or show side, would have no markings on it, the remaining layers would be the main structure. These would be cut with laser to acquire the best precision possible, and would also allow me to design the frame in order to contain the components out of view.
I also started drawing out possible angles and the necessary depth of the volume, translating into how many layers of wood I would need. I decided on six layers of wood, each with a depth of 6mm. As you can see below, my idea was to make a 45 degree angle in the middle layers in order to place the lights on top



So at first I just played around with the shape of each of the layers on top of each other:


Getting a feel on how I would fit the components inside. As a minimum, the leanest slice would at least have to have 2.6 cms, So that was the measure I used as the scale for the other slices.



After several failed cuts, designs, and a lot of illustrator, I finally arrived at the design below, which divided each of the 5 “out-of-view” pieces to be cut into three separate pieces, each one with a hole for wooden dowels.


Production
The Strips
The strips come in a silicon enclosure, so I cut it off to have more access to the strip itself. The enclosure is so nice I actually felt sad about having to cut it. Besides, it cost a lot.



I then made a little jig in order to be able to keep my lights a distance away while I still worked on them from my computer. See it below:


The structure
First approaches:

Failed design:




After 3 different failed cuts, I arrived at this design. Look at that beauty:





Putting it all together
I pasted the strips on the device using double-sided tape, and also sent the connecting cables inside the frame to the Arduino compartment as you can see below.







Finishing it up
So….How does it look?

HUGE THANKS TO:
- Jeff Feddersen
- Benjamin Light
- Schuyler Devos
API Website/ Server : https://horizonte-api.herokuapp.com/
Github API Repository: https://github.com/lacouture100/Horizonte-API
API Website/ Server : https://horizonte-api.herokuapp.com/
Github API Repository: https://github.com/lacouture100/Horizonte-API
Github project Repository: https://github.com/lacouture100/ITP-Time/tree/master/MidTerm