Inteface & Application Programming


Objectives for Week 14

  1. Write an application that interfaces a user with an input and/or output device that I made
  2. Group Assignment:
    • Compare as many tool options as possible

This week was about creating an interface with any of the boards I have created so far. Since, it was an area I had no prior experience in, our instructor, Midlaj helped me out through the process.

The next day after the global class, we had a brief session by Midlaj and Jogin, where they explained the basics of creating digital interface. After the session, Midlaj, showed us how a webpage can be created and showcased an example with ESP32 development board. We all tried our hands in creating a webpage right after.

I seeked help from an extension in Visual Studio Code called Cody AI to generate the code. I found the extension to be really helpful.

CodyAI

I made a simple code for a webpage that has two buttons, where, one button is for connecting the port and the other for "ON" and "OFF" condition. It also has a serial text area. Below showcases the elements I have created.

LED Toggle

To use, first, upload a code for "ON" and "OFF" condition for an LED in your board. Once uploaded, click on "Connection" button and select the port. Click on "ON" and "OFF" to see your LED lit up and off.

I used my Quentorres board for the purpose. Code for the Quentorres board is as below. You can download the code I have created for the webpage from the bottom of the page.

        #include < Arduino.h>
        int LED = 1;
            
        void setup() {
            pinMode(LED, OUTPUT);
            Serial.begin(9600);
        }
            
        void loop() {
            if (Serial.available() > 0) {
                char condition = Serial.read();
                if (condition == '1') {
                  digitalWrite(LED, HIGH);
                  Serial.println("The LED is now ON");
                } else if (condition == '0') {
                  digitalWrite(LED, LOW);
                  Serial.println("The LED is now OFF");
                }
            }
        }  
    

Explanation




WebSerial Control for DC Motors

The objective of this week was to take the boards I have created for the Communication week and to make an interface for the same. Since, I have done the process during Communication week, I already have the codes. I only had to do some modifications in order to accomodate the button features in the webpage.

Master

Master PCB with SAMD11C14A MC


Nodes

Node PCBs with ATtiny412 MC and A4953 Motor Driver

Refer documentation of Week 13 to know about the boards I have created and the connections I have done in order to communicate between the boards.

Task: To run the DC Motors in forward and reverse direction as per the buttons pressed and also the LEDs on corresponding Nodes lit up when motors are in motions.

Webpage

Master PCB Code

  // Define the motor driver control pins
const int motorPin1 = 27;  // IN1 connected to GPIO 18
const int motorPin2 = 14;  // IN2 connected to GPIO 19

void setup() {
  // Initialize serial communication at 115200 baud rate for debugging
  Serial.begin(115200);

  // Initialize the motor control pins as outputs
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);

  // Start with the motor stopped
  stopMotor();
}

void loop() {
  // Run the motor forward for 5 seconds
  Serial.println("Running motor forward");
  runMotorForward();
  delay(500);

  // Stop the motor for 2 seconds
  Serial.println("Stopping motor");
  stopMotor();
  delay(200);

  // Run the motor backward for 5 seconds
  Serial.println("Running motor backward");
  runMotorBackward();
  delay(500);

  // Stop the motor for 2 seconds
  Serial.println("Stopping motor");
  stopMotor();
  delay(2000);
}

void runMotorForward() {
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
}

void runMotorBackward() {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
}

void stopMotor() {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
}

Explanation

Node PCB Code

    #include 
      #include 
      #define LED_PIN 4
      void setup() {
        pinMode(LED_PIN, OUTPUT);
        pinMode(0, OUTPUT);  // Motor output 1
        pinMode(1, OUTPUT); 
        Wire.begin(8); 
        Wire.onReceive(receiveEvent);
      }
      
      void loop() {
        // Nothing is needed in the loop
      }
      
      void receiveEvent(int howMany) {
        while (Wire.available()) {
          int received = Wire.read(); // Read the command sent by the master
          if (received == 1) {
            digitalWrite(0, HIGH);
            digitalWrite(1, LOW);
            digitalWrite(LED_PIN, HIGH);
          } else if (received == 0) {
            digitalWrite(0, LOW);
            digitalWrite(1, LOW);
            digitalWrite(LED_PIN, LOW);
          } else {
            digitalWrite(1, HIGH);
            digitalWrite(0, LOW);
            digitalWrite(LED_PIN, HIGH);
          }
        }
      }
      
  

