Найти - Пользователи
Полная версия: Чтение modbus RTU запроса python 1.5
Начало » Mobile Python » Чтение modbus RTU запроса python 1.5
1 2 3 4
Svet
Добрый день!
Модуль использует python 1.5.
Мне нужно читать modbus Rtu ответы от прибора.
Модуль не дает возможность использовать внешние библиотеки…

Вот пример ответа прибора на запрос (Modbus RTU):
10 03 04 E1 35 41 EE 6D 1C = где получаем число 29.85 (float_32 ieee754)
Понял что нужно сделать вот так: 41EEE135
Можете помочь кодом? Как получить это число?
PooH
 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
Svet
PooH
Спасибо за ответ.
Но интерпретатор python в модуле Telit не может работать с внешней библиотекой struct.
Подскажите как можно это написать без такой библиотеки?
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
Svet
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

PooH
Svet
Код давал ошибки, немного подредактировал, но в модуле он почему-то не работает, видимо не может выполнить написанные функции
там позже я выкинул pow2. какие ошибки в коде? как выглядит “не работает”? неверный результат или что?
Svet
PooH
Попробовал исправленный второй вариант, тоже не стартует.
“Не работает” - это я загружаю pyo скрипт в модуль, и даю команду на запуск. Python на win проверяет и собирает скрипт. А вот сам модуль почему-то не может его обработать…
А ошибки я могу видеть, когда модуль смог запустить скрипт, но не смог что-то выполнить…
Если удаляю функцию, то скрипт стартует, но ругается на отсутствие функции.
Так же скрипт не запускается даже если просто в код вставить функцию эту без вызова ее из кода…
 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

Если 0b10000000 оставить так, то скрипт не собирается, ругается на эту строку. Если делаю так: ‘0b10000000’ то скрипт собирается, но скрипт в самом модуле не работает.

Пробовал писать в тех.поддержку модуля, ответили, что есть pdf с презентации, который может помочь. Прикрепил.
PooH
Как оказалось python 1.5 не умеет целые в двоичном виде(блин чувствую себя некрофилом).
Замените двоичные константы на шестнадцатиричные 0b10000000 на 0x80, 0b1111111 на 0x7F

ЗЫ: презенташка вообще левая, при чем тут фиксированная точка?!
PooH
Я еще заметил, что в том коде, что вы запостили поехали отступы, я, надеюсь, вы понимаете, что соблюдение отступов критично?
Svet
да, про отступы в курсе. Это при копировании почему-то уехал код, в ide все нормально, перепроверял.
Заменил двоичные константы на шестнадцатиричные, почему-то так же скрипт в модуле не стартанул…

Вот еще мануал по модулю python Скачать….
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB