Week 14 — Interface and Application Programming

This assignment focuses on the development of a desktop graphical interface using Java Swing for real-time monitoring and control of a custom ESP32-C3 embedded system. The application communicates through the UART protocol using JSerialComm, enabling bidirectional interaction between software and hardware for environmental monitoring and room lighting control.

View Assignment ↓

Individual Assignment

  • Write an application for the embedded board that interfaces a user with input and/or output devices.

Learning Outcomes

  • Implement a User Interface (UI) using programming.
  • Explore communication protocols between a custom microcontroller board and a desktop application.
  • Develop real-time interaction between software and embedded hardware systems.

Progress Status – Embedded Interface Application

Development of a desktop monitoring and control system using Java Swing, UART communication, and a custom ESP32-C3 embedded board.

1 – Embedded System Assembly 100%

Integration and programming of the custom ESP32-C3 PCB including DHT22 sensor, SSD1306 OLED display, and relay-based room lighting control.

2 – User Interface Layout 100%

Design and organization of graphical components in Java Swing, including status indicators, environmental monitoring panels, and interactive control elements.

3 – UART Communication 100%

Bidirectional serial communication implemented using Java JSerialComm and Arduino Serial protocol for real-time data exchange.

4 – Environmental Monitoring 100%

Real-time visualization of temperature and humidity values using the DHT22 sensor, desktop GUI, and OLED display synchronization.

5 – Relay Lighting Control 100%

Remote ON/OFF room light control using a relay module connected Normally Open (NO) and controlled directly from the Java interface.

System Demonstration

The following demonstration shows the complete operation of the embedded monitoring and control system, including UART communication, environmental monitoring, OLED visualization, and relay-based room lighting control through the Java Swing desktop application.

HeroShot of the complete embedded monitoring and control system

HeroShot: Complete embedded monitoring and control platform showing the Java Swing interface, ESP32-C3 system, OLED display, DHT22 sensor, and relay-based lighting control operating in real time.

Real-time interaction between the Java Swing interface and the ESP32-C3 embedded system using UART communication.

Context & System Overview

This assignment focuses on the development of a desktop application capable of communicating with a custom embedded system through the UART protocol. The project integrates both software and hardware components, allowing real-time monitoring of environmental variables and remote control of physical devices.

The graphical user interface was developed using Java Swing inside the NetBeans IDE. NetBeans provides an integrated graphical interface designer that simplifies the organization of visual components while still allowing full access to the application source code.

Using Swing made it possible to create a custom desktop interface composed of interactive elements such as icons, status indicators, environmental monitoring labels, connection management menus, and relay control buttons. The event-driven programming model also enabled real-time interaction between the GUI and the embedded system.

The embedded hardware platform used in this assignment was the custom ESP32-C3 PCB previously designed and fabricated during the Electronics Production week. The board integrates the XIAO ESP32-C3 microcontroller and provides the main communication and control interface for the sensors and actuators connected to the system.

The system includes:

  • DHT22 sensor for temperature and humidity monitoring
  • SSD1306 OLED display for local visualization
  • Relay module for room light control
  • UART serial communication between Java and ESP32-C3

Environmental data is acquired by the microcontroller, transmitted through UART, processed by the Java application, and displayed simultaneously on both the desktop interface and the OLED display. Additionally, the GUI can send commands back to the ESP32-C3 to remotely control the relay-connected lamp.

Custom ESP32-C3 PCB used for the interface application

Custom ESP32-C3 PCB developed during the Electronics Production week, used as the embedded hardware platform for this assignment.

Simulation Validation – Wokwi

Before implementing the circuits on physical hardware, all experiments were first simulated using Wokwi. This allowed me to validate both the code logic and the behavior of the output devices in a controlled environment.

Through simulation, I was able to perform early debugging, verify pin configurations, and test different control strategies such as PWM signals for the servo motor and buzzer, as well as I2C communication for the OLED display.

This approach significantly reduced development time and minimized the risk of hardware errors, such as incorrect wiring or unstable signal behavior. It also provided a better understanding of how different output devices respond to microcontroller commands.

Using simulation as a first step helped ensure that each output device behaved correctly before integrating it into the final physical system based on the custom PCB.

Embedded System and UART Communication

The embedded system was developed using the custom ESP32-C3 PCB designed during the Electronics Production week. The board integrates environmental sensing, local visualization, and actuator control capabilities through a unified hardware architecture.

The system uses a DHT22 sensor to measure temperature and humidity, an SSD1306 OLED display for local real-time visualization, and a relay module connected in Normally Open (NO) configuration to control the ON/OFF state of a room lamp.

UART Communication Protocol

Communication between the desktop application and the embedded board was implemented using the UART serial protocol. The ESP32-C3 continuously transmits environmental data through the serial interface, while the Java application sends control commands back to the microcontroller.

On the embedded side, communication was implemented using the Arduino Serial library, while the desktop application uses the JSerialComm Java library for serial port management and asynchronous data reading.

System Behavior

  • DHT22 sensor measures temperature and humidity
  • ESP32-C3 sends data through UART
  • Java Swing GUI displays real-time values
  • OLED display mirrors environmental information locally
  • GUI sends relay control commands (LON / LOFF)
  • ESP32-C3 activates or deactivates the relay output
ESP32-C3 embedded monitoring system connections

Embedded monitoring and control system using ESP32-C3, DHT22 sensor, SSD1306 OLED display, and relay module.

Circuit Connection

DHT22 Sensor
  • VCC → 3.3V
  • GND → GND
  • DATA → D0
SSD1306 OLED
  • VCC → 3.3V
  • GND → GND
  • SDA → SDA
  • SCL → SCL
Relay Module
  • VCC → 5V
  • GND → GND
  • IN → D1
  • COM → AC Line
  • NO → Lamp

Embedded Program Code


#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>

// ================= PINOUT =================
#define DHTPIN  D0
#define DHTTYPE DHT22

#define LED     D1

// ================= DHT =================
DHT dht(DHTPIN, DHTTYPE);

// --SSD1306--
#define height 64
#define width 128
#define rst -1

Adafruit_SSD1306 display(width, height, &Wire, rst);

//================ Variables ================
float tem = 0.0;
float hum = 0.0;

void setup() {

  pinMode(LED, OUTPUT);

  Serial.begin(115200);

  Wire.begin();

  dht.begin();

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0X3C)) {

    Serial.println("Oled Display NOT Found...");

    for (;;);
  }

  printTxt("Control");

  delay(3000);

  digitalWrite(LED, LOW);

  printTxt("OFF");
}

void loop() {

  // ===== READ DHT22 =====
  tem = dht.readTemperature();
  hum = dht.readHumidity();

  // ===== VALIDATE =====
  if (isnan(tem) || isnan(hum)) {

    Serial.println("DHT ERROR");

    delay(1000);

    return;
  }

  // ===== SEND SERIAL DATA =====
  Serial.print("Tem\t");

  Serial.print(tem);

  Serial.print(",\tHum\t");

  Serial.print(hum);

  Serial.println(";");

  // ===== PRINT DATA ON DISPLAY =====
  printData(tem, hum, digitalRead(LED));

  // ===== SERIAL COMMANDS =====
  if (Serial.available() > 0) {

    String txt = Serial.readString();

    txt.trim();

    if (txt == "LON") {

      digitalWrite(LED, HIGH);

      printTxt("ON");
    }
    else if (txt == "LOFF") {

      digitalWrite(LED, LOW);

      printTxt("OFF");
    }
  }

  delay(1000);
}
  

