AB&T
/
EasyCAT_LAB_very_simple
EasyCAT LAB - EtherCAT master very simple example
- 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.
- The EasyCAT LAB is provided as a kit by AB&T Tecnologie Informatiche, to allow everybody to have an educational EtherCAT® system up and running in a matter of minutes.
- It uses the SOEM (Simple Open EtherCAT® Master) library by rt-labs, that has been ported in the ecosystem by AB&T Tecnologie Informatiche.
- The slaves are based on the EasyCAT SHIELD and the Arduino UNO.
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 .
main.cpp
- Committer:
- EasyCAT
- Date:
- 11 months ago
- Revision:
- 2:368e7d4d8171
- Parent:
- 1:971b4897a4c5
File content as of revision 2:368e7d4d8171:
//******************************************************************************************** // * // 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() UnbufferedSerial 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_1->Segments = in_LAB_2->Buttons; // send to the slave LAB_2_1 the buttons status // from the slave LAB_2_2 out_LAB_2->Segments = in_LAB_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; ThisThread::sleep_for(100ms); } }