아누이노 관련 좋은 강좌입니다.

PDF로 배포하고 있으며 온라인 도서 형태입니다.

저자의 열성이 대단합니다.

입문자 뿐만 아니라 개발자들도 종종 이용해도 좋을 것 같네요.

네이버 "아두이노 생초보 무조건 따라하기 " 카페에서 내용을 확인하시면 됩니다.


작성자    → hgycap@hotmail.com

관련 URL → http://cafe.naver.com/myarduino/237




Table of Contents

 

Part I. 아두이노 배우기···························································································1  
  Chapter 1. 아두이노란 무엇인가?············································································2  
  Chapter 2. 아두이노 개발환경 설정·········································································12  
  Chapter 3. 아두이노 프로그램의 구조·······································································32  

  Chapter 4. 디지털 및 아날로그 입출력······································································40  

  Chapter 5. 아두이노 함수·····················································································50 
  Chapter 6. 기본 클래스······················································································· 77  
  Chapter 7. 라이브러리·······················································································106


Part II. 아두이노 사용하기·····················································································126
  Chapter 8. 아두이노를 위한 C/C++ 언어·································································127  
  Chapter 9. 디지털 및 아날로그 입출력 사용하기························································171  
  Chapter 10. 직렬 통신 사용하기···········································································207  
  Chapter 11. 센서 사용하기··················································································218

 


Part III. 아두이노 활용하기····················································································231  
  Chapter 12. 초음파 거리 센서··············································································232  
  Chapter 13. 텍스트 LCD····················································································245  
  Chapter 14. 그래픽 LCD····················································································258  
  Chapter 15. 7 세그먼트 표시장치··········································································270  
  Chapter 16. 네 자리 7 세그먼트 표시장치································································286  
  Chapter 17. EEPROM 라이브러리········································································295  
  Chapter 18. Real Time Clock··············································································298  
  Chapter 19. Real Time Clock - Wire 라이브러리 활용················································309  
  Chapter 20. 소프트웨어 시리얼·············································································326  
  Chapter 21. I2C와 SPI 통신을 이용한 아두이노 연결···················································334  
  Chapter 22. 블루투스·························································································348  
  Chapter 23. 서보 & DC 모터················································································369  
  Chapter 24. 모터 쉴드························································································380  
  Chapter 25. LED 매트릭스··················································································386  
  Chapter 26. I2C를 통한 LED 매트릭스 제어·····························································407  
  Chapter 27. 타이머 라이브러리 
  Chapter 28. 전자부품
  Chapter 29. 마이크로컨트롤러
  Chapter 30. 이더넷

  Chapter 31. 버튼 입력 확장

  Chapter 32. 부트로더

  Chapter 33. TFT-LCD
  Chapter 34. SD 라이브러리 
  Chapter 35. DIY Arduino 
  Chapter 36. ATmega128 
  Chapter 37. ATtiny85 

  Chapter 38 ~ 39 Reserved for future use

  Chapter 40. 아두이노 레오나르도

  Chapter 41. 아두이노 레오나르도 - 마우스 키보드 라이브러리

  Chapter 42. 아두이노 메가2560

  Chapter 43 ~ 47 Reserved for future use

  Chapter 48. 프로세싱 언어란 무엇인가? 

  Chapter 49. Reserved for future use 

  Chapter 50. 프로세싱으로 안드로이드 앱 만들기  

  Chapter 51. Reserved for future use 

  Chapter 52. Ketai 라이브러리 

  Chapter 53.1 프로세싱 - controlP5 라이브러리 - 버튼

  Chapter 53.2 프로세싱 - controlP5 라이브러리 - 노브 슬라이더

  Chapter 53.3 프로세싱 - controlP5 라이브러리 - 텍스트라벨, 텍스트필드

  Chapter 54 Ketai 라이브러리 - 블루투스 맛보기      

  Chapter 55.1 스마트폰으로 아두이노 제어하기 첫번째  

  Chapter 55.2 스마트폰으로 아두이노 제어하기 두번째   

  Chapter 55.3 스마트폰으로 아두이노 제어하기 세번째 - RGB LED 제어   

  Chapter 55.4 스마트폰으로 아두이노 제어하기 네번째 - 가변저항값을 그래프로 



