EasyCAT LAB - EtherCAT master very simple example

Dependencies:   SOEM

  • This repository contains a very basic example for the EasyCAT LAB , a complete educational and experimental EtherCAT® system, composed of one master and two slaves.

Note

  • This example uses two LAB 2 slaves.

Note

  • In this example, to keep things as simple as possible, only two bytes of data are exchanged between the slaves and the TFT display is not used .
Revision:
0:bc829777f1ea
Child:
1:971b4897a4c5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Jul 09 16:25:27 2019 +0000
@@ -0,0 +1,292 @@
+//********************************************************************************************    
+//                                                                                           *
+// This software is distributed as an example, "AS IS", in the hope that it could            *
+// be useful, WITHOUT ANY WARRANTY of any kind, express or implied, included, but            *
+// not limited,  to the warranties of merchantability, fitness for a particular              *
+// purpose, and non infringiment. In no event shall the authors be liable for any            *    
+// claim, damages or other liability, arising from, or in connection with this software.     *
+//                                                                                           *
+//******************************************************************************************** 
+
+
+// The AB&T EasyCAT LAB is a complete experimental EtherCAT® system, composed by
+// one master and two slaves.
+// The EasyCAT LAB software is provided free of charge and its pourpose is to allow
+// makers and educational institutes to experiment with the EtherCAT® protocol.
+//
+// The EasyCAT LAB is developed by "AB&T Tecnologie Informatiche" Via dell'About 2A Ivrea Italy.
+// www.bausano.net
+// www.easycatshield.com
+//
+// The EasyCAT LAB uses the SOEM library by rt:labs
+// https://rt-labs.com/products/soem-ethercat-master-stack/
+// 
+// EtherCAT® is a registered trademark and patented technology, licensed by Beckhoff Automation GmbH.
+// www.beckhoff.com
+// www.ethercat.org     
+
+
+#define ETH_TXBUFNB 16
+#define ETH_RXBUFNB 16
+
+#include "mbed.h"    
+
+#ifndef __align
+#define __align MBED_ALIGN
+#endif
+
+#include "config.h"  
+#include "soem_start.h"
+
+#define CYCLE_TIME 1000                 // master cycle time in uS                    
+                                        // 1000 = 1mS 
+
+                                  
+#define SysMilliS() (uint32_t)Kernel::get_ms_count()                                      
+
+Serial pc(USBTX,USBRX,115200);          // set the debug serial line speed to 115200
+
+
+
+//---- local functions ---------------------------------------------------------
+
+void Application();   
+void BlinkLedForever();
+
+//------------------------------------------------------------------------------
+
+Ticker SampleTicker;
+Thread thread;
+
+DigitalOut Test_1(D1);          // debug test points
+DigitalOut Test_2(D2);          //
+DigitalOut Test_3(D3);          //
+DigitalOut Test_4(D4);          //
+
+DigitalOut LED_RED(LED3);
+
+   
+//------------------------------------------------------------------------------   
+
+int ExpectWorkCounter;
+int WorkCounter; 
+int WorkCounterSafe; 
+bool NetworkError;  
+bool NetworkErrorSafe; 
+
+#define DATA_EXCHANGE_FLAG      (1UL << 0)
+#define APPLICATION_FLAG        (1UL << 1)
+
+EventFlags event_flags;
+
+Mutex IO_data;
+
+
+//---- data exchange thread ----------------------------------------------------
+
+void ExchangeMaster()
+{
+    while (true)
+    {
+        event_flags.wait_any(DATA_EXCHANGE_FLAG);   // the thread waits for the synchronization flag
+    
+        //Test_1 = 1;
+    
+        IO_data.lock();                             // Ethercat data exchange
+        ec_send_processdata();                      // 
+        WorkCounter = ec_receive_processdata(EC_TIMEOUTRET);  
+        
+        if (WorkCounter != ExpectWorkCounter)
+            NetworkError = true;
+        else
+            NetworkError = false;    
+                            
+        IO_data.unlock();                           //
+        event_flags.set(APPLICATION_FLAG);          // synchronize the application    
+        
+        //Test_1 = 0;                    
+    }
+}
+
+
+//----- thicker generated sample time ------------------------------------------
+
+void SampleIsr()                                    // set the event that starts
+{                                                   // the data exchange
+    event_flags.set(DATA_EXCHANGE_FLAG);            //
+}                                                   //
+    
+    
+//****** initialization ********************************************************
+
+int main()
+{      
+    int i;
+    
+    printf("Start \n");
+    
+    Test_1 = 0; 
+    Test_2 = 0;
+    Test_3 = 0;
+    Test_4 = 0;      
+        
+    NetworkError = false;  
+      
+    if (ec_init(NULL))                                              // init SOEM
+    {
+        printf("ec_init succeeded.\n");     
+        printf("Scanning the network\n");       
+          
+        if (network_scanning())
+        {   
+            if (network_configuration())                            // check network configuration
+            {
+                ec_config_map(&IOmap);                              // map the I/O
+                MapLocalStructures();                 
+
+                printf("\nSlaves mapped, state to SAFE_OP.\n");     
+                                                                    // wait for all slaves to reach SAFE_OP state         
+                ec_statecheck(0, EC_STATE_SAFE_OP,  EC_TIMEOUTSTATE);
+    
+                printf("Request operational state for all slaves\n");
+                ec_slave[0].state = EC_STATE_OPERATIONAL;           
+           
+                ec_send_processdata();                              // send one valid process data to make outputs in slaves happy
+                ExpectWorkCounter = ec_receive_processdata(EC_TIMEOUTRET);          
+               
+                ec_writestate(0);                                   // request OP state for all slaves 
+                
+                                                                    // wait for all slaves to reach OP state 
+                ec_statecheck(0, EC_STATE_OPERATIONAL,  EC_TIMEOUTSTATE);
+                if (ec_slave[0].state == EC_STATE_OPERATIONAL )
+                {
+                    printf("Operational state reached for all slaves.\n");
+                }
+                else
+                {
+                    printf("Not all slaves reached operational state.\n");
+                    ec_readstate();
+                    for(i = 1; i<=ec_slavecount ; i++)
+                    {
+                        if(ec_slave[i].state != EC_STATE_OPERATIONAL)
+                        {
+                            printf("Slave %d State=0x%04x StatusCode=0x%04x\n",
+                                    i, ec_slave[i].state, ec_slave[i].ALstatuscode);
+                        }
+                    }
+                      
+                    printf("Not all slaves reached operational state!\n"); 
+                    void BlinkLedForever();                          
+                }   
+                
+                                
+                thread.start(ExchangeMaster);
+                thread.set_priority(osPriorityRealtime); 
+
+                SampleTicker.attach_us(&SampleIsr, CYCLE_TIME);  
+              
+                Application();
+            }
+            
+            else
+            {
+                printf("Mismatch of network units!\n");               
+                BlinkLedForever();
+            }                       
+        }       
+        
+        else
+        {
+            printf("No slaves found!\n");     
+            BlinkLedForever();     
+        }           
+    }
+    else
+    {
+        printf("Ethernet interface init failed!");
+        BlinkLedForever();           
+    }    
+}             
+                                 
+              
+//****** user master application  **********************************************
+      
+void Application()      
+{        
+     
+    while(1)
+    {          
+        event_flags.wait_any(APPLICATION_FLAG);                     // the application waits for the synchronization flag
+        
+        //Test_2 = 1;     
+     
+        IO_data.lock();                                             // copy the Ethercat data to a safe buffer
+        memcpy(&IOmapSafe[0], &IOmap[0], IO_MAP_SIZE);              //
+                                                                    //                
+        if (NetworkError)                                           //    
+        {                                                           //
+            NetworkErrorSafe = NetworkError;                        //    
+            WorkCounterSafe = WorkCounter;                          //
+        }                                                           //
+        IO_data.unlock();                                           // 
+              
+        if (NetworkErrorSafe)
+        {           
+            printf("Network error!\n");                  
+            
+            if(WorkCounterSafe >= 0)
+            {
+                printf("Expected working counter %d\n", ExpectWorkCounter);                                                    
+                printf("Actual working counter %d\n", WorkCounterSafe); 
+            } 
+            else
+            {             
+                printf("Timeout\n");   
+            }                        
+                                         
+            printf("Please fix the error and press the reset button \n"); 
+            
+            SampleTicker.detach();                                  // stop the sample interrupt 
+            BlinkLedForever();                                      // and loop for ever                           
+        }     
+        
+        
+                                                                    //----- slaves  data management -----------            
+                                                                
+                                                                                                                                                                                      
+        out_LAB_2_1->Segments = in_LAB_2_2->Buttons;                // send to the slave LAB_2_1 the buttons status
+                                                                    // from the slave LAB_2_2    
+                                                                    
+                                                                                  
+        out_LAB_2_2->Segments = in_LAB_2_1->Buttons;                // send to the slave LAB_2_2 the buttons status
+                                                                    // from the slave LAB_2_1   
+                                                                    
+                                                                    
+                                                                    //----------------------------------------
+                                                                    
+                                                                     
+                                                                                                                                                                                                                                                                                         
+        IO_data.lock();                                             // copy the IO data from the safe area
+        memcpy(&IOmap[0], &IOmapSafe[0], IO_MAP_SIZE);              // to the EtherCAT buffer
+        IO_data.unlock();                                           //    
+        
+        //Test_2 = 0;                             
+    }       
+}      
+  
+//******************************************************************************
+
+
+void BlinkLedForever()                    // blink the red led forever to signal  
+                                          // an unrecoverable error condition
+                                          
+                                          // fix the error and press the reset button              
+{
+    while(1)
+    {           
+        LED_RED = !LED_RED;
+        wait_ms(100);    
+    }
+}    
+
+