Я пытаюсь подключить адаптер RS485 в UART для связи через Modbus на Raspberry Pi. Моя конечная цель - заставить все это работать с приложением Node, но до сих пор мой разработчик работал с Python.
Мое аппаратное соединение выглядит так:
[Modbus-Device] <===> [RS485 chip <==> Raspberry PI GPIO] контакты. RS485 имеет три провода (Transmit, Receive, Direction), к которым они подключены следующим образом
RaspiPi <=> Адаптер
GPIO 14 (8) - Tx <=> Data +
GPIO 15 (10) - Rx <=> - Данные-
GPIO 18 (12) - Направление
RS485 не является типичным 9-контактным адаптером. У меня три провода от чипа. Витая пара, которая служит дифференциальным набором и проводом заземления.
Мне удалось отправить последовательный обмен данными между этим adpater и адаптером USB-RS485, вручную перевернув GPIO18 для отправки / получения. (Код ниже) [1]. Этот код предназначен исключительно для проверки работоспособности адаптера
Я застрял при работе с Modbus на адаптере GPIO. Я пробовал использовать минимальную шину, которая хорошо работает с адаптером USB-RS485, но не работает с адаптером GPIO. Я подозреваю, что это потому, что направляющий штифт не устанавливается.
Идеальным решением было бы найти драйвер RS485 для GPIO на пи, но если не считать этого, я вижу три варианта
1 - Создайте свой собственный драйвер (что-то, с чем я совершенно не знаком)
2 - Каким-то образом получить библиотеку Modbus, чтобы перевернуть вывод GPIO в пространстве ядра
3 - Вручную отправьте сообщения Modbus через последовательный порт и отрегулируйте вывод GPIO в пространстве пользователя. Это кажется самым простым, но и худшим с точки зрения скорости и надежности. Моя попытка кода ниже [2]
Любой совет на эту тему был бы очень признателен. Если кто-то делал что-то подобное раньше и мог бы взвесить мои варианты, это было бы полезно. Я никогда не работал над программным обеспечением на этом уровне, поэтому я не нахожу удивительным, если бы был какой-то очевидный ответ, который я полностью игнорирую.
[1] Этот код связывается с другим адаптером RS485 на Raspberry Pi, подключенном через USB. Это было написано, чтобы доказать, что адаптер GPIO работает, и что я могу контролировать направление с помощью Pin 12 на Raspberry pi
import time
import serial
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT);
ser = serial.Serial(
port= '/dev/ttyS0',
baudrate= 57600,
parity= serial.PARITY_NONE,
stopbits= serial.STOPBITS_ONE,
bytesize= serial.EIGHTBITS,
timeout=1
)
def write_add():
counter = 0;
message = 0
while (True):
print "writing",
GPIO.output(12,1) #set high/transmit
ser.write('%d \n'%(message))
time.sleep(0.005) #baud for 57600
#time.sleep(0.5) #baud for 9600
GPIO.output(12, 0) #pin set to low/receive
loop_count = 0
res =""
while (res == ""):
res =ser.readline();
if(res != ""):
print ""
print "Read Cycles: "+str(loop_count)+" Total: "+str(counter)
print res
message = int(res) + 1
counter = counter + 1
elif(loop_count > 10):
res = "start over"
else:
print ".",
loop_count = loop_count + 1
write_add()
[2] Этот код пытается установить связь с другим устройством Modbus. Мое сообщение отправляется, но ответ - garabge. Я предполагаю, что указатель направления GPIO переворачивается либо слишком рано и отключает сообщение, либо слишком поздно и пропускает часть ответа.
import serial
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)
ser = serial.Serial(
port='/dev/ttyS0',
baudrate = 57600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
GPIO.output(12,1) #set high/transmit
ByteStringToSend = "\x00\x03\x01\xb8\x00\x01\x04\x02"
ser.write(ByteStringToSend)
time.sleep(0.005) #baud for 57600
GPIO.output(12, 0) #pin set to low/receive
ReceivedData = ""
while (ReceivedData == ""):
RecievedData = ser.readline();
print RecievedData
[3] Рабочий код USB-RS-485. USB-адаптер на Pi, подключенный к устройству Modbus. Этот код читает регистр 440 каждую секунду.
#1/usr/bin/env python
import minimalmodbus
import time
print minimalmodbus._getDiagnosticString()
minimalmodbus.BAUDRATE=57600
minimalmodbus.PARITY='N'
minimalmodbus.BYTESIZE=8
minimalmodbus.STOPBITS=1
minimalmodbus.TIMEOUT=0.1
instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 0) #port and slave
#instrument.debug = True
while True:
batterVolt = instrument.read_register(440, 2) #register number, number decimals
print batterVolt
time.sleep(1)
Редактировать: Уточненная схема.
Edit2: дополнительно уточнена схема и добавлен / отредактирован код