Esmacat
Published © GPL3+

EtherCAT Arduino Shield by Esmacat with LCD Shield Tutorial

Use an EtherCAT master to communicate with an EtherCAT Arduino Shield by Esmacat(EASE) on an Arduino to print button values on an LCD Shield

IntermediateProtip2 hours2,555

Things used in this project

Hardware components

Esmacat Master S
(Optional Esmacat Master)
×1
Esmacat Master C
(Optional Esmacat Master)
×1
Arduino UNO
Arduino UNO
×1
EtherCAT Arduino Shield by Esmacat (EASE)
×1
16x2 LCD Shield
×1
Power over Ethernet Injector
×1
Ethernet Cable, Cat6a
Ethernet Cable, Cat6a
×2
DC Adapter
To supply power to the Power over Ethernet Injector.
×1

Software apps and online services

Arduino IDE
Arduino IDE
Visual Studio 2017
Microsoft Visual Studio 2017
(Optional) IDE for building C++ Applications in Windows.
QT Creator
(Optional) IDE for building C++ Applications in Linux.

Story

Read more

Schematics

Hardware Setup Schematic

Schematic of the connection used in the tutorial

Physical Hardware Connection schematic

Hardware setup after final connections.

Code

Arduino with EASE and LCD Shield Code

Arduino
Code to be uploaded to the Arduino Uno Board.
/*
  Liquid Crystal & Esmacat Arduino Library - Printing User Input

  This sketch does the following:
  1) Prints the User input from the Serial Monitor on to 
     LCD Screen
  2) Prints the button pressed on the LCD Shield onto the
     Serial monitor on the Arduino IDE
  using EASE (EtherCAT Arduino Shield by Esmacat).

  created 15 Dec 2019
  by Harmonic Bionics Inc. (https://www.harmonicbionics.com/).
     
  
 */


/*
    PIN CONFIGURATION
    |-----------------------------------------|
    |  LCD PIN Number  |   Arduino PIN Number |
    |-----------------------------------------|
    |       RS         |      Digital Pin 8   |
    |     ENABLE       |      Digital Pin 9   |
    |       D4         |      Digital Pin 4   |
    |       D5         |      Digital Pin 5   |
    |       D6         |      Digital Pin 6   |
    |       D7         |      Digital Pin 7   |
    |     Buttons      |      Analog Pin A0   |
    |-----------------------------------------|
    
 */

/*
  Analog Input Values for the Push Buttons
  |------------------------------------------------|
  |    Push Button     |          A0 value         |
  |------------------------------------------------|
  |       SELECT       |   val >= 500 & val <= 750 |
  |        LEFT        |   val >= 300 & val < 500  |
  |         UP         |   val >= 50  & val < 150  |
  |        DOWN        |   val >= 150 & val < 300  |
  |        RIGHT       |   val >= 0   & val < 50   |
  |------------------------------------------------|
*/

#include <LiquidCrystal.h>      // Include LCD Arduino Library
#include <Esmacatshield.h>      //Include the Esmacat Arduino Library

#define ARDUINO_UNO_SLAVE_SELECT 10      // The chip selector pin for Arduino Uno is 10 

LiquidCrystal lcd_display(8, 9, 4, 5, 6, 7);      // Create an object for the Library class
Esmacatshield ease_1(ARDUINO_UNO_SLAVE_SELECT);      // Create a slave object and specify the Chip Selector Pin
                                

int ease_registers[8];      // EASE 8 registers

int analog_value;      // Initialise analog input value variable
String data;      // Initialize the data variable
int button_pressed;      // Encoded value for the buttons

/*
    -------------------------------------------
    |    Button on LCD     |    Encoded Value  |
    -------------------------------------------
    |         Left         |          1        |
    |          Up          |          2        |
    |         Down         |          3        |
    |         Right        |          4        |
    |        Select        |          5        |
    --------------------------------------------
 */

void setup() {
  
  lcd_display.begin(16,2);      //Initialise the number of (coloumns, rows) in the LCD
  
  lcd_display.print("Hello World ...");      // Print a message onto the LCD Display

  ease_1.start_spi();      // Start SPI for EASE
  
  Serial.begin(9600);      // Initialise the Serial Communication with the specified Baud Rate
}