Code Explanation

  • System Initialization and Peripheral Configuration: The program initializes multiple hardware subsystems during the setup() function, including UART communication, I2C communication, the DHT22 sensor, the OLED display, and the relay output pin. The ESP32-C3 acts as the central controller, coordinating sensor acquisition, graphical visualization, and actuator control simultaneously.
  • UART Communication using Serial Protocol: The communication between the embedded board and the Java Swing application is implemented through the UART serial protocol using the Arduino Serial library. The instruction:
    Serial.begin(115200);
    configures the serial interface at 115200 baud, enabling high-speed bidirectional communication between the ESP32-C3 and the desktop application. Environmental data is periodically transmitted, while control commands such as LON and LOFF are received from the GUI.
  • DHT22 Environmental Sensor Reading: The DHT22 sensor is used to measure both temperature and relative humidity. The instructions:
    
    tem = dht.readTemperature();
    hum = dht.readHumidity();
        
    retrieve environmental values directly from the sensor. Since DHT sensors are relatively slow and sensitive to timing, the library internally manages communication timing and checksum validation.
  • Sensor Validation and Error Detection: Sensor readings are validated using:
    
    if (isnan(tem) || isnan(hum))
        
    The function isnan() verifies whether the sensor returned invalid numerical values. If an error occurs, the system sends a diagnostic message through UART and skips the current iteration, preventing corrupted data from propagating into the graphical interface.
  • Formatted Serial Data Transmission: Environmental information is transmitted using a structured serial message format:
    
    Tem 25.5, Hum 60.0;
        
    This formatting strategy simplifies parsing inside the Java application, where the incoming UART stream is processed character by character. The semicolon (;) acts as an end-of-message delimiter, allowing synchronization between the embedded system and the desktop application.
  • OLED Display Rendering using I2C: The SSD1306 OLED display communicates through the I2C protocol using the Wire library. The display provides local real-time feedback, allowing the embedded system to operate independently even without the desktop application connected. The rendering process follows a buffered graphics approach: graphical elements are first written into memory and later transferred to the display using display.display(), minimizing flickering effects.
  • Relay Control Logic: The relay module is connected in Normally Open (NO) configuration and controlled through a digital GPIO pin. When the application receives:
    
    LON
        
    the relay output is activated:
    
    digitalWrite(LED, HIGH);
        
    and the room lamp turns ON. Similarly, the command:
    
    LOFF
        
    deactivates the relay and disconnects the load.
  • Bidirectional Human-Machine Interaction: The system demonstrates a complete bidirectional communication workflow:
    • Embedded system → sends environmental data
    • Desktop application → displays real-time monitoring
    • User interaction → triggers control commands
    • ESP32-C3 → actuates the relay output
    This architecture creates a complete Human-Machine Interface (HMI) where software and hardware interact continuously in real time.
  • Integrated Embedded System Architecture: The final program integrates multiple subsystems simultaneously:
    • Environmental sensing (DHT22)
    • Graphical local visualization (SSD1306)
    • UART communication
    • Desktop GUI interaction
    • Relay-based actuator control
    The loop() function continuously executes all these processes, creating a synchronized real-time monitoring and control platform.

Java Swing GUI Development

The desktop application was developed using Java Swing, a graphical user interface (GUI) toolkit included in the Java Foundation Classes (JFC). Swing provides a complete set of graphical components that allow developers to create desktop applications using an object-oriented and event-driven programming model.

Unlike low-code platforms, Swing applications are built entirely through code, giving full control over interface behavior, graphical customization, event management, and hardware integration. Since Swing is part of Java, applications can run across multiple operating systems through the Java Virtual Machine (JVM).

In this project, Swing was used to create a real-time monitoring and control interface connected to the ESP32-C3 embedded system through UART communication. The application includes graphical indicators, serial configuration menus, environmental monitoring panels, and relay control interaction.

Swing Components Used

Component Purpose Role in the Project
JFrame Main application window Acts as the main desktop interface container
JPanel Graphical container Used to organize interface sections and render custom backgrounds
JLabel Text and image display Displays sensor values, icons, and interactive graphics
JMenu Menu creation Creates UART configuration menus
JRadioButtonMenuItem Selectable options Allows baud rate and serial parameter selection
ButtonGroup Selection management Ensures only one UART option is selected at a time
JButton Standard button interaction Evaluated during development but replaced by labels for aesthetics

