- 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

+ Recent posts