Работа с Float

radist_morze
Offline
Зарегистрирован: 26.05.2013

Доброе время суток!

При раброте с float получаю результат с сотыми долями (13.46) но на ЖК не много места надо перевести в десятые (работать с субстрокой не хотелось бы), пробовал double = не помогло.

Может есть что по проще? Либо как-то передать дополнительные параметры float или double?

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Нужно использовать sprintf(char* buf, "%02.1f",Value_float);

radist_morze
Offline
Зарегистрирован: 26.05.2013

Спасибо буду пробовать.

Но почему на странице http://arduino.ru/Reference ничего про эту команду не написано (или оригинал на аГлицком вернее).

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Еще есть dtostrf(floatVar, minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf);

Эта функция из C++

Пишут что sprintf() урезан и не умеет c Float работать.

radist_morze
Offline
Зарегистрирован: 26.05.2013

NeiroN пишет:

Еще есть dtostrf(floatVar, minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf);

Эта функция из C++

Пишут что sprintf() урезан и не умеет c Float работать.

Прошу прощения, чтоб не убить кучу времени на изучение и подбор параметров. Раззьясните на моем примере:

есть float Rez = 13.61

как мне преобразовать в переменную Itog чтоб получилось 13.6

Да, и может какую библиотеку подключить надо?

 

maksim
Offline
Зарегистрирован: 12.02.2012
Looka
Offline
Зарегистрирован: 24.04.2012

sprintf()  - действительно не умеет.
Аналог:    dtostrf(floatVar, minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf);

 

 

 

 

__Alexander
Offline
Зарегистрирован: 24.10.2012

radist_morze пишет:

Прошу прощения, чтоб не убить кучу времени на изучение и подбор параметров. Раззьясните на моем примере:

есть float Rez = 13.61

как мне преобразовать в переменную Itog чтоб получилось 13.6

а зачем? память вы таки способом не с экономите. она уже выделена. ну будет у вас 13.60000000000 и толку? 

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013
1print (13.67, 1);

 

radist_morze
Offline
Зарегистрирован: 26.05.2013

__Alexander пишет:

radist_morze пишет:

Прошу прощения, чтоб не убить кучу времени на изучение и подбор параметров. Раззьясните на моем примере:

есть float Rez = 13.61

как мне преобразовать в переменную Itog чтоб получилось 13.6

а зачем? память вы таки способом не с экономите. она уже выделена. ну будет у вас 13.60000000000 и толку? 

Дело не в памяти а в отображении информации на ЖК дисплее, не помещается просто.

radist_morze
Offline
Зарегистрирован: 26.05.2013

ingener.solovyev пишет:

1print (13.67, 1);

Так мне не в сериал его толкать, а отдельно ругается ИДЕ на недекларированную функцию (может какую библиотеку припилить).

С Сериал работает чудесно, и даже округляет правильно а не просто режет крайнюю цифру.

float Rez=13.67;
Serial.println(Rez, 1);

13.7

maksim
Offline
Зарегистрирован: 12.02.2012

radist_morze пишет:

ingener.solovyev пишет:

1print (13.67, 1);

Так мне не в сериал его толкать, а отдельно ругается ИДЕ на недекларированную функцию (может какую библиотеку припилить).

С Сериал работает чудесно, и даже округляет правильно а не просто режет крайнюю цифру.

float Rez=13.67;
Serial.println(Rez, 1);

13.7

Я уже вам давал ссылку на print() поленились прочитать? Вот компилятор и ругается.

Никому тут не видно какой у вас там дисплей на столе лежит. Так вот если предположить, что у вас алфавитно-цифровой дисплей типа 16х2, то воводится просто

1lcd.print(rez, 1);

http://arduino.ru/forum/programmirovanie/izmerenie-davleniya-i-vyvod-dannykh-na-lcd-202-problema-s-pereschetom

radist_morze
Offline
Зарегистрирован: 26.05.2013

maksim пишет:

radist_morze пишет:

ingener.solovyev пишет:

1print (13.67, 1);

Так мне не в сериал его толкать, а отдельно ругается ИДЕ на недекларированную функцию (может какую библиотеку припилить).

С Сериал работает чудесно, и даже округляет правильно а не просто режет крайнюю цифру.

float Rez=13.67;
Serial.println(Rez, 1);

13.7

Я уже вам давал ссылку на print() поленились прочитать? Вот компилятор и ругается.

Никому тут не видно какой у вас там дисплей на столе лежит. Так вот если предположить, что у вас алфавитно-цифровой дисплей типа 16х2, то воводится просто

1lcd.print(rez, 1);

http://arduino.ru/forum/programmirovanie/izmerenie-davleniya-i-vyvod-dannykh-na-lcd-202-problema-s-pereschetom

Прошу прощения. Ссылку то прочитал, но увидев Сериал поостыл, по неопытности своей даже попробовал повторить без сериал.

А вот то что ЖК дисплей по сути тоже Последовательный интерфейс даже не подумал.

Благодарю, пошел домой пробовать.

maksim
Offline
Зарегистрирован: 12.02.2012

radist_morze пишет:

А вот то что ЖК дисплей по сути тоже Последовательный интерфейс даже не подумал.

Не одно и тоже не по сути и ни как вообще. Просто класс lcd наследуется от класса Stream так же как и Serial.

step962
Offline
Зарегистрирован: 23.05.2011

"пешком" нужное преобразование можно сделать следующим образом:

1float v;
2long V;
3...
4  v=13.67;
5  V=round(v*10);
6  V/10 -> целая часть числа
7  V%10 -> дробная часть числа (1 позиция)

 

__Alexander
Offline
Зарегистрирован: 24.10.2012

step962 пишет:

"пешком" нужное преобразование можно сделать следующим образом:

1float v;
2long V;
3...
4  v=13.67;
5  V=round(v*10);
6  V/10 -> целая часть числа
7  V%10 -> дробная часть числа (1 позиция)

+1

А еще легче просто не доводить до флоат. в авр нет флоата как такового и в 99% случаев можно обойтись и без него.

 

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

__Alexander пишет:

А еще легче просто не доводить до флоат. в авр нет флоата как такового и в 99% случаев можно обойтись и без него.

еще легче, взять нормальный экран TFT и не морочить голову.. тем более что они стоят щас по 10 баксов с доставкой вместе :)

__Alexander
Offline
Зарегистрирован: 24.10.2012

при чем тут одно к другому? тупак, ящетаю.

radist_morze
Offline
Зарегистрирован: 26.05.2013

Puhlyaviy пишет:

__Alexander пишет:

А еще легче просто не доводить до флоат. в авр нет флоата как такового и в 99% случаев можно обойтись и без него.

еще легче, взять нормальный экран TFT и не морочить голову.. тем более что они стоят щас по 10 баксов с доставкой вместе :)

ЖК заказал, только доставят через 1,5 месяца с АлиЭкспресс, тем более под рукой был 24х2.

А вот без флоата не получиться в моем случае. Делаю разрядное устройство для 5-ти 12В аккумуляторов, включенных последовательно, емкостью от 7,5 - 100 А-ч, т.е. при 10% токе разряда нужно разряжать током до 10 ампер (ШИМ с фильтрацией) и одновременно отслеживать напряжения на всех 5-ти банках + ток разряда. При достижении напряжения хоть на одной банке 10,6 В остановить разряд (дабы глубоко не разряжать).

Вопрос решен, дописываю код.

radist_morze
Offline
Зарегистрирован: 26.05.2013

Вопрос в догонку. Есть на МК вход опорного напряжения AREF если мы работаем с низкими напряжениями, например 2 вольта, то есть смысл понизить опорное напряжение , чтоб полностью воспользоваться 10-ти разрядным АЦП. А вот если работаю с большими напряжениями могу ли я поднять хотя бы до 10 вольт?

Просто сейчас, по вышеописанной схеме, когда меряю напряжение на крайнем аккуме (55 вольт) аналоговым входом через делитель напряжения, колебания погрешности довольно высоки, вплоть до +-0.2 вольта. Питание (оно же и опорное) колеблется 4,956-4,964, питаю ардуину пока от УСБ. Чую здесь копать надо...

__Alexander
Offline
Зарегистрирован: 24.10.2012

radist_morze пишет:

о есть смысл понизить опорное напряжение , чтоб полностью воспользоваться 10-ти разрядным АЦП.

Да.

radist_morze пишет:

А вот если работаю с большими напряжениями могу ли я поднять хотя бы до 10 вольт?

Нет. Опорное максимум питание. т.е 5В.

зы. Если вы используете АЦП, то принимаете число int, зачем вам флоат, если можно оперировать этим интом.

step962
Offline
Зарегистрирован: 23.05.2011

__Alexander пишет:

Нет. Опорное максимум питание. т.е 5В.

Согласно даташиту на 88/168/328 - 6,0 В (раздел 28.1)

Согласно даташиту на 1280/2560 - 6,0 В (раздел 31.1)

Но уж выше точно ни-ни (ибо "Absolute Maximum Ratings*")

 

 

radist_morze
Offline
Зарегистрирован: 26.05.2013

__Alexander пишет:

зы. Если вы используете АЦП, то принимаете число int, зачем вам флоат, если можно оперировать этим интом.

Результат измерения для моих механиков проще в вольтах выводить, и точности хватает одного символа после запятой. Спасибо всем ответевшим.

__Alexander
Offline
Зарегистрирован: 24.10.2012

step962 пишет:

Согласно даташиту на 88/168/328 - 6,0 В (раздел 28.1)

Согласно даташиту на 1280/2560 - 6,0 В (раздел 31.1)

Но уж выше точно ни-ни (ибо "Absolute Maximum Ratings*")

Ну если уж точнее и согласно даташиту, то Aref измеряется относительно AVCC, а AVCC в свою очередь макс. 5.5В. Это в том-же разделе.

sirik
Offline
Зарегистрирован: 10.11.2012

я сделал проще: использую библиотеку floatToString.h, в ней есть прекрасная функция:  floatToString(buffer, value, 2);

где, buffer - массив вида char buffer[длина сообщения];

value - float переменная

2 - количество цифр после запятой

 

и в конце выводишь buffer на экран

maksim
Offline
Зарегистрирован: 12.02.2012

sirik пишет:

я сделал проще: ....

И в каком именно месте ваш вариант проще чем lcd.print(rez, 1); ???

sirik
Offline
Зарегистрирован: 10.11.2012

потому что print выводит только int переменные

maksim
Offline
Зарегистрирован: 12.02.2012

Да ладно... Сами догадались? Или подсказал кто? Почитайте print().

sirik
Offline
Зарегистрирован: 10.11.2012

LCD, а не Serial. В ком порт вывести значение не проблема

 

там четко написано: void print(int value);

maksim
Offline
Зарегистрирован: 12.02.2012

Ветку выше перечитайте и не тратьте ни свое ни мое время. Лично для вас, если лень читать выше:

maksim пишет:

 класс lcd наследуется от класса Stream так же как и Serial.

sirik пишет:

там четко написано: void print(int value);

Где там?

sirik
Offline
Зарегистрирован: 10.11.2012

я не хочу тратиться ваше время, просто описал свое решение

там, это в описании класса  LCD4Bit_mod библиотеки ARDLCD216

p-a-h-a
Offline
Зарегистрирован: 17.01.2019

step962 пишет:

"пешком" нужное преобразование можно сделать следующим образом:

1float v;
2long V;
3...
4  v=13.67;
5  V=round(v*10);
6  V/10 -> целая часть числа
7  V%10 -> дробная часть числа (1 позиция)

Не работает. Не в ту сторону округляет. round заменил на floor и порядок.

Schwarz78
Offline
Зарегистрирован: 19.01.2019

Ни как устроен float, ни как устроен int, ни как устроен printf никому не интересно. Интересно по граблям скакать гуртом.

mixail844
Offline
Зарегистрирован: 30.04.2012

может кому будет полезно ,для того что бы sprintf работал с float , в коммандной строке компилятора надо добавить  аргумент  -u _printf_float 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

а еще есть 

https://www.microchip.com/webdoc/AVRLibcReferenceManual/group__avr__stdl...

не такая гибкая, мошт, как sprintf зато в дупло компилятора лезть не нада. 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

DetSimen пишет:

а еще есть 

