Мне нужно получить закодированные в шестнадцатеричном формате значения с плавающей запятой с одинарной точностью, поступающие из Arduino по последовательной линии (RS-232). Как преобразовать их в число с плавающей точкой Python, которые являются порядковыми номерами с двойной точностью?
Arduino отправляет что-то вроде "8192323E", а в Python я хотел бы иметь 0,174387. Я нашел « Преобразовать гекс в число с плавающей точкой », но кажется, что все они не работают с плавающей точкой одинарной точности.
На связанной странице это выглядит многообещающе:
from ctypes import *
def convert(s):
i = int(s, 16) # convert from hex to a Python int
cp = pointer(c_int(i)) # make this into a c integer
fp = cast(cp, POINTER(c_float)) # cast the int pointer to a float pointer
return fp.contents.value # dereference the pointer, get the float
Но это все равно не работает с моими поплавками одинарной точности.
В Java ( Обработка ) я смог сделать это:
float decodeFloat(String inString) {
byte [] inData = new byte[4];
inString = inString.substring(2, 10); // discard the leading "f:"
inData[0] = (byte) unhex(inString.substring(0, 2));
inData[1] = (byte) unhex(inString.substring(2, 4));
inData[2] = (byte) unhex(inString.substring(4, 6));
inData[3] = (byte) unhex(inString.substring(6, 8));
int intbits = (inData[3] << 24) | ((inData[2] & 0xff) << 16) | ((inData[1] & 0xff) << 8) | (inData[0] & 0xff);
//unhex(inString.substring(0, 8));
return Float.intBitsToFloat(intbits);
}
Для справки, это код C, работающий на Arduino, реализующий шестнадцатеричное кодирование.
void serialFloatPrint(float f) {
byte * b = (byte *) &f;
Serial.print("f:");
for(int i=0; i<4; i++) {
byte b1 = (b[i] >> 4) & 0x0f;
byte b2 = (b[i] & 0x0f);
char c1 = (b1 < 10) ? ('0' + b1) : 'A' + b1 - 10;
char c2 = (b2 < 10) ? ('0' + b2) : 'A' + b2 - 10;
Serial.print(c1);
Serial.print(c2);
}
}