bnjmnp / pysoem

Cython wrapper for the Simple Open EtherCAT Master Library
MIT License
95 stars 36 forks source link

Issue waiting until slaves are connected #119

Open jakezimmer opened 10 months ago

jakezimmer commented 10 months ago

Hi,

I have a system in which all slaves are initially powered down and would like the system to wait until they are all powered up before proceeding. Is there a recommended way to poll for the slaves and wait until they're all connected? If I start the script with the slaves powered, they connect immediately. If I start the script with the slaves initially unpowered, they do not ever connect.

I'm relatively new to EtherCAT but this wrapper has been very intuitive and easy to use so far so thank you.

I wrote a small test script to test the desired behavior but seem to be having some trouble with it.

# Set up pysoem
if_offset = 4
ifname = pysoem.find_adapters()[if_offset].name
try:
    while True:
        master = None
        master = pysoem.Master(ifname)
        master.close()
        time.sleep(2)
        master.open(ifname)
        if master.config_init() > 0:
            logging.info("Found {} slaves".format(len(master.slaves)))
            if len(master.slaves) < 4:
                logging.error("Not enough slaves found!")
                continue
            for slave in master.slaves:
                slave.recover()
                logging.info("Found {} with Product ID {}".format(slave.name, slave.id))
        else:
            logging.error("No slaves found!")
            continue
        break
except OSError as e:
    logging.error("Error while finding slaves: %s" % e)

Output:

2023-09-12 16:00:23,022 - root - ERROR - No slaves found!
2023-09-12 16:00:25,065 - root - ERROR - No slaves found!
2023-09-12 16:00:27,107 - root - ERROR - No slaves found!
2023-09-12 16:00:29,150 - root - ERROR - No slaves found!
2023-09-12 16:00:31,192 - root - ERROR - No slaves found!
2023-09-12 16:00:33,234 - root - ERROR - No slaves found!
2023-09-12 16:00:35,277 - root - ERROR - No slaves found!
2023-09-12 16:00:37,319 - root - ERROR - No slaves found!

This results in the system always reporting that no slaves were found no matter how long I let it run but, as stated, if I restart the python script with the slaves already on, it finds them immediately.

Output after stopping and restarting the python script:

2023-09-12 16:01:29,682 - root - INFO - Found 5 slaves
2023-09-12 16:01:29,683 - root - INFO - Found EPOS4 with Product ID 1766850560
2023-09-12 16:01:29,683 - root - INFO - Found EPOS4 with Product ID 1766850560
2023-09-12 16:01:29,683 - root - INFO - Found EPOS4 with Product ID 1766850560
2023-09-12 16:01:29,683 - root - INFO - Found EPOS4 with Product ID 1766850560
2023-09-12 16:01:29,683 - root - INFO - Found EPOS4 with Product ID 1766850560

Other system info: OS: Windows 10 EtherCAT slaves: Maxon EPOS4 Motor Controllers Ethernet Interface: Intel(R) Ethernet Connection (17) I219-V

Thanks for your insights.

Michaelicious commented 9 months ago

I was able to run the script, then turned on the ecat device, and it worked, although I have only 1 slave.

I have created an ecMaster class inhereting from pysoem.master, an added find adapters function.

def _find_adapters(self, nicName='PCIe'):
    # nicName = 'PCIe'                    # --- Will be added to INI file
    network_adapters = pysoem.find_adapters()
    for adapter in network_adapters:
        if nicName in str(adapter[1]):
            networkAdapterID = adapter[0]
            self.open(networkAdapterID)
            logging.info('Found network adapter\n'+str(networkAdapterID))
    return len(network_adapters) > 0

using this function inside the try: worked for me

try:
    i = 0
    while i < 15:
        i += 1
        master = None
        master = ecMaster()
        master.close()
        time.sleep(2)
        master._find_adapters()
        # master.open()
        if master.config_init() > 0:
            # master.config_dc()
            logging.info("Found {} slaves".format(len(master.slaves)))
            if len(master.slaves) < 1:
                logging.error("N-o-t enough slaves found!")
                continue
            for slave in master.slaves:
                slave.recover()
                print("Found {} with Product ID {}".format(slave.name, slave.id))
        else:
            logging.error("No slaves found!")
            continue
        break
except OSError as e:
    logging.error("Error while finding slaves: %s" % e)

Output-

ERROR:root:No slaves found!
ERROR:root:No slaves found!
ERROR:root:No slaves found!
ERROR:root:No slaves found!
ERROR:root:No slaves found!
ERROR:root:No slaves found!
ERROR:root:No slaves found!
ERROR:root:No slaves found!
ERROR:root:No slaves found!
Found *** with Product ID ***

you dont have to create a class like me, but try implementing find_adapters inside the try