Форум сайта python.su
0
Добрый день!
Модуль использует python 1.5.
Мне нужно читать modbus Rtu ответы от прибора.
Модуль не дает возможность использовать внешние библиотеки…
Вот пример ответа прибора на запрос (Modbus RTU):
10 03 04 E1 35 41 EE 6D 1C = где получаем число 29.85 (float_32 ieee754)
Понял что нужно сделать вот так: 41EEE135
Можете помочь кодом? Как получить это число?
Офлайн
72
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
Офлайн
0
PooHСпасибо за ответ.
Офлайн
72
Ну вот как-то так. Без оптимизаций, тупо в лоб, возможно с косяками.
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)
Офлайн
0
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
Офлайн
72
Svetтам позже я выкинул pow2. какие ошибки в коде? как выглядит “не работает”? неверный результат или что?
Код давал ошибки, немного подредактировал, но в модуле он почему-то не работает, видимо не может выполнить написанные функции
Офлайн
0
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Б)
Офлайн
72
Как оказалось python 1.5 не умеет целые в двоичном виде(блин чувствую себя некрофилом).
Замените двоичные константы на шестнадцатиричные 0b10000000 на 0x80, 0b1111111 на 0x7F
ЗЫ: презенташка вообще левая, при чем тут фиксированная точка?!
Отредактировано PooH (Авг. 12, 2016 12:05:18)
Офлайн
72
Я еще заметил, что в том коде, что вы запостили поехали отступы, я, надеюсь, вы понимаете, что соблюдение отступов критично?
Офлайн
0
да, про отступы в курсе. Это при копировании почему-то уехал код, в ide все нормально, перепроверял.
Заменил двоичные константы на шестнадцатиричные, почему-то так же скрипт в модуле не стартанул…
Вот еще мануал по модулю python Скачать….
Офлайн