Преобразовать массив float в char на ATtiny85
Мне трудно преобразовать число с плавающей запятой в массив символов, чтобы он сохранялся как "7.125", точно так же, как выглядит число с плавающей запятой.
Я пытаюсь установить связь с ATtiny85 (подчиненный) и программой на Raspberry Pi (ведущий) через I2C.
Главное устройство ожидает от подчиненного устройства 31 байт при отправке ему данных.
Когда я использую этот код на ATtiny85, все работает как надо, Pi получает данные правильно.
char computerdata[35];
computerdata[0] = '3';
computerdata[1] = '.';
computerdata[2] = '8';
computerdata[3] = '7';
computerdata[4] = '7';
TinyWire.send(1);
TinyWire.send(computerdata,30);
Конечно, мне нужно поместить в массив переменную с плавающей запятой, а не определять числа, как у меня для тестирования, и здесь все ломается.
Когда я делаю что-то подобное, это не работает, Pi сообщает об ошибке синтаксического анализа, но когда я делаю это на выводах Due with Serial, массив символов выглядит хорошо, но что-то в нем отличается.
sprintf(computerdata, "%2.32f", pH);
OR
snprintf (computerdata, 35, "%f", pH);
Что я упускаю? Есть идеи?
Спасибо
@robsworld78, 👍1
2 ответа
Лучший ответ:
Просто в дополнение к ответу Мишеля Кейзерса: sprintf()
или snprintf()
обычно являются правильным решением. Однако на платформе AVR плавающие
преобразования исключены из их реализации по умолчанию, потому что они
занимают довольно много места на флэш-памяти, даже если они не используются. С другой стороны,
avr-libc предоставляет нестандартную функцию dtostrf()
для выполнения этого преобразования. Программа
void setup() {
float f = 3.877;
char str[35];
dtostrf(f, 0, 3, str);
Serial.begin(9600);
Serial.println(str);
}
void loop(){}
выходные данные
3.877
Причина в том, что библиотека, реализующая snprintf
и sprintf
, может зависеть от компилятора, используемого для вашего MCU, поэтому в вашем случае она не поддерживается.
Если вам всегда нужна форма %2.32f
, почему бы не указать ее напрямую, например:
int i = int(3.877 * 1000.0); // Предполагая, что f имеет форму a.bcd, i будет 3877
char str[6];
str[0] = (i / 1000) % 10;
str[1] = '.';
str[2] = (i / 100) % 10;
str[3] = (i / 10) % 10;
str[4] = (i ) % 10;
str[5] = '0';
Также это будет намного быстрее.
Спасибо за ответ, но он не скомпилировался, получил эту ошибку. Эдгар работал хорошо. sketch_feb28b.ino: В функции 'void setup()': sketch_feb28b:21: ошибка: недопустимые операнды типов "double" и "int" для двоичного "operator%" sketch_feb28b:22: ошибка: недопустимые операнды типов "double" и "int" для двоичного "operator%" недопустимые операнды типов 'double' и 'int' для двоичного 'operator%', @robsworld78
Правда, поменял, теперь компилируется (на Ардуино не проверял).
Я оставлю его, несмотря на то, что в большинстве случаев dtostrf
лучше., @Michel Keijzers
теперь работает хорошо. :), @robsworld78
Спасибо за подтверждение, @Michel Keijzers
На attiny85 реальный вопрос заключается в том, почему вы получили поплавок в начале. :), @DataFiddler
@DataFiddler Потому что вам нужен один (?) … или вы имеете в виду, что обычно лучше избегать чисел с плавающей запятой и умножать значение с плавающей запятой на целое число с некоторыми конкретными цифрами (например, используйте целое значение * 1000, чтобы иметь 3 цифры в форме a.bcd ?), @Michel Keijzers
Вы конвертируете float в int. Вероятно, он стал плавать по * 5.0/1023
или подобной ерунде, @DataFiddler
@DataFiddler, я думаю, оператор должен ответить., @Michel Keijzers
- Связь последовательного порта Digispark
- Библиотеки I2C для ATTiny85?
- ATtiny85 Digispark clones failing USB handshake - как их запрограммировать?
- длина провода i2c
- Программирование сервопривода на ATtiny85
- Программирование микроконтроллера Attiny85 без arduino
- Digispark ATtiny 85 - не распознается как HID устройство
- Клавиатура Digispark ATtiny85
отлично спасибо!, @robsworld78