Physical Computing: Project 1

IMG_4398.JPG

Shematic

This was an initial schematic sketch I created. It included 7 flickering LEDs, a RTC connected to an Arduino Uno, and speaker connected to a Wave Shield on an Arduino 101 so the device can play music. The schematic shows all of this being controlled by an on off switch, but I later decided to limit the interaction to just controliing the sound with a puzzle like switch.

For my first physical computing project of the semester, I decided to create an Arduino-controlled Kinara. A Kinara is a seven-branched candleholder used in Kwanzaa celebrations. Each candle represents one of the Seven Principles of Kwanzaa and each night of the holiday one candle is lit.

IMG_4118.JPG

Construction:

The Kinara was designed on Adobe Illustrator and cut out of craft wood with a laser cutter. The base of the Kinara is two layers thick to create the Sankofa cut out and each candle has its corresponding principle in raised letters down the front.

IMG_4152.JPG

Adding Color:

After gluing I spray painted each of the candles to make them the proper color. Looking back I should have spray painted then glued on the secondary piece of wood, as there was a bit of bleeding through the protective tape barrier. I was able to sand it off, but reversing the order of operations would have made it completely avoidable.

Adding Flames:

The candle flames were taken from plastic tea lights then hot glued to the top of each candle stick. Flickering LEDs soldered to resistors and wires run down the back of each candle stick, fastened by a dollop of hot glue.

Wiring

Each of the 7 LEDs is wired to a digital port on the Arduino. The RTC would manage the date/time for the fully functional version of the Kinara is also connected to the Arduino. In order for it to manage time, a coin cell battery needs to be connected.

See the resources section at the bottom of this post for more information on the RTC and some of the tutorials I referenced.

Demo:

Below is a demo video of the Kinara in action.

Things that went wrong:

In addition to lighting, this project was supposed to have music. I purchased a WaveShield from AdaFruit but when it came time to assemble and solder I was missing some of the key bits to make the WaveShield work and had to abandon this feature for now. After my demo, my classmate Adnan shared with me a small SD card reader that could play sound through Arduino and was simpler to set up than the wave shield. In my next iteration, I will attempt to use that component to add a functioning music player to my Kinara. For this demonstration I had intended to use the song Kwanzaa by Teresa Jennings: https://www.youtube.com/watch?v=mrkoRwv0dts

Code:

Below is the code I used to demo the device. The idea of using an RTC was to have the Kinara light itself on the first day of Kwanzaa and keep time, lighting each candle at the appropriate time on the appropriate day. For demo purposes, the code is set to operate in a mini version of that 7-day cycle.

My code right now is unnecessarily long. Because the action implemented is very repetitive to condense the code one function that controls the light pattern could be written and executed under specific parameters each day, rather than setting each LED as HIGH or LOW each day.

Another area where the code could be simplified was in the naming of variables. However, I consciously chose to utilize the actual Swahili words for each principle as my variables because I wanted the values of Kwanzaa present in every aspect of this project. I feel this cultural acknowledgment should be prioritized especially because non-White, non-Western properties are often not at the forefront of tech, coding, or design.

