CAN(Controller Area Network) 프로토콜은 Bosch사에서 1986년 자동차 전장 용으로 처음 개발되었으며 1991년에 스펙 2.0이 발표되었고 현재 국제 표준 프로토콜로 성장하였습니다. 이는 호스트 컴퓨터 없이 3개 이상의 MCU나 controller, 장치들이 서로 다중 통신이 가능하며, 메시지는 우선순위 따라 ID(Identifier)를 할당하고 이 ID를 이용해 메시지를 구별합니다. 다양한 에러 감지 메커니즘이 상호 보완적으로 에러를 감지하기 때문에 높은 안정성을 보장하며, 메시지 전송 시 에러가 감지되면 자동적으로 해당 메시지를 즉시 재전송하는 기능이 있기 때문에 다른 프로토콜에 비해서 에러 회복 시간이 짧다는 것입니다.


차량에 적용하는 CAN 통신의 예제


버스가 유휴 상태인 경우 모든 CAN 노드는 메시지를 보낼 수 있고, 전송된 모든 메시지는 모든 노드에서 수신됩니다. 수신 노드는 ID 필터링 기준에 따라 메시지의 무시 여부를 판단합니다. 정교한 오류 감지 및 결함 격리 메커니즘과 문제가 발생한 메시지의 재전송으로 데이터 무결성과 일관성이 보장합니다. 또한 두 개 이상의 CAN 노드가 동시에 메시지 전송을 요청하는 경우 우선순위가 가장 높은 메시지가 즉시 버스 액세스 권한을 획득하도록 프로토콜이 보장합니다. 현재는 CAN의 안정성과 신뢰성 등 장점이 입증되어 항공기, 의료기 등에 사용되고 IoT application에서도 사용되는 추세입니다.


가장 쉽고 편리하고 익숙한 UART 통신은 별도의 transceiver가 필요없고 모든 MCU가 반드시 내장하게 됩니다. 그러나 보통 115200bps로 대략 10kbps로 느리며 한 바이트 통신이라는 단점이 있습니다. 예를 들어, 드론 제어를 할 경우에 다수의 센서 등과 같이 여러 바이트가 하나의 패킷이 되는 경우에는 패킷을 분리하는 작업이 용이하지 않다는 것입니다. 뿐만 아니라 UART는 하나의 장치와 두개의 선으로 독립적이야 하나 관성센서보드, 제어보드, 초음파센서보드, GPS, 무선통신만으로 5개를 초과하여 10가닥 이상이 필요하다는 것입니다.


CAN을 지원하는 MCU의 경우에는 한번에 8-byte 데이터를 전송하는 HW 패킷을 제공하므로 UART(보통 RS232/RS485) 통신에서는 패킷 통신을 위해 위에서 말한 것처럼 사용자가 일일이 패킷 형식을 만들어 주고 수신 받을 때도 그런 해석이 필요하지만 CAN은 8byte 데이터를 담는 HW 패킷 통신을 기본으로 함으로, 사용자는 데이터 버퍼에 데이터를 쓰고 전송만 하면 그 외 모든 처리는 하드웨어가 알아서 하므로 분산제어 분야 적용에도 용이하다는 것입니다.


CAN 통신의 특징:

1) 2선 twist pair를 이용한 전기적 differential 통신을 하므로 저가이며 전기적인 잡음에 매우 강해 신뢰성이 우수합니다.

2) 이론적으로 2,032개의 장치들을 연결할 수 있으나 CAN transceiver에 따라 최대 노드수(32, 64, 128...)는 달라 집니다.

3) 통신 버스를 공유하고 있는 CAN controller들은 모두가 마스터(master)가 될 수 있는 Multi-Master 통신을 합니다.

4) 40m 내에서 최대 1Mbps로 우수한 통신 속도를 갖습니다.

5) 8byte 데이터 전송을 하는 하드웨어 패킷을 제공합니다.

6) 다수의 MCU, DSP 등에 기본으로 내장되어 있습니다.

7) 통신 프로토콜/에러 처리를 하드웨어적으로 처리합니다.

8) PLUG & PLAY를 제공합니다.


CAN transceiver는 프레임이라는 패킷으로 CAN 네트워크에서 데이터를 전송하며, CAN 2.0B 버전 이후에 29bit 식별자를 갖는 extended data format의 간단한 설명입니다.



    • SOF(Start Of Frame) - 메시지 시작을 표시하며, 무부하 기간 이후 버스의 노드를 동기화하기 위해 사용

    • Identifier(ID, 식별자) - 메시지의 우선순위를 가리며 2진 값이 더욱 낮을수록 우선순위는 더욱 높아짐

    • RTR(Remote Transmission Request) - 원격 전송 요청 비트, 이 비트가 '0'이면 데이타 프레임이고, '1'이면 메세지가 원격 전송 요청을 의미

    • SRR(Substitute Remote Request) - 표준 프레임의 RTR 위치에 점유

    • IDE(IDentifier Extension) - 이 비트가 '0'이면 표준 CAN 식별자를 전송하고, '1'이면 확장 CAN 식별자를 전송을 의미

    • R0, R1 - 예약비트

    • DLC(Data Length Code) - 데이터 프레임의 데이터 바이트 수(0~8)

    • Data Field - 8byte(64bit) 전송 데이터, MSB부터 전송.

    • CRC(Cyclic Redundancy Check) - 16bit(15bit + 구획문자) 16bit checksum으로 오류 검출 Field.

    • ACK(ACKnowledge Field) - 2bit(1bit + 구획문자)로 오류가 없는 메시지가 전송되었다는 것을 나타냄.

    • EOF(End Of Frame Field) - 메세지(프레임) 종료 Field

    • IFS(Inter Frame Space) - 컨트롤러가 요구하는 시간의 양을 포함하며, 메시지 버퍼 영역에서 적절한 위치로 정확하게 수신된 프레임을 이동시킴