https://www.microchip.com/webdoc/AVRLibcReferenceManual/group__avr__stdl...

не такая гибкая, мошт, как sprintf зато в дупло компилятора лезть не нада. 

Я уже не первый раз обращаю внимание, что ты и, например, Женя, пользуетесь Атмеловской документацией на arc-libc. Хочу заметить, что это НЕ первичная документация, первична на сайте nongnu.org, то есть на самом сайте проекта arv-libc. Вот она: https://www.nongnu.org/avr-libc/user-manual/index.html

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

wdrakula пишет:

Я уже не первый раз обращаю внимание, что ты и, например, Женя, пользуетесь Атмеловской документацией на arc-libc.

Та не, я пользуюсь первым, что в гугле вылезет.  Иногда это avr-libc, иногда nongnu.... 

soznik
Offline
Зарегистрирован: 20.09.2015

lcd.print(rez, 1); 

Работает у меня работает на всех  LCD матрицах , а вот с светодиодной матрицей и библиотекой Max72xxPanel.h работать отказыватся пишет просто "1".

tape = utf8rus((String)+"Контейнер *1* "+(senIn,1)+"°C";

b707
Offline
Зарегистрирован: 26.05.2017

soznik пишет:

tape = utf8rus((String)+"Контейнер *1* "+(senIn,1)+"°C";

смешно пошутили, да...

Как вы думаете, между оператором print() и конструктором строки - нет разницы?

не работает и не должно.

iliarr
Offline
Зарегистрирован: 08.02.2020

Та-же проблема. Кроме того, длина числа меняется ( 9.1  , 12.3 ) на LCD2004 остаётся символ если не записать пробел на его место.  Решение оказалось простым.  Каждое число преобразуется в строку заданной длины и выводится на дисплей.

01String nomberToString(float nom){
02  int a = (int)nom;
03  int b = nom*10-a*10;
04  String out = String(a)+ "." + String(b) ;
05  int len = out.length();
06  for (int i=0; i<(5-len);i++){
07    out = out + " ";
08  }
09  return out;
10}

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

а еще есть dtostrf()

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

iliarr пишет:
Решение оказалось простым.

А ничего, что память фрагментирует?

результат:

или так и задумано?

iliarr
Offline
Зарегистрирован: 08.02.2020

Не задумывался об этом. Раз в секунду вывести на экран , ресурсов arduino nano хватает .

Предложите вариант , решающий ту-же задачу, без озвученных недостатков.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Евгений! Было бы поучительно, если разберёте ошибку...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А чего её разбирать, всё давно разобрано - http://arduino.ru/forum/programmirovanie/etyudy-dlya-nachinayushchikh-pamyat-3-dinamicheskie-i-avtomaticheskie-peremen

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

iliarr пишет:

Предложите вариант , решающий ту-же задачу, без озвученных недостатков.

Как-то на тон приказа смахивает? Не? А так, вообще, читайте статью по ссылке в посте выше.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

iliarr пишет:

Предложите вариант , решающий ту-же задачу, без озвученных недостатков.

Как-то на тон приказа смахивает? Не? А так, вообще, читайте статью по ссылке в посте выше.

да не, там ЩАСЖЕ не было )))

iliarr
Offline
Зарегистрирован: 08.02.2020

У человека был вопрос, он создал тему. У меня возник такой-же вопрос и эту тему я нашёл через поисковик. Просто и быстро решение здесь не нашёл, сделал своё и оно работает. Вы дали толковую критику этого решения, но не предложили альтернативное решение.  То что Вы больше меня понимаете в вопросе программирования ардуино, у меня сомнений нет.

Стандартный вопрос - варианты его решения. Смысл форума представляю именно так. :-)

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

iliarr пишет:

 Смысл форума представляю именно так. :-)

Не правильно представляешь. Поясню, поскольку не злой сегодня. Так, как ты представляешь устроены Q&A форумы, где задают вопросы и получают ответы. Самый известный для программистов - стековерфлоу.

А у нас просто хоббийный форум для общения. Не вопрос-ответ. Тебе нужен ответ - читай по ссылке, учись, задавай вопросы на Q&A форумах (как вариант ;)) ).

Без обид, плз, просто достало непонимание.