Skip to content

Instantly share code, notes, and snippets.

@morgulbrut
Last active November 30, 2015 18:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save morgulbrut/ed29a2c7a000f6117db1 to your computer and use it in GitHub Desktop.
Save morgulbrut/ed29a2c7a000f6117db1 to your computer and use it in GitHub Desktop.
Clock Firmware
#include "neopixel.h"
#include <math.h>
#include <algorithm>
#include <iterator>
#define PIXEL_PIN D2
#define PIXEL_COUNT 60
#define PIXEL_TYPE WS2812B
// thanks stackoverflow
#define CHECK_BIT(var,pos) !!((var) & (1<<(static_cast<int>(pos))))
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
int eepromAddTimeShift = 2;
/*
Handsmode:
curl https://api.particle.io/v1/devices/43002e001147343339383037/setHaMode -d access_token=68ac7f91a8d33a696ad5d84d7f3d7d6c104c87d3 -d params=8
curl 'https://api.particle.io/v1/devices/43002e001147343339383037/getHaMode?access_token=68ac7f91a8d33a696ad5d84d7f3d7d6c104c87d3'
Binary | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 1
Reverse | 0 0 0 0 | 0 0 0 0 | 1 1 1 1 | 1 1 1 1 | X
Trail | 0 0 0 0 | 1 1 1 1 | 0 0 0 0 | 1 1 1 1 | X
random Secs | 0 0 1 1 | 0 0 1 1 | 0 0 1 1 | 0 0 1 1 | X
rainbow Secs | 0 1 0 1 | 0 1 0 1 | 0 1 0 1 | 0 1 0 1 | X
*/
int handsMode = 16;
enum class modesMask{
RAINBOW_SECS,RAND_SECS,TRAIL,REVERSE,BINARY
};
int hourHue = 60;
int minuteHue = 180;
int secondHue = 300;
int timeShift = 1;
int brightness = 60;
String wifi;
int isConnected;
bool hourPxl[PIXEL_COUNT], minPxl[PIXEL_COUNT],secPxl[PIXEL_COUNT],hMarkPxl[PIXEL_COUNT];
float handCorr = 0.0;
int hourPos,minutePos,secondPos;
bool leds[8];
void setup(){
Particle.function("tellTime",tellTime);
//Particle.function("setTShift",setTimeShift);
Particle.function("setHaMode",setHandsMode);
Particle.function("setBright",setBright);
Particle.function("setHHue",setHourHue);
Particle.function("setMHue",setMinHue);
Particle.function("setSHue",setSecHue);
Particle.function("rndMode",randomMode);
Particle.variable("getHaMode",handsMode);
Particle.variable("getHHue",hourHue);
Particle.variable("getMHue",minuteHue);
Particle.variable("getSHue",secondHue);
Particle.variable("getBright",brightness);
Particle.variable("getWifi",wifi);
wifi = WiFi.SSID();
strip.begin();
strip.clear();
strip.setBrightness(brightness);
//timeShift = EEPROM.read(eepromAddTimeShift);
Time.zone(timeShift);
isConnected = 2;
randomSeed(Time.second());
// handsMode = random(17);
}
void loop(){
if(isConnected == 2 && Particle.connected()){
isConnected = 1;
}
handCorr=Time.minute()/60.0;
calcHandsPos();
drawClock();
strip.show();
delay(250);
}
void calcHandsPos(){
clearStrip();
if(!CHECK_BIT(handsMode,modesMask::BINARY)){
// set the hourmarks
for(int i = 0; i<PIXEL_COUNT; i++){
if(i%5==0){
hMarkPxl[i]=true;
}
}
// set the time pos
if(CHECK_BIT(handsMode,modesMask::RAND_SECS)){
hourPos = int(5*(Time.hour()%12+handCorr));
minutePos = Time.minute();
if(random(50)>40){
secondPos = Time.second();
}
}
else{
hourPos = int(5*(Time.hour()%12+handCorr));
minutePos = Time.minute();
secondPos = Time.second();
}
if(CHECK_BIT(handsMode,modesMask::TRAIL)){
for( int i = 0;i <=hourPos;i++){
hourPxl[i]=true;
}
for( int i = 0;i <=minutePos;i++){
minPxl[i]=true;
}
for( int i = 0;i <=secondPos;i++){
secPxl[i]=true;
}
}
else {
hourPxl[hourPos]=true;
minPxl[minutePos]=true;
secPxl[secondPos]=true;
}
if(CHECK_BIT(handsMode,modesMask::REVERSE)){
// reverse arrays;
std::reverse(std::begin(hourPxl), std::end(hourPxl));
std::reverse(std::begin(minPxl), std::end(minPxl));
std::reverse(std::begin(secPxl), std::end(secPxl));
}
}
else{ // BINARY MODE
intToBin(leds,Time.second());
strip.clear();
for (int i=0; i<7; i++) {
if(leds[i]==1){
secPxl[i*2] = true;
}
else{
hMarkPxl[i*2] = true;
}
}
intToBin(leds,Time.minute());
for (int i=0; i<7; i++) {
if(leds[i]==1){
minPxl[PIXEL_COUNT/3+i*2]=true;
}
else{
hMarkPxl[PIXEL_COUNT/3+i*2]=true;
}
}
intToBin(leds,Time.hour());
for (int i=0; i<7; i++) {
if(leds[i]==1){
hourPxl[PIXEL_COUNT*2/3+i*2]=true;
}
else{
hMarkPxl[PIXEL_COUNT*2/3+i*2]=true;
}
}
}
}
void drawClock(){
strip.clear();
drawHMarks();
if(secondPos>=minutePos && minutePos>=hourPos ){
drawSec();
drawMin();
drawHour();
}
else if(secondPos>=hourPos && hourPos>=minutePos ){
drawSec();
drawHour();
drawMin();
}
else if(minutePos>=secondPos && secondPos>=hourPos ){
drawMin();
drawSec();
drawHour();
}
else if(minutePos>=hourPos && hourPos>=secondPos ){
drawMin();
drawHour();
drawSec();
}
else if(hourPos>=minutePos && minutePos>=secondPos ){
drawHour();
drawMin();
drawSec();
}
else if(hourPos>=secondPos && secondPos>=minutePos ){
drawHour();
drawSec();
drawMin();
}
}
void drawHMarks(){
for(int i = 0; i<PIXEL_COUNT; i++){
if (hMarkPxl[i]) strip.setPixelColor(i,strip.Color(20,20,20));
}
}
void drawSec(){
for(int i = 0; i<PIXEL_COUNT; i++){
if (secPxl[i]){
if(CHECK_BIT(handsMode,modesMask::RAINBOW_SECS)){
strip.setPixelColor(i,ColorHSV(i*6,255,255));
}else{
strip.setPixelColor(i,ColorHSV(secondHue,255,255));
}
}
}
}
void drawMin(){
for(int i = 0; i<PIXEL_COUNT; i++){
if (minPxl[i]) strip.setPixelColor(i,ColorHSV(minuteHue,255,255));
}
}
void drawHour(){
for(int i = 0; i<PIXEL_COUNT; i++){
if (hourPxl[i]) strip.setPixelColor(i,ColorHSV(hourHue,255,255));
}
}
void clearStrip(){
for(int i = 0; i<PIXEL_COUNT; i++){
hourPxl[i]=false;
minPxl[i]=false;
secPxl[i]=false;
hMarkPxl[i]=false;
}
}
uint32_t ColorHSV(uint16_t hue,uint8_t sat, uint8_t val){
// hue: 0..360
// sat,val: 0..255
uint16_t r,g,b;
uint16_t H_accent = hue/60;
//unsigned int bottom = ((255 - sat) * val)>>8;
uint16_t bottom = 0;
uint16_t top = val;
uint16_t rising = ((top-bottom) *(hue%60 ) ) / 60 + bottom;
uint16_t falling = ((top-bottom) *(60-hue%60) ) / 60 + bottom;
switch(H_accent) {
case 0:
r = top;
g = rising;
b = bottom;
break;
case 1:
r = falling;
g = top;
b = bottom;
break;
case 2:
r = bottom;
g = top;
b = rising;
break;
case 3:
r = bottom;
g = falling;
b = top;
break;
case 4:
r = rising;
g = bottom;
b = top;
break;
case 5:
r = top;
g = bottom;
b = falling;
break;
}
return strip.Color(r,g,b);
}
void intToBin(bool *binArr,int val){
for (int i=0; i<8; i++) {
if (val%2){
binArr[i]=1;
}
else{
binArr[i]=0;
}
val/=2;
}
}
/* Callback functions */
int setHandsMode(String command){
handsMode = command.toInt();
return handsMode;
}
int tellTime(String command){
if (command == "hour"){
return Time.hour();
} else if (command == "minute"){
return Time.minute();
} else if (command == "second"){
return Time.second();
} else if (command == "now"){
return Time.now();
} else{
return -1;
}
}
int setHourHue(String command){
hourHue = constrain(command.toInt(),0,359);
return hourHue;
}
int setMinHue(String command){
minuteHue = constrain(command.toInt(),0,359);
return minuteHue;
}
int setSecHue(String command){
secondHue = constrain(command.toInt(),0,359);
return secondHue;
}
int setBright(String command){
brightness = constrain(command.toInt(),1,150);
strip.setBrightness(brightness);
return brightness;
}
int randomMode(String command){
handsMode = random(17);
return handsMode;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment