# arduino_Lan9252

本文作者:[WTB]

picture

# *购买链接

淘宝购买链接 (opens new window)

# *B站视频链接

# arduino ethercat初识

arduino ethercat初识 (opens new window)

# arduino ethercat示例1-2详解

arduino ethercat示例1-2详解 (opens new window)

# arduino ethercat示例3-4详解

arduino ethercat示例3-4详解 (opens new window)

# arduino ethercat示例5-6详解

arduino ethercat示例5-6详解 (opens new window)

# arduino ethercat PWM闭环步进电机演示

arduino ethercat PWM闭环步进电机演示 (opens new window)

# *pythonsoem概述

本资料主要针对初识EthreCat的入门级的参考资料,内容主要分两大部分,一个是EtherCat的主站,主要以python开发语言为基础,一个是EtherCat从站,主要是以Uncleo-f303re和UNO结合Lan9252底板,环境为VSCode Arduino为主。
关键词:
    1.EtherCat
    2.设备 ID : 主设备识别的唯一ID
    3.主站(master),从站(slave) 
    4.用于Arduino的ethercat库文件(easycat)
    EasyNavigator : 主站通讯查看软件
    EasyConfigurator :生产bin,xml,.h的配置软件 
    7.SOEM(Simple Open EtherCAT Master) : 本资资料用pysoem
    8.LAN9252 : EtherCat的通讯芯片
    9.  PDO
    10.SDO
    11.SYNC MASTER
EtherCat通讯模式类型:

picture

# *pysoem安装

 pip install pysoem  

picture

# *示例1和2

example-01;
    1.USB或者5V直流供电连接开发板,连接RJ_IN网口通过网线和电脑网口连接。
    2.用EasyNavigator_GUI.exe软件搜索,确保能扫描到开发板从站。
    3.用EasyCAT_Config_GUI.exe点击write EEPROM 烧写32_32_rev_1.bin。 
    4.程序中我们通过0.1秒增加计数来传入到PDO。
    5.用EasyNavigator_GUI.exe软件可以直观的看到计数的增加。
    6.在python中,使用pysoem将计数器值输出到终端。
example-02;
    1.USB或者5V直流供电连接开发板,连接RJ_IN网口通过网线和电脑网口连接。
    2.用EasyNavigator_GUI.exe软件搜索,确保能扫描到开发板从站。
    3.打开Easy Configurator,直接创建自定义数据!
    4.保存项目后点击create files,在保存项目的文件夹中会生成多个文件,将bin文件以write eeprom上传到lan9252,找到.h文件并将内容输入到Arduino!

picture picture

基本步骤;

    1.使用EasyConfigurator在LAN 9252上配置PDO ENTRY!
    2.在Arduino上使用EasyCAT库,在INPUT PDO中输入间隔100毫秒的计数器值!    
    3.使用EasyNavigator验证PDO ENTRY在LAN 9252上配置是否正确!
    4.在电脑上搜索网络助手!    
    5.使用pysoem连接到LAN 9252并切换到OP模式!    
    6.实时将PDO值输出到终端!

搜索网络适配器的python程序;

    import pysoem
    adapters = pysoem.find_adapters()  for i, adapter in enumerate(adapters):
    print('Adapter {}'.format(i))
    print('	{}'.format(adapter.name))
    print('	{}'.format(adapter.desc))    

arduino示例1代码;

    #include "EasyCAT.h"  
    #include <SPI.h>  
    EasyCAT EASYCAT(10);
    unsigned long wtb_t = 0;  
    uint16_t wtb_cnt = 0;
    void setup()
    {
        Serial.begin(9600);
        Serial.print ("\nEasyCAT - Generic EtherCAT slave\n");  
    if (EASYCAT.Init() == true)
        {
        Serial.print ("initialized");
        }
    else
        {
            Serial.print ("initialization failed");  pinMode(13, OUTPUT);
            while(1)
            {
            digitalWrite (13, LOW);  delay(500);
            digitalWrite (13, HIGH);  delay(500);
            }
        }
    }
    void loop()
        {
        EASYCAT.MainTask();  Application();
        }

    void Application ()
    {
        if(millis() - wtb_t > 100){  
        wtb_t = millis();  
        wtb_cnt++;
        EASYCAT.BufferIn.Byte[0] = wtb_cnt%256;  
        EASYCAT.BufferIn.Byte[1] = wtb_cnt/256;
        }
    }

Aduino示例2代码(自定义数据);

    #define CUSTOM  
    #include "wtb.h"

    #include "EasyCAT.h"  
    #include <SPI.h>  
    EasyCAT EASYCAT(10);

    unsigned long wtb_t = 0;  
    uint16_t wtb_cnt = 0;

    void setup()
    {
    Serial.begin(9600);
    Serial.print ("\nEasyCAT - Generic EtherCAT slave\n");  if (EASYCAT.Init() == true)
    {
    Serial.print ("initialized");
    }
    else
    {
    Serial.print ("initialization failed");  pinMode(13, OUTPUT);
    while(1)
    {
    digitalWrite (13, LOW);  delay(500);
    digitalWrite (13, HIGH);  delay(500);
    }
    }
    }
    void loop()
    {
    EASYCAT.MainTask(); 
    Application();
    }

    void Application ()
    {
    if(millis() - wtb_t > 100){ 
    wtb_t = millis(); 
    wtb_cnt++; //计数加1
    //EASYCAT.BufferIn.Byte[0] = wtb_cnt%256; 
    //EASYCAT.BufferIn.Byte[1] = wtb_cnt/256;   
    EASYCAT.BufferIn.Cust.CNT = wtb_cnt;
    }
    }

arduino示例 2(wtb.h);

    #ifndef CUSTOM_PDO_NAME_H  
    #define CUSTOM_PDO_NAME_H
    #define CUST_BYTE_NUM_OUT 2
    #define CUST_BYTE_NUM_IN 2
    #define TOT_BYTE_NUM_ROUND_OUT 4
    #define TOT_BYTE_NUM_ROUND_IN 4


    typedef union	//---- output buffer ----
    {
    uint8_t Byte [TOT_BYTE_NUM_ROUND_OUT];  struct
    {
    uint16_t DATA;
    }Cust;
    } PROCBUFFER_OUT;
    ypedef union	//---- input buffer ----
    {
    uint8_t Byte [TOT_BYTE_NUM_ROUND_IN];  struct
    {
    uint16_t CNT;
    }Cust;
    } PROCBUFFER_IN;

    #endif

python主站代码:

    import pysoem
    import threading
    import time
    import ctypes
    import struct
    # EtherCAT
    master = pysoem.Master()
    master.open('\\Device\\NPF_{66641FB8-F1DA-40CB-995C-167AA57A21A0}')

    if master.config_init() > 0:
        print(f'共发现{len(master.slaves)}个从站')
    else:
        print('No slaves found')
        master.close()
        raise Exception("NO SLAVE")
    slave = master.slaves[0]
    master.config_map()
    if master.state_check(pysoem.SAFEOP_STATE, timeout=50_000) != pysoem.SAFEOP_STATE:
        master.close()
        raise Exception("not all slaves reached SAFEOP state")
    
    slave.dc_sync(act=True, sync0_cycle_time=10_000_000)
    master.state = pysoem.OP_STATE
    master.send_processdata()
    master.receive_processdata(timeout=2000)
    # request OP state for all slaves
    master.write_state()
    all_slaves_reached_op_state = False
    for i in range(40):
        master.state_check(pysoem.OP_STATE, timeout=50_000)
        if master.state == pysoem.OP_STATE:
            all_slaves_reached_op_state = True
            break
    if all_slaves_reached_op_state:
        print("OP_MODULE")
    def thread1():
        while True:
            master.send_processdata()
            master.receive_processdata(timeout=2000)
            cnt1 = int.from_bytes(slave.input[0:2], byteorder='little', signed=False) 
            cnt2 = slave.input[1] * 256 + slave.input[0]
            print(f"cnt1={cnt1}, cnt2={cnt2}")
            #print(f"cnt1={cnt1}")
            time.sleep(0.5)
    ethercat_thread = threading.Thread(target=thread1, daemon=True)
    ethercat_thread.start()
    # 中断处理
    try:
        while True:
            time.sleep(0.1)
    except KeyboardInterrupt:
        print("中断.")
        master.state = pysoem.INIT_STATE
    # request INIT state for all slaves
        master.write_state()
        master.close()

# *示例3和4

主要内容: 1.将上一篇中进行的教程示例升级到具有GUI的python程序! 2.将可变电阻连接到阿杜伊诺的模拟0号插针上,并将测量出的10bit模拟值以无符号的16bit整数输入input pdo,发送到主节点! 3.示例3中获取开发板拨码开关的值,当值在0-255之间来回 切换时,请在input pdo中输入值并发送! 4.示例4将温湿度传感器(DHT-11)连接到阿杜伊诺的数字2号插针上,并将测量的温湿度值输出到python gui主屏幕

arduino示例3和4:

    #include "main.h"
    #include "EasyCAT.h"                // EasyCAT library to interface the LAN9252
    #include "DHT.h"
    #include <Arduino.h>
    #if !( defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3)  ||defined(STM32F4) || defined(STM32F7) || \
        defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32H7)  ||defined(STM32G0) || defined(STM32G4) || \
        defined(STM32WB) || defined(STM32MP1) || defined(STM32L5) )
    #error This code is designed to run on STM32F/L/H/G/WB/MP1 platform! Please check your Tools->Board setting.
    #endif

    // These define's must be placed at the beginning before #include "STM32TimerInterrupt.h"
    // _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
    // Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
    // Don't define TIMER_INTERRUPT_DEBUG > 2. Only for special ISR debugging only. Can hang the system.
    #define TIMER_INTERRUPT_DEBUG         0
    #define _TIMERINTERRUPT_LOGLEVEL_     0

    #include "STM32TimerInterrupt.h"

    // To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
    #include "STM32_ISR_Timer.h"

    #include <SimpleTimer.h>              // https://github.com/jfturcot/SimpleTimer
    #define TIMER_INTERVAL_MS         100
    #define HW_TIMER_INTERVAL_MS      50
    #ifndef LED_BUILTIN
    #define LED_BUILTIN       PC13              // Pin 33/PB0 control on-board LED_GREEN on F767ZI
    #endif
    // Depending on the board, you can select STM32 Hardware Timer from TIM1-TIM22
    // For example, F767ZI can select Timer from TIM1-TIM14
    // If you select a Timer not correctly, you'll get a message from ci[ompiler
    // 'TIMxx' was not declared in this scope; did you mean 'TIMyy'? 

    // Init STM32 timer TIM1
    STM32Timer ITimer(TIM1);
    HardwareSerial Serial1(PA10,PA9);
    // Init STM32_ISR_Timer
    // Each STM32_ISR_Timer can service 16 different ISR-based timers
    STM32_ISR_Timer ISR_Timer;

    #define TIMER_INTERVAL_0_5S           500L
    #define TIMER_INTERVAL_1S             1000L
    #define TIMER_INTERVAL_1_5S           1500L
    #define TIMER_INTERVAL_5S             5000L
    void TimerHandler()
    {
    ISR_Timer.run();
    }

    unsigned long previousMs = 0;
    uint16_t wtbcnt = 0;
    const int OUTPUTS_COUNT = 8;
    const char DHTPIN = PIN_A0;
    const char DHTTYPE = DHT11;
    // const int outPins[8] = {
    //   BitOut0, BitOut1, BitOut2, BitOut3, BitOut4, BitOut5, BitOut6, BitOut7
    // };
    // const int InPins[8] = {
    //   BitIn0, BitIn1, BitIn2, BitIn3, BitIn4, BitIn5, BitIn6, BitIn7
    // };

    //---- setup ---------------------------------------------------------------------------------------
    uint8_t humid;
    uint8_t temp;
    DHT dht(DHTPIN, DHTTYPE);
    void adapte_DHT()
    {
    digitalWrite(BitOut0, !digitalRead(BitOut0));
    humid = dht.readHumidity();
    temp = dht.readTemperature();
    //float hic = dht.computeHeatIndex(t, h, false);
    // Serial1.print(F("Humidity: "));
    // Serial1.print(h);
    // Serial1.print(F("%  Temperature: "));
    // Serial1.print(t);
    // Serial1.print(F("掳C "));
    // Serial1.print(hic);
    // Serial1.print(F("掳C "));
    }
    void setup()
    {
    Serial.begin(9600);
    Serial1.begin(9600);
    Serial1.print("Initialization...");
    dht.begin();
    
    pinMode(BitOut0,HIGH);
    // pinMode(BitOut1,HIGH);
    // pinMode(BitOut2,HIGH);
    // pinMode(BitOut3,HIGH);
    // pinMode(BitOut4,HIGH);
    // pinMode(BitOut5,HIGH);
    // pinMode(BitOut6,HIGH);
    // pinMode(BitOut7,HIGH);
    // digitalWrite (BitOut0, HIGH);
    // digitalWrite (BitOut1, HIGH);
    // digitalWrite (BitOut2, HIGH);
    // digitalWrite (BitOut3, HIGH);
    // digitalWrite (BitOut4, HIGH);
    // digitalWrite (BitOut5, HIGH);
    // digitalWrite (BitOut6, HIGH);
    // digitalWrite (BitOut7, HIGH);
    pinMode(BitIn0, INPUT_PULLUP);                                  
    pinMode(BitIn1, INPUT_PULLUP);                                  
    pinMode(BitIn2, INPUT_PULLUP);                                  
    pinMode(BitIn3, INPUT_PULLUP);
    pinMode(BitIn4, INPUT_PULLUP);                                  
    pinMode(BitIn5, INPUT_PULLUP);                                  
    pinMode(BitIn6, INPUT_PULLUP);                                  
    pinMode(BitIn7, INPUT_PULLUP);
    // for (size_t i = 0; i < OUTPUTS_COUNT; i++)
    // {
    //   int outPin = outPins[i];
    //   pinMode(outPin, OUTPUT);
    // }
    if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_MS * 1000, TimerHandler))
    {
        Serial.print(F("Starting ITimer OK, millis() = ")); Serial.println(millis());
    }
    else
        Serial.println(F("Can't set ITimer. Select another freq. or timer"));

    ISR_Timer.setInterval(TIMER_INTERVAL_0_5S,  adapte_DHT);
    if (EasyCAT_Init(SpiCS_Pin, ASYNC) == true) {
        Serial.println("done.");
    }
    else 
    {
        // initialization failed, blink LED until reset
        Serial.println("failed!");
        pinMode(BitOut0, OUTPUT);

        while(1)
        {
        digitalWrite (BitOut0, LOW);
        delay(500);
        digitalWrite (BitOut0, HIGH);
        delay(500);
        }
    }  
    previousMs = millis();
    }


    //---- main loop ----------------------------------------------------------------------------------------

    void loop()
    { 
    
    EasyCAT_MainTask();
    Application();
    }


    //---- user application ------------------------------------------------------------------------------

    void Application ()                                        

    {
    // #define ECAT_APP_CYCLE_TIME_MS 100
    
    // unsigned long nowMs = millis();
    // if (nowMs - previousMs >= ECAT_APP_CYCLE_TIME_MS)
    // {      
    //   previousMs = nowMs;
    //   //wtbcnt++;
    //   EasyCAT_BufferIn.Cust.CNT = 80;
    //  // EasyCAT_BufferIn.Cust.CNT = wtbcnt;
    //   // read slave RxPDO  
    //   // for (size_t i = 0; i < OUTPUTS_COUNT; i++)
    //   // {
    //   //   int outPin = outPins[i];
        
    //   //   if (EasyCAT_BufferOut.Cust.Out8 & (1 << i)) {
    //   //     digitalWrite (outPin, LOW);
    //   //   }
    //   //   else {
    //   //     digitalWrite (outPin, HIGH);
    //   //   }
    //   // }

        
    // }
    EasyCAT_BufferIn.Cust.CNT = humid;
    // if (digitalRead(BitIn0))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<0);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<0);
    //  if (digitalRead(BitIn1))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<1);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<1);
    //  if (digitalRead(BitIn2))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<2);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<2);
    //  if (digitalRead(BitIn3))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<3);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<3);
    //  if (digitalRead(BitIn4))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<4);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<4);
    //   if (digitalRead(BitIn5))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<5);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<5);
    //   if (digitalRead(BitIn6))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<6);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<6);
    //   if (digitalRead(BitIn7))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<7);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<7);

    }

示例3和4的 wth_01.h

    #ifndef CUSTOM_PDO_NAME_H
    #define CUSTOM_PDO_NAME_H

    //-------------------------------------------------------------------//
    //                                                                   //
    //     This file has been created by the Easy Configurator tool      //
    //                                                                   //
    //     Easy Configurator project ex01.prj
    //                                                                   //
    //-------------------------------------------------------------------//


    #define CUST_BYTE_NUM_OUT	2
    #define CUST_BYTE_NUM_IN	2
    #define TOT_BYTE_NUM_ROUND_OUT	4
    #define TOT_BYTE_NUM_ROUND_IN	4


    typedef union												//---- output buffer ----
    {
        uint8_t  Byte [TOT_BYTE_NUM_ROUND_OUT];
        struct
        {
            uint16_t    DATA;
        }Cust;
    } PROCBUFFER_OUT;


    typedef union												//---- input buffer ----
    {
        uint8_t  Byte [TOT_BYTE_NUM_ROUND_IN];
        struct
        {
            uint16_t    CNT;
        }Cust;
    } PROCBUFFER_IN;

    #endif

