반응형
Notice
Recent Posts
Recent Comments
Link
Brise
[atmega128] RC servo 예제 본문
반응형
이 예제에서는 가변저항의 전압값을 읽어온 후 전압값에 따라 서보모터를 움직인다.
가변저항은 이전 adc예제를 이용하여 전압값을 읽어오며, 읽어오는 전압값은
0~5V, 값으로는 0~1023사이의 값으로 읽어들여진다.
RC 서보모터의 경우 PWM 신호를 받아 동작한다.
서보모터의 한 주기는 20ms로 1초당 50번 반복되어야 하며
핀의 값이 HIGH인 시간이 0.5ms일 때 서보모터의 각도가 0도가 되며
핀의 값이 HIGH인 시간이 2.5ms일 때 서보모터의 각도가 180도가 된다.
아트메가128에서 서보모터를 제어하기 위해서 20ms주기의 PWM을 발생시킨다.
아트메가128에는 타이머 1,3(8비트 타이머) 타이머 2,4(16비트 타이머)가 있으며
8비트 타이머로는 충분한 정밀도를 확보하기 어렵기 때문에 16비트 타이머를 사용하도록 한다.
이 예제에서는 16비트 타이머인 타이머 3의 B핀의 PWM을 이용하여 서보모터를 제어한다.
데이터시트에 따르면 OCR3B는 Port E의 4번 핀에 연결되어 있으므로
서보모터의 신호선을 PE4에 연결한다.
그리고 서보모터에 GND와 VCC를 연결한다.
연결이 완료 되었으면 소스코드를 작성하여 빌드한 뒤 실행한다.
"main.c"
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #define F_CPU 16000000UL #include <avr/io.h> #include <util/delay.h> //#include <avr/delay.h> #include "nb_adc.h" #include "nb_pwm.h" float map_value(float value, float input_min, float input_max, float output_min, float output_max){ // need blocker float ratio = (value-input_min) / (input_max - input_min); float target = 0.0f; float output_band = output_max - output_min; target += output_min; target += ratio * output_band ; return target; } #define ADC_MIN 0 #define ADC_MAX 1023 #define SERVO_0_DEG 800 #define SERVO_180_DEG 5000 #define FILTER_LEN 8 int main(){ DDRA = 0xFF; PORTA = 0xFF; adc_init(); pwm3_init(); int16_t adc_value = 0; uint16_t pwm_array[FILTER_LEN]; uint16_t pwm_value = 0; while(1){ for(int i=0; i<FILTER_LEN ; i++){ adc_value = adc_read(); pwm_value = (uint16_t) map_value(adc_value, ADC_MIN, ADC_MAX, SERVO_0_DEG , SERVO_180_DEG); pwm_array[i] = pwm_value / FILTER_LEN; pwm_value = 0; for(int j = 0; j<FILTER_LEN; j++) pwm_value += pwm_array[j]; pwm3_set(pwm_value); } } return 0; } | cs |
"nb_pwm.h"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #ifndef NB_PWM_H #define NB_PWM_H #include <avr/io.h> #include <avr/interrupt.h> #include <stdio.h> #include <stdint.h> void pwm2_init(); void pwm2_set (uint8_t value); void pwm3_init(); void pwm3_set(uint16_t value); #endif | cs |
"nb_pwm.c"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include "nb_pwm.h" #define PWM_SCALE_MAX 8 #define PWM_TCNT_MAX 255 void pwm3_init(){ // set port DDRE |= 0x10; // mode select : #14 Fast PWM TCCR3A |= (1 << WGM31) | (0 << WGM30); TCCR3B |= (1 << WGM33) | (1 << WGM32); // Fast PWM output pin mode TCCR3A |= (1 << COM3B1) | (0 << COM3B0); // set timer clock scale TCCR3B |= (0 << CS32) | (1 << CS31) | (0 << CS30); ICR3 = 6000; } void pwm3_set(uint16_t value){ OCR3B = value; } | cs |
adc관련 파일은 adc예제에 있으며
최대한 가독성을 높게 하기 위하여 각 조작에 주석을 달았으니 크게 어렵지 않게 볼 수 있을 것이다.
코드를 변형하고 싶다면 이 코드를 기준삼아 datasheet를 검색하는 것이 좋다.
반응형
'MCU' 카테고리의 다른 글
[STM32CubeMX] STM32F429-DISC0 엔코더값 입력받기(quadrature encoder pulse) -2 (0) | 2017.04.29 |
---|---|
[STM32CubeMX] STM32F429-disc0 엔코더값 입력받기(quadrature encoder pulse) -1 (0) | 2017.04.28 |
[STM32CubeMX] STM32F429-DISC0 LCD 출력하기 (0) | 2017.04.27 |
[atmega128] adc 예제 (0) | 2017.04.22 |
아트메가 인공호흡용 아두이노 소스 (0) | 2017.04.15 |
STM32F429-DISCO TrueStudio 프로젝트 기본 템플릿 (0) | 2016.07.11 |
아두이노로 펠티어 항온 챔버(냉장고) 자작하기 (0) | 2016.07.09 |
Comments