Go Down

Topic: 10x10 word clock based on adafruit 8x8 code problem. (Read 314 times) previous topic - next topic

richigobankai

Hello there, need some help seeing where I've gone wrong.
I;m trying to make a work clock based on the adafruit 8x8, expanded to 10x10 using neopixel strips instead of the 8x8 premade matrix and using a pro mini instead of a trinket.
I've changed what I think needs to be changed and the code compiles and uploads, but the leds arent lighting up in the correct places. what should be in the bottom right, appears 34ish pixels further up the chain and stuff that should be at the top is cut off completely.
can anyone help shed some light on this for me?

Code: [Select]

/
 *=> - - I T - I S - - - >
 * < Q U A R T E R T E N <
 * > T W E N T Y H A L F >
 * < F I V E - P A S T - <
 * > T O - F U C K I N G >
 * < O N E T W O F O U R <
 * > E L E V E N F I V E >
 * < T H R E E S E V E N <
 * > T W E L V E I G H T >
 * < S I X N I N E T E N <
 *
 */

// include the library code:
#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

// define how to write each of the words

// 64-bit "mask" for each pixel in the matrix- is it on or off?
uint64_t mask;

// define masks for each word. we add them with "bitwise or" to generate a mask for the entire "phrase".
#define MFIVE    mask |= 0x3C0000000000000000        // these are in hexadecimal
#define MTEN     mask |= 0x700000000000000000000
#define AQUARTER mask |= 0x3F800000000000000000000
#define TWENTY   mask |= 0xFC000000000000000000 
#define HALF     mask |= 0x3C00000000000000000
#define PAST     mask |= 0x1E000000000000000
#define TO       mask |= 0xC00000000000000
#define ONE      mask |= 0x3800000000000
#define TWO      mask |= 0x700000000000
#define THREE    mask |= 0x3E000000
#define FOUR     mask |= 0xF0000000000
#define FIVE     mask |= 0x3C0000000
#define SIX      mask |= 0x380
#define SEVEN    mask |= 0x1F00000
#define EIGHT    mask |= 0x7C00
#define NINE     mask |= 0x78
#define TEN      mask |= 0x7
#define ELEVEN   mask |= 0xFC00000000
#define TWELVE   mask |= 0xFC000
#define FUCKING mask |= 0x1FC000000000000

// define pins
#define NEOPIN 8  // connect to DIN on NeoMatrix 8x8
#define RTCGND 6 // use this as DS1307 breakout ground
#define RTCPWR 5 // use this as DS1307 breakout power


// brightness based on time of day- could try warmer colors at night?
#define DAYBRIGHTNESS 40
#define NIGHTBRIGHTNESS 20

// cutoff times for day / night brightness. feel free to modify.
#define MORNINGCUTOFF 7  // when does daybrightness begin?   7am
#define NIGHTCUTOFF   22 // when does nightbrightness begin? 10pm


// define delays
#define FLASHDELAY 250  // delay for startup "flashWords" sequence
#define SHIFTDELAY 100   // controls color shifting speed


RTC_DS1307 RTC; // Establish clock object
DateTime theTime; // Holds current clock time

int j;   // an integer for the color shifting effect

// Do you live in a country or territory that observes Daylight Saving Time?
// https://en.wikipedia.org/wiki/Daylight_saving_time_by_country
// Use 1 if you observe DST, 0 if you don't. This is programmed for DST in the US / Canada. If your territory's DST operates differently,
// you'll need to modify the code in the calcTheTime() function to make this work properly.
#define OBSERVE_DST 1


// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//Adafruit_NeoPixel matrix = Adafruit_NeoPixel(100, NEOPIN, NEO_GRB + NEO_KHZ800);

// configure for 8x8 neopixel matrix
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(10, 10, NEOPIN,
                            NEO_MATRIX_TOP  + NEO_MATRIX_LEFT +
                            NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG,
                            NEO_GRB         + NEO_KHZ800);


