๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป Microprocessor/์บก์Šคํ†ค ์ฑŒ๋ฆฐ์ง€

[5์ฃผ์ฐจ] (Timer Counter Interrupt) Capston Challenge

by GroovyArea 2022. 10. 9.

๋ฌธ์ œ 2-1

  • LED, Buzzer ์‚ฌ์šฉ 
  • 2์ดˆ ๊ฐ„๊ฒฉ์œผ๋กœ ๊ต๋Œ€๋กœ ์ ๋ฉธ
  • ์Šค์œ„์น˜๊ฐ€ ๋ˆŒ๋ฆด ๊ฒฝ์šฐ Buzzer ๋™์ž‘
  • delay() ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ฝ”๋“œ ์ž‘์„ฑ

 

๋ฌธ์ œ ์ดํ•ด

  • ๋ฌธ์ œ ๊ทธ๋Œ€๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑ

 

์ฝ”๋“œ

int switch_state;
int int_sw = 2;
int LED1 = 22;
int LED2 = 24;
int BUZZER = 8;
int LED1_state = HIGH;
int LED2_state = LOW;

void setup() {
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(BUZZER, OUTPUT);
}

void loop() {
  flush();

  switch_state = digitalRead(2);
  if (switch_state == HIGH) {
    digitalWrite(BUZZER, HIGH);
  } else {
    digitalWrite(BUZZER, LOW);
  }
}

void flush() {
  if (LED1_state == HIGH) {
    digitalWrite(LED1, LED1_state);
    delay(2000);
  } else if (LED1_state == LOW) {
    digitalWrite(LED1, LED1_state);
    delay(2000);
  }

  if (LED2_state == HIGH) {
    digitalWrite(LED2, LED2_state);
    delay(2000);
  } else if (LED2_state == LOW) {
    digitalWrite(LED2, LED2_state);
    delay(2000);
  }

  LED1_state = !LED1_state;
  LED2_state = !LED2_state;
}

 

 

๋ฌธ์ œ 2-2, 2-3

  • 2-2
    • MsTimer2 ์ธํ„ฐ๋ŸฝํŠธ ์ด์šฉ
  • 2-3
    • TimerOne ์ธํ„ฐ๋ŸฝํŠธ ์ด์šฉ

 

๋ฌธ์ œ ์ดํ•ด

  • ๊ฐ ํƒ€์ด๋จธ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์ด์šฉํ•˜์ž

 

์ฝ”๋“œ

#include <TimerOne.h>
#include <MsTimer2.h>

int switch_state;
int int_sw = 2;
int LED1 = 22;
int LED2 = 24;
int BUZZER = 8;
int LED1_state = HIGH;
int LED2_state = LOW;

void setup() {
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  MsTimer2::set(2000, flush);
  MsTimer2::start();
}

void loop() {
  switch_state = digitalRead(2);
  if (switch_state == HIGH) {
    digitalWrite(BUZZER, HIGH);
  } else {
    digitalWrite(BUZZER, LOW);
  }
}

void flush() {
  if (LED1_state == HIGH) {
    digitalWrite(LED1, LED1_state);
  } else if (LED1_state == LOW) {
    digitalWrite(LED1, LED1_state);
  }

  if (LED2_state == HIGH) {
    digitalWrite(LED2, LED2_state);
  } else if (LED2_state == LOW) {
    digitalWrite(LED2, LED2_state);
  }

  LED1_state = !LED1_state;
  LED2_state = !LED2_state;
}

 

#include <TimerOne.h>

#include <MsTimer2.h>

#include <LiquidCrystal.h>

// LiquidCrystal lcd(42, 43, 44, 45, 46, 47);

int switch_state;
int int_sw = 2;
int LED1 = 22;
int LED2 = 24;
int BUZZER = 8;
int LED1_state = HIGH;
int LED2_state = LOW;

void setup() {
  // put your setup code here, to run once:

  // lcd.begin(16, 2);
  // lcd.print("hello!");
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  Timer1.initialize(2000000); // 2์ดˆ
  Timer1.attachInterrupt(flush);
}

