For our Physical Computing Final Project, we partnered with CLASS, an organization promoting community inclusion for people with disabilities, to create an assistive reminder device for Glenn, a Pittsburgh community member with memory and vision challenges.
The device helps Glenn track tasks like birthdays, feeding his dog, taking medicine, and changing his insulin pump using four glowing tabs with icons. At reminder times, it glows, speaks, and displays a large red message, such as “It’s time to take your pills.” Glenn stops reminders by pulling and reinserting the tab.
An internal clock manages events. There is an edit function for adjustments like changing medication times or resetting for daylight savings. If reminders overlap, Glenn can replay messages with the repeat button or by interacting with the glowing tabs. This allows him to hear and see the each of the reminders again. This device is designed to be simple and helpful for Glenn’s daily life.
A front view of the Reminder Box with the tabs put in resting position and the screen displaying a reminder for Glenn to take his medicine.
Each morning, Glenn sits down in his chair, and the reminder device beside him gently glows, signaling it’s time for his first task. A large red message appears on the e-ink display: “It’s time to take your medicine,” accompanied by a voice reminder. Glenn pulls out the tab to stop it. Later, the device glows again, this time for a birthday reminder, with the voice saying, “Remember to get a gift for Maria!” Glenn pushes the button to repeat the message and calls Access to schedule a time for him to go shopping. As the day goes on, the device helps him keep track of feeding his dog and other tasks, each with a glowing tab and clear message. Designed with his needs in mind, the device becomes a simple, effective part of his routine, ensuring he stays on top of important events.
A photograph of the overall reminder box in its off-state, showing the top interface as well as the front view of the tabs and the icons.
A photograph of the side door on the right side of the device that allows Glenn to replace the real-time clock battery when needed.
A photograph of the user pulling out the first tab, which is a reminder for Glenn to take his medicine.
A detailed photograph of the top interface, which has the E-ink screen to display the reminders, a button to repeat the reminder, an edit function to change the dates or times of reminders, and a volume button.
In this video, we show how the device is used with the pulling and pushing of the tabs. Each tab is for a different reminder, which, from left to right, is a reminder for medicine taking, insulin pump changing, dog feeding, and birthdays. When it is time for a reminder to go off, that tab will light up, which prompts the user to pull the tab out. Once they have completed the task, they will push the tab back in to let the device know that it has been complete.
For this first prototype we wanted to test what font sizes and colors were the easiest for Glenn to read. As a result we decided on the font size and red color that worked best for Glenn and were able to discuss with him how he wanted us to phrase the messages.
In this testing we wanted to find out what buttons and physical mechanics would work best for Glenn and what functions he wanted associated with each. As a result of our discussion with Glenn we found which shape and type of button was preferred and it turned into a discussion of the complexity of each button and what types would be helpful.
We both wanted to discuss with glenn the total size of the device as well as what screen angle would be optimal for him to read from. We did this through testing two plane boxes of different sizes as well as our cardboard model which had an adjustable top plate. As a result of this testing we chose an angle of screen that Glenn felt comfortable reading from. Were able to transition into a conversation into where the device will be placed and how that would affect the placement of other components like the power cord and speaker. In the photo to the right you can see Ben acting as a table to help Glenn picture what it would be like reading from the device if it were placed on his side table.
In this testing we wanted to both further explain our concept to Glenn and help him picture more of what the final device would look like which is why we used acrylic. We wanted to test out if he wanted a handle with a cut out for fingers or if he wanted more to grab on to with layered acrylic. As a result of this testing we found that Glenn liked having a solid handle to grab onto and we were able to discuss how we would lean further into the sci-fi aesthetic with the handle design.
During the prototyping phase, we explored handle design, screen angle, button type, text size, and overall form factor to determine what would work best for Glenn. We found that Glenn preferred a solid handle for easy gripping and an angled screen for comfortable reading. The font size and color were adjusted for optimal visibility, and we decided on a sci-fi purple aesthetic based on Glenn's love of purple. Knowing the device would be placed on a side table by his chair in the living room helped us decide on the device’s size and the placement of components.
Feedback from the critique helped us confirm the use of an e-ink display for adjustable text size and color, with large, red, Sans Serif fonts being easiest for Glenn to read. We also learned that Glenn had little preference for button size, opting for medium-sized buttons instead of the larger ones we initially thought would be necessary due to his vision impairment. After determining its location in Glenn’s home, we positioned the power cord near the outlet and the speaker near his chair, with the lamp in the area making the e-ink screen practical since it's difficult to see in low lighting. A surprise during prototyping was the need to increase the height of the device by about an inch and a half to accommodate the electronics.
A first prototype of the box design made out of wood. We did not consider the amount of space that was needed to hold the wires at the bottom of the box. After consideration, we made the box have more space at the bottom to hold these electronics.
As we were adjusting the total size of the box, we needed to test out the different positions of the handles and their ability to hit the push sensors we were originally planning on using. This wasn't consistently working well, so in the end, we switched to IR Beam sensors.
We needed to test out communication between the Raspberry Pi Pico and Arduino Uno would, and wanted to use as little pins as possible for other components. So the video shows simple serial communication (only using 2 pins other than groun and power) between the Pico and Uno by typing into the Arduino's serial port.
The inside of the box when we were working on connecting all the components together and figuring out how long wires need to be to stay in place when the box is closed. Since some already soldered wires were too short or too long, we had to re-solder a few connections.
Soldering the wires onto the E-ink display. Since the space given to us for soldering on the E-ink display was very small, we had to be very careful and attentive while doing this.
Laser cutting and gluing together the tabs made of transparent purple acrylic. Each handle consists of three layers of 1/8 inch acrylic to create enough thickness for Glenn to pull and push on the tabs.
A taped-up iteration of the final box with the lights turned on to test the transparency of the tabs. We had to adjust the placement of the LEDs on the back wall to make sure that they would shine through the clear tabs.
Our process was fairly linear and progressed well throughout the majority of the project. We ran into issues, mainly at the end, with things malfunctioning. Throughout the process, we made sure to check that everything would fit well into the box, and this helped us later without having to redo the final box multiple times once everything was wired. Throughout the process, we followed the Gantt chart well and worked to make sure as much as possible was done before we went on Thanksgiving break. We did a great job of using the prototype phase to answer a lot of questions and move forward confidently. This helped us progress well and stay on track. We worked relatively well at pivoting throughout; when things like the mechanics of having the handles hit the switches weren't consistently functioning well, we switched to IR Beam sensors. Unfortunately, in the end, a lot of our components were fried when we accidentally used too much voltage. However, the components of the device were all well thought out and relatively organized.
Most of our critique feedback focused on the device’s lack of functionality, which limited the content of the feedback received.
One helpful suggestion was reversing the placement of the icons beneath the handles. Reviewers pointed out that the handles somewhat obscured the icons, which we missed because we integrated the handles later in the process than we should have. Another piece of feedback was to include a grill in front of the speaker to protect it, a simple yet important suggestion that we hadn't considered as beginners with electronics.
We particularly liked the feedback about the handles: “The handle form factor is great, but sliding/wobbling (of the sliding task cards) could be optimized.” Initially, we planned to use drawer slides for the handles, but after moving away from that for financial reasons, trial and error revealed challenges in making the movement smooth. The movement of the handles was a challenge that we would have liked to spend more time on. It was great to hear how many people appreciated the device’s design, with one person saying, “Superb futurism. Great human-machine interaction. Not intrusive, but will not fade into the background.”
Lastly, we received the suggestion, “Make ‘programmable’ by using a smartphone app.” While this would make the device more widely usable, we felt it wouldn’t suit Glenn’s needs, as he often doesn’t carry or charge his phone. Having a smartphone app would allow for a more detailed edit feature but given Glenn's habits it would likely be underutilized.
Working with Glenn to design a device tailored to his needs was an insightful experience. One of the major takeaways was the importance of considering both functional needs and personal preferences, like his love for purple and sci-fi which heavily guided our design and greatly added to the personalized feel. Glenn was open and collaborative, providing valuable input. We were surprised by how much flexibility he showed throughout the project—he wasn't quick to shut down ideas. Once we started asking the right questions he enthusiastically participated in our design process.
Next time, we would assign components to controllers earlier, as we had to make multiple edits to our schematic when deciding which parts would connect to the Arduino Uno versus the Raspberry Pi. We’d also focus more on integrating the code with the device as a whole, not just individual parts, and dedicate more time to attachment methods for the electronics, mechanical movements of the tabs, and cable management. Additionally, we learned that the glue used with transparent acrylic affects the final appearance drastically. The biggest lesson was not powering the device with 12V instead of 5V, which fried our electronics and cost us valuable time.
This project reinforced the importance of accessible, customizable designs that meet the needs of the user and highlighted the challenges and rewards of teamwork.
"""
Reminder Box
This is code that will receive a signal from the Uno and draw the reminder on the e-ink display.
Pin mapping:
pin | role | details
------------------------------------------
~01 output E-Ink Screen
~08 output E-Ink Screen
~09 output E-Ink Screen
~10 output E-Ink Screen
~11 output E-Ink Screen
~13 output E-Ink Screen
~18 input IR Sensor (unused)
~19 input IR Sensor (unused)
~20 input IR Sensor (unused)
~21 input IR Sensor (unused)
~04 output Communication with Uno
~05 input Communication with Uno
Some of the code was taken from example code provided by Waveshare to setup the screen.
"""
from machine import Pin, SPI, UART
import time
import framebuf
import utime
# Display resolution
EPD_WIDTH = 400
EPD_HEIGHT = 300
SCK_PIN = 10
DIN_PIN = 11
RST_PIN = 1
DC_PIN = 8
CS_PIN = 9
BUSY_PIN = 13
class EPD_4in2_B:
def __init__(self):
self.reset_pin = Pin(RST_PIN, Pin.OUT)
self.busy_pin = Pin(BUSY_PIN, Pin.IN, Pin.PULL_UP)
self.cs_pin = Pin(CS_PIN, Pin.OUT)
self.sck_pin = 1
self.din_pin = 1
self.width = EPD_WIDTH
self.height = EPD_HEIGHT
self.flag = 0
self.spi = SPI(1,baudrate=4000_000,sck=Pin(SCK_PIN),mosi=Pin(DIN_PIN))
# self.spi.init(baudrate=4000_000)
self.dc_pin = Pin(DC_PIN, Pin.OUT)
self.buffer_black = bytearray(self.height * self.width // 8)
self.buffer_red = bytearray(self.height * self.width // 8)
self.imageblack = framebuf.FrameBuffer(self.buffer_black, self.width, self.height, framebuf.MONO_HLSB)
self.imagered = framebuf.FrameBuffer(self.buffer_red, self.width, self.height, framebuf.MONO_HLSB)
self.EPD_4IN2B_Init()
self.EPD_4IN2B_Clear()
utime.sleep_ms(500)
def digital_write(self, pin, value):
pin.value(value)
def digital_read(self, pin):
return pin.value()
def delay_ms(self, delaytime):
utime.sleep(delaytime / 1000.0)
def spi_writebyte(self, data):
self.spi.write(bytearray(data))
def module_exit(self):
self.digital_write(self.reset_pin, 0)
def gpio_init(self):
self.spi.deinit()
def spi_init(self):
self.spi = SPI(1,baudrate=4000_000,sck=Pin(SCK_PIN),mosi=Pin(DIN_PIN))
self.dc_pin = Pin(DC_PIN, Pin.OUT)
# Hardware reset
def reset(self):
self.digital_write(self.reset_pin, 1)
self.delay_ms(200)
self.digital_write(self.reset_pin, 0)
self.delay_ms(2)
self.digital_write(self.reset_pin, 1)
self.delay_ms(200)
def send_command(self, command):
self.digital_write(self.dc_pin, 0)
self.digital_write(self.cs_pin, 0)
self.spi_writebyte([command])
self.digital_write(self.cs_pin, 1)
def send_data(self, data):
self.digital_write(self.dc_pin, 1)
self.digital_write(self.cs_pin, 0)
self.spi_writebyte([data])
self.digital_write(self.cs_pin, 1)
def send_data1(self, buf):
self.digital_write(self.dc_pin, 1)
self.digital_write(self.cs_pin, 0)
self.spi.write(bytearray(buf))
self.digital_write(self.cs_pin, 1)
def send_read(self):
j = 0x00
self.sck_pin = Pin(SCK_PIN, Pin.OUT)
self.din_pin = Pin(DIN_PIN, Pin.IN, Pin.PULL_UP)
self.digital_write(self.dc_pin, 1)
self.digital_write(self.cs_pin, 0)
for i in range(0, 8):
self.digital_write(self.sck_pin, 0)
j = j << 1
if(self.digital_read(self.din_pin) == 1):
j = j | 0x01
else:
j = j & 0xfe
self.digital_write(self.sck_pin, 1)
self.digital_write(self.cs_pin, 1)
return j
def ReadBusy(self):
print("e-Paper busy")
if(self.flag == 1):
while(self.digital_read(self.busy_pin) == 1):
self.delay_ms(100)
else:
while(self.digital_read(self.busy_pin) == 0):
self.delay_ms(100)
print("e-Paper busy release")
def TurnOnDisplay(self):
if(self.flag == 1):
self.send_command(0x22)
self.send_data(0xF7)
self.send_command(0x20)
self.ReadBusy()
else:
self.send_command(0x12)
self.delay_ms(100)
self.ReadBusy()
def EPD_4IN2B_Init(self):
i = 0x00
self.reset()
self.send_command(0x2F)
self.delay_ms(100)
self.gpio_init()
i = self.send_read()
print(i)
self.spi_init()
if(i == 0x01):
self.flag = 1
self.ReadBusy()
self.send_command(0x12)
self.ReadBusy()
self.send_command(0x3C)
self.send_data(0x05)
self.send_command(0x18)
self.send_data(0x80)
self.send_command(0x11)
self.send_data(0x03)
self.send_command(0x44)
self.send_data(0x00)
self.send_data(self.width//8-1)
self.send_command(0x45)
self.send_data(0x00)
self.send_data(0x00)
self.send_data((self.height-1)%256)
self.send_data((self.height-1)//256)
self.send_command(0x4E)
self.send_data(0x00)
self.send_command(0x4F)
self.send_data(0x00)
self.send_data(0x00)
self.ReadBusy()
else:
self.flag = 0
self.send_command(0x04) # POWER_ON
self.ReadBusy()
self.send_command(0x00) # panel setting
self.send_data(0x0f)
def EPD_4IN2B_Clear(self):
high = self.height
if( self.width % 8 == 0) :
wide = self.width // 8
else :
wide = self.width // 8 + 1
if(self.flag == 1):
self.send_command(0x24)
self.send_data1([0xff] * high * wide)
self.send_command(0x26)
self.send_data1([0x00] * high * wide)
else:
self.send_command(0x10)
self.send_data1([0xff] * high * wide)
self.send_command(0x13)
self.send_data1([0x00] * high * wide)
self.TurnOnDisplay()
def EPD_4IN2B_Display(self,blackImage,redImage):
high = self.height
if( self.width % 8 == 0) :
wide = self.width // 8
else :
wide = self.width // 8 + 1
if(self.flag == 1):
self.send_command(0x24)
self.send_data1(blackImage)
self.send_command(0x26)
for j in range(0, high):
for i in range(0, wide):
self.send_data(~redImage[i + j * wide])
else:
self.send_command(0x10)
self.send_data1(blackImage)
self.send_command(0x13)
for j in range(0, high):
for i in range(0, wide):
self.send_data(~redImage[i + j * wide])
self.TurnOnDisplay()
def Sleep(self):
if(self.flag == 1):
self.send_command(0X10)
self.send_data(0x03)
else:
self.send_command(0X50)
self.send_data(0xf7)
self.send_command(0X02)
self.ReadBusy()
self.send_command(0X07)
self.send_data(0xA5)
# Event class to keep track of event data
class Event:
def __init__(self, day_of_week, hour, minute, event_type, message):
self.day_of_week = day_of_week
self.hour = hour
self.minute = minute
self.event_type = event_type
self.message = message
class Birthday(Event):
def __init__(self, day, month, message):
super().__init__(-1, 0, 0, 4, message)
self.day = day
self.month = month
# Initialize pins
epd = EPD_4in2_B()
uart = UART(1, baudrate=9600, tx=Pin(4), rx=Pin(5))
print("Pico Ready!")
# Events
events = {1: Event(-1, 0, 0, 1, "Time to take your pills!"), 2: Event(-1, 0, 0, 2, "Time to feed your dog!"), 3: Event(-1, 0, 0, 2, "Time to change your pump!"), 4: Birthday(1, 1, "Happy Birthday!")}
reminders = [] # queue for reminders
while True:
if uart.any():
# read data from arduino
data = uart.read()
print(f"Received Data from Uno: {data}")
decoded_data = data.decode().strip()
print(f"Received Decoded Data from Uno: {decoded_data}")
if decoded_data.isdigit(): # processing reminders
if decoded_data == "0":
if reminders:
# play next reminder
index = reminders.pop()
reminder = events[index]
reply = index
epd.EPD_4IN2B_Clear()
epd.imagered.text(reminder.message, epd.width//4, epd.height//2, 0x00)
epd.EPD_4IN2B_Display(epd.buffer_black,epd.buffer_red)
print(f"Pico reply: {reply}")
uart.write(reply)
else: # add reminder to queue
reminders.append(int(decoded_data))
print(reminders)
time.sleep(1)
"""
Reminder Box
This code will detect events based on time from the RTC and
send a signal to the Pico to draw the reminder and play the
audio once the reminder has been drawn. Lights will be lit
according to the event type of the reminder.
Pin mapping:
pin | role | details
------------------------------------------
~06 output Music Maker Shield
~07 output Music Maker Shield
~04 output Music Maker Shield
~03 output Music Maker Shield
~12 input Communication with Raspberry Pi Pico
~13 output Communication with Raspberry Pi Pico
~A3 output Button to repeat reminder
~A0 output Potentiometer to adjust volume
~08 output LED Strip for indicating reminder type
~09 output LED Strip for indicating reminder type
~10 output LED Strip for indicating reminder type
~A2 output LED Strip for indicating reminder type
Some of the code was taken from example code provided by Adafruit to setup the music maker shield.
"""
#include <Encoder.h>
#include <SoftwareSerial.h>
#include <I2C_RTC.h>
#include <PololuLedStrip.h>
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>
// These are the pins used for the music maker shield
const int SHIELD_RESET = -1; // VS1053 reset pin (unused!)
const int SHIELD_CS = 7; // VS1053 chip select pin (output)
const int SHIELD_DCS = 6; // VS1053 Data/command select pin (output)
// These are common pins between breakout and shield
const int CARDCS = 4; // Card chip select pin
// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
const int DREQ = 3; // VS1053 Data request, ideally an Interrupt pin
Adafruit_VS1053_FilePlayer musicPlayer =
// create breakout-example object!
// Adafruit_VS1053_FilePlayer(BREAKOUT_RESET, BREAKOUT_CS, BREAKOUT_DCS, DREQ, CARDCS);
// create shield-example object!
Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);
// This is to select the correct RTC
// static DS1307 RTC;
// static DS3231 RTC;
// static PCF8523 RTC;
// static PCF8563 RTC;
static MCP7940 RTC;
// These are the pins for communication between Arduino and Raspberry Pi
SoftwareSerial mySerial(12, 13);
// // These are the pins for the rotary encoder
// Encoder myEnc(2, 5);
// const int ENCODERBUTTON_PIN = 1;
// These are the pins for the button
const int REPEAT_BUT_PIN = A3;
// These are the pins for the volume knob (potentiometer)
const int VOLUME_POT_PIN = A0;
// These are the pins for the LED Strips
const int LEDSTRIP_PIN1 = 8;
const int LEDSTRIP_PIN2 = 9;
const int LEDSTRIP_PIN3 = 10;
const int LEDSTRIP_PIN4 = A2;
// Creating ledStrip objects
PololuLedStrip<LEDSTRIP_PIN1> ledStrip1;
PololuLedStrip<LEDSTRIP_PIN2> ledStrip2;
PololuLedStrip<LEDSTRIP_PIN3> ledStrip3;
PololuLedStrip<LEDSTRIP_PIN4> ledStrip4;
// Declaring a color buffer for the LED strip and preset colors to use
const int NUMLEDS = 10;
rgb_color colors[NUMLEDS];
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);
// // State to represent which mode the rotary encoder is on.
// enum State {
// DAY,
// MONTH,
// YEAR,
// HOUR,
// MINUTE,
// EVENT,
// };
// enum State state = HOUR;
// long encPosition = 0;
// Event struct to store data about events
struct Event {
int hour;
int minute;
int day;
int month;
int type; // 4 is for birthdays which only use day and month, 1-3 use hour minute
String audio[3]; // path to audio file to play
};
const int event_size = 5;
Event events[event_size];
// Examples of events
// {
// Event(-1, -1, -1, -1, -1, {}),
// Event(7, 00, -1, -1, 1, {String("/pills000.mp3")}),
// Event(12, 00, -1, -1, 1, [String("/pills000.mp3")]),
// Event(-1, -1, 1, 2, 4, {String("/feb00000.mp3"), String("/1_000000.mp3"), String("/birth000.mp3")}),
// Event(-1, -1, 23, 10, 4, {String("/oct00000.mp3"), String("/23_00000.mp3"), String("/birth000.mp3")}),
// };
// String to communicate to Pico through Serial
String receivedString = "";
void setup() {
// Initialize serial communication for Pico
Serial.begin(9600);
mySerial.begin(9600);
// Set up RTC
if (!RTC.isRunning()) {
RTC.setHourMode(CLOCK_H24);
RTC.setDateTime(__TIMESTAMP__);
RTC.startClock();
}
// Initialize Audio
if (! musicPlayer.begin()) { // initialise the music player
Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
while (1);
}
Serial.println(F("VS1053 found"));
if (!SD.begin(CARDCS)) {
Serial.println(F("SD failed, or not present"));
while (1); // don't do anything more
}
// list files
printDirectory(SD.open("/"), 0);
// Set volume for left, right channels. lower numbers == louder volume!
musicPlayer.setVolume(10, 10);
// Timer interrupts are not suggested, better to use DREQ interrupt!
//musicPlayer.useInterrupt(VS1053_FILEPLAYER_TIMER0_INT); // timer int
// If DREQ is on an interrupt pin (on uno, #2 or #3) we can do background
// audio playing
musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT); // DREQ int
// Turn off all lights
for (int i = 0; i < NUMLEDS; i++){
colors[i] = white;
}
ledStrip1.write(colors, NUMLEDS);
ledStrip2.write(colors, NUMLEDS);
ledStrip3.write(colors, NUMLEDS);
ledStrip4.write(colors, NUMLEDS);
Serial.println("UNO Ready!");
}
void loop() {
// Rotary Encoder Pseudocode
// long newEncPosition = myEnc.read();
// Serial.println(newEncPosition);
// int encoder_button = digitalRead(ENCODERBUTTON_PIN);
// if (newEncPosition != encPosition) {
// encPosition = newEncPosition;
// Serial.println(newEncPosition);
// if (state == EVENT) {
// if (encoder_button == HIGH) {
// state = event.type == 4 ? DAY : HOUR;
// }
// } else if (state == HOUR) {
// // cycle through
// } else if (state == MINUTE) {
// // cycle through
// } else {
// // cycle through
// }
// }
// Button
int button_val = digitalRead(A3);
if (button_val == LOW) {
mySerial.write(String(0).c_str());
}
// // Volume Knob
int pot_val = analogRead(VOLUME_POT_PIN);
pot_val = 255 - map(pot_val, 0, 1023, 0, 255);
musicPlayer.setVolume(pot_val, pot_val);
// Loop through events, if any of the event times match the current, send data to pico to get ready to display reminders
// also turn on lights for that event type
for (int i = 0; i < event_size; i++) {
Event event = events[i];
if (event.type == 1) {
if (RTC.getHours() == event.hour && RTC.getMinutes() == event.minute) {
mySerial.write(String(i).c_str());
for (int i = 0; i < NUMLEDS; i++){
colors[i] = white;
}
ledStrip1.write(colors, NUMLEDS);
}
} else if (event.type == 2) {
if (RTC.getHours() == event.hour && RTC.getMinutes() == event.minute) {
mySerial.write(String(i).c_str());
}
for (int i = 0; i < NUMLEDS; i++){
colors[i] = white;
}
ledStrip1.write(colors, NUMLEDS);
} else if (event.type == 3) {
if (RTC.getHours() == event.hour && RTC.getMinutes() == event.minute) {
mySerial.write(String(i).c_str());
}
for (int i = 0; i < NUMLEDS; i++){
colors[i] = white;
}
ledStrip1.write(colors, NUMLEDS);
} else if (event.type == 4) {
if (RTC.getMonth() == event.month && RTC.getDay() == event.day) {
mySerial.write(String(i).c_str());
}
for (int i = 0; i < NUMLEDS; i++){
colors[i] = white;
}
ledStrip1.write(colors, NUMLEDS);
}
}
if (Serial.available()) {
int val = Serial.read();
mySerial.write(val);
Serial.println(val);
if (val == 1) {
for (int i = 0; i < NUMLEDS; i++){
colors[i] = red;
}
ledStrip1.write(colors, NUMLEDS);
} else if (val == 2) {
for (int i = 0; i < NUMLEDS; i++){
colors[i] = green;
}
ledStrip2.write(colors, NUMLEDS);
} else if (val == 3) {
for (int i = 0; i < NUMLEDS; i++){
colors[i] = blue;
}
ledStrip3.write(colors, NUMLEDS);
} else if (val == 4) {
for (int i = 0; i < NUMLEDS; i++){
colors[i] = white;
}
ledStrip4.write(colors, NUMLEDS);
}
delay(1);
}
// receive event from pico to play audio
if (mySerial.available()) {
receivedString = mySerial.readString();
Serial.print("Received Reply from Pico: ");
Serial.print(receivedString);
Serial.print("\n");
int val = receivedString.toInt();
Event event = events[val];
// Play Audio
for (int i = 0; i < 3; i++) {
String audio = event.audio[i];
// musicPlayer.startPlayingFile(audio.c_str());
delay(1000);
}
// Turn off lights of correct LED strip
for (int i = 0; i < NUMLEDS; i++){
colors[i] = black;
}
if (val == 1) {
ledStrip1.write(colors, NUMLEDS);
musicPlayer.startPlayingFile("/pills000.mp3");
} else if (val == 2) {
ledStrip2.write(colors, NUMLEDS);
musicPlayer.startPlayingFile("/insul000.mp3");
} else if (val == 3) {
ledStrip3.write(colors, NUMLEDS);
musicPlayer.startPlayingFile("/dog00000.mp3");
} else if (val == 4) {
ledStrip4.write(colors, NUMLEDS);
musicPlayer.startPlayingFile("/birth000.mp3");
}
}
delay(50);
}
// File listing helper
void printDirectory(File dir, int numTabs) {
while(true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
//Serial.println("**nomorefiles**");
break;
}
for (uint8_t i=0; i<numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs+1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}