示例3和4的python GUI代码:

    import pysoem  
    import threading  
    import time  
    import ctypes  
    import struct
    import tkinter as tk
    from tkinter import messagebox
    master = pysoem.Master()
    master.open('\\Device\\NPF_{66641FB8-F1DA-40CB-995C-167AA57A21A0}')
    if master.config_init() > 0:
        print(f'共发现{len(master.slaves)}个从站')
    else:
        print('No slaves found')
        master.close()
        raise Exception("NO SLAVE")
    slave = master.slaves[0]
    master.config_map()
    if master.state_check(pysoem.SAFEOP_STATE, timeout=50_000) != pysoem.SAFEOP_STATE:
        master.close()
        raise Exception("not all slaves reached SAFEOP state")
    
    slave.dc_sync(act=True, sync0_cycle_time=10_000_000)
    master.state = pysoem.OP_STATE
    master.send_processdata()
    master.receive_processdata(timeout=2000)
    master.write_state()  
    all_slaves_reached_op_state = False
    for i in range(40):
        master.state_check(pysoem.OP_STATE, timeout=50_000)
        if master.state == pysoem.OP_STATE:
            all_slaves_reached_op_state = True
            break
    if all_slaves_reached_op_state:
        print("OP_MODULE")
    # GUI 
    root = tk.Tk()
    root.title("ethercat的通讯程序")

    root.geometry("600x400")

    label1 = tk.Label(root, text="湿度 值=0", font=("Arial", 30))  
    label1.pack()

    def thread1():  
        while True:
            master.send_processdata()  
            master.receive_processdata(timeout=2000)
            cnt1 = int.from_bytes(slave.input[0:2], byteorder='little', signed=False)  
            #print(f"cnt1={cnt1}")
            label1.config(text=f"湿度 值={cnt1}")  
            time.sleep(0.1)

    ethercat_thread = threading.Thread(target=thread1, daemon=True)  
    ethercat_thread.start()

    root.mainloop()

    print("程序已关闭.")  
    master.state = pysoem.INIT_STATE  
    # request INIT state for all slaves  master.write_state()
    master.close()

# *示例5和6

主要内容:

    补充示例4温湿度的示例,示例6,led的输出控制。

