Category Archives: Mouse

Meet the New World’s Fastest Micromouse Robot

http://spectrum.ieee.org/automaton/robotics/diy/meet-the-new-worlds-fastest-micromouse

One year ago, we got super excited when a micromouse managed to negotiate a maze in under five seconds. At the 2011 All Japan Micromouse Robot Competition in Tsukuba, the micromouse pictured above shaved an entire second off of that time, completing the maze in a scant 3.921 seconds. That’s fast.

AVR Studio + WinAVR + Procyson Libray #2

AVR Studio + WinAVR + Procyon Library #2

 

이전에는 아주 간단한 C 소스를 AVR Studio 통합환경에서 컴파일하고 시뮬레이션까지 하는 예제를 보였다이제는 조금은 세밀한 부분을 살펴 보자 내용들은 WinAVR Makefile  내용들을 어떻게 수정하는가 하는 부분과 아주 밀접한 관계가 있다.

 

 

 

예제 1> 링커에서 필요한 라이브러리 추가 해주기..

Windows, DOS용의 컴파일러들은 내가 수학함수, (Square Root, sqrt())같은 함수를  , math.h 파일만 포함을 시키더라도 자동적으로 math library 찾아서 필요한 모듈들을 링크 시켜 준다다른 함수들의 경우도 라이브리들도 마찬가지이다하지만, WinAVR(gcc) 이런 작업을 자동으로  주지 않는다

이 과정을 살펴 보자.

 

위와 같은 프로젝트를 새로 만들고,

[Next] 버튼을 누르고, Debug Platform 을 AVR Simulator, Device를 ATMega128을 선택한다.

 

아래와 같은 프로그램을 작성하고

 

#include <stdio.h>

 int main(void)

{

                  int ii;

                  float aa, bb;

 

                  aa = 4.4;

                  bb= sqrt(aa);

                  return 0;

 }

 

이것을 컴파일 하면?? 몇몇 경고(warning)  개의 에러가 발생한다.

“undefined reference to ‘sqrt’

 

 

 에러는 math.h 헤더 파일을 포함시키지 않았기 때문에 발생한다그러면 #include<math.h>  추가하고 컴파일을  보자역시나 같은 에러가 발생한다..

“undefined reference to ‘sqrt’

 

그렇다면헤더를 포함시켰는데 같은 에러가 발생을 하다니.. 라고 생각을   있다하지만앞서 math.h 포함하지 않은 경우의 경고를 자세히 살펴 보면..

 

