DynamicRC 광팬 커뮤니티에 오신 것을 환영합니다!
DynamicRC 광팬 커뮤니티

게시판 통합검색 help
subject/ name/ content/ comment

공지사항 자유게시판 QnA 제작일지 비행일지
RC전자공작 MCU STUDY IR·RF 자료실 Link 옛날 프로젝트룸

로그인 회원가입
타코미터 연구 두번째..
김영일  2012-05-10 11:35:00, 조회 : 3,265, 추천 : 236
1. 앞전 타코미터 실험에서 실용적인 정확성을 확인했으므로 이번에는 실제로
센서로부터 신호를 읽어오는 실험을 했습니다.
간이 측정기를 만들고 드릴에 플래그를 달았습니다.  실제로 피코즈 꼬리날개 크기
로 테이프 폭을 잘라 붙인것입니다. 이것이 인식되면 왠만한 프롭은 다 인식되겠지요.

2. 실험한 결과 저속에서는 인식하지만  고속회전에서는 인식을 하지 못했습니다.
이 센서 회로는 빛이 가려지면 출력이 high가 나오게끔 구성한 것입니다.
그런데 스코프로 파형을 확인해보면 저속에서는 low/high 신호가 확실히 구분되는데
고속으로 올릴수록 파형폭만 짧아지는것이 아니라 high전압도 채 상승하기 전에 하강하는
작은 톱니파 형식을 띄는게 보였습니다.

3. NPN TR한개과 저항 몇개를 조합하여 이리저리 저항값을 바꿔가며 테스트한 최종회로입니다.
뭐 TR증폭을 잘 몰라서 그냥 마구잡이로 저항바꿔가며 좋은 결과나올때까지 변경해본겁니다.
딴지좀 걸어주세요.

4. 파형이 그런대로 만족스럽습니다.   드릴의 최대 RPM은 2830인데 플래그 3개 붙여놓으니까
대략 8500 RPM의 값이 나옵니다.  이정도 속도면 소형,경량기체의 프로펠러 인식용으로는
충분한 스팩이라고 생각합니다.  
다음에는 반사형으로 구성해야겠습니다. 관통형은 아무래도 실용적이지 못하다고 생각합니다.

회로도도 없는데 소스가 필요할란가만은  그냥 코드만 보셔도 대략 회로를 어떻게 구성했는지
감 잡으실겁니다.

display는 대략 0.5초마다 한번씩이고,  RPM측정은 이전 DISPLAY 시점부터 들어온 펄스시간들 누적
값에 셈플링 횟수로 나눈, 전체 셈플링의 평균값이 되겠습니다. 0.5초동안 20개 들어오면
20개의 평균값을 취한다는 거죠.

//**********************************************************
//              Tachometer
//        LCD display version.
//------------------------------------------------
//  
//   Date : 2012 05. 10.
//   Programed by youngil.kim
//**********************************************************
#define F_CPU 16000000UL  // 16 MHz

#include <avr/io.h>  
#include <avr/interrupt.h>
#include <util/delay.h>

#include "Mymega16.h"


volatile unsigned char dsp_count, ovf_count;
volatile unsigned int flag, sample_count;
volatile unsigned long count16_sum;

//--------------[ flag ]--------------
#define        DSP                0
#define LOWRPM        1                

#define SAMPLE        100


// 외부 인터럽트 처리루틴
ISR (INT0_vect) {
        if (sample_count < SAMPLE) {
                count16_sum += ((unsigned long)ovf_count * 65536);
                count16_sum += TCNT1;
                TCNT1=0;
                ovf_count=0;
                sample_count++;
        }
}

//   초당 61회 호출된다.
ISR(TIMER0_OVF_vect ) {
        if (dsp_count > 30) {
                sbi(flag, DSP);                        // 대략 0.5초마다 display갱신.
                dsp_count = 0;
        }
        else dsp_count++;
        
//        if (chkbit(PORTB,0)) cbi(PORTB, 0);   // 펄스 제너레이터.
//        else sbi(PORTB, 0);
}

ISR(TIMER1_OVF_vect ) {
        ovf_count++;

}

int main (void) {
        unsigned char i;
        unsigned int temp;


        //---------[ 포트설정 ]------------------
        // 내부 pull-up 사용안함.
        sbi(MCUCR, PUD);
        
        DDRD = 0xFB;
        DDRA = 0xF2;
        DDRB = 0xFF;


        //---------[ 타이머0 설정 ]--------------
        sbi(TCCR0, CS12);  // 1024분주, display주기 설정용.
        cbi(TCCR0, CS11);
        sbi(TCCR0, CS10);
        
                        

        //---------[ 타이머1 설정 ]--------------
        cbi(TCCR1B, CS12);  // 64분주, 펄스폭 측정용.
        sbi(TCCR1B, CS11);
        sbi(TCCR1B, CS10);
        
        cbi(TCCR1B, WGM13);  // normal mode.
        cbi(TCCR1B, WGM12);
        cbi(TCCR1A, WGM11);
        cbi(TCCR1A, WGM10);


        //---------[ INT0 설정 ]------------------
        sbi (GICR, INT0);    // 외부 인터럽트 Enable.
        sbi (MCUCR, ISC01);
        cbi        (MCUCR, ISC00);  // falling edge detect type.



        //---------[ LCD 초기화 ]--------------

        LCD_initialize();


        locate (0,0);
        LCD_puts("_RPM Meter_");


        for(i=0;i<10;i++) _delay_ms(100);


        //---------[ 변수초기화 ]------------------

        clear_lcd();

        locate (0, 0);
        LCD_puts("RPM:");

        TCNT1 = 0;
        TCNT0 = 0;
        
        sbi(TIMSK, TOIE0);
        sbi(TIMSK, TOIE1);
        
        sei();   // interrupt 시작.


        //---------[ 메인 ]--------------
        for(;;) {
                if(chkbit(flag, DSP) != 0) {
                        cbi(flag, DSP);
                        // display처리

                        temp = 0;
                        locate(0,4);

                        if (sample_count > 1) {
                                count16_sum = count16_sum / sample_count;
                                temp = 15000000 / count16_sum;

                                LCD_num9999(temp);
                        }
                        else {
                                LCD_puts("<200");
                        }

                        count16_sum = 0;
                        sample_count = 0;
                        ovf_count = 0;

                }        

        }


}
 rpm1.jpg | 34.5 KB / 23 Download(s)     rpm2.jpg | 61.3 KB / 16 Download(s)     rpm3.jpg | 50.7 KB / 23 Download(s)     rpm4.jpg | 22.0 KB / 24 Download(s)     rpm5.jpg | 50.5 KB / 23 Download(s)     RPM_meter.zip | 33.7 KB / 21 Download(s)    


아직도
으미 아까븐 Mega16...
그렇게 컴파일하고 나면 몇바이트나 되나요?
2012-05-10
21:06:56
 


김영일
개발은 이거로 하고, 실전에는 mega48로 가야겠지요. 2220 byte입니다. 2012-05-10
22:21:48


추천하기 목록보기
Copyright 1999-2017 Zeroboard / skin by totoru
Copyright 2003-2010 DYNAMICRC.COM All rights reserved