Every year, on Christmas Eve, Santa Claus leaves his home in Rovaniemi (iin Finland, closed to the Arctic Circle) to travel all around the world and give presents to all the children. Wouldn't it be great if we can track Santa Claus position and be ready when he is approaching our city?
The idea is to build an ornament that display Santa Claus position in realtime on globe... but to add some dramatic to the ornament, the goal is to draw the globe by leveraging the persistence of vision or retinal persistence. Basically, a strip of LED rotates fast enough to give your eyes the illusion of a "solid" globe
Schematic
The heart of the project is an Arduiono Nano 33 IoT, which is connected to
- PIN 3: this is the input from the proximity sensor. More details about the prosimity sensor are available in my roadtest
- PIN 6: this is the output to control the WS2812 LED strips. Note that, because the LED strip uses a 5V control signal, I had to add a level shifter board to step up the 3.3V signal from Arduino to the 5V required by the LED strip
Tracking Santa position
As you may know or imagine, in a connected world even Santa Claus position is tracked. Two sources are available
- NORAD: Thsi was the original organization to provide Santa Claus's position information. This service dates back to 1955, when a typo on a newspaper caused the Norad command to receive thousands of calls from children asking for Santa Claus
- Google. This is a recet addition to the plethora of services provided by Google
I prefer the solution by Google because their undocumented API for the Santa tracking is more developer friendly. The API gives you back a JSON document with real-time information about the Santa, including
https://santa-api.appspot.com/info?client=web&language=en&fingerprint=&routeOffset=0&streamOffset=0
To request the position, we will use the WifiSSLClient class, which is included in the WiFiNINA library
#define HOST "santa-api.appspot.com" #define URL "/info?client=web&language=en&fingerprint=&routeOffset=0&streamOffset=0" WiFiSSLClient client; void requestPosition() { Serial.println("\nStarting connection to server..."); // if you get a connection, report back via serial: if (client.connect(HOST, 443)) { Serial.println("connected to server"); // Make a HTTP request: client.print("GET "); client.print(URL); client.println(" HTTP/1.1"); client.print("Host: "); client.println(HOST); client.println("Connection: close"); client.println(); } }
We are going to receive a JSON document similar to this:
{ "status":"OK", "v":"co20", "now":1672297855857, "takeoff":1671876031995, "duration":90000000, "location":"45.464203,9.189982", "route":["https://firebasestorage.googleapis.com/v0/b/santa-api.appspot.com/o/route%2Fsanta_en.json?alt=media\u0026token=x","https://firebasestorage.googleapis.com/v0/b/santa-api.appspot.com/o/route%2Fsanta.json?alt=media\u0026token=x"] }
First, we need to fetch the response. This is implemented as a loop where we check for available characters and, if anything is available, we read the character out of the receiving queue and stored in a String
// from the server, read them and print them: while (client.available()) { char c = client.read(); response += c; Serial.write(c); }
When no further data is available, we proceed with the parsing by leveraging the ArduinoJSON. First, we remove the HTTP header from the String we are going to parse (HTTP header and response are separated by an empty line, thus we look for the sequence of characters "\r\n\r\n". We can then feed the ArduinoJSON with the response and get the value of the "location" field
int idx = response.indexOf("\r\n\r\n"); if (idx > 0) { String jsonResponse = response.substring(idx+1); StaticJsonDocument<512> doc; deserializeJson(doc, jsonResponse); const char* loc = doc["location"]; location = loc; calcSantaPos(location); Serial.println(loc); response = ""; return true; }
The location is expressed as a string where latitude and longitude are separated by a comma. To extract latitude e longitude the following code is used
int idx = loc.indexOf(","); if (idx == -1) return; String lat = loc.substring(0, idx); String lon = loc.substring(idx+1); int iLat = lat.toInt(); int iLon = lon.toInt();
Since we don't need an extreme precision, we simply convert the coordinates to integer number (not to double). Finally, latitude and longitude are converted to X,Y coordinates of the image we are going to display
santaX = (NUM_LEDS/2) - ((iLat * (NUM_LEDS/2)) / 90); santaY = (NUM_COLS/2) - ((iLon * (NUM_COLS/2)) / 180);
Mechanical construction
Just not to make things too complicated, I printed the circle that hosts LEDs as a single piece. Due to my 3D printer's size limits, the circle is about 18 cm in diameter
The circular frame hosts a power bank and a breadboard with Arduino Nano 33 IoT and the connectors for
- a two-lines header strips to distribute the 5V power supply and ground from the power supply
- the input from the proximity sensor. More details about the prosimity sensor are available in my roadtest
- the output to control the WS2812 LED strips. Note that, because the LED strip uses a 5V control signal, I had to add a level shifter board to step up the 3.3V signal from Arduino to the 5V required by the LED strip
- In the picture, there is a small I2C display I used for debugging purposes and will be removed in the final setup
The initial goal was to place all the electronics outside the rotating frame, but I was not able to devise a reliable mechanism to provide the power and the control signal to the LED strip. Consequently, I mounted the power bank and the electronics inside the rotating frame. This simplifies the cabling and the mechanical construction in general, but requires some extra care to make everything balanced.
The motor is hosted in a 3D-printed base. On the top of the motor, I added a reference tag for the proximity sensor. The reference tag can is movable so that the globe can be rotated around its vertical axes
To limit vibrations due to the unbalanced frame, I made a plywood C-shaped support, where the above-mentioned motor is placed at the bottom and a smaller motor is placed at the top. The top motor is not going to be driven: it is just an easy way to get a bearing-mounted shaft
Controlling the LEDs strip
To draw the image, I will use a strip of WS2812 LEDs. LEDs are controlled by means of the FastLED library. To synchronize the update of LEDs with the rotation of the frame, I installed a proximity sensor.
The proximity sensor triggers an input when it passes over the mark attached to the base. The output signal form the proximity sensor is connected to PIN n.3, which, according to the documentation, can be connected to an interrupt routine
#define SENSOR_PIN 3 void setup() { ... pinMode(SENSOR_PIN, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), sensorISR, RISING); ... }
The interrupt routine (called sensorISR), sets the sensorDetected flag, which in turns triggers the update of the LEDs. To support different speeds, the time between two consecutives passes over the mark is calculated.
void sensorISR() { sensorDetected = true; unsigned long currMicros = micros(); if (prevMicros != 0) { rotDuration = currMicros - prevMicros; if (rotDuration < minDuration) minDuration = rotDuration; if (rotDuration > maxDuration) maxDuration = rotDuration; } detects ++; prevMicros = currMicros; }
The sensorDetected flag signals that the LED strip needs to be updated. This task is performed by the updateLEDs function. This function takes the duration calculated by the sensorISR to determine the columns refresh rate. More in detail, the value of rotDuration is divided by the number of the columns of the image to reproduce. This gives us the delay between two columns of the image or, in other words, the delay between updates of the LEDs string.
void updateLEDs(const unsigned char* image) { int i, r; unsigned long colDelay = rotDuration / NUM_COLS; const unsigned char* ptr = image; for (i=0; i<NUM_COLS; i++) { unsigned long startMicros = micros(); const unsigned char* tmp = ptr; for (r=0; r<NUM_LEDS; r++) { if ((r == santaX) && (i == santaY)) leds[(NUM_LEDS-1)-r] = CRGB(100, 0, 0); else leds[(NUM_LEDS-1)-r] = CRGB(*(tmp+2), *(tmp+1), *(tmp+0)); tmp += (NUM_COLS * 4); } FastLED.show(); if (i < NUM_COLS-1) { unsigned long elapsedMicros = micros() - startMicros; if (elapsedMicros < colDelay) delayMicroseconds(colDelay - elapsedMicros); else overflows ++; } ptr += 4; } }
The updateLEDs function takes an input argument which is the image to draw. This is an array of BGRA values (each value is an unsigned char - i.e. an 8-bit value) generated from a picture by this online converter
As an example, this is the original image
This is the resized image (40 x 31 pixels)
And this is the output of the online converter (this is an image made of 31 rows and 40 columns; each pixels as four bytes - R, G, B and alpha, which is always set to 0xff, but is ignored by the sketch)
0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x36, 0x0e, 0x0e, 0xff, 0x3c, 0x18, 0x18, 0xff, 0x5b, 0x40, 0x3f, 0xff, 0x77, 0x6d, 0x6e, 0xff, 0xa8, 0x9e, 0x9d, 0xff, 0x8d, 0x7c, 0x7c, 0xff, 0xaf, 0x9f, 0x9f, 0xff, 0xbc, 0xaf, 0xaf, 0xff, 0xdc, 0xd6, 0xd6, 0xff, 0xdc, 0xd6, 0xd6, 0xff, 0x9a, 0x87, 0x86, 0xff, 0x45, 0x20, 0x20, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x47, 0x27, 0x25, 0xff, 0x51, 0x31, 0x2e, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x3c, 0x15, 0x15, 0xff, 0x45, 0x1f, 0x1f, 0xff, 0x36, 0x0e, 0x0e, 0xff, 0x34, 0x0b, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x55, 0x36, 0x36, 0xff, 0x41, 0x1d, 0x1c, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x3b, 0x2e, 0x32, 0xff, 0x4d, 0x40, 0x43, 0xff, 0x53, 0x3e, 0x3f, 0xff, 0x73, 0x66, 0x65, 0xff, 0x79, 0x75, 0x77, 0xff, 0x56, 0x38, 0x36, 0xff, 0x68, 0x4e, 0x4b, 0xff, 0xa6, 0x98, 0x95, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xfb, 0xfb, 0xff, 0x9a, 0x95, 0x91, 0xff, 0x34, 0x0b, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x3d, 0x1b, 0x19, 0xff, 0x39, 0x14, 0x13, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0b, 0x0b, 0xff, 0x50, 0x35, 0x32, 0xff, 0x42, 0x20, 0x1f, 0xff, 0x32, 0x0c, 0x0c, 0xff, 0x33, 0x25, 0x27, 0xff, 0x3e, 0x42, 0x48, 0xff, 0x41, 0x53, 0x5a, 0xff, 0x37, 0x32, 0x35, 0xff, 0x31, 0x14, 0x14, 0xff, 0x31, 0x0e, 0x0d, 0xff, 0x39, 0x1f, 0x1e, 0xff, 0x33, 0x0e, 0x0e, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x32, 0x18, 0x19, 0xff, 0x31, 0x15, 0x14, 0xff, 0x29, 0x39, 0x38, 0xff, 0x29, 0x31, 0x31, 0xff, 0x28, 0x27, 0x26, 0xff, 0x24, 0x27, 0x23, 0xff, 0x31, 0x39, 0x3d, 0xff, 0x35, 0x52, 0x58, 0xff, 0x32, 0x3f, 0x3d, 0xff, 0x37, 0x42, 0x43, 0xff, 0x46, 0x56, 0x5a, 0xff, 0x53, 0x5b, 0x51, 0xff, 0x4f, 0x40, 0x40, 0xff, 0x33, 0x0f, 0x0f, 0xff, 0xb8, 0xbb, 0xb9, 0xff, 0xfe, 0xfe, 0xfe, 0xff, 0xca, 0xc2, 0xc0, 0xff, 0x4f, 0x33, 0x31, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x30, 0x13, 0x11, 0xff, 0x22, 0x2e, 0x27, 0xff, 0x22, 0x26, 0x21, 0xff, 0x2e, 0x15, 0x14, 0xff, 0x2c, 0x1f, 0x1a, 0xff, 0x2a, 0x2b, 0x28, 0xff, 0x29, 0x3a, 0x38, 0xff, 0x25, 0x43, 0x42, 0xff, 0x21, 0x4a, 0x44, 0xff, 0x23, 0x49, 0x4a, 0xff, 0x25, 0x4d, 0x4d, 0xff, 0x23, 0x4c, 0x4b, 0xff, 0x1f, 0x4a, 0x43, 0xff, 0x24, 0x42, 0x41, 0xff, 0x23, 0x47, 0x45, 0xff, 0x20, 0x43, 0x40, 0xff, 0x23, 0x31, 0x30, 0xff, 0x2c, 0x2a, 0x2c, 0xff, 0x33, 0x32, 0x36, 0xff, 0x33, 0x21, 0x22, 0xff, 0x2c, 0x29, 0x23, 0xff, 0x18, 0x42, 0x38, 0xff, 0x23, 0x4a, 0x40, 0xff, 0x1c, 0x43, 0x3c, 0xff, 0x1c, 0x43, 0x3f, 0xff, 0x18, 0x35, 0x31, 0xff, 0x1c, 0x3a, 0x37, 0xff, 0x21, 0x40, 0x45, 0xff, 0x27, 0x3c, 0x40, 0xff, 0x35, 0x29, 0x2a, 0xff, 0x35, 0x2e, 0x29, 0xff, 0x3c, 0x3b, 0x3d, 0xff, 0x34, 0x0d, 0x0d, 0xff, 0x99, 0x93, 0x92, 0xff, 0x92, 0x80, 0x7e, 0xff, 0x35, 0x0d, 0x0d, 0xff, 0x32, 0x1c, 0x1c, 0xff, 0x38, 0x1b, 0x1b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x31, 0x13, 0x11, 0xff, 0x17, 0x33, 0x29, 0xff, 0x17, 0x2a, 0x1f, 0xff, 0x12, 0x2d, 0x20, 0xff, 0x13, 0x30, 0x22, 0xff, 0x0c, 0x39, 0x27, 0xff, 0x0d, 0x3b, 0x2a, 0xff, 0x0f, 0x39, 0x2f, 0xff, 0x12, 0x37, 0x32, 0xff, 0x0d, 0x3c, 0x2b, 0xff, 0x10, 0x42, 0x31, 0xff, 0x14, 0x48, 0x38, 0xff, 0x16, 0x47, 0x39, 0xff, 0x13, 0x45, 0x36, 0xff, 0x17, 0x46, 0x3b, 0xff, 0x1f, 0x49, 0x45, 0xff, 0x1d, 0x4a, 0x44, 0xff, 0x1f, 0x46, 0x41, 0xff, 0x21, 0x4c, 0x48, 0xff, 0x27, 0x44, 0x41, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x30, 0x14, 0x10, 0xff, 0x28, 0x32, 0x29, 0xff, 0x34, 0x19, 0x15, 0xff, 0x46, 0x32, 0x2f, 0xff, 0x23, 0x43, 0x37, 0xff, 0x0e, 0x3a, 0x2a, 0xff, 0x10, 0x3b, 0x2d, 0xff, 0x15, 0x35, 0x2f, 0xff, 0x1c, 0x2d, 0x29, 0xff, 0x2f, 0x0f, 0x0f, 0xff, 0x25, 0x2d, 0x2e, 0xff, 0x23, 0x39, 0x39, 0xff, 0x30, 0x10, 0x10, 0xff, 0x33, 0x0b, 0x0b, 0xff, 0x36, 0x10, 0x0f, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x2c, 0x1a, 0x16, 0xff, 0x2d, 0x16, 0x14, 0xff, 0x18, 0x2b, 0x1f, 0xff, 0x1e, 0x28, 0x1c, 0xff, 0x0f, 0x3a, 0x26, 0xff, 0x0e, 0x40, 0x2a, 0xff, 0x0f, 0x44, 0x2e, 0xff, 0x0d, 0x42, 0x2a, 0xff, 0x0e, 0x40, 0x2d, 0xff, 0x0e, 0x3f, 0x2d, 0xff, 0x0c, 0x3d, 0x2a, 0xff, 0x0c, 0x3c, 0x26, 0xff, 0x0c, 0x3d, 0x27, 0xff, 0x12, 0x3f, 0x30, 0xff, 0x11, 0x44, 0x35, 0xff, 0x10, 0x43, 0x32, 0xff, 0x1f, 0x30, 0x26, 0xff, 0x2b, 0x1b, 0x17, 0xff, 0x25, 0x29, 0x1f, 0xff, 0x2d, 0x18, 0x14, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x34, 0x0c, 0x0b, 0xff, 0x33, 0x0d, 0x0d, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x2a, 0x1d, 0x16, 0xff, 0x17, 0x38, 0x2c, 0xff, 0x27, 0x56, 0x4f, 0xff, 0x1f, 0x50, 0x42, 0xff, 0x0f, 0x37, 0x27, 0xff, 0x0f, 0x34, 0x28, 0xff, 0x14, 0x32, 0x29, 0xff, 0x11, 0x31, 0x28, 0xff, 0x1b, 0x25, 0x1c, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x31, 0x0d, 0x0c, 0xff, 0x23, 0x34, 0x26, 0xff, 0x24, 0x34, 0x29, 0xff, 0x18, 0x44, 0x33, 0xff, 0x15, 0x4e, 0x3a, 0xff, 0x14, 0x4f, 0x39, 0xff, 0x1b, 0x53, 0x41, 0xff, 0x25, 0x57, 0x4c, 0xff, 0x28, 0x59, 0x52, 0xff, 0x2f, 0x5e, 0x5c, 0xff, 0x2e, 0x5e, 0x5b, 0xff, 0x17, 0x4b, 0x39, 0xff, 0x1e, 0x49, 0x3f, 0xff, 0x16, 0x44, 0x34, 0xff, 0x19, 0x47, 0x39, 0xff, 0x11, 0x49, 0x33, 0xff, 0x0f, 0x44, 0x2d, 0xff, 0x1a, 0x30, 0x21, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x2a, 0x1c, 0x15, 0xff, 0x33, 0x0b, 0x0a, 0xff, 0x33, 0x0b, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x24, 0x3b, 0x36, 0xff, 0x2e, 0x57, 0x59, 0xff, 0x35, 0x66, 0x64, 0xff, 0x18, 0x4b, 0x37, 0xff, 0x1a, 0x30, 0x21, 0xff, 0x0f, 0x3e, 0x29, 0xff, 0x15, 0x34, 0x21, 0xff, 0x2a, 0x17, 0x12, 0xff, 0x31, 0x0c, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x2e, 0x1e, 0x1a, 0xff, 0x1b, 0x51, 0x40, 0xff, 0x19, 0x45, 0x35, 0xff, 0x18, 0x50, 0x3d, 0xff, 0x29, 0x45, 0x39, 0xff, 0x26, 0x52, 0x43, 0xff, 0x4b, 0x6d, 0x6d, 0xff, 0x71, 0xa1, 0xaf, 0xff, 0x6a, 0x99, 0xb1, 0xff, 0x55, 0x81, 0x8b, 0xff, 0x4d, 0x7b, 0x82, 0xff, 0x62, 0x8c, 0xa0, 0xff, 0x5c, 0x86, 0x96, 0xff, 0x5c, 0x85, 0x98, 0xff, 0x32, 0x64, 0x5c, 0xff, 0x11, 0x4b, 0x32, 0xff, 0x21, 0x22, 0x16, 0xff, 0x32, 0x0c, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x37, 0x4b, 0x51, 0xff, 0x51, 0x78, 0x87, 0xff, 0x3c, 0x69, 0x6c, 0xff, 0x1d, 0x55, 0x42, 0xff, 0x17, 0x4b, 0x36, 0xff, 0x16, 0x3d, 0x29, 0xff, 0x31, 0x0e, 0x0c, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0b, 0x0b, 0xff, 0x33, 0x61, 0x67, 0xff, 0x30, 0x1a, 0x19, 0xff, 0x30, 0x24, 0x23, 0xff, 0x27, 0x3b, 0x33, 0xff, 0x38, 0x4d, 0x4f, 0xff, 0x30, 0x4c, 0x4a, 0xff, 0x3f, 0x49, 0x46, 0xff, 0x94, 0xc4, 0xdf, 0xff, 0x61, 0x90, 0xa4, 0xff, 0x54, 0x7f, 0x8a, 0xff, 0x81, 0xad, 0xc1, 0xff, 0x88, 0xac, 0xc3, 0xff, 0x7d, 0xa8, 0xc8, 0xff, 0x58, 0x87, 0x94, 0xff, 0x26, 0x4c, 0x3d, 0xff, 0x23, 0x22, 0x18, 0xff, 0x2b, 0x17, 0x11, 0xff, 0x32, 0x0b, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x39, 0x2c, 0x30, 0xff, 0x5f, 0x85, 0x9e, 0xff, 0x4a, 0x73, 0x82, 0xff, 0x1d, 0x56, 0x48, 0xff, 0x10, 0x4d, 0x36, 0xff, 0x24, 0x25, 0x1a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0b, 0x0b, 0xff, 0x51, 0x5f, 0x73, 0xff, 0x79, 0x9d, 0xb7, 0xff, 0x4a, 0x3d, 0x44, 0xff, 0x37, 0x17, 0x19, 0xff, 0x37, 0x25, 0x28, 0xff, 0x7d, 0xb1, 0xcf, 0xff, 0x63, 0x89, 0x9e, 0xff, 0x85, 0xae, 0xcd, 0xff, 0x6b, 0x97, 0xaf, 0xff, 0x57, 0x7d, 0x86, 0xff, 0x74, 0x9f, 0xb9, 0xff, 0x57, 0x86, 0x97, 0xff, 0x32, 0x61, 0x5f, 0xff, 0x21, 0x5b, 0x4b, 0xff, 0x2a, 0x32, 0x26, 0xff, 0x26, 0x22, 0x18, 0xff, 0x2a, 0x1b, 0x15, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x42, 0x4d, 0x54, 0xff, 0x56, 0x81, 0x94, 0xff, 0x28, 0x38, 0x31, 0xff, 0x24, 0x29, 0x1f, 0xff, 0x33, 0x0f, 0x0c, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x49, 0x37, 0x41, 0xff, 0x8e, 0xc1, 0xea, 0xff, 0x97, 0xd3, 0xf8, 0xff, 0x94, 0xca, 0xee, 0xff, 0xb2, 0xe2, 0xea, 0xff, 0x89, 0xaf, 0xba, 0xff, 0x98, 0xcc, 0xf1, 0xff, 0x7f, 0xa1, 0xb1, 0xff, 0x87, 0xa6, 0xbd, 0xff, 0x89, 0xb7, 0xcc, 0xff, 0x49, 0x82, 0x80, 0xff, 0x45, 0x76, 0x78, 0xff, 0x36, 0x61, 0x5a, 0xff, 0x17, 0x4c, 0x3d, 0xff, 0x11, 0x50, 0x37, 0xff, 0x23, 0x30, 0x23, 0xff, 0x33, 0x0c, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0b, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x35, 0x14, 0x15, 0xff, 0x39, 0x58, 0x5b, 0xff, 0x32, 0x1a, 0x18, 0xff, 0x30, 0x17, 0x10, 0xff, 0x3b, 0x2a, 0x15, 0xff, 0x34, 0x0b, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x8f, 0xb0, 0xc3, 0xff, 0x9c, 0xd6, 0xfb, 0xff, 0x9e, 0xd5, 0xf3, 0xff, 0x9d, 0xda, 0xf5, 0xff, 0x9d, 0xdb, 0xf7, 0xff, 0x9c, 0xce, 0xe1, 0xff, 0x7c, 0x90, 0xa7, 0xff, 0xa3, 0xd2, 0xe1, 0xff, 0x68, 0x6a, 0x75, 0xff, 0x53, 0x58, 0x5b, 0xff, 0x4a, 0x80, 0x83, 0xff, 0x42, 0x77, 0x74, 0xff, 0x25, 0x5d, 0x4a, 0xff, 0x1f, 0x58, 0x44, 0xff, 0x1c, 0x43, 0x2f, 0xff, 0x2f, 0x17, 0x12, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0b, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x2a, 0x1f, 0x19, 0xff, 0x20, 0x39, 0x2a, 0xff, 0x28, 0x23, 0x18, 0xff, 0x32, 0x11, 0x0f, 0xff, 0x31, 0x13, 0x10, 0xff, 0x33, 0x0b, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0b, 0x0b, 0xff, 0x77, 0xa2, 0xb7, 0xff, 0x99, 0xd8, 0xec, 0xff, 0x91, 0xca, 0xef, 0xff, 0xb7, 0xf3, 0xfa, 0xff, 0x96, 0xd6, 0xf5, 0xff, 0x93, 0xcd, 0xef, 0xff, 0x5e, 0x70, 0x7e, 0xff, 0x96, 0xc4, 0xdd, 0xff, 0x4d, 0x34, 0x35, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x43, 0x66, 0x71, 0xff, 0x34, 0x23, 0x22, 0xff, 0x2f, 0x34, 0x2c, 0xff, 0x24, 0x58, 0x46, 0xff, 0x31, 0x12, 0x0f, 0xff, 0x2f, 0x14, 0x11, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x32, 0x0c, 0x0b, 0xff, 0x29, 0x29, 0x1f, 0xff, 0x2e, 0x1b, 0x17, 0xff, 0x2d, 0x2b, 0x24, 0xff, 0x31, 0x10, 0x0e, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x29, 0x51, 0x41, 0xff, 0x39, 0x77, 0x72, 0xff, 0x4e, 0x8f, 0x95, 0xff, 0x4a, 0x8e, 0x8c, 0xff, 0x3d, 0x7f, 0x79, 0xff, 0x3b, 0x7a, 0x76, 0xff, 0x3b, 0x68, 0x6a, 0xff, 0x4d, 0x44, 0x52, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x3a, 0x3f, 0x40, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x14, 0x0f, 0xff, 0x25, 0x3f, 0x32, 0xff, 0x31, 0x11, 0x0f, 0xff, 0x2c, 0x1a, 0x13, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x34, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x32, 0x0d, 0x0c, 0xff, 0x25, 0x3d, 0x30, 0xff, 0x16, 0x50, 0x40, 0xff, 0x18, 0x38, 0x29, 0xff, 0x2e, 0x11, 0x0f, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x2f, 0x19, 0x14, 0xff, 0x26, 0x44, 0x34, 0xff, 0x30, 0x45, 0x39, 0xff, 0x15, 0x54, 0x3d, 0xff, 0x0c, 0x4b, 0x30, 0xff, 0x16, 0x58, 0x40, 0xff, 0x3d, 0x6e, 0x7f, 0xff, 0x48, 0x43, 0x59, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x32, 0x10, 0x0f, 0xff, 0x32, 0x0c, 0x0c, 0xff, 0x2f, 0x11, 0x0e, 0xff, 0x2b, 0x1b, 0x14, 0xff, 0x2c, 0x12, 0x0e, 0xff, 0x2b, 0x19, 0x12, 0xff, 0x32, 0x0b, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x34, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0b, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x20, 0x47, 0x38, 0xff, 0x0b, 0x3b, 0x25, 0xff, 0x0c, 0x3d, 0x29, 0xff, 0x1a, 0x36, 0x29, 0xff, 0x33, 0x0e, 0x0c, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x12, 0x42, 0x33, 0xff, 0x0a, 0x3b, 0x27, 0xff, 0x1a, 0x43, 0x36, 0xff, 0x39, 0x56, 0x64, 0xff, 0x33, 0x0c, 0x0d, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x32, 0x0d, 0x0b, 0xff, 0x22, 0x2e, 0x1d, 0xff, 0x14, 0x36, 0x21, 0xff, 0x29, 0x19, 0x11, 0xff, 0x2c, 0x13, 0x0e, 0xff, 0x30, 0x0e, 0x0c, 0xff, 0x33, 0x0b, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0b, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0b, 0x0b, 0xff, 0x17, 0x40, 0x30, 0xff, 0x0a, 0x37, 0x20, 0xff, 0x0a, 0x39, 0x22, 0xff, 0x10, 0x48, 0x35, 0xff, 0x22, 0x4c, 0x45, 0xff, 0x32, 0x10, 0x0f, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x21, 0x34, 0x2e, 0xff, 0x15, 0x44, 0x3b, 0xff, 0x22, 0x4d, 0x4c, 0xff, 0x2c, 0x27, 0x25, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x2d, 0x1e, 0x14, 0xff, 0x2b, 0x1b, 0x14, 0xff, 0x2d, 0x14, 0x10, 0xff, 0x2e, 0x12, 0x0d, 0xff, 0x1e, 0x38, 0x28, 0xff, 0x29, 0x1b, 0x14, 0xff, 0x32, 0x0d, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x2a, 0x32, 0x30, 0xff, 0x0e, 0x3e, 0x2c, 0xff, 0x10, 0x42, 0x2f, 0xff, 0x1f, 0x4c, 0x44, 0xff, 0x29, 0x49, 0x4a, 0xff, 0x33, 0x0b, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x29, 0x2d, 0x2c, 0xff, 0x1a, 0x44, 0x42, 0xff, 0x1e, 0x45, 0x44, 0xff, 0x27, 0x2a, 0x26, 0xff, 0x31, 0x0f, 0x0e, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x31, 0x0f, 0x0e, 0xff, 0x33, 0x23, 0x1f, 0xff, 0x33, 0x20, 0x16, 0xff, 0x30, 0x0f, 0x0c, 0xff, 0x32, 0x0c, 0x0b, 0xff, 0x33, 0x0b, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0b, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x37, 0x17, 0x1a, 0xff, 0x35, 0x58, 0x5f, 0xff, 0x19, 0x49, 0x3e, 0xff, 0x2e, 0x57, 0x5a, 0xff, 0x29, 0x37, 0x35, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x41, 0x4d, 0x57, 0xff, 0x3a, 0x5f, 0x68, 0xff, 0x28, 0x4e, 0x51, 0xff, 0x2b, 0x20, 0x1d, 0xff, 0x2e, 0x29, 0x2c, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x3a, 0x30, 0x36, 0xff, 0x3f, 0x66, 0x7d, 0xff, 0x3d, 0x56, 0x60, 0xff, 0x32, 0x1c, 0x1c, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0c, 0x0b, 0xff, 0x32, 0x0c, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x4b, 0x60, 0x72, 0xff, 0x1d, 0x4b, 0x41, 0xff, 0x23, 0x48, 0x41, 0xff, 0x2f, 0x19, 0x17, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x46, 0x3f, 0x4c, 0xff, 0x54, 0x79, 0x8e, 0xff, 0x32, 0x4c, 0x51, 0xff, 0x33, 0x14, 0x15, 0xff, 0x31, 0x1e, 0x21, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x3a, 0x28, 0x34, 0xff, 0x47, 0x67, 0x92, 0xff, 0x46, 0x66, 0x8f, 0xff, 0x53, 0x7d, 0xa6, 0xff, 0x39, 0x4a, 0x52, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x32, 0x0c, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x43, 0x5e, 0x69, 0xff, 0x23, 0x4e, 0x47, 0xff, 0x27, 0x29, 0x23, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x3c, 0x21, 0x27, 0xff, 0x52, 0x75, 0x92, 0xff, 0x33, 0x31, 0x36, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x35, 0x21, 0x26, 0xff, 0x3c, 0x5b, 0x7b, 0xff, 0x41, 0x5f, 0x89, 0xff, 0x62, 0x8c, 0xb9, 0xff, 0x36, 0x57, 0x62, 0xff, 0x32, 0x0c, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x31, 0x0c, 0x0b, 0xff, 0x42, 0x5f, 0x66, 0xff, 0x28, 0x49, 0x42, 0xff, 0x32, 0x0e, 0x0d, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x34, 0x29, 0x2d, 0xff, 0x33, 0x0d, 0x0d, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x30, 0x0f, 0x0d, 0xff, 0x2f, 0x23, 0x24, 0xff, 0x33, 0x0e, 0x0e, 0xff, 0x34, 0x4a, 0x4f, 0xff, 0x2a, 0x3d, 0x3b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x31, 0x0d, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x30, 0x13, 0x10, 0xff, 0x3b, 0x53, 0x5b, 0xff, 0x32, 0x17, 0x15, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x32, 0x0e, 0x0c, 0xff, 0x2c, 0x13, 0x0f, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0b, 0x0b, 0xff, 0x2b, 0x1a, 0x13, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x43, 0x2a, 0x26, 0xff, 0x3d, 0x45, 0x4d, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x34, 0x0b, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x32, 0x17, 0x16, 0xff, 0x33, 0x0c, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x44, 0x27, 0x24, 0xff, 0x3a, 0x33, 0x32, 0xff, 0x32, 0x0d, 0x0c, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x35, 0x0c, 0x0c, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x34, 0x0b, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0c, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x34, 0x0b, 0x0b, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x3a, 0x14, 0x14, 0xff, 0x48, 0x27, 0x27, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x37, 0x12, 0x12, 0xff, 0x38, 0x11, 0x11, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x38, 0x11, 0x11, 0xff, 0x3e, 0x1a, 0x19, 0xff, 0x3f, 0x19, 0x17, 0xff, 0x3a, 0x14, 0x13, 0xff, 0x3b, 0x13, 0x13, 0xff, 0x48, 0x23, 0x22, 0xff, 0x38, 0x10, 0x10, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x39, 0x12, 0x12, 0xff, 0x39, 0x12, 0x12, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x45, 0x22, 0x23, 0xff, 0x92, 0x8c, 0x8f, 0xff, 0x57, 0x3c, 0x3c, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x41, 0x1d, 0x1d, 0xff, 0x63, 0x4e, 0x51, 0xff, 0x6a, 0x55, 0x58, 0xff, 0x6a, 0x53, 0x52, 0xff, 0x58, 0x42, 0x44, 0xff, 0x6d, 0x5e, 0x60, 0xff, 0x8b, 0x79, 0x75, 0xff, 0xb6, 0xbb, 0xc0, 0xff, 0xaf, 0xb9, 0xc2, 0xff, 0x78, 0x73, 0x74, 0xff, 0x7b, 0x71, 0x75, 0xff, 0xb5, 0xc1, 0xca, 0xff, 0xb8, 0xbb, 0xbc, 0xff, 0xc6, 0xbe, 0xb3, 0xff, 0xb4, 0xab, 0xa0, 0xff, 0xcd, 0xcd, 0xcb, 0xff, 0xc1, 0xca, 0xce, 0xff, 0xbb, 0xc1, 0xc5, 0xff, 0xa4, 0x9c, 0x9c, 0xff, 0x7c, 0x6c, 0x6d, 0xff, 0x4b, 0x2d, 0x2f, 0xff, 0x33, 0x0a, 0x0a, 0xff, 0x36, 0x0e, 0x0e, 0xff, 0x35, 0x0d, 0x0d, 0xff, 0x46, 0x23, 0x23, 0xff, 0x65, 0x4c, 0x4c, 0xff, 0x7f, 0x6e, 0x6e, 0xff, 0x8f, 0x86, 0x87, 0xff, 0x8e, 0x86, 0x85, 0xff, 0x84, 0x7b, 0x7c, 0xff, 0x87, 0x81, 0x83, 0xff, 0xac, 0xb4, 0xb9, 0xff, 0x9c, 0x9d, 0xa1, 0xff, 0x98, 0x99, 0x9b, 0xff, 0xa1, 0xa8, 0xab, 0xff, 0x6b, 0x5c, 0x5b, 0xff, 0x3f, 0x1c, 0x1a, 0xff, 0x3b, 0x14, 0x13, 0xff, 0x43, 0x22, 0x20, 0xff, 0x7f, 0x75, 0x75, 0xff, 0xb0, 0xb5, 0xb7, 0xff, 0xb4, 0xbe, 0xc4, 0xff, 0xb3, 0xbd, 0xc2, 0xff, 0xb8, 0xc1, 0xc7, 0xff, 0xb4, 0xc0, 0xc9, 0xff, 0xad, 0xba, 0xc2, 0xff, 0xb5, 0xb8, 0xb8, 0xff, 0xae, 0xb5, 0xb8, 0xff, 0x99, 0xa1, 0xa5, 0xff, 0x8d, 0x90, 0x8f, 0xff, 0xa9, 0xad, 0xae, 0xff, 0xac, 0xb4, 0xba, 0xff, 0x9b, 0xa2, 0xa6, 0xff, 0xa2, 0xa8, 0xab, 0xff, 0xbf, 0xcc, 0xd5, 0xff, 0xba, 0xc8, 0xd3, 0xff, 0xa4, 0xae, 0xb4, 0xff, 0xaf, 0xb4, 0xb6, 0xff, 0xb0, 0xb5, 0xb7, 0xff, 0xab, 0xae, 0xb1, 0xff, 0x5d, 0x45, 0x47, 0xff, 0x42, 0x1f, 0x1f, 0xff, 0xa6, 0xa1, 0x99, 0xff, 0xaa, 0xa3, 0x9a, 0xff, 0x9b, 0x95, 0x8b, 0xff, 0x8e, 0x8a, 0x84, 0xff, 0x8a, 0x89, 0x83, 0xff, 0x9a, 0x95, 0x8c, 0xff, 0xa6, 0xa3, 0x9c, 0xff, 0xa2, 0xa5, 0xa5, 0xff, 0x9a, 0xa0, 0xa3, 0xff, 0x9d, 0xa5, 0xa9, 0xff, 0x94, 0x97, 0x98, 0xff, 0x85, 0x82, 0x7c, 0xff, 0x7f, 0x79, 0x6f, 0xff, 0x7b, 0x72, 0x65, 0xff, 0x87, 0x81, 0x78, 0xff, 0x85, 0x7e, 0x73, 0xff, 0x87, 0x82, 0x7a, 0xff, 0x90, 0x8e, 0x89, 0xff, 0x94, 0x98, 0x98, 0xff, 0xa3, 0xac, 0xb1, 0xff, 0xa0, 0xa3, 0xa4, 0xff, 0x99, 0x9b, 0x9a, 0xff, 0x9b, 0x9d, 0x9c, 0xff, 0x98, 0xa0, 0xa5, 0xff, 0x8e, 0x9b, 0xa3, 0xff, 0x8e, 0x9a, 0xa2, 0xff, 0x90, 0x9a, 0xa0, 0xff, 0x8f, 0x98, 0x9d, 0xff, 0x91, 0x9a, 0x9e, 0xff, 0x96, 0x9d, 0xa1, 0xff, 0x9d, 0xa3, 0xa7, 0xff, 0x9e, 0xa7, 0xac, 0xff, 0xa0, 0xa6, 0xaa, 0xff, 0xa3, 0xa8, 0xaa, 0xff, 0x9e, 0xa2, 0xa3, 0xff, 0xa0, 0xa5, 0xa7, 0xff, 0x9f, 0xa4, 0xa6, 0xff, 0x8e, 0x89, 0x88, 0xff, 0x9b, 0x97, 0x93, 0xff, 0xa2, 0x9f, 0x99, 0xff, 0xa7, 0xa8, 0xa9, 0xff, 0xaa, 0xab, 0xac, 0xff, 0xa8, 0xa5, 0xa3, 0xff, 0xa4, 0xa0, 0x9c, 0xff, 0xac, 0xac, 0xaa, 0xff, 0xad, 0xad, 0xab, 0xff, 0xac, 0xaf, 0xaf, 0xff, 0xa6, 0xaa, 0xab, 0xff, 0xaf, 0xb5, 0xb8, 0xff, 0xb6, 0xbc, 0xbf, 0xff, 0xab, 0xad, 0xad, 0xff, 0xab, 0xab, 0xa8, 0xff, 0xa7, 0xa4, 0x9f, 0xff, 0xa6, 0xa6, 0xa3, 0xff, 0xb0, 0xb4, 0xb4, 0xff, 0xb7, 0xbc, 0xbe, 0xff, 0xb7, 0xbc, 0xbd, 0xff, 0xb1, 0xb7, 0xba, 0xff, 0xb1, 0xb7, 0xba, 0xff, 0xae, 0xb4, 0xb6, 0xff, 0xaa, 0xb0, 0xb2, 0xff, 0xa5, 0xac, 0xb0, 0xff, 0xa2, 0xaa, 0xae, 0xff, 0xa2, 0xaa, 0xaf, 0xff, 0xa2, 0xab, 0xb1, 0xff, 0xa2, 0xaa, 0xaf, 0xff, 0xa4, 0xa9, 0xab, 0xff, 0xa9, 0xae, 0xb0, 0xff, 0xab, 0xb0, 0xb2, 0xff, 0xab, 0xb0, 0xb2, 0xff, 0xa9, 0xaf, 0xb2, 0xff, 0xa7, 0xad, 0xb1, 0xff, 0xa5, 0xab, 0xae, 0xff, 0xa6, 0xac, 0xae, 0xff, 0xa8, 0xae, 0xb0, 0xff, 0xad, 0xb4, 0xb8, 0xff, 0xb0, 0xb9, 0xbe, 0xff, 0xb0, 0xb8, 0xbd, 0xff, 0xa2, 0xa3, 0xa4, 0xff, 0xa8, 0xaa, 0xab, 0xff,
The size of the input image must be of the correct size: NUM_COLS in width and NUM_PIXELS in height
NUM_COLS is defined as
#define NUM_COLS 40
but can be changed. The more the column the more detailed is the image, but there is a limit related to the time it takes to update the LED strip. NUM_PIXELS is the the number of pixels installed on the circular frame. In my case
#define NUM_LEDS 25
Application logic
The Arduino sketch can be in four states
- APP_STARTUP: the Arduino sketch has just started. In this phase, a rainbow is shown. In the meantime, Arduino connects to Wifi network
- APP_FETCHING: in this phase, the Salta Claus position is queried. When a valid response is received, the application transitions to the APP_MAP state
- APP_MAP: the map with Santa location is shown. After 5 seconds, the application transitions to APP_SNOWFLAKE. Every 60 seconds, the application transitions to the APP_FETCHING state to get the updated Santa location
- APP_SNOWFLAKE: for demo purposes, every 5 seconds a snowflake is shown. After 5 seconds, the application goes back to the APP_MAP state
BOM
Description | Link | |
Arduino nano 33 iot | https://it.farnell.com/arduino/abx00032/scheda-svil-nano-33-iot-basetta/dp/3404693?st=nano | |
TT Electronics Reflective Optical Sensor |
https://it.farnell.com/tt-electronics-optek-technology/opb9001ac/ref-optical-sensor-module-4-5/dp/3276003?CMP=e14c-roadtest-RoadTest_7c36cdb7f8e44cb9b1ec9726493e4e2b-TT_ELECTRONICS%20/%20OPTEK%20TECHNOLOGY&COM=e14c-roadtest-RoadTest_7c36cdb7f8e44cb9b1ec9726493e4e2b-TT_ELECTRONICS%20/%20OPTEK%20TECHNOLOGY |
|
Power bank | ||
USB cable (to bring +5V and GND to electronics breadboard) | ||
Male and female strips | https://it.farnell.com/amp-te-connectivity/826926-2/header-diritta-bifase/dp/1248140 | |
Level shifter | https://www.amazon.it/dp/B07RDHR315?psc=1&ref=ppx_yo2ov_dt_b_product_details | |
12V DC motor | Recovered from a battery drill, but alternatives are available here https://it.farnell.com/pro-elec/pel00883/dc-motor-high-torque-6-12v/dp/3383478 | |
6V mini DC motor | Recovered from a toy, but alternatives are available here https://it.farnell.com/pro-elec/pel00883/dc-motor-high-torque-6-12v/dp/3383478 | |
15 x 10 cm plywood (15 mm thick) | ||
15 x 5 cm plywood (15 mm thick) |
||
26 x 10 cm plywood (15 mm thick) |
||
Steel angular brackets |
Demo
Unfortunately I do not have a professional camera that can make videos with a high frame rate or with a global shutter. For this reason, you will see many artifacts in the video I made to demonstrate the project features. Also, I had to use a black&-white images to have enough contrast and make the images visible in the video. In particular, I used the following images
The colored map is much more fancy than the black&white map. Also the rainbow effect can not be clearly seen, but you can have a better idea by looking at the light reflected on the wall on the back
Here are some picture I took. As you can see, it's impossible with my camera to take a decent picture of the globe
This is the rainbow effect. Taking a picture of direct LEDs light saturates the camera sensor and all pixels look white
This is the colored map. Again, the luminosity of the pixels saturates the camera sensor and colors can't be distinguished
With a black&white image, at least we can see image contours (this is the snowflake)
Here is the link to the same video with a better quality
Source code and 3D-printed parts
All source and STL files for the printed parts are available on my github
Here are two images to illustrate the position of the 3D-printed parts