본문으로 바로가기

한 일년도 훨씬 전쯤에 가속도센서를 이용한 각도 측정에 대한 글을 올렸었습니다만, 당시엔 실험자체를 제가 수행했던 것이 아니었고, 또 그 당시 홈페이지 자료도 다 잃어서 다시 실험하고 정리했습니다. 그러다보니 좀 늦었네요. 많은 분들(3명?^ㅠ^)이 메일과 제 방명록에 요청하셨었는데 참 죄송스럽다는.... 이번 테스트에는 당시의 DSP2812에서 Cortex M3 LM8962로 프로세서를 교체하고 가속도센서도 바꾸었습니다. 당시 가속도센서 여분이 없더라는..ㅜ.ㅜ 그래서 주위를 둘러보니 withrobot사의 myAccel3LV02라는 보드가 있더군요. 판매처는 모릅니다. 알아서 찾아주세요...

꽤 소형입니다. 판매자의 소개를 잠시 빌리면

이렇게 SPI, I2C 통신을 모두 지원한다는군요. 음... 이번에 데리고 놀고있는 CortexM3 보드가 ADC가 총 4개가 있더군요... 제가 생각하는 전체 센서모듈에서 가속도센서 3축에 자이로 2축을 생각하면 모자라길래 자이로센서는 직접 ADC할 생각으로 보정에 필요한 가속도센서는 SPI를 이용하기로 했습니다. 뭐 withrobot에서 배포하는 아름다운 예제가 있길래...~~^^

그 아름다운 예제를 이전에 제가 테스트한 - 엔코더해석 결과를 일정시간간격으로 시리얼통신으로 전송하기-에 포함시켜 생각하기로 했습니다. 가속도센서나 자이로센서나 판매처나 제작사도 많고 그러다보니 사용예제도 참 잘 배포된다는 생각이 듭니다. 그러나, 한가지 아쉬운것은 실제 참값과의 오차나 혹은 참값에 도달하는 시간등을 알수있도록 예제가 꾸며져 있는건 없더군요...(아직 못찾았다는...).. 그래서 저는 참값과의 비교를 위해 엔코더를 버릴수가 없더군요. 또 미분(실제로는 차분)과 적분등을 수행하기 위해 샘플링타임이 필요하니까 딱 위 최근글에서 제가 살짝 바꾼 예제에 가속도센서 예제를 포함시키는게 제일 편하다는 생각을 하게 된겁니다. 하여간... 위 그림처럼 가속도센서 예제에만 들어있는 헤더화일과 c화일을 프로젝트에 포함시킵니다.

그리고 저의 변형예제의 타이머인터럽트 핸들러에 위 코드를 넣어주면됩니다. (풀 코드는 맨아래 넣어두겠습니다..) 그러면

엔코더값, 가속도의 X축, 가속도의 Y축, 가속도의 Z축;

이렇게 시리얼통신으로 데이터가 넘어옵니다. 콤마(,)와 세미콜론(;)으로 데이터들 사이와 줄을 구분지은건 제가 사용할 프로그램이 MATLAB이기 때문에 받을때부터 좀 쉽게 받을려고 해서 그렇습니다.^^. 시리얼 통신으로 데이터를 받는 것도 [Cortex M3] 단순 시리얼통신 테스트 ComPortMaster에서 이야기한 방법 그대로 사용할 것입니다.

먼저 흔들리는 진자의 회전중심축에 가속도센서를 장착합니다.

그러면, 위 그림처럼 보이듯이, atan 함수를 이용해서 정말 간단히 기울어진 각도를 가속도센서를 이용해서 측정할 수 있다는 사실을 알 수 있습니다. 여기서 예전에도 이야기 했지만, 많은 분들이 말씀하시는 스케일펙터의 조절이라던지 가속도센서의 출력 범위(g)의 조절등은 고려할 필요가 없습니다. (적어도 위 상황이라면) 그것은 (y성분/z성분)을 계산할때, 각 종 펙터들을 그 이전에 곱했다 하더라도 약분되어서 없어질 것이기 때문입니다. 실험결과 데이터를 MATLAB에서 처리한 코드는

Acc = load('AccelTest01.txt');

