Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

Raspberry whit codesys to raspberry modbus tcp slave ... need a license ?

alverman
2018-05-06
2018-05-18
  • alverman - 2018-05-06

    hello, I have a raspberry card and I manage two Controllino maxi for home automation management with codesys.
    The two controllers are connected in modbus slave and work great.
    On the same network I then have another raspberry, located in the room, which I use as a magic mirror.
    Now I would like to be able to control the air conditioner and detect the temperature with that raspberry.
    To do this, do I need to install a codesys license on this raspberry too?

    Thanks, Alberto

     
  • alverman - 2018-05-08

    hi all, how can I make a raspberry a tcp modbus slave?
    I already have a raspberry with codesys so I would like to connect a simple raspberry with modbus tcp slave protocol and check it from codesys
    Thanks, Alberto

     
  • eschwellinger

    eschwellinger - 2018-05-09

    Hi,
    you only need the Raspberry PI runtime license (no additional modbus license)

    here in the Pi application section in this Forum is an example project for doing this:
    l viewtopic.php?f=21&t=6884 l
    Modbus project with 2 Pi's.

    BR
    Edwin

     
  • alverman - 2018-05-09

    But I thought it was like with arduino.
    Install the pymodbus library on raspberry and check it from codesys as in arduino.

     
  • alverman - 2018-05-14

    Good evening, I managed to connect a remote raspberry with pymodus with the following code.

    from pymodbus.server.async import StartTcpServer
    from pymodbus.device import ModbusDeviceIdentification
    from pymodbus.datastore import ModbusSequentialDataBlock, ModbusSlaveContext, ModbusServerContext
    import RPi.GPIO as GPIO
    import os
    os.system('modprobe w1-gpio')
    os.system('modprobe w1-therm')
    \#set up Raspberry GPIO 
    def main():
       
       store = ModbusSlaveContext(
          di = ModbusSequentialDataBlock(0, [0]*100),
          co = ModbusSequentialDataBlock(0, [0]*100),
          hr = ModbusSequentialDataBlock(0, [0]*100),
          ir = ModbusSequentialDataBlock(0, [0]*100))
       context = ModbusServerContext(slaves=store, single=True)
       identity = ModbusDeviceIdentification()
       identity.VendorName  = 'pymodbus'
       identity.ProductCode = 'PM'
       identity.VendorUrl   = 'http://github.com/simplyautomationized'
       identity.ProductName = 'pymodbus Server'
       identity.ModelName   = 'pymodbus Server'
       identity.MajorMinorRevision = '1.0'
       StartTcpServer(context, identity=identity)#, address=("localhost", 502))
    if __name__ == "__main__":
       main()
    

    Now I would like to map the outputs and the gpio revenue into codesys.
    In particular I would like to read the value of a probe ds18b20 connected to that pi.
    Do you help me insert the python code and map the exit in codesys?

    Thanks, Alberto

     
  • alverman - 2018-05-15

    .... I'm almost there.
    I read the ds18b20 on codesys !!
    I just need to be able to control the heat pump on that raspberry and I finished

     
  • alverman - 2018-05-17

    Well, I've decoded the infrared remote control for the heat pump and managed by python.
    Now I just have to put everything together on codesys

     
  • alverman - 2018-05-18

    Hi guys, I'm almost straight for arrival but I still miss what little that makes me sleep.
    Below I put the code that must run on the PI on which pymodbus runs.

    import time
    import argparse
    import sys, traceback
    import threading
    import RPi.GPIO as GPIO
    import smbus
    import subprocess
    import pymodbus
    from pymodbus.server.async import StartTcpServer
    from pymodbus.device import ModbusDeviceIdentification
    from pymodbus.datastore import ModbusSequentialDataBlock
    from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
    from pymodbus.register_read_message import ReadHoldingRegistersResponse
    from pymodbus.client.sync import ModbusTcpClient
    from pymodbus.server.sync import ModbusTcpServer
    global server
    global ip
    def ServerThread(e):
       global server
       # Configure the service logging
       #import logging
       #logging.basicConfig()
       #log = logging.getLogger()
       #log.setLevel(logging.DEBUG)
       # Initialize your data store
       store = ModbusSlaveContext(
          di = ModbusSequentialDataBlock(0, [0]*100),
          co = ModbusSequentialDataBlock(0, [0]*100),
          hr = ModbusSequentialDataBlock(0, [0]*100),
          ir = ModbusSequentialDataBlock(0, [0]*100))
       context = ModbusServerContext(slaves=store, single=True)
        
       # Initialize the server information
       identity = ModbusDeviceIdentification()
       identity.VendorName  = 'Pymodbus'
       identity.ProductCode = 'PM'
       identity.VendorUrl   = 'http://github.com/bashwork/pymodbus/'
       identity.ProductName = 'Pymodbus Server'
       identity.ModelName   = 'Pymodbus Server'
       identity.MajorMinorRevision = '1.0'
       # Run the server
       server = ModbusTcpServer(context, identity=identity, address=(ip, 502))
       print ("Server started")
       server.serve_forever(0.1)
       print ("Server stopped")
    def Clima(update_interval, e):
            #Gestione del climatizzatore
       print ("Clima")
       client = ModbusTcpClient(ip)
       while True:
                    rr = client.read_holding_registers(0x000A,1,unit=UNIT)
                    assert(rr.function_code < 0x80)     # test that we are not an error
                    if rr.registers[0] == 1:
                            subprocess.call(["irsend", "SEND_ONCE", "AnalysIR", "ACCENDI"])
                            #print (cmd)
                            time.sleep(0.01)
                            client.write_register(0x0008, 100)#VERIFICA
                    elif rr.registers[0] == 2:
                            subprocess.call(["irsend", "SEND_ONCE", "AnalysIR", "SPEGNI"])
                            #print (cmd)
                            time.sleep(0.01)
                            client.write_register(0x0008, 0)#VERIFICA
                    elif rr.registers[0] == 3:
                            subprocess.call(["irsend", "SEND_ONCE", "AnalysIR", "MODO_VENTILATORE"])
                            #print (cmd)
                            time.sleep(0.01)
                            client.write_register(0x0008, 101)#VERIFICA
                   break
                
    client.close()
    print ("Clima thread stopped")
    def TemperatureUpdateThread(update_interval, e):
            #Scrivo la temperatura nel registro 0x0000
       print ("TemperatureUpdateThread")
       client = ModbusTcpClient(ip)
       while True:
          if not e.isSet():
             tfile = open("/sys/bus/w1/devices/28-0117c15d88ff/w1_slave") 
             text = tfile.read()  
             tfile.close() 
             secondline = text.split("\n")[1] 
             temperaturedata = secondline.split(" ")[9] 
             temperature = float(temperaturedata[2:])
             client.write_register(0, temperature)
             print (temperature/1000)
             time.sleep(update_interval)
          else:
             break
       client.close()
       print ("Temperature 0 sensor thread stoped")
    if __name__ == "__main__":
       global server
       global ip
       print ("=== Modbus Device ===")
       parser = argparse.ArgumentParser(description='Modbus server')
       parser.add_argument('ip',  default='localhost', help='IP adress of modbus server')
       args = parser.parse_args()
       ip = args.ip
            e_exit = threading.Event()
            thServer = threading.Thread(name='ServerThread', target=ServerThread, args=(e_exit,))
            thTemperature = threading.Thread(name='TemperatureUpdateThread', target=TemperatureUpdateThread, args=(1, e_exit,))
            thClima = threading.Thread(name='Clima', target=Clima, args=(1, e_exit,))
            UNIT = 0x01
            
       # Init hardware
            GPIO.setmode(GPIO.BCM)
            GPIO.setwarnings(False)
       thServer.start()
       time.sleep(1)
       
       # Start clients
       time.sleep(1)
       thTemperature.start()
            time.sleep(1)
            thClima.start()
            
       # Wait for keyboard interrupt
       try:
          while True:
             time.sleep(1)
       except KeyboardInterrupt:
          print ("Stopping program")
       except Exception:
          traceback.print_exc(file=sys.stdout)
       # Set stop event for clients
       e_exit.set()
       # Shutdown server
       server.shutdown()
       # Wait until server shutdown
       while thServer.isAlive():
          time.sleep(1)
          
       # Clean up
       GPIO.cleanup()
          
       # Stop the program
       print ("Done")
       sys.exit(0)
    

    With this code I send on codesys the value of the temperature from the ds18b20 and contains code that controls the air conditioner.
    For the temperature everything is ok.
    The problem is with the commands to the air conditioner.
    The Climate thread works as it is but with a small but important flaw.

    When executing last command, elif leaves the thread

    I'm not familiar with Python, and by copying / modifying this piece of code found on the internet I understand that python uses indentation as terminators.
    Now I can not figure out how to fix this my little / big problem.

    Can you help me?

    Thanks, Alberto

     

    Related

    Talk.ru: 1


Log in to post a comment.