Форум сайта python.su
Добрый день!
Модуль использует python 1.5.
Мне нужно читать modbus Rtu ответы от прибора.
Модуль не дает возможность использовать внешние библиотеки…
Вот пример ответа прибора на запрос (Modbus RTU):
10 03 04 E1 35 41 EE 6D 1C = где получаем число 29.85 (float_32 ieee754)
Понял что нужно сделать вот так: 41EEE135
Можете помочь кодом? Как получить это число?
Офлайн
import struct s = '\x10\x03\x04\xE1\x35\x41\xEE\x6D\x1C' value = struct.unpack('>f', s[5]+s[6]+s[3]+s[4])[0] print value
Офлайн
PooHСпасибо за ответ.
Офлайн
Ну вот как-то так. Без оптимизаций, тупо в лоб, возможно с косяками.
s = '\x10\x03\x04\xE1\x35\x41\xEE\x6D\x1C' ls = map(lambda x: int(x.encode('hex'), 16), s) #не знаю в каком у вас виде, я перевел строку в массив целых def mantiss2float(mantiss, exp): r = exp and 1.0 or 0.0 # обработка денормализованого представления c = 0.5 byte = (mantiss >> 16) & 0xFF for i in range(1, 8): if (byte << i) & 0b10000000: r += c c = c / 2.0 byte = (mantiss >> 8) & 0xFF for i in range(8): if (byte << i) & 0b10000000: r += c c = c / 2.0 byte = mantiss & 0xFF for i in range(8): if (byte << i) & 0b10000000: r += c c = c / 2.0 return r sign = (ls[5] & 0b10000000) and -1 or 1 exp = (ls[5] << 1) | (ls[6] >> 7) mantiss = ((ls[6] & 0b1111111) << 16) | (ls[3] << 8) | ls[4] value = sign * 2**(exp-127) * mantiss2float(mantiss, exp) print sign, exp, mantiss print value
Отредактировано PooH (Авг. 11, 2016 17:38:18)
Офлайн
PooH
Ну вот как-то так. Без оптимизаций, тупо в лоб, возможно с косяками.
def pow2(n): if not n: return 0 elif n == 1: return 1 else: r = 1 for i in range(n): r = r* 2 return r def mantiss2loat(mantiss, exp): r = exp and 1.0 or 0.0 c = 0.5 byte = (mantiss >> 16) & 0xFF for i in range(1, 8): if ((byte << i) & '0b10000000'): r = r + c c = c / 2.0 byte = (mantiss >> 8) & 0xFF for i in range(8): if (byte << i) & '0b10000000': r = r + c c = c / 2.0 byte = mantiss & '0xFF' for i in range(8): if (byte << i) & '0b10000000': r = r + c c = c / 2.0 return r s = '\x10\x03\x04\xE1\x35\x41\xEE\x6D\x1C' ls = map(lambda x: int(x.encode('hex'), 16), s) sign = (ls[5] & '0b10000000') and -1 or 1 exp = (ls[5] << 1) | (ls[6] >> 7) mantiss = ((ls[6] & '0b1111111') << 16) | (ls[3] << 8) | ls[4] value = sign * pow2(exp-127) * mantiss2loat(mantiss, exp) print sign, exp, mantiss print 'Val = ' print value
Офлайн
Svetтам позже я выкинул pow2. какие ошибки в коде? как выглядит “не работает”? неверный результат или что?
Код давал ошибки, немного подредактировал, но в модуле он почему-то не работает, видимо не может выполнить написанные функции
Офлайн
PooHПопробовал исправленный второй вариант, тоже не стартует.
def mantiss2float(mantiss, exp): r = exp and 1.0 or 0.0 c = 0.5 byte = (mantiss >> 16) & 0xFF for i in range(1, 8): if (byte << i) & '0b10000000': r = r+c c = c / 2.0 byte = (mantiss >> 8) & 0xFF for i in range(8): if (byte << i) & '0b10000000': r = r+c c = c / 2.0 byte = mantiss & 0xFF for i in range(8): if (byte << i) & '0b10000000': r = r+c c = c / 2.0 return r
Отредактировано Svet (Авг. 12, 2016 11:56:21)
Прикреплённый файлы:
The_neglected_art_of_Fixed_Point_arithmetic_20060913.pdf (208,3 KБ)
Офлайн
Как оказалось python 1.5 не умеет целые в двоичном виде(блин чувствую себя некрофилом).
Замените двоичные константы на шестнадцатиричные 0b10000000 на 0x80, 0b1111111 на 0x7F
ЗЫ: презенташка вообще левая, при чем тут фиксированная точка?!
Отредактировано PooH (Авг. 12, 2016 12:05:18)
Офлайн
Я еще заметил, что в том коде, что вы запостили поехали отступы, я, надеюсь, вы понимаете, что соблюдение отступов критично?
Офлайн
да, про отступы в курсе. Это при копировании почему-то уехал код, в ide все нормально, перепроверял.
Заменил двоичные константы на шестнадцатиричные, почему-то так же скрипт в модуле не стартанул…
Вот еще мануал по модулю python Скачать….
Офлайн