ts = 0.01;
EncAngle = Acc(:,1)*360/2000;
AccY = Acc(:,3);
AccZ = Acc(:,4);
[N, temp] = size(EncAngle);
t = 0:ts:ts*(N-1);

AccAngle = -atan(AccY./AccZ)*180/pi+2.6;

figure
plot(t, EncAngle)
grid on
hold on
xlabel('second');
ylabel('degree');
plot(t, AccAngle, 'r')
legend('Encoder','Accelerometer');
hold off

위 코드에서 8번행은 그래프를 그리기 위한 시간축을 생성한 것이구요. 10번행은 atan함수를 이용해서 각도를 검출한 부분입니다. 부호가 '-'가 붙은 이유는 엔코더의 '+'방향과 반대로 연결되었더군요...^^... 그리고 10번행 마지막의 2.6도를 더하는 것은 가속도센서를 연결할 때 딱 센터를 맞추지 못하고 좀 기울어졌기 때문입니다. 뭐 프로세서단계에서 보정할 수 있었지만, 그놈의 귀찮음때문에....^^  예전 자료에 비하면, 일단 이번 가속도센서의 출력은 정말 깨끗하다는 사실을 알 수 있습니다. 노이즈를 많이 줄였다고 하던데 정말 그래보입니다.

위 그래프에서 파랑색선과 빨강색선이 거의 겹쳐잘 안보이긴 하는데요. 파랑색선은 진자에 직접연결된 엔코더에서 각도를 잡은겁니다. 즉, 참값이라고 봐도 무방합니다. 빨강선은 가속도센서에서 각도를 잡은겁니다. 이제 가속도센서가 각도를 검출할수있는 원리는 이야기했습니다. 그러나 가속도센서만으로 그 각도를 검출할 수 있는건 딱 위의 상황... 전 가속도센서 회전 중심축에 연결되어야하고 그 회전중심축은 제자리에 가만히 있어야만 할 때입니다.

위 그림처럼 만약 가속도센서가 회전중심축에 있지 못하면, 가속도센서는 접선방향의 가속도 성분과 법선방향의 가속도성분을 측정하게 되어서 회전각도를 검출하는데 문제가 생기게 됩니다.

위 그림처럼 가속도센서를 진자의 끝에 연결했습니다.  또 연결할때 실수(^^)로 이번엔 X축이 회전하게 되었다는...ㅋ... 뭐 그래도 상관은 없으니까요...

결과 그래프입니다. 파랑색 엔코더에서 읽어들인 회전각도와 상당한 오차가 발생한다는 사실을 알수있습니다. 중간에 팍 하고 튀는 부분은 제가 손으로 살짝 친겁니다. 가속도센서이니 충격에대해서는 당연히 다른 센서(속도성분을 검출하거나 각도성분을 검출하는 센서보다) 더 민감할 수 밖에 없을겁니다.

위 두 실험의 결론을 말하면, 가속도센서 만으로 각도를 검출하는것은 병진운동성분이 있는 경우는 힘들다는 것입니다. 이제 자이로가 등장해야지요...^^ 위 두 실험데이터는

gettingAngleUsingAccelerometor.zip

으로 올려놓았습니다. MATLAB화일과 시리얼통신으로 받은 데이터는 txt화일입니다. 마지막으로 아래에는 다시 메인 c 코드 전체입니다.

//*****************************************************************************
//
// Withrobot에서 배포하는 엔코더 테스트화일에 
// 시리얼 통신 예제와 타이머 인터럽트 사용예를 통합하고
// 다시 myAccel3LV02보드 테스트용 예제를 통합하고
// 출력양식을 조금 변경함.
//                                              -PinkWink-    2009.06.08
//
//
//*****************************************************************************

#include 
#include 
#include 
#include 
#include "../../../hw_types.h"
#include "hw_ssi.h"
#include "../../../hw_memmap.h"
#include "sysctl.h"
#include "gpio.h"
#include "uart.h"
#include "ssi.h"
#include "qei.h"
#include "ustdlib.h"
#include "timer.h"
#include "interrupt.h"

#include "myAccel3LV02.h"
#include "myAccel3LV02_hal_spi.h"

#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif

#define BUFFER_LEN              32

static void UARTPutString(char * str);
static void InitTIMERINT(void);
static void InitUART(void);
static void InitQEI(void);
static void TimerIntHandler(void);

