Category Archives: 13-pebbleclock

ST

27 Jan 2015

My watch face was inspired by the phrase ‘watch the clock’.

Sketches

There are 12 eyes, each representing the hour. The hour determines which eye is opened and blinking on a two second loop. The single open eye stares where the current minute hand would be pointing on a standard analog clock. For instance, at 5:30, the last eye would be looking straight down.

photos_watchface

I hoped that the eyes would bring the pebble to life, transform it from a smartwatch into an organism. I think I accomplished some level of this goal, though the design is still very digital and uniformly patterned. I wanted to use a frame-by-frame animation to simulate organic motion. Lastly, I chose to loop the animation to best represent time.

Upon evaluation, I feel that my clock does not make the best use of the space provided. Although the entire screen is filled with graphics, only one eye (1/12th of screen) blinks at a time.

pedro

27 Jan 2015

01lr

My idea for the pebble assignment was to work with subdivision patterns to represent time. Initially, I investigated some fractal division such as an incremental cracking. But once the resolution of the display was limited I would not be able to represent small divisions, so I decided to use a voronoi diagram as the logic behind the division.

I used processing to simulate the display of pebble watch in order to evaluate how the gradients of a grayscale brute-force voronoi could be simplified for a black and white screen.  These simulations show that the logic itself of the work had to be changed to fit the constraints. Firstly, I tried to use probability to simulate gray areas, but it resulted in a lost of legibility of the diagram. Then, I tried to simplify the diagram, painting only areas of equal distance for two centres. It resulted in an interesting visual effect that resembled the idea of a cracking display.


After defining the visual pattern, I tried to evaluate what would happen if each of these cells were agents that interact with the neighbours and the frame of the pebble, with forces of repulsion. As the time passes and the cells subdivide, each agent try to find a appropriate space in the area, establishing a bottom-up balance of the visual composition.

On one hand, with the dynamic behaviour of the cells, the original idea of subdivision was taken even further, but on the other hand, the implementation in the pebble watch was a difficult process, due to the brute forces algorithms underlying the diagram. The constraints involved in the implementation were related to the limited memory of the device, what imposed several limitations for the design of the Voronoi diagram. After several memory crashes, the resolution, the number of cells and the movement were reduces, what took the design one step back.

Finally, I consider that the Voronoi diagram is a very interesting device for the visualization of time. The obstacles faced in the implementation demand a careful optimization of the algorithms in order to incorporate the full potential of the design.

 

LValley

27 Jan 2015

My name is Lauren Valley, and I have a condition called “Resting Bitch Face.”

When I’m not paying attention to the expression on my face, it often looks like I am extremely pissed off or uninterested. This condition has affected me since I was in elementary school and teachers would stop me in the hallways and tell me that “it was okay to smile.”

I am still slightly in denial about my condition so I take no measures in trying to correct it—my other condition, “Resting Bitch Mouth.” Is something I take active steps to try to fix.

My Pebble Watch face aids me in the “realization” phase of correcting my “Resting Bitch Mouth.” When I get hungry, I often respond with sassy to borderline rude remarks, and based on the hour of the day and the amount of time its been since I’ve eaten, my responses can get kind of touchy.

I have programmed my watch to display sayings based on my regular meal times.

As time passes without food, the sayings displayed range from “It’s all good” when I’ve first eaten to “FUCK MY LIFE” if I’m feeling particularly hungry.

Screen Shot 2015-01-27 at 12.00.15 AM

I believe that this watch will aid my struggle in realizing my condition, and soon, the world will be a better place one resting bitch mouth at a time.

Screen Shot 2015-01-27 at 12.25.00 AMScreen Shot 2015-01-27 at 12.33.55 AMScreen Shot 2015-01-27 at 12.35.58 AM

12:00 (lunch time!!!!!!!)                              1:00pm                                     2:00pm

 

Screen Shot 2015-01-27 at 12.36.51 AMScreen Shot 2015-01-27 at 12.37.56 AMScreen Shot 2015-01-26 at 11.51.29 PM

3:00pm                                         4:00pm                                         4:30pm

New Project 1 from Lauren Valley on Vimeo.

 

#include 
#include 

jackkoo

27 Jan 2015

downloaddownload (2)download (1)

starts synced ->,                 synced  <-                         bottom guy turned first.

Hi this is my poem / timer.

Each row is 30 steps, and takes 30 seconds.

