簡體   English   中英

Raspberry Pi RS485 / Uart Modbus

[英]Raspberry Pi RS485/Uart Modbus

我試圖在UART上連接一個RS485適配器,通過Raspberry Pi上的modbus進行通信。 我的最終目標是讓所有這些都與Node應用程序一起工作,但到目前為止,我的開發人員一直使用Python。

我的硬件連接如下:

[Modbus-Device] <===> [RS485芯片<==> Raspberry PI GPIO]引腳。 RS485有三條線(發送,接收,方向),它們按如下方式連接

RaspiPi <=> 適配器

GPIO 14(8) - Tx <=>數據+

GPIO 15(10) - Rx <=> - 數據 -

GPIO 18(12) - 方向

RS485不是典型的9針適配器。 我有三根電線在芯片上運行。 雙絞線,用作差動裝置和地線。

通過手動翻轉GPIO18進行發送/接收,我能夠在此adpater和USB-RS485適配器之間發送串行通信。 (以下代碼)[1]。 此代碼純粹用於證明適配器的工作原理

我堅持讓modbus在GPIO適配器上工作。 我嘗試過使用minimalmodbus,它可以很好地與USB-RS485適配器配合使用,但是在GPIO適配器上失敗了。 我懷疑這是因為沒有設置方向引腳。

理想的解決方案是在pi上為GPIO找到一個RS485驅動程序,但我沒看到三個選項

1 - 制作我自己的驅動程序(我完全不熟悉的東西)2 - 以某種方式獲得一個modbus庫來翻轉內核空間中的GPIO引腳3 - 手動通過串行發送modbus消息並調整用戶空間中的GPIO引腳。 在速度和可靠性方面,這似乎是最簡單但也是最差的。 我的代碼嘗試低於[2]

關於這個主題的任何建議都將非常感激。 如果有人之前做過類似的事情並且可以權衡我的選擇,這會有所幫助。 我從來沒有在這個級別的軟件上工作,所以如果有一些明顯的答案我完全忽略了,我就不會感到驚訝。

[1]此代碼與連接USB的樹莓派上的另一個RS485適配器通信。 這是為了證明GPIO適配器正在工作,我可以用Raspberry pi上的Pin 12控制方向

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設備通信。 我的消息正在發送,但響應是嘎嘎嘎嘎。 我的假設是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代碼。 Pi上的USB適配器連接到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:進一步闡明了方案和添加/編輯的代碼

示例-2中的代碼實際上可以正常工作。 我只需要格式化響應。

print RecievedData.encode('hex')

這將以modbus響應格式給出十六進制字符串。 正如Andrej Debenjak所提到的,time.sleep (x)將取決於波特率和消息大小。

旁注:我發現這個頁面有助於破譯modbus傳輸。

http://www.modbustools.com/modbus.html

編輯:我發送的ByteString不適用於正確的modbus設置。 第一個字節x00是廣播字節,不應該請求響應。 看起來我正在使用的硬件有一些時髦的東西。 在典型的modbus設置中,您需要解決您嘗試與之通信的設備。 感謝Marker指出這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM