//1. Sử dụng nút ấn điều khiển 8 led đơn sáng theo yêu cầu: Ấn nút 1 các Led nhấp nháy so le nhau với tần số cho trước. Ấn nút 2, tất cả các Led đều tắt.

/*  Chương trình 1: sử dụng hàm khai báo chuẩn Arduino

  int on = 9; //Khai báo nút nhấn ON ở Pin9
  int off = 8; //Khai báo nút nhấn OFF ở Pin8
  int l1 = 0; //Khai báo LED1 ở Pin0
  int l2 = 1; //Khai báo LED2 ở Pin1
  int l3 = 2; //Khai báo LED3 ở Pin2
  int l4 = 3; //Khai báo LED4 ở Pin3
  int l5 = 4; //Khai báo LED5 ở Pin4
  int l6 = 5; //Khai báo LED6 ở Pin5
  int l7 = 6; //Khai báo LED7 ở Pin6
  int l8 = 7; //Khai báo LED8 ở Pin7
  int mode = 0; //Khai báo biến chế độ Led sáng ở chế độ nào 0 - stop, 1 - start

  void setup() {  //Khai báo trạng thái của các Pin Arduino
    pinMode(on, INPUT_PULLUP);
    pinMode(off, INPUT_PULLUP);
    pinMode(l1, OUTPUT);
    pinMode(l2, OUTPUT);
    pinMode(l3, OUTPUT);
    pinMode(l4, OUTPUT);
    pinMode(l5, OUTPUT);
    pinMode(l6, OUTPUT);
    pinMode(l7, OUTPUT);
    pinMode(l8, OUTPUT);
  }

  void loop() {

    if (mode == 0) {  //Nếu mode đang ở 0
      stop(); //Thì sẽ khởi động chương trình phụ stop()
    }

    while (digitalRead(on) == LOW) {  //Vòng lặp While nếu trạng thái nút ON được nhấn
      mode = 1; //Mode chuyển sang giá trị 1
      start();  //Khởi động chương trình phụ start()
    }
    
    while (digitalRead(off) == LOW) { //Vòng lặp While nếu trạng thái nút OFF được nhấn
      mode = 0; //Mode chuyển sang giá trị 0
      stop(); //Khởi động chương trình phụ stop()
    }

    if (mode == 1) {  //Nếu chương trình vẫn đang tiếp tục chạy, mode vẫn = 1
      start();  //Chương trình 1 khởi động tiếp tạo thành vòng lặp
    }
  }

  void start() {  //Chương trình phụ nháy đèn solo
      digitalWrite(l1, HIGH);
      digitalWrite(l3, HIGH);
      digitalWrite(l5, HIGH);
      digitalWrite(l7, HIGH);
      delay(1000);
      digitalWrite(l1, LOW);
      digitalWrite(l3, LOW);
      digitalWrite(l5, LOW);
      digitalWrite(l7, LOW);

      digitalWrite(l2, HIGH);
      digitalWrite(l4, HIGH);
      digitalWrite(l6, HIGH);
      digitalWrite(l8, HIGH);
      delay(1000);
      digitalWrite(l2, LOW);
      digitalWrite(l4, LOW);
      digitalWrite(l6, LOW);
      digitalWrite(l8, LOW);
  }
    
  void stop() { //Chương trình phụ tắt hết đèn
      digitalWrite(l1, LOW);
      digitalWrite(l3, LOW);
      digitalWrite(l5, LOW);
      digitalWrite(l7, LOW);
      digitalWrite(l2, LOW);
      digitalWrite(l4, LOW);
      digitalWrite(l6, LOW);
      digitalWrite(l8, LOW);
  }

  //Hết chương trình 1
  */

