//檔名:06-3-LeD4x16x16Matrix16ChineseCharGetNTP_DateTime_SSIVS_EE
//We always have to include the library
//#include <WiFi.h>  //引用Wi-Fi函式庫
//#include <time.h>  //引用時間格式及操作函式庫
#include "LedControl.h"

byte buffer[8];  // 宣告暫存點陣資料的變數
byte buffer1[8];  // 宣告暫存點陣資料的變數
byte buffer2[8];  // 宣告暫存點陣資料的變數

/*const char *ssid = "Kun-iPhone13";        //無線網路基地台的SSID
const char *password = "0912630032";    //無線網路基地台的密碼*/

//const char *ssid = "EE620";        //無線網路基地台的SSID
//const char *password = "ee620ee620";    //無線網路基地台的密碼

//const char *ssid = "SSIVS-Microcomputer";        //無線網路基地台的SSID
//const char *password = "047697021";    //無線網路基地台的密碼

/*const char *ntpServer = "pool.ntp.org"; //ntp伺服器網址
const long  gmtOffset_sec = 28800;      //台灣位於GMT+8,為28800秒
const int   daylightOffset_sec = 0;     //台灣不使用日光節約時間,設為0*/

char timeStringBuff1[100]; //100 chars should be enough 
char msg[100] ;
char msg1[100] ;
char timeStringBuff2[100]; //100 chars should be enough 
char msg2[100] ;
/*struct tm timeinfo;                    //建立一個時間結構,名字為timeinfo*/

const byte MaxDevice1 = 8;   // 代表串連8個MAX7219模組
const byte DATA1 = 7;  // 資料輸入線
const byte CLK1 = 5;  // 時脈線
const byte CS1= 6;  // 晶片選擇線
LedControl lc1=LedControl(DATA1,CLK1,CS1,MaxDevice1);
int  DispIndexNo1 = 0;

const byte MaxDevice2 = 8;   // 代表串連8個MAX7219模組
const byte DATA2 =10;  // 資料輸入線
const byte CLK2 = 8;  // 時脈線
const byte CS2= 9;  // 晶片選擇線
LedControl lc2=LedControl(DATA2,CLK2,CS2,MaxDevice2);
int  DispIndexNo2 = 0;

const byte MaxGroupNo = 4;   // 代表要顯示的中文字組有4組,每組4個中文16x16字型
/* we always wait a bit between updates of the display */
unsigned long delaytime=2000;  //2000ms=2s