반응형

□ USB To Serial port 설치 문제( Setup Problem )

 

아두이노 나노를 설치할 때 일반적으로 USB to Serial 포트를 자동 설치하지 못하고 FTDI 드라이버 등을 인스톨하여 수동 설치하는 경우가 일반적이다. 특히, Windows 7 64bit 환경에서는 거의 100% 발생한다.

 

그런데, 일부 아두이노 나노 호환 제품들은 FTDI 또는 PL2302 드라이버로 USB to Serial 포트 인식을 하지 못하는 경우가 있다.

 

이 중 WCH CH240G 칩셋을 사용한 제품이 가장 흔하다.  WCH CH240G 칩셋 오류는 아래와 같이 드라이버를 설치하여 해결할 수 있다.

 

 This device did not work with the FTDI drivers, nor the PL2302 drivers.

 

□ 정품과 USB to Serial port 컨트롤러에 WCH CH240G칩을 사용한 클론칩 구성 비교

정품( Original, FTDI )

클론( Clone, WCH CH240G )

 

 

 

 

 

 

시리얼 포트를 설치할 수 없을 경우

- 뒤면 chip 확인

  WCH CH340G 일 경우

 

 

 

 

 

□ Driver download

  - 제조사            WCH Nanjing QinHeng Electronics

  - 제조사 Driver   http://www.wch.cn/downloads.php?name=pro&proid=5

  - driver file       CH341SER.ZIP

 

 

□ 설치 방법( Setup Guide )

  1) CH341SER.ZIP Download 및 압축해제

 

  2) 드라이버 수동 설치 선택

 

 

  3) 압축을 해제한 디렉토리 지정

 

 

  4) 설치 결과 확인(Result)

 

 

반응형

- If you can try to use sprintf() to convert from a float to a string on Arduino, it doesn't work.

  The function sprintf() return a "?" instead of float format.

  The alternative to solve the problem is to use dtostrf(), the function in the avr-libc library.

 

아두이노에서 부동소수값 출력을 위해

 

sprintf( buf, "%f", 1.1f );

Srial.println( buf );

 

      → output : ?  

 

위와 같이 sprintf() 함수를 사용한 경우 1.1이 아닌 "?" 가 출력된다.

정확한 결과를 위해 

 

dtostrf() 함수를 사용

 

하여 해결 가능하다.

 

□ dtostrf()  개요

  - dtostrf() 함수는 부동소수(double, float) 변수를 주어진 형식에 따른 문자열을 출력

  - The dtostrf() function converts the double value passed in val into an ASCII representation that will be

    stored under s.

 

char* dtostrf

(

double 

__val,

signed char 

__width,

unsigned char 

__prec,

char * 

__s 

)

 

□ 매개변수 정의 

 매개변수

내용

 

 double __val

 - 변경할 부동소수

 - floatvar

   Float variable

 

 signed char __width

 - 음수부호(-)와 소수점을 포함한 전체 자리수

 - StringLengthIncDecimalPoint

   It is the length of the string will be created

 소수점 포함, 음수는 (-)포함

 unsigned char__ prec

 - 소수점을 제외한 소수점 자릿수

 - numVarsAfterDecimal

   The number of digits after the dicimal point 

 소수점 제외 

 char * __s

 - 문자열 버퍼 ( char buffer )

 - charbuf

   The char array to store the result

 

 

 

□ dtostrf() 사례 ( Sample )

#include    <stdio.h>
 
void    setup() {
    Serial.begin( 9600 );
}
 