arduino示例5:

    #include "main.h"
    #include "EasyCAT.h"                // EasyCAT library to interface the LAN9252
    #include "DHT.h"
    #include <Arduino.h>
    #if !( defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3)  ||defined(STM32F4) || defined(STM32F7) || \
        defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32H7)  ||defined(STM32G0) || defined(STM32G4) || \
        defined(STM32WB) || defined(STM32MP1) || defined(STM32L5) )
    #error This code is designed to run on STM32F/L/H/G/WB/MP1 platform! Please check your Tools->Board setting.
    #endif

    // These define's must be placed at the beginning before #include "STM32TimerInterrupt.h"
    // _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
    // Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
    // Don't define TIMER_INTERRUPT_DEBUG > 2. Only for special ISR debugging only. Can hang the system.
    #define TIMER_INTERRUPT_DEBUG         0
    #define _TIMERINTERRUPT_LOGLEVEL_     0

    #include "STM32TimerInterrupt.h"

    // To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
    #include "STM32_ISR_Timer.h"

    #include <SimpleTimer.h>              // https://github.com/jfturcot/SimpleTimer
    #define TIMER_INTERVAL_MS         100
    #define HW_TIMER_INTERVAL_MS      50
    #ifndef LED_BUILTIN
    #define LED_BUILTIN       PC13              // Pin 33/PB0 control on-board LED_GREEN on F767ZI
    #endif
    // Depending on the board, you can select STM32 Hardware Timer from TIM1-TIM22
    // For example, F767ZI can select Timer from TIM1-TIM14
    // If you select a Timer not correctly, you'll get a message from ci[ompiler
    // 'TIMxx' was not declared in this scope; did you mean 'TIMyy'? 

    // Init STM32 timer TIM1
    STM32Timer ITimer(TIM1);
    HardwareSerial Serial1(PA10,PA9);
    // Init STM32_ISR_Timer
    // Each STM32_ISR_Timer can service 16 different ISR-based timers
    STM32_ISR_Timer ISR_Timer;

    #define TIMER_INTERVAL_0_5S           500L
    #define TIMER_INTERVAL_1S             1000L
    #define TIMER_INTERVAL_1_5S           1500L
    #define TIMER_INTERVAL_5S             5000L
    void TimerHandler()
    {
    ISR_Timer.run();
    }

    unsigned long previousMs = 0;
    uint16_t wtbcnt = 0;
    const int OUTPUTS_COUNT = 8;
    const char DHTPIN = PIN_A0;
    const char DHTTYPE = DHT11;
    // const int outPins[8] = {
    //   BitOut0, BitOut1, BitOut2, BitOut3, BitOut4, BitOut5, BitOut6, BitOut7
    // };
    // const int InPins[8] = {
    //   BitIn0, BitIn1, BitIn2, BitIn3, BitIn4, BitIn5, BitIn6, BitIn7
    // };

    //---- setup ---------------------------------------------------------------------------------------
    float humid;
    float temp;
    DHT dht(DHTPIN, DHTTYPE);

    union{
    int16_t num1; //16bit  
    byte num2[2]; //16bit
    }wtb1;

    union{
    uint16_t num1; //16bit  
    byte num2[2]; //16bit
    }wtb2;


    void adapte_DHT()
    {
    digitalWrite(BitOut0, !digitalRead(BitOut0));
    humid = dht.readHumidity();
    temp = dht.readTemperature();
    wtb1.num1 = (int16_t)(temp*10);
    wtb2.num1 = (uint16_t)(humid*10);
    //float hic = dht.computeHeatIndex(t, h, false);
    // Serial1.print(F("Humidity: "));
    // Serial1.print(h);
    // Serial1.print(F("%  Temperature: "));
    // Serial1.print(t);
    // Serial1.print(F("掳C "));
    // Serial1.print(hic);
    // Serial1.print(F("掳C "));
    }
    void setup()
    {
    Serial.begin(9600);
    Serial1.begin(9600);
    Serial1.print("Initialization...");
    dht.begin();
    
    pinMode(BitOut0,HIGH);
    // pinMode(BitOut1,HIGH);
    // pinMode(BitOut2,HIGH);
    // pinMode(BitOut3,HIGH);
    // pinMode(BitOut4,HIGH);
    // pinMode(BitOut5,HIGH);
    // pinMode(BitOut6,HIGH);
    // pinMode(BitOut7,HIGH);
    // digitalWrite (BitOut0, HIGH);
    // digitalWrite (BitOut1, HIGH);
    // digitalWrite (BitOut2, HIGH);
    // digitalWrite (BitOut3, HIGH);
    // digitalWrite (BitOut4, HIGH);
    // digitalWrite (BitOut5, HIGH);
    // digitalWrite (BitOut6, HIGH);
    // digitalWrite (BitOut7, HIGH);
    pinMode(BitIn0, INPUT_PULLUP);                                  
    pinMode(BitIn1, INPUT_PULLUP);                                  
    pinMode(BitIn2, INPUT_PULLUP);                                  
    pinMode(BitIn3, INPUT_PULLUP);
    pinMode(BitIn4, INPUT_PULLUP);                                  
    pinMode(BitIn5, INPUT_PULLUP);                                  
    pinMode(BitIn6, INPUT_PULLUP);                                  
    pinMode(BitIn7, INPUT_PULLUP);
    // for (size_t i = 0; i < OUTPUTS_COUNT; i++)
    // {
    //   int outPin = outPins[i];
    //   pinMode(outPin, OUTPUT);
    // }
    if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_MS * 1000, TimerHandler))
    {
        Serial.print(F("Starting ITimer OK, millis() = ")); Serial.println(millis());
    }
    else
        Serial.println(F("Can't set ITimer. Select another freq. or timer"));

    ISR_Timer.setInterval(TIMER_INTERVAL_0_5S,  adapte_DHT);
    if (EasyCAT_Init(SpiCS_Pin, ASYNC) == true) {
        Serial.println("done.");
    }
    else 
    {
        // initialization failed, blink LED until reset
        Serial.println("failed!");
        pinMode(BitOut0, OUTPUT);

        while(1)
        {
        digitalWrite (BitOut0, LOW);
        delay(500);
        digitalWrite (BitOut0, HIGH);
        delay(500);
        }
    }  
    previousMs = millis();
    }


    //---- main loop ----------------------------------------------------------------------------------------

    void loop()
    { 
    
    EasyCAT_MainTask();
    Application();
    }


    //---- user application ------------------------------------------------------------------------------

    void Application ()                                        

    {
    // #define ECAT_APP_CYCLE_TIME_MS 100
    
    // unsigned long nowMs = millis();
    // if (nowMs - previousMs >= ECAT_APP_CYCLE_TIME_MS)
    // {      
    //   previousMs = nowMs;
    //   //wtbcnt++;
    //   EasyCAT_BufferIn.Cust.CNT = 80;
    //  // EasyCAT_BufferIn.Cust.CNT = wtbcnt;
    //   // read slave RxPDO  
    //   // for (size_t i = 0; i < OUTPUTS_COUNT; i++)
    //   // {
    //   //   int outPin = outPins[i];
        
    //   //   if (EasyCAT_BufferOut.Cust.Out8 & (1 << i)) {
    //   //     digitalWrite (outPin, LOW);
    //   //   }
    //   //   else {
    //   //     digitalWrite (outPin, HIGH);
    //   //   }
    //   // }

        
    // }
    EasyCAT_BufferIn.Byte[0] = wtb1.num2[0];
    EasyCAT_BufferIn.Byte[1] = wtb1.num2[1];
    EasyCAT_BufferIn.Byte[2] = wtb2.num2[0];
    EasyCAT_BufferIn.Byte[3] = wtb2.num2[1];
    // if (digitalRead(BitIn0))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<0);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<0);
    //  if (digitalRead(BitIn1))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<1);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<1);
    //  if (digitalRead(BitIn2))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<2);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<2);
    //  if (digitalRead(BitIn3))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<3);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<3);
    //  if (digitalRead(BitIn4))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<4);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<4);
    //   if (digitalRead(BitIn5))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<5);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<5);
    //   if (digitalRead(BitIn6))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<6);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<6);
    //   if (digitalRead(BitIn7))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<7);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<7);

    }

示例5的wtb_05.h

    #ifndef CUSTOM_PDO_NAME_H
    #define CUSTOM_PDO_NAME_H

    //-------------------------------------------------------------------//
    //                                                                   //
    //     This file has been created by the Easy Configurator tool      //
    //                                                                   //
    //     Easy Configurator project wtb_05.prj
    //                                                                   //
    //-------------------------------------------------------------------//


    #define CUST_BYTE_NUM_OUT	2
    #define CUST_BYTE_NUM_IN	4
    #define TOT_BYTE_NUM_ROUND_OUT	4
    #define TOT_BYTE_NUM_ROUND_IN	4


    typedef union												//---- output buffer ----
    {
        uint8_t  Byte [TOT_BYTE_NUM_ROUND_OUT];
        struct
        {
            uint16_t    DATA;
        }Cust;
    } PROCBUFFER_OUT;


    typedef union												//---- input buffer ----
    {
        uint8_t  Byte [TOT_BYTE_NUM_ROUND_IN];
        struct
        {
            uint32_t    CNT;
        }Cust;
    } PROCBUFFER_IN;

    #endif