unsigned char d[]={
0X02,0X02,0X01,0X3A,0X7F,0XEA,0X2A,0XBF,0X2A,0XC0,0X3F,0XBF,0X2A,0XAA,0X2A,0XBA,  // 歡 上下相反
0X40,0X02,0X30,0X10,0X0C,0X0E,0X03,0XE9,0X0C,0X08,0X30,0X28,0X40,0X18,0X00,0X00,

0X41,0X10,0X25,0X92,0X19,0X54,0X1F,0X30,0X20,0X00,0X40,0X00,0X47,0XFE,0X42,0X02,  // 迎  上下相反
0X41,0X01,0X40,0X00,0X5F,0XFE,0X42,0X02,0X44,0X02,0X43,0XFE,0X20,0X00,0X00,0X00,

0X40,0X80,0X40,0X84,0X20,0X88,0X10,0X90,0X0F,0XA0,0X00,0X80,0X00,0X80,0X00,0XFF,  // 光 上下相反
0X3F,0X80,0X40,0XA0,0X40,0X90,0X40,0X88,0X40,0X84,0X40,0X80,0X20,0X80,0X10,0X00,

0X3F,0XFE,0X11,0X22,0X1F,0X3E,0X11,0X22,0X11,0XE2,0X00,0X00,0X7E,0X10,0X42,0X0C,  // 臨 上下相反
0X42,0XF6,0X7E,0X95,0X00,0X9C,0X7E,0X94,0X42,0XF4,0X42,0X04,0X7E,0X04,0X00,0X00,


0X00,0X00,0X40,0X80,0X40,0X4A,0X21,0X4A,0X19,0X2A,0X07,0X2A,0X01,0X19,0X01,0X7F,  // 秀  上下相反
0X05,0X19,0X27,0X19,0X45,0X29,0X44,0X29,0X44,0X49,0X3C,0X88,0X00,0X80,0X00,0X00,    

0X10,0X20,0X08,0X20,0X04,0X20,0X02,0X20,0X21,0X20,0X40,0XE0,0X40,0X00,0X7F,0XFF,  // 水  上下相反
0X00,0X00,0X01,0XC0,0X02,0X20,0X04,0X20,0X08,0X20,0X10,0X20,0X10,0X00,0X00,0X00,

0X00,0X00,0X7F,0X04,0X01,0X04,0X01,0X74,0X1D,0X54,0X15,0X54,0X15,0X55,0X15,0X56,  // 高  上下相反
0X15,0X54,0X1D,0X54,0X01,0X74,0X21,0X04,0X41,0X04,0X7F,0X04,0X00,0X04,0X00,0X00,

0X20,0X00,0X20,0X04,0X20,0X04,0X20,0X04,0X20,0X04,0X20,0X04,0X20,0X04,0X3F,0XFC,  // 工  上下相反 
0X20,0X04,0X20,0X04,0X20,0X04,0X20,0X04,0X20,0X04,0X20,0X04,0X20,0X00,0X00,0X00,

0X00,0X10,0X00,0X0C,0X00,0X54,0X1F,0X55,0X15,0X55,0X15,0X25,0X15,0X05,0X7F,0X7F,  // 電  上下相反
0X55,0X05,0X55,0X25,0X55,0X55,0X5F,0X55,0X40,0X54,0X40,0X04,0X40,0X1C,0X30,0X00,

0X03,0X88,0X00,0X68,0X7F,0XFF,0X00,0X88,0X03,0X08,0X10,0XA4,0X48,0XB6,0X47,0XAD,  // 機  上下相反
0X44,0XB2,0X28,0XFF,0X17,0X80,0X18,0XA4,0X24,0XB6,0X40,0XED,0X40,0XB0,0X30,0X20,

0X04,0X10,0X03,0X14,0X00,0XD2,0X7F,0XFF,0X00,0X91,0X01,0X10,0X04,0X10,0X04,0X00,  // 科  上下相反
0X04,0X44,0X04,0X88,0X05,0X10,0X7F,0XFF,0X04,0X00,0X04,0X00,0X04,0X00,0X00,0X00,

0X01,0XF8,0X02,0X04,0X04,0X02,0X08,0X01,0X10,0X01,0X20,0X01,0X40,0X01,0X00,0X06,  // 愛心 上下相反
0X80,0X18,0X00,0X04,0X40,0X02,0X20,0X01,0X10,0X01,0X08,0X02,0X04,0X04,0X03,0XF8,

0X00,0X00,0X40,0X80,0X40,0X4A,0X21,0X4A,0X19,0X2A,0X07,0X2A,0X01,0X19,0X01,0X7F,  // 秀  上下相反
0X05,0X19,0X27,0X19,0X45,0X29,0X44,0X29,0X44,0X49,0X3C,0X88,0X00,0X80,0X00,0X00,    

0X20,0X00,0X20,0X04,0X20,0X04,0X20,0X04,0X20,0X04,0X20,0X04,0X20,0X04,0X3F,0XFC,  // 工  上下相反 
0X20,0X04,0X20,0X04,0X20,0X04,0X20,0X04,0X20,0X04,0X20,0X04,0X20,0X00,0X00,0X00,

0X00,0X10,0X00,0X0C,0X00,0X54,0X1F,0X55,0X15,0X55,0X15,0X25,0X15,0X05,0X7F,0X7F,  // 電  上下相反
0X55,0X05,0X55,0X25,0X55,0X55,0X5F,0X55,0X40,0X54,0X40,0X04,0X40,0X1C,0X30,0X00,

0X03,0X88,0X00,0X68,0X7F,0XFF,0X00,0X88,0X03,0X08,0X10,0XA4,0X48,0XB6,0X47,0XAD,  // 機  上下相反
0X44,0XB2,0X28,0XFF,0X17,0X80,0X18,0XA4,0X24,0XB6,0X40,0XED,0X40,0XB0,0X30,0X20,

0X00,0X01,0XF8,0X01,0XA8,0X01,0XA9,0XFF,0XA8,0X01,0X00,0X7D,0X07,0X55,0X15,0X54,  // Teacher 上下相反
0XE5,0X00,0X10,0X00,0X17,0X7C,0X12,0X12,0X06,0X7C,0X00,0X00,0X00,0X00,0X00,0X00
}; 