../sqrttest.c:9: warning: implicit declaration of function `sqrt’

 

라는 부분이 있다 부분에서 차이가 있는 것이다.  앞서 math.h 파일을 포함하지 않았을 때에는 함수의 형태를 선언(declaration) 하지 않았고이번에는 math.h 파일 안에서 함수의 형태가 저장이 되어 있으니 경고는 사라진 것이고마지막에 링크를 할려니 sqrt() 

수와 관련된 부분이 없다는 것이다.

 경우함수가 소스 형태가 아닌 라이브러리 형태로 되어 있는데이것은 c:\WinAVR\avr\lib\libm.a 파일이다확장명이 a  것은 linux 쪽에서 사용하는 방식이 그러려니 하고 넘어가자.. 아니다!  WinAVR에서는 라이브러리의 확장명이 a  되어 있다고 기억해 두자.. 나중에 써먹을 일이 있을지도 모른다.

 

배우 송광호씨도반칙왕에서 배운 두발차기를 나중에 살인의 추억(맞나??)에서  써먹었다고 하니아직은 젊고 머리가 좋을 아니 늙었더라도 한번은 기억을  보자..

 

.. 그러면 링크 과정에서 어떻게  라이브러리를 추가 하는가예전이라면 직접 Makefile 수정을 하겠지만이제는 AVR Studio 있으니 여기서 수정하는 방법을 알려 주겠다.

Makefile 아주  고칠  있다는 사람들은  글을 읽는 것을 여기서 중지 해도 된다 첫번째 예제의 목표가 이것인데아는 사람은  글을 읽는 시간도 아끼는 것이 좋지 않을까??  그리고 실수(float) 문자열로 바꾸는 예제가 예제 2번에 있으니 그걸 보고 싶다면 아래로.. ~~ 넘어가기 바란다.

 

 

 

프로젝트 윈도우용어는   없다.. 정확히 배우질 못해서..알게 되면 알려 주리라..)에서 프로젝트 이름의 옆에서 마우스 우측버튼(.. 본인은 예전 과다한 마우스 작업으로 오른쪽 어깨랑 목을 7주일 동안 거의 꼼짝을 못한 적이 있어서 현재 왼손으로 마우스를 쓰고 있기는 한데오른  잡이를 기준으로 설명하겠다.) 눌러서 팝업 메뉴가 뜨면,

 

거기서 [Edit Configuration Options…] 선택하고,

 

라이브러리 설정 창에서 libm.a  선택한 , [—->] 버튼을 눌러서 링크할 라이브러리에 추가를  준다. [확인] 누르고 다시 컴파일을 하기 전에  옵션이 과연 Makefile 어떻게 수정했는가를 잠시 살펴 보자.

현재 작업은 C:\WinAVR\my\4answer\sqrttest\ 디렉토리에서 하고 있으며소스파일과 hex파일도  디렉토리에 생겨난다그러나 Makfile C:\WinAVR\my\4answer\sqrttest\default 디렉토리에 있다현재 있는 Makefile  Makefile.default 라는 이름으로 카피를  놓고툴바에서 Build Active Configuration 버튼  누르자..  버튼의 그림은  설명서 시리즈 1번에 표시가 되어 있다. F7  눌러도 된다. libm.a 라이브러리를 추가하고  후라서 성공적으로 hex파일이 생겨난 것을   있을 것이다. Build 과정에서 생기는 프로그램의 실행과정을 살펴 보면,

 

avr-gcc -mmcu=atmega128  sqrttest.o   -lm  -o sqrttest.elf

 

라는 부분이 있다 여기서 –l 옵션은 링크할  필요한 라이브러리를 지정해 주는 옵션이고, m   libm.a 에서 m  의미한다이것은gcc 에서 사용하는 방법이니이렇게 한다 라고 기억을  두자..

 

그리고 나서 디렉토리에 있는 Makefile Makefile.default  비교해 보자.

 

 

왼쪽이 라이브러리 추가 하기 전이고오른쪽이 math 라이브러리를 추가한  이다 36~37번의 2개의 내용이 추가 되어 있음을   있다.

 

 

.. 하나의 예제를 통해서 라이브러리를 어떻게 추가하는  알아 보았다하지만  예제를 작성하면서 한가지 사실을  알게 되었다. #include<math.h>  제거 하더라도라이브러리 옵션만  잡아 주면 문제가 없다는 것이다. gcc 혼자서 libm.a  뒤져서 sqrt()함수를 찾는 다는 것이다물론 함수의 이름이 implicit하게 선언되었다는  경고(warning) 발생한다이렇게 사용하는 것이 가능은 하지만이렇게 하지 않도록 한다반드시 기존의 함수를 이용할 때에는 해당하는 헤더파일을 포함하도록 한다.  

 

잘못  습관 나중에 고생!!

 

이말을 기억하면서 말이다.

 

 

 이제 조금은  골치 아픈 예를 하나 살펴 보자.

 

예제 2>: 실수를 문자열로 바꾸는 예제를 이용해서 디버거도 써보자..

 

 문제는 예전에 본인이 실수(floating number) 문자열로 바꾸어서 LCD 표시하는 작업을 하다가 해결을 못해서 www.avrfreaks.net 에서 그 답을 찾은 것인데일단 프로그램을 다음과 같이 수정해 보자 

 

주의실수(by mistake) sqrt()  매개변수와 return 값을 double 아닌 float 했는데그림을 다시  캡쳐하는 것이 번거로워서 그냥 쓰기로 했다여러분들이 사용할  반드시 전부 double 하기 바란다.

 

#include <stdio.h>

#include <math.h>

int main(void)

{

                  int ii;

                  float aa, bb;

                  unsigned char ucBuffer[32];

 

                  aa = 4.4;

                  bb= sqrt(aa);

                 

                  sprintf(ucBuffer,”SQRT(4.4) =[%5.2f]”,bb);

                  return 0;

 

}

 

Build   보면  된다그렇다면 ucBuffer안을 어떻게 확인  것인가?? 이제 디버거를 사용해 보자!! 

 글을 읽는 사람들이 전부 같은 study board 가지고 있다면 소스를 거기에 맞게 작성하겠지만사용자 마다 하드웨어의 구성이 틀리고시리얼 포트를  것인지, LCD  것인지 모르니.. 이렇게 그냥 버퍼 szBuffer 문자열을 구성한   문자열을 확인  보는 것이다이렇게 하면 디버거 사용법도 익힐  있으니… 일거 양득이라고 생각을 하고예제를 만들었다.

 

프로그램 소스 중에서 return 0;  줄에 커서를 위치 시키고툴바에서 Build and Run 버튼을 누른다.

 

그러면 노란색 화살표가 main() 함수의 첫번째 줄에  있게 된다 그리고 return 0; 앞에 있는 짙은 갈색의 동그라미는 무시하기 바란다.. Break Point 인데 내가 설정을 해 놓기는 했지만, 설명을 하지 않을 것이기 때문이다.

 

디버거는 프로그램의 모든 과정을 따라   있는데 지금의 문제는 szBuffer 내용을 보는 것이므로좀전에 커서를 일부러 return 0;  위치시켜 놓았으므로, Run To Cursor (Ctrl+F10) 버튼을 누른다그러면 노란색 화살표가 return 0; 으로 옮겨 가게 된다 말은  화살표가 있는  까지 프로그램이 수행 되었다는 것이다.

 

 

 

 바에서 Toggle Watch Window  누른다변수들의 값을 보는(watch) 툴을 사용하겠다는 것이다.

 

 

 

그러면 하나의 독립된 창이 뜨게 되는데,

 

 

Name 란에 aa, bb, ucBuffer  입력한다. aa bb  초기의 값과 sqrt() 계산 결과이다.

 

그리고 aa  4.400001  되어 있는데이런 증세에 대해서는 machine epsilon이나 실수를 저장하는 포멧 IEEE-???  관계가 있는 것으로 알고 있는데 혹시 학문적으로 정확히 알고 있는 사람은 알려 주시기를 바란다.

 

우리가 지금 보고 싶은 것은 ucBuffer[32] 값(내용)이다 Watch 윈도에서 배열은 앞에 [+] 표시를  놓았으니 심볼을 클릭하면 내용을 보여 준다.

 

 

  내용이 프로그램에서 지정한 출력이 포멧 처럼,

SQRT(4.4) =[… 까지는 맞는데 계산 결과인 bb값을 %5.2f 포멧에 맞춰서 제대로 표현 못하고 있다다섯칸을 차지하면서 마지막에 ? 나온다만일 출력되는 실수(float) 길이를 포멧에서 정하지 않으면자동적으로 ?  나오게 된다.

 

 문제는 라이브러리 옵션과  함께 링크 옵션을 정해 줘야만 해결할  있다 

앞서의 1번의 예제에서와 같이, library 추가해 주면 되는데필요한 라이브러리는 libprintf_flt.a 이다.

 

또한

Custom Option에서

 

[Linker Options]  위와 같은 옵션을 넣어 준다.  이후 다시 시뮬레이션을  보면,

 

 

 

원하는 문자열을 얻을  있다사실  글을 적으면서도  링커 옵션에 대해서는 확실히 알아  수가 없었다내가 가지고 있는 “ATMega128 마스터”  1판에서도 이렇게 실수를 sprintf()함수를 이용해서 변환시키는 예제는 없는  같으며(모든 예제를 면밀히 살피지는 않았지만 …링커의 옵션에 대한 부분에서도 다루고 있지 않다.

그래서 그냥 쓰기로 했다.  사실 이렇게 그냥 쓰는 것에 대해선 나중에  부분과 관련되어 문제가 발생할 경우 해결을 못하는 경우가생긴다하지만 어쩔  없이 그냥 쓰자나중에 알게 되면 정리를 하기로 하고 말이다..

 

그리고  시뮬레이션을 통해서 디버그를 돌리면서  2가지의 예제에 대해서 작업을 하다 보니종종 에러가 발생을 한다.

하지만 이것은  예제에서 다루고자 하는 내용이 아니므로  문제의 해결은 하지 않고서 넘어가겠다.

 

 두가지의 예제를 통해서,

 

1> AVR Studio에서 Makefile  쉽게 수정하는 방법을 배웠고!

2> 디버거를 사용하는 것을 배웠고!

3> 실수(float number) 문자열로 변환할  필요한 라이브러리와 옵션들을 알아 보았다.!

 

 

To be continued?????  Still I don’t now …..  

AVR Studio + WINAVR 사용하기

AVR Studio + WINAVR 사용하기  

다운로드는 자료실에 올려져 있으므로 참고하시기 바랍니다.

상용컴파일러가 아닌 무료 컴파일러 및 통합환경 이며개발하는데 있어서 전혀 불편함을 감수하지 않아도 되는 훌륭한 조합으로 나타났습니다.

 

 

 

 

AVR Studio 4  실행하면 처음에 다음과 같은 다이얼 로그박스가 나타납니다.

만일 처음이 아니면 전에 만들어진 프로젝트들이 리스트에 나타나며 해당 프로젝트를 선택하면 됩니다.

처음이므로 New Project 버튼을 클릭합니다.

 

 

New Project 버튼을 누르면 다음과 같은 화면이 나오고 Location 을 눌러 프로젝트를 생성시킬 디렉토리를 선택한다음 프로젝트 명을 써 넣습니다.

프로젝트 이름에 맞게 디렉토리도 생성됩니다.

Create initial File check  하게 되면 프로젝트명에 해당하는 파일을 생성 해줍니다.

JTAG을 가지고 있다면 다음 버튼을없다면 Finish  눌러 프로젝트를 시작합니다.

 

 

 


AVR Studio 4 의 통합환경 이며startup.c 파일이 옵션에 따라 생성되어 있으며처음에는 빈화면이 나타납니다.

아래의 코드를 입력합니다.

 

 

#include <avr/io.h>

 

/*

#define outp(A, B) B = A

#define inp(A) A

*/

 

void delay_us(unsigned int us)

{

             unsigned int i;

 

             for(i = 0; i < us; i++){ // 4 cycle +

                           asm(“PUSH R0″); // 2 cycle +

                           asm(“POP R0″);  // 2 cycle +

                           asm(“PUSH R0″); // 2 cycle +

                           asm(“POP R0″);  // 2 cycle + =12 cycle for 11.0592MHZ

                           asm(“PUSH R0″); // 2 cycle +

                           asm(“POP R0″);  // 2 cycle = 16 cycle = 1us for 16MHz

             }

}

 

void delay_ms(unsigned int ms)

{

             unsigned int i;

 

             for(i = 0; i < ms; i++)

                           delay_us(1000);

}

 

int main(void)

{

    unsigned char LED, i;

 

    DDRB  = 0xFF; //set output

    PORTB = 0xFF;

 

    LED = 0xFE;

 

    while(1)

    {

 

        // left shift

                           for(i = 0; i < 7; i++)

        {

            PORTB = LED;

            LED = (LED << 1) | 1;

            delay_ms(1000); //1sec

        }

        // right shift

                           for(i = 0; i < 7; i++)

        {

            PORTB = LED;

            LED = (LED >> 1) | 0x80;

            delay_ms(1000); //1sec

        }

 

             }

}

 

위의 코드는 PB 에 LED 가 연결되있는 상태입니다.

코드에서 좀 어색한 부분이 outp 등의 함수가 보이지 않습니다.

AVR-GCC의 최근 버전들은 outpinp 등의 함수를 지원하지 않으며 직접 포트에 값을 입력하거나 읽어오는 방식으로 처리하고 있습니다.

과거에 outp 등의 함수를 많이 사용해서 변경하기가 귀찬다면

#define outp(A, B) B = A

#define inp(A) A

위의 함수처럼 지원하지 않는 함수를 매크로로 선언하여 사용하면 코드 변경없이 사용 가능합니다.

해당 소스는 LED가 좌우로 왔다 갔다 하는 소스 입니다.

시간 지연 함수는 인터넷에서 거의 표준(?)으로 사용하는 소스를 가져다 사용하였습니다.

16MHz 에서 정확히 시간은 맞지 않는 듯 합니다.

소스가 이해가 안 된다면

 


컴파일전에 해당 MCU  선택하거나 기타 옵션을 선택하여 주어야 합니다.

Project->Configuration Options 메뉴를 선택하면 다음과 같은 다이얼로그가 나타나며, Device를 선택하고 Create Hex File 을 선택하여 줍니다.

 

 

 

 

F7 키를 눌러 컴파일을 합니다.

아래쪽 영역에서 다음과 같은 메시지가 나타납니다.

에러나 경고가 나타나는 경우 Bullet 이 빨간색으로 나타나게 됩니다.

성공적으로 경고 없이 빌드되었다고 나왔습니다.

 

 

프로젝트를 생성시킨 디렉토리에 가면 default 라는 디렉토리가 나타나는데이부분은 컴파일 옵션을 각각 설정하여 옵션별로 디렉토리가 생성되어진 것입니다.

Default 안으로 들어가면 startup.hex 파일이 생성된 것이 보입니다.

 

 

 

PonyProg2000 등의 프로그래머로 HEX 파일을 다운로드 하면 동작하는것을 보게 됩니다.

위의 예제는 16MHz 로 동작하게 되어있으며, 16MHz 로 동작시키기 위해서는 Fuse bit 설정등을 하여야 하며 강좌란에 곧 올리겠습니다. 내부 클럭으로 동작하게 되는경우 깜빡이는 속도가 많이 늦게 됩니다…1MHz 로 동작한다면…16초마다 한번…^^;

 

이 문서는 코딩 및 컴파일의 과정이며, AVR Studio 호환이 되는 프로그래머를 가지고 있다면 AVR Studio 에서 hex 파일을 다운로드 할수 있고 JTAG 이 있으면 디버깅도 가능합니다.

 

감사합니다.