FUJIFILM | FinePix E500 | Normal program | Pattern | 1/10sec | F/2.9 | 0.00 EV | 4.7mm | ISO-400 | Off Compulsory | 2009:01:14 15:34:18

FUJIFILM | FinePix E500 | Normal program | Pattern | 1/8sec | F/2.9 | 0.00 EV | 4.7mm | ISO-400 | Off Compulsory | 2009:01:14 15:35:00

일단은 보면 두개의 파형이 다르다.
하나는 45Hz 이고 다른 하나는 48Hz 이다...

위의 사진(45Hz)은 180도로 설정하기 위한 2000us 이고
아래 사진(48Hz)은    0도로 설정하기 위한 600us 이다. (grid 하나당 10ms)

아무튼, 20ms 간격은 맞지만, 문제는 20ms 로 반복되는 것이 아니라
20ms 이후에 신호가 나옴으로 인해서 점점 주기에서 벗어나는 문제가 발생했다.
이래저래 PWM 신호 발생 루틴을 수정해야할듯 하다.



ES-311은 원래 HS-311의 클론이고,
HS-311은 1500usec neutral에 +- 900 usec으로 제어신호를 보내면 된다.(머리 데굴데굴 0ㅁ0)

[링크 : http://www.servocity.com/html/hs-311_standard.html]

2010.02.03 추가
HS-311 은 90도 버전과 180도 버전 두가지가 존재하나 보다.

2010/01/11 - [AVR / 8051] - Atmega128에서 아날로그 서보모터 작동시키기(Atmega128 analog servo tutorial)

신고
Posted by 구차니

댓글을 달아 주세요

How to control analog servo using Atmega128 timer0 (8bit timer)

서보모터는, 재미난 녀석이다. 근데 다루기 쉽지는 않다 ㅠ.ㅠ
예전에 구매한 녀석으로 이렇게 생겨먹었다.

특이하게도 색이 흰색/빨강/검정이 아니라 주황/빨강/갈색이다.
빨강은 Vcc
갈색은 GND
주황은 Signal 이다.


서보 스펙
아날로그 신호를 받아들이며(아날로그 서보)
4.8V에 0.19sec/60' 대략 180도 전체 이동에 0.6sec 정도 걸린다.(생각보다 빠른거 같은데 막상보면 느리다.)

AVR 스펙
us-technology 사의 제품으로 16Mhz로 작동하며
PORTC 는 디버깅용 LED
PORTF 는 PWM 출력용으로 사용하였다.

Timer0(8bit timer)를 이용하여, PWM 신호를 만들어낸다.(Timer만으로 제어함)
[링크 : http://www.us-technology.co.kr/product/product_main.asp?mode=101&smode=2]

소스코드는 AVR BIBLE (배성중/북두출판사) 를 참고하였으며
winavr 요즘 버전에 맞추고(ISR, outp 매크로, include 경로), 클럭이 맞지않아 변수들을 수정하여 타이밍을 조절하였다.

지루한 계산
16Mhz = 16,000,000 hz 이고
서보 모터는 20ms = 0.02sec 단위로 신호를 넣어준다.
그리고 PWM 신호는 0.5ms ~ 2ms 사이의 길이를 넣어주면 0 ~ 180도의 각도로 이동한다.
(책에는 1.5ms 에서 길거나 짧거나 라고 하는데 서보마다 다른듯.. 데이터 시트에도 없다 ㄱ-)

일단 8bit timer를 사용함으로 256 clock 마다 overflow를 발생시키며
    16,000,000(clock/sec) / 256 = 62,500 times
1초에 62,500 번의 overflow가 발생하게 된다.
    1/62500 = 0.000016 sec 이며
    62500/50 = 1250 이다.(20ms 는 1초에 50회)
즉, 256번씩의 overflow를 1250번 반복하게 되면 0.02sec = 20msec 간격을 잡을수 있다.
그리고 1msec는 62.5 인터럽트가 모이면 되고,
실험적으로 서보에서 사용하는 PWM의 width를 얻어내면 된다.

엘레파츠 ES-311 서보에서
     0도는 0.512ms = 32 overflows
    90도는 1.216ms = 76 overflows
    180도 1.792ms = 112 overflows

아무튼 위의 값은 정확한건 아니지만.. (ㄱ-) 대략적으로 맞아들어가며
0도와 180도의 하한/상한을 찾은뒤 평균내면 90도가 잡아진다.(레드썬!)
(위의 값으로는 180도 쪽이 약간 5도 정도 부족해 보이나,
끽끽대며 더이상 가지 못하는 문제가 있어 실질적으로 90도를 약간 좌측으로 수정해야 하지 않을까 싶다.)

대충의 계산방식이 들어있는 스프레드시트 파일.
클럭과 timer overflow 에 필요한 clock을 입력하면 된다.


소스코드 & 동영상


신고
Posted by 구차니

댓글을 달아 주세요

  1. 게르드

    오오~ 서보도 잘 움직이네요..^^ +_+

    2010.01.20 14:27 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • 이거 버전 1 이고
      파워분리하고 쇼해서 기판이 좀 달라졌어 ㅋㅋ

      2010.01.20 14:36 신고 [ ADDR : EDIT/ DEL ]
  2. 비밀댓글입니다

    2011.03.04 11:01 [ ADDR : EDIT/ DEL : REPLY ]
    • 회로도 까지 만들어 가면서 만든 녀석이 아니라서요 ^^;
      그냥 단순하게 pin 하나를 서보의 signal에 연결하고
      전원 / gnd 는 따로 연결을 해주고
      ATMEGA의 PWM 기능을 사용하지 않고, 딜레이를 사용하여 PWM 신호를 생성하는 식으로 구현했었습니다.

      2011.03.04 11:11 신고 [ ADDR : EDIT/ DEL ]
  3. 비밀댓글입니다

    2014.11.08 16:28 [ ADDR : EDIT/ DEL : REPLY ]
    • for(;;) 안에 딜레이나 일정 시간에 한번씩만 값을 바꾸는 루틴이 필요 합니다.
      while(sec < 49)
      61
      {
      62
      PORTC = Bout;
      63
      }
      제 코드에서는 이런식으로 #if 1 별로
      값을 한번만 바꾸도록 해서 필요한 주기 동안은 값이 hi/low로 설정되어 있도록 되어있습니다.

      2014.11.09 15:46 신고 [ ADDR : EDIT/ DEL ]