Reloj binario con adafruit_neopixel

Qué increíble!!

Ojalá fueras mi alumno porque te sacaría buen programador/electrónico al menos por el año que me tuvieras de profesor.

Primero las herramientas: Qué voy a instalar? Un RTC Real Time Clock o Reloj de Tiempo Real.
Qué modelo tengo? DS1307 que es una porquería pero sirve para experimentar rápido y es barato y el DS3231 y sus variantes que son mas precisos.
Esperemos tengas este último.
De todos modos siempre cuando desconoces algo, lo buscas... cómo? en google pones :
Arduino RTC
Arduino DS1302
Arduino DS3231
Y tendras no algunos sino muchos tutoriales.

Bien, el RTC es un dispositivo I2C que es un BUS que usa SDA y SCL o sea pines A4 y A5 además de tener que alimentarlo o sea GND y VCC (sea 3.3 o 5V que depende de tu arduino)

Ya sabes de que hablas, un RTC, sabes como se conecta al bus I2C.
Que sigue? pues comunicarme y para ello uso librerías.

Según tu IDE vas al gestor de librerías y pones RTC y tendrás muchas opciones. A mi no me gusta esa opción en ESTE CASO.
Uso esta librería por otras razones que ahora no vienen al caso.

Librería RTC de PJRC

Soporta todos los tipos de RTC que se usan.

Tiene dos ejemplos como casi todas las librerías traen sus ejemplos.
Uno para fijar la hora y otro para leerla.

Ahora descargarás la librería de la opción indicada en Github . Ya nos cuentas si tienes problemas.

Corre los ejemplos y si esta bien cableado el RTC debería funcionar.
Prueba desconectando y conectando el USB para comprobar que el RTC funciona bien cuando la energía se corta.

Cuando tengas eso me dices y mientras evalúó la modificación al reloj neopixel

Aca el código modificado para 20 bits y con cambio de colores. Yo no le di colores eso te lo dejo a vos.

#include <TimeLib.h>
#include <Adafruit_NeoPixel.h>
#include <string.h>
#include <Wire.h>
#include <DS1307RTC.h>

#define pixel_pin   6 //Pin al que he conectado la tira de leds
#define pixel_count 25// numero de leds usados
Adafruit_NeoPixel strip = Adafruit_NeoPixel (25, 6, NEO_GRB + NEO_KHZ800); //declaracion necesaria no se muy bien porque :s

int time = 1000; //Tiempo para los segundos


#define TIME_HEADER  "T"   // Header tag for serial time sync message
#define TIME_REQUEST  7    // ASCII bell character requests a time sync message 

void hora_to_binario(byte hora, byte min, byte seg);
void digitalClockDisplay();

void setup() {
  Serial.begin(115200);
  while (!Serial) ; // wait until Arduino Serial Monitor opens

  // Ajustar al hora manualmente y luego comentarlo siempre y cuando no se apague el arduino.
  // setTime(20, 42, 00, 17, 04, 2018);
 
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  setSyncInterval(600);
  if (timeStatus() != timeSet) 
      Serial.println("No pude sincronizarme con el RTC");
   else
      Serial.println("RTC ha fijado el tiempo del sistema");

  strip.begin();//necesarios para poder comenzar no se muy bien por que.
  strip.show();//muestra la anterior linea.
  strip.setPixelColor(0,255,255,255);//para comenzar con los leds en blanco, primer digito representa el nº del led y las siguientes cifras el color en R G y B
  strip.setPixelColor(1,255,255,255);
  strip.setPixelColor(2,255,255,255);
  strip.setPixelColor(3,255,255,255);
  strip.setPixelColor(5,255,255,255);
  strip.setPixelColor(6,255,255,255);
  strip.setPixelColor(7,255,255,255);
  strip.setPixelColor(9,255,255,255);
  strip.setPixelColor(10,255,255,255);
  strip.setPixelColor(11,255,255,255);
  strip.setPixelColor(12,255,255,255);
  strip.setPixelColor(14,255,255,255);
  strip.setPixelColor(15,255,255,255);
  strip.setPixelColor(16,255,255,255);
  strip.setPixelColor(18,255,255,255);
  strip.setPixelColor(19,255,255,255);
  strip.setPixelColor(20,255,255,255);
  strip.setPixelColor(21,255,255,255);
  strip.setPixelColor(23,255,255,255);
  strip.setPixelColor(24,255,255,255);
  strip.show();
}

void loop() {
  
  if (timeStatus() == timeSet) {
       digitalClockDisplay();
   }
   delay(1000);
}
 
void digitalClockDisplay(){
  // digital clock display of the time
  char buffer[40];
  time_t tnow = now();

  sprintf(buffer, "%02d:%02d:%02d", hour(tnow),minute(tnow),second(tnow));
  Serial.println(buffer); 
  hora_to_binario(hour(tnow),minute(tnow),second(tnow));
}



time_t requestSync() {
  Serial.write(TIME_REQUEST);  
  return 0; // the time will be sent later in response to serial mesg
}

void hora_to_binario(byte hora, byte min, byte seg) {

  // Secuencia de bits
  // 2 bits decenas horas    + 4 bits horas
  // 3 bits decenas minutos  + 4 bits minutos 
  // 3 bits decenas segundos + 4 bits segundos
  // total 20 bits 

  unsigned long tmp = (unsigned long) (hora/10)<<17UL | 
                      (unsigned long) (hora%10)<<14UL | 
                      (unsigned long) (min/10) <<10UL | 
                      (unsigned long) (min%10) <<7UL | 
                      (unsigned long) (seg/10) <<3UL | 
                      (unsigned long) (seg%10);
  unsigned long z;
  byte cont = 0;

  // Bits
  // tienes de 0.. 19 por eso 2^19 = 524288 

  for (z = 524288; z > 0UL; z >>= 1UL) {
        Serial.print(((tmp & z) == z)? '1' : '0');
        bool tmp1 = ((tmp & z) == z); // tmp1 valdra 1 o 0     
        switch (cont) {  // cont lleva la posicion del bit del neopixel
          case 0 ... 3: // para las unidades de segundos
                        if (tmp1) 
                            strip.setPixelColor(cont, 255,255,255);  // 1              
                        else 
                            strip.setPixelColor(cont, 100,  0,  0);  // 0
                        break;
          case 4 ... 6: // para las decenas de segundos
                        if (tmp1) 
                            strip.setPixelColor(cont, 255,255,255);  // 1              
                        else
                            strip.setPixelColor(cont, 100,  0,  0);  // 0
                        break;
          case 7 ... 10: // para las unidades de minutos
                        if (tmp1) 
                            strip.setPixelColor(cont, 255,255,255);  // 1              
                        else
                            strip.setPixelColor(cont, 100,  0,  0);  // 0
                        break;
          case 11 ... 13: // para las decenas de minutos
                        if (tmp1) 
                            strip.setPixelColor(cont, 255,255,255);  // 1              
                        else
                            strip.setPixelColor(cont, 100,  0,  0);  // 0
                        break;
          case 14 ... 17: // para las unidades de horas
                        if (tmp1) 
                            strip.setPixelColor(cont, 255,255,255);  // 1              
                        else
                            strip.setPixelColor(cont, 100,  0,  0);  // 0
                        break;
          case 18 ... 19: // para las decenas de horas
                        if (tmp1) 
                            strip.setPixelColor(cont, 255,255,255);  // 1              
                        else
                            strip.setPixelColor(cont, 100,  0,  0);  // 0
                        break;
        }
        cont++;
    }
    strip.show();
}