대표적인 CAN Transceiver로는 PCA82C250/C251가 있습니다.



'Flight Controller 이해 > 인터페이스' 카테고리의 다른 글

드론에서 사용되는 무선 통신  (1) 2017.03.09
TWI(I2C) 통신이란?  (0) 2014.03.24
Posted by Nature & Life


다음의 GitHub에서 bldc-tool의 소스 코드를 다운로드 합니다.

https://github.com/vedderb/bldc-tool


다음의 Qt 홈페이지에서 Qt 프로그램을 받기 위해서는 다음의 링크에서 'Get your open source package' 버튼을 클릭하여 installer 프로그램을 우선 다운로드 받아 실행시켜야 합니다.

Qt 다운로드


위 installer는 Qt 설치를 위해 필요한 콤포넌트를 설정하고 온라인으로 해당 패키지를 다운로드 하기 위한 프로그램으로 자신의 OS를 감지하여 받게 됩니다. 진행하다 보면 다운로드 하기 위한 콤포넌트를 설정하는 화면에서 아래와 같이 설정하고 진행하면 됩니다.



위 설정에서 버젼은 다른 버젼을 사용해도 무방할 것으로 생각되지만 필자는 용량의 이유로 위와 같은 컴포넌트만을 받기로 하였습니다. 필자는 Windows 10(32-bit) 환경입니다. 여기서 MinGW라는 것이 있는데 Qt는 cross platform으로 OS에 무관하며 컴파일러(예를 들어 g++, gdb, make) 등을 Linux 정신에 맞게 GNU를 사용합니다. 이를 Windows 환경에서도 사용할 수 있도록 만든 것이 MinGW이고 'Minimalist GNU for Windows'의 약자입니다. 참고로 64bit라 하여도 위 설정에서처럼 32bit를 사용해야 하며 반드시 설치하여야 합니다.


설치 후 Qt Creator를 실행시키고 메인 화면에서 'Open Project'를 클릭하여 다운로드 한 bldc-tool 폴더 내에 'BLDC_Tool.pro'를 선택하여 로드합니다. 다음은 'Tools' 메뉴에 'Options' 메뉴를 클릭합니다. 좌측 메뉴에서 'Build & Run'을 클릭하고 우측에서 'Qt versions', 'Compilers', 'Debuggers'를 아래와 같이 순차적으로 수정합니다.



위 화면에서와 같이 Qt와 MinGW가 정상적으로 설치되었다면 자동 감지(Auto-detected)되지만 그렇지 않은 경우 'Add' 메뉴로 일일이 각각 설정해 주어야 합니다. 그리고 위 화면에서 'Kits' 탭으로 이동하면 다음과 같은 화면을 볼 수 있습니다.



모든 것이 정상적이면 위와 같이 설정되고 그렇지 않으면 각 항에서 'Manage' 버튼으로 직접 수정해 주어야 합니다. 마지막으로 로드된 프로젝트 메인 화면 좌측 'Projects'를 클릭하고 빌드시 생성되는 파일들의 위치 정도를 설정해 주면 됩니다.



메인 화면의 'Build' 메뉴에서 빌드('Build All')하면 debug 폴터에 BLDC-Tool.exe 실행파일이 생성되고 'Build' 메뉴의 'Run'으로 실행시키면 됩니다. debug 폴더에서 실행 파일을 직접 클릭하여 실행시킬 수도 있는데 이 경우에는 *.dll 파일이 없다는 오류가 발생하는데 이는 정적(static)으로 빌드하였기 때문으로 배포시에 동적(dynamic) 빌드하면 해결됩니다.



Posted by Nature & Life
Software Programming/Qt2017. 12. 24. 16:05


임베디드(Embedded) 시스템을 제어하거나 테스트하기 위한 프로그램 개발에는 여러 프로그램들이 사용되어질 수 있습니다. 예를 들어 Windows 환경에서 API나 MFC를 이용하여 개발한 경우, Linux와 같은 다른 환경에서 사용하기 위해서는 다시 그 환경에 맞는 툴을 사용하여 다시 제작하여야 합니다. 그러나 Qt는 cross platform으로 Unix, Linux 그리고 Windows, MAC OS X 등등 다양한 platform과 iOS나 Android 조차에서도 다시 컴파일하면 하면 된다는 것입니다.


역사적으로 Qt는 1995년 최초 버전이 공식 배포 되었고 이후 20년간 Qt는 산업 흐름에 맞추어 기능이 확장되고 성능이 개선되어 왔으며, 해당 기간 동안 전세계 1백만명이 넘는 개발자들에 의해서 검증된 안정적이고 성숙된 제품이 되었습니다. 현재 Qt 는 GUI 개발과 더불어 응용 프로그램 개발 전반을 커버하는 1,300여개의 풍부한 라이브러리들과 다양한 개발 도구를 갖춘 종합적인 개발 프레임워크 제품으로 완성되었다고 알려집니다.



