Skip to content

14. Interface and application programming

Task: Interface and Application Programming

  • Group assignment:
    • Compare as many tool options as possible.
    • Document your work on the group work page and reflect on your individual page what you learned.
  • Individual assignment
    • Write an application for the embedded board that you made. that interfaces a user with an input and/or output device(s)

GROUP ASSIGNMENT

We used Different communication modes to communicate . That are listed below . .

Group Assignment Link

DIFFERENT COMMUNICATION METHODS

There are several widely-used communication methods between microcontrollers and other devices. These methods each have their own advantages and specific use cases. Let's explore some of the most common communication protocols used in embedded systems.

Communication Method Advantages Disadvantages Common Uses
Serial (UART) Simple to implement
Low hardware requirements
Well-documented Limited range
Relatively slow speed
Point-to-point only Debug communication
Basic device interfacing
Terminal applications
WebSerial Browser-based interface
No additional software needed
Modern user experience Requires web browser support
More complex implementation
Limited browser compatibility Web-based device control
Interactive debugging
Remote monitoring
WebSocket Real-time bidirectional
Persistent connection
Efficient for streaming More complex setup
Requires server implementation
Higher overhead Live data monitoring
Chat applications
Real-time updates
I2C Multiple devices on same bus
Standardized protocol
Hardware support built-in Short range
Limited speed
Address conflicts possible Sensor integration
Display connections
Inter-chip communication
SPI High speed
Full duplex
Simple hardware interface More pins required
Limited cable length
One master only Fast sensor reading
Display interfaces
Memory communication

SERIAL COMMUNICATION

Serial communication is a method of data transmission where data is sent one bit at a time, sequentially, over a communication channel or bus. It's widely used in embedded systems and microcontroller applications due to its simplicity and reliability. In our lab sessions, we'll explore both traditional serial communication using UART (Universal Asynchronous Receiver-Transmitter) and modern implementations like USB serial communication.

WEBSOCKET

WebSocket is a communication protocol that provides full-duplex communication channels over a single TCP connection. It enables real-time, bidirectional data exchange between a client (typically a web browser) and a server. Unlike traditional HTTP requests, WebSocket maintains a persistent connection, making it ideal for applications requiring live updates, chat functionality, or continuous data streaming from server to client.

WEBSERIAL

WebSerial is a powerful protocol that enables communication between web browsers and microcontrollers through a web interface. It provides a more user-friendly alternative to traditional serial communication by allowing control and monitoring of devices through a browser-based interface. This modern approach eliminates the need for dedicated serial terminal software and makes device interaction more accessible to users.

In this interfacing lab, we'll explore several projects involving ESP32 and various peripherals. The first project demonstrates basic LED control through serial communication, allowing us to turn an LED on and off using commands. We'll then progress to more complex applications including Bluetooth connectivity, OLED display integration, and web server implementations.

First, we wrote a simple code that involves serial communication. I used the RP2040's built-in LED for this process. The concept is straightforward: when we write "1" in the serial monitor, the LED turns on, and when we write "0", the LED turns off.

image.png

const int led = 25;
char a;
void setup() {
  pinMode(led, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  a = Serial.read();
  if (a == '1') {
    digitalWrite(led, LOW);
    Serial.println("ON");
  } else if (a == '0') {
    digitalWrite(led, HIGH);
    Serial.println("OFF");
  }
}

Subsequently, our instructor Midlaj shared his innovative WebSerial implementation with the class. This advanced code enabled us to control the LED's state through a web interface, representing a significant step up from basic serial communication. The WebSerial protocol established a bridge between the web browser and our microcontroller, allowing us to send commands through a user-friendly website interface rather than the traditional serial monitor. This modification demonstrated how modern web technologies can be integrated with embedded systems for enhanced user interaction and control.

image.png

Next, I delved into learning basic JavaScript with the guidance of Midlaj, who helped me understand the fundamental concepts and core functionalities of the language. We began our exploration by creating an interactive project: a real-time input box implementation. This dynamic interface allowed users to enter text that would instantly appear on the screen without requiring a page refresh, demonstrating the power of JavaScript's event handling and DOM manipulation capabilities. As we progressed, we enhanced the functionality by adding sophisticated features such as dynamic styling - the text would automatically change its color and font size based on the number of characters entered. For instance, when the character count exceeded certain thresholds, the display would transition through different visual states, showcasing JavaScript's ability to create responsive and interactive user experiences. Through this hands-on project, I gained a solid understanding of JavaScript's basic principles, including event listeners, conditional statements, and dynamic styling modifications.

image.png

The second Colour is below

image.png

This is the 3rd Colour .

image.png

Below i have attached the Code that i have used . where i have used Html for the styling and the javascript for quick responsive .

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Interactive Header</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            margin-top: 50px;
        }
        input {
            margin: 10px;
            padding: 5px;
        }
        button {
            padding: 5px 10px;
        }
    </style>
