Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 9, 2016 19:48:30

Svet
Зарегистрирован: 2016-08-09
Сообщения: 18
Репутация: +  0  -
Профиль   Отправить e-mail  

Чтение modbus RTU запроса python 1.5

Добрый день!
Модуль использует python 1.5.
Мне нужно читать modbus Rtu ответы от прибора.
Модуль не дает возможность использовать внешние библиотеки…

Вот пример ответа прибора на запрос (Modbus RTU):
10 03 04 E1 35 41 EE 6D 1C = где получаем число 29.85 (float_32 ieee754)
Понял что нужно сделать вот так: 41EEE135
Можете помочь кодом? Как получить это число?

Офлайн

#2 Авг. 10, 2016 11:58:32

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Чтение modbus RTU запроса python 1.5

 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



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

#3 Авг. 11, 2016 10:13:11

Svet
Зарегистрирован: 2016-08-09
Сообщения: 18
Репутация: +  0  -
Профиль   Отправить e-mail  

Чтение modbus RTU запроса python 1.5

PooH
Спасибо за ответ.
Но интерпретатор python в модуле Telit не может работать с внешней библиотекой struct.
Подскажите как можно это написать без такой библиотеки?

Офлайн

#4 Авг. 11, 2016 12:59:44

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Чтение modbus RTU запроса python 1.5

Ну вот как-то так. Без оптимизаций, тупо в лоб, возможно с косяками.

 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)

Офлайн

#5 Авг. 12, 2016 10:13:51

Svet
Зарегистрирован: 2016-08-09
Сообщения: 18
Репутация: +  0  -
Профиль   Отправить e-mail  

Чтение modbus RTU запроса python 1.5

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

Офлайн

#6 Авг. 12, 2016 10:45:38

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Чтение modbus RTU запроса python 1.5

Svet
Код давал ошибки, немного подредактировал, но в модуле он почему-то не работает, видимо не может выполнить написанные функции
там позже я выкинул pow2. какие ошибки в коде? как выглядит “не работает”? неверный результат или что?



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

#7 Авг. 12, 2016 11:55:12

Svet
Зарегистрирован: 2016-08-09
Сообщения: 18
Репутация: +  0  -
Профиль   Отправить e-mail  

Чтение modbus RTU запроса python 1.5

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 с презентации, который может помочь. Прикрепил.

Отредактировано Svet (Авг. 12, 2016 11:56:21)

Прикреплённый файлы:
attachment The_neglected_art_of_Fixed_Point_arithmetic_20060913.pdf (208,3 KБ)

Офлайн

#8 Авг. 12, 2016 12:04:26

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Чтение modbus RTU запроса python 1.5

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

ЗЫ: презенташка вообще левая, при чем тут фиксированная точка?!



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Отредактировано PooH (Авг. 12, 2016 12:05:18)

Офлайн

#9 Авг. 12, 2016 12:15:45

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Чтение modbus RTU запроса python 1.5

Я еще заметил, что в том коде, что вы запостили поехали отступы, я, надеюсь, вы понимаете, что соблюдение отступов критично?



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

#10 Авг. 12, 2016 12:31:11

Svet
Зарегистрирован: 2016-08-09
Сообщения: 18
Репутация: +  0  -
Профиль   Отправить e-mail  

Чтение modbus RTU запроса python 1.5

да, про отступы в курсе. Это при копировании почему-то уехал код, в ide все нормально, перепроверял.
Заменил двоичные константы на шестнадцатиричные, почему-то так же скрипт в модуле не стартанул…

Вот еще мануал по модулю python Скачать….

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version