// set pin definition
int DIN_pin = 11;
int LOAD_pin = 10;
int CLOCK_pin = 13;
int NUM_segment = 4;

// MAX7219 register address
byte max7219_REG_noop = 0x00;
byte max7219_REG_digit0 = 0x01;
byte max7219_REG_digit1 = 0x02;
byte max7219_REG_digit2 = 0x03;
byte max7219_REG_digit3 = 0x04;
byte max7219_REG_digit4 = 0x05;
byte max7219_REG_digit5 = 0x06;
byte max7219_REG_digit6 = 0x07;
byte max7219_REG_digit7 = 0x08;
byte max7219_REG_decodeMode = 0x09;
byte max7219_REG_intensity = 0x0a;
byte max7219_REG_scanLimit = 0x0b;
byte max7219_REG_shutdown = 0x0c;
byte max7219_REG_displayTest = 0x0f;

byte matrixData1_8X8[8] = { // simbol panah kiri
B00010000,B00100000,B01000000,B11111111,B11111111,B01000000,B00100000,B00010000};

byte matrixData2_8X8[8] = { 
B00000000,B00000000,B11101110,B10000100,B11100100,B00100100,B11100100,B00000000};

byte matrixData3_8X8[8] = { // Matrix pattern
B00000000,B00000000,B11101111,B10101001,B10101111,B10101000,B11101000,B00000000};

byte matrixData4_8X8[8] = { // Matrix pattern
B00001000,B00000100,B00000010,B11111111,B11111111,B00000010,B00000100,B00001000};

// Control one MAX7219 module
void MAX7219_1Unit(byte reg_addr, byte reg_data) {
 // First, send the register address
 shiftOut(DIN_pin,CLOCK_pin,MSBFIRST,reg_addr);
 shiftOut(DIN_pin,CLOCK_pin,MSBFIRST,reg_data);
 // Next, send the data
 // After transmission, set the DIN pin to LOW
digitalWrite(DIN_pin,LOW);
}

void MAX_update() {
  digitalWrite(LOAD_pin,HIGH);
  digitalWrite(LOAD_pin,LOW);
}

void Draw () // Display data to LED matrix
{
 MAX7219_1Unit(max7219_REG_digit0, matrixData1_8X8[0]); MAX7219_1Unit(max7219_REG_digit0, matrixData2_8X8[0]);MAX7219_1Unit(max7219_REG_digit0, matrixData3_8X8[0]);MAX7219_1Unit(max7219_REG_digit0, matrixData4_8X8[0]),MAX_update();
 MAX7219_1Unit(max7219_REG_digit1, matrixData1_8X8[1]); MAX7219_1Unit(max7219_REG_digit1, matrixData2_8X8[1]);MAX7219_1Unit(max7219_REG_digit1, matrixData3_8X8[1]);MAX7219_1Unit(max7219_REG_digit1, matrixData4_8X8[1]),MAX_update();
 MAX7219_1Unit(max7219_REG_digit2, matrixData1_8X8[2]); MAX7219_1Unit(max7219_REG_digit2, matrixData2_8X8[2]);MAX7219_1Unit(max7219_REG_digit2, matrixData3_8X8[2]);MAX7219_1Unit(max7219_REG_digit2, matrixData4_8X8[2]),MAX_update();
 MAX7219_1Unit(max7219_REG_digit3, matrixData1_8X8[3]); MAX7219_1Unit(max7219_REG_digit3, matrixData2_8X8[3]);MAX7219_1Unit(max7219_REG_digit3, matrixData3_8X8[3]);MAX7219_1Unit(max7219_REG_digit3, matrixData4_8X8[3]),MAX_update();
 MAX7219_1Unit(max7219_REG_digit4, matrixData1_8X8[4]); MAX7219_1Unit(max7219_REG_digit4, matrixData2_8X8[4]);MAX7219_1Unit(max7219_REG_digit4, matrixData3_8X8[4]);MAX7219_1Unit(max7219_REG_digit4, matrixData4_8X8[4]),MAX_update();
 MAX7219_1Unit(max7219_REG_digit5, matrixData1_8X8[5]); MAX7219_1Unit(max7219_REG_digit5, matrixData2_8X8[5]);MAX7219_1Unit(max7219_REG_digit5, matrixData3_8X8[5]);MAX7219_1Unit(max7219_REG_digit5, matrixData4_8X8[5]),MAX_update();
 MAX7219_1Unit(max7219_REG_digit6, matrixData1_8X8[6]); MAX7219_1Unit(max7219_REG_digit6, matrixData2_8X8[6]);MAX7219_1Unit(max7219_REG_digit6, matrixData3_8X8[6]);MAX7219_1Unit(max7219_REG_digit6, matrixData4_8X8[6]),MAX_update();
 MAX7219_1Unit(max7219_REG_digit7, matrixData1_8X8[7]); MAX7219_1Unit(max7219_REG_digit7, matrixData2_8X8[7]);MAX7219_1Unit(max7219_REG_digit7, matrixData3_8X8[7]);MAX7219_1Unit(max7219_REG_digit7, matrixData4_8X8[7]),MAX_update();
}

void setup ( ) {
 pinMode(DIN_pin, OUTPUT);
 pinMode(CLOCK_pin, OUTPUT);
 pinMode(LOAD_pin, OUTPUT);

 digitalWrite(CLOCK_pin, HIGH);

 // Initialize MAX7219 registers
 MAX7219_1Unit(max7219_REG_scanLimit, 0x07); // Display digits 0 1 2 3 4 5 6 7
 MAX7219_1Unit(max7219_REG_scanLimit, 0x07);
 MAX7219_1Unit(max7219_REG_scanLimit, 0x07);
 MAX7219_1Unit(max7219_REG_scanLimit, 0x07);
 MAX_update();

 MAX7219_1Unit(max7219_REG_decodeMode, 0x00);  // Disable decoding
 MAX7219_1Unit(max7219_REG_decodeMode, 0x00);
 MAX7219_1Unit(max7219_REG_decodeMode, 0x00);
 MAX7219_1Unit(max7219_REG_decodeMode, 0x00);
 MAX_update();
 
 // Not shutdown mode
 MAX7219_1Unit(max7219_REG_shutdown, 0x01);   //normal operation
 MAX7219_1Unit(max7219_REG_shutdown, 0x01);
 MAX7219_1Unit(max7219_REG_shutdown, 0x01);
 MAX7219_1Unit(max7219_REG_shutdown, 0x01);
 MAX_update();
 
 // Not test mode
 MAX7219_1Unit(max7219_REG_displayTest, 0x00); //normal operation 
 MAX7219_1Unit(max7219_REG_displayTest, 0x00);
 MAX7219_1Unit(max7219_REG_displayTest, 0x00);
 MAX7219_1Unit(max7219_REG_displayTest, 0x00);
 MAX_update();

 for(int i=1; i<=8; i++) {// Set all LED intensity to low
 MAX7219_1Unit(i,0);
 MAX7219_1Unit(i,0);
 MAX7219_1Unit(i,0);
 MAX7219_1Unit(i,0);
 MAX_update();
 }

 // Set LED intensity range: 0x00 ~ 0x0f
 MAX7219_1Unit(max7219_REG_intensity, 0x0a);
 MAX7219_1Unit(max7219_REG_intensity, 0x0a);
 MAX7219_1Unit(max7219_REG_intensity, 0x0a);
 MAX7219_1Unit(max7219_REG_intensity, 0x0a);
 MAX_update();

 delay(1000);
}

void loop () {
 Draw();
}