#include <Adafruit_NeoPixel.h>

#define PIXELS_PER_SEGMENT  2     // Number of LEDs in each Segment
#define PIXELS_DIGITS       4     // Number of connected Digits 
#define PIXELS_PIN          2     // GPIO Pin

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXELS_PER_SEGMENT * 7 * PIXELS_DIGITS, PIXELS_PIN, NEO_GRB + NEO_KHZ800);

//Pixel Arrangement
/*
          a
        f   b
          g
        e   c
          d
*/

// Segment array
byte segments[7] = {
  //abcdefg
  0b0000001,     // Segment g
  0b0000100,     // Segment e
  0b0001000,     // Segment d
  0b0010000,     // Segment c
  0b0100000,     // Segment b
  0b1000000,     // Segment a
  0b0000010     // Segment f
};

//Digits array
byte digits[10] = {
  //abcdefg
  0b1111110,     // 0
  0b0110000,     // 1
  0b1101101,     // 2
  0b1111001,     // 3
  0b0110011,     // 4
  0b1011011,     // 5
  0b1011111,     // 6
  0b1110000,     // 7
  0b1111111,     // 8
  0b1110011      // 9
};

//Clear all the Pixels
void clearDisplay() {
  for (int i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, strip.Color(0, 0, 0));
  }
  strip.show();
}

void setup() {
  strip.begin();
  strip.setBrightness(250);
}

void loop() {
  //disp_Seg(200);
  // ### Cycle through all segments (DelayTime)
  // ### Przechodź przez wszystkie segmenty (DelayTime)
  // ### Show digits from 0-9 (DelayTime)
  // ### Pokaż cyfry od 0 do 9 (DelayTime)
  disp_Digits(1000);
  // ### Show some Animations with the segments
  // ### Pokaż kilka animacji z segmentami
  //disp_Animation();
  // ### Count numbers in Ascending order (NUMBER, DelayTime)
  // ### Zliczaj liczby w kolejności rosnącej (NUMBER, DelayTime)
  //disp_CountUP(500, 450);
  // ### Count numbers in Descending order (NUMBER, DelayTime)
  // ### Zliczaj liczby w kolejności malejącej (NUMBER, DelayTime)
  //disp_CountDOWN(500, 250);
}

void disp_Seg(int wait) {
  clearDisplay();
  for (int d = 0; d < 5; d++) {
    for (int i = 6; i > 0; i--) {
      for (int n = 0; n < PIXELS_DIGITS; n++) {
        writeSegment(n, i);
      }
      strip.show();
      delay(wait);
    }
  }
}

void disp_Digits(int wait) {
  clearDisplay();
  for (int i = 0; i < 10; i++) {
    for (int n = 0; n < PIXELS_DIGITS; n++) {
      writeDigit(n, i);
    }
    strip.show();
    delay(wait);
  }
}

void disp_CountUP(int num, int wait) {
  clearDisplay();
  for (int i = 0; i <= num; i++) {
    writeDigit(0, (i / 100) % 10);
    writeDigit(1, (i / 10) % 10);
    writeDigit(2, (i / 1) % 10);
    strip.show();
    delay(wait);
  }
}

void disp_CountDOWN(int num, int wait) {
  clearDisplay();
  for (int i = num; i >= 0; i--) {
    writeDigit(0, (i / 100) % 10);
    writeDigit(1, (i / 10) % 10);
    writeDigit(2, (i / 1) % 10);
    strip.show();
    delay(wait);
  }
}

void disp_Animation() {
  clearDisplay();
  //UP-DOWN
  for (int i = 0; i < 7; i++) {
    for (int n = 0; n < PIXELS_DIGITS; n++) writeSegment(n, 5);
    strip.show();
    delay(100);
    for (int n = 0; n < PIXELS_DIGITS; n++) writeSegment(n, 0);
    strip.show();
    delay(100);
    for (int n = 0; n < PIXELS_DIGITS; n++) writeSegment(n, 2);
    strip.show();
    delay(100);
    for (int n = 0; n < PIXELS_DIGITS; n++) writeSegment(n, 0);
    strip.show();
    delay(100);
    for (int n = 0; n < PIXELS_DIGITS; n++) writeSegment(n, 5);
    strip.show();
    delay(100);
  }
  //LEFT-RIGHT
  for (int i = 0; i < 5; i++) {
    for (int n = 0; n < PIXELS_DIGITS; n++) {
      writeSegment(n, 6);
      strip.show();
      delay(150);
    }
    for (int n = PIXELS_DIGITS - 1; n >= 0; n--) {
      writeSegment(n, 3);
      strip.show();
      delay(150);
    }
    clearDisplay();
    for (int n = 0; n < PIXELS_DIGITS; n++) {
      writeSegment(n, 1);
      strip.show();
      delay(150);
    }
    for (int n = PIXELS_DIGITS - 1; n >= 0; n--) {
      writeSegment(n, 4);
      strip.show();
      delay(150);
    }
    clearDisplay();
  }
  //ZIG-ZAG
  for (int i = 0; i < 5; i++) {
    for (int n = 0; n < PIXELS_DIGITS; n++) {
      writeSegment(n, 6);
      strip.show();
      delay(125);
      clearDisplay();
      writeSegment(n, 1);
      strip.show();
      delay(125);
      clearDisplay();
      writeSegment(n, 4);
      strip.show();
      delay(125);
      clearDisplay();
      writeSegment(n, 3);
      strip.show();
      delay(125);
      clearDisplay();
    }
  }
}