</head>
<body>
    <h1 id="header">My Name is <span id="name">Abin</span></h1>
    <input type="text" id="inputBox" placeholder="Type your name here..." />
    <button id="updateButton">Click Me</button>

    <script>
        let port;
        let write;
        let reader;

        async function name(params) {

        }
        const nameSpan = document.getElementById('name'); 
        const inputBox = document.getElementById('inputBox');

        // Update only the name part in real-time as the user types
        inputBox.addEventListener('input', function(e) {
            const inputValue = inputBox.value;
            nameSpan.textContent = inputValue.trim() !== "" ? inputValue : "Abin";
            if (inputBox.value.length > 10) {
            document.getElementById("name").style.color = "red";
            document.getElementById("name").style.fontSize = "2em";
        } else if (inputBox.value.length > 5) {
            document.getElementById("name").style.color = "black";
            document.getElementById("name").style.fontSize = "1em";
        } else {
            document.getElementById("name").style.color = "green";
            document.getElementById("name").style.fontSize = "1.5em";
        }
        });


    </script>
</body>
</html>

In the Above code, the span element helps to isolate and target specific portions of text within the HTML document. It acts as a container that allows us to apply unique styling and JavaScript functionality to just the name portion of the text, without affecting the surrounding content. This selective targeting enables dynamic updates and real-time style changes to occur specifically on the name text while maintaining the structure of the rest of the heading.

WEBSERIAL AND OLED INSTANT DISPLAY

For my assignment this week, I decided to create an innovative project utilizing WebSerial communication protocol. The project focused on developing an interactive system where users could input text through a customized input box on a web interface. What made this particularly interesting was the real-time functionality - as users typed their text into the input box, it would be instantly transmitted and displayed on an OLED screen connected to the microcontroller. This implementation demonstrated the seamless integration between web technologies and embedded hardware, showcasing how modern interfaces can directly interact with physical displays in real-time.

image.png

#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET    -1
#define I2C_SDA 21
#define I2C_SCL 22

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// WiFi credentials
const char* ssid = "FabGuest";
const char* password = "4fabGUEST";

// Web server running on port 80
AsyncWebServer server(80);

// Variable to store current text
String oledText = "Hello, ESP32!";