기존의 개발 환경에서는 '볼륨' 버튼도 직접 제작하거나 별도의 라이브러리를 구입해야 하지만, Qt에서는 고급스러운 GUI 환경을 덕택에 가져다 쓰면 되고 상업적인 목적이 아닌 이상 소스 코드 채 배포되며 무료이면서 어떤 제한도 없다는 것입니다. 예를 들어, Qt만의 전통적이며 강력한 GUI 개발 기능은 Qt Widget으로부터 새롭게 지원되고 있는 Qt 자체의 GUI 개발용 스크립트 언어인 Qt Quick/QML로 이어졌고, QML을 이용하면 기존의 MFC 등의 개발 도구로는 구현이 매우 어려운 에니메이션이나 3D 인터페이스와 같은 자연스러운 그래픽 효과들도 쉽고 빠르게 구현할 수 있다는 것입니다.


뿐만 아니라, 프로그램 개발에 필수적인 멀티 스레드 프로세스 통신, 네트워크, OpenGL의 3D 그래픽, HTML5 지원 통합 웹엔진, XML 데이터베이스 등 C++ 개발자가 개발 중에 필요한 요구 사항도 다양한 라이브러리에 모듈형식으로 기능별로 제공한다는 것입니다. 또한 스마트폰과 태블릿 환경에서 요구되는 기존의 물리적 버튼과 원시적인 액정 스크린이 아닌 스마트폰과 같은 터치 패널 디스플레이 탑재와 고급스럽고 풍부한 표현을 가진 UI/HMI를 총망라 하고 있다는 것입니다.


Qt 에서는 'Qt Creator' 라는 통합 IDE 환경을 이용하여 코드를 작성하게 하며 GUI 화면을 직접 디자인하고 이를 개발코드와 직접 연결시킬 수 있는 'Qt Designer', GUI 개발을 편리하게 해주는 Qt 자체의 스크립트 언어인 'QML'과 UI 개발을 할 수 있는 'Qt Quick(Qt User Interface Creation Kit', Qt로 제작된 GUI 화면의 상세한 리소스 프로파일링이 가능한 'Qt Quick Profiler', Qt 라이브러리에 대한 상세한 도움말 문서인 'Qt Assistant'를 포함합니다. 또한 Visual Stuido나 Eclipse등 친숙한 개발 환경에서도 플러그인 하여 이용할 수도 있다는 것입니다.



Qt는 C++을 기반으로 하여 주로 C++을 사용하지만, 파이썬(Python), 루비(Ruby), C, 펄(Perl), 파스칼(Pascal)과도 연동됩니다. C 보다 C++을 사용할 경우 확장이 용이하다는 장점이 있습니다. 그러므로 클래스(class) 등의 C++의 기본 개념 지식이 먼저 요구됩니다.


https://www.qt.io/



'Software Programming > Qt' 카테고리의 다른 글

UART(Serial) 통신 예제  (2) 2018.03.03
Hello world 예제  (0) 2018.03.02
Posted by Nature & Life


VESC 하드웨어(v4.8)의 회로도 입니다.

https://github.com/vedderb/bldc-hardware






Posted by Nature & Life
Embedded Programming/ChibiOS2017. 12. 19. 19:29


http://www.playembedded.org/blog/en/2017/08/24/demos-chibios-stm32/

http://www.playembedded.org/blog/en/2016/10/29/explanation-multithreading-chibios/


Cortex-M4 MCU(ST32F4)를 환경에서 Real Time OS(RTOS)인 ChibiOS를 이용한 임베디드(embedded) 시스템의 코딩의 예제입니다. 참고하시기 바랍니다.

 

주요 헤더 파일입니다.

chconf.h

Kernel에 관련된 세팅이 포함되며 예를 들어 시스템 Timer와 Kernel 파라미터, 디버깅에 연관된 스위치 등입니다.

/*===========================================================================*/
/**
* @name Debug options
* @{
*/
/*===========================================================================*/
 
/**
* @brief   Debug option, kernel statistics.
*
* @note    The default is @p FALSE.
*/
#define CH_DBG_STATISTICS                   FALSE
 
/**
* @brief   Debug option, system state check.
* @details If enabled the correct call protocol for system APIs is checked
*          at runtime.
*
* @note    The default is @p FALSE.
*/
#define CH_DBG_SYSTEM_STATE_CHECK           FALSE
 
/**
* @brief   Debug option, parameters checks.
* @details If enabled then the checks on the API functions input
*          parameters are activated.
*
* @note    The default is @p FALSE.
*/
#define CH_DBG_ENABLE_CHECKS                FALSE
 
/**
* @brief   Debug option, consistency checks.
* @details If enabled then all the assertions in the kernel code are
*          activated. This includes consistency checks inside the kernel,
*          runtime anomalies and port-defined checks.
*
* @note    The default is @p FALSE.
*/
#define CH_DBG_ENABLE_ASSERTS               FALSE
 
/**
* @brief   Debug option, trace buffer.
* @details If enabled then the trace buffer is activated.
*
* @note    The default is @p CH_DBG_TRACE_MASK_DISABLED.
*/
#define CH_DBG_TRACE_MASK                   CH_DBG_TRACE_MASK_DISABLED
 
/**
* @brief   Trace buffer entries.
* @note    The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is
*          different from @p CH_DBG_TRACE_MASK_DISABLED.
*/
#define CH_DBG_TRACE_BUFFER_SIZE            128
 
/**
* @brief   Debug option, stack checks.
* @details If enabled then a runtime stack check is performed.
*
* @note    The default is @p FALSE.
* @note    The stack check is performed in a architecture/port dependent way.
*          It may not be implemented or some ports.
* @note    The default failure mode is to halt the system with the global
*          @p panic_msg variable set to @p NULL.
*/
#define CH_DBG_ENABLE_STACK_CHECK           FALSE
 