The return trip included makes it 1 minute per cycle. At each 59th step of the second being, he/she turns around before the 60th step. This causes a small gap that represents a minute.  Each round the characters’ gap increases once as more minutes are represented. This pattern eventually cycles though and returns to its default state. There can be a total of 60 gaps between them. Meaning that this piece can time up to exactly 1 hour.

It’s also a little poem about two friends separating and getting back together :D

Here is my sketch. and some explainationIMG_0032

IMG_0068

Here is my code!

#include <pebble.h>
#include <stdlib.h>
 
static Window *s_main_window;

int s_second = 0;
int s_second2 = 0;

bool direction1 = true;
bool direction2 = true;
bool isam = true;

static BitmapLayer *s_bg;
static GBitmap *s_bg_bitmap;

static BitmapLayer *s_sprite_minuite1;
bool s_sprite_minuite1_frame = true;
static BitmapLayer *s_sprite_minuite2;
bool s_sprite_minuite2_frame = true;

static GBitmap *s_sprite1f1_bitmap;
static GBitmap *s_sprite1f2_bitmap;

static GBitmap *s_sprite2f1_bitmap;
static GBitmap *s_sprite2f2_bitmap;

static GBitmap *s_spritef1_bitmap;
static GBitmap *s_spritef2_bitmap;
static GBitmap *s_spritef1L_bitmap;
static GBitmap *s_spritef2L_bitmap;

typedef struct vector2 vector2;

struct vector2
{
 float x;
 float y;
};
 
vector2 sprite1Position = {10, 10};
vector2 sprite2Position = {10 ,23};

bool animationFrame = false;

static PropertyAnimation *s_property_animation;
static PropertyAnimation *s_property_animation2;

static void destroy_property_animation(PropertyAnimation **prop_animation) {
 if (*prop_animation == NULL) {
 return;
 }

 if (animation_is_scheduled((Animation*) *prop_animation)) {
 animation_unschedule((Animation*) *prop_animation);
 }

 property_animation_destroy(*prop_animation);
 *prop_animation = NULL;
}

static void trigger_custom_animation() {
 
 
 destroy_property_animation(&s_property_animation);
 //*s_property_animation = NULL;
 destroy_property_animation(&s_property_animation2);
 //*s_property_animation2 = NULL;
 
 Layer *s_layer = bitmap_layer_get_layer(s_sprite_minuite1);
 Layer *s_layer2 = bitmap_layer_get_layer(s_sprite_minuite2);
 
 // Set start and end
 GRect from_frame = layer_get_frame(s_layer);
 GRect to_frame = GRect(sprite1Position.x, sprite1Position.y, 10, 11);
 
 GRect from_frame2 = layer_get_frame(s_layer2);
 GRect to_frame2 = GRect(sprite2Position.x, sprite2Position.y, 10, 11);
 
 // move first guy
 if (direction1 == true)
 {
 if (sprite1Position.x < 130)
 {
 sprite1Position.x += 4.0;
 }
 }else
 {
 if (sprite1Position.x > 10)
 {
 sprite1Position.x -= 4.0;
 }
 }
 
 if (direction2 == true)
 {
 if (sprite2Position.x < 130)
 {
 sprite2Position.x += 4.0;
 }
 }else
 {
 if (sprite2Position.x > 10)
 {
 sprite2Position.x -= 4.0;
 }
 }
 
 // Create the animation
 s_property_animation = property_animation_create_layer_frame(s_layer, &from_frame, &to_frame);
 s_property_animation2 = property_animation_create_layer_frame(s_layer2, &from_frame2, &to_frame2);
 
 // Flip the animations
 if (s_sprite_minuite1_frame)
 {
 bitmap_layer_set_bitmap (s_sprite_minuite1, s_sprite1f2_bitmap);
 s_sprite_minuite1_frame = !s_sprite_minuite1_frame;
 }
 else
 {
 bitmap_layer_set_bitmap (s_sprite_minuite1, s_sprite1f1_bitmap);
 s_sprite_minuite1_frame = !s_sprite_minuite1_frame;
 }
 
 // Flip the animations
 if (s_sprite_minuite2_frame)
 {
 bitmap_layer_set_bitmap (s_sprite_minuite2, s_sprite1f1_bitmap);
 s_sprite_minuite2_frame = !s_sprite_minuite2_frame;
 }
 else
 {
 bitmap_layer_set_bitmap (s_sprite_minuite2, s_sprite1f2_bitmap);
 s_sprite_minuite2_frame = !s_sprite_minuite2_frame;
 }

 
 // Schedule to occur ASAP with default settings
 animation_schedule((Animation*) s_property_animation);
 animation_schedule((Animation*) s_property_animation2);
}