示例5的python GUI

    import pysoem  
    import threading  
    import time  
    import ctypes  
    import struct
    import tkinter as tk
    from tkinter import messagebox
    master = pysoem.Master()
    master.open('\\Device\\NPF_{66641FB8-F1DA-40CB-995C-167AA57A21A0}')
    if master.config_init() > 0:
        print(f'共发现{len(master.slaves)}个从站')
    else:
        print('No slaves found')
        master.close()
        raise Exception("NO SLAVE")
    slave = master.slaves[0]
    master.config_map()
    if master.state_check(pysoem.SAFEOP_STATE, timeout=50_000) != pysoem.SAFEOP_STATE:
        master.close()
        raise Exception("not all slaves reached SAFEOP state")
    
    slave.dc_sync(act=True, sync0_cycle_time=10_000_000)
    master.state = pysoem.OP_STATE
    master.send_processdata()
    master.receive_processdata(timeout=2000)
    master.write_state()  
    all_slaves_reached_op_state = False
    for i in range(40):
        master.state_check(pysoem.OP_STATE, timeout=50_000)
        if master.state == pysoem.OP_STATE:
            all_slaves_reached_op_state = True
            break
    if all_slaves_reached_op_state:
        print("OP_MODULE")
    # GUI 
    root = tk.Tk()
    root.title("ethercat的通讯程序")

    root.geometry("600x400")

    label1 = tk.Label(root, text="温度 值=0", font=("Arial", 30))  
    label1.pack()
    label2 = tk.Label(root, text="湿度 值=0", font=("Arial", 30))  
    label2.pack()
    def thread1():  
        while True:
            master.send_processdata()  
            master.receive_processdata(timeout=2000)
            cnt1 = int.from_bytes(slave.input[0:2], byteorder='little', signed=True)
            cnt2 = int.from_bytes(slave.input[2:4], byteorder='little', signed=False)
            #print(f"cnt1={cnt1}")
            label1.config(text=f"温度 值={cnt1/10}°C")
            label2.config(text=f"湿度 值={cnt2/10}%")
            time.sleep(0.1)

    ethercat_thread = threading.Thread(target=thread1, daemon=True)  
    ethercat_thread.start()

    root.mainloop()

    print("程序已关闭.")  
    master.state = pysoem.INIT_STATE  
    # request INIT state for all slaves  master.write_state()
    master.close()

