Get hands-on with making your own Human-Machine Interface (HMI) using the powerful Arduino GIGA R1 WiFi, its interactive touchscreen display, and the Arduino Opta. HMIs bridge the gap between you and your project, giving you intuitive control, real-time data visualization, and efficient operation.
Imagine designing custom interfaces that respond instantly to your touch, displaying clear visuals and data to help you make informed decisions. The GIGA's processing power ensures smooth performance, while the Opta automates tasks based on your input or sensor readings.
Ready to dive in? Let's explore the key features of theArduino components:
- Arduino GIGAR1 WiFi: This powerhouse microcontroller handles complex calculations and graphics with ease. Connect diverse sensors and devices with its numerous ports, and enjoy ample memory for your project needs.
- Arduino GIGA DisplayShield: Design user-friendly interfaces with a vibrant touchscreen and built-in libraries. Swipe, tap, and interact with your project effortlessly.
- Arduino Opta: Program automation logic easily with ladder logic, even if you're new to it. The PLC reliably controls your project based on user input or sensor data.
By combining these components, you'll create an HMI that empowers you to interact with your project like never before.
Getting Started with Your Own Interface!With the LVGL library, programming the Arduino GIGA Display Shield is easy. Decide how many buttons you want, and whether you want a bar to display data like temperature or humidity, the possibilities are endless!
Step by step:
Next, we will guide you through the steps to create your interface:
In this example, two buttons are used to operate two relays by sending a signal to the Arduino Opta. Two LED indicators are also added, and they will illuminate when two external buttons are pressed.
Additionally, a temperature-indicating bar was set up, utilizing an LM35 sensor to provide the data.
The Arduino H7 Video library, which manages the display, is part of the GIGA Board Package.
we will be using three different libraries:
- Arduino_H7_Video, this one is bundled with the Board Package, so make sure you have the latest version of the GIGA Board Package installed.
- Arduino_GigaDisplayTouch
- lvgl
To install them, open the library manager and install the latest version by searching for "Arduino_GigaDisplayTouch" and "lvgl".
In the sketch include the libraries like this:
#include "Arduino_H7_Video.h"
#include "lvgl.h"
#include "Arduino_GigaDisplayTouch.h"
The first thing we need to do is to define the display we are using, by creating an object using the Arduino_H7_Video class, specifying the height, width, and type of display.
Arduino_H7_Video Display(800, 480, GigaDisplayShield); //Display type and dimensions
Also, to be able to use the touch capability of the screen we need to create an object using the Arduino_GigaDisplayTouch class
Arduino_GigaDisplayTouch TouchDetector;
In the setup(), we begin by initializing the display and the touch detector.
void setup(){
Display.begin();
TouchDetector.begin();
}
With these things set up, we can go on to configure the LVGL elements.
Creating a Grid LayoutCreating a grid that you can then fill with elements will consist of a defined column and row.
- This will create two columns with 370 px width and 350 px.
col_dsc[] = {370, 350, LV_GRID_TEMPLATE_LAST};
- Every row will have 440 pixels.
row_dsc[] = {440, LV_GRID_TEMPLATE_LAST};
Then we need to create a pointer for the screen space.
Here it will be called the grid.
lv_obj_t * grid = lv_obj_create(lv_scr_act());
To set the grid description that we defined before use:
lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
Now that the columns and rows have been defined the overall screen needs to be taken into account. This is achieved by using lv_obj_set_size(grid, Display.width(), Display.height()) to make it easy we will allow the grid to use the entire screen.
lv_obj_set_size(grid, Display.width(), Display.height());
Then, just to test it out, let's add an object to the grid: first declare the obj pointer and add it to the grid, then we set the grid cell via the lv_obj_set_grid_cell() method.
lv_obj_t* obj;
obj = lv_obj_create(grid);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1, //column
LV_GRID_ALIGN_STRETCH, 0, 1); //row
The lv_obj_set_grid_cell()) has a set of parameters related to how the object is positioned and aligned. In this case, we have created a 2x1 grid, where the 0 (column) and 0 (row) indicate where on the grid it should go.
#include "Arduino_H7_Video.h"
#include "lvgl.h"
#include "Arduino_GigaDisplayTouch.h"
Arduino_H7_Video Display(800, 480, GigaDisplayShield);
Arduino_GigaDisplayTouch TouchDetector;
void setup() {
Display.begin();
TouchDetector.begin();
//Display & Grid Setup
lv_obj_t* screen = lv_obj_create(lv_scr_act());
lv_obj_set_size(screen, Display.width(), Display.height());
static lv_coord_t col_dsc[] = { 370, 350, LV_GRID_TEMPLATE_LAST };
static lv_coord_t row_dsc[] = { 440, LV_GRID_TEMPLATE_LAST };
lv_obj_t* grid = lv_obj_create(lv_scr_act());
lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
lv_obj_set_size(grid, Display.width(), Display.height());
//left
lv_obj_t* obj;
obj = lv_obj_create(grid);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1, //column
LV_GRID_ALIGN_STRETCH, 0, 1); //row
//right
obj = lv_obj_create(grid);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 1, 1, //column
LV_GRID_ALIGN_STRETCH, 0, 1); //row
}
void loop() {
lv_timer_handler();
}
Now that we have the grid we can start adding objects that we want.
To display an image on the screen we first need to define it. Take the desired image, convert it into the correct format, and place the image in the same folder as the sketch. Now use LV_IMG_DECLARE(filename); For example, the image we use will be named img_arduinologo.
LV_IMG_DECLARE(img_arduinologo);
obj is a pointer that will be used to hold the information about the screen space information for the image. The img1 is used for the elements of the image itself.
lv_obj_t * obj;
lv_obj_t * img1;
With lv_obj_set_size we can define the resolution of the image
LV_IMG_DECLARE(img_arduinologo);
img1 = lv_img_create(obj_cb);
lv_img_set_src(img1, &img_arduinologo);
lv_obj_set_size(img1, 200, 150);
Now that we have the image, it is time to add buttons and LED indicators to the side we want on our screen.
To create the buttons object uselv_btn_create
(obj) and assign it to a suitable variable, here we use the button pointer. Next set the text that will appear next to the button by using lv_label_set_text
(label_LR1
, "Led/Relay1");, here Led/Relay1 will be printed in the button.
We can also set the resolution, in pixels.
cb_LR1 = lv_btn_create(obj_cb); // Create the button and store its object: button
lv_obj_set_size(cb_LR1, 100, 40);
label_LR1 = lv_label_create(cb_LR1);
lv_label_set_text(label_LR1, "Led/Relay1");
To create the LED indicator is very similar to the button, lv_led_create(obj_cb)
The status of the LED can be defined with the lv_led_off or lv_led_on function.
obj_led1 = lv_led_create(obj_cb);
lv_led_off(obj_led1);
The last element to add to the screen in this example would be a bar.
The bar can be created with:
slider = lv_bar_create(obj_slide);
Set the desired size of the bar with lv_obj_set_size.
slider = lv_bar_create(obj_slide);
lv_obj_set_size(slider, 310, 20); // Set the width
lv_obj_align(slider, LV_ALIGN_CENTER, 0, 0);
With lv_obj_align, we can align the object wherever we want, in this example was aligned to coordinates 0, 0, so it would be in the center of the second grid.
Thanks to an LM35 connected to the Arduino Opta, we can obtain the ambient temperature and display it in the bar.
Now that we have all the elements to display on our screen, it is time to connect the Arduino Opta.
We will use WiFi Modbus TCP to Send Data from an Arduino Opta to the Arduino GIGA.
First, we need to set up a WiFi Modbus TCP server on an Arduino Opta, allowing it to send data (LED and input status) to the Arduino GIGA. This communication happens wirelessly through your local network.
(Please see the code in the files attached to this project, Opta_Server)
- Download and install theArduinoModbuslibrary in your Arduino IDE.
- Create a new file named
arduino_secrets.h
in your project folder. This file will store your WiFi credentials (SSID and password) securely. This code uses the provided SSID and password to establish a stable internet connection.
The code acts as a translator between the physical world (sensors, LEDs, relays) and the Modbus TCP network protocol.
It receives commands from the Arduino GIGA, controls the connected hardware accordingly, and sends back information about the inputs and analog readings.
The updateOuts function reads coil values from the Modbus client and uses them to turn on/off the connected LEDs and relays.
The updateWInputs function reads the states of digital input pins and writes their values to specific Modbus coils, sending this information to the GIGA.
The updateWInputs function also reads the voltage from the analog input pin, converts it to a digital value, and writes it to a Modbus register, allowing the GIGA to access this data.
Once we have the Opta code, it is time to make the Arduino GIGA able to send and receive information to the Opta through Modbus TCP.
(Please see the files attached to this project to see the code. HMI_Client)
Establish a connection to the Modbus TCP server running on the Arduino Opta (IP address specified in Opta_server
).
In the main loop, we need to ensure that the Modbus TCP client is connected.
// client not connected
if (!modbusTCPClient.connected()) {
//Serial.println("Modbus TCP Client failed to connect! Restart HMI");
}
else {
// client connected
InWidgets();
//OutButtons();
}
If connected, we will read coil values from the Arduino Opta, turn on/off corresponding LEDs, read the analog input register value from the Opta, convert it to temperature, update the slider position, and display the value on the GIGA display.
Also, when a button is pressed/released, it sends a coil write command to the Opta to turn on/off the corresponding LED/relay.
void InWidgets (){
int voltFOpta;
float TempScreen;
char voltageStr[20];
/* Reading coils to update the LEDs on HMI */
if (modbusTCPClient.coilRead(0x02)){
lv_led_on(obj_led1);
}
else
{
lv_led_off(obj_led1);
}
if (modbusTCPClient.coilRead(0x03)){
lv_led_on(obj_led2);
}
else
{
lv_led_off(obj_led2);
}
/* Reading the input register to update the Temperature, analog in */
voltFOpta = modbusTCPClient.inputRegisterRead(0x04);
TempScreen = voltFOpta * (100.0/4095); //Analog input 0 - 10 volts; 12 bit resolution, 0 - 4095; 10mV/°C.
lv_bar_set_value(slider, TempScreen, LV_ANIM_OFF);
sprintf(voltageStr, "%.0f", TempScreen, "°C");
lv_label_set_text(label1, voltageStr);
}
Unlock the Power of Intuitive Control with your Custom HMI
Congratulations on building your own Human-Machine Interface using the powerful Arduino GIGA, the Arduino GIGA Display Shield interactive touchscreen, and the Arduino Opta! Through this project, you've gained valuable experience in combining hardware, software, and design to create a tool that empowers you to interact with your project like never before.
Remember, your HMI is not just a collection of buttons and displays; it's a gateway to seamless control and a deeper understanding of your project. With the flexibility of the Arduino GIGA and the LVGL library, you have the potential to:
- Continuously refine your interface: Add more complex elements, incorporate feedback mechanisms, and tailor the design to your specific needs.
- Expand your project's capabilities: Integrate new sensors and actuators, enabling your HMI to control a wider range of functions.
- Share your creation: Showcase your unique HMI design and inspire others to explore the possibilities of interactive projects.
As you continue your journey in the world of HMIs, remember that the possibilities are truly endless. Embrace the power of customization, unleash your creativity, and unlock the full potential of your project with your one-of-a-kind Human-Machine Interface!
Comments
Please log in or sign up to comment.