Explanation

The Arduino IDE code for the Master and 2 Nodes PCB are available to download at the bottom of the page.

Connections
Connections

For the interface, I chose Web Serial API. It is a web standard that enables websites to communicate with serial devices. This can be very useful for applications that need to interact with custom hardware, scientific instruments, or other devices that utilize serial communication. The Web Serial API is part of the Web APIs available in modern browsers, providing a way for web applications to access serial ports, including devices connected via USB, allowing direct communication with a wide range of devices from within the web browser.

Features of Web Serial API

With the help of Cody AI in Visual Studio Code, I created an HTML code for the Webpage. I made a simple page with the necessary buttons and required port access. The code for the page is available to download.

Webpage
<!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>WebSerial Motor Control</title>
    <style>
      body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        margin: 0;
        font-family: "Bell MT", sans-serif;
      }
      .container {
        background-color: rgb(165, 165, 166);
        padding: 20px;
        border-radius: 10px;
        text-align: center;
      }
      button {
        width: 80px;
        height: 40px;
        font-size: 16px;
        font-family: "Bell MT", sans-serif;
      }
      .forward {
        background-color: green;
        color: white;
        border-radius: 20px;
      }
      .reverse {
        background-color: blue;
        color: white;
        border-radius: 20px;
      }
      .stop {
        background-color: red;
        color: white;
        width: 60px;
        height: 60px;
        border-radius: 50%;
      }
      .connect {
        background-color: black;
        color: white;
        width: 150px;
        height: 40px;
        border-radius: 5px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <h1>WebSerial Control for DC Motors</h1>
      <button class="connect" onclick="connectSerial()">
        Connect to Device
      </button>
  
      <h2>Motor 1</h2>
      <button class="forward" onclick="sendCommand('Q')">Forward</button>
      <button class="reverse" onclick="sendCommand('R')">Reverse</button>
      <button class="stop" onclick="sendCommand('P')">STOP</button>
      <h2>Motor 2</h2>
      <button class="forward" onclick="sendCommand('G')">Forward</button>
      <button class="reverse" onclick="sendCommand('H')">Reverse</button>
      <button class="stop" onclick="sendCommand('F')">STOP</button>
  
      <script>
        let port;
        let writer;
  
        async function connectSerial() {
          if ("serial" in navigator) {
            try {
              const requestOptions = { baudRate: 9600 };
              port = await navigator.serial.requestPort();
              await port.open(requestOptions);
  
              const textEncoder = new TextEncoderStream();
              const writableStreamClosed = textEncoder.readable.pipeTo(
                port.writable
              );
  
              writer = textEncoder.writable.getWriter();
              console.log("Connected");
            } catch (err) {
              console.error("There was an error opening the serial port:", err);
            }
          } else {
            console.error("Web Serial API not supported.");
          }
        }
  
        async function sendCommand(command) {
          if (!writer) {
            console.log("Serial port not connected");
            return;
          }
          await writer.write(command + "\n");
          console.log("Sent command:", command);
        }
      </script>
    </div>
  </body>
  </html>
  

Explanation

Click here to view the webpage I have created.

Webpage

In the page, click on "Connect to Device" to select the port and click your button of choice to run the motor forward, reverse and finally stop.

Webpage

Here's the result.



Group Assignment

This week's group assingment was to compare as many application tools available. Communication

For further details, click on the link below.

Group Assignment-Week 14



Download Files

LED Toggle (HTML Code)DC Motor WebSerial (HTML Code)DC Motor WebSerial (zip)