void setup() {
  // put your setup code here, to run once:

  //Serial for debugging
  //Serial.begin(9600);

  // set pinmodes
  pinMode(NEOPIN, OUTPUT);

  // set analog pins to power DS1307 breakout!
  pinMode(RTCGND, OUTPUT); // analog 2
  pinMode(RTCPWR, OUTPUT); // analog 3

  // set them going!
  digitalWrite(RTCGND, LOW);  // GND for RTC
  digitalWrite(RTCPWR, HIGH); // PWR for RTC

  // start clock
  Wire.begin();  // Begin I2C
  RTC.begin();   // begin clock

  if (! RTC.isrunning()) {
    //Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
    // add 2.5 minutes to get better estimates
    theTime = RTC.now();
    theTime = theTime.unixtime() + 150;
    // DST? If we're in it, let's subtract an hour from the RTC time to keep our DST calculation correct. This gives us
    // Standard Time which our DST check will add an hour back to if we're in DST.
    if (OBSERVE_DST == 1) {
      if (checkDst() == true) { // check whether we're in DST right now. If we are, subtract an hour.
        theTime = theTime.unixtime() - 3600;
      }
    }
    RTC.adjust(theTime);
  }

  matrix.begin();
  matrix.setBrightness(DAYBRIGHTNESS);
  matrix.fillScreen(0); // Initialize all pixels to 'off'
  matrix.show();

  // startup sequence... do colorwipe?
  // delay(500);
  // rainbowCycle(20);
  delay(500);
  flashWords(); // briefly flash each word in sequence
  delay(500);
}

void loop() {
  // put your main code here, to run repeatedly:

  adjustBrightness();
  displayTime();

  //mode_moon(); // uncomment to show moon mode instead!


}





richigobankai

The matrix has been tested and works fine with both strandtest and matrixtest examples.

Any insight would be greatly appreciated

This is what I'm using to calculate the hex mask values btw

Code: [Select]

 - - I T - I S - - -
 Q U A R T E R T E N
 T W E N T Y H A L F
 F I V E - P A S T -
 T O - F U C K I N G
 O N E T W O F O U R
 E L E V E N F I V E
 T H R E E S E V E N
 T W E L V E I G H T
 S I X N I N E T E N


five    3C0000000000000000

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

fucking    1FC000000000000

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

it is    3600000000000000000000000

0 0 1 1 0 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

to    C00000000000000

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

past    1E000000000000000

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

Half    3C00000000000000000

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

twenty    FC000000000000000000

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

quarter     3F800000000000000000000

0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

ten    700000000000000000000

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

number one    3800000000000

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

number two    700000000000

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

number three    3E000000

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

Number four    F0000000000

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

number five    3C0000000

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

Number six    380

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0

number seven    1F00000

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

Number eight    7C00

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0

number nine    78

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 1 0 0 0

number ten     7

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 1


Number eleven    FC00000000

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

Number twelve    FC000

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0



richigobankai

for example the lights on currently should be on "to" and "two" since its currently twenty to two in the morning.

PaulRB

Code: [Select]

// 64-bit "mask" for each pixel in the matrix- is it on or off?
uint64_t mask;

But there are 100 pixels in your matrix, not 64.

And before you ask/try, no, there is no such thing as uint100_t.

Why have you not posted all the code? I don't see the definition of flashWords() or displayTime() for example. You need to read the forum guidelines in the sticky post. I see you used code tags, but there is other important advice in there also.

richigobankai

Apologies for the missing info.

Moon.ino
Code: [Select]
/*
  Adapted from phil b's TIMESQUARE WATCH code.

  Only here if you feel like it!

*/

// Moon display: shows APPROXIMATE phase of moon.  This is not a medical
// device -- do not rely on this data if you are prone to lycanthropy.
// The phase shown is based on time elapsed since a known new moon, an
// approach that the Arduino can easily process but may be limited by a
// few flaws: the "known new moon" time is based on UTC, not local time,
// and may be a few hours off; the lunar period is assumed uniform and
// is rounded to whole seconds, and thus may drift over very long periods;
// unknown long-term accuracy of RTClib (e.g. DST & leap seconds ignored);
// uses 32-bit unixtime() and thus likely innacurate in years 2038+.
// This is for fun, not Real Science(tm).

// Used by various display modes for smooth fade-out before sleep
const uint8_t PROGMEM
fade[] =
{
  0,  1,  1,  2,  4,  5,  8, 10, 13, 17, 22, 27, 32, 39, 46,
  53, 62, 71, 82, 93, 105, 117, 131, 146, 161, 178, 196, 214, 234, 255
};

