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!

/media/uploads/jgusta21/image2.jpg /media/uploads/jgusta21/image1.jpg

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-BridgePin
PWMAp21
AIN2p23
AIN1p22
VMOT+5v
AO1neg (on motor 1)
AO2pos (on motor 1)
AO1pos (on motor 2)
AO2neg (on motor 2)
STBYVCC (with 5.1k ohm resistor)

Ethernet Magjack Pinout

Touchpad PinPin
GNDgnd
VCCvout
SDAp9 w pullup
SCLp10 w pullup
IRQp24

Touchpad Pinout

Touchpad PinPin
GNDgnd
VCCvout
SDAp9 w pullup
SCLp10 w pullup
IRQp24

SD Card Reader

SD Reader PinPin
VCCVout
DOp6
SCKp7
GNDGND
DIp5
CSp8
Ethernet MagjackPin
P1TD-
P2TD+
P7RD-
P8RD+

Speaker Setup

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

Link: http://github.com/jfordham8/Slappy


Please log in to post comments.