void loop() {

  // Code to print the button pressed on the LCD to the Serial Monitor
  analog_value = analogRead(A0);
  
  if (analog_value <= 750)      //To check if a button has been pressed
  {
    ease_1.write_reg_value(0,analog_value);      //Write register data (register,value, led_on)
    Serial.println(analog_value);
  }
  
  ease_1.get_ecat_registers(ease_registers);
  button_pressed = ease_registers[1];      // Receive the encode the value for register 
  
  
  if (button_pressed == 1)
  {
    lcd_display.setCursor(0,1);      // set the LCD cursor position (Coloumn number,Row number)
    lcd_display.print("L"); 
    Serial.print(ease_registers[2]);
    Serial.println("\t Left Button Pressed");
  }
  
  if (button_pressed == 2)
  {
    lcd_display.setCursor(0,1);
    lcd_display.print("U"); 
    Serial.print(ease_registers[2]);
    Serial.println("\t Up Button Pressed");
  }

  if (button_pressed == 3)
  {
    lcd_display.setCursor(0,1);
    lcd_display.print("D"); 
    Serial.print(ease_registers[2]);
    Serial.println("\t Down Button Pressed");
  }
  
  if (button_pressed == 4)
  {
    lcd_display.setCursor(0,1);      
    lcd_display.print("R");
    Serial.print(ease_registers[2]); 
    Serial.println("\t Right Button Pressed");
  }

  if (button_pressed == 5)
  {
    lcd_display.setCursor(0,1);
    lcd_display.print("S"); 
    Serial.print(ease_registers[2]);
    Serial.println("\t Select Button Pressed");
  }
}

ease_with_lcd/main.cpp

C/C++
Software to be run on the EtherCAT Master, main.cpp file
/** @file
 *  @brief This file contains the template for the main program for the Esmacat slave
 *  project */
/*****************************************************************************************
 * INCLUDES
 ****************************************************************************************/
#include <iostream>
#include "my_app.h"

/*****************************************************************************************
 * FUNCTIONS
 ****************************************************************************************/
/**
 * @brief Initializes the execution of the Ethercat communication and
 *        primary real-time loop for your application for the desired
 *        slave
 * @return
 */

int main()
{
    //this is defined in my_app.cpp and my_app.h
    my_app app;

    // if you already know the ethernet adapter name for EtherCAT, uncomment and use the line below
    //    app.set_ethercat_adapter_name(" WRITE YOUR ETHERNET ADAPTER NAME");

    // If the name is not known, select through the terminal an ethernet adapter (the slave)
    // you'd like to communicate with over EtherCAT
    app.set_ethercat_adapter_name_through_terminal();

    // start the esmacat application customized for your slave
    app.start();

    //the application runs as long as the esmacat master and slave are in communication
    while (app.is_esmacat_master_closed() == FALSE );
    return 0;
}

ease_with_lcd/my_app.h

C/C++
Header files for the applications class
/** @file
 * @brief This file contains the declaration of the class associated with the user-defined
 * application for the Esmacat slave project */

#ifndef MY_APP_H
#define MY_APP_H

/*****************************************************************************************
 * INCLUDES
 ****************************************************************************************/
#include <iostream>
#include "application.h"
//Include the header file for the Esmacat slave you plan to use for e.g. Analog Input slave
//#include "esmacat_analog_input.h"
#include "ethercat_arduino_shield_by_esmacat.h"
using namespace std;


/*****************************************************************************************
 * CLASSES
 ****************************************************************************************/
/**
 * @brief Description of your custom application class
 *
 * Your custom application class my_app inherits the class 'esmacat_application'
 * Write functions to override the parent functions of 'esmacat_application'
 * Declare an object of your slave class (e.g. ecat_ai)
 * Declare any other variables you might want to add
 * Define the constructor for initialization
 */
class my_app : public esmacat_application
{
private:
    void assign_slave_sequence(); /** identify sequence of slaves and their types*/
    void configure_slaves(); /** setup the slave*/
    void init(); /** code to be executed in the first iteration of the loop */
    void loop(); /** control loop*/

    esmacat_ethercat_arduino_shield_by_esmacat ease_1;  /** < create a Esmacat slave object for the EASE shield */
    uint32_t lcd_analog_input_value;
//    uint32_t prev_analog_value;
public:
    /** A constructor- sets initial values for class members */
    my_app()
    {
        // lcd_analog_input_value = 1023;   // Initialize the variable to some random value
    }
};

#endif // MY_APP_H

ease_with_lcd/my_app.cpp