Project Creation Workflow

Java project creation in NetBeans

Creation of the Java Application project inside NetBeans.

Creating the Java Project

The first step consisted of creating a standard Java Application project inside NetBeans. This automatically generates the project structure, source folders, build configuration, and dependency management required by the application.

NetBeans simplifies project organization by separating:

  • Source code files
  • Resources and images
  • Libraries and dependencies
  • Build and execution configuration

This modular structure is especially useful for medium and large desktop applications.

Creating the JFrame Interface

After creating the project, a JFrame Form was added. A JFrame represents the main application window and acts as the root container for all graphical components.

Swing interfaces are constructed hierarchically, where graphical components are placed inside containers such as panels and frames.

NetBeans automatically generates part of the interface code, including:

  • Component initialization
  • Graphical layout configuration
  • Object declarations
  • Event listener structures

This reduces repetitive coding tasks while still allowing manual customization.

JFrame creation

Creation of the JFrame form used as the main application window.

NetBeans GUI editor

Graphical positioning of Swing components using the NetBeans editor.

GUI Layout and Component Positioning

The NetBeans GUI editor provides a visual drag-and-drop interface that allows components to be positioned interactively.

During this stage, the application layout was organized into:

  • Environmental monitoring indicators
  • Connection status section
  • Relay control interface
  • UART configuration menus
  • Custom background graphics

Several graphical attributes were configured manually, including:

  • Fonts and text sizes
  • Object alignment
  • Foreground colors
  • Transparent backgrounds
  • Image scaling
  • Custom icons

This process allowed the interface to achieve a more personalized appearance compared to default Swing applications.

Final Interface Preview

The final application integrates graphical monitoring, serial communication, and hardware interaction inside a unified desktop interface.

One important design decision was the use of JLabel components instead of traditional JButton objects for interactive controls.

Although buttons provide native interaction behavior, labels make it easier to display and scale images without default button borders or styling.

This allowed the interface to use graphical icons as interactive elements, producing a cleaner and more visually integrated design.

The application also dynamically changes icons to represent system states such as:

  • Connected / Disconnected status
  • Relay ON / OFF state
  • Environmental indicators
Final GUI preview

Final Java Swing interface used for real-time monitoring and relay control.

UART Communication in Java

One of the most important parts of this project was the implementation of bidirectional UART communication between the Java Swing application and the ESP32-C3 embedded system.

Unlike Arduino IDE environments where serial communication is handled automatically, desktop applications require direct management of serial ports, communication parameters, asynchronous data reading, event listeners, and exception handling.

To implement this communication layer, the project uses the JSerialComm library, which provides cross-platform serial communication support for Java.

Libraries Used

Library Purpose
com.fazecast.jSerialComm UART serial communication management
javax.swing Graphical user interface components
java.io.OutputStream Sending serial data to the ESP32-C3
java.awt Graphics and image management

SerialPort Object Creation


private SerialPort serialComm;
private OutputStream output;

The SerialPort object represents the physical UART communication interface.

This object is responsible for:

  • Opening and closing COM ports
  • Configuring serial parameters
  • Sending and receiving data
  • Managing communication events

The OutputStream object is used to transmit bytes directly to the ESP32-C3 board.

Automatic COM Port Detection

The application dynamically scans all available serial ports connected to the operating system.

Each detected COM port is automatically converted into a selectable menu option inside the GUI.

This allows the application to adapt dynamically when USB devices are connected or disconnected.


for (SerialPort p : SerialPort.getCommPorts()) {

    JRadioButtonMenuItem menuPort =
        new JRadioButtonMenuItem();

    menuPort.setText(
        p.getSystemPortName()
    );

    this.Port_Group.add(menuPort);

    this.jMenu_Port.add(menuPort);

    this.portList.add(menuPort);
}

