#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include "Font_Data.h"

//#define INVERT_UPPER_ZONE //menetapkan zone upper dibalik (invert) 
#define DEBUG 1   //menetapkan DEBUG=1

//menentukan jumlah perangkat yang kita miliki dalam kaskade
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_ZONES 2 //menetapkan maximum zone=2 (upper & lower)
#define ZONE_SIZE 4 //menetapkan ukuran zone =4 ()
#define MAX_DEVICES (MAX_ZONES * ZONE_SIZE)

#define ZONE_UPPER  1   //set zone atas = 1
#define ZONE_LOWER  0   //set zone bawah = 1
#define PAUSE_TIME 0    //set lamanya Pause
#define SCROLL_SPEED 50 //set kecepatan scrolling

//menentukan pin pada perangkat yg terhubung ke board Arduino
#define CS_PIN    10
//#define DATA_PIN  11 //pin ini bisa bebas jika baris 25 dibuka
//#define CLK_PIN   13 //pin ini bisa bebas jika baris 25 dibuka
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);////pin SPI
//MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);//SOFTWARE SPI

//#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) //menentukan ukuran array
char *msg[] =  {  //pointer array Message
  "Membuat peraga dobel modul menggunakan 2 font custom dengan 2 zone",
  "Zone 0 untuk bagian lower",
  "Zone 1 untuk bagian upper",
  "BIG",
  "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
  "abcdefghijklmnopqrstuvwxyz",
  "0123456789",
  "`!@#$%^&*()_+-={};:'\"<>?,./|\\{}",
};

void setup() {
  P.begin(MAX_ZONES); //inisialisasi LED Dot Matrix

  /* Setup zone menjadi 2 bagian (lower & upper). Setiap zone memiliki 
     font yang berbeda yaitu atas & bawah untuk setiap huruf          */
  P.setZone(ZONE_LOWER, 0, ZONE_SIZE - 1);
  P.setZone(ZONE_UPPER, ZONE_SIZE, MAX_DEVICES-1);
  P.setFont(ZONE_LOWER, BigFontLower); //set zone lower dengan BigFontLower
  P.setFont(ZONE_UPPER, BigFontUpper); //set zone upper dengan BigFontUpper
  P.setCharSpacing(P.getCharSpacing()*2); // double height --> double spacing

  #ifdef INVERT_UPPER_ZONE //jika zone atas dibalik (invert) eksekusi baris dibawah
    P.setZoneEffect(ZONE_UPPER, true, PA_FLIP_UD);
    P.setZoneEffect(ZONE_UPPER, true, PA_FLIP_LR);
  #endif

  #if DEBUG //jika DEBUG=1 maka eksekusi baris dibawah
    Serial.begin(57600);
    Serial.println("[Demo dobel modul : start]");
  #endif
}

void loop() {
  static uint8_t cycle = 0; //penghitung (indeks) utk msg[]

  //Jalankan animasi dan cek jika kedua zone telah komplit. Animasi
  //tidak sama panjang krn effect upper/lower yg ditampilkan berbeda
  P.displayAnimate();
  if (P.getZoneStatus(ZONE_LOWER) && P.getZoneStatus(ZONE_UPPER)) {
    #if DEBUG
      Serial.println(cycle); //kirim nilai cycle ke Serial jika DEBUG=1
    #endif

    switch (cycle) {
      default:
        P.setFont(ZONE_LOWER, BigFontLower);
        P.setFont(ZONE_UPPER, BigFontUpper);
        #ifdef INVERT_UPPER_ZONE
          P.displayZoneText(ZONE_LOWER, msg[cycle], PA_LEFT, SCROLL_SPEED, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
          P.displayZoneText(ZONE_UPPER, msg[cycle], PA_LEFT, SCROLL_SPEED, 0, PA_SCROLL_RIGHT, PA_SCROLL_RIGHT);
        #else
          P.displayZoneText(ZONE_LOWER, msg[cycle], PA_RIGHT, SCROLL_SPEED, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
          P.displayZoneText(ZONE_UPPER, msg[cycle], PA_LEFT, SCROLL_SPEED, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
        #endif
      break;

      case 1:
        P.setFont(ZONE_LOWER, NULL);        //lower dengan ukuran huruf normal
        P.setFont(ZONE_UPPER, BigFontUpper);//upper dg separuh huruf besar
        P.displayZoneText(ZONE_LOWER, msg[1], PA_CENTER, SCROLL_SPEED, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
        P.displayZoneText(ZONE_UPPER, msg[3], PA_CENTER, SCROLL_SPEED, 0, PA_PRINT, PA_NO_EFFECT);
      break;

      case 2:
        P.setFont(ZONE_LOWER, BigFontLower);//zone lower diset dg separuh huruf besar (BigFont)
        P.setFont(ZONE_UPPER, NULL);        //zone upper diset dg huruf normal
        P.displayZoneText(ZONE_LOWER, msg[3], PA_CENTER, SCROLL_SPEED, 0, PA_PRINT, PA_NO_EFFECT);//tanpa efek
        #ifdef INVERT_UPPER_ZONE
          P.displayZoneText(ZONE_UPPER, msg[2], PA_CENTER, SCROLL_SPEED, 0, PA_SCROLL_RIGHT, PA_SCROLL_RIGHT);
        #else
          P.displayZoneText(ZONE_UPPER, msg[2], PA_CENTER, SCROLL_SPEED, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
        #endif
      break;

      case 3:
        P.setFont(ZONE_LOWER, BigFontLower);//zone lower diset dg karakter besar (BigFont)
        P.setFont(ZONE_UPPER, BigFontUpper);//zone upper diset dg karakter besar (BigFont)
        P.displayZoneText(ZONE_LOWER, msg[3], PA_CENTER, SCROLL_SPEED, 2000, PA_PRINT, PA_NO_EFFECT); // PA_SCROLL_LEFT, PA_SCROLL_LEFT);
        P.displayZoneText(ZONE_UPPER, msg[3], PA_CENTER, SCROLL_SPEED, 2000, PA_PRINT, PA_NO_EFFECT); //PA_SCROLL_RIGHT, PA_SCROLL_RIGHT);
      break;
    }
    cycle = (cycle + 1) % ARRAY_SIZE(msg); //siapkan siklus berikutnya
    P.displayClear();   //hapus display
    P.synchZoneStart(); //sinkronkan dari awal kembali
  }
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
matrix1:V+
matrix1:GND
matrix1:DIN
matrix1:CS
matrix1:CLK
matrix1:V+.2
matrix1:GND.2
matrix1:DOUT
matrix1:CS.2
matrix1:CLK.2
gnd1:GND
matrix3:V+
matrix3:GND
matrix3:DIN
matrix3:CS
matrix3:CLK
matrix3:V+.2
matrix3:GND.2
matrix3:DOUT
matrix3:CS.2
matrix3:CLK.2