static void main_window_load(Window *window) 
{
 // Sprite 1 textures
 s_spritef1_bitmap = gbitmap_create_with_resource(RESOURCE_ID_f1);
 s_spritef2_bitmap = gbitmap_create_with_resource(RESOURCE_ID_f2);

 s_spritef1L_bitmap = gbitmap_create_with_resource(RESOURCE_ID_f1L);
 s_spritef2L_bitmap = gbitmap_create_with_resource(RESOURCE_ID_f2L);

 // Sprite 1 Set initial
 s_sprite1f1_bitmap = s_spritef1_bitmap;
 s_sprite1f2_bitmap = s_spritef2_bitmap;
 
 // Sprite 2
 s_sprite2f1_bitmap = s_spritef1L_bitmap;
 s_sprite2f2_bitmap = s_spritef2L_bitmap;
 
 s_bg_bitmap = gbitmap_create_with_resource(RESOURCE_ID_bg);
 s_bg = bitmap_layer_create(GRect(10, 10, 120, 120));
 bitmap_layer_set_bitmap(s_bg, s_bg_bitmap);
 layer_add_child(window_get_root_layer(window), bitmap_layer_get_layer(s_bg));

 // Sprite Minuite 1
 s_sprite_minuite1 = bitmap_layer_create(GRect(0, 0, 10, 11));
 bitmap_layer_set_bitmap(s_sprite_minuite1, s_spritef1_bitmap);
 layer_add_child(window_get_root_layer(window), bitmap_layer_get_layer(s_sprite_minuite1));

 // Sprite Minuite 2
 s_sprite_minuite2 = bitmap_layer_create(GRect(0, 0, 10, 11));
 bitmap_layer_set_bitmap(s_sprite_minuite2, s_spritef1_bitmap);
 layer_add_child(window_get_root_layer(window), bitmap_layer_get_layer(s_sprite_minuite2));
}

static void main_window_unload(Window *window) {
 // Destroy TextLayer
}

static void tick_handler(struct tm *tick_time, TimeUnits units_changed)
{
 trigger_custom_animation();
 s_second = s_second + 1;
 
 // First sprite takes 30 steps, 30 steps
 if (s_second >= 30)
 {
 if (direction1)
 {
 s_sprite1f1_bitmap = s_spritef1L_bitmap;
 s_sprite1f2_bitmap = s_spritef2L_bitmap;
 }
 else
 {
 s_sprite1f1_bitmap = s_spritef1_bitmap;
 s_sprite1f2_bitmap = s_spritef2_bitmap;
 }
 direction1 = !direction1;
 s_second = 0;
 }
 
 // Second sprite takes 30 steps, 29 steps
 s_second2 = s_second2 + 1;
 if (s_second2 >= 29)
 {
 if (direction2)
 {
 if (s_second2 >= 30)
 {
 s_sprite2f1_bitmap = s_spritef1_bitmap;
 s_sprite2f2_bitmap = s_spritef2_bitmap;
 direction2 = !direction2;
 s_second2 = 0;
 }
 }
 else
 {
 s_sprite2f1_bitmap = s_spritef1L_bitmap;
 s_sprite2f2_bitmap = s_spritef2L_bitmap;
 direction2 = !direction2;
 s_second2 = 0;
 }
 }
 
}

static void init() {
 
 // Create main Window element and assign to pointer
 s_main_window = window_create();

 // Set handlers to manage the elements inside the Window
 window_set_window_handlers(s_main_window, (WindowHandlers) {
 .load = main_window_load,
 .unload = main_window_unload
 });

 // Show the Window on the watch, with animated=true
 window_stack_push(s_main_window, true);
 
 // Register with TickTimerService
 tick_timer_service_subscribe(SECOND_UNIT, tick_handler);
 
 trigger_custom_animation();
}

static void deinit() {
 // Destroy Window
 window_destroy(s_main_window);
}

int main(void) {
 init();
 app_event_loop();
 deinit();
}

John Choi

26 Jan 2015

PebbleWatch

At first, I just wanted to make a binary clock.  I looked around for a bit and it turned out those are actually pretty mainstream.  So I decided to make a Ternary clock!  (This is fitting for a clock because after all, Sumerian time is pretty divisible by 3.)  Here, the horizontal lines represent 0, the vertical line represents 1, and the square represents 2.  I decided to make the lowest bit display on the left and the highest bit on the right, since we naturally read English text from left to right, and doing numbers this way as well makes more sense.  I kind of screwed up with the seconds, so that although it goes up from 0 to 60, it isn’t in perfect sync with the minutes.  I retrospect, developing for the Pebble watch was really annoying on the Android.  I finally figured out why it wasn’t working with my Android phone while it did on my tablet: the Android version was outdated!  (Version needs to be at least 4.2.2)  Anyways,  I think the end result looks kind of like the messaging system the Predator alien has on its wearable wrist device.  Cool stuff.