static const uint8_t PROGMEM
phases[] = {
  0x3B, 0x1F, 0x01, 0x00, 0x3E, 0x26, 0x03, 0x00, 0x3F, 0x2E, 0x06, 0x00, 0x42, 0x3E, 0x07,
  0x00, 0x47, 0x56, 0x07, 0x00, 0x54, 0x7A, 0x07, 0x00, 0x81, 0x88, 0x07, 0x00, 0xCC, 0x88,
  0x07, 0x00, 0xF2, 0x88, 0x07, 0x00, 0xF2, 0x84, 0x06, 0x00, 0xF0, 0x77, 0x03, 0x00, 0xED,
  0x63, 0x01, 0x00, 0xE3, 0x42, 0x01, 0x00, 0xCE, 0x27, 0x01, 0x00, 0x96, 0x1E, 0x01, 0x00,
  0x56, 0x1E, 0x01, 0x00, 0x00, 0x0B, 0x36, 0x01, 0x00, 0x0B, 0x46, 0x06, 0x00, 0x0B, 0x60,
  0x07, 0x00, 0x0B, 0x98, 0x07, 0x00, 0x0D, 0xCC, 0x07, 0x00, 0x46, 0xE8, 0x07, 0x01, 0xFC,
  0xE8, 0x07, 0x7A, 0xFF, 0xE8, 0x07, 0xFF, 0xFF, 0xE8, 0x08, 0xFF, 0xFF, 0xE1, 0x05, 0xFF,
  0xFF, 0xC5, 0x02, 0xFF, 0xFF, 0x89, 0x01, 0xFF, 0xF5, 0x47, 0x01, 0xFF, 0x82, 0x36, 0x01,
  0xEB, 0x0D, 0x36, 0x01, 0x1F, 0x0B, 0x36, 0x01, 0x00, 0x00, 0x0B, 0x1F, 0x00, 0x00, 0x0B,
  0x47, 0x00, 0x00, 0x0B, 0x6D, 0x00, 0x00, 0x1D, 0x89, 0x00, 0x00, 0x4D, 0x88, 0x00, 0x06,
  0xFF, 0x88, 0x00, 0xC3, 0xFF, 0x88, 0x64, 0xFF, 0xFF, 0x88, 0xFF, 0xFF, 0xFF, 0x88, 0xFF,
  0xFF, 0xFF, 0x72, 0xFF, 0xFF, 0xFF, 0x4B, 0xFF, 0xFF, 0xF5, 0x22, 0xFF, 0xFF, 0x78, 0x1F,
  0xFF, 0xB8, 0x0B, 0x1F, 0xFF, 0x04, 0x0B, 0x1F, 0x26, 0x00, 0x0B, 0x1F, 0x00, 0x00, 0x00,
  0x3B, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0xA4, 0x00, 0x00, 0x01, 0xF5, 0x00, 0x00,
  0x21, 0xF5, 0x00, 0x00, 0xFF, 0xF7, 0x00, 0xA0, 0xFF, 0xF5, 0x5C, 0xFF, 0xFF, 0xF5, 0xFF,
  0xFF, 0xFF, 0xF5, 0xFF, 0xFF, 0xFF, 0xDC, 0xFF, 0xFF, 0xFF, 0xA2, 0xFF, 0xFF, 0xFF, 0x59,
  0xFF, 0xFF, 0x7A, 0x3B, 0xFF, 0xF5, 0x00, 0x3C, 0xFF, 0x0C, 0x00, 0x3C, 0x2A, 0x00, 0x00,
  0x3C, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0xA4, 0x00, 0x00,
  0x01, 0xF5, 0x00, 0x00, 0x20, 0xF5, 0x00, 0x00, 0xFF, 0xF5, 0x00, 0xA0, 0xFF, 0xF5, 0x5D,
  0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xF5, 0xFF, 0xFF, 0xFF, 0xDC, 0xFF, 0xFF, 0xFF, 0xA0,
  0xFF, 0xFF, 0xFF, 0x58, 0xFF, 0xFF, 0x7A, 0x3B, 0xFF, 0xF5, 0x00, 0x3C, 0xFF, 0x0C, 0x00,
  0x3C, 0x2B, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x0B, 0x1F, 0x00, 0x00, 0x0B, 0x48, 0x00, 0x00,
  0x0B, 0x6D, 0x00, 0x00, 0x1D, 0x88, 0x00, 0x00, 0x4E, 0x88, 0x00, 0x06, 0xFF, 0x88, 0x00,
  0xC3, 0xFF, 0x88, 0x66, 0xFF, 0xFF, 0x88, 0xFF, 0xFF, 0xFF, 0x89, 0xFF, 0xFF, 0xFF, 0x73,
  0xFF, 0xFF, 0xFF, 0x4B, 0xFF, 0xFF, 0xF5, 0x22, 0xFF, 0xFF, 0x77, 0x1F, 0xFF, 0xB8, 0x0B,
  0x1F, 0xFF, 0x04, 0x0B, 0x1F, 0x26, 0x00, 0x0B, 0x1F, 0x00, 0x0B, 0x36, 0x01, 0x00, 0x0B,
  0x46, 0x06, 0x00, 0x0B, 0x5E, 0x07, 0x00, 0x0B, 0x9A, 0x07, 0x00, 0x0E, 0xCC, 0x07, 0x00,
  0x46, 0xE8, 0x07, 0x01, 0xFC, 0xE6, 0x07, 0x7C, 0xFF, 0xE8, 0x07, 0xFF, 0xFF, 0xE8, 0x07,
  0xFF, 0xFF, 0xE1, 0x05, 0xFF, 0xFF, 0xC7, 0x02, 0xFF, 0xFF, 0x88, 0x01, 0xFF, 0xF7, 0x48,
  0x01, 0xFF, 0x84, 0x36, 0x01, 0xEB, 0x0D, 0x36, 0x01, 0x1F, 0x0B, 0x36, 0x01, 0x3B, 0x1F,
  0x01, 0x00, 0x3F, 0x27, 0x03, 0x00, 0x3F, 0x2D, 0x06, 0x00, 0x41, 0x3E, 0x07, 0x00, 0x47,
  0x55, 0x07, 0x00, 0x52, 0x7A, 0x07, 0x00, 0x7F, 0x88, 0x07, 0x00, 0xCA, 0x88, 0x07, 0x00,
  0xF2, 0x88, 0x07, 0x00, 0xF5, 0x82, 0x06, 0x00, 0xF2, 0x77, 0x03, 0x00, 0xED, 0x63, 0x01,
  0x00, 0xE6, 0x42, 0x01, 0x00, 0xCE, 0x27, 0x01, 0x00, 0x96, 0x1F, 0x01, 0x00, 0x56, 0x1F,
  0x01, 0x00
}
,
leftHalf[]  = {
  0, 0,  0,  0,  0,  0,  0,  0, 15, 14, 13, 12, 11, 10, 9,
  8, 8,  8,  8,  8,  8,  8,  8,  7,  6,  5,  4,  3,  2, 1
}
,
rightHalf[] = {
  0, 1,  2,  3,  4,  5,  6,  7,  8,  8,  8,  8,  8,  8, 8,
  8, 9, 10, 11, 12, 13, 14, 15,  0,  0,  0,  0,  0,  0, 0
};