void writeDigit(int index, int val) {
  byte digit = digits[val];
  for (int i = 6; i >= 0; i--) {
    int offset = index * (PIXELS_PER_SEGMENT * 7) + i * PIXELS_PER_SEGMENT;
    uint32_t color;
    if (digit & 0x01 != 0) {
      if (val == 1) color = strip.Color(255, 255, 0); // CRGB::Yellow
      if (val == 2) color = strip.Color(255, 0, 0); // CRGB::Red
      if (val == 3) color = strip.Color(0, 0, 255); // CRGB::Blue
      if (val == 4) color = strip.Color(0, 128, 0); // CRGB::Green
      if (val == 5) color = strip.Color(255, 69, 0); // CRGB::Orange Red
      if (val == 6) color = strip.Color(255, 0, 255); // CRGB::Fuchsia
      if (val == 7) color = strip.Color(0, 255, 0); // CRGB::Lime
      if (val == 8) color = strip.Color(0, 128, 128); // CRGB::Teal
      if (val == 9) color = strip.Color(0, 255, 255); // CRGB::Aqua
      if (val == 0) color = strip.Color(128, 0, 0); // CRGB::Maroon
    } else {
      color = strip.Color(0, 0, 0);
    }
    for (int j = offset; j < offset + PIXELS_PER_SEGMENT; j++) {
      strip.setPixelColor(j, color);
    }
    digit = digit >> 1;
  }
}

