Pages

430AlarmClock

This piece of code was made possible by Trey German, Robert Wessels, and Cathy Wicks of Texas Instruments. Without Trey’s knowledge and Cathy’s encouragement, I wouldn’t have been able to make this program. Robert is the one who told me about this project.

When creating 430AlarmClock, I adhered to my usual procedure for designing programs:

0. Make a general outline
1. Get the hardware
2. Write the basic stuff
3. Tweak, test, repeat until it works
4. Add/remove/tweak features until you are satisfied
5. Publish, add license, do whatever else you need to do

I made the outline first. It looked like this:
• Clock with increment of 1s/s, overflow each digit pair after 23:59:59
• At least 1 alarm
• If user turns off alarm but fails to get up within 10 minutes, connect to social media, email, etc. to say something like “I turned my alarm clock off but never got up.”

For hardware, I used an MSP430-F5529LP with a Grove BoosterPack.

I poked around and found the required libraries. They can be found on the Grove wiki.

After that, I started in on the code. The first segment was pretty simple: make the clock tick.

#include <TM1637.h>
TM1637 out1(9, 10); //HH:MM
TM1637 out2(3, 4);  //SS

Here I initialize a pair of 7-segment LED drivers. They communicate via I2C, so they only need 2 pins each.

int8_t startTime[3] = {12,49,30};
int8_t hours, minutes, seconds;

startTime[3] will hold the time the clock’s starting time. hours, minutes, and seconds will hold the current time.

void setup() {
  out1.init();
  out1.set(BRIGHT_TYPICAL);
  
  out2.init();
  out2.set(BRIGHT_TYPICAL);
}

The setup() method only runs once, so it is useful for one-time tasks such as initializing devices, setting pinModes, and starting Serial communication. Here I use it to initialize the 7-segment displays and I set their brightness to BRIGHT_TYPICAL, which is best for use indoors. For use outdoors, change this to BRIGHTEST.

void loop() {
  out1.display(0, (hours-(hours%10))/10);
  out1.display(1, hours%10);
  
  out1.display(2, (minutes-(minutes%10))/10);
  out1.display(3, minutes%10);
  
  out2.display(0, (seconds-(seconds%10))/10);
  out2.display(1, seconds%10);
  
  seconds = getSeconds()%60;
  minutes = getMinutes()%60;
  hours = getHours()%24;
  
  delay(100);
}

The first six lines tell the TM1637s to display the current time (which, for the first tick, is 00:00:00). Then we update the time. The reason for doing it this way is so first it tests the displays, then it updates the time and sends it, then repeats.

int getSeconds() {
  return millis()/1000 + startTime[2];
}

int getMinutes() {
  return getSeconds()/60 + startTime[1];
}

int getHours() {
  return getMinutes()/60 + startTime[0];
}

The getSeconds(), Minutes(), and Hours() functions took me some time to work out though. But eventually I figured it out: getSeconds() calculates how many seconds have gone by and adds the starting seconds to that. getMinutes() turns getSeconds() into minutes and adds the starting minutes to it, and so on and so forth.

The next step was to implement the alarm. It was pretty simple:

Add uint8_t alarm[] = {HH, MM, SS};
Add a boolean to say if the alarm is active or not (alarmActive).
Also, #define buzzer.
Then, add this into loop():

  if((seconds == alarm[2]) && (minutes == alarm[1]) && (hours == alarm[0])) alarmActive = true;
  
  if(alarmActive) {
    tone(buzzer, 200*(seconds%minutes));
  } else {
    noTone(buzzer);
  }

The first line makes the alarm go off when the current time equals the alarm’s time. The next if statement controls the buzzer, whose pitch changes every second to be super annoying.

I used an ultrasonic tripwire to detect if the user had gotten up or not.

I imported Ultrasonic.h, made a new Ultrasonic object called tripwire, and assigned it to pin 39.
I then made a tripwire reference (called tripwireRef) so that the tripwire wouldn’t constantly trigger. It initialized in setup().

  tripwireRef = getDistance();

I also had to make my own getDistance() method so not detecting anything (closest object > ultrasonic sensor range) wouldn’t disable the alarm. If the sensor detected nothing, it would default to 0.

int8_t getDistance() {
  int8_t value = tripwire.MeasureInInches();
  if(value < 2) value = 127;
  return value;
}

Then I added the code to turn the alarm off:

  if(getDistance() < tripwireRef-2) alarmActive = false;

The tripwireRef-2 is because the tripwire’s reading fluctuates, but generally never >±2.

Then I found out that the WiFi BoosterPack was fried, so I couldn’t go any further.

Here is the final version of my code: 430AlarmClock.zip Enjoy!

photo

Leave a Reply