C/C++
Source Code of the appliction class
/** @file
 * @brief This file contains the definition of the functions associated with the user-defined
 * application for the Esmacat slave project */
 /*****************************************************************************************
 * INCLUDES
 ****************************************************************************************/
#include "my_app.h"

/*****************************************************************************************
 * FUNCTIONS
 ****************************************************************************************/
/**
 * @brief Identifies the actual Esmacat slave sequence in the EtherCAT communication chain.
 */
void my_app::assign_slave_sequence(){
    // tell the master what type of slave is at which point in the chain
    assign_esmacat_slave_index(&ease_1, 0);  //<-- The arduino is connected in number 0
}

/**
 * @brief Configure your Esmacat slave.
 * Link Esmacat slave object with the actual Esmacat slave in the EtherCAT communication chain.
 * Functions beginning with 'configure_slave' must only be executed in this function
 */
void my_app::configure_slaves(){


    // add initialization code here
    // Functions starting with "configure_slave" work only in configure_slaves() function
}

/** @brief Initialization that needs to happen on the first iteration of the loop
 */
void my_app::init()
{ 
    // prev_analog_value = 1023;
}

/**
 * @brief Executes functions at the defined loop rate
 */
void my_app::loop(){
    // add functions below that are to be executed at the loop rate
    lcd_analog_input_value = ease_1.get_input_variable_0_IN_GEN_INT0();

    cout << lcd_analog_input_value << "\t";
    // Determine the button pressed based on the analog value received
    if (lcd_analog_input_value >= 0 && lcd_analog_input_value <= 50)
    {
        ease_1.set_output_variable_1_OUT_GEN_INT1(4);  // <-- Write the corresponding encoding for right
        cout << "Right Button Pressed" << endl;   // <-- Printing message onto the terminal
        ease_1.set_output_variable_2_OUT_GEN_INT2(lcd_analog_input_value);   //<-- Send the anlog value back to arduino to print in the Serial Monitor
    }
    if (lcd_analog_input_value >= 50 && lcd_analog_input_value <= 150)
    {
        ease_1.set_output_variable_1_OUT_GEN_INT1(2);  // <-- Write the corresponding encoding for up
        cout << "Up Button Pressed" << endl;
        ease_1.set_output_variable_2_OUT_GEN_INT2(lcd_analog_input_value);
    }
    if (lcd_analog_input_value >= 150 && lcd_analog_input_value <= 300)
    {
        ease_1.set_output_variable_1_OUT_GEN_INT1(3);  // <-- Write the corresponding encoding for down
        cout << "Down Button Pressed" << endl;
        ease_1.set_output_variable_2_OUT_GEN_INT2(lcd_analog_input_value);
    }
    if (lcd_analog_input_value >= 300 && lcd_analog_input_value <= 500)
    {
        ease_1.set_output_variable_1_OUT_GEN_INT1(1);  // <-- Write the corresponding encoding for left
        cout << "Left Button Pressed" << endl;
        ease_1.set_output_variable_2_OUT_GEN_INT2(lcd_analog_input_value);
    }
    if (lcd_analog_input_value >= 500 && lcd_analog_input_value <= 750)
    {
        ease_1.set_output_variable_1_OUT_GEN_INT1(5);  // <-- Write the corresponding encoding for Select
        cout << "Select Button Pressed" << endl;
        ease_1.set_output_variable_2_OUT_GEN_INT2(lcd_analog_input_value);
    }
}

ease_with_lcd/CMakeLists.txt

Plain text
CMake Lists file of the project
file(GLOB MY_PROJECT_HEADERS *.h)
file(GLOB MY_PROJECT_SOURCES *.cpp *.c)

add_executable(ease_with_lcd ${MY_PROJECT_SOURCES} ${MY_PROJECT_HEADERS})

target_link_libraries(ease_with_lcd ethercat_driver esmacat)

install(TARGETS ease_with_lcd DESTINATION ./bin)

Esmacat Master Software

Helper software code to be used on the Esmacat master. (Contains the header files and source codes for EtherCAT communication).

EtherCAT Arduino Shield by Esmacat (EASE) Arduino Library

Library file to be included in the Arduino IDE.

Credits

Esmacat

Esmacat

11 projects • 16 followers
Esmacat is an easy yet powerful EtherCAT solution for robotics. Our EtherCAT tech allow users to run EtherCAT applications in minutes!

Comments