// HTML page
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <title>ESP32 OLED Live Text</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    body { font-family: Arial; background: #222; color: #fff; text-align: center; }
    input[type=text] { width: 60%%; padding: 10px; font-size: 1.2em; border-radius: 5px; border: none; }
    button { padding: 10px 20px; font-size: 1.2em; border-radius: 5px; border: none; background: #4CAF50; color: #fff; }
    .container { margin-top: 50px; }
    .oled-preview { margin-top: 30px; font-size: 1.3em; color: #FFD700; }
  </style>
</head>
<body>
  <div class="container">
    <h2>Send Text to OLED</h2>
    <form id="oledForm">
      <input type="text" id="oledInput" placeholder="Type here..." maxlength="32" required>
      <button type="submit">Send</button>
    </form>
    <div class="oled-preview" id="oledPreview"></div>
  </div>
  <script>
    document.getElementById('oledForm').onsubmit = function(e){
      e.preventDefault();
      var text = document.getElementById('oledInput').value;
      fetch('/update?text=' + encodeURIComponent(text))
        .then(response => response.text())
        .then(data => {
          document.getElementById('oledPreview').innerText = 'OLED: ' + text;
        });
      document.getElementById('oledInput').value = '';
    }
  </script>
</body>
</html>
)rawliteral";

void setup() {
  Serial.begin(115200);
  Wire.begin(I2C_SDA, I2C_SCL);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("SSD1306 allocation failed");
    for(;;);
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Connecting WiFi...");
  display.display();

  WiFi.begin(ssid, password);
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  display.clearDisplay();
  display.setCursor(0,0);
  display.println("WiFi Connected!");
  Serial.println(WiFi.localIP());
  display.display();
  delay(1000);

  // Serve HTML page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });

  // Handle text update
  server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
    if(request->hasParam("text")) {
      oledText = request->getParam("text")->value();
      updateOLED(oledText);
      request->send(200, "text/plain", "OK");
    } else {
      request->send(400, "text/plain", "Missing text");
    }
  });

  server.begin();
  updateOLED(oledText);
}

void loop() {
  // Nothing needed here
}

void updateOLED(String text) {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Current Text:");
  display.setTextSize(2);
  display.setCursor(0, 20);
  display.println(text);
  display.display();
}

KODULAR

Kodular is a visual, drag-and-drop app development platform that enables users to create fully functional Android applications without the need for traditional coding. It provides a user-friendly interface where components can be arranged on a virtual screen and programmed using block-based logic, similar to MIT App Inventor. Kodular supports integration with various hardware and web services, making it ideal for rapid prototyping of IoT projects, educational tools, and custom productivity apps. Its extensive component library and active community make it accessible for both beginners and experienced developers looking to quickly build and deploy mobile applications.

Write now i am working with making a app using kodular .

You could align the buttons to center first after using layouts . and in layouts using vertical and making the settings as shown below .

After This when You Add buttons It would be Centered By itself .

This is the block Structure that i have formulated to send the Tasks , Date and Time Via Http protocol . So i Receive the Output in Oled .

image.png

#include <WiFi.h>
#include <WebServer.h>  // Use the basic WebServer library for simplicity

const char* ssid = "FabGuest";
const char* password = "4fabGUEST";

WebServer server(80);

void handleUpdate() {
  String task = "";
  String date = "";
  String timeStr = "";

  if (server.hasArg("task")) task = server.arg("task");
  if (server.hasArg("date")) date = server.arg("date");
  if (server.hasArg("time")) timeStr = server.arg("time");

  Serial.println("Received HTTP GET /update");
  Serial.print("Task: ");
  Serial.println(task);
  Serial.print("Date: ");
  Serial.println(date);
  Serial.print("Time: ");
  Serial.println(timeStr);
  Serial.println("----------------------");

  server.send(200, "text/plain", "OK");
}

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("Connecting to WiFi...");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi connected! IP address: ");
  Serial.println(WiFi.localIP());

  server.on("/update", handleUpdate);
  server.begin();
  Serial.println("HTTP server started");
}

void loop() {
  server.handleClient();
}
Below i have attached the Realtime Working Video of the Project .

CONCLUSION

During Week 16, I explored various interface and application programming techniques to enable communication between the ESP32 and both web and mobile interfaces. I experimented with Serial, WebSerial, and HTTP protocols, successfully sending and receiving data between the ESP32 and a browser using WebSerial, as well as between the ESP32 and a custom Kodular app via HTTP GET requests. I learned how to create interactive web interfaces using JavaScript, which allowed real-time updates to be displayed on an OLED screen connected to the ESP32. Additionally, I compared the advantages and limitations of synchronous (WebServer) and asynchronous (AsyncWebServer) web servers, gaining insights into their impact on hardware interactions, especially with I2C devices. This week’s work strengthened my understanding of integrating embedded hardware with modern user interfaces, emphasizing the importance of protocol selection, real-time feedback, and robust system design for responsive IoT applications.

FILES

PROMPTS


Last update: May 7, 2025