UART Communication Parameters


this.serialComm.setBaudRate(this.baudRate);

this.serialComm.setNumDataBits(this.dataBits);

this.serialComm.setNumStopBits(this.stopBits);

this.serialComm.setParity(this.parityBits);

UART communication requires several synchronized parameters between the ESP32-C3 and the desktop application.

  • Baud Rate: transmission speed
  • Data Bits: size of transmitted data packets
  • Stop Bits: frame synchronization
  • Parity: error checking mechanism

These parameters are configurable directly from the GUI menus, allowing the application to support multiple serial configurations.

The default configuration used in this project is:

  • 115200 baud
  • 8 data bits
  • 1 stop bit
  • No parity

Asynchronous Serial Event Listener

One of the most important features of JSerialComm is its event-driven communication model.

Instead of continuously polling the serial port, the application uses a SerialPortDataListener that automatically triggers whenever new data arrives.

This asynchronous approach improves efficiency and enables real-time GUI updates without blocking the application thread.


activePort.addDataListener(
  new SerialPortDataListener() {

    @Override
    public int getListeningEvents() {
      return SerialPort
        .LISTENING_EVENT_DATA_RECEIVED;
    }

    @Override
    public void serialEvent(
      SerialPortEvent event
    ) {

      byte[] newData =
        event.getReceivedData();

    }
});

UART Data Processing


if (c == '\n') {

    String msg =
      dataBuffer.toString().trim();

    SwingUtilities.invokeLater(() -> {
        dataLabelProcess(msg);
    });

    dataBuffer.setLength(0);
}

Incoming UART data is received byte-by-byte and accumulated inside a StringBuilder buffer.

When the newline character is detected, the complete message is processed.

The method:

SwingUtilities.invokeLater()

ensures that GUI components are updated safely inside the Swing Event Dispatch Thread (EDT), preventing concurrency problems during real-time interface updates.

Sensor Data Parsing

The ESP32-C3 sends structured messages containing temperature and humidity values.

The application validates the message format, separates the variables, extracts numerical values, and updates the interface dynamically.

This parsing stage acts as a simple communication protocol layer between hardware and software.


if(msg.charAt(0) == 'T' &&
   msg.charAt(msg.length()-1) == ';') {

    String[] variables = msg.split(",");

    this.jLabel_TemVal
        .setText(variables[0] + "°C");

    this.jLabel_HumVal
        .setText(variables[1] + "%");
}

Sending Commands to the ESP32-C3


private void sendData(String txt) {

    txt += this.endLine;

    this.output.write(txt.getBytes());
}

Communication is fully bidirectional.

The GUI can send commands such as:

  • LON → Relay ON
  • LOFF → Relay OFF

These commands are converted into byte arrays and transmitted through the UART interface directly to the ESP32-C3.

End-line characters can also be configured dynamically using the GUI menus, supporting:

  • No terminator
  • New Line (\n)
  • Carriage Return (\r)
  • Both (\r\n)

Exception Handling

Serial communication is highly dependent on external hardware availability.

For this reason, the application includes multiple exception handling mechanisms to prevent crashes during:

  • Disconnected devices
  • Invalid COM port selection
  • Communication failures
  • I/O transmission errors

Error dialogs are displayed using JOptionPane, allowing the user to identify problems quickly.


catch (Exception e2) {

    JOptionPane.showMessageDialog(
        this,
        e2,
        "ERROR",
        JOptionPane.ERROR_MESSAGE
    );

    this.enableTools();
}

Environmental Monitoring

One of the main functionalities of the application is the real-time monitoring of environmental variables using a DHT22 sensor connected to the ESP32-C3.

The system continuously measures:

  • Ambient temperature
  • Relative humidity

These values are transmitted through UART, processed inside the Java application, and dynamically displayed in the graphical interface using Swing labels and graphical indicators.

