diff --git a/Clock.cpp b/Clock.cpp index ef1eddc..0148f1c 100644 --- a/Clock.cpp +++ b/Clock.cpp @@ -1,10 +1,29 @@ #include #include "Kernel.h" #include "EAT.h" +#include "Util.h" + +#define CLOCK_OFFSET_X 1 +#define CLOCK_OFFSET_Y 1 +#define CLOCK_SIZE 78 +#define CLOCK_FACE_COLOUR 0xAAAAAA +#define CLOCK_FACE_OUTLINE_COLOUR 0x666666 +#define CLOCK_FACE_OUTLINE_WIDTH 4 +#define CLOCK_FACE_HOUR_MARKER_TOP_COLOUR 0x333333 +#define CLOCK_FACE_HOUR_MARKER_COLOUR 0x666666 +#define CLOCK_FACE_HOUR_MARKER_SIZE 4 +#define CLOCK_HOUR_COLOUR 0x333333 +#define CLOCK_HOUR_LENGTH 20 +#define CLOCK_MINUTE_COLOUR 0x666666 +#define CLOCK_MINUTE_LENGTH 25 + +#define DEGREES_TO_RADIANS 0.0174533 RTC_TimeTypeDef time_to_rtc(char* time); RTC_DateTypeDef date_to_rtc(char* date); -void redraw(RTC_TimeTypeDef time); +void redraw(RTC_TimeTypeDef time, RTC_DateTypeDef date); +void draw_face(); +unsigned int rgb_to_colour(unsigned long colour); int last_minute = -1; @@ -54,19 +73,85 @@ int Clock(int pid, unsigned int signal) } if (signal & SIGNAL_REDRAW) { - redraw(time); + RTC_DateTypeDef date; + M5.Rtc.GetData(&date); + redraw(time, date); } } return 0; } -void redraw(RTC_TimeTypeDef time) +void draw_face() +{ + int center_x = CLOCK_OFFSET_X + (CLOCK_SIZE / 2); + int center_y = CLOCK_OFFSET_Y + (CLOCK_SIZE / 2); + int radius = CLOCK_SIZE / 2; + int inner_radius = radius - (CLOCK_FACE_OUTLINE_WIDTH / 2); + + // Draw face + M5.Lcd.fillCircle(center_x, center_y, radius, rgb_to_colour(CLOCK_FACE_OUTLINE_COLOUR)); + M5.Lcd.fillCircle(center_x, center_y, inner_radius, rgb_to_colour(CLOCK_FACE_COLOUR)); + + // Draw lines + for (int i=0; i<360; i+=(360/12)) + { + // Effectively our polar coordinates are + // i,inner_radius -> i,inner_radius-CLOCK_FACE_HOUR_MARKER_SIZE + + int x1 = (inner_radius - CLOCK_FACE_HOUR_MARKER_SIZE) * cos(i * DEGREES_TO_RADIANS); + int y1 = (inner_radius - CLOCK_FACE_HOUR_MARKER_SIZE) * sin(i * DEGREES_TO_RADIANS); + int x2 = (inner_radius + 1) * cos(i * DEGREES_TO_RADIANS); + int y2 = (inner_radius + 1) * sin(i * DEGREES_TO_RADIANS); + + x1 += center_x; + x2 += center_x; + y1 += center_y; + y2 += center_y; + + // 0 degrees = right, draw top at 270 + M5.Lcd.drawLine(x1, y1, x2, y2, i == 270 ? rgb_to_colour(CLOCK_FACE_HOUR_MARKER_TOP_COLOUR) : rgb_to_colour(CLOCK_FACE_HOUR_MARKER_COLOUR)); + } + +} + +void draw_arm(int angle, int length, unsigned int colour) { - M5.Lcd.setCursor(0, 40); - char time_str[6]; - sprintf(time_str, "%02d:%02d", time.Hours, time.Minutes); - M5.Lcd.print(time_str); + angle -= 90; + // clock center + int center_x = CLOCK_OFFSET_X + (CLOCK_SIZE / 2); + int center_y = CLOCK_OFFSET_Y + (CLOCK_SIZE / 2); + + int x = length * cos(angle * DEGREES_TO_RADIANS); + int y = length * sin(angle * DEGREES_TO_RADIANS); + + M5.Lcd.drawLine(center_x, center_y, center_x + x, center_y + y, colour); +} + +void redraw(RTC_TimeTypeDef time, RTC_DateTypeDef date) +{ + draw_face(); + + // Write date? + int center_x = CLOCK_OFFSET_X + (CLOCK_SIZE / 2); + int center_y = CLOCK_OFFSET_Y + (CLOCK_SIZE / 2); + M5.Lcd.setCursor(center_x + (CLOCK_SIZE / 16), center_y + (CLOCK_SIZE / 6)); + M5.Lcd.setTextColor(rgb_to_colour(CLOCK_FACE_OUTLINE_COLOUR), rgb_to_colour(CLOCK_FACE_COLOUR)); + M5.Lcd.print(date.Date); + + int hour = time.Hours; + if (hour > 12) hour -= 12; + int minute = time.Minutes; + + int minute_angle = 360.0 * (minute / 60.0); + int hour_angle = (360.0 * (hour / 12.0)) + (minute_angle / 12.0); + draw_arm(hour_angle, CLOCK_HOUR_LENGTH, rgb_to_colour(CLOCK_HOUR_COLOUR)); + draw_arm(minute_angle, CLOCK_MINUTE_LENGTH, rgb_to_colour(CLOCK_MINUTE_COLOUR)); + + //M5.Lcd.setCursor(0, 40); + //char time_str[6]; + //sprintf(time_str, "%02d:%02d", time.Hours, time.Minutes); + //M5.Lcd.print(time_str); } RTC_TimeTypeDef time_to_rtc(char* time)