Передача Значений С Плавающей Точкой Через Технология Сети
У меня возникли проблемы с передачей поплавка через простую 2-узловую сеть Xbee.
Я знаю, что система Xbee передает пакеты через байты, поэтому я могу отправить символ, но у меня возникли проблемы с отправкой чего-либо большего, и я, кажется, нигде не могу найти никакой документации.
Вот мой текущий (базовый) код.
Отправитель:
(... appropriate setup...)
void loop()
{
sensorValue = analogRead(analogInPin);
sensorValueTemp = sensorValue / 9.31; //LM35 measurement into Centigrade
Serial.print(sensorValueTemp);
delay(1000);
}
Приемник:
(...appropriate setup...)
void loop() {
lcd.setCursor(0, 0);
if (Serial.available() > 0) {
lcd.print(incomingByte);
}
delay(1000);
}
Любой намек на то, чтобы заставить поплавок успешно передаваться, был бы отличным? Или если это уже так будучи правильно передан, как правильно его прочитать?
Спасибо
3 ответа:
Вы можете отправить
float
в байтах и восстановитьfloat
в приемнике.Вам может помочь следующий пример:
Сторона отправителя:
float x = 1128.476; char b[sizeof(x)]; memcpy(b, &x, sizeof(x)); // Iterate over b and send bytes // [...]
Сторона приемника:
В конце концов, у вас естьfloat y = 0; char b[sizeof(x)]; // Store 4 bytes representing the float into b // [...] // Rebuild the float memcpy(&y, b, sizeof(y));
float y
на стороне получателя, которая имеет такое же представлениеfloat x
на стороне отправителя.
Вы можете отправлять все двоичные данные, которые вы хотите, между двумя машинами одинаковой архитектуры, компоновки памяти, байт-эндианнеса и т. д. просто беря указатель размером с байт
(char *)
на стороне "отправки" и повторяя по объекту ссылки для количества байтов в этом объекте. На "принимающей" стороне, вы выделяете объект того же размера (поплавок, длинный, структуру struct foo), и получив байт, один байт-размер указателя, который после увеличивается после каждого байта полученный.На стороне отправителя --
void sendObject(const void *object, size_t size) { char *outputCursor = (char *) object; for (;size > 0;size--) yourSendAByteFunction(*outputCursor++); }
На принимающей стороне, предполагая, что функция yourReceiveAByteFunction () возвращает 0..255 для допустимого байта и -1 для "ошибки приема", вы можете сделать это --
int receiveObject(void *object, size_t size) { char *inputCursor = (char *) object; for (;size > 0;size--) { int nextByte = yourReceiveAByteFunction(); if (nextByte < 0) return FALSE; *inputCursor++ = nextByte; } return TRUE; }
Вы можете выполнить ту же проверку ошибок ввода-вывода в функции
sendObject()
, объявивyourSendAByteFunction()
, чтобы она возвращалаTRUE
илиFALSE
в зависимости от того, произошла ли ошибка в выводе. Все зависит от того, какую сложность вы можете выдержать, и есть ли у вас надежная передача ссылка.Вы также можете сделать бит инкапсуляции данных, если у вас есть байты, которые вы не можете передать, имея байт "shift" и набор байтовых значений, которые предваряются байтом "shift", чтобы представлять какой-то другой байт.
Ваш исходный отправитель отправляет строку ASCII, представляющую значение float.
Чтобы получить и отобразить значение, вам нужно изменить строки, как показано ниже:
(...appropriate setup...) void loop() { lcd.setCursor(0, 0); while (Serial.available() > 0) { //Changed Line incomingByte = Serial.read(); //Added Line lcd.print(incomingByte); } delay(1000); }
Примечание: Если было бы лучше завершить последовательный выход с помощью CR для синхронизации устройств вместо задержки(1000);