|
It is currently Wed Jul 06, 2011 7:26 pm
|
View unanswered posts | View active topics
 |
|
 |
|
| Author |
Message |
|
MonkeyEnFuego
|
Post subject: 7 Segment Watch  Posted: Sun Apr 17, 2011 8:50 pm |
Joined: Wed Mar 23, 2011 9:35 am Posts: 54
|
Think of this as my remote hack-a-thon submission  For my first app, I decided to do something simple. This app mimics a 7-segment display for a watch, including "ghosting" for the segment that aren't active but are always visible in "real life". Features - Shows hour:min:sec - Displays time for 10 seconds, then sleeps to save battery - Cycles colors every 3 minutes (blue, green, red) That's it! Thanks, Matt  /** * Simple program to display 7 segment time * * Copyright (C) 2011, Matt Shea [email protected] twitter.com/Matt_Shea * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. **/
#include <pulse_os.h> #include <pulse_types.h>
#define FALSE 0 #define NULL 0 #define TRUE 1
#define MERIDIEM_AM 0 #define MERIDIEM_PM 1
// How big are we going to make the segment size #define SEGMENT_WIDTH 16 #define SEGMENT_HEIGHT 2*SEGMENT_WIDTH #define SEGMENT_THICKNESS 3 #define SEGMENT_SPACING 3
static const color24_t COLOR_RED24 = {0xff, 0x00, 0x00, 0}; static const color24_t COLOR_DARKRED24 = {0x0f, 0x00, 0x00, 0}; static const color24_t COLOR_GREEN24 = {0x00, 0xff, 0x00, 0}; static const color24_t COLOR_DARKGREEN24 = {0x00, 0x0f, 0x00, 0}; static const color24_t COLOR_BLUE24 = {0x00, 0x00, 0xff, 0}; static const color24_t COLOR_DARKBLUE24 = {0x00, 0x00, 0x0f, 0};
static struct pulse_time_tm current_time; static struct pulse_time_tm last_time;
color24_t f_colors[3]; color24_t b_colors[3];
/** * Seven segment definition. * * AAAAAAA * F B * F B * F B * GGGGGGG * E C * E C * E C * DDDDDDD */
// Bit fields to specify rendering a segment #define S_A 0x1 #define S_B 0x2 #define S_C 0x4 #define S_D 0x8 #define S_E 0x10 #define S_F 0x20 #define S_G 0x40 #define S_NONE 0x0 #define S_ALL 0x7F
// Mask lookups for numbers 0-9 static const uint8_t segment_mask[10] = { S_A | S_B | S_C | S_D | S_E | S_F, // Digit 0 S_B | S_C, // Digit 1 S_A | S_B | S_G | S_E | S_D, // Digit 2 S_A | S_B | S_G | S_C | S_D, // Digit 3 S_F | S_B | S_G | S_C, // Digit 4 S_A | S_F | S_G | S_C | S_D, // Digit 5 S_F | S_G | S_C | S_E | S_D, // Digit 6 S_A | S_B | S_C, // Digit 7 S_ALL, // Digit 8 S_A | S_F | S_G | S_B | S_C // Digit 9 };
void init_time() { last_time.tm_min = 0; last_time.tm_sec = 0; last_time.tm_hour = 0; }
void handle_button_causing_wakeup ();
void main_app_init () { // Set a timer to go to sleep if we don't hear from anyone pulse_update_power_down_timer(10000); init_time(); // Setup the color look ups; f_colors[0] = COLOR_BLUE24; b_colors[0] = COLOR_DARKBLUE24; f_colors[1] = COLOR_GREEN24; b_colors[1] = COLOR_DARKGREEN24; f_colors[2] = COLOR_RED24; b_colors[2] = COLOR_DARKRED24; // Register a callback for the woke_from_button event pulse_register_callback(ACTION_WOKE_FROM_BUTTON, &handle_button_causing_wakeup); }
void handle_button_causing_wakeup () { pulse_update_power_down_timer(10000); }
void main_app_handle_button_down() { }
void main_app_handle_button_up() { // Reset any timer to go to sleep pulse_update_power_down_timer(10000);
}
void draw_line_horizontal (uint8_t x, uint8_t y, uint8_t len, color24_t color) { pulse_set_draw_window(x, y, x+len, y); for (uint8_t i=0; i < len; i++) { pulse_draw_point24(color); } }
void draw_line_vertical (uint8_t x, uint8_t y, uint8_t len, color24_t color) { pulse_set_draw_window(x, y, x, y+len); for (uint8_t i=0; i < len; i++) { pulse_draw_point24(color); } }
/** * Draw '/'. E.g 45 degree line */ void draw_line_slash(uint8_t x, uint8_t y, uint8_t len, color24_t color) { for (uint8_t i=0; i < len; i++) { pulse_set_draw_window(x, y, x, y); pulse_draw_point24(color); x--; y++; } }
/** * Draw '\'. E.g. a 45 degree line */
void draw_line_backslash(uint8_t x, uint8_t y, uint8_t len, color24_t color) {
for (uint8_t i=0; i < len; i++) { pulse_set_draw_window(x, y, x, y); pulse_draw_point24(color); x++; y++; }
}
void draw_7segment_top (uint8_t x, uint8_t y, uint8_t w, color24_t color) { for (uint8_t i=0; i < SEGMENT_THICKNESS; i++) { draw_line_horizontal(x+i, y+i, w - (2*i), color); } }
void draw_7segment_bottom (uint8_t x, uint8_t y, uint8_t w, color24_t color) { for (uint8_t i=0; i < SEGMENT_THICKNESS; i++) { draw_line_horizontal(x+i, y-i, w - (2*i), color); } }
void draw_7segment_left (uint8_t x, uint8_t y, uint8_t h, color24_t color) { for (uint8_t i=0; i < SEGMENT_THICKNESS; i++) { draw_line_vertical(x+i,y+i, h/2 - (2*i), color); } }
void draw_7segment_right (uint8_t x, uint8_t y, uint8_t h, color24_t color) { for (uint8_t i=0; i < SEGMENT_THICKNESS; i++) { draw_line_vertical(x-i,y+i, h/2 - (2*i), color); } }
void draw_7segment_middle(uint8_t x, uint8_t y, uint8_t w, color24_t color) { draw_line_horizontal(x+1, y, w - 2, color); draw_line_horizontal(x, y+1, w , color); draw_line_horizontal(x+1, y+2, w - 2, color); }
/** * Draw a 7 segment number digit. * * val - val to print should be less than 10 * x/y - coordinates to print at * w/h - width/height of the number * f_color - foreground color for an active segment * b_color - background color for a "ghost" segment * */ void draw_7segment_number(uint8_t val, uint8_t x, uint8_t y, uint8_t w, uint8_t h, color24_t f_color, color24_t b_color) { // Sanity check that we only do 1 digit val = val % 10; // Get the mask of segments uint8_t mask = segment_mask[val]; // Render either the foreground or background (ghost) color // Depending on the mask draw_7segment_top(x+1, y, w, (mask & S_A ? f_color : b_color));
draw_7segment_right(x + w + 1, y+2, h, (mask & S_B ? f_color : b_color)); draw_7segment_right(x + w + 1, y+4+h/2, h, (mask & S_C ? f_color : b_color)); draw_7segment_bottom(x+1,y+h + 4 + 1, w, (mask & S_D ? f_color : b_color)); draw_7segment_left(x, y+4+h/2, h, (mask & S_E ? f_color : b_color)); draw_7segment_left(x, y+2, h, (mask & S_F ? f_color : b_color)); draw_7segment_middle(x+1, y+h/2 + 1, w, (mask & S_G ? f_color : b_color)); }
/** * Draw a '1' only if the val is greater than zero. This would be for the first digit of the watch to save width */ void draw_7segment_one(uint8_t val, uint8_t x, uint8_t y, uint8_t h, color24_t f_color, color24_t b_color) { draw_7segment_right(x, y+2, h, (val > 0 ? f_color : b_color)); draw_7segment_right(x, y+4+h/2, h, (val > 0 ? f_color : b_color)); }
/** * Draw a ':' */ void draw_colon (uint8_t x, uint8_t y, color24_t color) { draw_line_vertical(x,y-4, 4, color); draw_line_vertical(x+1,y-4, 4, color); draw_line_vertical(x+2,y-4, 4, color); draw_line_vertical(x,y+4, 4, color); draw_line_vertical(x+1,y+4, 4, color); draw_line_vertical(x+2,y+4, 4, color); }
void draw_clock(color24_t f_color, color24_t b_color) { // AM or PM uint8_t meridiem = MERIDIEM_AM; // Local variable to deal with non-military time display uint8_t hour = current_time.tm_hour; uint8_t min = current_time.tm_min; uint8_t sec = current_time.tm_sec; if (hour >= 12) meridiem = MERIDIEM_PM; if (hour > 12) hour -= 12;
uint8_t y = SCREEN_HEIGHT/2 - SEGMENT_HEIGHT/2; uint8_t x = SEGMENT_SPACING; // Draw the "1" draw_7segment_one(hour / 10, x, y, SEGMENT_HEIGHT, f_color, b_color); x += SEGMENT_THICKNESS + SEGMENT_SPACING; // Draw the rest of the hour draw_7segment_number(hour % 10, x, y, SEGMENT_WIDTH, SEGMENT_HEIGHT, f_color, b_color); x += SEGMENT_WIDTH + SEGMENT_SPACING + 1; // Draw the colon draw_colon(x, y + 1 + SEGMENT_HEIGHT/2, (sec % 2 == 0 ? f_color : b_color)); x += SEGMENT_THICKNESS + 2; // Draw the min draw_7segment_number(min / 10, x, y, SEGMENT_WIDTH, SEGMENT_HEIGHT, f_color, b_color); x += SEGMENT_WIDTH + SEGMENT_SPACING + 1; draw_7segment_number(min % 10, x, y, SEGMENT_WIDTH, SEGMENT_HEIGHT, f_color, b_color);
// Draw the sec y += SEGMENT_HEIGHT/2; x += SEGMENT_WIDTH + 4; draw_7segment_number(sec / 10, x, y, SEGMENT_WIDTH/2, SEGMENT_HEIGHT/2, f_color, b_color); x += SEGMENT_WIDTH/2 + 4; draw_7segment_number(sec % 10, x, y, SEGMENT_WIDTH/2, SEGMENT_HEIGHT/2, f_color, b_color);
}
void main_app_loop () { pulse_get_time_date(¤t_time); if (last_time.tm_sec != current_time.tm_sec || last_time.tm_min != current_time.tm_min || last_time.tm_hour != current_time.tm_hour) { draw_clock(f_colors[current_time.tm_min%3], b_colors[current_time.tm_min%3]); last_time.tm_sec= current_time.tm_sec; last_time.tm_min = current_time.tm_min; last_time.tm_hour = current_time.tm_hour; } }
void main_app_handle_doz() { init_time(); }
void main_app_handle_hardware_update(enum PulseHardwareEvent event) {
}
|
|
|
|
 |
|
MonkeyEnFuego
|
Post subject: Re: 7 Segment Watch  Posted: Sun Apr 17, 2011 9:41 pm |
Joined: Wed Mar 23, 2011 9:35 am Posts: 54
|
Better image of what it looks like. With a different color 
|
|
|
|
 |
|
number3
|
Post subject: Re: 7 Segment Watch  Posted: Tue Apr 19, 2011 5:55 am |
Joined: Wed Apr 06, 2011 8:53 pm Posts: 32
|
|
Very nice! Thanks for posting it!
|
|
|
|
 |
|
|
 |
|
 |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum
|
|