/**
* @brief   Debug option, stacks initialization.
* @details If enabled then the threads working area is filled with a byte
*          value when a thread is created. This can be useful for the
*          runtime measurement of the used stack.
*
* @note    The default is @p FALSE.
*/
#define CH_DBG_FILL_THREADS                 FALSE
 
/**
* @brief   Debug option, threads profiling.
* @details If enabled then a field is added to the @p thread_t structure that
*          counts the system ticks occurred while executing the thread.
*
* @note    The default is @p FALSE.
* @note    This debug option is not currently compatible with the
*          tickless mode.
*/
#define CH_DBG_THREADS_PROFILING            FALSE
 

/** @} */


halconf.h

ChibiOS/HAL 드라이버에 관련된 특성을 포함합니다. 예를 들어, PAL, CAN, ADC, DAC, PWM, Serial 드라이버 등이 해당됩니다. 참고로 사용하지 않는 드라이버는 disable 시켜야 합니다.


/**
* @brief   Enables the PAL subsystem.
*/
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
#define HAL_USE_PAL                 TRUE
#endif
 
/**
* @brief   Enables the ADC subsystem.
*/
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
#define HAL_USE_ADC                 FALSE
#endif
 
/**
* @brief   Enables the CAN subsystem.
*/
#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
#define HAL_USE_CAN                 TRUE
#endif
 
/**
* @brief   Enables the DAC subsystem.
*/
#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
#define HAL_USE_DAC                 FALSE

#endif


mcuconf.h

MCU에 관련된 모든 설정을 포함합니다. 따라서 MCU에 따라 다릅니다. Clock 트리, DMA, IRQ 우선순위 등이 예입니다.


ChibiOS의 가장 중요한 특성 중의 하나는 멀티스레딩(multi-threading)입니다. 이는 Kernel이 한가지 이상의 스레드를 독립적으로 나란히 동시에 실행하는 것입니다. 스레드는 실제의 함수이고 시작되었을 때 우선순위 레벨(priority level)과 working area에 연관됩니다. Working area는 스레드에 할당된 메모리의 부분이고 우선 순위는 상대적인 숫자로 나타냅니다.


모든 스레드는 그 루프 내에 sleep과 suspending 함수를 가져야 합니다. 이런 방식으로 CPU의 소유권은 여러 스레드 사이에서 스위치 되고 스케쥴은 진행될 수 있습니다. ChibiOS는 다른 sleep 함수를 제공합니다. 다음 함수는 XXX [ms] 시간 동안 스레드를 suspending 합니다. 이 함수는 ChibiOS 이하의 os\rt\include\chthreads.h에 선언되어 있습니다.


chThdSleepMilliseconds(<xxx>);


Makefile

Embitz와 같은 IDE 환경을 사용시 일일이 지정해야 하고 IDE 툴마다 다를 수 있지만, 전통적인 Unix 환경에서 Makefile을 이용한 방법이 일목요연하고 유지관리가 용이하기 때문에 Makefile을 이용한 빌드 기준으로 설명합니다.


ChibiOS를 사용하기 위해서는 ChibiOS가 설치된 상대 경로의 지정이 필요합니다. 

# Imported source files and paths
PROJECT = build
CHIBIOS = ../../..
MCU = cortex-m4
TRGT = arm-none-eabi-


참고로 'build'는 프로젝트 이름이며 MCU는 cortex-m4이고 TRGT는 GNU Toolchain을 사용함을 의미합니다.

main.c

static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {
 
  (void)arg;
  chRegSetThreadName("Thread1");
  while (true) {
    palTogglePad(GPIOA, GPIOA_LED_GREEN);
    chThdSleepMilliseconds(200);
  }
}
 
int main(void) {
  halInit();
  chSysInit();
 
  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO + 1, Thread1, NULL);
  while (true) {
    palTogglePad(GPIOA, GPIOA_LED_RED);
    chThdSleepMilliseconds(375);
  }

}


위의 예제에서 128byte의 크기를 갖는 waThread1라는 이름의 working area를 선언하고 Thread1이라는 함수를 선언합니다. 위의 두 라인은 단지 메모리와 함수를 선언한 것이며 main() 함수에서 thread 생성을 시켜야 사용할 수 있습니다. THE_FUNCTION의 arg는 함수 내부 코드로 전달되는 인자입니다.


chRegSetThreadName("blinker");


위 함수는 루프 이전에 단 한번 실행됩니다. 이 함수는 ChibiOS 이하의 os\rt\include\chregistry.h에 선언되어 있습니다.



main()함수 내의 2가지 함수가 실행되는데 이는 시스템 초기화를 실행하는 것으로, hallnit()는 ChibiOS/HAL과 HAL 서브 시스템을 초기화 하는 것이며 chSysInit()는 ChibiOS/RT의 API와 Kernel을 초기화합니다. 이후에는 main() 함수의 스레드와 다른 모든 스레드가 실행될 준비가 되지 않았을 때 실행되는 idle 스레드가 생성됩니다. 또한 이들 초기화 이전에 어떤 API의 실행은 하지 말아야 합니다. ChibiOS/RT 그리고 ChibiOS/HAL에 근거한 모든 프로그램은 위와 동일한 방식으로 시작합니다. 여기서 halInit() 함수는 ChibiOS 이하의 os\hal\include\hal.h에 그리고 chSysInit() 함수는 ChibiOS 이하의 os\rt\include\chsys.h에 선언되어 있습니다.


