The project involves a HMI system which is designed as a modular upgrade add-on for easy expansion of existing industrial control systems (ICS) application. The board features a capacitive touch sensors for wireless control and remote interaction. An LCD display will be attached for real-time sensor monitoring and heads-up display of relay status. The communication shall use Modbus TCP over Wifi for interoperability with existing ICS systems with minimal wiring involved.
The board comes with an Infineon PSoC6-062S2.
MCU: CY8C624ABZI-S2D44, Cortex-M4 150MHz, Cortex-M0 100MHz, 2MB Flash and 1MB SRAM MCU
The wireless plug-in is an Infineon CYW43012:
The cyw43012 module is an SDIO high-speed wifi & bluetooth module developed by Infineon based on CYW43012. CYW43012 provides ultra-low power Wi-Fi® and Bluetooth® connections to extend the battery life of wearable devices, smart home products and portable audio applications. At the same time, its advanced coexistence engine can provide the best combination performance for 2.4 and 5-GHz dual-band Wi-Fi and dual-mode Bluetooth/Low Power Bluetooth (BLE) 5.0 applications.
Currently, the documentations of the board are still hard to find. We can find some information here (in Chinese):
- Schematic https://gitee.com/rt-thread-board/ifx-psoc62-evalkit
- Setup instructions https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/hw-board/ifx-eval-kit/ifx-eval-kit
- Reviews https://club.rt-thread.org/ask/article/74bb091d04751d5a.html
Important note: The CYW43012 module requires 1V8 logic levels. Please set the switch to 1V8.
BOM & CodeThis project requires minimal BOM materials to keep it low-cost, requiring only 3 components:
- Infineon Psoc6-evaluationkit-062S2
- CYW43012 Wifi Module
- SSD1306 Display I2C Module
I have attached the full program code at the end of this article.
Starting RT-Thread ProjectOpen the RT-Thread SDK Manager from the menu bar. Install Board Support Package > POSC62-IFX-EVAL-KIT
Create new project and choose the WiFi example cyw43012_wifi_demo
template. Ensure that the programming mode is set to KitProg3 and SWD.
The template code will generate a simple blinking LED example in the main.c
file, along with the drivers needed for Wifi.
According to the schematic, there are 2 LEDs. You may modify the LED_PIN to test different blinking LEDsConfigure Networking
- LED1: P0.0
- LED2: P0.1
Open the RT-Thread Settings
As we start with the cyw43012_wifi_demo
example, you will find that the cyw43012 wifi driver has already been enabled for you.
Enable socket & network interface device
When we run the example, we confirm that there is a WLAN MAC Address has been successfully detected.
We also use the following functions to connect to the WiFi network.
// Connect to Wifi
while(rt_wlan_connect(ssid, password) != RT_EOK) {
rt_kprintf("Could not connect to Wifi. Retrying... \r\n");
rt_thread_mdelay(1000 * 3);
}
rt_kprintf("Wifi successfully connected \r\n");
Setup libmodbusWe need to communicate with the ModBus TCP protocol.
Enable the libmodbus package and select tcp mode.
I chose libmodbus as it is the most lightweight and well-known library that is used in different cross-platform projects. Unfortunately, I found the code is outdated. It was originally for RT-Thread v4.xx. Some fixes must be done before I managed to successfully compile it.
Fixes for libmodbusEnable support for legacy versions
Enable POSIX standard I/O devices
Go to packages/libmodbus-latest/
to make the following changes:
(1) In modbus-private.h,
add #include <sys/select.h>
(2) In modbus-tcp.c
, comment out flags |= SOCK_CLOEXEC;
and flags |= SOCK_NONBLOCK;
.
Reference: https://club.rt-thread.org/ask/article/d367b2c1c1d65c0e.htmlSetup OLED Display
Go to Packages and enable the ssd1306 graphics library.
Go to Hardware and Enable Software I2C Bus.
We will connect to pins A4 and A5. So set the pin numbers to 84 and 85.
Formula for Pin numbers:PORT * 8 + PIN
Arduino A4 (P10.4) = 8*10 + 4 = number 84
Arduino A5 (P10.5) = 8*10 + 5 = number 85
This is how the wiring looks like:
Connect from OLED to PSoC6 Board
VCC = 3V3
GND = GND
SCL = A4 (number 84)
SDA = A5 (number 85)
Note: Initially I wanted to use the hardware i2c with the SCL and SDA pins on the Arduino header. Unfortunately there were issues.
I believe the WiFi module driver interferes with the hardware I2C pin peripherals, and will give us a "bus fault" error on pin numbers 64 and 65
Therefore, I had to workaround this by using the software I2C on pins A4 and A5 instead.
Issues with the CapSense hardwareI also initially wanted to use the capacitive touch sliders for the project. However, I was unable to get it working.
When I enabled the Slider demo, I was able to detect a single touch. But unable determine the sliding motion. This is possibly due to the PCB design. As my country has more humid weather, the capacitance effect could not be calibrated well.
Setup for Industrial SystemMy setup simulates an industrial controls for a Boiler system. It consists of several inputs, output status lights and output blower motor.
The logic is programmed like so: (1) Run/Stop button for the motor(2) LEDs showing the motor status(3) A switch to trigger a flashing alarm.
In the Siemens Logo, we set the IP address and enable Modbus access.
Take note of the Modbus address space. I summarized it in a table below
Here is the libmodbus minimal code. Pay attention that libmodbus is zero-indexed, while the PLC is one-indexed.
// Connect to modbus server
modbus_t *ctx = modbus_new_tcp("192.168.77.77", 502, AF_INET);
modbus_set_slave(ctx, 1);
modbus_connect(ctx);
// Read from modbus server
uint8_t coils[8] = {0};
uint8_t inputs[8] = {0};
// Note: libmodbus is zero-indexed
// Coils start at 8193 (one-indexed)
// Inputs start at 1 (one-indexed)
modbus_read_bits(ctx, 8192, 8, coils);
modbus_read_input_bits(ctx, 0, 8, inputs);
// Print it out
rt_kprintf("Coils: ");
for (int i = 0; i < 8; i++) {
rt_kprintf("<%d>", coils[i]);
}
rt_kprintf("\r\n");
rt_kprintf("Inputs: ");
for (int i = 0; i < 8; i++) {
rt_kprintf("<%d>", inputs[i]);
}
rt_kprintf("\r\n");
rt_kprintf("-------------------------------------------\r\n");
// Close
modbus_close(ctx);
After running the code, we are successfully able to connect to the target IP address and read from the modbus. The data updates in real-time
Lastly we integrate the information into the display. We can read out the specific item from the modbus data array, and write the information onto the SSD1306 display.
// Export to variables
motor = coils[0]; // Q1
red_led = coils[1]; // Q2
green_led = coils[2]; // Q3
run_btn = inputs[5]; // I6
stop_btn = inputs[6]; // I7
alarm_switch = inputs[7]; // I8
More details are attached in the program code below.
To conclude this project, we successfully integrated a modular HMI system into an industrial control system using minimal hardware and Modbus TCP. We faced some hardware challenges, such as issues with I2C drivers and capacitive touch sliders. However, working around the issues, we were able to achieve real-time Modbus data visualized on an OLED display in a portable & modular setup.
Comments
Please log in or sign up to comment.