void loop() {
  // put your main code here, to run repeatedly:
  // lcd.setCursor(0, 1);
  // lcd.print(millis() / 1000);
  switch_state = digitalRead(2);
  if (switch_state == HIGH) {
    digitalWrite(BUZZER, HIGH);
  } else {
    digitalWrite(BUZZER, LOW);
  }
}

void flush() {
  if (LED1_state == HIGH) {
    digitalWrite(LED1, LED1_state);
  } else if (LED1_state == LOW) {
    digitalWrite(LED1, LED1_state);
  }

  if (LED2_state == HIGH) {
    digitalWrite(LED2, LED2_state);
  } else if (LED2_state == LOW) {
    digitalWrite(LED2, LED2_state);
  }

  LED1_state = !LED1_state;
  LED2_state = !LED2_state;
}

 

 

๋ฌธ์ œ 3

  • ๋””๋ฐ”์šด์Šค ํšŒ๋กœ ์„ค๊ณ„
  • Falling 1๋ฒˆ  :
    • ์ดˆ์ŒํŒŒ ์„ผ์„œ LCD์— ๊ฑฐ๋ฆฌ ๋””์Šคํ”Œ๋ ˆ์ด
    • ํƒ€์ด๋จธ ์ธํ„ฐ๋ŸฝํŠธ ์‚ฌ์šฉ 2ํ–‰์— ๋””์Šคํ”Œ๋ ˆ์ด, 1์ดˆ๋งˆ๋‹ค LED ์ ๋ฉธ
  • Falling 3๋ฒˆ :
    • ์‹ค์‹œ๊ฐ„ LCD์— ๊ฑฐ๋ฆฌ ๋””์Šคํ”Œ๋ ˆ์ด
    • 20์„ผํ‹ฐ๋ฏธํ„ฐ ๋ฏธ๋งŒ LED ๊ณ„์† HIGH
    • 20์„ผํ‹ฐ๋ฏธํ„ฐ ์ดˆ๊ณผ ํƒ€์ด๋จธ ์ธํ„ฐ๋ŸฝํŠธ ์‚ฌ์šฉ 1์ดˆ๋งˆ๋‹ค ์ ๋ฉธ
  • Rising 5๋ฒˆ : 
    • ์ดˆ์ŒํŒŒ ์„ผ์„œ LCD์— ๊ฑฐ๋ฆฌ ๋””์Šคํ”Œ๋ ˆ์ด
    • 20์„ผํ‹ฐ๋ฏธํ„ฐ ๋ฏธ๋งŒ ํƒ€์ด๋จธ ์ธํ„ฐ๋ŸฝํŠธ ์‚ฌ์šฉ 1์ดˆ๋งˆ๋‹ค LED ์ ๋ฉธ
    • ๊ทธ ์ด์™ธ LED HIGH, LCD 2ํ–‰์— ๊ฒฝ๊ณ  ๋ฌธ์ž ์ถœ๋ ฅ

 

๋ฌธ์ œ ์ดํ•ด

  • ํ•˜๋‚˜์˜ ํ•€์œผ๋กœ ํด๋ง๊ณผ ๋ผ์ด์ง• ์—ฃ์ง€๋ฅผ ๋™์‹œ์— ๊ฒ€์ถœํ•  ์ˆ˜ ์—†๋‹ค
    • ํด๋ง์ด ๋๋‚˜๋ฉด ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์ดˆ๊ธฐํ™” ํ•˜๋Š” ์ˆ˜ ๋ฐ–์—.
  • ํƒ€์ด๋จธ ์ธํ„ฐ๋ŸฝํŠธ๋Š” ๋งˆ์ง€๋ง‰์— ์„ธํŒ…๋œ ํ•จ์ˆ˜๋งŒ ์‹คํ–‰ํ•œ๋‹ค.
    • stop()์„ ํ˜ธ์ถœํ•  ๊ฒƒ.

 

์ฝ”๋“œ

#include <TimerOne.h>

#include <MsTimer2.h>

#include <LiquidCrystal.h>

LiquidCrystal lcd(42, 43, 44, 45, 46, 47);

