Episode 15: Switching screens
-
This example shows how to use multiple GUI-O screens and switch between them.
GUI-O supports up to five (5) screens, where widgets can be placed.
Switching between screens can be performed in two ways: using the 1. built-in flick functionality or by creating a 2. flick area widget (FLA) and reacting to user input on the ESP32 side.
Here, I will only cover only the first option. For the second option, see the GUI-O developer manual (hint: see section Multiple screen support).I will be using GUI-O Bluetooth Low Energy (LE) connection, but the example can be easily be ported to other connection types.
Software prerequisites:
-
Arduino IDE (https://www.arduino.cc/en/software)
-
ESP32 Arduino board support, if using ESP32 based board (see https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html)
-
GUI-O design tool (https://www.gui-o.com/design-tool)
-
GUI-O application (https://play.google.com/store/apps/details?id=com.guio.guioapp)
-
For additional information about the GUI-O application, download the developer manual from https://www.gui-o.com/
Components needed:
- ESP32-WROOM-32 (or any other Arduino supported Bluetooth Low Energy capable board)
The entire tutorial is split into various steps. All necessary information is given in each step.
0. DESIGN THE GUI (optional)
The best way to create a GUI layout is to use GUI-O live designer tool.
Note that the Arduino source code already includes the necessary commands, so this step is not needed, unless you want to make some visual adjustments. If you make adjustments, please include the generated ASCII code in the Arduino source code (see section 1. UPLOAD THE SOURCE CODE).
First, you need to establish a TCP/IP connection between the designer tool and GUI-O application:
- Determine the local IP address of your PC's network interface (WiFi or Ethernet)
- Under Windows, open the command prompt, enter
ipconfig
and press Enter - Under Linux, open the terminal, enter
ifconfig
and press Enter
-
Open GUI-O application and open settings menu. Select "Connections -> Ethernet" and create a new device with IP address (determined from 1.) and any port between 49152 - 65535
-
Open GUI-O designer and select "TCP/IP connection" tab. Set the IP address and port. Both values must match the device settings created within the GUI-O application. Click "Start server" button.
-
Within the GUI-O application, tap the created device and wait for successful connection.
-
In the GUI-O designer, select "File -> Load designer file" and load the SwitchScreen.gdf design file. Make the desired adjustments, if necessary. Copy / replace the GUI-O commands into the Arduino source code (see section 1. UPLOAD THE SOURCE CODE).
1. UPLOAD THE SOURCE CODE
The source code has inline comments, describing the important parts of the code. You can copy the source code from the snippet below, or download it here.
Upload the code to your board (make sure that the correct board and upload port are selected). Reset the board after upload.
/* * GUI-O Switch screen Bluetooth example (using ESP32-WROOM-32) * * Copyright (C) 2023, kl3m3n * last updated on 01.04.2023 * * SPDX-License-Identifier: BSD-3-Clause */ #include <BLEDevice.h> #include <BLEServer.h> #include <BLEUtils.h> #include <BLE2902.h> namespace uuid { static const char *SERVICE_UUID = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"; static const char *RX_CHARACTERISTIC_UUID = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"; static const char *TX_CHARACTERISTIC_UUID = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"; } // namespace uuid // forward declare parser for incoming messages void parseGuioMsg(const String &msg); // setup done flag bool setupDone = false; // custom handling of server callbacks class CustomBLEServerCallbacks: public BLEServerCallbacks { void onConnect(BLEServer* pServer) { Serial.println("Connected!"); }; void onDisconnect(BLEServer* pServer) { Serial.println("Disconnected!"); // restart advertising after disconnect, otherwise GUI-O cannot re-connect if(setupDone) { // restart advertising on disconnect delay(500); pServer->startAdvertising(); } } }; // custom handling of characteristic callbacks class CustomBLECharacteristicCallbacks: public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { std::string msg = pCharacteristic->getValue(); // parse message string parseGuioMsg(String(msg.c_str())); } }; // global ptr BLECharacteristic *pTxCharacteristic; void setup() { // debug output Serial.begin(115200); // create device BLEDevice::init("SwitchScreen"); // create server and register callback BLEServer *pServer = BLEDevice::createServer(); pServer->setCallbacks(new CustomBLEServerCallbacks()); // create service BLEService *pService = pServer->createService(uuid::SERVICE_UUID); // crate Tx characteristic and add descriptor pTxCharacteristic = pService->createCharacteristic(uuid::TX_CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_NOTIFY); pTxCharacteristic->addDescriptor(new BLE2902()); // crate Rx characteristic and register callback BLECharacteristic *pRxCharacteristic = pService->createCharacteristic(uuid::RX_CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_WRITE_NR); pRxCharacteristic->setCallbacks(new CustomBLECharacteristicCallbacks()); // start the service and start advertising pService->start(); pServer->getAdvertising()->start(); // setup done flag setupDone = true; } void loop() { } void sendMsg(const String &msg) { pTxCharacteristic->setValue(std::string(msg.c_str())); pTxCharacteristic->notify(); delay(50); } void parseGuioMsg(const String &msg) { if(msg.startsWith("@init")) { Serial.println("GUI-O app is requesting INITIALIZATION!"); // clear screen and set background sendMsg("@cls\r\n"); sendMsg("@guis BGC:#FFFFFF PGF:1\r\n"); delay(100); // initialize GUI sendMsg("|LB UID:title X:50 Y:20 FSZ:4 FFA:\"font8\" TXT:\"Switch<br>screen\"\r\n"); sendMsg("|LB UID:home X:50 Y:50 FGC:#607196 SHE:1 SHC:#FFC759 FSZ:5 FFA:\"font1\" TXT:\"HOME SCREEN\"\r\n"); sendMsg("|LB UID:screen1 X:50 Y:50 FGC:#607196 SHE:1 SHC:#FFC759 FSZ:5 FFA:\"font1\" TXT:\"SCREEN 1\" SCI:1\r\n"); sendMsg("|LB UID:screen2 X:50 Y:50 FGC:#607196 SHE:1 SHC:#FFC759 FSZ:5 FFA:\"font1\" TXT:\"SCREEN 2\" SCI:2\r\n"); sendMsg("|LB UID:screen3 X:50 Y:50 FGC:#607196 SHE:1 SHC:#FFC759 FSZ:5 FFA:\"font1\" TXT:\"SCREEN 3 ...\" SCI:3\r\n"); sendMsg("|LB UID:details X:50 Y:90 FSZ:2 TXT:\"GUI-O switch screen<br>demonstration by kl3m3n\"\r\n"); } }
2. ESTABLISH CONNECTION
Open GUI-O application and press Add in the upper-right corner of the home screen. Tap on Bluetooth LE and search for devices (enable Bluetooth and Location services, if prompted). Tap on the "SwitchScreen" device, select Nordic UART service and wait for successful connection (confirm device pairing if prompted).
Close the settings menu and press the Initialize button (see image below) from the GUI-O application home screen.
3. THE RESULT
Image below shows the result (screen capture) on my Android device after pressing the "Initialize" button. The bottom screen indicator indicates the number of screens and the currently active screen. Navigation between screens is possible by flicking left or right at the bottom of the screen. This is shown in the video below.
If you have any questions or run into any problems, please let me know!
Best regards,
kl3m3n -