블로그 이미지
대갈장군

calendar

1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31

Notice

'프로그래밍/Arduino'에 해당되는 글 1

  1. 2013.09.26 Arduino에서 입력으로 들어오는 트리거 신호 지연시키기
2013. 9. 26. 05:58 프로그래밍/Arduino

어쩌다 보니 Arduino를 사용하게 되었는데 이 조그마한 기판을 사용하는 목적은 입력으로 들어오는 5 V / 60 Hz의 신호를 원하는 시간만큼 딜레이를 줘서 고대로 내보내거나 혹은 주파수를 원하는 형태 즉, 30 Hz, 20 Hz, 15 Hz로 변환 하는 것이었다.


처음 생각은 간단하겠는데 였는데 생각보다 쉽지 않았다. 제일 먼저 시도한 것이 analogRead() 함수 였는데 이것의 문제점은 기본적으로 이 함수는 최대한 빨리 입력으로 들어오는 신호를 읽어 들인다는 것이다. 다시 말해서 모든 입력 트리거를 캐치하지 못할 수도 있다는 것.


왜냐면 입력으로 들어오는 트리거 신호는 60 Hz 이므로 16.6ms 마다 5 V에서 0 V로 떨어졌다 바로 다시 5 V로 바뀌는 구조 인데 여기서 0 V로 유지되는 시간이 무지 무지 짧다는 점. 그렇기 때문에 analogRead() 함수가 아니라 attachInterrupt() 함수를 이용해야 한다. 


http://arduino.cc/en/Reference/attachInterrupt 를 참고하면 어떻게 attachInterrupt() 함수를 사용하는지 알수 있다. 기본적으로 디지털 핀 2번으로 입력을 넣고 코드에서 attachInterrupt() 함수를 해당 핀에 연결시키면 트리거가 들어올때 마다 100% 확률로 연결되어진 콜백함수를 호출한다. 고로 신호를 읽을 걱정은 안해도 된다.


다만 그 다음 스텝인 신호 지연을 어떻게 하느냐는 것이었는데, 이것은 micros() 함수를 사용해서 트리거가 들어오는 시점(0 V로 떨어지는 순간)의 시간을 기억해 둔 다음 지연시키고자 하는 만큼의 시간을 더해서 기억해 둔 다음 현재의 시간이 기억해둔 시점보다 크거나 기억해둔 시점 더하기 1 ms 의 시간보다 적으면 (그 범위에 있다면), 그 시간동안 0 V를 출력 핀으로 전송한다. 그 외의 시간에는 계속해서 5 V를 출력 핀으로 전송한다. 물론 원한다면 1 ms이아니라 더 정교한 시간 조절도 가능하다. 하지만 반드시 어느 정도의 시간동안은 0 V를 유지해야 하는데 왜냐면 너무 짧게 0 V를 유지하면 오실로스코프에도 잡히지 않을 정도로 빠르게 통과해 버린다.


추가적으로 60 Hz 속도의 주파수를 30, 20, 15 Hz로 변경하는 방법은 몫과 나눗셈 그리고 나머지를 이용한 방법이다. attachInterrupt() 함수를 CHANGE 플래그와 함께 사용하면 입력 신호가 상태 변화를 일으키는 모든 경우에 콜백 함수를 호출한다. 즉, 하나의 트리거에 대해서 낮은 볼트에서 높은 볼트, 그리고 높은 볼트에서 낮은 볼트로 두 번 변화를 일으키므로 두 번의 콜백 함수가 호출된다.


고로 나눗셈을 이용한 주파수 변환시에 이것을 고려해서 60 Hz에서는 2로 나누고 30 Hz에서는 4로 20 Hz에서는 6 그리고 15 Hz에서는 8로 나누면 된다. 콜백함수가 매번 호출될 때 마다 카운터를 하나씩 올려서 정해진 몫으로 나누면 남은 나머지가 바로 언제 0 V가 되어야 하는지를 알려준다. 원한다면 쉬프팅도 가능하다.


또 가장 주의 해야 할 점이 Arduino와 같은 계판 기기는 주로 오랜 시간 작동하므로 항상 변수의 범주에 대해서 깊이 생각해봐야 했다. 단순히 int로 선언한 카운터가 시간이 지나 한참 지나 결국 오버플로우가 되면 0으로 초기화 되면서 알수 없는 에러가 터지기 때문에 내가 작성한 코드에서는 적당한 시점에서 카운터를 0으로 초기화 시켜서 오버플로우가 발생하지 않도록 했다.


다만, micros() 함수가 메뉴얼에 보면 56분 정도 후에 리셋된다고(오버플로우로 인한) 해 놨는데 이것이 어떠한 영향을 미칠지에 대해서 검증이 좀 필요한 것 같다. 


추가로 시리얼 포트를 통한 통신으로 C# GUI와 연동하면 사용자의 어여쁜 GUI와 강력크한 Arduino의 능력을 섞어서 쓸수 있다. 아마도 더 좋은 방법이 많이 있겠지만...



posted by 대갈장군
prev 1 next