int main(void)
{
    SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ);

    InitTIMERINT();		// Initialize Timer Interrupt
    InitUART();			// Initialize Serial
    InitQEI();			// Initialize Encoder Module
    MA3_INIT();			// Initialize Accelerometer

    // Loop Start.
    while(1)
    {
    }
}

static void TimerIntHandler(void)
{
    unsigned long pos;
    char buffer[BUFFER_LEN];
    short data_short_array[3];

	// Clear interrupt flag
	TimerIntClear( TIMER0_BASE, TIMER_TIMA_TIMEOUT );

	// Read Encoder Value
	pos = QEIPositionGet(QEI0_BASE);
	usnprintf(buffer, BUFFER_LEN, "%d, ", pos);
	buffer[BUFFER_LEN - 1] = 0;
	UARTPutString(buffer);

	// Read Accel Data
	MA3_CS_ON();
	MA3_READ(MA3_REG_OUTX_L, (unsigned char*)data_short_array, sizeof(data_short_array));
	MA3_CS_OFF();
	usnprintf(buffer, BUFFER_LEN, "%d,  %d,  %d;\n", data_short_array[0], data_short_array[1], data_short_array[2]);
	UARTPutString(buffer);
}

static void UARTPutString(char * str)
{
    while(*str)
        UARTCharPut(UART0_BASE, *str++);
}

static void InitTIMERINT(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    TimerConfigure( TIMER0_BASE, TIMER_CFG_32_BIT_PER );
    TimerLoadSet( TIMER0_BASE, TIMER_A, SysCtlClockGet() / 100 );	// 10ms
    TimerIntRegister( TIMER0_BASE, TIMER_A, TimerIntHandler );
    IntMasterEnable();
    TimerIntEnable( TIMER0_BASE, TIMER_TIMA_TIMEOUT );
    TimerEnable( TIMER0_BASE, TIMER_A );
}

static void InitUART(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
}

static void InitQEI(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);

    GPIOPinTypeQEI(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_6);
    QEIConfigure(QEI0_BASE, (QEI_CONFIG_CAPTURE_A_B | QEI_CONFIG_NO_RESET | QEI_CONFIG_QUADRATURE | QEI_CONFIG_NO_SWAP), 0xffffffff);
    QEIVelocityConfigure(QEI0_BASE, QEI_VELDIV_1, SysCtlClockGet() / 100);

    QEIEnable(QEI0_BASE);
    QEIVelocityEnable(QEI0_BASE);
}