void    loop() {
    char    CAa [20] = "";
    char    CAb [20] = "";
    char    CAc [ 3] = "";
    char    CAd [ 5] = "0000";
 
    char buf[128];    
 
    dtostrf( 123.123    ,  6, 2, CAa );
    dtostrf( 456.456     , 1, 3, CAb );
    sprintf(buf, "dtostrf( 123.123     ,  6, 2, CAa ) -> %15s\n"
                 "dtostrf( 456.456     ,  1, 3, CAb ) -> %15s"
                 , CAa
                 , CAb          );
    Serial.println(buf);
 
    dtostrf( 123.123    ,  6, 2, CAa );
    dtostrf( 456.4567    , 6, 2, CAb );
    sprintf(buf, "dtostrf( 123.123     ,  6, 2, CAa ) -> %15s\n"
                 "dtostrf( 456.4567    ,  6, 2, CAb ) -> %15s"
                 , CAa
                 , CAb          );
    Serial.println(buf);
 
    dtostrf( 12312.123   , 3, 2, CAa );
    dtostrf( 456.4567789 , 2, 5, CAb );
    sprintf(buf, "dtostrf( 12312.123   ,  3, 2, CAa ) -> %15s\n"
                 "dtostrf( 456.45674444,  2, 5, CAb ) -> %15s"
                 , CAa
                 , CAb          );
    Serial.println(buf);
 
    dtostrf( 123.12345678, 10, 3, CAa );
    dtostrf( 456456.4567 , 11, 4, CAb );
    sprintf(buf, "dtostrf( 123.12345678, 10, 3, CAa ) -> %15s\n"
                 "dtostrf( 456456.4567 , 11, 4, CAb ) -> %15s"
                 , CAa
                 , CAb          );
    Serial.println(buf);
 
    dtostrf( 123.123     , 10, 3, CAa );
    dtostrf( 456456.45   , 10, 4, CAb );
    sprintf(buf, "dtostrf( 123.123     , 10, 3, CAa ) -> %15s\n"
                 "dtostrf( 456456.45   , 10, 4, CAb ) -> %15s"
                 , CAa
                 , CAb          );
    Serial.println(buf); 
 
    dtostrf( 789.789    ,  3, 3, CAc );
    sprintf(buf, "dtostrf( 789.789     ,  3, 3, CAc ) -> %15s\n"
                 "CAd is 0000                         -> %15s"
                 , CAc         
                 , CAd );
    Serial.println(buf);
       
   delay( 2000 );
}       

 

 

□ 결과 (Result)

dtostrf( 123.123     ,  6, 2, CAa ) ->          123.12      // Normal. 정상
dtostrf( 456.456     ,  1, 3, CAb ) ->         456.456      // Error. 전체자리수 무시됨
dtostrf( 123.123     ,  6, 2, CAa ) ->          123.12      // Normal. 정상
dtostrf( 456.4567    ,  6, 2, CAb ) ->          456.46      // Normal. 정상. 소수점 끝자리 반올림됨
dtostrf( 12312.123   ,  3, 2, CAa ) ->        12312.12      // Error. 전체자리수 무시됨
dtostrf( 456.45674444,  2, 5, CAb ) ->       456.45679      // Error. 부동소수 오류(끝자리 4가 아님)
dtostrf( 123.12345678, 10, 3, CAa ) ->         123.123      // Normal. 정상
dtostrf( 456456.4567 , 11, 4, CAb ) ->     456456.4700      // Error. 부동소수 오류 발생
dtostrf( 123.123     , 10, 3, CAa ) ->         123.123      // Normal. 정상
dtostrf( 456456.45   , 10, 4, CAb ) ->     456456.4400      // Error. 소수점 끝자리 오류발생
dtostrf( 789.789     ,  3, 3, CAc ) ->         789.789      // Error. sizeof(CAc)→3, Buffer Over Flow 발생
CAd is 0000                         ->            .789      // Error. CAc의 BoF로 원래 값이 지워짐

 

결과에서 알 수 있듯이 dtostrf()도 정확한 연산이 되는 것은 아니다.

그러나, dtostrf()를 sprintf() 대신 충분히 사용가능하다.

 

As the result, dtostrf () also is not working exactly.
But, however , the dtostrf () is fully available instead of sprintf().

 

