Physical Computing: Project 1
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.
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.
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); } }
Links to Resources/Acknowledgements:
RTC Setup Tutorial https://www.youtube.com/watch?v=kGjYwAqAp6A
RTC interrupt Tutorial https://www.youtube.com/watch?v=lyvoOEO-Ncg
RTC Library Info https://adafruit.github.io/RTClib/html/class_r_t_c___p_c_f8523.html#ae8d6c49c65fa7b509f76380a33b282ca
Playing music with the Wave Shield
Dave Stein helped with coding. Leia Chang helped with laser cutting.