Reading Environmental Data from the ESP32-C3


tem = dht.readTemperature();

hum = dht.readHumidity();

The DHT22 sensor is responsible for measuring ambient temperature and relative humidity.

The ESP32-C3 periodically reads the sensor values using the DHT library, which internally handles timing synchronization and checksum validation required by the protocol.

The measured values are stored in floating-point variables and later transmitted to the Java application through UART communication.

Serial Transmission Format

The ESP32-C3 sends environmental data using a structured serial message format.

This formatting is important because it allows the Java application to identify, separate, and process incoming variables correctly.

The semicolon character acts as an end-of-message marker, while the comma separates temperature and humidity values.


Serial.print("Tem\t");

Serial.print(tem);

Serial.print(",\tHum\t");

Serial.print(hum);

Serial.println(";");

Message Validation and Parsing


if(msg.charAt(0) == 'T' &&
   msg.charAt(msg.length()-1) == ';') {

    String[] variables = msg.split(",");
}

Once the UART message arrives, the Java application validates whether the received data matches the expected protocol structure.

The program verifies:

  • Correct initial character
  • Correct message termination
  • Presence of both variables

After validation, the message is divided into two sections using the comma separator.

Numerical Data Extraction

The incoming UART message contains both text and numerical information.

To isolate the sensor values, the application iterates character-by-character through the received string, extracting only valid numerical symbols.

This filtering process removes:

  • Text labels
  • Tabs and spaces
  • Special formatting characters

The result is a clean numerical value ready to be displayed inside the GUI.


for(char c : variables[n].toCharArray()) {

    if(Character.isDigit(c) ||
       c == '.' ||
       c == '-') {

        aux += c;
    }
}

Dynamic JLabel Update


this.jLabel_TemVal
    .setText(variables[0] + "°C");

this.jLabel_HumVal
    .setText(variables[1] + "%");

One of the most important mechanisms in the interface is the dynamic modification of Swing labels using the method:

setText()

In Swing, a JLabel is a graphical object capable of displaying text or images.

The method:

setText()

allows the content of the label to be updated in real time while the application is running.

This mechanism transforms the GUI into a live monitoring dashboard, where environmental values are refreshed continuously as new UART data arrives from the ESP32-C3.

Without this dynamic update capability, the interface would only display static information.

Thread-Safe GUI Updates

Since serial communication events occur asynchronously, GUI updates cannot be executed directly from the serial communication thread.

Swing requires graphical updates to be executed inside the Event Dispatch Thread (EDT) to prevent concurrency problems.

For this reason, the project uses:

SwingUtilities.invokeLater()

which safely schedules the interface update inside the correct graphical thread.


SwingUtilities.invokeLater(() -> {

    dataLabelProcess(msg);

});

Real-Time Monitoring System


if(msg == null || msg.isEmpty()) {
    return;
}

The monitoring system operates continuously while validating incoming data in real time.

Before processing any message, the application verifies:

  • That data actually exists
  • That the message is not empty
  • That the format is correct

This prevents corrupted UART messages from generating interface errors or invalid sensor readings.

The result is a stable real-time monitoring platform capable of continuously synchronizing the embedded system with the desktop GUI.

Relay Lighting Control

In addition to environmental monitoring, the application also implements remote actuator control through a relay module connected to the ESP32-C3.

The relay operates in Normally Open (NO) configuration and is used to control the ON/OFF state of a room lamp directly from the Java Swing interface.

This creates a complete Human-Machine Interface (HMI) where the desktop application can both:

  • Monitor environmental variables
  • Control physical hardware remotely

Interactive JLabel as a Control Element


jLabel_LedImg.addMouseListener(
    new java.awt.event.MouseAdapter() {

    public void mouseClicked(
        java.awt.event.MouseEvent evt
    ) {

        jLabel_LedImgMouseClicked(evt);
    }
});

Instead of using a traditional JButton, the application uses a clickable JLabel as the relay control interface.

