Interface STONE HMI Display with Arduino
In this tutorial we will see how to interface the Stone HMI Display with ARDUINO. We will control a LED connected to the Arduino using the buttons on the display, also we will print some numerical value on the display.
For this tutorial I am going to use the Arduino UNO controller. The HMI Displays generally communicates using the UART, so in order to control the display, all we need is a controller with UART peripheral, which is actually very common to find.
Let’s start with the connection
The Connection
The Stone HMI Display have the connector header in order to connect to the microcontrollers. But the spacing between the pins is too wide, and I couldn’t find any male header which can fit it. The display comes along with a USB-UART board which can also be used to power the display.
After doing some continuity testing I have found that the pins of this USB-UART board can also use used as the TX and RX pins. The diagram for the same is shown below
The HMI Display communicates in the RS232 format and in order to convert it to the TTL, I am using a RS232 to TTL converter.
The MCU is connected to the display via this converter as shown below.
Note that between the MAX232 converter and the USB-UART board, there is a cross connection, TX->RX and RX->TX. But between the MCU and MAX232 converter, there is a straight connection, TX->TX and RX->RX.
The MAX232 needs to be supplied 5V, as it will misbehave at 3.3V.
Also the UNO board have an on board LED which we will control using the buttons on the display.
The Design
Below is the image from the Stone designer including all the elements used in the Design.
There are 3 Labels
- Label 1 indicates the LED State
- Label 2 have the fixed string, “VALUE =”, and it does not change
- Label 3 is going to be updated with the value from the Integer Variable.
There are 2 buttons, LED01 is the ON button and we will program it to turn ON the LED. LED02 is the OFF button and it will turn the LED OFF.
The Code
On Pressing the button on the display, it sends the data via the UART. The data sent by the HMI Display is shown below:
Basically we get the 12 bytes of fixed data, and the rest depends on what name have we set for the button. As per this tutorial, I have set the button names as LED01 and LED02, so the total data sent by the display would be 12 Bytes + 5 Bytes for button name + 1 byte for the value = 18 Bytes.
We are going to use the built in functions provided under the Serial function to handle this incoming data.
But first in the setup function we will configure the UART at 115200 Baud Rate.
void setup() {
Serial.begin (115200);
pinMode(LED_BUILTIN, OUTPUT);
}
- Here We will configure the UART at 115200 baud rate.
- Also set the LED as Output.
void loop() {
if (Serial.find("LED")) {
Serial.readBytesUntil('>', RxData, 2);
- Inside the loop we will look for the string “LED“. Once the string is found the Serial.find function will return TRUE.
- Here we look for the “LED” because it is the name of the button we created on the display. After pressing these buttons, the display outputs the data containing the button name in it.
The ON and OFF buttons are named as LED01 and LED02. The “LED” part remain common in both of them, and it’s the next 2 characters which differentiate them from each other.
So after we found the string “LED”, we will get the rest of the characters of these button names. This will determine whether the ON or the OFF button was pressed.
Serial.readBytesUntil('>', RxData, 2);
will read the 2 bytes after the LED string. It will store these 2 bytes in the RxData array.
if (RxData[1] == '1')
{
digitalWrite(LED_BUILTIN, HIGH);
sprintf(TxData, "ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"label1\",\"text\":\"LED ON\"}>ET");
Serial.write(TxData);
}
We will look for the 2nd byte of this RxData array.
- If this byte is 1, that means the button name must be LED01, which means the ON button was pressed.
- Here we will first turn the LED ON.
- Then we need to send the text “LED ON” to the label 1 indicating that the LED is ON.
In order to send the text to the label, we used the command given in the instruction manual of the display. Below is the image from the manual showing this command.
The sprintf is just used to copy the string to the TxData buffer, which is then sent via the UART.
Similar to ON button, we also check for the OFF button, and then proceed accordingly. Below is the full code related to the buttons.
if (Serial.find("LED")) {
Serial.readBytesUntil('>', RxData, 2);
if (RxData[1] == '1')
{
digitalWrite(LED_BUILTIN, HIGH);
sprintf(TxData, "ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"label1\",\"text\":\"LED ON\"}>ET");
Serial.write(TxData);
}
else if (RxData[1] == '2')
{
digitalWrite(LED_BUILTIN, LOW);
sprintf(TxData, "ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"label1\",\"text\":\"LED OFF\"}>ET");
Serial.write(TxData);
}
}
We also need to send the Integral value to another label we created on the display. In order to do so, I am going to increment a variable and then convert its value to the Ascii format and send to the label.
sprintf(TxData, "ST<{\"cmd_code\":\"set_text\",\"type\":\"label\",\"widget\":\"label3\",\"text\":\"%d\"}>ET", num++);
Serial.write(TxData);
- Here we will store the command into the TxData buffer with the text field as the format specifier of the integral value (%d)
- The value to be stored in this identifier is that of the num variable.
- We will then send the data to the u art using the
Serial.write
function.
Result
Below are the images of the LCD and the Arduino
- In the image above, the LED is turned on after pressing the ON button
- The LED state shows the the LED is ON
- Also note the value = 6, it is the value of the num variable that we incremented in the code
- In the image above, the LED is turned off after pressing the OFF button
- The LED state shows the the LED is OFF
- Also note the value = 12, it is the value of the num variable that we incremented in the code