Here is a sketch:
pebblesketch
Here are some stills:0-40-46
Time:  0 hours, 40 minutes and 46 seconds.

24-10-53
Time: 24 hours, 10 minutes and 53 seconds.

And here is the code:

 
#include 

//windows and layers  
static Window *s_main_window;
static Layer *s_canvas_layer;

//variables to be used
int hours = 0;
int minutes = 0;
int seconds = 0;

//---CLOCK UPDATE STUFF---//
static void update_time() {
  // Get a tm structure
  time_t temp = time(NULL); 
  struct tm *tick_time = localtime(&temp);
  static char buffer[] = "00:00";

  // Write the current hours and minutes into the buffer
  if(clock_is_24h_style() == true) {
    // Use 24 hour format
    strftime(buffer, sizeof("00:00"), "%H:%M", tick_time);
  } else {
    // Use 12 hour format
    strftime(buffer, sizeof("00:00"), "%I:%M", tick_time);
  }
  //update hours and minutes
  hours = (int)(buffer[0]-'0')*10+(int)(buffer[1]-'0');
  minutes= (int)(buffer[3]-'0')*10+(int)(buffer[4]-'0');
  //reset seconds
  if(seconds == 60) {
    seconds = 0;
  } else {
    seconds += 1;
  }
  //mark layer dirty for rerendering
  layer_mark_dirty(s_canvas_layer);
}
static void tick_handler(struct tm *tick_time, TimeUnits units_changed) {
  update_time();
}

//---CANVAS STUFF---//
void drawSymbol(int shape, int x, int y, GContext *ctx) {
  //shape:  0 = horizontal line, 1 = vertical line, 2 = square
  graphics_context_set_fill_color(ctx, GColorBlack);
  if(shape == 0) {
    graphics_fill_rect(ctx, GRect(x+6, y+16, 24, 4), 0, GCornerNone);
  } else if(shape == 1) {
    graphics_fill_rect(ctx, GRect(x+16, y+6, 4, 24), 0, GCornerNone);  
  } else if(shape == 2) {
    graphics_fill_rect(ctx, GRect(x+10, y+10, 16, 16), 0, GCornerNone);    
  }
}
//draw the time in ternary:
static void canvas_update_proc(Layer *this_layer, GContext *ctx) {
  //update time
  update_time();
  
  //get ternary hours:
  int thours = hours;
  for(int h = 0; h < 4; h++) {
    drawSymbol(thours%3,h*36,0,ctx);
    thours /= 3;
  }
  //get ternary minutes:
  int tminutes = minutes;
  for(int m = 0; m < 4; m++) {
    drawSymbol(tminutes%3,m*36,36,ctx);
    tminutes /= 3;
  }
  //get ternary seconds:
  int tseconds = seconds;
  for(int s = 0; s < 4; s++) {
    drawSymbol(tseconds%3,s*36,72,ctx);
    tseconds /= 3;
  }
  
}

//---WNDOW STUFF---//
static void main_window_load(Window *window) {
  Layer *window_layer = window_get_root_layer(window);
  GRect window_bounds = layer_get_bounds(window_layer);
  s_canvas_layer = layer_create(GRect(0, 0, window_bounds.size.w, window_bounds.size.h));
  layer_add_child(window_layer, s_canvas_layer);
  layer_set_update_proc(s_canvas_layer, canvas_update_proc);
  
  update_time();
}
static void main_window_unload(Window *window) {
  layer_destroy(s_canvas_layer);
}


//---REQUIRED FUNCTIONS---//
static void init() {
  s_main_window = window_create();
  // Set handlers to manage the elements inside the Window
  window_set_window_handlers(s_main_window, (WindowHandlers) {
    .load = main_window_load,
    .unload = main_window_unload
  });
  // Show the Window on the watch, with animated=true
  window_stack_push(s_main_window, true);
  
  tick_timer_service_subscribe(SECOND_UNIT, tick_handler);
}
static void deinit() {
  // Destroy Window
  window_destroy(s_main_window);
} 
int main(void) {
  init();
  app_event_loop();
  deinit();
}