Slappy: mbed Multi-sense Alarm Clock
ECE 4180 Final Design Project: by William Castro, Josh Fordham, Joe Gustainis, and Stein Lobo
Project Overview
SLAPPY is a multi-sense alarm clock, which, in addition to playing annoying alarm noises to wake you up, will actually slap you awake with a motorized arm!

Features
Soft, cushioned motorized arm flaps back and forth, slapping anything in its path
Variety of annoying loud noises using speaker and audio amplifier
C# GUI using HTTP requests sets alarm, through private web server
Extra vibration motor on the base add addition noise
Information
Below are tables showing the hook-up guide for the SLAPPY Hardware
H-Bridge for Motor Hookup
| H-Bridge | Pin |
|---|---|
| PWMA | p21 |
| AIN2 | p23 |
| AIN1 | p22 |
| VMOT | +5v |
| AO1 | neg (on motor 1) |
| AO2 | pos (on motor 1) |
| AO1 | pos (on motor 2) |
| AO2 | neg (on motor 2) |
| STBY | VCC (with 5.1k ohm resistor) |
Ethernet Magjack Pinout
| Touchpad Pin | Pin |
|---|---|
| GND | gnd |
| VCC | vout |
| SDA | p9 w pullup |
| SCL | p10 w pullup |
| IRQ | p24 |
Touchpad Pinout
| Touchpad Pin | Pin |
|---|---|
| GND | gnd |
| VCC | vout |
| SDA | p9 w pullup |
| SCL | p10 w pullup |
| IRQ | p24 |
SD Card Reader
| SD Reader Pin | Pin |
|---|---|
| VCC | Vout |
| DO | p6 |
| SCK | p7 |
| GND | GND |
| DI | p5 |
| CS | p8 |
| Ethernet Magjack | Pin |
|---|---|
| P1 | TD- |
| P2 | TD+ |
| P7 | RD- |
| P8 | RD+ |
Speaker Setup
Information
This is the speaker hookup guide.
https://developer.mbed.org/users/4180_1/notebook/using-a-speaker-for-audio-output/
Code for mbed 1
Note that this project required two mbeds due to RAM constraints with multiple threads.
// Includes
#include "mbed.h"
#include "wave_player.h"
#include "SDFileSystem.h"
#include "rtos.h"
#include "mpr121.h"
//MOTOR
PwmOut controlMotor(p21);
DigitalOut ain1(p22);
DigitalOut ain2(p23);
DigitalIn control(p26);
InterruptIn interrupt(p24);
AnalogOut DACout(p18);
SDFileSystem sd(p5, p6, p7, p8, p12, "sd"); //SD card
FILE *wave_file;
wave_player waver(&DACout);
I2C i2c(p9, p10);
Mpr121 mpr121(&i2c, Mpr121::ADD_VSS);
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
DigitalOut feedback(p25);
void alarm_sound(void const * args), codeInterrupt(void const * args);
//
int main()
{
Thread thread1(alarm_sound);
Thread thread2(codeInterrupt);
interrupt.mode(PullUp);
while(1) {
if(feedback==1) {
controlMotor=0;
return 0;
}
if (control == 1 && feedback == 0) {
controlMotor = 1;
ain1 = 1;
ain2 = 0;
wait(.4);
ain1 = 0;
ain2 = 1;
wait(.4);
} else {
ain1 = 0;
ain2 = 0;
wait(.5);
ain1 = 0;
ain2 = 0;
wait(.5);
controlMotor=0;
}
}
}
//Alarm Sound
void alarm_sound(void const *args)
{
while(1) {
if (control == 1 && feedback == 0) {
wave_file = fopen("/sd/wavfiles/alarm.wav", "r");
waver.play(wave_file);
fclose(wave_file);
}
}
}
void codeInterrupt(void const * args)
{
// while(1) {
// int key_code=0;
// int i=0;
// int value=mpr121.read(0x00);
// value +=mpr121.read(0x01)<<8;
// // LED demo mod
// i=0;
// // puts key number out to LEDs for demo
// for (i=0; i<12; i++) {
// if (((value>>i)&0x01)==1) key_code=i+1;
// }
// led4=key_code & 0x01;
// led3=(key_code>>1) & 0x01;
// led2=(key_code>>2) & 0x01;
// led1=(key_code>>3) & 0x01;
// }
int key_code=0;
int i=0;
int val=11;
char code[4];
while(1) {
int value=mpr121.read(0x00);
value +=mpr121.read(0x01)<<8;
for (i=0; i<12; i++) {
if (((value>>i)&0x01)==1) key_code=i;
}
if(val != key_code) {
if (code[0] == NULL) {
led1=1;
code[0] = (char)key_code;
} else if (code[1] == NULL) {
led2=1;
code[1] = (char)key_code;
} else if (code[2] == NULL) {
led3=1;
code[2] = (char)key_code;
} else if (code[3] == NULL) {
led4=1;
code[3] = (char)key_code;
}
}
if(code[3] != NULL) {
//pc.printf("Value: %d%d%d%d\r\n", code[0],code[1],code[2],code[3]);
if (((int)code[0] == 1) && ((int)code[1] == 2)&& ((int)code[2] == 3) && ((int)code[3] == 4)) {
//pc.printf("Turn off\r\n");
feedback = 1;
} else {
//pc.printf("Didn't turn off \r\n");
led1=0;
led2=0;
led3=0;
led4=0;
code[0]=NULL;
code[1]=NULL;
code[2]=NULL;
code[3]=NULL;
}
}
val=key_code;
}
}
Code for mbed 2
// Includes
#include "mbed.h"
#include "NTPClient.h"
#include "EthernetInterface.h"
#include <vector>
#include <string>
#include "mbed_rpc.h"
#include "RPCCommand.h"
#include "HTTPServer.h"
#include "Formatter.h"
#include "RequestHandler.h"
#include "RPCType.h"
#include "HTTPClient.h"
//MOTOR
PwmOut controlMotor(p21);
DigitalOut ain1(p22);
DigitalOut ain2(p23);
DigitalOut control(p25);
Serial pc(USBTX, USBRX);
EthernetInterface eth;
NTPClient ntp;
alarmModel _alarm;
string dayOfWeek, month, dayNum, ampm;
int hour, minute, sec;
void SendCMD(),getreply(),ESPsetbaudrate(),parse_time(void const *args), dev_recv(), pc_recv(), eth_setup(), getTime();
HTTPServer create_simple_server(), create_interactive_server();
Serial esp(p28, p27); // tx, rx
DigitalOut reset(p26);
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
DigitalIn feedback(p21);
Timer t;
int counter = 0;
int count,ended,timeout;
char buf[2024];
char snd[1024];
//
int main()
{
eth_setup();
char * ipAddr = "1";
while(ipAddr == "1") {
wait(3);
ipAddr = eth.getIPAddress();
}
pc.printf("%s ", ipAddr);
wait(1);
getTime();
time_t ctTime;
ctTime=time(NULL)-3600*4;
pc.printf("%s \r\n", ctime(&ctTime));
Thread thread1(parse_time);
while(1) {
if(feedback == 1) {
control = 0;
}
RPCType::instance().register_types();
HTTPServer srv = create_interactive_server();
if(!srv.init(80)) {
eth.disconnect();
pc.printf("Thread 1 error.\n");
//return;
}
srv.run();
}
}
void parse_time(void const *args)
{
pc.printf("Parse started");
time_t ctTime; //system time structure;
char buffer[80]; //BUFFER TO HOLD FORMATTED TIME DATA
while (1) {
// loop and periodically update the LCD's time display
ctTime = time(NULL)-(3600*4); //TIME with offset for eastern time US
//pc.printf("Time is: %s", ctime(&ctTime));
//pc.printf("Alarm is: %d:%d", hour, minute);
//FORMAT TIME FOR DISPLAY AND STORE FORMATTED RESULT IN BUFFER
strftime(buffer,80,"%a %b %d %T %p %z %Z",localtime(&ctTime));
int i=0;
char* chars_array = strtok(buffer, " :");
while(chars_array) {
switch(i) {
case 0:
dayOfWeek = chars_array;
break;
case 1:
month = chars_array;
break;
case 2:
dayNum = chars_array;
break;
case 3:
int hourTemp = atoi(chars_array);
if(hourTemp > 12) hourTemp -= 12;
hour = hourTemp;
break;
case 4:
minute = atoi(chars_array);
break;
case 5:
sec = atoi(chars_array);
break;
case 6:
ampm = chars_array;
break;
}
i++;
chars_array = strtok(NULL, " :");
}
if (_alarm.hours == hour && _alarm.minutes == minute && counter==0) {
control=1;
counter = 1;
}
}
}
//Setup Wifi
void eth_setup()
{
eth.init(); //static IP
eth.connect();
}
void dev_recv()
{
while(esp.readable()) {
pc.putc(esp.getc());
}
}
void pc_recv()
{
while(pc.readable()) {
esp.putc(pc.getc());
}
}
// Sets new ESP8266 baurate, change the esp.baud(xxxxx) to match your new setting once this has been executed
void ESPsetbaudrate()
{
strcpy(snd, "AT+CIOBAUD=115200\r\n"); // change the numeric value to the required baudrate
SendCMD();
}
HTTPServer create_simple_server()
{
HTTPServer srv;
srv.add_request_handler("DELETE", new DeleteRequestHandler());
srv.add_request_handler("GET", new GetRequestHandler());
srv.add_request_handler("PUT", new PutRequestHandler());
return srv;
}
HTTPServer create_interactive_server()
{
HTTPServer srv(new InteractiveHTMLFormatter());
srv.add_request_handler("GET", new ComplexRequestHandler());
return srv;
}
void SendCMD()
{
esp.printf("%s", snd);
}
void getreply()
{
memset(buf, '\0', sizeof(buf));
t.start();
ended=0;
count=0;
while(!ended) {
if(esp.readable()) {
buf[count] = esp.getc();
count++;
}
if(t.read() > timeout) {
ended = 1;
t.stop();
t.reset();
}
}
}
void getTime()
{
if (ntp.setTime("0.pool.ntp.org") == 0) {
pc.printf("Set time successfully\r\n");
} else {
printf("Error\r\n");
}
}
C# GUI Code
Used for the C# GUI used to program the alarm via web server
Please log in to post comments.
