首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >树莓Pi Pi 485/Uart Modbus

树莓Pi Pi 485/Uart Modbus
EN

Stack Overflow用户
提问于 2018-05-16 17:19:33
回答 1查看 11.1K关注 0票数 6

我试图让一个RS485适配器连接在UART上,通过Raspberry上的modbus进行通信。我的最终目标是让所有这些都可以用于Node应用程序,但到目前为止,我的开发已经使用了Python。

我的硬件连接看起来如下:

Modbus-设备<===> RS485芯片<==>覆盆子PI GPIO引脚。RS485有三条线(发送、接收、指示),它们按以下方式连接

RaspiPi <=> 适配器

GPIO 14 (8) - Tx <=> Data+

GPIO 15 (10)- Rx <=>-数据-

GPIO 18 (12) -方向

RS485不是一个典型的9引脚适配器.一片芯片上有三根电线。作为差速器和地线的双绞线。

我已经能够发送串行通信之间的这个加载机和一个USB 485适配器手动翻转GPIO18发送/接收。(下面的代码)1.这段代码纯粹是为了证明适配器工作

我被困在让modbus在GPIO适配器上工作。我试过使用minimalmodbus,它可以很好地工作在USB 485适配器上,但是对GPIO适配器失败了。我怀疑这是因为方向针没有被设置好。

理想的解决方案是在pi上为GPIO找到一个RS485驱动程序,但除此之外,我看到了三个选项

让我自己的驱动程序(我完全不熟悉的东西)2-得到一个modbus库翻转GPIO引脚在内核空间3-手动发送modbus消息通过串行和调整GPIO引脚在用户空间。就速度和可靠性而言,这似乎是最简单的,但也是最差的。我的代码尝试低于2

如能就这一问题提出任何建议,将不胜感激。如果有人曾经做过类似的事情,并能在我的选择中发挥作用,那将是有帮助的。我从来没有在这个层次上研究过软件,所以如果有一些明显的答案我完全忽略了,我就不会感到惊讶了。

1此代码与与USB连接的raspberry pi上的另一个RS485适配器进行通信。这是为了证明GPIO适配器是工作的,我可以在Raspberry pi上用Pin 12控制方向。

代码语言:javascript
复制
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的方向引脚正被翻转,要么太快,要么切断消息,要么太晚了,丢失了一些响应。

代码语言:javascript
复制
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。

代码语言:javascript
复制
#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:进一步明确的方案和添加/编辑的代码

EN

回答 1

Stack Overflow用户

发布于 2018-05-17 19:12:46

示例2中的代码实际上工作正常。我只需要格式化回应。

代码语言:javascript
复制
print RecievedData.encode('hex')

这将以modbus响应格式给出十六进制字符串。正如Andrej所暗示的,time.sleep(x)将取决于波特率和消息大小。

附带注意:我发现这个页面在解码modbus传输方面很有帮助。

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

编辑:我发送的 ByteString不应该在适当的modbus设置上工作。第一个字节x00是广播字节,不应该请求响应。看来我正在使用的硬件有一些古怪的东西在进行。在典型的modbus设置中,您需要处理要与哪个设备通信的地址。谢谢马克指出这一点。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50376697

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档