댓글을 달아 주세요

  1. 이전 댓글 더보기
  2. mijong 2011.03.03 19:10

    cpu에 엔코더 해석 기능이 있다고요??

    음 그냥 엔코더의 값을 읽어 들여서 그값을 프로그래밍 상에서 해석하고

    각도로 환산 까지 같이 해줄수는 없나요??

    • BlogIcon PinkWink 2011.03.04 08:56 신고

      이부분은 좀 그렇습니다. 엔코더는 A,B라고 해서 Z상을 제외하고 상이 두개 입니다. 이 두개의 상의 위상차를 이용해서 방향을 잡고, 펄스를 카운트해서 각도를 계산합니다. 엔코더의 사용방법에 대해서는 저는 다룬적이 없습니다.

  3. mijong 2011.03.09 11:48

    엔코더 하나 학교에서 지원 받아서 살려고 하는데

    윙크 님은 어떤 엔코더를 추천하시나요??

    그리고 엔코더 해석 하려면 따른 엔코더 드라이버가 필요한가 보네요??/

    • BlogIcon PinkWink 2011.03.09 12:51 신고

      한바퀴에 512펄스정도면 괜찮습니다. 모양리아 크기는 천차만별이니 선택하셔야하구요. 디바이스마트같은곳을 검색해보시면 됩니다. 사용하시는 MCU 별로 검색해보시면 아마 엔코더 해석법은 나올겁니다

  4. mijong 2011.03.09 11:50

    그리고 혹시 각도 측정에 대해 많이 찻던중

    가변저항을 이용해서 측정하는 것도 있더라고요.

    가변저항으로 각도 측정 하는거는 어떻게 생각하시는지요????

    • BlogIcon PinkWink 2011.03.09 13:05 신고

      아랫댓글은 의미없는것같아 삭제했습니다. ADC 방식의 말씀하신것은 흔히 포텐셔미터라고 부릅니다. 엔코더에 비하면 ADC 노이즈가 있을겁니다. 각도측정에 많이 사용하는데 괜찮을 겁니다. 그러나 역시 사용하고자하는 목적에 부합되는지는 설계자의 판단입니다.

  5. starlsh 2011.04.17 23:02

    안녕하세요?

  6. starlsh 2011.04.17 23:22

    안녕하세요?
    가속도센서에 대해 알고픈것이 있어 헤메이다가 PinkWink님의 블로그를 찾게되였습니다.
    외람되지만 한가지 질문할려고 합니다.
    저는 지금 안드로이드폰에 장착된 가속도센서로 작업을 하고 있는데요, 폰을 테이블우에 수평으로 놓고 x축과 y축으로의 이동거리를 구하려고 합니다. x축과 y축에 해당한 가속도값을 얻고 중력성분을 떼버리는데 까지는 하였는데... 값이 너무 산만하고 또 한축에서로 방향(정의 방향, 부의 방향)에 따라 양의 값과 음의 값이 달라지고 가속도값이다나니 한방향(정 혹은 부의 방향)에서도 가속과 감속에 따라 음의 값과 양의 값이 추출됩니다.
    그러다나니 이동방향을 잡기 힘듭니다.
    가속도센서로는 이동거리와 방향을 정확히 잡을수없는걸가요?
    만약 할수있다면 어떤원리에 기초해서 어떤 공식으로 실현해야 하는지...
    철없는 질문이지만 답변 좀 주세요…

    그리고 발을 상하셨다는데 수술후 운동치료를 잘 하셔야 합니다.
    저도 팔을 수술하였는데 운동치료를 잘 못해 지금도 약간씩 고생을 하고 있습니다… 빨리 완쾌되시기를…

    • BlogIcon PinkWink 2011.04.18 08:31 신고

      자이로센서를 이용한 각도측정과 한계라는 글을 보시면 아시겠지만, 어떤 센서의 출력을 적분해서 원하는 것을 얻는 것은 아주 힘듭니다. 자이로센서의 경우만 봐도 한번만 적분하는 것인데도. 보정용으로서 다른 센서가 필요할 정도이거든요.
      가속도센서로 이동 거리까지 잡는 다는 것은 두 번의 적분이 수행되어야하므로 꽤 어려운 일이 됩니다. 그리고, 가속도센서로 방향만이라도 잡는 것도 생각보다는 어렵습니다. 방향은 '+'방향으로 진행하고 있지만, 그 가속도나 속도성분은 '-'방향일 수 있거든요.
      결론은 가속도센서만 가지고 이동거리와 방향을 잡는 것은 무지 어렵다는 것입니다.

  7. starlsh 2011.04.18 13:42

    답변 감사합니다.

  8. Stdlib 2011.05.22 00:42

    안녕하세요.
    cortex lms-8962 보드에서 stdlib.h를 사용하려고 이것저것 알아보다. 들어오게 되었습니다. 포스팅하신내용와 크게 관련은 없어 보이나. 작성하신 코드에 stdlib가 인클루드 되어 있어 질문드립니다. 사용하고 싶은 함수는 malloc인데 혹시..사용하는법을 아시나요?

    • BlogIcon PinkWink 2011.05.22 08:01 신고

      아.. 제가 하드웨어(펌웨어) 쪽은 이 글을 작성할 당시 빤짝 해본거였어요^^
      잘 모른답니다.
      도움이 되지 못해 죄송합니다.^^

  9. 커피향기 2012.03.16 22:34

    안녕하세용~저기...PP:있으세용?아니..햄스터에대해서물어볼려구용..헤헤....저아직,13살이에용....헤..(햄스터초보랍니당~)

  10. 커피향기 2012.03.17 20:20

    감사해용~~(애교애교____)

  11. 전병현 2012.10.26 18:47

    안녕하세요 매일 이곳글을 참고만 하다가 한가지 질문이 있어 질문하고자 합니다.
    우선 질문에 관련된 제가 하고있는 작업을 소개하자면...
    가속도센서와 자이로 센서를 부착한 물체의 이동 궤적을 추적하는것입니다.
    현재 두센서는 평행하게 위치한 상태로 함께 움직이게끔 되어있구요..
    원래 그냥 소프트웨어 개발잔데 몇년간 손놓고 있던 삼각함수와 미적분을 다시 건드리니
    머리가 많이 아프네요... 수많은 시도를 해보고 문제가 있어 이렇게 질문드리니 답변 부탁드릴게요

    만약 물체가 센서의 x축 +방향으로 이동후 정지시 (물체의 기울기와 방향은 변하지 않는다 가정합니다)
    가속도계의 x그래프는 +증가하였다 정점을 찍고 감소하여 -로되었다가 다시 정점을 찍고 0이 됩니다.
    이동후 물체가 멈춰있다면 이론상으로는 x그래프의 양수구간의 적분값과 음수 구간의 적분값이 같아서
    마지막 속도가 0이되어야 맞는데... 실제로는 어느정도 오차가 생깁니다.
    그리하여.. 실제론 물체가 멈춰있음에도 센서로 계산해낸 속도상으로는
    물체가 계속 등속도 운동을하고 있는첫처럼 보입니다.
    실제로 가속했다 감속하여 멈춘것이 아닌
    가속후 감속하여 저속으로 움직이는 경우와 같아지는것이죠

    질문을 정리하자면
    1)어떻게 하면 멈춘 상황의 오차인지... 단지 감속한 상태인건지를 판별할 수 있을까요?
    2)이러한 오차를 없앨수 있는 방법이 있는건지 알고싶습니다..
    3)실제로 가속도 센서와 자이로를 이용하여 트래킹하는 사용중이 시스템이 있는지 알고싶네요..
    4)실제로 신뢰성있는 시스템 개발이 가능할까요?

    읽어주셔서 감사합니다.

    • BlogIcon PinkWink 2012.10.26 19:35 신고

      이와관련된 많은 질문들에 제가 항상 답변을 드리지만,

      실제 센서의 데이터를 단순히 적분한다는 것은
      많은 오차를 가지고 있습니다.
      실제 센서들이 가지는 노이즈, 오차등때문에
      이것이 적분되면서 꽤 많은 오차가 누적되기 때문입니다.

      결국, 아주 좋은 센서가 아니라면
      저가의 MEMS형은 결국 한 번의 적분만으로도 좋지 않은 결과가 나옵니다.

      그런데 가속도센서를 두 번이나 적분을 한다면, 그 결과는 뻔하지요.

      꽤 좋은 센서 0 바꿔 말하면 꽤 비싼 센서가 아니라면
      (혹은 비싸다고 하더라도, 결국 오차는 있습니다.)
      힘듭니다.

      그래서 많은 논문이나 자료를 보면, 아주아주 많은 필터에 대해 이야기를 합니다.

  12. 심희석 2013.07.08 08:41

    안녕하세요 , 전 유비쿼터스 센서 네트워크 하다가 궁금한게 있어서 그러는데요
    통신을 zigbee로 하고 가속도 센서를 BMA150 을 써서 가속도의 값을 측정하려고 하는데요
    날아오는 데이터 값이
    0d 1d 01 d5 01 32
    x y z 이렇게 각각 상위비트 하위비트로 나눠서 16진수로 오는데
    이를 가시적으로 확인 가능한 데이터로 바꾸려면 어떻게 해야할까요?

    • BlogIcon PinkWink 2013.07.08 14:50 신고

      정말 죄송합니다. 전 회로나 펌웨어 설계를 하는 엔지니어라 아니랍니다. 각각의 센서들에 대해서는 역시 해당 센서의 메뉴얼을 확인하는 것이 가장 좋을 듯합니다. 도움이 되지 못했네요...ㅠㅠ

  13. 루도군 2013.08.31 19:31

    안녕하세요 가속도와 자이로 센서를 공부하고 있는 학생입니다.
    자료를 찾다가 우연히 들렸는데요. 현재 하고 있는게 자동차에 3축 자이로 가속도 센서를 달아서
    조향각을 구하려고 하는데요. z축 회전각, yaw각을 구해야 되는데 위에 공식에 넣으면 세타에 아크탄젠트 y/x로
    하면 될까요? 실험 하신 내용이 x축을 기준으로 회전하신거 같아서요. ㅎㅎ

    • BlogIcon PinkWink 2013.08.31 20:35 신고

      조향각 즉, 위 글 기준으로 YAW 각을 얻고 싶다면, 하나의 센서가 더 필요합니다. 저가의 자이로라면 나머지 두 각도는 가속도센서와 함께 사용하면 되지만, YAW는 가속도센서로 보상할 수 없기 때문에 지자기 센서가 필요합니다.
      YAW, PITCH, ROLL을 모두 검출하기 위해 필요한것은
      3축 자이로
      3축 가속도
      3축 지자기 센서입니다.

  14. 이후창 2014.07.28 19:15

    안녕하세요. 항상 포스팅 하시는 글 잘 읽고 있습니다.
    가속도 센서로 기울기를 측정하려고 합니다.

    2가지 문의 사항에 대해서 글 기록합니다.

    1. 위에 그림에서 Theta를 atan(y/z)로 정의하셨는데요. g*sin(theta) = y 활용하면 변수가 하나면 되어서 더 용이할 것 같은데요, 혹시 특별히 atan를 사용하시는 이유가 있나요?

    2. 제가 제대로 이해했는지 모르겠는데요, 가속도 센서만으로 각도를 측정할 수 없는 것은 dynamic g에는 각속도가 함께 포함되어서 그런 것이지요? static g만 입력되는 경우는 가능한 것이 맞는지요?

    • BlogIcon PinkWink 2014.07.28 21:18 신고

      특별히 atan을 사용한 이유는 없습니다. 그냥 그 순간 그게 떠올랐을 뿐입니다.^^.
      그리고 크게 움직이지 않는 상황이라면 가속도 센서만으로 각도를 잡아도 됩니다만 그 "크게 움직이지 않는 상황"이라는 기준은 역시 실험해서 확인해보셔야할 듯 합니다.

  15. Sharn 2015.01.19 03:19

    안녕하세요. 궁금한 점이 있어서 글 남겨봅니다.

    가속도 센서로 기울기를 구하는 공식은 정지한 상태에서는 정확도가 높지만 이동중인 경우에는 선형가속도가 포함되기 때문에 에러가 증가하는 것으로 알고 있는데요.

    제가 알고 싶은 것은 선형가속도를 계산해낼수만 있다면 이를 보정할수 있다는 건데,, 여기저기 찾아본 결과

    일단은 가속도와 자이로를 결합해 나온 오일러각을 이용해서 선형가속도를 구할수 있다고 들었는데,, 혹시 관련 공식이나 관련 논문에 대해서 알고 계신것이 있나요?

    • BlogIcon PinkWink 2015.01.19 12:10 신고

      네.. 저도 한참 그때는 그걸 꽤 많이 공부했었는데요. 뭐 어느정도 하다가 중단했지만.ㅠㅠ. 그때 당시에는 각도를 구하는 것보다 더 어려웠습니다. 그리고 너무 오래되서 당시 자료는 기억이 나질 않네요.ㅠㅠ.

  16. Sharn 2015.01.21 21:55

    아.. 네 아쉽네요. ㅋ
    그래도 여기 블로그에서 많은 정보 얻어갑니다. 감사합니다^^

  17. 마정호 2015.01.23 03:13

    안녕하세요 요즘 세그웨이를 만들려고 공부하고 있는 한 공대 학생입니다.
    제대 하고 나름 열심히하는데 머리가 굳어서 그런지 여기 블로그에 있는 정보를 이해하는것도 벅차네요..
    atan(y/z)로 x축의 theta를 구한다는게 이해가 잘 안되네요 ...
    x축 의 theta는 xz평면에서 atan(x/z)를 이용해서 구할수도 있는거 아닌가요? 이해를 잘 못한건가..
    가속도 센서와 자이로 센서 테스트 하고있는데 각도추출이 잘 안돼서요...

    Sen.Accel_x.iqDegree =_IQmpy(_IQatan(_IQdiv(Sen.Accel_x.iqDegree,Sen.Accel_z.iqDegree)),_IQ(57.35));
    x축 센서값이랑 z축 센서값을 iir필터를 거친뒤에 atan를 이용해서 radian으로 표현하기위해서 iq를 곱했는데
    제가 뭔가 잘못알고있는듯 한데 알려주시면 감사하겠네요 ㅜ

    • BlogIcon PinkWink 2015.01.23 12:50 신고

      뭐.. 여하튼...
      x축 중심의 회전이 발생하면
      yz 평면이 x축을 중심으로 회전을 하며
      같은 방향으로 3축 가속도 센서를 설치했다면
      역시 동일하게 y축과 z축의 가속도 성분을 읽어서 삼각함수를 적용해야합니다.

  18. 이경헌 2015.01.23 23:09

    안녕하세요.. MMA7260Q 가속도센서로 각도값 추출하고 있는 사람입니다.
    글 정말 많이 도움되고 있습니다. 감사드려요!!!!
    제가.. 일단 소스를...
    g_iq17_filtered_val_x = g_iq17_LPF_outdata_x - g_iq17_offset_x;
    g_iq17_Volt_x = _IQmpy(_IQdiv(g_iq17_filtered_val_x, _IQ(4096)),_IQ(3.3)); ------------------------- ①
    g_iq17_angle_x = _IQdiv(_IQmpy(_IQatan(_IQdiv(g_iq17_Volt_y, g_iq17_Volt_z)), _IQ(180)), _IQ(3.14)); -----②
    g_iq17_angle_y = _IQdiv(_IQmpy(_IQatan(_IQdiv(g_iq17_Volt_x, g_iq17_Volt_z)), _IQ(180)), _IQ(3.14));
    이렇게 X,Y,Z축 값을 Volt값으로 받아서 atan를 써서 각도값을 받으려요 하는데요.. 정말 희한합니다.ㅠㅠ
    결과를 말씀드리자면 X축,Y축 각도값을 받아보면 평면상태일때 -90,90이 반복되면서 쓰레기값이 계속뜨고(막 떠요)
    -88? 88부터는 제대로 뜨더라구요.. 제 생각엔 -90 90이 겹처서 막 이상하게 뜨는거 같은데.. 이유를 모르겟어요..
    90도, -90도 기울이면 X축 = 46, -46값이 최대... Y축 = 20, -20이 최대입니다..
    위에 댓글을 보면 중력의 영향을 받지 않는 충의 중간값을 1.65라고 하고 빼주면 0도가 맞춰진다고하는데..
    무슨 말씀이신지 모르겟어요..
    1. ①② 식... 이해가 잘...안갑니다..ㅠㅠ
    2. 값이.. 이상하게 뜨네요....
    3. 그리고 기준전압값?을 뺴야 0도가 나온다고 하셧는데.. -0.002319 0.013191 이렇게 세세한 값을.. 어떻게 빼주죠..
    바쁘시더라도.. 한번만 도와주세요 ㅠㅠㅠ 정말... 3.4일전에 ADC값 잘받았는데.. 각도추출.. 남들은 쉽다고 하는데 어려워죽겟어요..ㅠㅠ 매일 밤새는데 ㅠㅠ

    • BlogIcon PinkWink 2015.01.25 09:56 신고

      제가 포스팅한 내용인데 질문을.. 하셨네요... 이 글에 있는 내용입니다만... 바이어스되는 수치를 기준 0으로 보아야하기 떄문에 그렇습니다. 결국 어디가 0인지를 알려고 하는 거지요. 그걸 빼는건 앞부분에 좀 기다렸다가 그 숫자를 항상 빼기도 합니다.
      그리고 atan 함수를 사용하셨다면... 90도 근방은 안됩니다. tan90도가 무한대거든요.

  19. robo 2015.03.19 14:58

    정말 잘읽었습니다. 많은 도움이 되었습니다. 한가지 여쭤볼 것이 있는데 지금 MPU 9150이라는 가속도센서와 자이로 센서가 결합된 센서를 사용하고 있는데 이 제품을 X축방향이나 Y축방향으로 회전시켜 나오는 데이터만으로도 가속도센서와 자이로 센서 구분이 가능할까요?

    • BlogIcon PinkWink 2015.03.19 19:58 신고

      음.. 가속도센서와 자이로센서의 결과를 모르시는 경우는 구분하기 쉽지 않을겁니다. 그런데.. 데이터 시트에 나와있을텐데요^^

  20. 봄날이왔네여 2015.04.01 19:39

    안녕하세요 핑크윙크님~
    잘보고 있습니다! 하다가 의문점이 들어 질문하나 하겠습니다. ㅠㅠ
    g_iq17_LPF_outdata_x = _IQ17mpy( _IQ(SEN_Kb), g_iq17_LPF_indata_x + g_iq17_acc_val_x ) - _IQ17mpy( _IQ(SEN_Ka), g_iq17_LPF_outdata_x );
    g_iq17_LPF_indata_x = g_iq17_acc_val_x;
    일단 이렇게 IIR 필터를 걸쳤구요..

    g_iq17_Volt_x = _IQmpy(_IQdiv(g_iq17_LPF_outdata_x, _IQ(4096)),_IQ(3.3)) - _IQ(1.494);
    g_iq17_Volt_z = _IQmpy(_IQdiv(g_iq17_LPF_outdata_z, _IQ(4096)),_IQ(3.3)) - _IQ(1.04);

    전압값으로 바꿔주고. [[ - _IQ(1.494) ]] [[ - _IQ(1.04) ]] 해준이유는 0으로 맞춰주기 위해서 빼준겁니다.

    g_iq17_angle_x = _IQdiv(_IQmpy(_IQatan(_IQdiv(g_iq17_Volt_x, g_iq17_Volt_z)), _IQ(180)), _IQ(3.14));

    이렇게 아크탄젠트를 이용해서 각도값을 받아봤습니다.
    수평상태일때는 -0.0985도 ~ 0도 ~ 0. 09091도 이렇게 거의 0도로 유지합니다.
    하지만 -88도 ~ 88도까지 기울이면 (-90,90일때는 무한대이기 떄문에 그전까지 해봤습니다.) 90도에 가까운 값이 떠야하는데 최대 -20도 ~ 20도까지 밖에 안뜹니다...
    상수를 더 곱해줘야하는지... 어떻게 해야할 지 잘 모르겠습니다.. ㅠㅠ

    • BlogIcon PinkWink 2015.04.01 22:11 신고

      네.... 일단 제 글을 읽으셨다니 감사합니다.
      그러나 위에분이 남기실 글과 같은 글로 보이는데...
      현재 질문하신 언어 문법 등을 저는 모릅니다.
      소스코드를 보여주고 계시지만... 저는 잘 모르겠네요ㅠㅠ
      IQ? JQ? ...
      아무튼... 도움을 드리지 못해 안타깝습니다.ㅠㅠ

    • 봄날이왔네여 2015.04.01 22:19

      g_iq17_angle_x = _IQdiv(_IQmpy(_IQatan(_IQdiv(g_iq17_filtered_val_x, g_iq17_filtered_val_z)), _IQ(180)), _IQ(3.14));
      이부분에서
      각도는 [ atan( x축 adc값 / z축 adc값 ) ] X 180 / 3.14를 해주는데
      180과 3.14는 어떻게 나온 값인지 잘모르겠습니다..
      그리고 위에 식으로 각도를 추출하면 20~ 0 ~ -20 까지 밖에 안나오나 X 500정도를 해주면 -85 ~ 0 ~ 85 정도도 뜨긴 하는데.. 이 상수값을 어떻게 맞춰줘야 할지 모르겠네요 ㅠㅠ

    • BlogIcon PinkWink 2015.04.02 14:48 신고

      아마 180과 3.14는 해당 각도를 보기 편하게 라디안에서 degree로 변환하는 것일겁니다.
      그리고 별도의 상수를 곱하는 것은 이해하기 어렵습니다.
      다시 한번 기초 데이터를 확인하면서 진행하셔야할 듯 합니다.
      그리고 소스에서는 알 수 없지만...
      z축과 x축 성분으로 구할 수 있는 것은 y축의 회전 각도입니다.
      만약 x축 회전각도를 알고 싶으시다면
      z축과 y축의 성분으로 계산하셔야합니다.

  21. 지나가는사람 2015.07.29 10:21

    PinkWink님 너무 친절하신거같아욥ㅋㅋ
    블로그 잘 보고 갑니다~