dtostrf() STM32 проблема
- Войдите на сайт для отправки комментариев
Втр, 16/11/2021 - 02:12
Всем привет. Помогите устранить проблему. Есть значение с датчика температуры "123.45", хочу получить целое число "123".
Использую dtostrf().
В результате в порту получаю значение "123.0" Такая беда только с платами STM32F103. Когда загружаю скетч в ProMini все ОК получаю "123".
В чем может быть проблема?
char temp = 123.56;
void setup() {
Serial.begin(9600);
}
void loop() {
char temp_serial[20];
dtostrf( temp , 3, 0, temp_serial);
Serial.println (temp_serial);
}
Может быть потому что char дробным не бывает?
Видимо, внутри STM32 framework первый аргумент обрабатывается иначе, нежели внутри AVR libc.
Serial.println(int(temp));
Serial.println(int(temp));
Это так не работает. Это никак не работает, у него temp типа char.
Думаю это машинально написано.
Я хочу вывести значение на экране, использую библиотеку U8g2. Значение нужно выводить целым числом. Я не знаю как, возможно есть какие-то другие методы.
Пробовал использовать sprintf() но могу понять как оно работает.
chartemp = 123.56; это не число !!!floattemp = 123.56; это число !!!float temp=123.56; void setup () { Serial.begin(9600); Serial.println("Start"); Serial.println(temp); Serial.println(int(temp)); } void loop() { }Извините перепутал.
Но когда даже
floattemp = 123.56;То в консоли получаем "123.0"
Вы слепой ?
Вы не поняли проблему. Меня интересует функция dtostrf(). Для отображения данных на дисплее требуется тип данных char Поэтому я использую dtostrf().
float temp = 123.56; void setup() { Serial.begin(9600); } void loop() { char temp_serial[20]; dtostrf( temp , 3, 0, temp_serial); Serial.println (temp_serial); }В консоле "124.0"
...хочу получить целое число...
может вы задачу не правильно описали ?
все просто и понятно))
float temp=123.56; void setup () { char str[20]; Serial.begin(9600); Serial.println("Start"); Serial.println(temp); dtostrf(temp,3,0,str); Serial.println(str); sprintf(str,"%i",int(temp)); Serial.println(str); } void loop() { }Serial.printf давно есть, даже на avr.
rkit ему надо символьное представление числа, а не вывод в serial ...
Спасибо . Все заработало.
Теперь возник вопрос, если я хочу получить значение с одним знаком после зяпятой. как должна выглядеть строка ???
sprintf(str,"%i",int(temp));У int не может быть дробной части. Ты что нибудь про типы данных знаешь? Прочитай учебник. Про типы. Про dtostrf , какой параметр отвечает за количество знаков после запятой у типа float. НЕ int.
код функции из официального ядра STM для ардуино:
char *dtostrf(double val, signed char width, unsigned char prec, char *sout) { //Commented code is the original version /*char fmt[20]; sprintf(fmt, "%%%d.%df", width, prec); sprintf(sout, fmt, val); return sout;*/ // Handle negative numbers uint8_t negative = 0; if (val < 0.0) { negative = 1; val = -val; } // Round correctly so that print(1.999, 2) prints as "2.00" double rounding = 0.5; for (int i = 0; i < prec; ++i) { rounding /= 10.0; } val += rounding; // Extract the integer part of the number unsigned long int_part = (unsigned long)val; double remainder = val - (double)int_part; // Extract digits from the remainder unsigned long dec_part = 0; double decade = 1.0; for (int i = 0; i < prec; i++) { decade *= 10.0; } remainder *= decade; dec_part = (int)remainder; if (negative) { sprintf(sout, "-%ld.%0*ld", int_part, prec, dec_part); } else { sprintf(sout, "%ld.%0*ld", int_part, prec, dec_part); } // Handle minimum field width of the output string // width is signed value, negative for left adjustment. // Range -128,127 char fmt[129] = ""; unsigned int w = width; if (width < 0) { negative = 1; w = -width; } else { negative = 0; } if (strlen(sout) < w) { memset(fmt, ' ', 128); fmt[w - strlen(sout)] = '\0'; if (negative == 0) { char *tmp = malloc(strlen(sout) + 1); strcpy(tmp, sout); strcpy(sout, fmt); strcat(sout, tmp); free(tmp); } else { // left adjustment strcat(sout, fmt); } } return sout; }видно что как минимум 1 цифра после запятой будет выведена
Разница между
и
только в том, что первая для temp = 123.52 выведет 123.0, а вторая 123.5
Вывод - функция dtostrf() предназначена для печати float - то есть чисел со знаками после точки. Если вам нужно печатать целое - то сначала переведите свое число в целое, а потом печататйте как целое - через sprintf, itoa и так далее
Ок, спасибо. Я получил ответ на все вопросы.