树莓派学习笔记——实现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 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)
【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扩展库,利用树莓派,原来觉得难以实现的东西现在做起来特别简单。