arduino示例6代码-PDO-LED控制

    #include "main.h"
    #include "EasyCAT.h"                // EasyCAT library to interface the LAN9252
    #include "DHT.h"
    #include <Arduino.h>
    #if !( defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3)  ||defined(STM32F4) || defined(STM32F7) || \
        defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32H7)  ||defined(STM32G0) || defined(STM32G4) || \
        defined(STM32WB) || defined(STM32MP1) || defined(STM32L5) )
    #error This code is designed to run on STM32F/L/H/G/WB/MP1 platform! Please check your Tools->Board setting.
    #endif

    // These define's must be placed at the beginning before #include "STM32TimerInterrupt.h"
    // _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
    // Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
    // Don't define TIMER_INTERRUPT_DEBUG > 2. Only for special ISR debugging only. Can hang the system.
    #define TIMER_INTERRUPT_DEBUG         0
    #define _TIMERINTERRUPT_LOGLEVEL_     0

    #include "STM32TimerInterrupt.h"

    // To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
    #include "STM32_ISR_Timer.h"

    #include <SimpleTimer.h>              // https://github.com/jfturcot/SimpleTimer
    #define TIMER_INTERVAL_MS         100
    #define HW_TIMER_INTERVAL_MS      50
    #ifndef LED_BUILTIN
    #define LED_BUILTIN       PC13              // Pin 33/PB0 control on-board LED_GREEN on F767ZI
    #endif
    // Depending on the board, you can select STM32 Hardware Timer from TIM1-TIM22
    // For example, F767ZI can select Timer from TIM1-TIM14
    // If you select a Timer not correctly, you'll get a message from ci[ompiler
    // 'TIMxx' was not declared in this scope; did you mean 'TIMyy'? 

    // Init STM32 timer TIM1
    STM32Timer ITimer(TIM1);
    HardwareSerial Serial1(PA10,PA9);
    // Init STM32_ISR_Timer
    // Each STM32_ISR_Timer can service 16 different ISR-based timers
    STM32_ISR_Timer ISR_Timer;

    #define TIMER_INTERVAL_0_5S           500L
    #define TIMER_INTERVAL_1S             1000L
    #define TIMER_INTERVAL_1_5S           1500L
    #define TIMER_INTERVAL_5S             5000L
    void TimerHandler()
    {
    ISR_Timer.run();
    }

    unsigned long previousMs = 0;
    uint16_t wtbcnt = 0;
    const int OUTPUTS_COUNT = 8;
    const char DHTPIN = PIN_A0;
    const char DHTTYPE = DHT11;
    const int outPins[8] = {
    BitOut0, BitOut1, BitOut2, BitOut3, BitOut4, BitOut5, BitOut6, BitOut7
    };
    // const int InPins[8] = {
    //   BitIn0, BitIn1, BitIn2, BitIn3, BitIn4, BitIn5, BitIn6, BitIn7
    // };

    //---- setup ---------------------------------------------------------------------------------------
    float humid;
    float temp;
    DHT dht(DHTPIN, DHTTYPE);

    union{
    int16_t num1; //16bit  
    byte num2[2]; //16bit
    }wtb1;

    union{
    uint16_t num1; //16bit  
    byte num2[2]; //16bit
    }wtb2;


    void adapte_DHT()
    {
    // digitalWrite(BitOut0, !digitalRead(BitOut0));
    humid = dht.readHumidity();
    temp = dht.readTemperature();
    wtb1.num1 = (int16_t)(temp*10);
    wtb2.num1 = (uint16_t)(humid*10);
    //float hic = dht.computeHeatIndex(t, h, false);
    // Serial1.print(F("Humidity: "));
    // Serial1.print(h);
    // Serial1.print(F("%  Temperature: "));
    // Serial1.print(t);
    // Serial1.print(F("掳C "));
    // Serial1.print(hic);
    // Serial1.print(F("掳C "));
    }
    void setup()
    {
    Serial.begin(9600);
    Serial1.begin(9600);
    Serial1.print("Initialization...");
    dht.begin();
    
    pinMode(BitOut0,HIGH);
    pinMode(BitOut1,HIGH);
    pinMode(BitOut2,HIGH);
    pinMode(BitOut3,HIGH);
    pinMode(BitOut4,HIGH);
    pinMode(BitOut5,HIGH);
    pinMode(BitOut6,HIGH);
    pinMode(BitOut7,HIGH);
    // digitalWrite (BitOut0, HIGH);
    // digitalWrite (BitOut1, HIGH);
    // digitalWrite (BitOut2, HIGH);
    // digitalWrite (BitOut3, HIGH);
    // digitalWrite (BitOut4, HIGH);
    // digitalWrite (BitOut5, HIGH);
    // digitalWrite (BitOut6, HIGH);
    // digitalWrite (BitOut7, HIGH);
    pinMode(BitIn0, INPUT_PULLUP);                                  
    pinMode(BitIn1, INPUT_PULLUP);                                  
    pinMode(BitIn2, INPUT_PULLUP);                                  
    pinMode(BitIn3, INPUT_PULLUP);
    pinMode(BitIn4, INPUT_PULLUP);                                  
    pinMode(BitIn5, INPUT_PULLUP);                                  
    pinMode(BitIn6, INPUT_PULLUP);                                  
    pinMode(BitIn7, INPUT_PULLUP);
    // for (size_t i = 0; i < OUTPUTS_COUNT; i++)
    // {
    //   int outPin = outPins[i];
    //  // pinMode(outPin, OUTPUT);
    //  digitalWrite(outPin,LOW);
    // }
    if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_MS * 1000, TimerHandler))
    {
        Serial.print(F("Starting ITimer OK, millis() = ")); Serial.println(millis());
    }
    else
        Serial.println(F("Can't set ITimer. Select another freq. or timer"));

    ISR_Timer.setInterval(TIMER_INTERVAL_0_5S,  adapte_DHT);
    if (EasyCAT_Init(SpiCS_Pin, ASYNC) == true) {
        Serial.println("done.");
    }
    else 
    {
        // initialization failed, blink LED until reset
        Serial.println("failed!");
        pinMode(BitOut0, OUTPUT);

        while(1)
        {
        digitalWrite (BitOut0, LOW);
        delay(500);
        digitalWrite (BitOut0, HIGH);
        delay(500);
        }
    }  
    previousMs = millis();
    }


    //---- main loop ----------------------------------------------------------------------------------------

    void loop()
    { 
    
    EasyCAT_MainTask();
    Application();
    }


    //---- user application ------------------------------------------------------------------------------

    void Application ()                                        

    {
    #define ECAT_APP_CYCLE_TIME_MS 100
    
    unsigned long nowMs = millis();
    if (nowMs - previousMs >= ECAT_APP_CYCLE_TIME_MS)
    {      
        previousMs = nowMs;
        //wtbcnt++;
        //EasyCAT_BufferIn.Cust.CNT = 80;
    // EasyCAT_BufferIn.Cust.CNT = wtbcnt;
    // read slave RxPDO  
    //   for (size_t i = 0; i < OUTPUTS_COUNT; i++)
    //   {
    //     int outPin = outPins[i];
        
    //     if (EasyCAT_BufferOut.Cust.DATA & (1 << i)) {
    //       digitalWrite (outPin, LOW);
    //     }
    //     else {
    //       digitalWrite (outPin, HIGH);
    //     }
    //  }
    if (EasyCAT_BufferOut.Byte[0] & (1 << 0)) {
            digitalWrite (BitOut0, LOW);
        }
        else {
            digitalWrite (BitOut0, HIGH);
        }
    if (EasyCAT_BufferOut.Byte[1] & (1 << 0)) {
            digitalWrite (BitOut1, LOW);
        }
        else {
            digitalWrite (BitOut1, HIGH);
        }
    if (EasyCAT_BufferOut.Byte[2] & (1 << 0)) {
            digitalWrite (BitOut2, LOW);
        }
        else {
            digitalWrite (BitOut2, HIGH);
        }
    if (EasyCAT_BufferOut.Byte[3] & (1 << 0)) {
            digitalWrite (BitOut3, LOW);
        }
        else {
            digitalWrite (BitOut3, HIGH);
        }
    if (EasyCAT_BufferOut.Byte[4] & (1 << 0)) {
            digitalWrite (BitOut4, LOW);
        }
        else {
            digitalWrite (BitOut4, HIGH);
        }
    if (EasyCAT_BufferOut.Byte[5] & (1 << 0)) {
            digitalWrite (BitOut5, LOW);
        }
        else {
            digitalWrite (BitOut5, HIGH);
        }
    if (EasyCAT_BufferOut.Byte[6] & (1 << 0)) {
            digitalWrite (BitOut6, LOW);
        }
        else {
            digitalWrite (BitOut6, HIGH);
        }
    if (EasyCAT_BufferOut.Byte[7] & (1 << 0)) {
            digitalWrite (BitOut7, LOW);
        }
        else {
            digitalWrite (BitOut7, HIGH);
        }
    // digitalWrite(BitOut0,!EasyCAT_BufferOut.Byte[0]);  
    // digitalWrite(BitOut1,!EasyCAT_BufferOut.Byte[1]);  
    // digitalWrite(BitOut2,!EasyCAT_BufferOut.Byte[2]);  
    // digitalWrite(BitOut3,!EasyCAT_BufferOut.Byte[3]);
    // digitalWrite(BitOut4,!EasyCAT_BufferOut.Byte[4]);  
    // digitalWrite(BitOut5,!EasyCAT_BufferOut.Byte[5]);  
    // digitalWrite(BitOut6,!EasyCAT_BufferOut.Byte[6]);  
    // digitalWrite(BitOut7,!EasyCAT_BufferOut.Byte[7]);
    EasyCAT_BufferIn.Byte[0] = wtb1.num2[0];
    EasyCAT_BufferIn.Byte[1] = wtb1.num2[1];
    EasyCAT_BufferIn.Byte[2] = wtb2.num2[0];
    EasyCAT_BufferIn.Byte[3] = wtb2.num2[1];
    }
    // EasyCAT_BufferIn.Byte[0] = wtb1.num2[0];
    // EasyCAT_BufferIn.Byte[1] = wtb1.num2[1];
    // EasyCAT_BufferIn.Byte[2] = wtb2.num2[0];
    // EasyCAT_BufferIn.Byte[3] = wtb2.num2[1];
    // if (digitalRead(BitIn0))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<0);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<0);
    //  if (digitalRead(BitIn1))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<1);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<1);
    //  if (digitalRead(BitIn2))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<2);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<2);
    //  if (digitalRead(BitIn3))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<3);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<3);
    //  if (digitalRead(BitIn4))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<4);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<4);
    //   if (digitalRead(BitIn5))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<5);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<5);
    //   if (digitalRead(BitIn6))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<6);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<6);
    //   if (digitalRead(BitIn7))                            // the four input pins are mapped to the
    //    EasyCAT_BufferIn.Cust.CNT &= ~(1<<7);      // lower nibble of input Byte 6
    //   else                                                //      
    //     EasyCAT_BufferIn.Cust.CNT |= (1<<7);

    }