palTogglePad() 함수는 ChibiOS 이하의 os\hal\include\hal_pal.h에 선언되어 있으며, 첫번째 인자는 포트이고 두번째 인자는 그 포트 내에서의 패드 숫자입니다. 따라서 이 함수는 해당 포트의 해당 패드에 그 논리적인 상태 즉, LED를 토글(toggle)합니다.



chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO + 1, Thread1, NULL);


위의 스레드의 생성 함수는 5개의 인자가 필요하며 첫번째는 working area의 포인트이며 마지막 인자는 Thread1 함수로 전달될 파라미터로 이 경우에는 아무것도 보내지 않습니다. 이 함수는 ChibiOS 이하의 os\rt\include\chthreads.h에 선언되어 있습니다.


이 경우에 3개의 스레드인, Thead1, main, idle가 있으며 즉, Kernel은 3가지 스레드를 관리게 되는데 개념적인 timing 플로우는 다음과 같습니다.



위 그림에서 스레드는 y축 상에 우선순위에 따라 실행되고 x축은 시간이 됩니다. chSysInit()이 실행될 때 main() 함수는 main이라는 스레드가 되고 Thread1의 생성될 때까지 실행됩니다. Thread1이 생성된 후에는 main와 Thread1이 준비된 상태가 됩니다. 


ChibiOS의 우선순위는 정수이고 LOWPRIO와 HIGHPRIO의 범위를 가지며 main 스레드는 NORMALPRIO의 우선 순위를 가지며 전체 범위의 중간 값을 가집니다. Thread1과 main() 함수 내에 chThdSleepMilliseconds() 함수는 시간을 지연시키지만 그 동안 CPU의 소유권을 다음의 우선순위 스레드에 넘기게 됩니다.



'Embedded Programming > ChibiOS' 카테고리의 다른 글

ChibiOS/RT 설치  (1) 2018.02.25
ChibiOS/RT의 특징  (0) 2018.02.25
Posted by Nature & Life


비교적 무거운 환경인 ChibiStudio 혹은 Eclipse IDE나 제한이 많은 Keil, IAR 등의 상용 IDE를 사용하지 않고 Windows 환경에서 무료로 사용할 수 있는 Embitz 환경으로, 오픈 소스 RTOS인 ChibiOS를 사용한 VESC 펌웨어의 컴파일 방법입니다. 참고로 Embitz는 emblocks의 새로운 이름입니다.


VESC firmware compile step for Embitz v1.11


VESC firmware : https://github.com/vedderb/bldc

Embitz : https://www.embitz.org/

Msys : http://downloads.sourceforge.net/mingw/MSYS-1.0.11.exe


1. Settings->Tools... , Toolchain executables , additional paths.

- enter path to Msys/bin

1. 'Tools' 메뉴의 'Toolchain executables' 탭을 클릭하고 'additional paths' 눌러 Msys/bin 경로를 찾아 추가합니다. 여기서 Msys를 설치하지 않으며 'make.exe'파일을 이용할 수 없게 됩니다.


2. Create new project.

- choose Empty template

- name project title as 'BLDC_4_ChibiOS', will make things easier.

- untick debug checkbox

- change create release configuration to 'upload'

- change ouput dir to 'build\'

- change objects output dir to 'build\obj\'

2. 'new project'를 생성합니다.

- 'Empty template' 를 선택합니다

- 'project title'을 'BLDC_4_ChibiOS'으로 입력하는데 이는 makefile에 이미 정의된 것으로 후에 생길 오류들을 없애기 위함입니다.

- 'debug checkbox'를 체크 해제합니다

- 'release'대신 'upload' 폴더로 생성하도록 'release'를 'upload'로 변경합니다

- 'output dir'를 'build\'로 변경합니다

- 'objects output dir'를 'build\obj\'로 변경합니다


3. copy all files from bldc-master to BLDC_4_ChibiOS

3. github에서 다운로드하여 압축해제 한 'bldc-master' 폴더 내에 모든 파일을 새롭게 생성된 'BLDC_4_ChibiOS' 폴더 안으로 복사합니다


4. right click on your project choose 'add files recursivly'

- choose folder 'BLDC_4_ChibiOS'

4. project를 오른쪽 클릭하여 'add files recursivly'를 선택합니다.

- 'BLDC_4_ChibiOS' 폴더를 선택합니다


5. right click on your project choose 'properties'

- check checkbox 'this is a custom Makefile'

5. project를 오른쪽 클릭하여 'properties'를 선택합니다.

- 'this is a custom Makefile'의 체크 박스를 체크합니다. 즉 기존의 makefile를 사용함을 의미합니다.


6. Build target

6. Build target을 클릭하여 컴파일 합니다.


7. Clean target을 클릭하여 생성된 파일을 삭제할 수 있는데 삭제되지 않으면, 'Project'의 'Build options' 메뉴를 클릭하여 '"Make commands' 탭을 선택하고 'Clean project/target'란 '$make -f $makefile clean $target'라는 정보가 올바로 입력되어 있는지 확인합니다.


during build there is no response or status.

컴파일하는 동안에 어떤 응답이나 상태를 보이지는 않습니다.


제 경우에는 15분 26초 정도 걸렸습니다.

Intel Atom CPU Z3735F @1.33GHz / 2GB 메모리 / Windows 10 Home(32bit)



