I have always been fascinated with using colors to represent numeric data, and finally brought this idea to fruition with a four "digit" clock. Why octal? Because I haven't been able to reliably distinguish ten colors. The colors used - representing zero through seven - are white, red, orange, yellow, green, aqua (cyan), blue, and magenta, rendered on neopixels. The image above shows orange-aqua : magenta-white, ie 25:70 in octal, which is (2x7)+5: 7x7 in decimal ie 19:49 (7.49 for 12 hour folk).
The container is 3D printed. The front face has a series of thick cones printed into the back of it, preventing light bleed to the adjacent spots, each of which is a seat for a neopixel. The back contains a USB power inlet and buttons to set hours and minutes. The processor is an arduino nano, conveniently getting the power, and it is connected to a real time clock as well as the neopixels.
Code and hookup details below:
// Octal clock. Hours and minutes each represented by two color lights hhmm
// digits represented by colors 0=white, 1=red, 2=orange, 3=yellow, 4= green
// 5=aqua, 6=blue, 7 = magenta
// Date and time functions using a DS3231 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"
RTC_DS3231 rtc;
// adafruit neopixel 4 pixels
// wiring: d8 to hour button, NO to ground; d5 to neopixel; d9 to minute button NO to ground
// wiring: a5 to SCL; a4 to SDA on 3231
#include <Adafruit_NeoPixel.h>
#define PIN 5
Adafruit_NeoPixel strip = Adafruit_NeoPixel(12, PIN, NEO_GRB + NEO_KHZ800);
#define HOUR_PIN 8
#define MINUTE_PIN 9
//#define SET_PIN 7
#define DEBOUNCE_DELAY 10
#define MAX_BUTTONS_INPUT 20
// 3 one dimensional arrays to hold color values
//numbers 0 1 2 3 4 5 6 7
// colors w r o y g c b m
int r[]={40 ,110,100,70 ,0 ,0 ,0 ,70 };
int g[]={36 ,0 ,15 ,60 ,90 ,60 ,0 ,0 };
int b[]={20 ,0 ,0 ,0 ,0 ,15 ,100,60 };
void setup () {
Serial.begin(9600);
rtc.begin();
rtc.adjust(DateTime(2014, 1, 21, 21, 57, 30)); //Plug in clock at correct time, no need for resets
strip.begin();
strip.show(); // Initialize all pixels to 'off'
pinMode(HOUR_PIN, INPUT_PULLUP);
pinMode(MINUTE_PIN, INPUT_PULLUP);
//pinMode(SET_PIN, INPUT_PULLUP);
}
int lastButtonValue[MAX_BUTTONS_INPUT];
int currentButtonValue[MAX_BUTTONS_INPUT];
void loop () {
//int set_button = debounce(SET_PIN);not used in this implementation
int hour_button = debounce(HOUR_PIN);
int minute_button = debounce(MINUTE_PIN);
if(hour_button && hasChanged(HOUR_PIN))
{
DateTime newTime = DateTime(rtc.now().unixtime()+3600);//blocks of 1 hour
rtc.adjust( newTime );
}
if(minute_button && hasChanged(MINUTE_PIN))
{
DateTime newTime = DateTime(rtc.now().unixtime()+60);//blocks of 1 minute
rtc.adjust( newTime );
}
DateTime now = rtc.now();
//int s=now.second();
int m=d2o(now.minute());//get octal value of minutes
int h=d2o(now.hour());//get octal value of hours
//split into individual digits
int m1=(m/10);
int m0=(m-10*(m/10));
int h1=(h/10);
int h0=(h-10*(h/10));
int c[]={h1,h0,m1,m0};
// Serial.println (h0);
// Serial.println (m1);
// Serial.println (m0);
strip.setPixelColor(0, r[h1],g[h1],b[h1]); //h1, hour 10s
strip.setPixelColor(1, r[h0],g[h0],b[h0]); //h0, hour 1s
strip.setPixelColor(2, r[m1],g[m1],b[m1]); // m1, min 10s
strip.setPixelColor(3, r[m0],g[m0],b[m0]); //mo, min 1s
strip.show();
delay(300);
//cleanup (not needed in this implementation)
// strip.setPixelColor(0, 0,0,0);
// strip.setPixelColor(1, 0,0,0);
// strip.setPixelColor(2, 0,0,0);
// strip.setPixelColor(3, 0,0,0);
//
//strip.show();
}
//end of main loop
//functions
int debounce(int pin) //inverting output for internal pullup
{
int val = !digitalRead(pin);
if( val == lastButtonValue[pin] )
{
currentButtonValue[pin] = val;
return val;
}
delay(DEBOUNCE_DELAY);
val = !digitalRead(pin);
if( val != lastButtonValue[pin] )
{
currentButtonValue[pin] = val;
return val;
}
currentButtonValue[pin] = lastButtonValue[pin];
return lastButtonValue[pin];
}
boolean hasChanged(int pin)
{
return lastButtonValue[pin] != currentButtonValue[pin];
}
int d2o(int decimalnum) //decimal to octal conversion
{
int octalnum = 0, temp = 1;
while (decimalnum != 0)
{
octalnum = octalnum + (decimalnum % 8) * temp;
decimalnum = decimalnum / 8;
temp = temp * 10;
}
return octalnum;
}

No comments:
Post a Comment