// Time/date of a known new moon (UNIX time) - Dec 7 1999 22:32
#define NEW_MOON 944605920
#define LP       2551443L // Lunar period in seconds

uint8_t phase = 0;

void mode_moon() {

  DateTime theTime = RTC.now();
  phase = (uint8_t) (((theTime.unixtime() - NEW_MOON) % LP) / (24L * 3600L));

  //uint8_t  b = 255; //(uint8_t)pgm_read_byte(&fade);
  uint8_t  b = (uint8_t)pgm_read_byte(&fade);

  matrix.fillScreen(0);
  blit(phases, 64, 8, pgm_read_byte(&rightHalf[phase]) * 4 , 0, 4, 0, 4, 8, b );
  matrix.setRotation(2);
  blit(phases, 64, 8, pgm_read_byte(&leftHalf[phase])  * 4 , 0, 4, 0, 4, 8, b );
  matrix.setRotation(0);


  matrix.show();
}


void blit(const uint8_t *img, int iw, int ih, int sx, int sy, int dx, int dy,
          int w, int h, uint8_t b) {
  uint16_t b1;
  uint8_t  shift, x, y;

  shift = 16;


  if ((dx >= 8) || ((dx + w - 1) < 0)) return; // Quick X-only clipping

  b1 = (uint16_t)b + 1; // +1 so shift (rather than divide) can be used

  for (y = 0; y < h; y++) {
    for (x = 0; x < w; x++) {
      byte clr = ((uint8_t)pgm_read_byte(&img[(sy + y) * iw + sx + x]) * b1);
      if (clr > 0 && clr < 70) {
        clr = clr * 40;  // boost dim pixels
      }
      matrix.drawPixel(dx + x, dy + y,
                       matrix.Color(0, 0, clr)); // draw in blue, pale white pixels look green and funky...

    }
  }
}