VESC는 Unix 환경에서 작성되어 비록 Windows 환경에서 Embitz IDE를 사용하더라도 Compile과 Link에 사용되는 Toolchain과 Makefile을 사용하기 때문에 Unix 기반의 'make.exe', 'rm.exe' 등이 포함된 [Msys와 같은] Build 유틸이 설치되어야 합니다. GNU ARM Embedded Toolchain과 Debugger로는 오픈 소스인 OpenOCD를 사용합니다.



'Flight Controller 이해 > 전자속도제어기(ESC)' 카테고리의 다른 글

Qt에서 bldc-tool 컴파일 방법  (0) 2017.12.24
VESC 하드웨어(v4.8) 회로도  (0) 2017.12.21
VESC - Open Source ESC(4)  (0) 2017.11.09
VESC - Open Source ESC(3)  (0) 2017.11.04
VESC - Open Source ESC(2)  (0) 2017.11.04
Posted by Nature & Life


임베디드(Embedded)나 펌웨어 궁극적으로는 둘다 작은 시스템 내에 하드웨어 제어를 위해 EEPROM 등에 기록되는 일종의 프로그램입니다. 거의 같다라고 봐도 무방합니다. 하지만 근래 들어서 시스템의 복잡화로 인해 기존의 펌웨어를 제작할 때 사용되는 프로그래밍 방식 '슈퍼루프 방식'은 프로그래머의 체계적인 프로그램 설계와 짜임세 있는 구성이 프로그래머를 피곤하게 할 만큼 복잡하게 되었습니다.


이에 대한 대안으로서 나온 것이 RTOS(Real Time OS)라는 것인데 ROM에 기록되는 펌웨어 중에서도 특히 이런 RTOS를 이용한 것을 임베디드(내장형 시스템)라 칭하는 경우가 많습니다. RTOS를 사용하게 되면 ROM에 기록되어야 할 펌웨어의 크기가 커지고, 시스템 오버해드라 하여 불필요한 부하를 가져다 주게 됩니다. 하지만, 펌웨어 개발의 융통성과, 안정성, 정확성을 고려할 때 펌웨어의 크기나 시스템 오버해드는 충분이 무시할 수 있는 요소가 된다는 것입니다.


대표적인 RTOS인 ChibiOS


RTOS를 이용한 임베디드 시스템은 꼭 ARM같이 거대한 프로세서에만 사용되는 것은 아닙니다. 상당히 유명한 uCOS-II경우 구식 8051부터 Intel 32bit까지 다양한 플랫폼을 지원합니다. 8051계열에도 얼마든지 임베디드 시스템을 펌웨어로 올릴 수 있습니다.


펌웨어는 일반적으로 롬(ROM)에 저장된 하드웨어를 제어하는 마이크로 프로그램을 의미합니다. 프로그램이라는 관점에서는 소프트웨어와 동일하지만 하드웨어와 밀접한 관계를 가지고 있다는 점에서 일반 응용 소프트웨어와 구분되어 펌웨어는 소프트웨어와 하드웨어의 특성을 모두 가지고 있다고 할 수 있습니다.


예를 들어 어떤 기능을 발휘하는 하드웨어를 만든다고 할 때, 그것을 제어하는 모든 회로를 하드웨어로만 만들면, 그 구조도 대단히 복잡해지고 심지어는 논리적인 표현을 하기가 어려운 부분도 발생합니다. 이런 경우 상당부분을 소프트웨어로 대체하되 그 소프트웨어가 저장된 기억장치를 하드웨어의 제어회로 중의 중심부분으로 구성하면, 매우 간단하면서도 적은 비용으로 문제를 해결할 수 있게 됩니다. 이렇게 만든 하드웨어적인 소프트웨어를 펌웨어라 합니다.


이렇게 할 경우 하드웨어의 입장에서는 별도의 논리회로를 가진 것이 아니기 때문에 소프트웨어적인 특성을 가지고 있지만, 소프트웨어 입장에서는 마이크로 프로그램이 하드웨어를 제어하기 때문에 하드웨어적인 특성을 가진다고 설명할 수 있습니다.


소프트웨어의 기능을 펌웨어로 변경할 수 있으면 속도가 현저하게 증대되어 고속 처리가 필요한 프로그램은 펌웨어로 만들어 사용하기도 합니다. 또한 하드웨어의 기능을 펌웨어로 변경하면 속도는 느려지지만, 그 기능을 위한 논리회로를 설계하여 사용하는 것보다 저렴하고, 편리하게 구현하여 사용할 수 있는 장점을 가지기도 한다는 것입니다.




'Embedded Programming > Environment' 카테고리의 다른 글

왜 RTOS가 필요한가?  (0) 2018.01.31
Posted by Nature & Life


가속도계(Accelerometer)는 움직임이 있을 때마다 값이 튈 수 밖에 없는데 이는 움직임에 따른 가속도와 중력가속도가 합해져 마치 중력가속도 방향이 변한 것처럼 보이기 때문입니다. 이러한 고주파 잡음을 제거하기 위해서는 저역 통과필터(Low pass filter; LPF)를 사용해야 합니다. 반면에 자이로(Gyroscope)는 잡음이 긴 시간에 대해서 누적(적분)되어 드리프트(혹은 바이어스)되므로 짧은 시간인 고역 통과필터(High pass filter; HPF)를 사용해야 합니다. 이러한 아이디어를 구체화한 것이 아래의 블록선도와 같으며 이를 IMU(Inertia Measurement Unit) 데이터를 융합하는데 가장 간단한 방법인 보상필터(Complementary filter) 혹은 상보필러라 부릅니다.




