산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

간편한 아두이노 스톱워치: 버튼 작동 크로노미터 제작하기

구성품 및 부품

부품 수량 비고
Arduino UNO 1 어떤 아두이노든 가능, 아두이노가 아닐 수도 있음
버튼 (래칭 타입 아님) 1 풀다운 저항 필요 (1kΩ 사용)
저항 10kΩ 1

앱 및 온라인 서비스

프로젝트 소개

재미있는 프로젝트를 진행하던 중 버튼을 누를 때마다 작동하는 아두이노 크로노미터가 필요했습니다. 복잡한 건 아니지만, 이 코드가 다른 분들 프로젝트에도 유용할 것 같아 공유합니다. 아마 1시간 정도 코딩 시간을 아껴드릴 겁니다.

EEPROM

전원을 끊거나 보드를 리셋해도 정보를 잃지 않는 아두이노의 비휘발성 메모리입니다. #include <EEPROM.h> 라이브러리를 사용하며 기본 설치되어 있습니다.

인터럽트 (Interrupts)

아두이노 내부에서 작업이 진행 중이어도 특정 핀이 HIGH가 되면 하던 일을 멈추고 ISR(인터럽트 서비스 루틴) 함수를 실행하게 하는 기능입니다. 별도 라이브러리 불필요.

attachInterrupt(digitalPinToInterrupt(interruptPin), refreshTime, CHANGE);로 인터럽트 핀의 로직 레벨이 변할 때마다(LOW→HIGH, HIGH→LOW) 함수가 트리거됩니다. 풀다운 저항 덕분에 평소엔 LOW 상태를 유지합니다.

프로젝트 코드

정의 및 인클루드

#include <EEPROM.h>
#define interruptPin 2
#define eeAddress 0 // 아두이노 EEPROM 주소 (내부 비휘발성 메모리)
float starttime = 0;
float endtime = 0;
float resulttime = 0, oldresulttime = 0;

EEPROM 라이브러리 포함, 버튼을 핀 2에 연결. EEPROM 주소 0에 시간 저장 (float = 4바이트). 아두이노 우노는 1024바이트(ATmega328) EEPROM을 가지며, 정리 차원에서 주소 0을 사용했습니다.

setup()

void setup() {
  Serial.begin(9600);
  while (!Serial) { ; } // 네이티브 USB 포트용 대기
  Serial.println("Serial comms are ready sir!:.. bip bip");
  attachInterrupt(digitalPinToInterrupt(interruptPin), refreshTime, CHANGE);
}

loop()

void loop() { } // 여기에 본인 코드 추가

기타 함수들

void refreshTime() {
  if (digitalRead(interruptPin)) { // HIGH: 버튼 눌림 시작
    starttime = millis();
    Serial.print("Start time: ");
    Serial.println(starttime);
  } else if (digitalRead(interruptPin) == LOW) { // LOW: 버튼 뗌
    endtime = millis();
    resulttime = endtime - starttime;
    Serial.print("End time: ");
    Serial.println(endtime);
    Serial.print("Result time: ");
    Serial.println(resulttime);
    WhatsNewEeprom(); // EEPROM에 저장
  }
}

void WhatsNewEeprom() {
  Serial.println("-----------checking eeprom");
  EEPROM.get(eeAddress, oldresulttime);
  Serial.print("oldresulttime"); Serial.println(oldresulttime);
  Serial.print("resulttime"); Serial.println(resulttime);
  if (resulttime != oldresulttime) {
    EEPROM.put(eeAddress, resulttime);
    Serial.print("-----Ding! New time recorded in eeprom: "); Serial.println(resulttime);
  } else {
    Serial.println("No new time found, eeprom was not disturbed");
  }
}

인터럽트 핀 상태 변화 시 실행되는 함수입니다. 버튼 누름 시작(HIGH) 시점과 떼는 시점(LOW)을 감지해 millis()로 시간 차이를 구하고, EEPROM에 저장된 이전 값과 비교해 새로운 기록일 때만 갱신합니다.

보너스: 버튼 디바운싱

아두이노 처리 속도에 비해 사람은 매우 느려, 버튼 한 번 누르는 동안 신호가 여러 번 HIGH/LOW로 튕깁니다(bouncing). 이를 해결하는 방법:

커패시터가 빠른 전압 변화를 흡수해 튐 현상을 방지합니다.

코드

아두이노 크로노미터 (Arduino)

// coded by Javier Muñoz 23/10/2017
// questions to javimusama@gmail.com
#include <EEPROM.h>
#define interruptPin 2
#define eeAddress 0
float starttime = 0;
float endtime = 0;
float resulttime = 0, oldresulttime = 0;

void setup() {
  Serial.begin(9600);
  while (!Serial) { ; }
  Serial.println("Serial comms are ready sir!:.. bip bip");
  attachInterrupt(digitalPinToInterrupt(interruptPin), refreshTime, CHANGE);
}

void loop() {
  // your stuff here
  // (eeprom stored) last time measured in milliseconds "float resulttime"
}

void refreshTime() {
  if (digitalRead(interruptPin)) {
    starttime = millis();
    Serial.print("Start time: ");
    Serial.println(starttime);
  } else if (digitalRead(interruptPin) == LOW) {
    endtime = millis();
    resulttime = endtime - starttime;
    Serial.print("End time: ");
    Serial.println(endtime);
    Serial.print("Result time: ");
    Serial.println(resulttime);
    WhatsNewEeprom();
  }
}

void WhatsNewEeprom() {
  Serial.println("-----------checking eeprom");
  EEPROM.get(eeAddress, oldresulttime);
  Serial.print("oldresulttime"); Serial.println(oldresulttime);
  Serial.print("resulttime"); Serial.println(resulttime);
  if (resulttime != oldresulttime) {
    EEPROM.put(eeAddress, resulttime);
    Serial.print("-----Ding! New time recorded in eeprom: "); Serial.println(resulttime);
  } else {
    Serial.println("No new time found, eeprom was not disturbed");
  }
}

회로도

풀다운 저항을 사용한 버튼 간단 연결

제조공정

  1. 아다프루트 60-LED 네오픽셀 링 4개로 스타일리시 벽시계 만들기
  2. DIY 아두이노 워드 클럭 – 세련된 실시간 텍스트 시계 만들기
  3. 아두이노 나노와 노키아 5110 LCD로 20kHz 오실로스코프 만들기: 쉬운 DIY 가이드
  4. 블루투스 제어 아두이노 스파이봇(Spybot) 만들기
  5. 플릭모트(FlickMote): 스마트 홈을 위한 제스처 제어 IR 리모컨
  6. DIY 아두이노 TV B-Gone: 모든 TV를 끄는 만능 리모컨
  7. 아두이노로 만드는 대형 LED 마스터 시계 (알람 기능 포함, 12m 거리에서도 식별 가능)
  8. 아두이노로 간단한 장애물 센서 만들기 - IR LED & 포토다이오드 튜토리얼
  9. 아두이노와 블루투스로 만드는 스마트 물건 찾기 'Find Me'
  10. DS1302 RTC와 아두이노 우노로 만드는 신뢰할 수 있는 알람 시계