#include <RTClib.h> RTC_PCF8523 rtc; const int timerInterruptPin = 2; const int buttonPin = 4; const int Kuji = 7; //day2 const int Ujamaa = 8; //day4 const int Kuumba = 9; //day6 const int Umoja = 10; //day1 const int Imani = 11; //day7 const int Nia = 12; //day5 const int Ujima = 13; //day3 int buttonState = 0; volatile bool countdownInterruptTriggered = false; volatile int numCountdownInterrupts = 0; void setup() { Serial.begin(57600); #ifndef ESP8266 while (!Serial); // wait for serial port to connect. Needed for native USB #endif if (! rtc.begin()) { Serial.println("Couldn't find RTC"); Serial.flush(); abort(); } //add my 7 LED functions!!! pinMode(buttonPin, INPUT); pinMode(LED_BUILTIN, OUTPUT); pinMode(Kuji, OUTPUT); pinMode(Ujamaa, OUTPUT); pinMode(Kuumba, OUTPUT); pinMode(Umoja, OUTPUT); pinMode(Imani, OUTPUT); pinMode(Nia, OUTPUT); pinMode(Ujima, OUTPUT); pinMode(timerInterruptPin, INPUT_PULLUP); // Timer configuration is not cleared on an RTC reset due to battery backup! rtc.deconfigureAllTimers(); // rtc.enableCountdownTimer(PCF8523_FrequencyHour, 24); // for actual use rtc.enableCountdownTimer(PCF8523_FrequencySecond, 20 ); //can change for demo attachInterrupt(digitalPinToInterrupt(timerInterruptPin), countdownOver, FALLING); } void countdownOver () { // Set a flag to run code in the loop(): countdownInterruptTriggered = true; numCountdownInterrupts++; } void loop () { if (countdownInterruptTriggered && numCountdownInterrupts == 1) { Serial.println(F("1st countdown interrupt triggered. Accurate timekeeping starts now.")); digitalWrite(Umoja, HIGH); //day1 digitalWrite(Kuji, LOW); digitalWrite(Ujima, LOW); digitalWrite(Ujamaa, LOW); digitalWrite(Nia, LOW); digitalWrite(Kuumba, LOW); digitalWrite(Imani, LOW); delay(15000); digitalWrite(Umoja, LOW); //day1 digitalWrite(Kuji, LOW); digitalWrite(Ujima, LOW); digitalWrite(Ujamaa, LOW); digitalWrite(Nia, LOW); digitalWrite(Kuumba, LOW); digitalWrite(Imani, LOW); countdownInterruptTriggered = false; // don't come in here again } else if (countdownInterruptTriggered && numCountdownInterrupts == 2) { Serial.println(F("2nd countdown interrupt triggered.")); digitalWrite(Umoja, HIGH); //day2 digitalWrite(Kuji, HIGH); digitalWrite(Ujima, LOW); digitalWrite(Ujamaa, LOW); digitalWrite(Nia, LOW); digitalWrite(Kuumba, LOW); digitalWrite(Imani, LOW); delay(15000); digitalWrite(Umoja, LOW); //day2 digitalWrite(Kuji, LOW); digitalWrite(Ujima, LOW); digitalWrite(Ujamaa, LOW); digitalWrite(Nia, LOW); digitalWrite(Kuumba, LOW); digitalWrite(Imani, LOW); countdownInterruptTriggered = false; // don't come in here again } else if (countdownInterruptTriggered && numCountdownInterrupts == 3) { Serial.println(F("3rd countdown interrupt triggered.")); digitalWrite(Umoja, HIGH); //day3 digitalWrite(Kuji, HIGH); digitalWrite(Ujima, HIGH); digitalWrite(Ujamaa, LOW); digitalWrite(Nia, LOW); digitalWrite(Kuumba, LOW); digitalWrite(Imani, LOW); delay(15000); digitalWrite(Umoja, LOW); //day3 digitalWrite(Kuji, LOW); digitalWrite(Ujima, LOW); digitalWrite(Ujamaa, LOW); digitalWrite(Nia, LOW); digitalWrite(Kuumba, LOW); digitalWrite(Imani, LOW); countdownInterruptTriggered = false; } else if (countdownInterruptTriggered && numCountdownInterrupts == 4) { Serial.println(F("4th countdown interrupt triggered.")); digitalWrite(Umoja, HIGH); //day4 digitalWrite(Kuji, HIGH); digitalWrite(Ujima, HIGH); digitalWrite(Ujamaa, HIGH); digitalWrite(Nia, LOW); digitalWrite(Kuumba, LOW); digitalWrite(Imani, LOW); delay(15000); digitalWrite(Umoja, LOW); //day4 digitalWrite(Kuji, LOW); digitalWrite(Ujima, LOW); digitalWrite(Ujamaa, LOW); digitalWrite(Nia, LOW); digitalWrite(Kuumba, LOW); digitalWrite(Imani, LOW); countdownInterruptTriggered = false; } else if (countdownInterruptTriggered && numCountdownInterrupts == 5) { Serial.println(F("5th countdown interrupt triggered.")); digitalWrite(Umoja, HIGH); //day5 digitalWrite(Kuji, HIGH); digitalWrite(Ujima, HIGH); digitalWrite(Ujamaa, HIGH); digitalWrite(Nia, HIGH); digitalWrite(Kuumba, LOW); digitalWrite(Imani, LOW); delay(15000); digitalWrite(Umoja, LOW); //day5 digitalWrite(Kuji, LOW); digitalWrite(Ujima, LOW); digitalWrite(Ujamaa, LOW); digitalWrite(Nia, LOW); digitalWrite(Kuumba, LOW); digitalWrite(Imani, LOW); countdownInterruptTriggered = false; } else if (countdownInterruptTriggered && numCountdownInterrupts == 6) { Serial.println(F("6th countdown interrupt triggered.")); digitalWrite(Umoja, HIGH); //day6 digitalWrite(Kuji, HIGH); digitalWrite(Ujima, HIGH); digitalWrite(Ujamaa, HIGH); digitalWrite(Nia, HIGH); digitalWrite(Kuumba, HIGH); digitalWrite(Imani, LOW); delay(15000); digitalWrite(Umoja, LOW); //day6 digitalWrite(Kuji, LOW); digitalWrite(Ujima, LOW); digitalWrite(Ujamaa, LOW); digitalWrite(Nia, LOW); digitalWrite(Kuumba, LOW); digitalWrite(Imani, LOW); countdownInterruptTriggered = false; } else if (countdownInterruptTriggered && numCountdownInterrupts == 7) { Serial.println(F("7th countdown interrupt triggered.")); digitalWrite(Umoja, HIGH); //day7 digitalWrite(Kuji, HIGH); digitalWrite(Ujima, HIGH); digitalWrite(Ujamaa, HIGH); digitalWrite(Nia, HIGH); digitalWrite(Kuumba, HIGH); digitalWrite(Imani, HIGH); delay(15000); digitalWrite(Umoja, LOW); //day7 digitalWrite(Kuji, LOW); digitalWrite(Ujima, LOW); digitalWrite(Ujamaa, LOW); digitalWrite(Nia, LOW); digitalWrite(Kuumba, LOW); digitalWrite(Imani, LOW); //Disabling countdown and detaching interrupt. rtc.disableCountdownTimer(); detachInterrupt(digitalPinToInterrupt(timerInterruptPin)); delay(2000); } }
Previous
Previous

Generated Media: New york is better than here Video

Next
Next

Physical Computing: Week 3 Labs