여기서 과 는 각각 1차 저역 통과필터, 1차 고역 통과필터로 그 합은 안정성의 문제로 '1'이 성립되어야만 합니다. 2차 필터도 구현할 수 있지만 편의상 1차 필터로만 제한합니다. 위 그림으로부터 수식을 정리하면 다음과 같습니다.



여기서 는 차단주파수(cut off frequency)를 결정합니다. 위 식을 정리하면 다음과 같습니다.



위 수식으로 블록선도를 다시 그리면 다음과 같습니다.



위 수식을 MCU로 처리하기 위해서는 연속시간에 대한 이산화가 필요하고 하드웨어 상에 아날로그 혹은 디지털 필터(예를 들어 IIR, FIR 등)를 사용하지 않는 이상 코드로 구현해야 합니다. MCU 성능 개선으로 외장 디지털 필터나 디지털 필터 알고리즘을 사용하지 않고 수식을 이산화하여 구현하였습니다.


동일한 연속 시간 전달 함수(continous time transfer function) G(s)를 이산화하는 방법에는 여러가지가 있으며 안정도와 고주파 잡음 등과 같은 성능이 동일하지는 않습니다. 전형적으로 연속 시간 전달 함수(continous time transfer function) G(s)를 이산(불연속 시간 전달 함수(discrete time transfer function) H(z)로 변환하는 방법은 전형적으로 다음과 같은 방법이 있습니다.


1) 후방 차분법(backward difference) : 

2) Bilinear transformation, expansion of ln(z) : 

3) Impulse invariance transformation : 


가장 기본적인 후방 차분법(backward difference)을 적용하면 이므로 이를 대입하여 다시 정리하면 추정 각도 는 다음과 같이 나타낼 수 있습니다.



여기서 편의상 가속계인 accelerometer의 첫글자 , 자이로 측정치로부터의 각속도(rotation rate)라 놓았습니다.


위 식에 z 변환인 은 이산 시스템에서 이므로 위 식을 이산 신호 시스템으로 변경하면 다음과 같습니다. 다른 말로 는 단위 시간 지연(unit time delay)과도 같기 때문입니다.



위 식에서 이면 다음과 같습니다.



정성적으로 위 수식에서 만일 가속도계에 측정치가 튄다면 즉, 고주파 잡음이 들어갔다면, 0.01이 곱하여져 새로운 각도가 계산됩니다. 그러나 0.01이 곱하여지므로 기여도는 작아 각도는 프로그램 루프(loop)가 상당히 반복되어도 매우 천천히 증가하게 됩니다. 이는 가속도계 입력이 추정 각도 계산에 실시간으로 반영되기 어렵고 이는 출력이 반응하지 않는다는 의미로 고주파 잡음은 제거되고 서서히 증감되는 저주파 측정치만 반영되게 된다는 의미입니다.


는 weight factor라 부르며 통상 0.95~0.98 범위의 값을 사용합니다.



Appendix A.


Reference:

http://d1.amobbs.com/bbs_upload782111/files_44/ourdev_665531S2JZG6.pdf

http://www.olliw.eu/2013/imu-data-fusing/#chapter21

http://www.dummies.com/education/science/signals-and-systems-working-with-transform-theorems-and-pairs/(z-transform)




Posted by Nature & Life


MPU6050 센서는 가속도계(Accelerometer)와 자이로(Gyroscope)가 1개의 칩에 모두 포함하고 있는 6DOF(Degrees of Freedom) MEMS(Micro Electro Mechanical Systems) 센서로, I2C(Inter Integrated Circuit) 통신 프로토콜을 통해서 데이터를 가져올 수 있습니다. 다음은 MPU6050의 메뉴얼입니다.


http://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf



MPU6050의 특징입니다.

      • 3-axis Accel + 3-axis Gyroscope DMP(Digital Motion Processor)

      • ±1% Temperature Sensor( Digital output )

      • 7개의 16bit ADC를 내장하여 16bit 정교한 기울기 출력

      • ±250,±500,±1000,±2000(˚/sec) dps 자이로, ±2,±4,±8,±16g 가속도 (User programable)

      • 1024byte fifo buffer

      • I2C 400KHz

      • Programable Interrupts

      • High-G Interrupts

      • VDD: 2.375V ~ 3.46V

      • Gyroscope Operating current 3.6mA( Standby 5uA )

      • Accelerometer Operating current 500uA( Low Power mode 10uA~ )

      • Programable Low-Pass Filter

      • -40℃ ~ +85℃ (TA 25℃ )

      • StartUp time 30msec

      • Self Test

      • I2C Address : 0x68 ( except R/W 0x1 )

      • I2C Master or Slave

      • Auxiliary I2C bus for communicating to an off-chip 3-Axis digital output magnetometer(지자계 센서) or other sensors.


MPU6050은 24pin QFN 패키지로 내부 timing generator를 사용하지 않는 경우 외장 32.768kHz 혹은 19.2MHz 클럭이 필요합니다. 따라서 사용이 용이하도록 주변 소자를 내장한 MPU6050의 Breakout 보드가 있으며 GY-521의 그 중의 하나입니다.


GY-521의 회로도


GY-521 모듈

(가속도계와 자이로의 방향은 MPU6050 칩의 1번 핀을 기준으로 3차원 축이 결정되며 MPU6050과 동일함을 알 수 있습니다)


