Wie im folgenden Quellcode zu erkennen möchte ich mit meinem RPi3, als Modbusmaster, mehrere Slaves (Arduino Nano) abfragen bzw. deren Holding_Register auslesen. Dies klappt soweit auch ganz gut. Es gibt aber zwei Scenarien bei denen mir das jetzige Script mit einem Fehler abbricht. Aktuell ist das Script so eingestellt, dass statisch 10 Slaves abgefragt werden, zukünftig würde ich das Script so anpassen, dass die bei 4bit-Adresscodierung maximale Anzahl an Slaves abgefragt werden sollen, also max. 15 request´s.
1. Die Anzahl der Slaves ist u.U. nicht immer gleich
2. Das Klimadatenmesssystem soll schnellstmöglich an den Start gehen auch wenn noch nicht alle Slaves bauseitig installiert sind
3. Es kann durchaus sein, dass ich noch einen Raum mehr messtechnisch erfassen möchte, dann soll aber das Script nicht dafür angefasst werden müssen
Wie in einem vorherigen Thread schon erwähnt, die print()´s dienen derzeit nur zu Entwicklungszwecken bis die Daten in die SQL-Datenbank geschrieben werden. Sofern einer von X Slaves nicht erreichbar ist, schreibe ich dann 0-Werte in die DB oder lasse den Eintrag weg - das ist ein anderes Thema.
Jetzt habe ich mich schon etwas mit Pymodbus und den mitgelieferten Modulen beschäftigt, kann aber für RTU irgendwie keine Möglichkeit finden Slaves, sozusagen, auf Existens oder Status=Online zu überprüfen. Hat dazu jemand von euch Erfahrenen einen Lösungsansatz?
#! /usr/bin python
# -*- coding: utf-8 -*-
import time
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
# Only activated when Debugging
# import logging
# logging.basicConfig()
# log = logging.getLogger()
# log.setLevel(logging.DEBUG)
# Binärcodierung der Räume:
# -------------------------------------
# Binär Raum Slave-ID
# -------------------------------------
# 0000 = broadcast 0
# 0001 = Kind Ost 1
# 0010 = Badezimmer 2
# 0011 = Schlafzimmer 3
# 0100 = Kind West 4
# 0101 = Flur OG 5
# 0110 = Spitzboden 6
# 0111 = Aussen 7
# 1000 = Kueche 8
# 1001 = Flur EG 9
# 1010 = Flur UG 10
Debug_Mode = 0
Delay = 0.2
runSlaves = 1
AnzMessungen = 15
runAllOver = 1
Slave = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Room = ['Broadcast', 'Kind Ost', 'Badezimmer', 'Schlafzimmer', 'Kind West', 'Flur OG', 'Spitzboden', 'Aussen', 'Kueche', 'Flur EG', 'Flur UG']
def Verbindung_LeseRegister(runSlaves):
client = ModbusClient(method="rtu", port="/dev/ttyUSB0", stopbits=2, bytesize=8, parity='N', baudrate=9600, timeout=7)
client.connect()
""" time.sleep(Delay) """
# Starting add, num of reg to read, slave unit.
Slave[runSlaves] = client.read_holding_registers(0000, 4, unit=runSlaves)
# Close connection
client.close()
return Slave
def Messung_Klimadaten(runSlaves):
Temperature = 0
Humidity = 0
Heatindex = 0
DHT_Error = 0
print ("Start Measuring... please wait for ") + str( Delay*AnzMessungen)+ str(" seconds...")
# Fuehre N Messungen aus und speichere dann den Mittelwert
for MessungNr in range(AnzMessungen):
try:
Verbindung_LeseRegister(runSlaves)
Temperature = Temperature+float(Slave[runSlaves].getRegister(0))/100
Humidity = Humidity+float(Slave[runSlaves].getRegister(1))/100
Heatindex = Heatindex+float(Slave[runSlaves].getRegister(2))/100
DHT_Error = DHT_Error+Slave[runSlaves].getRegister(3)
if Debug_Mode == 1:
print("Messvorgang ") + str(MessungNr) + str(" aus ") + str(Room[runSlaves]) + str(" ") + str(Temperature)
MessungNr = MessungNr+1
time.sleep(Delay)
except (KeyboardInterrupt, SystemExit):
print ("Messung Klimadaten abgebrochen")
raise
Temperature = round(Temperature/AnzMessungen, 2)
Humidity = round(Humidity/AnzMessungen, 2)
Heatindex = round(Heatindex/AnzMessungen, 2)
return Temperature, Humidity, Heatindex, DHT_Error
while True:
try:
ReturnValue = Messung_Klimadaten(runSlaves)
if ReturnValue[3] == 0:
print ("|+++++++++++++++++++++++++++++++++++++++++++|")
print (" ")
print ("Temperatur ") + str(Room[runSlaves]) + str(" ") + str(ReturnValue[0]) + str(" °C")
print (" ")
print ("Luftfeuchtgikeit ") + str(Room[runSlaves]) + str(" ") + str(ReturnValue[1]) + str(" %")
print (" ")
print ("Gefuehlte Temperatur ") + str(Room[runSlaves]) + str(" ") + str(ReturnValue[2]) + str(" °C")
print (" ")
print ("|+++++++++++++++++++++++++++++++++++++++++++|")
else:
print ("DHT-Connection Error! Iĺl try again!")
print (str( ReturnValue[3]))
"""Wenn Modbusfehler 'Slave nicht erreichbar' abgestellt ist, 2 durch AnzMessungen ersetzen!"""
if runSlaves == 10:
runSlaves = 1
else:
runSlaves = runSlaves+1
except (KeyboardInterrupt, SystemExit):
print ('Haupt-Programm abgebrochen')
raise
Alles anzeigen