Skip to content

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 that interfaces a user with an input and/or output device(s) on a board that you made.

Learning outcomes

  • Implement a User Interface (UI) using programming and explore protocols to communicate with an embedded board.

As usual here is my timetable:

Group Assignment

Reflection

This week, we learned how to create apps and interfaces for microcontroller boards. Interfaces help hardware and software talk to each other smoothly. We tried out tools like web servers and MIT App Inventor in our group project. With an ESP32 board, LEDs, and a servo, we made a web server that works on phones and lets you control things from a browser. I figured out how to set up networks, put code on the board, and fix problems. It’s cool to see how tech can make things easy to use and work together nicely.

Click here to view our group assignment

Individual Assignment

Hero shot!!

This week’s assignment was to make an application that interfaces a user with an input and/ or output device that we made. So I will be doing a part of my final project for this week’s asssignment and also control a servo motor through the webserver I will be hosting.

SO let’s start with taking in inputs from the webserver and displaying a random topic upon pressing the button. I only learnt this week that I cannot store data from the webserver so I will be adding a sd card module for my final project.

SO this code is basically an edited version from the previous display I did on the serial monitor. Here is the code:

#include <Arduino.h>
#include <WiFi.h> // Use WiFi.h library for ESP32-C3
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

AsyncWebServer server(80);

// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "your-ssid";
const char* password = "your-ssid-password";

const char* PARAM_INPUT = "input";

// OLED settings
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET    -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Button pin
#define BUTTON_PIN 3

// Define maximum number of input messages to store
#define MAX_MESSAGES 10

// Array to store input messages
String messages[MAX_MESSAGES];

// Variables to track number of stored messages
int numMessages = 0;

bool buttonPressed = false;

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}

void setup() {
  Serial.begin(115200);
  Wire.begin();

  pinMode(BUTTON_PIN, INPUT_PULLUP);

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  display.clearDisplay();
  display.display();

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult()!= WL_CONNECTED) {
    Serial.println("WiFi Failed!");
    return;
  }
  Serial.println();
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  // Send web page with input fields to client
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(200, "text/html", "<form action='/get' method='get'>"
                                     "Input: <input type='text' name='input'><br>"
                                     "<input type='submit' value='Submit'></form>");
  });

  // Send a GET request to <ESP_IP>/get?input=<inputMessage>
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
    // Get input message and store it
    if (request->hasParam(PARAM_INPUT)) {
      storeMessage(request->getParam(PARAM_INPUT)->value());
    }

    // Send response to client without displaying the message
    request->send(200, "text/html", "Data received. Press the button to display.");
  });

  server.onNotFound(notFound);
  server.begin();
}

void loop() {
  // Check if the button is pressed
  if (digitalRead(BUTTON_PIN) == LOW) {
    buttonPressed = false;
    delay(1000); // Add debounce delay if needed
  }

  // Display random message only if the button is pressed
 if (digitalRead(BUTTON_PIN) == HIGH) {
    displayRandomMessage();
    buttonPressed = true; // Reset buttonPressed flag after displaying message
  }
}

void storeMessage(String message) {
  // Check if there's still space in the array to store the message
  if (numMessages < MAX_MESSAGES) {
    // Store the message in the array
    messages[numMessages++] = message;}
}

void displayRandomMessage() {
  if (buttonPressed && numMessages > 0) {
    int randomIndex = random(0, numMessages);
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(0, 0);
    display.println("Message:");
    display.println(messages[randomIndex]);
    display.display();
    buttonPressed = true; // Reset buttonPressed flag after displaying message
  } else {
    Serial.println("No messages to display.");
  }
}      

Code Explanation:

SO the webserver was setup using basic HTML coding. It inlcudes a form (‘

‘) with a text box (‘‘) where I can type in the topics. And to send the topic to the xiao esp 32c3, there is a button (‘‘).

When the “Submit” button is pressed, it checks if there is any text in the box (‘hasParam(PARAM_INPUT)’), and if so, it saves it and then sends back a message to the brower saying “Data received. Press the button to display”.

And Since I already explained how to add the required libraries in the previous weeks, I will not be including the addition process of the libraries. So here is the output!

I then tried to control a servo motor through the webserver. I was able to control the movement of the servo such that I was able to move them either 0 degrees or 180 degrees. I used html to create the webserver. And since I am using xiao esp 32 c3 (An esp), a different esp servo library is required for controlling the servo.

SO use this link to download the lTheibrary like this:

Then include the library like this : go to sketch -> include libraries -> add zip files -> add the zip file you downlaoded you eariler:

Then, if you want to run a test code for the servo motor, go to files -> examples -> scroll to esp servo -> sweep(or any other examples).

So here is the code(Example code from the servo motor library) for the servo control through the webserver:

#include <WiFi.h>
#include <ESP32Servo.h>

const char* ssid = "your-hotspot-ssid";     // Your mobile hotspot SSID
const char* password = "your-hotspot-password"; // Your mobile hotspot password

Servo myservo;  // create servo object to control a servo
int pos = 0;    // variable to store the servo position
int servoPin = 3; // PWM GPIO pin connected to the servo

WiFiServer server(80); // Create a webserver object that listens on port 80

void setup() {
  Serial.begin(115200);

  // Connect to Wi-Fi
  Serial.println("Connecting to WiFi");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting...");
  }
  Serial.println("Connected to WiFi");

  // Print ESP32-C3's IP address
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  // Initialize servo
  myservo.attach(servoPin, 1000, 2000); // attaches the servo to the servo object

  // Start the server
  server.begin();
  Serial.println("Server started");
}

void loop() {
  WiFiClient client = server.available(); // Check for incoming clients

  if (client) { // If a new client connects
    Serial.println("New client connected");
    while (client.connected()) { // Loop while the client is connected
      if (client.available()) { // If there's data from the client
        String request = client.readStringUntil('\r'); // Read the request until newline character

        if (request.indexOf("/0") != -1) { // If the request contains "/0"
          // Move servo to position 0 degrees
          myservo.write(0);
          delay(15); // Wait for the servo to reach the position
        } else if (request.indexOf("/180") != -1) { // If the request contains "/180"
          // Move servo to position 180 degrees
          myservo.write(180);
          delay(15); // Wait for the servo to reach the position
        }

        // Send HTTP response with HTML content
        client.println("HTTP/1.1 200 OK");
        client.println("Content-type:text/html");
        client.println();
        client.println("<html><head><title>Servo Control</title></head><body>");
        client.println("<h1>Servo Control</h1>");
        client.println("<p>Click the buttons below to control the servo motor:</p>");
        client.println("<form action='/0'><button type='submit'>Move to 0 degrees</button></form>");
        client.println("<form action='/180'><button type='submit'>Move to 180 degrees</button></form>");
        client.println("</body></html>");
        break;
      }
    }
    client.stop(); // Disconnect the client
    Serial.println("Client disconnected");
  }
}

And here is the output:

Reflecion

This week’s assignment was really cool and a bit challenging. I learned how to set up a web server on the ESP32 using simple HTML. This means I could create a webpage with a text box and a submit button so users can send messages to the ESP32. I found out that while I can capture and save these messages, the ESP32 alone isn’t great for storing data long-term, so I’ll need to add an SD card for my final project.

I also adapted some of my previous code to display random messages on an OLED screen when a button is pressed. Plus, I managed to control a servo motor through the web server, making it move to specific angles when I clicked buttons on the webpage. This week really helped me understand how to create interfaces between web pages and hardware devices.

Files

THAT’S OT FOR THIS WEEK !!!

HAVE A NICE DAY!


Last update: June 25, 2024