...

Assignment

/imagine "scan of a medieval manuscript featuring a circuit with only one button and only two LEDs"

Week 01 assignment requires the circuit with one pushbutton and two leds to function in this cycle: (off, click, one LED, click, two LEDs, click, off…).

Final result demo

From sketch to breadboard

Initial sketch: Initial sketch on paper

Final circuit connected on the breadboard: Final circuit connected on the breadboard

Code

You can add code inside the code fences. The letter c after the three backticks means that the syntax highlighting will use the programming language c as the rules on how different parts of the text should be highlighted.

The main logic:

if (btnState == HIGH) {
  switch(counter){
    case 0:
      digitalWrite(ledA, HIGH);
      counter++;
      Serial.print("One light! counter: "); // debugging purpose
      break;
    case 1:
      digitalWrite(ledB, HIGH);
      counter++;
      Serial.print("Two lights! counter: ");
      break;
    case 2:
      digitalWrite(ledA, LOW);
      digitalWrite(ledB, LOW);
      counter=0;
      Serial.print("Lights off! counter: ");
      break;
  }
  Serial.println(counter); // debugging purpose
}

After uploading the code, I tested the circuit and realised that the button value might be read multiple times for one press. Here is the Serial Monitor output: Serial monitor output when there is no debounce

Hence, I utilised the millis() and a delay time to monitor the timing of reading input and decide if the duration is long enough as one press. Here is the final working code:

// constant
const int btnPin = 2;
const int ledA = 12;
const int ledB = 13;

// variable
int btnState = LOW;
int lastBtnState = LOW; 
int counter = 0;

unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(ledA, OUTPUT);
  pinMode(ledB, OUTPUT);

  pinMode(btnPin, INPUT);

  Serial.begin(9600);
  digitalWrite(ledA, LOW);
  digitalWrite(ledB, LOW);
}

void loop() {
  int reading = digitalRead(btnPin);

  if(reading != lastBtnState){
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != btnState) {
      btnState = reading;

      if (btnState == HIGH) {
        switch(counter){
          case 0:
            digitalWrite(ledA, HIGH);
            counter++;
            Serial.print("One light! counter: ");
            break;
          case 1:
            digitalWrite(ledB, HIGH);
            counter++;
            Serial.print("Two lights! counter: ");
            break;
          case 2:
            digitalWrite(ledA, LOW);
            digitalWrite(ledB, LOW);
            counter=0;
            Serial.print("Lights off! counter: ");
            break;
        }
        Serial.println(counter);
      }
    }
  }
  lastBtnState = reading;
}  

And here is the serial monitor output for the code with debounce: Serial monitor output after debounce implemented