// 在程式記憶體區(快閃記憶體)儲存點矩陣字元資料
PROGMEM const unsigned char CH[] = {
1, 8, B0000000, B0000000, B0000000, B0000000, B0000000, // space
1, 8, B1011111, B0000000, B0000000, B0000000, B0000000, // !
3, 8, B0000011, B0000000, B0000011, B0000000, B0000000, // "
5, 8, B0010100, B0111110, B0010100, B0111110, B0010100, // #
4, 8, B0100100, B1101010, B0101011, B0010010, B0000000, // $
5, 8, B1100011, B0010011, B0001000, B1100100, B1100011, // %
5, 8, B0110110, B1001001, B1010110, B0100000, B1010000, // &
1, 8, B0000011, B0000000, B0000000, B0000000, B0000000, // '
3, 8, B0011100, B0100010, B1000001, B0000000, B0000000, // (
3, 8, B1000001, B0100010, B0011100, B0000000, B0000000, // )
5, 8, B0101000, B0011000, B0001110, B0011000, B0101000, // *
5, 8, B0001000, B0001000, B0111110, B0001000, B0001000, // +
2, 8, B10110000, B1110000, B0000000, B0000000, B0000000, // ,
2, 8, B0001000, B0001000, B0001000, B0001000, B0000000, // -
1, 8, B1000000, B0000000, B0000000, B0000000, B0000000, // .
4, 8, B1000000, B0111000, B0000111, B0000000, B0000000, // /
4, 8, B0111110, B1000001, B0111110, B0000000, B0000000, // 0
3, 8, B1000010, B1111111, B1000000, B0000000, B0000000, // 1
3, 8, B1100010, B1010001, B1001110, B0000000, B0000000, // 2
5, 8, B0100010, B1000001, B1001001, B0110110, B0000000, // 3
4, 8, B0011000, B0010100, B1111111, B0010000, B0000000, // 4
4, 8, B0100111, B1000101, B1000101, B0111000, B0000000, // 5
4, 8, B0111110, B1001001, B1001001, B0110000, B0000000, // 6
4, 8, B0000001, B1110001, B0001001, B0000111, B0000000, // 7
4, 8, B0110110, B1001001, B1001001, B0110110, B0000000, // 8
4, 8, B0100110, B1001001, B1001001, B0111110, B0000000, // 9
3, 8, B0000000, B0100100, B0000000, B0000000, B0000000, // :
2, 8, B10000000, B01010000, B0000000, B0000000, B0000000, // ;
3, 8, B0010000, B0101000, B1000100, B0000000, B0000000, // < 
3, 8, B0101000, B0101000, B0101000, B0000000, B0000000, // =
3, 8, B1000100, B0101000, B0010000, B0000000, B0000000, // >
4, 8, B0000010, B1011001, B0001001, B0000110, B0000000, // ?
5, 8, B0111110, B1001001, B1010101, B1011101, B0001110, // @
4, 8, B1111110, B0010001, B0010001, B1111110, B0000000, // A
4, 8, B1111111, B1001001, B1001001, B0110110, B0000000, // B
4, 8, B0111110, B1000001, B1000001, B0100010, B0000000, // C
4, 8, B1111111, B1000001, B1000001, B0111110, B0000000, // D
4, 8, B1111111, B1001001, B1001001, B1000001, B0000000, // E
4, 8, B1111111, B0001001, B0001001, B0000001, B0000000, // F
4, 8, B0111110, B1000001, B1001001, B1111010, B0000000, // G
4, 8, B1111111, B0001000, B0001000, B1111111, B0000000, // H
3, 8, B1000001, B1111111, B1000001, B0000000, B0000000, // I
4, 8, B0110000, B1000000, B1000001, B0111111, B0000000, // J
4, 8, B1111111, B0001000, B0010100, B1100011, B0000000, // K
3, 8, B1111111, B1000000, B1000000, B1000000, B0000000, // L
5, 8, B1111111, B0000010, B0001100, B0000010, B1111111, // M
5, 8, B1111111, B0000100, B0001000, B0010000, B1111111, // N
4, 8, B0111110, B1000001, B1000001, B0111110, B0000000, // O
4, 8, B1111111, B0001001, B0001001, B0000110, B0000000, // P
4, 8, B0111110, B1000001, B1000001, B10111110, B0000000, // Q
4, 8, B1111111, B0001001, B0001001, B1110110, B0000000, // R
4, 8, B1000110, B1001001, B1001001, B0110010, B0000000, // S
5, 8, B0000001, B0000001, B1111111, B0000001, B0000001, // T
4, 8, B0111111, B1000000, B1000000, B0111111, B0000000, // U
5, 8, B0001111, B0110000, B1000000, B0110000, B0001111, // V
5, 8, B0111111, B1000000, B0111000, B1000000, B0111111, // W
5, 8, B1100011, B0010100, B0001000, B0010100, B1100011, // X
4, 8, B0000111, B0001000, B1110000, B0001111, B0000000, // Y
4, 8, B1100001, B1010001, B1001001, B1000111, B0000000, // Z
2, 8, B1111111, B1000001, B0000000, B0000000, B0000000, // [
4, 8, B0000001, B0000110, B0011000, B1100000, B0000000, // backslash
2, 8, B1000001, B1111111, B0000000, B0000000, B0000000, // ]
3, 8, B0000010, B0000001, B0000010, B0000000, B0000000, // hat
4, 8, B1000000, B1000000, B1000000, B1000000, B0000000, // _
2, 8, B0000001, B0000010, B0000000, B0000000, B0000000, // `
4, 8, B0100000, B1010100, B1010100, B1111000, B0000000, // a
4, 8, B1111111, B1000100, B1000100, B0111000, B0000000, // b
4, 8, B0111000, B1000100, B1000100, B0101000, B0000000, // c
4, 8, B0111000, B1000100, B1000100, B1111111, B0000000, // d
4, 8, B0111000, B1010100, B1010100, B0011000, B0000000, // e
3, 8, B0000100, B1111110, B0000101, B0000000, B0000000, // f
4, 8, B10011000, B10100100, B10100100, B01111000, B0000000, // g
4, 8, B1111111, B0000100, B0000100, B1111000, B0000000, // h
3, 8, B1000100, B1111101, B1000000, B0000000, B0000000, // i
4, 8, B1000000, B10000000, B10000100, B1111101, B0000000, // j
4, 8, B1111111, B0010000, B0101000, B1000100, B0000000, // k
3, 8, B1000001, B1111111, B1000000, B0000000, B0000000, // l
5, 8, B1111100, B0000100, B1111100, B0000100, B1111000, // m
4, 8, B1111100, B0000100, B0000100, B1111000, B0000000, // n
4, 8, B0111000, B1000100, B1000100, B0111000, B0000000, // o
4, 8, B11111100, B0100100, B0100100, B0011000, B0000000, // p
4, 8, B0011000, B0100100, B0100100, B11111100, B0000000, // q
4, 8, B1111100, B0001000, B0000100, B0000100, B0000000, // r
4, 8, B1001000, B1010100, B1010100, B0100100, B0000000, // s
3, 8, B0000100, B0111111, B1000100, B0000000, B0000000, // t
4, 8, B0111100, B1000000, B1000000, B1111100, B0000000, // u
5, 8, B0011100, B0100000, B1000000, B0100000, B0011100, // v
5, 8, B0111100, B1000000, B0111100, B1000000, B0111100, // w
5, 8, B1000100, B0101000, B0010000, B0101000, B1000100, // x
4, 8, B10011100, B10100000, B10100000, B1111100, B0000000, // y
3, 8, B1100100, B1010100, B1001100, B0000000, B0000000, // z
3, 8, B0001000, B0110110, B1000001, B0000000, B0000000, // {
1, 8, B1111111, B0000000, B0000000, B0000000, B0000000, // |
3, 8, B1000001, B0110110, B0001000, B0000000, B0000000, // }
4, 8, B0001000, B0000100, B0001000, B0000100, B0000000, // ~
};