Adjustbrightness.ino

Code: [Select]

// change brightness based on the time of day.

void adjustBrightness() {

  // get time from the RTC
  //DateTime thetime = RTC.now();
  theTime = calculateTime(); // takes into account DST

  //change brightness if it's night time
  if (theTime.hour() < MORNINGCUTOFF || theTime.hour() > NIGHTCUTOFF) {
    matrix.setBrightness(NIGHTBRIGHTNESS);
  } else {
    matrix.setBrightness(DAYBRIGHTNESS);
  }
}


calculatetime.ino

Code: [Select]

/*
 *  Function to figure out if we're in Daylight Saving Time, then adding an hour if we are in DST.
 *  adapted from nseidle
 *  https://github.com/nseidle/Daylight_Savings_Time_Example/blob/master/Daylight_Savings_Time_Example.ino
 *
 *  This algorithm is programmed to observe Daylight Saving Time in the United States, where as of the time of writing  DST is observed
 *  between the second Sunday in March and the first Sunday in November. The rules for DST vary by country and territory.
 *  https://en.wikipedia.org/wiki/Daylight_saving_time_by_country
 *
 *  If you're in a territory which observes DST differently this code will need to be modified. If you're lucky enough to not observe DST
 *  then much of this code can be commented out!
 *
 *  This method doesn't check whether its 2am or not when the time change officially occurs. This could be more accurate at the expense of being more complicated.
 *
 */

DateTime calculateTime() {

  DateTime RTCTime = RTC.now();

  if (OBSERVE_DST == 1) {
    if (checkDst() == true) {
      RTCTime = RTCTime.unixtime() + 3600;  // add 1 hour or 3600 seconds to the time
    }
  }

  Serial.print(RTCTime.year(), DEC);
  Serial.print('/');
  Serial.print(RTCTime.month(), DEC);
  Serial.print('/');
  Serial.print(RTCTime.day(), DEC);
  Serial.print(' ');
  Serial.print(RTCTime.hour(), DEC);
  Serial.print(':');
  Serial.print(RTCTime.minute(), DEC);
  Serial.print(':');
  Serial.print(RTCTime.second(), DEC);
  Serial.println();

  return RTCTime;
}

boolean checkDst() {

  DateTime RTCTime = RTC.now();

  //Get the day of the week. 0 = Sunday, 6 = Saturday
  int previousSunday = RTCTime.day() - RTCTime.dayOfTheWeek();

  boolean dst = false; //Assume we're not in DST
  if (RTCTime.month() > 3 && RTCTime.month() < 11) dst = true; //DST is happening!

  //In March, we are DST if our previous Sunday was on or after the 8th.
  if (RTCTime.month() == 3)
  {
    if (previousSunday >= 8) dst = true;
  }
  //In November we must be before the first Sunday to be dst.
  //That means the previous Sunday must be before the 1st.
  if (RTCTime.month() == 11)
  {
    if (previousSunday <= 0) dst = true;
  }

  return dst;

}



richigobankai

colorfunctions.ino

Code: [Select]

// show colorshift through the phrase mask. for each NeoPixel either show a color or show nothing!
void applyMask() {

  for (byte i = 0; i < 64; i++) {
    boolean masker = bitRead(mask, 63 - i); // bitread is backwards because bitRead reads rightmost digits first. could have defined the word masks differently
    switch (masker) {
      case 0:
        matrix.setPixelColor(i, 0, 0, 0);
        break;
      case 1:
        matrix.setPixelColor(i, Wheel(((i * 256 / matrix.numPixels()) + j) & 255));
        //matrix.setPixelColor(i, WHITE);
        break;
    }
  }

  matrix.show(); // show it!
  delay(SHIFTDELAY);
  j++; // move the colors forward
  j = j % (256 * 5);

  // reset mask for next time
  mask = 0;
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {

  WheelPos = 255 - WheelPos;
  uint32_t wheelColor;

  if (WheelPos < 85) {
    wheelColor = matrix.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else if (WheelPos < 170) {
    WheelPos -= 85;
    wheelColor = matrix.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  } else {
    WheelPos -= 170;
    wheelColor = matrix.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }

  // convert from 24-bit to 16-bit color - NeoMatrix requires 16-bit. perhaps there's a better way to do this.
  uint32_t bits = wheelColor;
  uint32_t blue = bits & 0x001F;     // 5 bits blue
  uint32_t green = bits & 0x07E0;    // 6 bits green
  uint32_t red = bits & 0xF800;      // 5 bits red

  // Return shifted bits with alpha set to 0xFF
  return (red << 8) | (green << 5) | (blue << 3) | 0xFF000000;
}


// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  
  uint16_t i, j;

  for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
    for (i = 0; i < matrix.numPixels(); i++) {
      matrix.setPixelColor(i, Wheel(((i * 256 / matrix.numPixels()) + j) & 255));
    }
    matrix.show();
    delay(wait);
  }
}




