/*

   第五周项目:多模式流水灯

   学号:220201964
   姓名:魏香凝
   班级:物联网工程 202
   Board         Digital Pins Usable For Interrupts
   Uno           2, 3
   Interrupts are useful for making things happen automatically in microcontroller programs,
   and can help solve timing problems. Good tasks for using an interrupt may include reading a rotary encoder, or monitoring user input.

   The blink time of LED depends on Ratecrl()
   mode selected by buttondetect().
   blink pause controlled by Pauseblink()
   LED blinking group selected by Blink().

  The circuit:
   button attached to analog input A0
   button interrupt attached to pin 2
   74LS138 address pin attached to arduino pin 8,9,10
   74LS138 select pin E1 attached to arduino pin 5
   74LS138 select pin E2 and E3 attached to GND
   8 LEDs anode (long leg) attached to +5V through a 220ohm resistor.
   4 buttons attached to +5V through 4 different resistors.
*/

#define NObuttonpressed 0
#define leftledon 1
#define pauseblink 2
#define blinkratecrl 3
#define rightledon 4

const byte interruptPin = 2;
const int button = A0;
const int lsE1 = 4;
const int lsA0 = 8;
const int lsA1 = 9;
const int lsA2 = 10;
int sensorValue = 0; // variable to store the value coming from pin A0
int buttonstate;
int storebuttonstate = NObuttonpressed;
int blinkrate = 1000;
int addvalue = 100;
int pauseflag = 1;

void setup() {
  Serial.begin(9600);
  //declare the pin 2 as external interrupt pin, and buttondetect() as  Interrupt Service Routine:
  //RISING: defines the interrupt should be triggered when the pin goes from low to high:
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), buttondetect, RISING);
  // declare the ls138 address pins and select pin as OUTPUTs:
  pinMode(lsE1, OUTPUT);
  pinMode(lsA0, OUTPUT);
  pinMode(lsA1, OUTPUT);
  pinMode(lsA2, OUTPUT);
}

void loop() {
  switch (buttonstate) {
    case blinkratecrl:
      Ratecrl();
      break;
    case pauseblink:
      Pauseblink();
      break;
    case leftledon:
    case rightledon:
      Blink();
      break;
    default:
      break;
  }
}
void buttondetect() {
  sensorValue = analogRead(button);
  Serial.println(sensorValue);
  //sensorValue的值根据你的模拟按键所连接的电阻而不同,
  //请通过实验,在if和else if的判断条件中设置合适的值
  if (sensorValue >= 1010 && pauseflag == 1) {
    //left led blink
    buttonstate = leftledon;
    storebuttonstate = buttonstate;
    digitalWrite(lsE1, HIGH);
  }
  else if (sensorValue >= 980 && sensorValue <= 1005) {
    //pause blink
    buttonstate = pauseblink;
  }
  else if (sensorValue >= 560 && sensorValue <= 580 && pauseflag == 1) {
    //blink rate control
    buttonstate = blinkratecrl;
  }
  else if (sensorValue >= 700 && sensorValue <= 720 && pauseflag == 1) {
    //right led blink
    buttonstate = rightledon;
    storebuttonstate = buttonstate;
    digitalWrite(lsE1, HIGH);
  }
  else {
    buttonstate = NObuttonpressed;
  }
  Serial.println(buttonstate);
}
void Blink() {
  switch (buttonstate) {
    //判断按键是1号键,黄色LED开始闪烁
    case leftledon: {
        digitalWrite(lsA0, LOW);
        digitalWrite(lsA1, LOW);
        digitalWrite(lsA2, LOW);
        delay(Ratecrl());
        digitalWrite(lsA0, HIGH);
        digitalWrite(lsA1, LOW);
        digitalWrite(lsA2, LOW);
        delay(Ratecrl());
        digitalWrite(lsA0, LOW);
        digitalWrite(lsA1, HIGH);
        digitalWrite(lsA2, LOW);
        delay(Ratecrl());
        digitalWrite(lsA0, HIGH);
        digitalWrite(lsA1, HIGH);
        digitalWrite(lsA2, LOW);
        delay(Ratecrl());
      }
      break;
    //判断按键是4号键,绿色LED开始闪烁
    //查阅74LS138真值表,对三位地址引脚进行赋值
    case rightledon: {
        //请完成此处代码;
      }
      break;
    default:
      break;
  }
}

void Pauseblink() {
  //第一次按下按键,LED暂停闪烁
  if (pauseflag) {
    pauseflag = 1 - pauseflag;
    digitalWrite(lsE1, LOW);
    buttonstate = NObuttonpressed;
  }
  //第二次按下按键,LED开始闪烁
  else {
    //请完成此处代码;
  }
}
//闪烁频率初始值为1秒,每按一次3号键频率提高0.1秒,返回闪烁频率值;
//至频率提高到0.1秒时,再按一次3号键,频率恢复为初始值;
int Ratecrl() {
  //请完成此处代码;
  return blinkrate;
}