The label behaves as a graphical button by attaching a MouseListener event to the image component.

This approach provides greater visual customization because labels allow images to be displayed naturally without default Swing button borders, focus indicators, or platform-specific styles.

As a result, the interface achieves a cleaner and more modern visual appearance.

Dynamic Icon Switching

One of the most important visual features of the interface is the dynamic replacement of icons according to the relay state.

When the user clicks the graphical label, the application changes:

  • The displayed image
  • The status text
  • The internal boolean state

This creates immediate visual feedback, allowing the user to understand whether the relay is currently ON or OFF.


if (this.ledOn) {

    this.setImgLabel(
        "/IMG/LedOFF.png",
        this.jLabel_LedImg
    );

    this.jLabel_LED.setText("LED OFF");

    this.ledOn = false;

} else {

    this.setImgLabel(
        "/IMG/LedON.png",
        this.jLabel_LedImg
    );

    this.jLabel_LED.setText("LED ON");

    this.ledOn = true;
}

Image Scaling and Icon Management


Image img = new ImageIcon(
    this.getClass().getResource(dir)
).getImage();

img = img.getScaledInstance(
    label.getWidth(),
    label.getHeight(),
    Image.SCALE_SMOOTH
);

label.setIcon(new ImageIcon(img));

Swing uses the Icon system to display graphical resources inside components such as labels and buttons.

In this project, icons are loaded dynamically from the application resources using:

new ImageIcon()

Since original images may have different resolutions, each image is automatically resized to match the dimensions of the target label.

The method:

getScaledInstance()

rescales the image while:

  • Maintaining aspect ratio
  • Improving visual quality
  • Smoothing pixel interpolation

This allows all graphical indicators to maintain a consistent visual appearance regardless of the original image size.

Relay Command Processing

After updating the GUI state, the application sends a UART command to the ESP32-C3 indicating the desired relay state.

The commands used are:

  • LON → Relay ON
  • LOFF → Relay OFF

These messages are interpreted by the embedded system, which then activates or deactivates the relay output pin.

This creates a complete bidirectional control architecture between the desktop GUI and the embedded hardware.


this.sendData(
    this.ledOn ? "LON" : "LOFF"
);

Relay Processing inside the ESP32-C3


if (txt == "LON") {

    digitalWrite(LED, HIGH);

    printTxt("ON");

}
else if (txt == "LOFF") {

    digitalWrite(LED, LOW);

    printTxt("OFF");
}

On the embedded side, the ESP32-C3 continuously listens for incoming UART commands.

When the message LON is received, the relay GPIO pin is activated, energizing the relay coil and turning the lamp ON.

Conversely, the message LOFF deactivates the output and disconnects the load.

The OLED display is also updated locally, providing visual confirmation directly on the embedded device.

Real-Time Human-Machine Interaction

The final relay control system demonstrates a complete Human-Machine Interface workflow:

  • User interacts with the Java GUI
  • GUI updates graphical indicators
  • UART command is transmitted
  • ESP32-C3 processes the command
  • Relay activates physical hardware
  • OLED display confirms system state

This architecture combines:

  • Desktop software engineering
  • Embedded systems programming
  • Real-time communication
  • Graphical interface design
  • Physical actuator control

GUI Interaction
      ↓
UART Transmission
      ↓
ESP32-C3 Processing
      ↓
Relay Activation
      ↓
Physical Lamp Control

Final Reflection

This week focused on understanding how software interfaces can interact with embedded systems in real time through communication protocols and graphical user interfaces.

Throughout this assignment, I explored the complete workflow required to integrate desktop software development with embedded hardware systems. Unlike previous assignments that focused primarily on electronics or firmware, this project required combining multiple disciplines simultaneously:

  • Desktop GUI development
  • UART communication protocols
  • Embedded programming
  • Real-time data processing
  • Graphical interface design
  • Hardware control and monitoring

