뉴티씨



  • HOME
  • 고객지원
  • 질문답변


 
자이로 센서 데이터 받는 법에 대해서..
 글쓴이 : 관리자
작성일 : 17-04-21 05:55
조회 : 80  
안녕하세요? 고객님,
저희 뉴티씨 제품을 이용하여 주셔서 감사합니다.

홈페이지의 소스는 적분을 통하여 면적을 구하는 소스입니다.
그것을 통하여 각을 구해내는 것인데,
적분시 디지타이징되는 부분에서 누적에러가 발생하므로, 누적분이 반영되어,
약간씩 틀어지는 것인데, 그 부분을 가속도 센서를 이용하여 보정하면 되는 것입니다.

고객님의 소스를 저희가 일일이 테스트 해서 알려드리기는 참 어려운 부분입니다.
거기에서 한단계 더 넘어서야 잘 동작하는 상태로 가게 되는 데,
가속도 만으로 쓴다면, 충격 등에 의해서도 값이 자주 바뀌게 되므로, 자이로 등을 써야 합니다.

저희 질문의 범위를 넘어서서, 답변을 잘 드리지 못함을 죄송하게 생각합니다.
참고 :
http://www.newtc.co.kr/dpshop/bbs/board.php?bo_table=m53&wr_id=50
http://www.newtc.co.kr/dpshop/bbs/board.php?bo_table=m53&wr_id=26&sca=&sfl=wr_subject%7C%7Cwr_content&stx=%EC%9E%90%EC%9D%B4%EB%A1%9C&sop=and

참고로, 드리프트 심하다면, 자이로를 통한 각이동량은 저희 소스로 구하여 쓰는 것이 어떨까 생각합니다.

감사합니다.