반응형

'아두이노 > 일반' 카테고리의 다른 글

[브리핑] 아두이노 강좌  (0) 2016.02.03
Arduino Nano USB to Serial Port 설치-WCH CH340G  (0) 2014.12.31
I2C 통신  (0) 2014.11.21
Arduino 사용자 라이브러리 작성법  (0) 2014.11.16

아두이노에서 I2C 통신을 구현하기에 앞 서서 I2C 통신의 기본원리를 살펴 보면 아래와 같다.

 

□ 동기식 통신방식, I2C 개요

- 기존 1:1 통신방식인 시리얼(RS232C) 통신의 단점을 개선하여 Master/Slave 기반 1:N 통신이 가능하도록 고안된
  프로토콜

- Philips에서 개발

 

 

 

 

 

 

□ RS232C 대비 I2C 통신 특성

I2C 통신 방식은 RS232C의 단점을 개선한 것으로 두 방식의 특성을 비교하면 아래와 같다. 

 

 I2C

 RS232C 

 통신 방식

 1:N

 1:1

 통신 구조

 - SCL(클록), SDA(데이터) 이용 

 - RX, TX 이용  

 타이밍 처리

 - 클록신호를 이용한 동기식 통신

 - 유연한 타이밍 관리가 가능 

 - 보레이트(전송속도) 엄수 필요 

 

□ I2C통신 구성 시 주의 사항

I2C 통신은 오픈 컬렉터 구성이므로 구성 시 반드시 풀업 저항이 필요하다.

 

 

 

 

 

□ 아두이노 I2C통신

 

 

 

반응형

 

□ 사용자 라이브러리 구성 방법

스케치 파일(ino)에 소스를 작성하는 것은 비효율적인 경우가 많다.

한 예로, ino 파일을 다른 Editor (Visual Studio, eclipse 등 )에서 사용하는데 확장자로 인해서 번거롭고 별도 헤더파일 정의도 없어 라이브러리로 사용이 불편하거나 하는 등 여러 단점이 존재한다.

특히, 복잡한 프로그램을 개발하는 경우 다양한 사용자 라이브러리들을 별도의 파일로 만들어 사용하는 것은 불가결하다.

 

이런 이유로, 복잡한 프로그램은 두말할 것도 없고 단순 기능도 스케치 파일(ino)와 사용자 라이브러리(별도 소스파일)을 분리해서 개발하는 것은 좋은 방법이다.

아두이노에서 사용자 라이브러리를 사용하는 것은 간단하며 아래와 같은 형태로 쉽게 구성이 가능하다.

 

그림) 아두이노 사용자 라이브러리 구성도 

 

  Sample.ino

 프로그램 Sample에 대한 스케치

  Sample.h

 Sample.cpp 소스에 대한 헤더파일

  Sample.cpp

 실제 기능/클래스를 이용한 실행 소스 

- 실제 소스는 Sample.h와 Sample.cpp에서 작성하여 재사용성을 높이고 ino 파일은 스케치 역할과 프로그램 설명,
   저작권 설명 등 부수적인 역할만 수행

 

 

사용자 라이브러리를 위한 별도 소스파일에서 가장 먼저 지정해야하는 것은 #include “Arduino.h” 구문을 사용하는 것이다.

#include "Arduino.h"    

- 아두이노 표준 타입, 사전 정의된 상수, 함수들에 대한 헤더파일

- 아두이노 표준 제공 기능을 사용할 수 있도록 해준다.

 

해당 파일은 일반 스케치(ino 파일)에서는 암묵적으로 자동 추가되지만, 사용자 라이브러리 파일에서는 자동 추가되지 않아서 직접 지정해 주어야 한다.

주의해야할 사항으로는스케치 파일에서는 Arduino.h와 IDE에서 "새탭"으로 정의한 소스 및 헤더파일 들만 자동 추가된다.

따라서, 소스 내에서 Serial 클래스와 같은 #include <Wire.h> 등을 사용할 때나 다른 라이브러리 등을 사용할 경우에는 스케치 파일에도 반드시 명시적으로 기재해 주어야 한다.