void setup() {
  int i;
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
   for(i=0;i<MaxDevice1;i++)
   {
    /*The MAX72XX is in power-saving mode on startup,
      we have to do a wakeup call  */
     lc1.shutdown(i,false);
     /* Set the brightness to a medium values */
     //lc1.setIntensity(i,8); 原來亮度
     lc1.setIntensity(i,8);
     /* and clear the display */
     lc1.clearDisplay(i);
   }

   for(int i=0;i<MaxDevice2;i++)
   {
    /*The MAX72XX is in power-saving mode on startup,
      we have to do a wakeup call  */
     lc2.shutdown(i,false);
     /* Set the brightness to a medium values */
     lc2.setIntensity(i,8);
     /* and clear the display */
     lc2.clearDisplay(i);
   }

   
  Serial.begin(9600);
  /*Serial.printf("連線到 %s ", ssid);*/
  /*WiFi.begin(ssid, password);              //連到基地台*/
  
  /*strcpy(msg1,"Connecting . . .");   // 要顯示的字串內容
  DispIndexNo1 = 0;
  printStringWithShift1(msg1);
  ClearRemainDisp1();*/

  /*strcpy(msg2,ssid);   // 要顯示連接的Wifi的名稱
  DispIndexNo2 = 0;
  printStringWithShift2(msg2);
  ClearRemainDisp2();
  delay(delaytime); //每顯示一個字休息1000ms=1秒 */
  
  //while (WiFi.status() != WL_CONNECTED){   //當狀態不是已連線
  //  delay(500);                            //等待0.5秒
  //  Serial.print(".");                     //印出一個點提示讓你知道
  //}                                        //回到迴圈判斷處,再判斷一次
  //Serial.println("已連線");
  /*configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);  //設定NTP參數*/
  //m.init();         // 初始化MaxMatrix物件
  //m.setIntensity(8);  // 設定亮度

}