One of the most important learning outcomes was understanding how asynchronous communication works between a desktop application and a microcontroller. Implementing UART communication using JSerialComm introduced concepts such as serial configuration, event listeners, threading, message parsing, and exception handling.

Another key insight was the importance of structured communication protocols. Even though the transmitted messages were relatively simple, defining message delimiters, validation mechanisms, and parsing logic became essential for reliable real-time interaction between systems.

The graphical interface development process also provided a deeper understanding of event-driven programming. Through Java Swing, I worked with graphical components, interactive labels, icons, menus, and real-time GUI updates, transforming the application into a complete Human-Machine Interface (HMI).

One particularly interesting aspect of the project was using graphical labels instead of traditional buttons to create a cleaner and more customized interface design. This reinforced how software engineering decisions are not only functional, but also related to usability and user experience.

From the embedded systems perspective, integrating the DHT22 sensor, OLED display, and relay module into a single synchronized platform demonstrated how multiple subsystems can operate simultaneously while sharing communication resources and system logic.

Another important takeaway was understanding how desktop software can become a powerful extension of embedded systems. Instead of relying only on local displays or buttons, the project introduced remote visualization, dynamic graphical feedback, and bidirectional interaction between hardware and software.

Finally, this assignment reinforced the importance of combining software architecture, communication protocols, interface design, and embedded programming into a unified development workflow. The project demonstrated how modern embedded systems increasingly depend on integrated software ecosystems rather than isolated microcontroller programs.

Group Assignment Reflection

The group assignment complemented the individual project by providing a broader comparison of different technologies used for interface and application programming.

Analyzing multiple development frameworks helped contextualize the advantages and limitations of each approach, especially regarding scalability, graphical flexibility, communication capabilities, and integration with embedded systems.

Since I already had previous experience using MIT App Inventor, I intentionally decided not to use it for the individual assignment, even though it remains an excellent low-code platform for rapid prototyping and educational projects.

Instead, I chose to challenge myself by developing the entire application in Java Swing. This decision aligned more closely with my background in Object-Oriented Programming and allowed me to apply software engineering concepts within a real embedded systems workflow.

Working with Java Swing reinforced concepts such as:

  • Modularity and software structure
  • Event-driven programming
  • Graphical component management
  • Object-oriented architecture
  • Thread-safe GUI updates
  • Communication protocol implementation

Developing the interface entirely through code also provided significantly greater flexibility and architectural control compared to visual low-code tools. Although the workflow required more planning and debugging, the resulting system became more scalable and professionally structured.

The comparison between technologies also motivated me to continue exploring the Java ecosystem. As a future personal learning objective, I am interested in studying the Spring framework series, particularly Spring Boot and related web technologies, in order to develop scalable web and mobile applications connected to embedded and IoT systems.

Overall, both the individual and group assignments reinforced the importance of selecting technologies not only based on simplicity, but also according to scalability, maintainability, software architecture, and long-term development goals.

Downloads & Resources

The following resources include the embedded firmware, Wokwi simulation, Java Swing desktop application, and the complete NetBeans development project used during Week 14 – Interface and Application Programming.

⚡ Embedded Firmware

Arduino IDE firmware for the ESP32-C3 including DHT22 environmental monitoring, SSD1306 OLED visualization, UART communication, and relay-based room lighting control.

🌐 Wokwi Simulation

Complete online simulation of the embedded monitoring and relay control system using ESP32-C3, DHT22 sensor, OLED display, and UART communication.

🖥️ Java Swing Application

Executable Java Swing desktop application packaged as a runnable JAR file. Includes UART communication, environmental monitoring, and relay control interface.

☕ NetBeans Project

Complete Java NetBeans project including Swing GUI source code, JSerialComm integration, image resources, and project configuration files.

Sections
Requirements Status System Demo System Overview Wokwi Simulation 1. Embedded System 2. Java Swing GUI 3. UART Communication 4. Environmental Monitoring 5. Relay Control Final Reflection Group Reflection Downloads