Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed mbed-rtos 4DGL-uLCD-SE RPCInterface
Diff: main.cpp
- Revision:
- 14:5b3f49d7bf19
- Parent:
- 13:f1649dc31b04
- Child:
- 15:5120c88a7a87
--- a/main.cpp Tue Nov 12 19:27:35 2019 +0000 +++ b/main.cpp Wed Dec 04 01:55:03 2019 +0000 @@ -3,50 +3,142 @@ #include "mbed_rpc.h" #include "uLCD_4DGL.h" +#include <time.h> +#include <math.h> /* Example RPC commands that have currently been implemented /writeLCD/run Hello_world -/setTime/run 1256729737 +/setTime/run <unix time> <UTC offset (-5 for Atlanta)> +/setTime/run 1256729737 -5 */ +volatile bool display_notification = false; +volatile bool display_time = true; + +volatile int utc_offset; //keeps track of the current timezone of the watch + uLCD_4DGL uLCD(p9,p10,p11); // serial tx, serial rx, reset pin; -Serial bluetooth(p13,p14); +//Serial bluetooth(p13,p14); Serial pc(USBTX, USBRX); +InterruptIn view_button(p12); + Mutex stdio_mutex; //mutex used when accessing stdio functions -Mutex lcd_mutex; //mutex used when accessing the bluetooth serial object +Mutex lcd_mutex; //mutex used when accessing the lcd object Thread bluetooth_thread; //thread responsible for receiving rpc commands over bluetooth Thread time_thread; //thread responsible for updating the lcd with the current time //rpc function prototypes -void writeLCD(Arguments *in, Reply *out); +void displayNotification(Arguments *in, Reply *out); void setTime (Arguments *in, Reply *out); -RPCFunction rpcWriteLCD(&writeLCD, "writeLCD"); +RPCFunction rpcWriteLCD(&displayNotification, "notify"); RPCFunction rpcSetTime(&setTime, "setTime"); +//interrupt routine for when the input button is pressed +void view_button_pressed(void){ + display_notification = false; + display_time = true; +} + +//flip the y coordinate around so that standard cartesian coordinates can be used +int flipy(int y_coord){ + return (128-y_coord); +} + +#define C_X 64 +#define C_Y 64 +#define M_PI 3.141592 +//create the tick marks for an analog clock on the lcd display +void setup_analog_clock(uint32_t color){ + + lcd_mutex.lock(); + uLCD.filled_circle(64, 64, 5, color); //centercircle + double angle; + //start from 3 oclock and draw all the clock tick marks counter-clockwise + for(angle = 0; angle < (2*M_PI)-(M_PI/12); angle += M_PI/6){ + uLCD.line(54*cos(angle)+C_X,flipy(54*sin(angle)+C_Y), 64*cos(angle)+C_X,flipy(64*sin(angle)+C_Y), color); //3 oclock tick mark + } + lcd_mutex.unlock(); + +} + +#define RAD_PER_SEC (2*M_PI)/60 +#define RAD_PER_MIN (2*M_PI)/60 +#define RAD_PER_HOUR (2*M_PI)/12 +//create the second, minute, and hour hands for an analog clock on the lcd display +void show_time_analog(int sec, int minute, int hour, int day, int month, int year, uint32_t sec_color, uint32_t min_color, uint32_t hour_color, uint32_t back_color) { + static double angle; + static int prev_sec; + static int prev_minute; + static int prev_hour; + + lcd_mutex.lock(); + + //tear down the previous hands that were drawn + angle = -(RAD_PER_SEC*prev_sec) + M_PI/2; + uLCD.line(C_X,C_Y,64*cos(angle)+C_X, flipy(64*sin(angle)+C_Y),back_color); + + angle = -(RAD_PER_MIN*prev_minute) + M_PI/2; + uLCD.line(C_X,C_Y,52*cos(angle)+C_X, flipy(52*sin(angle)+C_Y),back_color); + + angle = -(RAD_PER_HOUR*prev_hour) + M_PI/2; + uLCD.line(C_X,C_Y,40*cos(angle)+C_X, flipy(40*sin(angle)+C_Y),back_color); + + //draw the new hands + angle = -(RAD_PER_SEC*sec) + M_PI/2; + uLCD.line(C_X,C_Y,64*cos(angle)+C_X, flipy(64*sin(angle)+C_Y),sec_color); + + angle = -(RAD_PER_MIN*minute) + M_PI/2; + uLCD.line(C_X,C_Y,52*cos(angle)+C_X, flipy(52*sin(angle)+C_Y),min_color); + + angle = -(RAD_PER_HOUR*hour) + M_PI/2; + uLCD.line(C_X,C_Y,40*cos(angle)+C_X, flipy(40*sin(angle)+C_Y),hour_color); + + stdio_mutex.lock(); + + //print the current date in a month/day/year format + //uLCD.locate(4,10); + //uLCD.printf(" "); + uLCD.locate(4,10); + uLCD.printf("%2d/%2d/%4d",month, day, year); + uLCD.locate(8,11); + if (hour < 12) {uLCD.printf("AM");} + else {uLCD.printf("PM");} + + stdio_mutex.unlock(); + lcd_mutex.unlock(); + + //store the location of the current hands + prev_sec = sec; + prev_minute = minute; + prev_hour = hour; + +} void time_thread_func() { - + struct tm * t; //time struct defined in time.h + static time_t unix_time; + static bool prev_display_time; + while (true) { - time_t seconds = time(NULL); - - stdio_mutex.lock(); - lcd_mutex.lock(); - - uLCD.locate(0,0); - uLCD.printf("%s", ctime(&seconds)); //Time as a basic string - - stdio_mutex.unlock(); - lcd_mutex.unlock(); - - //printf("Time as seconds since January 1, 1970 = %d\n", seconds); - - //char buffer[32]; - //strftime(buffer, 32, "%I:%M %p\n", localtime(&seconds)); - //printf("Time as a custom formatted string = %s", buffer); + if (display_time == true) { + if (prev_display_time == false){ //clear whatever was previously on the screen + lcd_mutex.lock(); + uLCD.cls(); + lcd_mutex.unlock(); + } + unix_time = time(NULL); + t = localtime(&unix_time); + + setup_analog_clock(WHITE); + int hour = (t->tm_hour + utc_offset); + if (hour < 0){ hour += 24;} + show_time_analog(t->tm_sec,t->tm_min,hour,t->tm_mday,t->tm_mon+1,t->tm_year+1900,RED+BLUE,WHITE,BLUE,BLACK); + } + prev_display_time = display_time; Thread::wait(1000); //only update every second } @@ -96,20 +188,26 @@ int main() { + uLCD.baudrate(3000000); //jack up baud rate to max for fast display + view_button.mode(PullUp); + view_button.fall(&view_button_pressed); + + bluetooth_thread.start(bluetooth_thread_func); time_thread.start(time_thread_func); } - // Make sure the method takes in Arguments and Reply objects. void setTime (Arguments *in, Reply *out) { static const char * unix_time_str; uint32_t unix_time; - + int offset; //set_time(1256729737); // Set RTC time to Wed, 28 Oct 2009 11:35:37 unix_time_str = in->getArg<const char*>(); //get a pointer to the location where the argument string is stored + offset = in->getArg<int>(); unix_time = atoll(unix_time_str); + utc_offset = offset; set_time(unix_time); // Set RTC time to Wed, 28 Oct 2009 11:35:37 @@ -117,16 +215,36 @@ // Make sure the method takes in Arguments and Reply objects. -void writeLCD (Arguments *in, Reply *out) { +void displayNotification (Arguments *in, Reply *out) { + static char display_str[18]; static const char * msg_str; + int i,j; + bool break_out = false; + + display_notification = true; + display_time = false; msg_str = in->getArg<const char*>(); //get a pointer to the location where the argument string is stored stdio_mutex.lock(); lcd_mutex.lock(); - uLCD.locate(0,2); - uLCD.printf("%s\r\n",msg_str); + uLCD.cls(); + uLCD.locate(0,0); + i = 0; + while(true){ + for(j=0; j<18; j++){ + if (msg_str[i+j] == '_'){ + display_str[j] = ' '; + } else { + display_str[j] = msg_str[i+j]; + } + if (msg_str[i+j] == '\0') {break_out = true; break;} + } + i+= 18; + uLCD.printf("%s\r\n",display_str); + if (break_out){break;} + } stdio_mutex.unlock(); lcd_mutex.unlock();