/*
 This method will display the characters for the
 word "Arduino" one after the other on the matrix. 
 (you need at least 5x7 leds to see the whole chars)
 */
void writeArduinoOnMatrix() {
  /* here is the data for the characters */
  int GroupIndexNo,i,j,k;

  for (GroupIndexNo=0;GroupIndexNo<MaxGroupNo;GroupIndexNo++)
  {

     DispIndexNo1=0; 
     /* now display them one by one with a small delay */
     for(j=0;j<MaxDevice1*8;j++) //有N行要顯示
     {
       lc2.setColumn(DispIndexNo1/8,7-(DispIndexNo1%8),d[(128*GroupIndexNo)+(j*2)]);
       lc1.setColumn(DispIndexNo1/8,7-(DispIndexNo1%8),d[(128*GroupIndexNo)+(j*2+1)]);     
       DispIndexNo1++;
     }  
     delay(delaytime); //每顯示一個字休息   
  }
  //delay(delaytime); //最後一個字再多休息

}


void loop() { 
  writeArduinoOnMatrix();
  for(int i=0;i<8;i++)
  {  // 顯示網路時間 N 次
     /*GetNtpDateTime();*/
  }

}

/*void GetNtpDateTime()
{

 if (!getLocalTime(&timeinfo)) {        //取回NTP時間,請注意前面有個驚嘆號。整行意思是:執行取回時間,再檢查是否取回失敗
    strcpy(msg1,"N e t w o r k E r r o r");   // 要顯示的字串內容
    Serial.println("網路時間取回失敗");      //如果失敗,回傳訊息
    //configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);  //設定NTP參數
  }else{ 
    //成功取回時間
    strftime(timeStringBuff1, sizeof(timeStringBuff1), "D a t e = %F ", &timeinfo);
    strcpy(msg1, timeStringBuff1);

    strftime(timeStringBuff2, sizeof(timeStringBuff2), "T i m e = %T ", &timeinfo);
    strcpy(msg2, timeStringBuff2);
  
    Serial.println(&timeinfo, "現在日期:%F 現在時間:%T ");  //列印取回的時間
  }
  // 執行底下的自訂函數,傳入顯示字串
  DispIndexNo1 = 0;
  printStringWithShift1(msg1);
  ClearRemainDisp1();
  //delay(delaytime); //每顯示一個字休息500ms=0.5秒 
  
  DispIndexNo2 = 0;
  printStringWithShift2(msg2);
  ClearRemainDisp2();
  delay(500); //每顯示一個字休息500ms=0.5秒 
          
  
}*/

