Chore Checker in its initial state with all tasks incomplete. All toggles are facing up and NeoPixels are lit up red. The LED strip progress bar all white on the top.
1c. A brief explanation of the project.
This project is a chore checklist that also tracks whose turn it is to clean between my roommate and I. We alternate on a weekly basis to complete chores in our apartment. The chore board alternates between colors of blue and purple, indicating the status of each person's turn. The LED strip on the top of the board showcases the progression of completion of tasks. As the toggle switches get turned down, the strip, which was initially white, lights up with either purple or blue, depending on the turn. When all the switches are turned down, the progress strip gets fully colored. Next, the user will turn all the switches up to reset the board, and it will be the next person's turn to complete the chores. This project helped me learned about wiring toggle switches to an Arduino and connecting that to both LED and neopixel outputs. In addition, I also got to explore the software logic behind switches in order to implement the outputs that I wanted.
1d. Images:
Interior Wiring of project
Three tasks completed
What it looks like with power off
Standing view of interior
1e. Video Demo
In this video, I demonstrate how the chore board works. First, it's person blue's turn. When the toggles are flipped down, after a task is completed, the corresponding red NeoPixel on the right side turns off. As each NeoPixel gets turned off, the number of LEDs on the progression strip located at the top of the board increases. After all the toggles are flipped down, meaning that the user has completed all their tasks, the LED strip on the top will start alternating and flashing until all the toggles are reset (flipped up). Now, it's user purple's turn. The same logic applies to the second user, but the progression on the LED strip fills up with purple instead of blue this time. This continues by alternating between the two users using the two LED colors of blue and purple.
2. Process images and review
Your process section should have at least 4 photos each of which is captioned, and ~100–300 words describing any aspect(s) of your process you'd like your readers to know about. Did something surprise you with how well or how terribly it went? Did something take much longer than expected? Did you get lucky and something worked out unexpectedly? Tell us about it.
Drawing schematic out
First Lasercut Design
Second Lasercut Iteration
Light output wiring completed
In the middle of soldering
Adding acrylic strips
Adding the Side Frame
The process started with figuring out how the LED strips, NeoPixels, and toggle switches would be wired together. There were 8 toggle switches, so each of them had to be connected to a pin as input since we needed to know the status of each one individually. There were also 8 separate NeoPixels, but I could not connect each one as an output pin because there wouldn't be enough pins, so I chained them together by connecting the output of one to the input of the next one. While building the checklist and attaching the electrical components to the board, I realized that the holes for my NeoPixels were 1-3mm off, so the jumper wires could not be attached. Due to that issue, I had to laser cut my board again with the adjustments. That took some time because I ended up having to take the pieces off the first wooden board and attach them to the new board. However, after the changes had been made, the rest of the process of wiring components up and programming went smoothly.
3. Discussion
Overall, I am relatively happy with how my project turned out because the logic of the button works exactly as I had intended it to work. The LEDs turn on smoothly when the actions are implemented on the board. It switches between the two users successfully after all the tasks are completed, prompting the reset of switches. I found that I spent a lot of time designing the whole checklist board because the measurements would have to be adjusted multiple times to make sure that the switches fit perfectly. However, I did enjoy putting everything together when the measurements were adjusted correctly. Creating the code logic took some time as I needed to make both the LED strips and Neopixels work in different ways, but it wasn't too difficult.
Next time, I would try to get all the soldering done and wired up before laser cutting the design because components can change throughout that process, so it would be more efficient to make the case last. I would also want to explore more complex electrical components to use in my design and experiments with their code implementations. Additionally, I also thought about adding two reset buttons so that the board can be reset at any time by either user without going through all the switches. That would be a useful feature when users decide to switch their turns in the chore sequence. If I were to build another iteration or just continue working on the project, I would definitely add the two rest buttons.
I did not have time to implement everything that was suggested to me during the critiques in class. For instance, someone mentioned that I could add a holder for the dry-erase marker so the user can easily access it when writing on the chore board. I really like that idea because it sounds like a useful addition that would complete the whole design. Multiple individuals also brought up the idea of using dry-erase strips for the part of the board where users write the task. However, I was not able to obtain the material, so the acrylic strips were the next best option.
4. Technical information
Code submission
/*
Chore Checklist
This piece of code controls the LED strips and Neopixel lights based on the user's input, which results in the change of state on the switches on the checklist board. The code implements the logic of the LED lightings based on whether or not all the tasks have been completed and indicates to the user whose turn it is to complete the chores. When the toggles are measured as high, that means a task has been completed. If all the toggles are set to high, the LED on the top status bar will start alternating colors, indicating that it's the next user's turn. The lights will keep alternating until all toggles have been reset to low. Once all toggles are reset, the status bar will use the second color to indicate completion. The loop keeps going between the two users with colors of blue and purple.
Citation:
- Code edited by ChatGPT
/*
#include <Adafruit_NeoPixel.h>
#include <PololuLedStrip.h>
const int LEDSTRIPPIN = 2; // pin to connect strip to
const int PIXELPIN = 3; //pin to connect neopixel to
const int NUMLEDS = 8; // number of LEDs in the strip
//button pins
const int BUTTON1 = 6;
const int BUTTON2 = 7;
const int BUTTON3 = 8;
const int BUTTON4 = 9;
const int BUTTON5 = 10;
const int BUTTON6 = 11;
const int BUTTON7 = 12;
const int BUTTON8 = 13;
//brightness of the neopixels
const int BRIGHTNESS = 16;
// Create an ledStrip object and specify the pin it will use.
PololuLedStrip<LEDSTRIPPIN> ledStrip;
// Create an array for holding the colors (3 bytes per color).
rgb_color testing[NUMLEDS];
rgb_color tasks[NUMLEDS];
// rgb_color
rgb_color black = rgb_color(0, 0, 0);
rgb_color white = rgb_color(255, 255, 255);
rgb_color red = rgb_color(255, 0, 0);
rgb_color orange = rgb_color(255, 75, 0);
rgb_color yellow = rgb_color(255, 255, 0);
rgb_color green = rgb_color(0, 255, 0);
rgb_color blue = rgb_color(0, 0, 255);
rgb_color indigo = rgb_color(75, 0, 130);
Adafruit_NeoPixel strip(NUMLEDS, PIXELPIN, NEO_RGB + NEO_KHZ800);
//check if all the switches are off
bool allSwitchesOff(const int pins[], int n) {
for (int k = 0; k < n; k++) if (digitalRead(pins[k]) == LOW) return false; // LOW = ON
return true;
}
uint8_t turn = 0; // turn 0 = Person 1 and turn 1 = Person 2
const rgb_color TURN_COLOR[2] = { blue, indigo }; // fill color per turn
const rgb_color CELEB_ALT[2] = { white, red }; // alternating blink colors
//LED strip will continously blink until the user have = reset all the buttons
void blinkUntilAllOff(const int pins[], int nPins,
rgb_color c1, rgb_color c2,
uint16_t ms = 150) {
while (!allSwitchesOff(pins, nPins)) {
for (int j = 0; j < NUMLEDS; j++) tasks[j] = (j & 1) ? c1 : c2;
ledStrip.write(tasks, NUMLEDS); delay(ms);
for (int j = 0; j < NUMLEDS; j++) tasks[j] = (j & 1) ? c2 : c1;
ledStrip.write(tasks, NUMLEDS); delay(ms);
}
}
void pololuFill(int count, rgb_color fill) {
for (int j = 0; j < NUMLEDS; j++) tasks[j] = (j < count) ? fill : white;
ledStrip.write(tasks, NUMLEDS);
}
//reset to original state for the next user
void resetStrips() {
for (int j = 0; j < NUMLEDS; j++) tasks[j] = white; // Pololu baseline
ledStrip.write(tasks, NUMLEDS);
for (int j = 0; j < NUMLEDS; j++) strip.setPixelColor(j, 0); // NeoPixels off
strip.show();
}
void setup() {
//sets up all the input and output pins
pinMode(LEDSTRIPPIN, OUTPUT);
pinMode(PIXELPIN, OUTPUT);
pinMode(BUTTON1, INPUT_PULLUP);
pinMode(BUTTON2, INPUT_PULLUP);
pinMode(BUTTON3, INPUT_PULLUP);
pinMode(BUTTON4, INPUT_PULLUP);
pinMode(BUTTON5, INPUT_PULLUP);
pinMode(BUTTON6, INPUT_PULLUP);
pinMode(BUTTON7, INPUT_PULLUP);
pinMode(BUTTON8, INPUT_PULLUP);
Serial.begin(9600);
strip.begin();
strip.setBrightness(BRIGHTNESS);
// strip.show();
for (int i = 0; i < NUMLEDS; ++i) tasks[i] = white;
ledStrip.write(tasks, NUMLEDS);
}
void loop() {
//reading switch values
int button1val = digitalRead(BUTTON1);
int button2val = digitalRead(BUTTON2);
int button3val = digitalRead(BUTTON3);
int button4val = digitalRead(BUTTON4);
int button5val = digitalRead(BUTTON5);
int button6val = digitalRead(BUTTON6);
int button7val = digitalRead(BUTTON7);
int button8val = digitalRead(BUTTON8);
int buttonVals[8] = {button1val, button2val, button3val,
button4val, button5val, button6val, button7val, button8val};
const int BUTTONS[8] = {BUTTON1,BUTTON2,BUTTON3,BUTTON4,BUTTON5,BUTTON6,BUTTON7,BUTTON8};
Serial.println(button1val);
int complete = 0;
for (uint16_t i = 0; i < NUMLEDS; i++) {
int buttonval = buttonVals[i];
if (buttonval == HIGH){
strip.setPixelColor(i, strip.Color(0, 255, 0)); // R,G,B
} else {
strip.setPixelColor(i, 0);
}
}
strip.show();
// Pololu: fill using the current turn's color
int onCount = 0;
for (int i = 0; i < NUMLEDS; i++) if (buttonVals[i] == LOW) onCount++;
pololuFill(onCount, TURN_COLOR[turn]);
// When all ON → celebrate with alternating colors, then wait until all OFF, reset, and switch turns
if (onCount == NUMLEDS) {
// quick indication with alternating lights on the strip
for (int t = 0; t < 6; t++) {
for (int j = 0; j < NUMLEDS; j++) tasks[j] = (j & 1) ? CELEB_ALT[0] : CELEB_ALT[1];
ledStrip.write(tasks, NUMLEDS); delay(120);
for (int j = 0; j < NUMLEDS; j++) tasks[j] = (j & 1) ? CELEB_ALT[1] : CELEB_ALT[0];
ledStrip.write(tasks, NUMLEDS); delay(120);
}
// keep blinking (turn colors) until all switches are OFF --> reset
blinkUntilAllOff(BUTTONS, NUMLEDS, TURN_COLOR[turn], white, 180);
// reset visuals
resetStrips();
// ---- TOGGLE TURN HERE ----
turn ^= 1; // next player/turn
}
delay(5);
}