MPU6050(GY-521)은 가속도계를 포함하므로 가속도를 측정하는 센서는 아닙니다. 단지 가속도를 이용하여 3차원 공간상 X, Y 그리고 Z 축을 중심으로 기울어진 각도(기울기)를 얻는 센서입니다. 가속도는 중력 방향과의 반대 방향일 때 양(+)이고 아래에서 각 축에 곡선 화살표는 자이로의 회전방향을 나타냅니다. 가속도계와 자이로 외에도 온도도 측정할 수 있는데 이는 이와같은 센서가 온도에 따라 약간 변화하기 때문에 이를 보정하는 목적으로 제공합니다.


만일 MPU6050을 비행기에 탑재하고 진행방향이 Y축 방향과 같다면 가속도계 출력 AccX는 롤(Roll), AccY는 피치(Pitch)그리고 AccZ는 요(Yaw)가 됩니다. 즉 AccX는 X축을 기준으로 기울어진 각도를 의미합니다. 가속도계는 X, Y축에 대해서 기울어진 정도를 중력가속도[g]의 단위로 출력합니다. 이때 기준 방향은 중력방향입니다. 그러나 Z축이 중력방향이 일치하는 경우 요를 구할 수 없다는 것입니다.


만일 움직이지 않고 이동하는 경우 진행 방향의 가속도의 영향으로 중력 방향이 변하게 되어 부정확하게 된다는 것입니다. 이러한 이유로 자이로의 측정 결과를 참조하게 되는데, 자이로는 짧은 시간은 정확하기 때문입니다. 하지만 긴 시간에 대해서는 자이로 센서가 측정시 함유하는 잡음 등을 각속도를 적분하여 기울기를 얻기 때문에 적분하는데, 이 과정에서 오차(적분상수)는 누적되고 시간에 따라 자이로 측정값은 드리프트하게 됩니다. 이때 변화분을 bias라고도 부릅니다.



위 그림에서 X축을 중심으로 회전한 각도 φ와 Y축을 중심으로 회전한 각도 ρ의 계산식입니다. 만일 X축 자체가 기울어지지 않았다면, 중력이 X축 상에 기여도는 없어 φ는 arctan(Ay/Az)으로 간략하게 됩니다. 여기서 Ax, Ay, Az는 AccX, AccY, AccZ입니다. ρ에서 음의 부호는 X축 중심으로 회전각도는 Y축이 위쪽으로 기울어져야 양이지만, Y축 중심으로 회전각도는 X축이 아래로 기울어져야 양이기 때문입니다.


MPU6050을 사용해 실시간으로 기울기를 요구하는 시스템은 가속도계의 측정값과 자이로의 측정값을 적절히 잡음을 고려하여 융합하고 최적의 가장 정확한 기울기를 얻어냅니다. 이때 사용하는 필터는 보상필터(Complementary filter; 혹은 상보필터)와 칼만필터(Kalman filter)로 알려집니다.


MPU6050은 7개의 채널에 대해서 16bit 크기의 값을 출력해주는 고성능 ADC를 내장하므로 각 축의 센서 출력값에 대해서 int16_t(-32768~32767)의 자료형으로 접근해야 합니다. 또한 MPU6050은 update rate(sampling time)이 가속도, 자이로에 대해서 각각 4~1000Hz, 4~8000Hz으로 출력값을 제공합니다.


MPU6050은 내부 레지스터를 이용해서 출력 값의 범위를 조정할 수 있습니다. 예를 들어 가속도계에서 AFS_SEL=0으로 설정함으로써 출력은 ±2[g]까지 나타낼 수 있으며 이를 2byte 크기로 나타내게 됩니다. 만일 AFS_SEL=0과 FS_SEL=0을 설정하였다면 다음과 같습니다.



가속도계에서는 최대 ±2[g]이고(-2g에서 +2g까지 측정하여 -32768에서 +32767까지 매핑Scale Factor가 1g당 16,384로 출력에 이를 나누어주면 실제 [g] 단위를 얻을 수 있습니다. 그러나 우리가 원하는 것은 기울어지 각도이므로 arctan에서는 비율(ratio)만을 사용하므로 단위는 의미가 없게 됩니다. 자이로에서는 최대 ±250[deg/s]이고(-250에서 +250까지 측정하여 -32768에서 32767까지 매핑Scale Factor가 131(32767/250)로 출력에 이를 나누어주면 실제 [deg/s] 단위의 각가속도를 얻을 수 있습니다. 각 센서는 감도(Sensitivity)를 증가시킬수록 미세하게 측정 가능하지만 정확도는 떨어집니다.


다음은 아두이노(Arduino) 보드와 GY-521(MPU6050) 모듈과의 연결 방법과 Wire 라이브러리를 이용하여 실행한 MPU6050의 데이터 출력의 예제입니다.


아두이노 보드와 연결 방법



// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
// August 17, 2014
// Public Domain

#include<Wire.h>
const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
void setup(){
  Wire.begin(); // Wire 라이브러리 초기화
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);      // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  Serial.begin(9600);
}
void loop(){
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  Serial.print("AcX = "); Serial.print(AcX);
  Serial.print(" | AcY = "); Serial.print(AcY);
  Serial.print(" | AcZ = "); Serial.print(AcZ);
  Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53);  //equation for temperature in degrees C from datasheet
  Serial.print(" | GyX = "); Serial.print(GyX);
  Serial.print(" | GyY = "); Serial.print(GyY);
  Serial.print(" | GyZ = "); Serial.println(GyZ);
  delay(333); 
}




'Flight Controller 이해 > 센서' 카테고리의 다른 글

관성측정장치(IMU)의 원리  (0) 2017.03.14
드론에 요구되는 각종 센서들  (0) 2017.02.26
Posted by Nature & Life