Displaytime.ino

Code: [Select]

// function to generate the right "phrase" based on the time

void displayTime(void) {

  // get time from the RTC
  //DateTime theTime = RTC.now();
  theTime = calculateTime(); // takes into account DST

  // serial print current time
  /*
  Serial.print(theTime.year(), DEC);
  Serial.print('/');
  Serial.print(theTime.month(), DEC);
  Serial.print('/');
  Serial.print(theTime.day(), DEC);
  Serial.print(' ');
  Serial.print(theTime.hour(), DEC);
  Serial.print(':');
  Serial.print(theTime.minute(), DEC);
  Serial.print(':');
  Serial.print(theTime.second(), DEC);
  Serial.println();
  */

  // time we display the appropriate theTime.minute() counter
  if ((theTime.minute() > 4) && (theTime.minute() < 10)) {
    MFIVE;
    //Serial.print("five");
  }
  if ((theTime.minute() > 9) && (theTime.minute() < 15)) {
    MTEN;
    //Serial.print("ten");
  }
  if ((theTime.minute() > 14) && (theTime.minute() < 20)) {
    AQUARTER;
    //Serial.print("a quarter");
  }
  if ((theTime.minute() > 19) && (theTime.minute() < 25)) {
    TWENTY;
    //Serial.print("twenty");
  }
  if ((theTime.minute() > 24) && (theTime.minute() < 30)) {
    TWENTY;
    MFIVE;
    //Serial.print("twenty five");
  }
  if ((theTime.minute() > 29) && (theTime.minute() < 35)) {
    HALF;
    //Serial.print("half");
  }
  if ((theTime.minute() > 34) && (theTime.minute() < 40)) {
    TWENTY;
    MFIVE;
    //Serial.print("twenty five");
  }
  if ((theTime.minute() > 39) && (theTime.minute() < 45)) {
    TWENTY;
    //Serial.print("twenty");
  }
  if ((theTime.minute() > 44) && (theTime.minute() < 50)) {
    AQUARTER;
    //Serial.print("a quarter");
  }
  if ((theTime.minute() > 49) && (theTime.minute() < 55)) {
    MTEN;
    //Serial.print("ten");
  }
  if (theTime.minute() > 54) {
    MFIVE;
    //Serial.print("five");
  }

  if ((theTime.minute() < 5))
  {
    switch (theTime.hour()) {
      case 1:
      case 13:
        ONE;
        break;
      case 2:
      case 14:
        TWO;
        break;
      case 3:
      case 15:
        THREE;
        break;
      case 4:
      case 16:
        FOUR;
        break;
      case 5:
      case 17:
        FIVE;
        break;
      case 6:
      case 18:
        SIX;
        break;
      case 7:
      case 19:
        SEVEN;
        break;
      case 8:
      case 20:
        EIGHT;
        break;
      case 9:
      case 21:
        NINE;
        break;
      case 10:
      case 22:
        TEN;
        break;
      case 11:
      case 23:
        ELEVEN;
        break;
      case 0:
      case 12:
        TWELVE;
        break;
    }

  }
  else if ((theTime.minute() < 35) && (theTime.minute() > 4))
  {
    PAST;
    //Serial.print(" past ");
    switch (theTime.hour()) {
      case 1:
      case 13:
        ONE;
        break;
      case 2:
      case 14:
        TWO;
        break;
      case 3:
      case 15:
        THREE;
        break;
      case 4:
      case 16:
        FOUR;
        break;
      case 5:
      case 17:
        FIVE;
        break;
      case 6:
      case 18:
        SIX;
        break;
      case 7:
      case 19:
        SEVEN;
        break;
      case 8:
      case 20:
        EIGHT;
        break;
      case 9:
      case 21:
        NINE;
        break;
      case 10:
      case 22:
        TEN;
        break;
      case 11:
      case 23:
        ELEVEN;
        break;
      case 0:
      case 12:
        TWELVE;
        break;
    }
  }
  else
  {
    // if we are greater than 34 minutes past the hour then display
    // the next hour, as we will be displaying a 'to' sign
    TO;
    //Serial.print(" to ");
    switch (theTime.hour()) {
      case 1:
      case 13:
        TWO;
        break;
      case 14:
      case 2:
        THREE;
        break;
      case 15:
      case 3:
        FOUR;
        break;
      case 4:
      case 16:
        FIVE;
        break;
      case 5:
      case 17:
        SIX;
        break;
      case 6:
      case 18:
        SEVEN;
        break;
      case 7:
      case 19:
        EIGHT;
        break;
      case 8:
      case 20:
        NINE;
        break;
      case 9:
      case 21:
        TEN;
        break;
      case 10:
      case 22:
        ELEVEN;
        break;
      case 11:
      case 23:
        TWELVE;
        break;
      case 0:
      case 12:
        ONE;
        break;
    }
  }
  applyMask(); // apply phrase mask to colorshift function

}