void writeSegment(int index, int val) {
  byte seg = segments[val];
  for (int i = 6; i >= 0; i--) {
    int offset = index * (PIXELS_PER_SEGMENT * 7) + i * PIXELS_PER_SEGMENT;
    uint32_t color;
    if (seg & 0x01 != 0) {
      if (val == 1) color = strip.Color(255, 255, 0); // CRGB::Yellow
      if (val == 2) color = strip.Color(255, 0, 0); // CRGB::Red
      if (val == 3) color = strip.Color(0, 0, 255); // CRGB::Blue
      if (val == 4) color = strip.Color(0, 128, 0); // CRGB::Green
      if (val == 5) color = strip.Color(255, 69, 0); // CRGB::Orange Red
      if (val == 6) color = strip.Color(255, 0, 255); // CRGB::Fuchsia
      if (val == 7) color = strip.Color(0, 255, 0); // CRGB::Lime
      if (val == 8) color = strip.Color(0, 128, 128); // CRGB::Teal
      if (val == 9) color = strip.Color(0, 255, 255); // CRGB::Aqua
      if (val == 0) color = strip.Color(128, 0, 0); // CRGB::Maroon
    } else {
      color = strip.Color(0, 0, 0);
    }
    for (int j = offset; j < offset + PIXELS_PER_SEGMENT; j++) {
      strip.setPixelColor(j, color);
    }
    seg = seg >> 1;
  }
}
nano:12
nano:11
nano:10
nano:9
nano:8
nano:7
nano:6
nano:5
nano:4
nano:3
nano:2
nano:GND.2
nano:RESET.2
nano:0
nano:1
nano:13
nano:3.3V
nano:AREF
nano:A0
nano:A1
nano:A2
nano:A3
nano:A4
nano:A5
nano:A6
nano:A7
nano:5V
nano:RESET
nano:GND.1
nano:VIN
nano:12.2
nano:5V.2
nano:13.2
nano:11.2
nano:RESET.3
nano:GND.3
rgb1:VDD
rgb1:DOUT
rgb1:VSS
rgb1:DIN
rgb2:VDD
rgb2:DOUT
rgb2:VSS
rgb2:DIN
rgb3:VDD
rgb3:DOUT
rgb3:VSS
rgb3:DIN
rgb4:VDD
rgb4:DOUT
rgb4:VSS
rgb4:DIN
rgb5:VDD
rgb5:DOUT
rgb5:VSS
rgb5:DIN
rgb6:VDD
rgb6:DOUT
rgb6:VSS
rgb6:DIN
rgb7:VDD
rgb7:DOUT
rgb7:VSS
rgb7:DIN
rgb8:VDD
rgb8:DOUT
rgb8:VSS
rgb8:DIN
rgb9:VDD
rgb9:DOUT
rgb9:VSS
rgb9:DIN
rgb10:VDD
rgb10:DOUT
rgb10:VSS
rgb10:DIN
rgb11:VDD
rgb11:DOUT
rgb11:VSS
rgb11:DIN
rgb12:VDD
rgb12:DOUT
rgb12:VSS
rgb12:DIN
rgb13:VDD
rgb13:DOUT
rgb13:VSS
rgb13:DIN
rgb14:VDD
rgb14:DOUT
rgb14:VSS
rgb14:DIN
rgb15:VDD
rgb15:DOUT
rgb15:VSS
rgb15:DIN
rgb16:VDD
rgb16:DOUT
rgb16:VSS
rgb16:DIN
rgb17:VDD
rgb17:DOUT
rgb17:VSS
rgb17:DIN
rgb18:VDD
rgb18:DOUT
rgb18:VSS
rgb18:DIN
rgb19:VDD
rgb19:DOUT
rgb19:VSS
rgb19:DIN
rgb20:VDD
rgb20:DOUT
rgb20:VSS
rgb20:DIN
rgb21:VDD
rgb21:DOUT
rgb21:VSS
rgb21:DIN
rgb22:VDD
rgb22:DOUT
rgb22:VSS
rgb22:DIN
rgb23:VDD
rgb23:DOUT
rgb23:VSS
rgb23:DIN
rgb24:VDD
rgb24:DOUT
rgb24:VSS
rgb24:DIN
rgb25:VDD
rgb25:DOUT
rgb25:VSS
rgb25:DIN
rgb26:VDD
rgb26:DOUT
rgb26:VSS
rgb26:DIN
rgb27:VDD
rgb27:DOUT
rgb27:VSS
rgb27:DIN
rgb28:VDD
rgb28:DOUT
rgb28:VSS
rgb28:DIN
rgb29:VDD
rgb29:DOUT
rgb29:VSS
rgb29:DIN
rgb30:VDD
rgb30:DOUT
rgb30:VSS
rgb30:DIN
rgb31:VDD
rgb31:DOUT
rgb31:VSS
rgb31:DIN
rgb32:VDD
rgb32:DOUT
rgb32:VSS
rgb32:DIN
rgb33:VDD
rgb33:DOUT
rgb33:VSS
rgb33:DIN
rgb34:VDD
rgb34:DOUT
rgb34:VSS
rgb34:DIN
rgb35:VDD
rgb35:DOUT
rgb35:VSS
rgb35:DIN
rgb36:VDD
rgb36:DOUT
rgb36:VSS
rgb36:DIN
rgb37:VDD
rgb37:DOUT
rgb37:VSS
rgb37:DIN
rgb38:VDD
rgb38:DOUT
rgb38:VSS
rgb38:DIN
rgb39:VDD
rgb39:DOUT
rgb39:VSS
rgb39:DIN
rgb40:VDD
rgb40:DOUT
rgb40:VSS
rgb40:DIN
rgb41:VDD
rgb41:DOUT
rgb41:VSS
rgb41:DIN
rgb42:VDD
rgb42:DOUT
rgb42:VSS
rgb42:DIN
rgb43:VDD
rgb43:DOUT
rgb43:VSS
rgb43:DIN
rgb44:VDD
rgb44:DOUT
rgb44:VSS
rgb44:DIN
rgb45:VDD
rgb45:DOUT
rgb45:VSS
rgb45:DIN
rgb46:VDD
rgb46:DOUT
rgb46:VSS
rgb46:DIN
rgb47:VDD
rgb47:DOUT
rgb47:VSS
rgb47:DIN
rgb48:VDD
rgb48:DOUT
rgb48:VSS
rgb48:DIN
rgb49:VDD
rgb49:DOUT
rgb49:VSS
rgb49:DIN
rgb50:VDD
rgb50:DOUT
rgb50:VSS
rgb50:DIN
rgb51:VDD
rgb51:DOUT
rgb51:VSS
rgb51:DIN
rgb52:VDD
rgb52:DOUT
rgb52:VSS
rgb52:DIN
rgb53:VDD
rgb53:DOUT
rgb53:VSS
rgb53:DIN
rgb54:VDD
rgb54:DOUT
rgb54:VSS
rgb54:DIN
rgb55:VDD
rgb55:DOUT
rgb55:VSS
rgb55:DIN
rgb56:VDD
rgb56:DOUT
rgb56:VSS
rgb56:DIN
GND5VSDASCLSQWRTCDS1307+
rtc1:GND
rtc1:5V
rtc1:SDA
rtc1:SCL
rtc1:SQW