>
>
> 안녕하세요.. 모 대학교 전자공학과 학생입니다..
>
> 고객지원-자주하는 질문에 올라온 자이로센서 데이터 받는 소스는 제가 이해하기가 좀 어려워서
> 임의로 간단하게 데이터를 받아서 사용중인데요. 데이터 신뢰도가 너무 낮아서 좀 쉽게 설명해주실 수 있나
> 해서 질문 올려요.. 가속도는 그럭저럭 데이터가 괜찮아요.. 상보필터를 이용해서
> 보정을 하려고하는데 일반적으로 자이로데이터0.9 가속도데이터0.1 정도를 사용한다는데
> 저는 가속도를 0.8을 사용하고 자이로를 0.2만 썼습니다.. 없는거나 마찬가지인데요..
> 자이로 센서 데이터받을 때 신뢰도를 높이려면 어떻게 해야되는지 설명해주실 수 있나요?..
>
> 아래 소스에서 자이로 가속도 둘다 평균내서 쓰고있는데
> 제가 아는 한에서는 상보필터에서 자이로는 평균내지않고 순간변화량을 신뢰하고 가속도는 평균값을 신뢰한다고하는데 자이로를 평균내주지 않으면 그나마도 데이터를 볼 수 없을 정도로 드리프트가 심해요..
>
>
> #include <io.h>
> #include <delay.h>
> #include <alcd.h>
> #include <stdio.h>
> #include <math.h>
>
> #define FIRST_ADC_INPUT 0
> #define LAST_ADC_INPUT 1
> unsigned int adc_data[LAST_ADC_INPUT-FIRST_ADC_INPUT+1];
> #define ADC_VREF_TYPE ((0<<REFS1) | (0<<REFS0) | (0<<ADLAR))
>
> void cw_step(int a);
> void ccw_step(int a);
>
> interrupt [ADC_INT] void adc_isr(void)
> {
> static unsigned char input_index=0;
> adc_data[input_index]=ADCW;
> if (++input_index > (LAST_ADC_INPUT-FIRST_ADC_INPUT))
>    input_index=0;
> ADMUX=(FIRST_ADC_INPUT | ADC_VREF_TYPE)+input_index;
> delay_us(10);
> ADCSRA|=(1<<ADSC);
> }
>
> void main(void)
> {
> char text[16];
> char text2[16];
>
> int gyro_volt = 0;
> int gyro_volt2_sum = 0;
> int gyro_volt2_average = 0;
> int gyro_degree = 0;
>
> int acc_volt = 0;
> int acc_volt_sum = 0;
> int acc_volt_average = 0;
> int acc_degree = 0;
>
> int before_angle = 0;
> int after_angle = 0;
>
> int i = 0;
>
> PORTA = 0x00;
> DDRA = 0xFF;
>
> ASSR = 0x00;
> TCCR0 = 0x06; //256분주
> TCNT0 = 0x83;
> OCR0 = 0x00;
>
> ADMUX=FIRST_ADC_INPUT | ADC_VREF_TYPE;
> ADCSRA=(1<<ADEN) | (1<<ADSC) | (0<<ADFR) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);
> SFIOR=(0<<ACME);
>
> lcd_init(16);
>
> #asm("sei")
>
> while (1)
>      {
>      lcd_clear();
>      lcd_gotoxy(0,0);
>     
>      if(gyro_volt == 0)
>      gyro_volt = adc_data[0];
>      if(acc_volt == 0) 
>      acc_volt = adc_data[1];
>     
>      for(i=0;i<10;i++){     
>      gyro_volt2_sum += adc_data[0];
>      delay_us(1);
>      }
>     
>      for(i=0;i<10;i++){     
>      acc_volt_sum += adc_data[1];
>      delay_us(1);
>      }
>     
>      gyro_volt2_average = gyro_volt2_sum/10;
>      acc_volt_average = acc_volt_sum/10;
>
>      gyro_degree += (int)((gyro_volt - gyro_volt2_average)*9.7533136*0.1);
>     
>      acc_degree = (int)(asin(((acc_volt_average-acc_volt)*0.0048828125/0.8)) * 180/PI * 1.6);
>     
>      before_angle = (int)(0.20*(before_angle + (gyro_volt - gyro_volt2_average)*9.7533136*0.1)+0.80*(asin((acc_volt_average-acc_volt)*0.0048828125/0.8)) * 180/PI);
>     
>      sprintf(text,"%i %i %i",gyro_volt,adc_data[0],gyro_degree); 
>     
>      sprintf(text2,"%i %i %i",acc_volt, acc_degree, before_angle);
>     
>      gyro_volt2_sum = 0;
>      acc_volt_sum = 0;
>     
>      lcd_puts(text);
>      lcd_gotoxy(0,1);
>      lcd_puts(text2);
>     
>      if(after_angle-before_angle>0){//int형이므로 1도 차이마다 모터제어 
>      cw_step(after_angle-before_angle);
>      }
>      else if(after_angle-before_angle<0){
>      ccw_step(before_angle-after_angle);
>      }   
>     
>      after_angle = before_angle;
>           
>      delay_ms(10);     
>      }
> }
>
> void cw_step(int a)
> {
>    int b;
>    for(b=0;b<a;b++){
>      PORTA.0 = 0x01;
>      PORTA.1 = 0x00;
>      PORTA.2 = 0x01;
>      PORTA.3 = 0x00;
>      delay_ms(1);
>
>      PORTA.0 = 0x01;
>      PORTA.1 = 0x00;
>      PORTA.2 = 0x00;
>      PORTA.3 = 0x01;
>      delay_ms(1);
>
>      PORTA.0 = 0x00;
>      PORTA.1 = 0x01;
>      PORTA.2 = 0x00;
>      PORTA.3 = 0x01;
>      delay_ms(1);
>
>      PORTA.0 = 0x00;
>      PORTA.1 = 0x01;
>      PORTA.2 = 0x01;
>      PORTA.3 = 0x00;
>      delay_ms(1); 
>      }
> }
>
> void ccw_step(int a)
> {
>    int b;
>    for(b=0;b<a;b++){
>      PORTA.0 = 0x00;
>      PORTA.1 = 0x01;
>      PORTA.2 = 0x01;
>      PORTA.3 = 0x00;
>      delay_ms(1);
>
>      PORTA.0 = 0x00;
>      PORTA.1 = 0x01;
>      PORTA.2 = 0x00;
>      PORTA.3 = 0x01;
>      delay_ms(1);
>
>      PORTA.0 = 0x01;
>      PORTA.1 = 0x00;
>      PORTA.2 = 0x00;
>      PORTA.3 = 0x01;
>      delay_ms(1);
>
>      PORTA.0 = 0x01;
>      PORTA.1 = 0x00;
>      PORTA.2 = 0x01;
>      PORTA.3 = 0x00;
>      delay_ms(1);
>      }
> }
>