Добрый день!
В университете поставили задачу получить данные о температуре и влажности с прибора ПВТ100 и вывести их в консоль линукса (Ubuntu 16.04). Общаюсь с оборудованием через ssh. Физически потрогать или что-то сделать не могу (пару раз в день там находятся люди, которых можно попросить что-то сделать). Как мне сказали, там стоит преобразователь USB-to-RS485. (больше мне подробностей не сообщили, но если что-то спросить, то думаю, в ответе проблем у них не будет). Раньше не был знаком в вашей продукцией, как и с интерфейсом RS-485 и протоколом ModBus. Первым делом начал гуглить, что и как. Собственно нашел много всяких примеров, но ни один не смог заставаить работать. Из того, что нашел, пробовал: (информация с этого сайта тык)
Так вот, для начала опробовал я библиотеку modbus-tk, но ничего не вышло (дальше я с ней не разбирался).
Перешёл к библиотеке minimalmodbus и уделил ей больше внимания.
Вот руководство по эксплуотации для моего устройства. От туда взял, что:
- baudrate = 9600
- bytesize = 8
- stopbits = 1
- Контроль четности: отсутствует
- адрес сетевого прибора: 16 (10cc, как я понял)
Далее мне нужно получить данные сначал просто с датчика температуры:
Номер первого регистра (из даташита) = 0x0102 hex или 258 10сс
Собственно вот са код программы: (с использованием minimalmodbus)
Код:
import minimalmodbus
import serial
port = '/dev/ttyUSB0' # serial port
slave_adress = 16 # 10cc
## Number of the first register 0x0102 16cc or 258 10cc ##
hex_number = 102
dec_number = 258
dec_name_number = 2
register_number = dec_name_number
number_of_decimals = 2 # temperature value from -4000 to +12000 C
baudrate = 9600 # from datasheet
bytesize = 8 # from datasheet
stopbits = 1 # from datasheet
timeout = 0.1 # where to get it from?
def main():
print("starting...")
minimalmodbus.BAUDRATE = baudrate
minimalmodbus.TIMEOUT = timeout
instrument = minimalmodbus.Instrument(port, slave_adress, mode='rtu')
instrument.mode = minimalmodbus.MODE_RTU # rtu or ascii mode
print(instrument.read_register(register_number, numberOfDecimals=2, functioncode=3, signed=True)) # Registernumber, number of decimals
instrument.debug = True
main()
print(instrument.read_register(register_number, numberOfDecimals=2, functioncode=3, signed=True))
В документации к данной библиотеке написано, что все используется в 10сс (ссылкаl)
Тогда получается, я ввожу следующие данные:
- register_number = 258 (номер нашего первого регистра в dec)
- numberOfDecimals =2 (тк надо поделить на 100)
- functioncode = 3 (чтение значений из нескольких регистров хранения, в даташите только его можно использовать для чтения, как я понял)
- signed=True (тк мне нужен знак)
При запуске получаю ошибку:
Код:
Traceback (most recent call last):
File "./ModBus_RTU_master.py", line 30, in <module>
main()
File "./ModBus_RTU_master.py", line 27, in main
print(instrument.read_register(register_number, numberOfDecimals=2, functioncode=3, signed=True)) # Registernumber, number of decimals
File "/usr/local/lib/python3.5/dist-packages/minimalmodbus.py", line 258, in read_register
return self._genericCommand(functioncode, registeraddress, numberOfDecimals=numberOfDecimals, signed=signed)
File "/usr/local/lib/python3.5/dist-packages/minimalmodbus.py", line 697, in _genericCommand
payloadFromSlave = self._performCommand(functioncode, payloadToSlave)
File "/usr/local/lib/python3.5/dist-packages/minimalmodbus.py", line 795, in _performCommand
response = self._communicate(request, number_of_bytes_to_read)
File "/usr/local/lib/python3.5/dist-packages/minimalmodbus.py", line 930, in _communicate
raise IOError('No communication with the instrument (no answer)')
OSError: No communication with the instrument (no answer)
Дальше я решил проверить само устройство: (сделал всё, что нашел)
- sudo chmod 0777 /dev/ttyUSB0 (это я ещё сделал первым делом)
Код:
crwxrwxrwx 1 root dialout 188, 0 Jun 21 08:25 /dev/ttyUSB0
Код:
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 0; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread clocal -crtscts
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff
-iuclc -ixany imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt
-echoctl -echoke -flusho -extproc
Дальше решил проверить все slave adress с 1 по 258 для registeradress 1-3 (название прибора по даташиту) и для всех возможных скоростей обмена 1200, 2400, 4800, 9600, 19200, 38400, 57600
Вот код программы:
Код:
import minimalmodbus
import serial
port = '/dev/ttyUSB0' # serial port
slave_adress = 1 # 10cc
## Number of the first register 0x0102 16cc or 258 10cc ##
hex_number = 102
dec_number = 258
register_number = dec_number
number_of_decimals = 1 # temperature value from -4000 to +12000 C
baudrate = 57600 # from datasheet
bytesize = 8 # from datasheet
stopbits = 1 # from datasheet
timeout = 0.1 # where to get it from?
def main():
print("starting...")
minimalmodbus.BAUDRATE = baudrate
minimalmodbus.TIMEOUT = timeout
for baudrate_test in [57600, 38400, 19200, 9600, 4800, 2400, 1200]:
minimalmodbus.BAUDRATE = baudrate_test
print(baudrate_test)
for slave_adress_test in range(247):
instrument = minimalmodbus.Instrument(port, slave_adress_test+1)
for register_number_test in [1, 2, 3]:
try:
print(instrument.read_register(register_number_test, 4, 3, True)) # Registernumber, number of decimals
print("slave adress: " + str(slave_adress_test+1) + " adress: " + str(register_number_test) + " OK")
instrument.debug = True
except:
i = 0
print(slave_adress_test+1)
main()
Дальше я посмотрел вот это на форуме, но я также не смог ничего дельного получуть.
Я прошу вас мне помочь или направить в какую-нибудь сторону, тыкнуть в ошибку. Мне необходимо после выходных сдать эту работу, а пока я ничего не смог получить с данного устройства.
PS
Появилась информация о переходнике: Silicon Labs CP210x USB to UART Bridge
Также теперь есть возможность подключаться дистанционно через teamviewer
Заранее вам спасибо!