/*  Chương trình 2: sử dụng biến mảng để khai báo, rút ngắn câu lệnh

  int mode = 0; //Khai báo biến Mode gán chế độ hoạt động của chương trình
  int on = 9; //Khai báo nút nhấn ON ở chân Pin9
  int off = 8;  //Khai báo nút nhấn OFF ở chân Pin8
  byte led[] = {0, 1, 2, 3, 4, 5, 6, 7};

  void setup() {
    pinMode(on, INPUT_PULLUP);
    pinMode(off, INPUT_PULLUP);
    for (int i = 0; i < 8; i++) { //Dùng vòng lặp FOR để khai báo Pin Output
      pinMode(led[i], OUTPUT);
    }
  }

  void stop() { //Chương trình phụ tắt hết các đèn
    for (int i = 0; i < 8; i++)
      digitalWrite(led[i], LOW);
  }

  void start() {  //Chương trình phụ bật đèn so le
    for (int i = 0; i < 8; i = i + 2) { //Tạo vòng lặp FOR, xác định led ở vị trí 1, 3, 5, 7
      digitalWrite(led[i], HIGH); //Bật đèn
    }
    delay_setup(); //Giữ trạng thái bật đèn dùng chương trình delay phụ
    for (int i = 0; i < 8; i = i + 2) { //Vòng lặp FOR, xác định lại những LED 1, 3, 5, 7
      digitalWrite(led[i], LOW);  //Tắt những đèn đó
    }

    for (int i = 1; i < 8; i = i + 2) { //Tạo vòng lặp FOR, xác định led ở vị trí 2, 4, 6, 8
      digitalWrite(led[i], HIGH); //Bật đèn
    }
    delay_setup(); //Giữ trạng thái bật đèn dùng chương trình delay phụ
    for (int i = 1; i < 8; i = i + 2) { //Vòng lặp FOR, xác định lại những LED 2, 4, 6, 8
      digitalWrite(led[i], LOW);  //Tắt những đèn đó
    }
  }

  void delay_setup() {  //Chương trình phụ tạo hàm delay với thời gian setup sẵn
    delay(1000);
  }

  void loop() {
    if (mode == 0) {  //Nếu mode đang ở 0
      stop(); //Thì sẽ khởi động chương trình phụ stop()
    }

    while (digitalRead(on) == LOW) {  //Vòng lặp While nếu trạng thái nút ON được nhấn
      mode = 1; //Mode chuyển sang giá trị 1
      start();  //Khởi động chương trình phụ start()
    }
      
    while (digitalRead(off) == LOW) { //Vòng lặp While nếu trạng thái nút OFF được nhấn
      mode = 0; //Mode chuyển sang giá trị 0
      stop(); //Khởi động chương trình phụ stop()
      }

    if (mode == 1) {  //Nếu chương trình vẫn đang tiếp tục chạy, mode vẫn = 1
      start();  //Chương trình 1 khởi động tiếp tạo thành vòng lặp
    }
  }

  //Hết chương trình 2
  */

/*  Chương trình 3: Xử dụng mã Hex để xuất tín hiệu 8 bit

  int mode;

  void setup() {
    DDRD = 0xff; //Khởi tạo PortD với chân Pin 0~7 là cổng Output ra LED
    PORTB = 0x03; //Khởi tạo PortB chân Pin 8, 9 là INPUT_PULLUP
  }

  void delay_setup() {  //Chương trình phụ tạo delay chung
    delay(500);
  }

  void start() { //Chương trình phụ bật đèn ở PortD chân Pin 0, 2, 4, 6
    PORTD = 0x55; //Xuất đồng loạt 8 bit với 4 đèn ở mức HIGH 0x55 = B01010101
    delay_setup();
    PORTD = 0xAA; //Xuất đồng loạt 8 bít với 4 đèn ở mức HIGH 0x55 = B10101010
    delay_setup();
  }

  void stop() { //Chương trình phụ tắt hết đèn
    PORTD = 0x00; //Xuất đồng loạt 8 bít với 8 đèn đều ở mức LOW
  }

  void loop() {
    if (mode == 0) {  //Nếu mode đang ở 0
      stop(); //Thì sẽ khởi động chương trình phụ stop()
    }

    while (digitalRead(9) == LOW) {  //Vòng lặp While nếu trạng thái nút ON ở Pin 9 được nhấn
      mode = 1; //Mode chuyển sang giá trị 1
      start();  //Khởi động chương trình phụ start()
    }
        
    while (digitalRead(8) == LOW) { //Vòng lặp While nếu trạng thái nút OFF ở Pin 8 được nhấn
      mode = 0; //Mode chuyển sang giá trị 0
      stop(); //Khởi động chương trình phụ stop()
    }

    if (mode == 1) {  //Nếu chương trình vẫn đang tiếp tục chạy, mode vẫn = 1
      start();  //Chương trình 1 khởi động tiếp tạo thành vòng lặp
    }
  }

  //Hết chương trình 3
  */

// Chương trình 4: Dùng hàm millis()

  int on = 9;
  int off = 8;
  int l1 = 0;
  int l2 = 1;
  int l3 = 2;
  int l4 = 3;
  int l5 = 4;
  int l6 = 5;
  int l7 = 6;
  int l8 = 7;

  int pinLed1;  //Gán trạng thái cho nhóm Led 1, 3, 5, 7
  int pinLed2;  //Gán trạng thái cho nhóm Led 2, 4, 6, 8

  int time_start = 0; //Gán biến thời gian bắt đầu
  int time_run; //Gán biến thời gian bấm giờ của board Arduino
  int time_delay = 500; //Gán biến thời gian nhấp nháy đèn

  int mode; //Gán biến trạng thái chương trình đang hoạt động

  void setup() {
    pinMode(on, INPUT_PULLUP);
    pinMode(off, INPUT_PULLUP);
    pinMode(l1, OUTPUT);
    pinMode(l2, OUTPUT);
    pinMode(l3, OUTPUT);
    pinMode(l4, OUTPUT);
    pinMode(l5, OUTPUT);
    pinMode(l6, OUTPUT);
    pinMode(l7, OUTPUT);
    pinMode(l8, OUTPUT);
  }

  void loop() {
   
    if (mode == 0)
      stop();

    while (digitalRead(on) == LOW) {
      mode = 1;
      start();
    }
    
    while (digitalRead(off) == LOW) {
      mode = 0; 
      stop();
    }

    if (mode == 1)
      start();
  }

  void start() {  //Chương trình phụ bắt đầu nhấp nháy đèn so le
    time_run = millis();  //Cài đặt biến time_run là thời gian kể từ lúc Arduino bắt đầu chương trình từ 0~ limit (thường limit = 50 days)

    if (time_run - time_start >= time_delay) {  //Nếu time_run - time_start (lúc này = 0) >= time_delay
      time_start = time_run;  //Thì time_start = time_run - Mục đích để giữ cho hiệu time_run - time_start ~ time_delay

      if (pinLed1 == 0) { //Nếu nhóm Led 1 đang ở LOW
        pinLed1 = 1;  //Thì nhóm Led 1 chuyển sang trạng thái HIGH
        pinLed2 = 0;  //Và nhóm Led 2 chuyển sang trạng thái LOW
      }
      else {  //Nếu nhóm Led 1 đang ở trạng thái HIGH
        pinLed1 = 0;  //Thì nhóm Led 1 chuyển sang trạng thái LOW
        pinLed2 = 1;  //Và nhóm Led 2 chuyển sang trạng thái HIGH
      }

      digitalWrite(l1, pinLed1);
      digitalWrite(l3, pinLed1);
      digitalWrite(l5, pinLed1);
      digitalWrite(l7, pinLed1);

      digitalWrite(l2, pinLed2);
      digitalWrite(l4, pinLed2);
      digitalWrite(l6, pinLed2);
      digitalWrite(l8, pinLed2);
    }
  }

  void stop() { //Chương trình phụ dừng toàn bộ đèn Led
    digitalWrite(l1, LOW);
    digitalWrite(l3, LOW);
    digitalWrite(l5, LOW);
    digitalWrite(l7, LOW);

    digitalWrite(l2, LOW);
    digitalWrite(l4, LOW);
    digitalWrite(l6, LOW);
    digitalWrite(l8, LOW);
  }

    //Hết chương trình 4
  //
$abcdeabcde151015202530fghijfghij