void printStringWithShift1(char* s)
{
  while (*s != 0 && (DispIndexNo1 < (MaxDevice1*8)) )
  {
    printCharWithShift1(*s);
    s++;
  }
}

void printStringWithShift2(char* s)
{
  while (*s != 0 && (DispIndexNo2 < (MaxDevice2*8)) )
  {
    printCharWithShift2(*s);
    s++;
  }
}


void printCharWithShift1(char c)
{
  int i,j,k;
  
  if (c < 32) return;
  c -= 32;
  if (DispIndexNo1 >= (MaxDevice1*8) ) return;
  memcpy_P(buffer1, CH + 7 * c, 7);

  for(j=0;j<buffer1[0];j++) //有N行要顯示
  {
     lc1.setColumn(DispIndexNo1/8,7-(DispIndexNo1%8),buffer1[2+j]);
     DispIndexNo1++;
     if (DispIndexNo1 >= (MaxDevice1*8) ) return;    
  }
  
}

void printCharWithShift2(char c)
{
  int i,j,k;
  
  if (c < 32) return;
  c -= 32;
  if (DispIndexNo2 >= (MaxDevice2*8) ) return;
  memcpy_P(buffer2, CH + 7 * c, 7);

  for(j=0;j<buffer2[0];j++) //有N行要顯示
  {
     lc2.setColumn(DispIndexNo2/8,7-(DispIndexNo2%8),buffer2[2+j]);
     DispIndexNo2++;
     if (DispIndexNo2 >= (MaxDevice2*8) ) return;    
  }
  
}


void ClearRemainDisp1(void)
{
  int j;

  if (DispIndexNo1 >= (MaxDevice1*8) ) return;
  for(j=0;j<=(MaxDevice1*8);j++) //有N行要清除顯示
  {
     lc1.setColumn(DispIndexNo1/8,7-(DispIndexNo1%8),0);
     DispIndexNo1++;
     if (DispIndexNo1 >= (MaxDevice1*8) ) return;    
  }

}

void ClearRemainDisp2(void)
{
  int j;

  if (DispIndexNo2 >= (MaxDevice2*8) ) return;
  for(j=0;j<=(MaxDevice2*8);j++) //有N行要清除顯示
  {
     lc2.setColumn(DispIndexNo2/8,7-(DispIndexNo2%8),0);
     DispIndexNo2++;
     if (DispIndexNo2 >= (MaxDevice2*8) ) return;    
  }

}