flashwords.ino

Code: [Select]

// test function, can we draw those words correctly?

void flashWords(void) {

  FUCKING;  
  applyMask();
  delay(FLASHDELAY * 2);

  MFIVE;
  applyMask();
  delay(FLASHDELAY);

  MTEN;
  applyMask();
  delay(FLASHDELAY);

  AQUARTER;
  applyMask();
  delay(FLASHDELAY);

  TWENTY;
  applyMask();
  delay(FLASHDELAY);

  HALF;
  applyMask();
  delay(FLASHDELAY);

  TO;
  applyMask();
  delay(FLASHDELAY);

  PAST;
  applyMask();
  delay(FLASHDELAY);

  ONE;
  applyMask();
  delay(FLASHDELAY);

  TWO;
  applyMask();
  delay(FLASHDELAY);

  THREE;
  applyMask();
  delay(FLASHDELAY);

  FOUR;
  applyMask();
  delay(FLASHDELAY);

  FIVE;
  applyMask();
  delay(FLASHDELAY);

  SIX;
  applyMask();
  delay(FLASHDELAY);

  SEVEN;
  applyMask();
  delay(FLASHDELAY);

  EIGHT;
  applyMask();
  delay(FLASHDELAY);

  NINE;
  applyMask();
  delay(FLASHDELAY);

  TEN;
  applyMask();
  delay(FLASHDELAY);

  ELEVEN;
  applyMask();
  delay(FLASHDELAY);

  TWELVE;
  applyMask();
  delay(FLASHDELAY);

  // blank for a bit
  applyMask();
  delay(FLASHDELAY);

}



Quote
But there are 100 pixels in your matrix, not 64.

And before you ask/try, no, there is no such thing as uint100_t.
so what CAN I use instead?

PaulRB

I've got an idea, which I think would work for lighting up the words of the time.

I'm not sure if my idea would work for the other parts of your code, mostly the moon phase stuff. I don't think that uses the bit masks, and if so, it might not be a problem.

The idea is to abandon the bit mask approach. It is wasteful of memory anyway, and would be even more wasteful if you tried to extend it to 100 pixels. The reason it is wasteful is because the words on your clock are made up of contiguous pixel locations, as far as I can see.  If so, each word can be represented by a start pixel and and end pixel. All the pixels in between start and end will be lit as part of the word. You don't need bits to show that, and that's why the bit mask approach is wasteful.

You have 22 words and 6 gaps. Make two byte arrays:
Code: [Select]
byte wordEndPixel[28] = { ... };
byte wordLit[28];


Between the curly braces, list the end pixel numbers for each of your 22 words/gaps (the last one should end at 99) .

The wordLit[] array can hold 0 or 1 to indicate if that word is currently lit and would need to be updated by

Then, in applyMask(), change the code to go through all 28 words. For each word, determine if that word should be lit by checking the wordLit[] array. If the word is to be lit, light all the pixels up to the end pixel for that word. If the word is not lit, clear all the pixels up to the end pixel for the word.

Does this make sense?

Go Up