또한, 사용되는 라이브러리들의 구성관계를 파악하기에 용이하므로 새탭 메뉴를 통해 정의된 사용자 라이브러리의 헤더파일도 명시적으로 선언(#include로 기재)해 주는 것이 좋다.

 

 Sample.ino

 

Sample.h 

 

 Sample.cpp

 

 // 프로그램 개요

 // 저작권 : ... ...

 // ... ...

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 // 전처리 상수 선언

 #define PORT_NO 12

 #define TIME        1000

            ... ...

 

 // 함수 or 클래스 선언

 void userfunction1();

 void userfunction2();

            ... ...

 

 

 

 

 

 

 

 

 

 // 필수 추가

 #include "Arduino.h"

 #include "Sample.h"

            ... ...

 

 void setup() {

            ... ...

 }

 

 void loop() {

            ... ...

 }

 

 void userfunction1() {

            ... ...

 }

 

 - 주석을 이용해서 프로그램

    설명, 저작권 표기 등 가능

 

 - 헤더 파일

 - 상수선언, 함수, 클래스 선언

 

 

 - 실제 소스 구성 부문

 - 사용자 라이브러리

 

 

 

□ 예제를 통한 확인

아래 예제는 아두이노 IDE에서 제공되는 Basic 예제인 Blink를 이용한 사용자 라이브러리 사용방법이다.

충분한 확인을 위해  고의로 기존 Blink.ino 단일 파일을 복잡한 여러 파일로 분리했다.

 

 그림) Blink.ino 의 분리 

- 단일 스케치 파일을 여러  라이브러리로 구성하여 사용성을 높임

 

 

1) 원본 소스 Blink.ino 확인

   - "파일 메뉴 - 예제"를 통해서 Blink.ino를 불러 온다.

 

 

2) Test.ino 생성 

   - Blink.ino를 다른이름으로 저장하여 Test.ino를 생성한다.

   - 저장한 후 Test.ino의 내용은 맨 마지막에 삭제해도 되고 이 단계에서 삭제해도 된다.

   - 해당 예제에서는 맨 마지막에 삭제하는 것으로 설정했다.

 

 

3) 새탭 메뉴를 이용, 신규  파일 생성 

  - 스케치를 통한 파일의 연결은 새탭을 통해서 가능하다.

 

 

4) 신규 파일명 부여 후 저장 

  - 하단 입력창을 통해서 이름부여 후 저장한다.

 

 

5) 반복해서 필요한 파일 전체 생성 

  - 예제를 통해 확인해 필요한 모든 파일을 생성한다.

  - Test.h, Test.cpp, Blink.h, Blink.cpp

 

 

6) blink.ino에서 원본 소스 복사

아두이노 IDE에서 제공되는 Basic 예제 "Blink" 소스 - blink.ino에서 복사해서 수정을 시작한다.

편의 상 복사한 것으로 내용을 수기 입력해도 당연히 된다.

}
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
}

 

// the loop function runs over and over again forever
void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                // wait for a second
  digitalWrite(13, LOW);   // turn the LED off by making the voltage LOW
  delay(1000);                // wait for a second

 

7) 원본 소스에서 Blink.h, Blink.cpp 구성

  - 테스트를 위해 Blink 소스를 아래와 같이 수정해서 Blink.cpp로 저장한다.

  - 해당 작업으로 좀 더 유연하게 사용가능한 blinkInit, LEDon, LEDoff 함수를 만들 수 있다.

