回答

收藏

[教程] 【一网打尽】使用树莓派实现MODBUS RTU协议

Raspberry Pi Raspberry Pi 9059 人阅读 | 0 人回复 | 2015-03-26

本文使用树莓派实现MODBUS RTU从机,借助python库——modbus-tk实现RTU从机。

MODBUS是一种灵活可靠的工业通信协议,常用的MODBUS协议包括MODBUS RTU和MODBUS TCP。借助python强大的库函数,可以在树莓派平台上非常方便的实现MODBUS主机和从机,MODBUS RTU和TCP,甚至一个树莓派既可以跑MODBUS RTU主机也可以同时跑MODBUS TCP从机。相比于其他平台(例如STM32),在树莓派上实现modbus真的太简单了。

假设树莓派8个可用GPIO端口分别连接LED,在很多工控领域一个LED可称为控制点,在modbus协议中一个控制点被抽象为线圈寄存器,操作相应的线圈寄存器有05H和15H指令。若使用modbus-tk便不必关心modbus协议的具体内容。

下面就通过modbus中协议实现树莓派扩展板上LED的控制。


  1. #!/usr/bin/env python
  2. # -*- coding: utf_8 -*-
  3. import sys
  4. import logging
  5. import threading
  6. import modbus_tk
  7. import modbus_tk.defines as cst
  8. import modbus_tk.modbus as modbus
  9. import modbus_tk.modbus_rtu as modbus_rtu
  10. import serial
  11. import time
  12. import RPi.GPIO as GPIO
  13. logger = modbus_tk.utils.create_logger(name="console", record_format="%(message)s")
  14. # 创建server
  15. server = modbus_rtu.RtuServer(serial.Serial("/dev/ttyAMA0", 9600))
  16. slaver = server.add_slave(1)
  17. # BCM GPIO编号
  18. pins = [17,18,27,22,23,24,25,4]
  19. def setup():
  20.     # 采用BCM编号
  21.     GPIO.setmode(GPIO.BCM)
  22.     # 设置所有GPIO为输出状态,且输出低电平
  23.     for pin in pins:
  24.         GPIO.setup(pin, GPIO.OUT)
  25.         GPIO.output(pin, GPIO.LOW)
  26.    
  27.     slaver.add_block("coil", cst.COILS, 0, 16)
  28.     slaver.set_values("coil", 0, 16*[0])
  29.       
  30. def loop():
  31.     logger.info("running...")
  32.     # 启动从机
  33.     server.start()
  34.     while True:
  35.         values = slaver.get_values("coil", 0, 8)
  36.         #print values[0]
  37.         for i in range(0, 8):
  38.             if values[i] == 1:
  39.                 GPIO.output(pins[i], GPIO.HIGH)
  40.             else:
  41.                 GPIO.output(pins[i], GPIO.LOW)
  42.       
  43.         # 必要的延时
  44.         time.sleep(0.5)
  45. def destory():
  46.     logger.info("destory")
  47.     for pin in pins:
  48.         GPIO.output(pin, GPIO.LOW)
  49.         GPIO.setup(pin, GPIO.IN)
  50.    
  51.     # 停止从机
  52.     server.stop()
  53.       
  54. if __name__ == "__main__":
  55.     setup()
  56.     try:
  57.         loop()
  58.     except KeyboardInterrupt:
  59.         destory()
复制代码

测试图片:



分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条