int switch_state;
int LED = 22;
int TRIGGER = 12;
int ECHO = 13;
int LED_state = HIGH;
int LCD_state = HIGH;

const byte interruptPin = 2;
volatile int fallingCount = 0;
volatile int risingCount = 0;
volatile long cm;  // ๊ฑฐ๋ฆฌ๋ฅผ ์ „์—ญ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
  pinMode(ECHO, INPUT);
  pinMode(TRIGGER, OUTPUT);

  noInterrupts();
  interrupts();
  attachInterrupt(digitalPinToInterrupt(interruptPin), fallingAct, FALLING);  // Falling ๋ถ€ํ„ฐ ์ง„ํ–‰

  lcd.begin(16, 2);
}

void loop() {  // ํ•ญ์ƒ ์ดˆ์ŒํŒŒ ๊ฑฐ๋ฆฌ๋Š” lcd์— ๋””์Šคํ”Œ๋ ˆ์ด
  // put your main code here, to run repeatedly:
  cm = getDistanceOfCm();
  lcd.setCursor(0, 0);
  lcd.print(cm);
}

// ์ฒซ๋ฒˆ์งธ Falling edge ์‹œ ๋™์ž‘ ํ•จ์ˆ˜
void countOneAct() {
  lcd.setCursor(0, 1);
  lcd.print(millis() / 1000);

  flushLed();
}

// lcd ์ ๋ฉธ
void countFiveAct() {
  if (LCD_state == HIGH) {
    lcd.setCursor(0, 1);
    lcd.print("Warning!!");
  } else if (LCD_state == LOW) {
    lcd.clear();
  }

  LCD_state = !LCD_state;
}

// led ์ ๋ฉธ
void flushLed() {
  digitalWrite(LED, LED_state);
  LED_state = !LED_state;
}

// ์ดˆ์ŒํŒŒ์„ผ์„œ ์ž‘๋™ ๋ฐ cm ๋ณ€ํ™˜ ํ•จ์ˆ˜
long getDistanceOfCm() {
  digitalWrite(TRIGGER, LOW);  // ์ถœ๋ ฅ ๊นจ๋—ํžˆ!
  delayMicroseconds(2);

  digitalWrite(TRIGGER, HIGH);  // ์ถœ๋ ฅ ์‹œ์ž‘
  delayMicroseconds(10);

  digitalWrite(TRIGGER, LOW);  // ์ถœ๋ ฅ ์ข…๋ฃŒ

  long duration = pulseIn(ECHO, HIGH);  // ์—์ฝ”๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ๊ฐ€ HIGH ์˜€์„ ์‹œ๊ฐ„์„ ์ €์žฅ
  return (duration / 2) / 29.1;         // cm๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฐ˜ํ™˜
}

//Falling edge Interrupt Service Routine
void fallingAct() {

  fallingCount++;  // Falling count 1 ์ฆ๊ฐ€

  if (fallingCount == 1) {
    MsTimer2::set(1000, countOneAct);
    MsTimer2::start();
  }

  if (fallingCount == 3) {
    lcd.clear();

    if (cm < 20) {
      MsTimer2::stop();
      digitalWrite(LED, HIGH);
    } else {
      MsTimer2::set(1000, flushLed);
      MsTimer2::start();
    }
  }

  if (fallingCount > 3) {
    MsTimer2::stop();
    noInterrupts();  // Rising Edge๋ฅผ ๊ฒ€์ถœํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ธํ„ฐ๋ŸฝํŠธ ์ข…๋ฃŒ
    interrupts();
    attachInterrupt(digitalPinToInterrupt(interruptPin), risingAct, RISING);
  }
}

void risingAct() {
  risingCount++;

  if (risingCount == 5) {
    lcd.clear();

    if (cm < 20) {
      MsTimer2::stop();
      MsTimer2::set(1000, flushLed);
      MsTimer2::start();
    } else {
      MsTimer2::stop();
      digitalWrite(LED, HIGH);
      MsTimer2::set(2000, countFiveAct);
      MsTimer2::start();
    }
  }
}

 

 

๋ฐ˜์‘ํ˜•