void setup() {
  pinMode(13, OUTPUT);

void blinkInit() {
  pinMode(13, OUTPUT);
}

 

 

void loop() {
  digitalWrite(13, HIGH);   
  delay(1000);            

    
  digitalWrite(13, LOW);   
  delay(1000);               
}

 

 

 

 

 

void LEDon() {
  digitalWrite(13, HIGH);   
}

 

void LEDoff {

  digitalWrite(13, LOW);   
}

 

  - Blink.h와 Blink.cpp의 최종소스는 아래와 같다.

Blink.h

 Blink.cpp

void blinkInit();
void LEDon();
void LEDoff();

 

 

 

 

 

 

 

 

 

#include "Arduino.h"
#include "Blink.h"
 
void blinkInit() {
  pinMode(13, OUTPUT);
}

void LEDon() {
  digitalWrite(13, HIGH); 
}

 

void LEDoff() {
  digitalWrite(13, LOW);  
}

 

8) 원본소스에서 Test.h, Test.cpp 구성

  - 원소스인 Blink.ino에서 아래와 수정해서 메인 프로세스에 해당하는 Test.cpp도 생성한다. 

  - test.cpp는 Main 프로세스(C의 Main함수)에 해당하는 것으로 아래처럼 보다 직관적으로 구성이 가능해졌다.

void setup() {
  pinMode(13, OUTPUT);

void setup() {
  blinkInit(); 
}

 

void loop() {
  digitalWrite(13, HIGH);   
  delay(1000);            

    
  digitalWrite(13, LOW);   
  delay(1000);               
}

 

 

 

 

 

void loop() {
  LEDon();
  delay(1000);              

 

  LEDoff();
  delay(1000);             
}

 

  - Test.h와 Test.cpp의 최종소스는 아래와 같다.

Test.h

 Test.cpp

// Test.cpp에 사용자 함수가 없으므로

// Test.h에는 아무 것도 선언할 내용이 없다.

 

 

 

 

 

 

 

 

 

  

 

 

#include "Arduino.h"
#include "Test.h"
#include "Blink.h"

 

void setup() {
  blinkInit(); 
}

 

void loop() {
  LEDon();
  delay(1000); 


  LEDoff();
  delay(1000); 
}

 

10) 분리 완료(사용자 라이브러리 생성 완료 및 Test.ino 내용 삭제)

  - 최종적으로 Test.ino 의 모든 내용을 지운다. Test.ino는 어떠한 코드도 사용할 필요가 없게 된다.

  - 이후 Test.ino 파일의 용도는 프로그램 설명, 저작권 등에 대한 내용을 기재하는데 사용하면 된다.

 

11) 컴파일 및 확인

  - 컴파일이 성공적으로 끝난 것을 확인이 가능하며, 업로드하여 테스트해도 기존 Blink.ino와 동일한 내용 확인이

    가능하다.

 

 

 

 

12) 결론

  - Blink.ino 파일은 스케치파일(ino)와 메인파트(Test.cpp)와 사용자 라이브러리(Blink.cpp)로 분리가 되어

    보다 유연한 구조를 가지게 되었음을 알 수 있다.

  - 해당 예제는 고의로 복잡한 구성을 만들었다. 다만, 예제에서 알 수 있듯이 간단한 소스도 스케치 파일과

     소스파일을 분리하는 것이 구조 상 활용시 장점이 많게 된다.

 

끝으로, 이미 위에서 언급한 바와 같이 스케치 파일에서는 Arduino.h와 IDE에서 "새탭"으로 정의한 소스 및 헤더파일 들만 자동 추가된다. 따라서,

 

1. 소스 내에서 Serial 클래스와 같은 #include <Wire.h> 등을 사용할 때나 다른 라이브러리 등을 사용할 경우에는 

   스케치 파일에도 반드시 명시적으로 선언(#include로 기재)해 주어야 한다.

 

2. 사용되는 라이브러리들의 구성관계를 파악하기에 용이하므로 새탭 메뉴를 통해 정의된 사용자 라이브러리의

    헤더파일도 명시적으로 선언해 주는 것이 좋다.

 

를 유의해서 작성하는 것이 필요하다. 

 

즉, ino 파일은 프로그램의 전체 구조에 대한 맵과 같아서 사용되는 모든 라이브러리들을 명시적 선언해 주는 것이 좋은 방법이다.

 

 

샘플소스 :Test.zip

 

 

 

반응형

+ Recent posts