示例6的wtb_05.h

    #ifndef CUSTOM_PDO_NAME_H
    #define CUSTOM_PDO_NAME_H

    //-------------------------------------------------------------------//
    //                                                                   //
    //     This file has been created by the Easy Configurator tool      //
    //                                                                   //
    //     Easy Configurator project wtb_05.prj
    //                                                                   //
    //-------------------------------------------------------------------//


    #define CUST_BYTE_NUM_OUT	8
    #define CUST_BYTE_NUM_IN	4
    #define TOT_BYTE_NUM_ROUND_OUT	8
    #define TOT_BYTE_NUM_ROUND_IN	4


    typedef union												//---- output buffer ----
    {
        uint8_t  Byte [TOT_BYTE_NUM_ROUND_OUT];
        struct
        {
            uint64_t    DATA;
        }Cust;
    } PROCBUFFER_OUT;


    typedef union												//---- input buffer ----
    {
        uint8_t  Byte [TOT_BYTE_NUM_ROUND_IN];
        struct
        {
            uint32_t    CNT;
        }Cust;
    } PROCBUFFER_IN;

    #endif

示例6 python GUI代码

    import pysoem  
    import threading  
    import time  
    import ctypes  
    import struct
    import tkinter as tk
    from tkinter import messagebox

    master = pysoem.Master()
    master.open('\\Device\\NPF_{66641FB8-F1DA-40CB-995C-167AA57A21A0}')
    if master.config_init() > 0:
        print(f'共发现{len(master.slaves)}个从站')
    else:
        print('No slaves found')
        master.close()
        raise Exception("NO SLAVE")
    slave = master.slaves[0]
    master.config_map()
    if master.state_check(pysoem.SAFEOP_STATE, timeout=50_000) != pysoem.SAFEOP_STATE:
        master.close()
        raise Exception("not all slaves reached SAFEOP state")
    
    slave.dc_sync(act=True, sync0_cycle_time=10_000_000)
    master.state = pysoem.OP_STATE
    master.send_processdata()
    master.receive_processdata(timeout=2000)
    master.write_state()  
    all_slaves_reached_op_state = False
    for i in range(40):
        master.state_check(pysoem.OP_STATE, timeout=50_000)
        if master.state == pysoem.OP_STATE:
            all_slaves_reached_op_state = True
            break
    if all_slaves_reached_op_state:
        print("OP_MODULE")
    output_len = len(slave.output)
    #output_len = 7
    print(f"output_len={output_len}")
    tmp = bytearray([0 for i in range(output_len)])

    def led_control(num,state):
        print(f"LED={num},STATE={state}")
        tmp[num] = state
        slave.output = bytes(tmp)
        master.send_processdata()
    # GUI 
    root = tk.Tk()
    root.title("ethercat的通讯程序")
    root.geometry("600x400")

    label1 = tk.Label(root, text="温度 值=0", font=("Arial", 30))  
    label1.pack()
    label2 = tk.Label(root, text="湿度 值=0", font=("Arial", 30))  
    label2.pack()

    btn_led1_on = tk.Button(root, text="LED1 ON",command=lambda:led_control(0,1))
    btn_led1_on.pack()
    btn_led1_off = tk.Button(root, text="LED1 OFF",command=lambda:led_control(0,0))
    btn_led1_off.pack()

    btn_led2_on = tk.Button(root, text="LED2 ON",command=lambda:led_control(1,1))
    btn_led2_on.pack()
    btn_led2_off = tk.Button(root, text="LED2 OFF",command=lambda:led_control(1,0))
    btn_led2_off.pack()

    btn_led3_on = tk.Button(root, text="LED3 ON",command=lambda:led_control(2,1))
    btn_led3_on.pack()
    btn_led3_off = tk.Button(root, text="LED3 OFF",command=lambda:led_control(2,0))
    btn_led3_off.pack()

    btn_led4_on = tk.Button(root, text="LED4 ON",command=lambda:led_control(3,1))
    btn_led4_on.pack()
    btn_led4_off = tk.Button(root, text="LED4 OFF",command=lambda:led_control(3,0))
    btn_led4_off.pack()

    btn_led5_on = tk.Button(root, text="LED5 ON",command=lambda:led_control(4,1))
    btn_led5_on.pack()
    btn_led5_off = tk.Button(root, text="LED5 OFF",command=lambda:led_control(4,0))
    btn_led5_off.pack()
    def thread1():  
        while True:
            master.send_processdata()  
            master.receive_processdata(timeout=2000)
            cnt1 = int.from_bytes(slave.input[0:2], byteorder='little', signed=True)
            cnt2 = int.from_bytes(slave.input[2:4], byteorder='little', signed=False)
            #print(f"cnt1={cnt1}")
            label1.config(text=f"温度 值={cnt1/10}°C")
            label2.config(text=f"湿度 值={cnt2/10}%")
            time.sleep(0.01)
        
    ethercat_thread = threading.Thread(target=thread1, daemon=True)  
    ethercat_thread.start()

    root.mainloop()

    print("程序已关闭.")  
    master.state = pysoem.INIT_STATE  
    # request INIT state for all slaves  master.write_state()
    master.close()

# *示例7和8

主要内容: 控制闭环步进电机,多电机同步控制。

WTB物联网   |