![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
alarmclock with 2 alarm times, 128x64 LCD with KS0108, displays time / time&date / a menu to change time & alarms, rotary encoder with push button, relay which switsches on a hi-fi system or something else, a 1F- Cap as a backup supply
Alarmclock
features:
- alarmclock with 2 alarm times
- 128x64 LCD with KS0108
- displays time / time&date / a menu to change time & alarms
- sleeptimer, relay is switched of when timer runs out
- rotary encoder with push button
- relay which switsches on a hi-fi system or something else
- a 1F- Cap as a backup supply
todo/ desired improvements/ known issues:
- a more precise real time clock would be nice
- a speaker or beeper directly connected to the mbed
- there is a bug where the big font is not displayed correctly
Schematic:
/media/uploads/gaebu/alarmclock_mbed_128x64.pdf
Diff: main.cpp
- Revision:
- 0:62a6f55722d9
- Child:
- 1:8a7f4f79f84d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Jan 21 12:35:29 2014 +0000 @@ -0,0 +1,575 @@ + /* + * @author gaebu + * + * @section LICENSE + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @section DESCRIPTION + +//---------------------------------------------------------------- +// Alarmclock +// ----------- +// features: +// - alarmclock with 2 alarm times +// - 128x64 LCD with KS0108 +// - displays time / time&date / a menu to change time & alarms +// - rottary encoder with push button +// - relay which switsches on a hi-fi system or something else +// - a 1F- Cap as a backup supply +//---------------------------------------------------------------- +// todo/ desired improvements: +// - the sleeptimer isn't integrated already +// - a real time clock would be nice +// - a speaker or beeper directly connected to the mbed +//---------------------------------------------------------------- +*/ + +#include "mbed.h" +#include "KS0108.h" +#include "QEI.h" +//#include "math.h" +//#include "Arial12.h" +//#include "Arial14.h" +//#include "arial_bold_14.h" +#include "Comic24.h" +//#include "SystemFont5x7.h" +//#include "vivaldi16.h" +//#include "MyPhone_20.h" +#include "MyPhone_40.h" +#include "alarmclock.h" +//#include <string> + +// _RST,_DI, _RW, _E, _CS2, _CS1,DB0, DB1, DB2, DB3, DB4, DB5, DB6, DB7) +KS0108 display(p13, p12, p14, p11, p30, p29, p21, p22, p23, p24, p25, p26, p27, p28); + +QEI wheel (p17, p16, NC, 18); +DigitalIn wheelpush(p18); +DigitalOut led1(LED1), led2(LED2), relay(p15), enbackligth(p19); + +int main() +{ + //general init + menu=1; + menuDisp=1; + alarmon=0; + alarmset2=0; + sleeptimer=30; + + alarm.tm_sec = 00; // 0-59 + alarm.tm_min = 00; // 0-59 + alarm.tm_hour = 6; // 0-23 + alarm2.tm_sec = 00; // 0-59 + alarm2.tm_min = 00; // 0-59 + alarm2.tm_hour = 5; // 0-23 + + //display title & frame + display.ClearScreen(); + display.PutString(0,30,"alarmclock"); + display.EmptyRectangle(0,0,127,63,BLACK); + display.HLine(0,127,7,BLACK); + + + display.GotoXY(10,16); + display.SelectFont(Comic24,BLACK,ReadData); + display.PrintString("by_gaebu!"); + wait(2); + clearmenu(); + + /* + //print all chars + display.ClearScreen(); + int x=0,y=0; + for (int i=0x20;i<0xff;i++){ + display.Putchar(y,x,i); + x=x+8; + if (x>120){ + x=0; + y++; + } + } + while(1){} + */ +//mainloop +//--------------------------------------------------------------- + while (1) { + //read time + seconds = time(NULL); + + led1=relay; + + //ckeck if button pressed or wheel turned + checkbutton(); + //menu=wheel.getPulses(); + if (wheel.getPulses()>1){ + wheel.reset(); + menu++; + if (menu>7) + menu=0; + } + if (wheel.getPulses()<1){ + wheel.reset(); + if (menu==0) + menu=7; + else + menu--; + } + display.PrintInteger(menu,0,100); + + //ring the alarm? + if(alarmon | alarmon2) { + relay=1; + //blstate=!blstate; + backlight(1);//blstate); + if(menuold!=menu) { //ring until any button pressed + alarmon=0; + alarmon2=0; + relay=0; + backlight(blstate);//old); + } + } + + //check alarm + if(alarmset & !alarmon) { + newtime = localtime(&seconds); + if(alarm.tm_min==newtime->tm_min & alarm.tm_hour==newtime->tm_hour & alarm.tm_sec==newtime->tm_sec) { + alarmon=1; + //menuold=menu; + //blstateold=blstate; + } + } + if(alarmset2 & !alarmon2) { + newtime = localtime(&seconds); + if(alarm2.tm_min==newtime->tm_min & alarm2.tm_hour==newtime->tm_hour & alarm2.tm_sec==newtime->tm_sec) { + alarmon2=1; + //menuold=menu; + //blstateold=blstate; + } + } + + //display menu + //--------------------------------------------------------------- + if (menu!=menuold) { + menuDisp=menu; + if (menu<2 | (menu==2&menuold==1) | (menu==7&menuold==0)){ + clearmenu(); + } + menuold=menu; + } + else if (menu>1 & !(wheelpushed|wheelpushedlong)) //don't redraw menu if no time is diplayed or no input made + menuDisp=99; + else + menuDisp=menu; + + switch (menuDisp) { + //--- Menu 1 --- date&time + case 0: + strftime(x_day, 20, "%a, %d %b %Y\n", localtime(&seconds)); + display.PutString(3,20,x_day); + + strftime(x_time, 16, "%X\n", localtime(&seconds)); + display.PutString(4,30,x_time); + + if (wheelpushed) { //switch backlight if button pressed + blstate=!blstate; + backlight(blstate); + } + if (wheelpushedlong) { //switch relay if button pressed long + relay=!relay; + } + break; + + //--- Menu 2 --- time big + case 1: + strftime(x_time, 16, "%H:%M", localtime(&seconds)); + display.GotoXY(32,24); + //display.SelectFont(MyPhone_40,BLACK,ReadData); + display.SelectFont(Comic24,BLACK,ReadData); + display.PrintString(x_time); + + if (wheelpushed) { //switch backlight if button pressed + blstate=!blstate; + backlight(blstate); + } + if (wheelpushedlong) { //switch relay if button pressed long + relay=!relay; + } + break; + + //--- Menu 3 --- display menu, alarm1 on/off + case 2: + if (wheelpushed) { + alarmset=!alarmset; + } + printmenu(2); + break; + //--- Menu 4 --- display menu, alarm2 on/off + case 3: + if (wheelpushed) { + alarmset2=!alarmset2; + // readchar=0; + } + printmenu(3); + break; + //--- Menu 5 --- set alarm 1 + case 4: + if (wheelpushed) { + setalarm(1); + } + printmenu(4); + break; + //--- Menu 6 --- set alarm 2 + case 5: + if (wheelpushed) { + setalarm(2); + } + printmenu(5); + break; + //--- Menu 7 --- set time&date + case 6: + if (wheelpushed) { + settimedate(); + } + printmenu(6); + break; + + //--- Menu 8 --- sleep timer + case 7: + if (wheelpushed) { + setsleeptimer(); + } + printmenu(7); + break; + case 99: + //do nothing + break; + default: + display.PutString(0,100,"error"); + exit(1); + } + } +} +//functions +//------------------------------------------ +void clearmenu() +{ + //display.FullRectangle(1,9,126,62,WHITE); + + //display title & frame + display.ClearScreen(); + display.PutString(0,30,"alarmclock"); + display.EmptyRectangle(0,0,127,63,BLACK); + display.HLine(0,127,7,BLACK); +} +//------------------------------------------ +void printmenu(int selectedline) +{ + + //zeile1 + + //zeile2 + display.PutString(2,20,"Alarm 1:"); + if (alarmset) + display.PutString(2,80,"on "); + else + display.PutString(2,80,"off "); + //zeile3 + display.PutString(3,20,"Alarm 2:"); + if (alarmset2) + display.PutString(3,80,"on "); + else + display.PutString(3,80,"off "); + //zeile4 + display.PutString(4,20,"set Alarm 1"); + strftime(alarmtime, 6, "%H:%M\n", &alarm); + display.PutString(4,85,alarmtime); + //zeile5 + display.PutString(5,20,"set Alarm 2"); + strftime(alarmtime, 6, "%H:%M\n", &alarm2); + display.PutString(5,85,alarmtime); + //zeile6 + display.PutString(6,20,"set Time/ Date"); + //zeile7 + display.PutString(7,20,"sleep timer"); + //select line + for (i=2;i<8;i++) + display.PutString(i,2," "); + display.PutString(selectedline,2,"~~"); + //frame + display.EmptyRectangle(0,0,127,63,BLACK); +} +//------------------------------------------ +void setsleeptimer(){ + clearmenu(); + wheel.reset(); + change_sleeptimer=true; + display.PutString(3,30,"set sleeptimer"); + display.PutString(5,30,"min:"); + while(change_sleeptimer){ + if (sleeptimer<10) + display.PutString(5,65," "); + if (sleeptimer<100) + display.PutString(5,70," "); + if (sleeptimer<1000) + display.PutString(5,75," "); + if (sleeptimer<10000) + display.PutString(5,80," "); + display.PrintInteger(sleeptimer,5,60); + + checkbutton(); + if (wheel.getPulses()>1){ + if (sleeptimer<10080) + sleeptimer+=5; + } + else if (wheel.getPulses()<1){ + if (sleeptimer>5) + sleeptimer-=5; + } + if (wheel.getPulses()!=1) + wheel.reset(); + + if (wheelpushed) { + change_sleeptimer=false; + wheelpushed=false; + wheel.reset(); + } + } +} +//------------------------------------------ +void setalarm(char alnb) +{ + clearmenu(); + wheel.reset(); + change_alarm_hour=1; + display.PutString(4,30,"-- "); + if (alnb == 1) + al_to_change=alarm; + else + al_to_change=alarm2; + while (change_alarm_hour) { + strftime(alarmtime, 6, "%H:%M\n", &al_to_change); + display.PutString(3,30,alarmtime); + checkbutton(); + if (wheel.getPulses()>1) + wheelturned='r'; + else if (wheel.getPulses()<1) + wheelturned='l'; + if (wheel.getPulses()==1) + wheelturned=0; + else + wheel.reset(); + + if (wheelturned=='r') { + al_to_change.tm_hour++; + if (al_to_change.tm_hour>23) + al_to_change.tm_hour=0; + } + if (wheelturned=='l') { + al_to_change.tm_hour--; + if (al_to_change.tm_hour<0) + al_to_change.tm_hour=23; + } + if (wheelpushed) { + change_alarm_hour=0; + change_alarm_min=1; + display.PutString(4,30," --"); + } + } + while (change_alarm_min) { + strftime(alarmtime, 6, "%H:%M\n", &al_to_change); + display.PutString(3,30,alarmtime); + + checkbutton(); + if (wheel.getPulses()>1) + wheelturned='r'; + else if (wheel.getPulses()<1) + wheelturned='l'; + if (wheel.getPulses()==1) + wheelturned=0; + else + wheel.reset(); + if (wheelturned=='r') { + al_to_change.tm_min++; + if (al_to_change.tm_min>59) + al_to_change.tm_min=0; + } + if (wheelturned=='l') { + al_to_change.tm_min--; + if (al_to_change.tm_min<0) + al_to_change.tm_min=59; + } + if (wheelpushed) { + change_alarm_min=0; + if (alnb == 1) + alarm=al_to_change; + else + alarm2=al_to_change; + wheelturned=0; + wheelpushed=false; + wheel.reset(); + } + } +} +//------------------------------------------ +void settimedate() +{ + clearmenu(); + wheel.reset(); + seconds = time(NULL); + newtime = localtime(&seconds); + set_td_menu=1; + wheelturned=1; + //menuold=0; + display.PutString(4,30,"-- "); + if (newtime->tm_year==70) + newtime->tm_year=113; + + while(set_td_menu>0) { + if(wheelturned>0) { //update display if changed + strftime(x_day, 20, "%d.%m.%Y\n", newtime); + display.PutString(5,30,x_day); + + char x_time[16]; + strftime(x_time, 16, "%H:%M\n", newtime); + display.PutString(3,30,x_time); + } + checkbutton(); + //menu=wheel.getPulses(); + //display.PrintInteger(menu,0,100); + //if (menu>menuold) + if (wheel.getPulses()>1) + wheelturned='r'; + else if (wheel.getPulses()<1) + wheelturned='l'; + if (wheel.getPulses()==1) + wheelturned=0; + else + wheel.reset(); + //menuold=menu; + + switch(set_td_menu) { + case 0: + break; // Invalid entry + case 1: //set hour + if (wheelturned=='r') { + newtime->tm_hour++; + if (newtime->tm_hour>23) + newtime->tm_hour=0; + } + if (wheelturned=='l') { + newtime->tm_hour--; + if (newtime->tm_hour<0) + newtime->tm_hour=23; + } + if (wheelpushed) { + set_td_menu++; + display.PutString(4,30," --"); + } + break; + case 2: //set min + if (wheelturned=='r') { + newtime->tm_min++; + if (newtime->tm_min>59) + newtime->tm_min=0; + } + if (wheelturned=='l') { + newtime->tm_min--; + if (newtime->tm_min<0) + newtime->tm_min=59; + } + if (wheelpushed) { + set_td_menu++; + display.PutString(4,30," "); + display.PutString(6,30,"-- "); + } + break; + case 3: //set day + if (wheelturned=='r') { + newtime->tm_mday++; + if (newtime->tm_mday>31) + newtime->tm_mday=1; + } + if (wheelturned=='l') { + newtime->tm_mday--; + if (newtime->tm_mday<1) + newtime->tm_mday=31; + } + if (wheelpushed) { + set_td_menu++; + display.PutString(6,30," -- "); + } + break; + case 4: //set month + if (wheelturned=='r') { + newtime->tm_mon++; + if (newtime->tm_mon>11) + newtime->tm_mon=0; + } + if (wheelturned=='l') { + newtime->tm_mon--; + if (newtime->tm_mon<0) + newtime->tm_mon=11; + } + if (wheelpushed) { + set_td_menu++; + display.PutString(6,30," ----"); + } + break; + case 5: //set month + if (wheelturned=='r') { + newtime->tm_year++; + if (newtime->tm_year>200) + newtime->tm_year=100; + } + if (wheelturned=='l') { + newtime->tm_year--; + if (newtime->tm_year<100) + newtime->tm_year=200; + } + if (wheelpushed) { + set_td_menu=0; + display.PutString(6,30," "); + // convert to timestamp and set + set_time(mktime(newtime)); + wheelturned=0; + wheelpushed=false; + //menuDisp=0; + //menuold=0; + wheel.reset(); + } + break; + default: + display.PutString(0,100,"error"); + exit(1); + } + } +} +//------------------------------------------ +void backlight (bool onoff) +{ + led2=onoff; + enbackligth=onoff; +} +//------------------------------------------ +void checkbutton() +{ + wheelpushed=false; + wheelpushedlong=false; + if (!wheelpush) { + temp=0; + while(!wheelpush) { + wait(0.01); + temp++; + } + if (temp>150) + wheelpushedlong=true; + else + wheelpushed=true; + } +} \ No newline at end of file