The most wonderful time of the year is here, which always conjures up the age-old question- “What do I wear to all the holiday events?”. For me the answer is simple, an ugly sweater, the uglier the better. Ugly sweaters are great because they’re warm, they’re festive, and they’re a built-in conversation starter. But I see many of the same people at these holiday events and don’t want to start the same conversation each time. I need options for my small talk, and yes I want my sweater to be the one to provide them. Why not outsource even that aspect of the human experience to technology? It’s one of the most annoying aspects! So with that in mind, I set off on a quest to build the smartest holiday sweater around.
My requirements for this sweater were:
- Must light up so I could make jokes about it being merry and bright
- Must have at least two separate conversation starters built into it aside from the standard “Wow, that’s quite the sweater”
- Must be able to look like a semi-normal sweater when not turned on so I don’t get stared at in public
- Must change regularly so even if I saw the same people at different events the conversation would be a bit different
- Must not electrocute, burn, or otherwise maim me
With those requirements in mind and inspiration from a sign in front of a local bank, I decided to build the Introvert’s Holiday Survival Sweater. This sweater contains a 16 x 16 LED matrix that counts down the time until Christmas, shows pre-programmed holiday-themed pictures, and says bye for you when it’s after 10pm. In short, it brings the party with you wherever it goes.
Supplies needed
Components:
- Particle board: A Boron is ideal for cellular connectivity, but a Photon 2 or Argon works for WiFi-only setups.
- 16×16 addressable LED matrix (WS2812B): For colorful animations.
- Level shifter: Ensures the 3.3V data signal from the Particle board works with the 5V LEDs.
- 4 x AA battery holder with 4 AA batteries: Rechargeable batteries provide roughly 5V.
- Tip: For testing, use a wired 5V supply before switching to batteries.
- Breadboard and wires: For prototyping and connections.
- Project housing: I used an old case I had lying around. You can use something pre-bought or make your own. Altoid containers are pretty useful for this if you’re in a pinch.
- Sweater or sweatshirt: Something sturdy enough to support the electronics.
- Fabric: For creating a pocket for the electronic housing.
Tools:
- Soldering iron and solder: For permanent connections.
- Hot glue gun: For securing components.
- Computer running Particle Workbench: For coding.
Skills needed
- Basic soldering knowledge.
- Familiarity with C++ programming and microcontrollers.
- A sense of humor for when something inevitably goes wrong (or maybe that’s just me).
Step 1: Wiring the components
Matrix pinout
The WS2812B matrix has three key connections:
- VCC (5V): This pin supplies power to the LEDs. It must receive a stable 5V power supply to avoid flickering or damage to the LEDs.
- GND (Ground): Completes the circuit. It is crucial that all components in the circuit share a common ground to function correctly.
- Data In: This pin receives a signal from the Particle board to control the LEDs. The data signal must be boosted to 5V using a level shifter for reliable operation.
Powering the matrix
- Connect the matrix to the battery holder:
- Locate the VCC (5V) wire on the LED matrix. Using a jumper wire, connect this pin to the positive terminal of the 4 x AA battery holder. If you’re using a breadboard, connect the VCC pin to the positive rail.
- Locate the GND pin on the LED matrix. Connect it to the negative terminal of the battery holder. If using a breadboard, connect the GND pin to the ground rail.
Important: Double-check the polarity of the battery holder before connecting it to avoid reversing the voltage, which can damage the components.
Connecting the data line
The data line allows the Particle board to control the LED matrix.
- Connect the Particle board to the matrix:
- Locate the Data In pin on the LED matrix. Connect it to D2 on the Particle board using a jumper wire.
- Add a level shifter:
- The Particle board sends a 3.3V data signal, but the WS2812B LEDs require a 5V signal. Insert a level shifter between the D2 pin of the Particle board and the Data In pin of the matrix.
- Connect the input side of the level shifter to the Particle board’s D2 pin.
- Connect the output side of the level shifter to the LED matrix’s Data In pin.
- The Particle board sends a 3.3V data signal, but the WS2812B LEDs require a 5V signal. Insert a level shifter between the D2 pin of the Particle board and the Data In pin of the matrix.
- Power the level shifter:
- Connect the level shifter’s HV (High Voltage) pin to the 5V power rail (from the battery holder).
- Connect its LV (Low Voltage) pin to the 3.3V output from the Particle board.
- Ensure the GND pin of the level shifter is connected to the shared ground.
Sharing ground
All components must share a common ground for proper operation.
- Connect the GND pin of the Particle board to the same GND rail used by:
- The LED matrix.
- The battery holder.
- The level shifter.
- Use jumper wires to ensure a consistent ground connection across all devices.
Testing the setup
Before switching to the battery holder, test the setup with a wired 5V power supply:
- Replace the 4 x AA battery holder with a regulated 5V DC power source.
- Connect the positive terminal of the power supply to the VCC rail.
- Connect the negative terminal to the GND rail.
- Turn on the power supply and observe the LEDs. If the wiring is correct:
- The LEDs should light up in their default state.
- The Particle board should communicate successfully with the LED matrix.
- If the LEDs do not light up:
- Check the connections for loose or incorrect wiring.
- Verify the level shifter is functioning properly.
Once you’ve confirmed everything works with the wired power supply, switch to the 4 x AA battery holder for portable use. This ensures your setup is stable and prevents troubleshooting issues later
Step 2: Programming the Particle board
The provided code is the heart of your project. It controls the LED matrix, calculates the days until Christmas, and alternates between patterns like a Christmas tree, the word “BYE,” and a countdown.
Understanding the code
The provided code is the backbone of the Introvert’s Holiday Survival Sweater. It orchestrates the LED animations, calculates the days until Christmas, and switches between various festive patterns. Below is a breakdown of the key components and their functionality.
Initialization
The initialization section sets up the NeoPixel library, defines constants, and configures the LED matrix and colors.
#include <neopixel.h>
#include "Particle.h"
SYSTEM_MODE(AUTOMATIC);
SerialLogHandler logHandler(LOG_LEVEL_INFO);
#define NUM_ROWS 16
#define NUM_COLS 16
#define PIXEL_COUNT (NUM_ROWS * NUM_COLS)
#define PIXEL_PIN D2
#define WEAR_PIN D3
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, WS2812B);
#define RED strip.Color(255, 0, 0)
#define GREEN strip.Color(0, 255, 0)
#define OFF strip.Color(0, 0, 0)
NUM_ROWS
andNUM_COLS
: Define the size of the LED matrix (16×16 grid).PIXEL_COUNT
: Total number of LEDs on the matrix.PIXEL_PIN
: Specifies the pin (D2) used to send data to the LED matrix.- Colors like
RED
andGREEN
are pre-defined for use in animations.
Pattern definitions
The patterns are stored as 16×16 grids, where 1
represents an illuminated pixel and 0
represents a blank pixel.
const uint8_t TREE_PATTERN[16][16] = {
{0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
...
};
TREE_PATTERN
: Creates a simple Christmas tree.- Similar patterns are defined for the countdown (e.g., “DAYS,” “UNTIL,” and “XMAS”).
Calculating days until Christmas
This function calculates the number of days left until December 25th, accounting for the current date and time.
int calculateDaysUntilChristmas() {
int currentYear = Time.year();
int currentMonth = Time.month();
int currentDay = Time.day();
if (currentMonth == 12 && currentDay > 25) {
currentYear++;
}
struct tm currentTime = {0};
currentTime.tm_year = currentYear - 1900;
currentTime.tm_mon = currentMonth - 1;
currentTime.tm_mday = currentDay;
time_t now = mktime(¤tTime);
struct tm christmasTime = {0};
christmasTime.tm_year = currentYear - 1900;
christmasTime.tm_mon = 11; // December
christmasTime.tm_mday = 25;
time_t christmas = mktime(&christmasTime);
return (christmas - now) / 86400; // Convert seconds to days
}
- This function uses
mktime
to calculate the difference in days between the current date and Christmas.
Displaying patterns
The displayPattern
function lights up the LEDs according to a 16×16 pattern grid.
void displayPattern(const uint8_t pattern[16][16], uint32_t color) {
strip.clear();
for (int row = 0; row < NUM_ROWS; row++) {
for (int col = 0; col < NUM_COLS; col++) {
if (pattern[row][col] == 1) {
int pixelIndex = row * NUM_COLS + col;
strip.setPixelColor(pixelIndex, color);
}
}
}
strip.show();
delay(2000); // Display for 2 seconds
}
- Loops through the grid and illuminates LEDs corresponding to
1
in the pattern array. - The
setPixelColor
function assigns the desired color to each LED.
Countdown animation
This function lights up a number of LEDs to represent the days left until Christmas.
void displayCountdown(int days) {
strip.clear();
for (int i = 0; i < days && i < PIXEL_COUNT; i++) {
strip.setPixelColor(i, GREEN);
}
strip.show();
delay(2000);
}
- Lights up the first
days
LEDs in green, capped at the number of LEDs in the matrix.
Scrolling the “GOODBYE” message
This function scrolls the “GOODBYE” pattern horizontally across the matrix.
void scrollGoodbye() {
for (int offset = NUM_COLS; offset > -NUM_COLS; offset--) {
strip.clear();
for (int row = 0; row < NUM_ROWS; row++) {
for (int col = 0; col < NUM_COLS; col++) {
int matrixCol = col + offset;
if (matrixCol >= 0 && matrixCol < NUM_COLS && GOODBYE_PATTERN[row][col] == 1) {
int pixelIndex = row * NUM_COLS + matrixCol;
strip.setPixelColor(pixelIndex, RED);
}
}
}
strip.show();
delay(150);
}
}
- Shifts the “GOODBYE” pattern across the matrix, creating a scrolling effect.
Main program logic
The loop
function alternates between displaying patterns during the day and scrolling “GOODBYE” at night.
void loop() {
int currentHour = Time.hour();
int daysUntil = calculateDaysUntilChristmas();
if (currentHour >= 22) {
scrollGoodbye();
} else {
displayPattern(TREE_PATTERN, GREEN);
displayPattern(DAYS_PATTERN, RED);
displayCountdown(daysUntil);
displayPattern(UNTIL_PATTERN, RED);
displayPattern(XMAS_PATTERN, RED);
}
}
- Between 10 PM and midnight, the sweater displays the “GOODBYE” scrolling message.
- During the day, it alternates between the Christmas tree, countdown, and other festive patterns.
How the sweater works
- During setup, the LEDs initialize, and brightness is set to a low level to avoid overpowering glare.
- The main loop continuously calculates the time, displays patterns, and switches animations based on the time of day.
- Festive patterns like the Christmas tree and countdown keep the sweater dynamic and engaging.
- After 10 PM, the scrolling “GOODBYE” animation lets everyone know the sweater is ready to retire for the night.
By understanding these sections, you can appreciate how the code brings your holiday sweater to life with intelligent animations and festive charm!
Loading the code
- Open Particle Workbench on your computer.
- Copy the provided code and paste it into the main
.ino
file. - Connect your Particle board to your computer via USB.
- Compile the code and flash it to the Particle board using the “Flash” button in Particle Workbench.
Step 3: Attaching the components to the sweater
Once the hardware is tested and the code is running, it’s time to assemble your sweater.
Securing the LED matrix
- Choose a placement:
- The matrix works best on the front center of the sweater for maximum visibility.
- Attach the matrix:
- Use a hot glue gun or hand-stitch the matrix onto the sweater. Ensure the LEDs face outward and the wiring is accessible from the inside.
Creating a pocket for the electronics
- Add fabric for a pocket:
- Sew or glue a fabric pocket to the inside of the sweater, large enough to hold the Particle board, level shifter, and battery pack.
- Organize the components:
- Place the Particle board, level shifter, and battery holder in the pocket.
- Ensure the connections are secure and won’t pull apart with movement.
Routing and hiding wires
- Tuck the wires:
- Run the wires along the seams of the sweater to keep them out of sight.
- Use zip ties or fabric tape to secure the wires in place.
- Secure connections:
- Double-check that all connections (e.g., the data line to D2, power to the battery pack) are tight and properly insulated.
Step 4: Final assembly and testing
- Power up the sweater:
- Insert batteries into the holder and turn on the system. The LED matrix should light up with the programmed animations.
- Check for comfort:
- Wear the sweater to ensure it’s comfortable and the electronics are secure.
- Final decorations:
- Add extra holiday flair, such as tinsel, ornaments, or a festive border around the matrix.
Conclusion
Congratulations! Your Introvert’s Holiday Survival Sweater is ready to light up holiday parties and spark festive conversations. Wear it proudly and let your tech-savvy creation spread the holiday cheer! 🎄✨