`
hulianwang2014
  • 浏览: 691307 次
文章分类
社区版块
存档分类
最新评论
  • bcworld: 排版成这样,一点看的欲望都没有了
    jfinal

树莓派学习笔记——实现modbus RTU从机

 
阅读更多

0.前言

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

【有用的参考资料】
【1】MODBUS协议整理——汇总——如果您还不熟悉modbus,请你花点时间看看吧。
【2】freemodbus modbus TCP 学习笔记——STM32平台,通过uIP实现modbus TCP从机
【3】MODBUS学习笔记——modbus tk modbus TCP主机实现——使用modbus tk实现modbus TCP主机。平台为PC,无需修改可移植到树莓派。
【4】树莓派学习笔记——UART使用——树莓派UART端口使用,本例中将会使用到该文提到的内容。
【5】树莓派学习笔记——RPi.GPIO 流水灯——GPIO相关操作,本例中将会使用到该文提到的内容。
【6】STM32 移植FreeModbus 详细过程——个人学习modbus的开始

1.modbus tk安装

详见以下博文

2.简单的例子

【说明】
假设树莓派8个可用GPIO端口分别连接LED,在很多工控领域一个LED可称为控制点,在modbus协议中一个控制点被抽象为线圈寄存器,操作相应的线圈寄存器有05H和15H指令。若使用modbus-tk便不必关心modbus协议的具体内容。下面就通过modbus中协议实现树莓派扩展板上LED的控制。
【代码】
#!/usr/bin/env python
# -*- coding: utf_8 -*-
import sys
import logging
import threading
import modbus_tk
import modbus_tk.defines as cst
import modbus_tk.modbus as modbus
import modbus_tk.modbus_rtu as modbus_rtu
import serial
import time
import RPi.GPIO as GPIO
logger = modbus_tk.utils.create_logger(name="console", record_format="%(message)s")
# 创建server
server = modbus_rtu.RtuServer(serial.Serial("/dev/ttyAMA0", 9600))
slaver = server.add_slave(1)
# BCM GPIO编号
pins = [17,18,27,22,23,24,25,4]
def setup():
    # 采用BCM编号
    GPIO.setmode(GPIO.BCM)
    # 设置所有GPIO为输出状态,且输出低电平
    for pin in pins:
        GPIO.setup(pin, GPIO.OUT)
        GPIO.output(pin, GPIO.LOW)
   
    slaver.add_block("coil", cst.COILS, 0, 16)
    slaver.set_values("coil", 0, 16*[0])
       
def loop():
    logger.info("running...")
    # 启动从机
    server.start()
    while True:
        values = slaver.get_values("coil", 0, 8)
        #print values[0]
        for i in range(0, 8):
            if values[i] == 1:
                GPIO.output(pins[i], GPIO.HIGH)
            else:
                GPIO.output(pins[i], GPIO.LOW)
       
        # 必要的延时
        time.sleep(0.5)
def destory():
    logger.info("destory")
    for pin in pins:
        GPIO.output(pin, GPIO.LOW)
        GPIO.setup(pin, GPIO.IN)
   
    # 停止从机
    server.stop()
       
if __name__ == "__main__":
    setup()
    try:
        loop()
    except KeyboardInterrupt:
        destory()


【分析】
【1】server = modbus_rtu.RtuServer(serial.Serial("/dev/ttyAMA0", 9600))
创建一个RTU从机,使用串口/dev/ttyAMA0。请注意server和主机并不是一个概念,这里可能胡产生概念的混淆,这里server可理解为一个设备,而这个设备可以具有多个身份(例如具有多个从机ID)
【2】slaver = server.add_slave(1)
从机编号为1。一个server可以加入多个编号从机。
【3】slaver.add_block("coil", cst.COILS, 0, 16)
创建寄存器,寄存器的别名为coil,寄存器为线圈寄存器(COILS),寄存器起始地址为0,寄存器个数为16.
【4】slaver.set_values("coil", 0, 16*[0])
线圈寄存器的初始值全部为0
【5】values = slaver.get_values("coil", 0, 8)
读取线圈寄存器具体值,线圈寄存器地址从0到7,共8个。

3.测试


图1 modbus rtu测试

4.总结

使用python,借助python扩展库,利用树莓派,原来觉得难以实现的东西现在做起来特别简单。


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics