![](/media/cache/profiles/433cd42837eb8bc231c8db5e4267cafc.jpg.50x50_q85.jpg)
EasyCAT LAB - EtherCAT master simple example
Dependencies: SOEM SPI_TFT_ILI9341 TFT_fonts
- This repository contains a simple 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 only two bytes of data are exchanged between the slaves and are also visualized on the TFT display.
main.cpp@2:a0e017115fc5, 2021-05-28 (annotated)
- Committer:
- sulymarco
- Date:
- Fri May 28 09:37:01 2021 +0000
- Revision:
- 2:a0e017115fc5
- Parent:
- 1:385bdd2b4cd6
- Child:
- 3:9c8c179d1f8a
Added compatibility with the Adafruit TFT
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
sulymarco | 0:13be39911caf | 1 | //******************************************************************************************** |
sulymarco | 0:13be39911caf | 2 | // * |
sulymarco | 0:13be39911caf | 3 | // This software is distributed as an example, "AS IS", in the hope that it could * |
sulymarco | 0:13be39911caf | 4 | // be useful, WITHOUT ANY WARRANTY of any kind, express or implied, included, but * |
sulymarco | 0:13be39911caf | 5 | // not limited, to the warranties of merchantability, fitness for a particular * |
sulymarco | 0:13be39911caf | 6 | // purpose, and non infringiment. In no event shall the authors be liable for any * |
sulymarco | 0:13be39911caf | 7 | // claim, damages or other liability, arising from, or in connection with this software. * |
sulymarco | 0:13be39911caf | 8 | // * |
sulymarco | 0:13be39911caf | 9 | //******************************************************************************************** |
sulymarco | 0:13be39911caf | 10 | |
sulymarco | 0:13be39911caf | 11 | |
sulymarco | 0:13be39911caf | 12 | // The AB&T EasyCAT LAB is a complete experimental EtherCAT® system, composed by |
sulymarco | 0:13be39911caf | 13 | // one master and two slaves. |
sulymarco | 0:13be39911caf | 14 | // The EasyCAT LAB software is provided free of charge and its pourpose is to allow |
sulymarco | 0:13be39911caf | 15 | // makers and educational institutes to experiment with the EtherCAT® protocol. |
sulymarco | 0:13be39911caf | 16 | // |
sulymarco | 0:13be39911caf | 17 | // The EasyCAT LAB is developed by "AB&T Tecnologie Informatiche" Via dell'About 2A Ivrea Italy. |
sulymarco | 0:13be39911caf | 18 | // www.bausano.net |
sulymarco | 0:13be39911caf | 19 | // www.easycatshield.com |
sulymarco | 0:13be39911caf | 20 | // |
sulymarco | 0:13be39911caf | 21 | // The EasyCAT LAB uses the SOEM library by rt:labs |
sulymarco | 0:13be39911caf | 22 | // https://rt-labs.com/products/soem-ethercat-master-stack/ |
sulymarco | 0:13be39911caf | 23 | // |
sulymarco | 0:13be39911caf | 24 | // EtherCAT® is a registered trademark and patented technology, licensed by Beckhoff Automation GmbH. |
sulymarco | 0:13be39911caf | 25 | // www.beckhoff.com |
sulymarco | 2:a0e017115fc5 | 26 | // www.ethercat.org |
sulymarco | 2:a0e017115fc5 | 27 | |
sulymarco | 2:a0e017115fc5 | 28 | |
sulymarco | 2:a0e017115fc5 | 29 | //****************************************************************************** |
sulymarco | 2:a0e017115fc5 | 30 | |
sulymarco | 2:a0e017115fc5 | 31 | //#define ADA_TFT // IMPORTANT!!! |
sulymarco | 2:a0e017115fc5 | 32 | |
sulymarco | 2:a0e017115fc5 | 33 | // If your EasyCAT LAB uses the Adafruit TFT |
sulymarco | 2:a0e017115fc5 | 34 | // you must uncomment this define |
sulymarco | 2:a0e017115fc5 | 35 | |
sulymarco | 2:a0e017115fc5 | 36 | // If your EasyCAT LAB uses the Seeed Studio TFT |
sulymarco | 2:a0e017115fc5 | 37 | // you must comment this define |
sulymarco | 2:a0e017115fc5 | 38 | |
sulymarco | 2:a0e017115fc5 | 39 | //****************************************************************************** |
sulymarco | 0:13be39911caf | 40 | |
sulymarco | 0:13be39911caf | 41 | |
sulymarco | 0:13be39911caf | 42 | #define ETH_TXBUFNB 16 |
sulymarco | 0:13be39911caf | 43 | #define ETH_RXBUFNB 16 |
sulymarco | 0:13be39911caf | 44 | |
sulymarco | 0:13be39911caf | 45 | #include "mbed.h" |
sulymarco | 0:13be39911caf | 46 | |
sulymarco | 0:13be39911caf | 47 | #ifndef __align |
sulymarco | 0:13be39911caf | 48 | #define __align MBED_ALIGN |
sulymarco | 0:13be39911caf | 49 | #endif |
sulymarco | 0:13be39911caf | 50 | |
sulymarco | 0:13be39911caf | 51 | #include "config.h" |
sulymarco | 0:13be39911caf | 52 | #include "SPI_TFT_ILI9341.h" |
sulymarco | 0:13be39911caf | 53 | #include "Arial12x12.h" |
sulymarco | 0:13be39911caf | 54 | #include "Arial24x23.h" |
sulymarco | 0:13be39911caf | 55 | #include "Arial28x28.h" |
sulymarco | 0:13be39911caf | 56 | #include "font_big.h" |
sulymarco | 0:13be39911caf | 57 | #include "soem_start.h" |
sulymarco | 0:13be39911caf | 58 | |
sulymarco | 0:13be39911caf | 59 | #define CYCLE_TIME 1000 // master cycle time in uS |
sulymarco | 0:13be39911caf | 60 | // 1000 = 1mS |
sulymarco | 0:13be39911caf | 61 | |
sulymarco | 0:13be39911caf | 62 | |
sulymarco | 0:13be39911caf | 63 | #define SysMilliS() (uint32_t)Kernel::get_ms_count() |
sulymarco | 0:13be39911caf | 64 | |
EasyCAT | 1:385bdd2b4cd6 | 65 | UnbufferedSerial pc(USBTX,USBRX,115200); // set the debug serial line speed to 115200 |
sulymarco | 0:13be39911caf | 66 | |
sulymarco | 0:13be39911caf | 67 | |
sulymarco | 0:13be39911caf | 68 | //---- TFT with resistive touchscreen pins ------------------------------------- |
sulymarco | 0:13be39911caf | 69 | |
sulymarco | 0:13be39911caf | 70 | // the display used is the SeeedStudio 2.8 inch TFT v2.0 |
sulymarco | 0:13be39911caf | 71 | // http://wiki.seeedstudio.com/2.8inch_TFT_Touch_Shield_v2.0/ |
sulymarco | 2:a0e017115fc5 | 72 | // |
sulymarco | 2:a0e017115fc5 | 73 | // or the Adafruit 2.8" with resistive touchscreen |
sulymarco | 2:a0e017115fc5 | 74 | // https://www.adafruit.com/product/1651 |
sulymarco | 2:a0e017115fc5 | 75 | |
sulymarco | 2:a0e017115fc5 | 76 | // the touchscreen is not used in this example |
sulymarco | 0:13be39911caf | 77 | |
sulymarco | 0:13be39911caf | 78 | #define PIN_YP A3 // resistive touchscreen |
sulymarco | 0:13be39911caf | 79 | #define PIN_YM A1 // |
sulymarco | 0:13be39911caf | 80 | #define PIN_XM A2 // |
sulymarco | 0:13be39911caf | 81 | #define PIN_XP A0 // |
sulymarco | 0:13be39911caf | 82 | |
sulymarco | 0:13be39911caf | 83 | #define PIN_MOSI D11 // TFT display SPI |
sulymarco | 0:13be39911caf | 84 | #define PIN_MISO D12 // |
sulymarco | 0:13be39911caf | 85 | #define PIN_SCLK D13 // |
sulymarco | 2:a0e017115fc5 | 86 | |
sulymarco | 2:a0e017115fc5 | 87 | #if defined ADA_TFT // pins for the Adafruit TFT |
sulymarco | 2:a0e017115fc5 | 88 | #define PIN_CS_TFT D10 // |
sulymarco | 2:a0e017115fc5 | 89 | #define PIN_DC_TFT D9 // |
sulymarco | 2:a0e017115fc5 | 90 | #define PIN_CS_TSC D8 // |
sulymarco | 2:a0e017115fc5 | 91 | |
sulymarco | 2:a0e017115fc5 | 92 | #else // pins for the SeeedStudio TFT |
sulymarco | 2:a0e017115fc5 | 93 | #define PIN_CS_TFT D5 // |
sulymarco | 2:a0e017115fc5 | 94 | #define PIN_DC_TFT D6 // |
sulymarco | 2:a0e017115fc5 | 95 | #endif // |
sulymarco | 0:13be39911caf | 96 | |
sulymarco | 0:13be39911caf | 97 | |
sulymarco | 0:13be39911caf | 98 | |
sulymarco | 0:13be39911caf | 99 | //---- visualization parameters ------------------------------------------------ |
sulymarco | 0:13be39911caf | 100 | |
sulymarco | 0:13be39911caf | 101 | #define BUTTONS_1_X 80 |
sulymarco | 0:13be39911caf | 102 | #define BUTTONS_1_Y 60 |
sulymarco | 0:13be39911caf | 103 | |
sulymarco | 0:13be39911caf | 104 | #define BUTTONS_2_X 80 |
sulymarco | 0:13be39911caf | 105 | #define BUTTONS_2_Y 180 |
sulymarco | 0:13be39911caf | 106 | |
sulymarco | 0:13be39911caf | 107 | |
sulymarco | 0:13be39911caf | 108 | #define BUTTONS_1_WIDTH 26 |
sulymarco | 0:13be39911caf | 109 | #define BUTTONS_1_R 3 |
sulymarco | 0:13be39911caf | 110 | #define BUTTONS_1_STEP 60 |
sulymarco | 0:13be39911caf | 111 | |
sulymarco | 0:13be39911caf | 112 | #define BUTTONS_2_WIDTH BUTTONS_1_WIDTH |
sulymarco | 0:13be39911caf | 113 | #define BUTTONS_2_R BUTTONS_1_R |
sulymarco | 0:13be39911caf | 114 | #define BUTTONS_2_STEP BUTTONS_1_STEP |
sulymarco | 0:13be39911caf | 115 | |
sulymarco | 0:13be39911caf | 116 | |
sulymarco | 0:13be39911caf | 117 | //---- local functions --------------------------------------------------------- |
sulymarco | 0:13be39911caf | 118 | |
sulymarco | 0:13be39911caf | 119 | void DrawBanner(); |
sulymarco | 0:13be39911caf | 120 | void DrawSlaveFixedParts(); |
sulymarco | 0:13be39911caf | 121 | void DrawButtons_1_Value(uint8_t Value); |
sulymarco | 0:13be39911caf | 122 | void DrawButtons_2_Value(uint8_t Value); |
sulymarco | 0:13be39911caf | 123 | |
sulymarco | 0:13be39911caf | 124 | void Application(); |
sulymarco | 0:13be39911caf | 125 | |
sulymarco | 0:13be39911caf | 126 | |
sulymarco | 0:13be39911caf | 127 | //---- global variables -------------------------------------------------------- |
sulymarco | 0:13be39911caf | 128 | |
sulymarco | 0:13be39911caf | 129 | |
sulymarco | 0:13be39911caf | 130 | bool FirstRound; |
sulymarco | 0:13be39911caf | 131 | |
sulymarco | 0:13be39911caf | 132 | //------------------------------------------------------------------------------ |
sulymarco | 0:13be39911caf | 133 | |
sulymarco | 0:13be39911caf | 134 | SPI_TFT_ILI9341 TFT(PIN_MOSI, PIN_MISO, PIN_SCLK, PIN_CS_TFT, NC, PIN_DC_TFT); |
sulymarco | 0:13be39911caf | 135 | |
sulymarco | 0:13be39911caf | 136 | Ticker SampleTicker; |
sulymarco | 0:13be39911caf | 137 | Thread thread; |
sulymarco | 0:13be39911caf | 138 | |
sulymarco | 0:13be39911caf | 139 | DigitalOut Test_1(D1); // debug test points |
sulymarco | 0:13be39911caf | 140 | DigitalOut Test_2(D2); // |
sulymarco | 0:13be39911caf | 141 | DigitalOut Test_3(D3); // |
sulymarco | 0:13be39911caf | 142 | DigitalOut Test_4(D4); // |
sulymarco | 0:13be39911caf | 143 | |
sulymarco | 0:13be39911caf | 144 | |
sulymarco | 0:13be39911caf | 145 | //------------------------------------------------------------------------------ |
sulymarco | 0:13be39911caf | 146 | |
sulymarco | 0:13be39911caf | 147 | uint8_t Buttons_1; |
sulymarco | 0:13be39911caf | 148 | uint8_t PrevButtons_1; |
sulymarco | 0:13be39911caf | 149 | uint8_t Segments_1; |
sulymarco | 0:13be39911caf | 150 | uint8_t PrevSegments_1; |
sulymarco | 0:13be39911caf | 151 | |
sulymarco | 0:13be39911caf | 152 | uint8_t Buttons_2; |
sulymarco | 0:13be39911caf | 153 | uint8_t PrevButtons_2; |
sulymarco | 0:13be39911caf | 154 | uint8_t Segments_2; |
sulymarco | 0:13be39911caf | 155 | uint8_t PrevSegments_2; |
sulymarco | 0:13be39911caf | 156 | |
sulymarco | 0:13be39911caf | 157 | |
sulymarco | 0:13be39911caf | 158 | //------------------------------------------------------------------------------ |
sulymarco | 0:13be39911caf | 159 | |
sulymarco | 0:13be39911caf | 160 | int ExpectWorkCounter; |
sulymarco | 0:13be39911caf | 161 | int WorkCounter; |
sulymarco | 0:13be39911caf | 162 | int WorkCounterSafe; |
sulymarco | 0:13be39911caf | 163 | bool NetworkError; |
sulymarco | 0:13be39911caf | 164 | bool NetworkErrorSafe; |
sulymarco | 0:13be39911caf | 165 | |
sulymarco | 0:13be39911caf | 166 | #define DATA_EXCHANGE_FLAG (1UL << 0) |
sulymarco | 0:13be39911caf | 167 | #define APPLICATION_FLAG (1UL << 1) |
sulymarco | 0:13be39911caf | 168 | |
sulymarco | 0:13be39911caf | 169 | EventFlags event_flags; |
sulymarco | 0:13be39911caf | 170 | |
sulymarco | 0:13be39911caf | 171 | Mutex IO_data; |
sulymarco | 0:13be39911caf | 172 | |
sulymarco | 0:13be39911caf | 173 | |
sulymarco | 0:13be39911caf | 174 | //---- data exchange thread ---------------------------------------------------- |
sulymarco | 0:13be39911caf | 175 | |
sulymarco | 0:13be39911caf | 176 | void ExchangeMaster() |
sulymarco | 0:13be39911caf | 177 | { |
sulymarco | 0:13be39911caf | 178 | while (true) |
sulymarco | 0:13be39911caf | 179 | { |
sulymarco | 0:13be39911caf | 180 | event_flags.wait_any(DATA_EXCHANGE_FLAG); // the thread waits for the synchronization flag |
sulymarco | 0:13be39911caf | 181 | |
sulymarco | 0:13be39911caf | 182 | //Test_1 = 1; |
sulymarco | 0:13be39911caf | 183 | |
sulymarco | 0:13be39911caf | 184 | IO_data.lock(); // Ethercat data exchange |
sulymarco | 0:13be39911caf | 185 | ec_send_processdata(); // |
sulymarco | 0:13be39911caf | 186 | WorkCounter = ec_receive_processdata(EC_TIMEOUTRET); |
sulymarco | 0:13be39911caf | 187 | |
sulymarco | 0:13be39911caf | 188 | if (WorkCounter != ExpectWorkCounter) |
sulymarco | 0:13be39911caf | 189 | NetworkError = true; |
sulymarco | 0:13be39911caf | 190 | else |
sulymarco | 0:13be39911caf | 191 | NetworkError = false; |
sulymarco | 0:13be39911caf | 192 | |
sulymarco | 0:13be39911caf | 193 | IO_data.unlock(); // |
sulymarco | 0:13be39911caf | 194 | event_flags.set(APPLICATION_FLAG); // synchronize the application |
sulymarco | 0:13be39911caf | 195 | |
sulymarco | 0:13be39911caf | 196 | //Test_1 = 0; |
sulymarco | 0:13be39911caf | 197 | } |
sulymarco | 0:13be39911caf | 198 | } |
sulymarco | 0:13be39911caf | 199 | |
sulymarco | 0:13be39911caf | 200 | |
sulymarco | 0:13be39911caf | 201 | //----- thicker generated sample time ------------------------------------------ |
sulymarco | 0:13be39911caf | 202 | |
sulymarco | 0:13be39911caf | 203 | void SampleIsr() // set the event that starts |
sulymarco | 0:13be39911caf | 204 | { // the data exchange |
sulymarco | 0:13be39911caf | 205 | event_flags.set(DATA_EXCHANGE_FLAG); // |
sulymarco | 0:13be39911caf | 206 | } // |
sulymarco | 0:13be39911caf | 207 | |
sulymarco | 0:13be39911caf | 208 | |
sulymarco | 0:13be39911caf | 209 | //****** initialization ******************************************************** |
sulymarco | 0:13be39911caf | 210 | |
sulymarco | 0:13be39911caf | 211 | int main() |
sulymarco | 0:13be39911caf | 212 | { |
sulymarco | 0:13be39911caf | 213 | int i; |
sulymarco | 0:13be39911caf | 214 | |
sulymarco | 0:13be39911caf | 215 | printf("Start \n"); |
sulymarco | 0:13be39911caf | 216 | |
sulymarco | 0:13be39911caf | 217 | Test_1 = 0; |
sulymarco | 0:13be39911caf | 218 | Test_2 = 0; |
sulymarco | 0:13be39911caf | 219 | Test_3 = 0; |
sulymarco | 0:13be39911caf | 220 | Test_4 = 0; |
sulymarco | 0:13be39911caf | 221 | |
sulymarco | 0:13be39911caf | 222 | TFT.background(Black); // init TFT |
sulymarco | 0:13be39911caf | 223 | TFT.cls(); // |
sulymarco | 2:a0e017115fc5 | 224 | |
sulymarco | 2:a0e017115fc5 | 225 | #if defined ADA_TFT |
sulymarco | 2:a0e017115fc5 | 226 | TFT.set_orientation(1); |
sulymarco | 2:a0e017115fc5 | 227 | #else |
sulymarco | 2:a0e017115fc5 | 228 | TFT.set_orientation(3); |
sulymarco | 2:a0e017115fc5 | 229 | #endif |
sulymarco | 0:13be39911caf | 230 | |
sulymarco | 0:13be39911caf | 231 | DrawBanner(); |
sulymarco | 0:13be39911caf | 232 | |
sulymarco | 0:13be39911caf | 233 | NetworkError = false; |
sulymarco | 0:13be39911caf | 234 | |
sulymarco | 0:13be39911caf | 235 | if (ec_init(NULL)) // init SOEM |
sulymarco | 0:13be39911caf | 236 | { |
sulymarco | 0:13be39911caf | 237 | printf("ec_init succeeded.\n"); |
sulymarco | 0:13be39911caf | 238 | printf("Scanning the network\n"); |
sulymarco | 0:13be39911caf | 239 | |
sulymarco | 0:13be39911caf | 240 | TFT.cls(); |
sulymarco | 0:13be39911caf | 241 | |
sulymarco | 0:13be39911caf | 242 | TFT.set_font((unsigned char*) Arial12x12); |
sulymarco | 0:13be39911caf | 243 | TFT.foreground(Green); |
sulymarco | 0:13be39911caf | 244 | TFT.locate(0, 0); |
sulymarco | 0:13be39911caf | 245 | |
sulymarco | 0:13be39911caf | 246 | TFT.printf("Scanning the network\n"); |
sulymarco | 0:13be39911caf | 247 | |
sulymarco | 0:13be39911caf | 248 | if (network_scanning()) |
sulymarco | 0:13be39911caf | 249 | { |
sulymarco | 0:13be39911caf | 250 | if (network_configuration()) // check network configuration |
sulymarco | 0:13be39911caf | 251 | { |
sulymarco | 0:13be39911caf | 252 | ec_config_map(&IOmap); // map the I/O |
sulymarco | 0:13be39911caf | 253 | MapLocalStructures(); |
sulymarco | 0:13be39911caf | 254 | |
sulymarco | 0:13be39911caf | 255 | printf("\nSlaves mapped, state to SAFE_OP.\n"); |
sulymarco | 0:13be39911caf | 256 | // wait for all slaves to reach SAFE_OP state |
sulymarco | 0:13be39911caf | 257 | ec_statecheck(0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE); |
sulymarco | 0:13be39911caf | 258 | |
sulymarco | 0:13be39911caf | 259 | printf("Request operational state for all slaves\n"); |
sulymarco | 0:13be39911caf | 260 | ec_slave[0].state = EC_STATE_OPERATIONAL; |
sulymarco | 0:13be39911caf | 261 | |
sulymarco | 0:13be39911caf | 262 | ec_send_processdata(); // send one valid process data to make outputs in slaves happy |
sulymarco | 0:13be39911caf | 263 | ExpectWorkCounter = ec_receive_processdata(EC_TIMEOUTRET); |
sulymarco | 0:13be39911caf | 264 | |
sulymarco | 0:13be39911caf | 265 | ec_writestate(0); // request OP state for all slaves |
sulymarco | 0:13be39911caf | 266 | |
sulymarco | 0:13be39911caf | 267 | // wait for all slaves to reach OP state |
sulymarco | 0:13be39911caf | 268 | ec_statecheck(0, EC_STATE_OPERATIONAL, EC_TIMEOUTSTATE); |
sulymarco | 0:13be39911caf | 269 | if (ec_slave[0].state == EC_STATE_OPERATIONAL ) |
sulymarco | 0:13be39911caf | 270 | { |
sulymarco | 0:13be39911caf | 271 | printf("Operational state reached for all slaves.\n"); |
sulymarco | 0:13be39911caf | 272 | } |
sulymarco | 0:13be39911caf | 273 | else |
sulymarco | 0:13be39911caf | 274 | { |
sulymarco | 0:13be39911caf | 275 | printf("Not all slaves reached operational state.\n"); |
sulymarco | 0:13be39911caf | 276 | ec_readstate(); |
sulymarco | 0:13be39911caf | 277 | for(i = 1; i<=ec_slavecount ; i++) |
sulymarco | 0:13be39911caf | 278 | { |
sulymarco | 0:13be39911caf | 279 | if(ec_slave[i].state != EC_STATE_OPERATIONAL) |
sulymarco | 0:13be39911caf | 280 | { |
sulymarco | 0:13be39911caf | 281 | printf("Slave %d State=0x%04x StatusCode=0x%04x\n", |
sulymarco | 0:13be39911caf | 282 | i, ec_slave[i].state, ec_slave[i].ALstatuscode); |
sulymarco | 0:13be39911caf | 283 | } |
sulymarco | 0:13be39911caf | 284 | } |
sulymarco | 0:13be39911caf | 285 | |
sulymarco | 0:13be39911caf | 286 | TFT.foreground(Red); |
sulymarco | 0:13be39911caf | 287 | TFT.locate(0, 0); |
sulymarco | 0:13be39911caf | 288 | TFT.printf("Not all slaves reached operational state!"); |
sulymarco | 0:13be39911caf | 289 | while(1){} |
sulymarco | 0:13be39911caf | 290 | } |
sulymarco | 0:13be39911caf | 291 | |
sulymarco | 0:13be39911caf | 292 | DrawSlaveFixedParts(); |
sulymarco | 0:13be39911caf | 293 | |
sulymarco | 0:13be39911caf | 294 | thread.start(ExchangeMaster); |
sulymarco | 0:13be39911caf | 295 | thread.set_priority(osPriorityRealtime); |
sulymarco | 0:13be39911caf | 296 | |
sulymarco | 0:13be39911caf | 297 | SampleTicker.attach_us(&SampleIsr, CYCLE_TIME); |
sulymarco | 0:13be39911caf | 298 | |
sulymarco | 0:13be39911caf | 299 | Application(); |
sulymarco | 0:13be39911caf | 300 | } |
sulymarco | 0:13be39911caf | 301 | |
sulymarco | 0:13be39911caf | 302 | else |
sulymarco | 0:13be39911caf | 303 | { |
sulymarco | 0:13be39911caf | 304 | printf("Mismatch of network units!\n"); |
sulymarco | 0:13be39911caf | 305 | TFT.foreground(Red); |
sulymarco | 0:13be39911caf | 306 | TFT.locate(0, 0); |
sulymarco | 0:13be39911caf | 307 | TFT.printf("Mismatch of network units!"); |
sulymarco | 0:13be39911caf | 308 | |
sulymarco | 0:13be39911caf | 309 | while(1){} |
sulymarco | 0:13be39911caf | 310 | } |
sulymarco | 0:13be39911caf | 311 | } |
sulymarco | 0:13be39911caf | 312 | |
sulymarco | 0:13be39911caf | 313 | else |
sulymarco | 0:13be39911caf | 314 | { |
sulymarco | 0:13be39911caf | 315 | printf("No slaves found!\n"); |
sulymarco | 0:13be39911caf | 316 | TFT.foreground(Red); |
sulymarco | 0:13be39911caf | 317 | TFT.printf("No slaves found!"); |
sulymarco | 0:13be39911caf | 318 | |
sulymarco | 0:13be39911caf | 319 | while(1){} |
sulymarco | 0:13be39911caf | 320 | } |
sulymarco | 0:13be39911caf | 321 | } |
sulymarco | 0:13be39911caf | 322 | else |
sulymarco | 0:13be39911caf | 323 | { |
sulymarco | 0:13be39911caf | 324 | printf("Ethernet interface init failed!"); |
sulymarco | 0:13be39911caf | 325 | TFT.foreground(Red); |
sulymarco | 0:13be39911caf | 326 | TFT.locate(0, 0); |
sulymarco | 0:13be39911caf | 327 | TFT.printf("Ethernet interface init failed!"); |
sulymarco | 0:13be39911caf | 328 | while(1){} |
sulymarco | 0:13be39911caf | 329 | } |
sulymarco | 0:13be39911caf | 330 | } |
sulymarco | 0:13be39911caf | 331 | |
sulymarco | 0:13be39911caf | 332 | |
sulymarco | 0:13be39911caf | 333 | //****** user master application ********************************************** |
sulymarco | 0:13be39911caf | 334 | |
sulymarco | 0:13be39911caf | 335 | void Application() |
sulymarco | 0:13be39911caf | 336 | { |
sulymarco | 0:13be39911caf | 337 | |
sulymarco | 0:13be39911caf | 338 | while(1) |
sulymarco | 0:13be39911caf | 339 | { |
sulymarco | 0:13be39911caf | 340 | event_flags.wait_any(APPLICATION_FLAG); // the application waits for the synchronization flag |
sulymarco | 0:13be39911caf | 341 | |
sulymarco | 0:13be39911caf | 342 | //Test_2 = 1; |
sulymarco | 0:13be39911caf | 343 | |
sulymarco | 0:13be39911caf | 344 | IO_data.lock(); // copy the Ethercat data to a safe buffer |
sulymarco | 0:13be39911caf | 345 | memcpy(&IOmapSafe[0], &IOmap[0], IO_MAP_SIZE); // |
sulymarco | 0:13be39911caf | 346 | // |
sulymarco | 0:13be39911caf | 347 | if (NetworkError) // |
sulymarco | 0:13be39911caf | 348 | { // |
sulymarco | 0:13be39911caf | 349 | NetworkErrorSafe = NetworkError; // |
sulymarco | 0:13be39911caf | 350 | WorkCounterSafe = WorkCounter; // |
sulymarco | 0:13be39911caf | 351 | } // |
sulymarco | 0:13be39911caf | 352 | IO_data.unlock(); // |
sulymarco | 0:13be39911caf | 353 | |
sulymarco | 0:13be39911caf | 354 | if (NetworkErrorSafe) |
sulymarco | 0:13be39911caf | 355 | { |
sulymarco | 0:13be39911caf | 356 | TFT.rect(35,50, 285, 182, Red); |
sulymarco | 0:13be39911caf | 357 | TFT.fillrect(36,51, 284, 181, Black); |
sulymarco | 0:13be39911caf | 358 | TFT.foreground(Red); |
sulymarco | 0:13be39911caf | 359 | TFT.set_font((unsigned char*) Arial28x28); |
sulymarco | 0:13be39911caf | 360 | TFT.locate(58, 65); |
sulymarco | 0:13be39911caf | 361 | TFT.printf("Network error!"); |
sulymarco | 0:13be39911caf | 362 | printf("Network error!\n"); |
sulymarco | 0:13be39911caf | 363 | TFT.foreground(Magenta); |
sulymarco | 0:13be39911caf | 364 | TFT.set_font((unsigned char*) Arial12x12); |
sulymarco | 0:13be39911caf | 365 | TFT.locate(58, 106); |
sulymarco | 0:13be39911caf | 366 | |
sulymarco | 0:13be39911caf | 367 | if(WorkCounterSafe >= 0) |
sulymarco | 0:13be39911caf | 368 | { |
sulymarco | 0:13be39911caf | 369 | TFT.printf("Expected working counter %d", ExpectWorkCounter); |
sulymarco | 0:13be39911caf | 370 | TFT.locate(58, 118); |
sulymarco | 0:13be39911caf | 371 | TFT.printf("Actual working counter %d", WorkCounterSafe); |
sulymarco | 0:13be39911caf | 372 | printf("Expected working counter %d\n", ExpectWorkCounter); |
sulymarco | 0:13be39911caf | 373 | printf("Actual working counter %d\n", WorkCounterSafe); |
sulymarco | 0:13be39911caf | 374 | } |
sulymarco | 0:13be39911caf | 375 | else |
sulymarco | 0:13be39911caf | 376 | { |
sulymarco | 0:13be39911caf | 377 | TFT.printf("Timeout"); |
sulymarco | 0:13be39911caf | 378 | printf("Timeout\n"); |
sulymarco | 0:13be39911caf | 379 | } |
sulymarco | 0:13be39911caf | 380 | |
sulymarco | 0:13be39911caf | 381 | TFT.foreground(Green); |
sulymarco | 0:13be39911caf | 382 | TFT.locate(58, 142); |
sulymarco | 0:13be39911caf | 383 | TFT.printf("Please fix the error and"); |
sulymarco | 0:13be39911caf | 384 | TFT.locate(58, 154); |
sulymarco | 0:13be39911caf | 385 | TFT.printf("press the reset button"); |
sulymarco | 0:13be39911caf | 386 | printf("Please fix the error and press the reset button \n"); |
sulymarco | 0:13be39911caf | 387 | |
sulymarco | 0:13be39911caf | 388 | SampleTicker.detach(); // stop the sample interrupt |
sulymarco | 0:13be39911caf | 389 | while(1){} // and loop for ever |
sulymarco | 0:13be39911caf | 390 | } |
sulymarco | 0:13be39911caf | 391 | |
sulymarco | 0:13be39911caf | 392 | |
sulymarco | 0:13be39911caf | 393 | //----- slave LAB_2_1 data management ------ |
sulymarco | 0:13be39911caf | 394 | // |
sulymarco | 0:13be39911caf | 395 | Buttons_1 = in_LAB_2_1->Buttons; // read the buttons status from the slave |
sulymarco | 0:13be39911caf | 396 | // |
sulymarco | 0:13be39911caf | 397 | if (Buttons_1 != PrevButtons_1) // check if the buttons value has changed |
sulymarco | 0:13be39911caf | 398 | { // |
sulymarco | 0:13be39911caf | 399 | PrevButtons_1 = Buttons_1; // remember the current buttons value |
sulymarco | 0:13be39911caf | 400 | DrawButtons_1_Value(Buttons_1); // draw the current buttons value on the TFT |
sulymarco | 0:13be39911caf | 401 | } // |
sulymarco | 0:13be39911caf | 402 | // |
sulymarco | 0:13be39911caf | 403 | out_LAB_2_1->Segments = Buttons_2; // send to the slave the buttons status |
sulymarco | 0:13be39911caf | 404 | // from the slave LAB_2_2 |
sulymarco | 0:13be39911caf | 405 | |
sulymarco | 0:13be39911caf | 406 | |
sulymarco | 0:13be39911caf | 407 | |
sulymarco | 0:13be39911caf | 408 | //----- slave 2_2 data management ---------- |
sulymarco | 0:13be39911caf | 409 | // |
sulymarco | 0:13be39911caf | 410 | Buttons_2 = in_LAB_2_2->Buttons; // read the buttons status from the slave |
sulymarco | 0:13be39911caf | 411 | // |
sulymarco | 0:13be39911caf | 412 | if (Buttons_2 != PrevButtons_2) // check if the buttons value has changed |
sulymarco | 0:13be39911caf | 413 | { // |
sulymarco | 0:13be39911caf | 414 | PrevButtons_2 = Buttons_2; // remember the current buttons value |
sulymarco | 0:13be39911caf | 415 | DrawButtons_2_Value(Buttons_2); // draw the current buttons value on the TFT |
sulymarco | 0:13be39911caf | 416 | } // |
sulymarco | 0:13be39911caf | 417 | // |
sulymarco | 0:13be39911caf | 418 | out_LAB_2_2->Segments = Buttons_1; // send to the slave the buttons status |
sulymarco | 0:13be39911caf | 419 | // from the slave LAB_2_1 |
sulymarco | 0:13be39911caf | 420 | |
sulymarco | 0:13be39911caf | 421 | |
sulymarco | 0:13be39911caf | 422 | |
sulymarco | 0:13be39911caf | 423 | IO_data.lock(); // copy the IO data from the safe area |
sulymarco | 0:13be39911caf | 424 | memcpy(&IOmap[0], &IOmapSafe[0], IO_MAP_SIZE); // to the EtherCAT buffer |
sulymarco | 0:13be39911caf | 425 | IO_data.unlock(); // |
sulymarco | 0:13be39911caf | 426 | |
sulymarco | 0:13be39911caf | 427 | //Test_2 = 0; |
sulymarco | 0:13be39911caf | 428 | } |
sulymarco | 0:13be39911caf | 429 | } |
sulymarco | 0:13be39911caf | 430 | |
sulymarco | 0:13be39911caf | 431 | |
sulymarco | 0:13be39911caf | 432 | //****************************************************************************** |
sulymarco | 0:13be39911caf | 433 | |
sulymarco | 0:13be39911caf | 434 | |
sulymarco | 0:13be39911caf | 435 | |
sulymarco | 0:13be39911caf | 436 | //******* general functions **************************************************** |
sulymarco | 0:13be39911caf | 437 | |
sulymarco | 0:13be39911caf | 438 | |
sulymarco | 0:13be39911caf | 439 | |
sulymarco | 0:13be39911caf | 440 | //----- draw the fixed part of the slaves visualization ------------------------ |
sulymarco | 0:13be39911caf | 441 | |
sulymarco | 0:13be39911caf | 442 | void DrawSlaveFixedParts() |
sulymarco | 0:13be39911caf | 443 | { |
sulymarco | 0:13be39911caf | 444 | int i; |
sulymarco | 0:13be39911caf | 445 | |
sulymarco | 0:13be39911caf | 446 | TFT.cls(); // clear screen |
sulymarco | 0:13be39911caf | 447 | TFT.line(0, 120, 340, 120, Green); // draw the separation line |
sulymarco | 0:13be39911caf | 448 | |
sulymarco | 0:13be39911caf | 449 | for (i=0; i<3; i++) // draw the buttons fixed parts |
sulymarco | 0:13be39911caf | 450 | { // for the LAB_2_1 slave |
sulymarco | 0:13be39911caf | 451 | TFT.circle(BUTTONS_1_X+(i*BUTTONS_1_STEP), BUTTONS_1_Y, BUTTONS_1_R, Red); |
sulymarco | 0:13be39911caf | 452 | TFT.circle(BUTTONS_1_X+BUTTONS_1_WIDTH+(i*BUTTONS_1_STEP), BUTTONS_1_Y, BUTTONS_1_R, Red); |
sulymarco | 0:13be39911caf | 453 | // |
sulymarco | 0:13be39911caf | 454 | TFT.line(BUTTONS_1_X+(i*BUTTONS_1_STEP)-BUTTONS_1_R, BUTTONS_1_Y, BUTTONS_1_X+(i*BUTTONS_1_STEP)-BUTTONS_1_R-4, BUTTONS_1_Y, Red); |
sulymarco | 0:13be39911caf | 455 | TFT.line(BUTTONS_1_X+BUTTONS_1_WIDTH+(i*BUTTONS_1_STEP)+BUTTONS_1_R, BUTTONS_1_Y, BUTTONS_1_X+BUTTONS_1_WIDTH+(i*BUTTONS_1_STEP)+BUTTONS_1_R+4 , BUTTONS_1_Y, Red); |
sulymarco | 0:13be39911caf | 456 | } // |
sulymarco | 0:13be39911caf | 457 | // |
sulymarco | 0:13be39911caf | 458 | TFT.set_font((unsigned char*) Arial12x12); // |
sulymarco | 0:13be39911caf | 459 | TFT.locate(BUTTONS_1_X+12, BUTTONS_1_Y+20); // |
sulymarco | 0:13be39911caf | 460 | TFT.printf("LAB_2_1 Buttons"); // |
sulymarco | 0:13be39911caf | 461 | |
sulymarco | 0:13be39911caf | 462 | for (i=0; i<3; i++) // draw the buttons fixed parts |
sulymarco | 0:13be39911caf | 463 | { // for the LAB_2_2 slave |
sulymarco | 0:13be39911caf | 464 | TFT.circle(BUTTONS_2_X+(i*BUTTONS_2_STEP), BUTTONS_2_Y, BUTTONS_2_R, Red); |
sulymarco | 0:13be39911caf | 465 | TFT.circle(BUTTONS_2_X+BUTTONS_2_WIDTH+(i*BUTTONS_2_STEP), BUTTONS_2_Y, BUTTONS_2_R, Red); |
sulymarco | 0:13be39911caf | 466 | // |
sulymarco | 0:13be39911caf | 467 | TFT.line(BUTTONS_2_X+(i*BUTTONS_2_STEP)-BUTTONS_2_R, BUTTONS_2_Y, BUTTONS_2_X+(i*BUTTONS_2_STEP)-BUTTONS_2_R-4, BUTTONS_2_Y, Red); |
sulymarco | 0:13be39911caf | 468 | TFT.line(BUTTONS_2_X+BUTTONS_2_WIDTH+(i*BUTTONS_2_STEP)+BUTTONS_2_R, BUTTONS_2_Y, BUTTONS_2_X+BUTTONS_2_WIDTH+(i*BUTTONS_2_STEP)+BUTTONS_2_R+4 , BUTTONS_2_Y, Red); |
sulymarco | 0:13be39911caf | 469 | } // |
sulymarco | 0:13be39911caf | 470 | // |
sulymarco | 0:13be39911caf | 471 | TFT.set_font((unsigned char*) Arial12x12); // |
sulymarco | 0:13be39911caf | 472 | TFT.locate(BUTTONS_2_X+12, BUTTONS_2_Y+20); // |
sulymarco | 0:13be39911caf | 473 | TFT.printf("LAB_2_2 Buttons"); // |
sulymarco | 0:13be39911caf | 474 | |
sulymarco | 0:13be39911caf | 475 | DrawButtons_1_Value (Buttons_1); // draw the buttons status |
sulymarco | 0:13be39911caf | 476 | DrawButtons_2_Value (Buttons_2); // |
sulymarco | 0:13be39911caf | 477 | |
sulymarco | 0:13be39911caf | 478 | FirstRound = true; |
sulymarco | 0:13be39911caf | 479 | } |
sulymarco | 0:13be39911caf | 480 | |
sulymarco | 0:13be39911caf | 481 | |
sulymarco | 0:13be39911caf | 482 | //---- draw the starting banner ------------------------------------------------ |
sulymarco | 0:13be39911caf | 483 | |
sulymarco | 0:13be39911caf | 484 | void DrawBanner() |
sulymarco | 0:13be39911caf | 485 | { |
sulymarco | 0:13be39911caf | 486 | TFT.set_font((unsigned char*) Arial24x23); |
sulymarco | 0:13be39911caf | 487 | TFT.foreground(Red); |
sulymarco | 0:13be39911caf | 488 | TFT.locate(30, 30); |
sulymarco | 0:13be39911caf | 489 | TFT.printf("EasyCAT"); |
sulymarco | 0:13be39911caf | 490 | TFT.locate(30, 60); |
sulymarco | 0:13be39911caf | 491 | TFT.printf("SOEM MASTER"); |
sulymarco | 0:13be39911caf | 492 | |
sulymarco | 0:13be39911caf | 493 | TFT.foreground(Magenta); |
sulymarco | 0:13be39911caf | 494 | TFT.locate(30, 100); |
sulymarco | 0:13be39911caf | 495 | TFT.printf("simple example"); |
sulymarco | 0:13be39911caf | 496 | |
sulymarco | 0:13be39911caf | 497 | TFT.set_font((unsigned char*) Arial12x12); |
sulymarco | 0:13be39911caf | 498 | TFT.foreground(Green); |
sulymarco | 0:13be39911caf | 499 | TFT.locate(30, 150); |
sulymarco | 0:13be39911caf | 500 | TFT.printf("www.bausano.net"); |
sulymarco | 0:13be39911caf | 501 | |
sulymarco | 0:13be39911caf | 502 | TFT.foreground(Green); |
sulymarco | 0:13be39911caf | 503 | TFT.locate(30, 170); |
sulymarco | 0:13be39911caf | 504 | TFT.printf("www.easycatshield.com"); |
sulymarco | 0:13be39911caf | 505 | |
sulymarco | 0:13be39911caf | 506 | TFT.locate(30, 190); |
sulymarco | 2:a0e017115fc5 | 507 | TFT.printf("https://openethercatsociety.github.io/"); |
sulymarco | 2:a0e017115fc5 | 508 | |
sulymarco | 2:a0e017115fc5 | 509 | TFT.foreground(Red); |
sulymarco | 2:a0e017115fc5 | 510 | TFT.locate(30, 220); |
sulymarco | 2:a0e017115fc5 | 511 | #if defined ADA_TFT |
sulymarco | 2:a0e017115fc5 | 512 | TFT.printf("Adafruit TFT"); |
sulymarco | 2:a0e017115fc5 | 513 | #else |
sulymarco | 2:a0e017115fc5 | 514 | TFT.printf("Seeed Studio TFT"); |
sulymarco | 2:a0e017115fc5 | 515 | #endif |
sulymarco | 0:13be39911caf | 516 | } |
sulymarco | 0:13be39911caf | 517 | |
sulymarco | 0:13be39911caf | 518 | |
sulymarco | 0:13be39911caf | 519 | //---- slaves data visualization functions ------------------------------------- |
sulymarco | 0:13be39911caf | 520 | |
sulymarco | 0:13be39911caf | 521 | void DrawButtons_1_Value (uint8_t Value) // visualize on the TFT the |
sulymarco | 0:13be39911caf | 522 | { // slave LAB_2_1 buttons status |
sulymarco | 0:13be39911caf | 523 | uint8_t Slope; |
sulymarco | 0:13be39911caf | 524 | int i; |
sulymarco | 0:13be39911caf | 525 | |
sulymarco | 0:13be39911caf | 526 | for (i=0; i<3; i++) |
sulymarco | 0:13be39911caf | 527 | { |
sulymarco | 0:13be39911caf | 528 | if ((Value & 0x04) == 0x04) |
sulymarco | 0:13be39911caf | 529 | Slope = BUTTONS_1_R; |
sulymarco | 0:13be39911caf | 530 | else |
sulymarco | 0:13be39911caf | 531 | Slope = 16; |
sulymarco | 0:13be39911caf | 532 | |
sulymarco | 0:13be39911caf | 533 | TFT.fillrect(BUTTONS_1_X+(i*BUTTONS_1_STEP), BUTTONS_1_Y-16-1, BUTTONS_1_X+BUTTONS_1_WIDTH+(i*BUTTONS_1_STEP), BUTTONS_1_Y-BUTTONS_1_R-1, Black); |
sulymarco | 0:13be39911caf | 534 | |
sulymarco | 0:13be39911caf | 535 | TFT.line(BUTTONS_1_X+(i*BUTTONS_1_STEP), BUTTONS_1_Y-BUTTONS_1_R-1, BUTTONS_1_X+BUTTONS_1_WIDTH+(i*BUTTONS_1_STEP), BUTTONS_1_Y-Slope-1, Red); |
sulymarco | 0:13be39911caf | 536 | |
sulymarco | 0:13be39911caf | 537 | Value = Value << 1; |
sulymarco | 0:13be39911caf | 538 | } |
sulymarco | 0:13be39911caf | 539 | } |
sulymarco | 0:13be39911caf | 540 | |
sulymarco | 0:13be39911caf | 541 | |
sulymarco | 0:13be39911caf | 542 | void DrawButtons_2_Value (uint8_t Value) // visualize on the TFT the |
sulymarco | 0:13be39911caf | 543 | { // slave LAB_2_2 buttons status |
sulymarco | 0:13be39911caf | 544 | uint8_t Slope; |
sulymarco | 0:13be39911caf | 545 | int i; |
sulymarco | 0:13be39911caf | 546 | |
sulymarco | 0:13be39911caf | 547 | for (i=0; i<3; i++) |
sulymarco | 0:13be39911caf | 548 | { |
sulymarco | 0:13be39911caf | 549 | if ((Value & 0x04) == 0x04) |
sulymarco | 0:13be39911caf | 550 | Slope = BUTTONS_1_R; |
sulymarco | 0:13be39911caf | 551 | else |
sulymarco | 0:13be39911caf | 552 | Slope = 16; |
sulymarco | 0:13be39911caf | 553 | |
sulymarco | 0:13be39911caf | 554 | TFT.fillrect(BUTTONS_2_X+(i*BUTTONS_2_STEP), BUTTONS_2_Y-16-1, BUTTONS_2_X+BUTTONS_2_WIDTH+(i*BUTTONS_2_STEP), BUTTONS_2_Y-BUTTONS_2_R-1, Black); |
sulymarco | 0:13be39911caf | 555 | |
sulymarco | 0:13be39911caf | 556 | TFT.line(BUTTONS_2_X+(i*BUTTONS_2_STEP), BUTTONS_2_Y-BUTTONS_2_R-1, BUTTONS_2_X+BUTTONS_2_WIDTH+(i*BUTTONS_2_STEP), BUTTONS_2_Y-Slope-1, Red); |
sulymarco | 0:13be39911caf | 557 | |
sulymarco | 0:13be39911caf | 558 | Value = Value << 1; |
sulymarco | 0:13be39911caf | 559 | } |
sulymarco | 0:13be39911caf | 560 | } |
sulymarco | 0:13be39911caf | 561 |