Skip to content

14. Interface and application programming

Hero Shot

Assignment :

individual assignment:

  • write an application that interfaces a user with an input &/or output device that you made

group assignment:

  • compare as many tool options as possible

Group assignment

You can find our group page here and this week group assignement here

Individual assignment

New start

For this week, I started by making a new board with XIAO ESP32S3 as my previous was not working anymore.

It works for some time but rapidly I had difficulties to upload programs, then the board systematically turned off after about 30s and finally I couldn’t upload anything.

Facing this, I decided to use my previous board from week 09.

Interface programming

I didn’t know where to start. I had a vague idea of an interface showing the two components of my final project inputs: the mood scale and the interaction acceptance scale.

I decided to tried Node-Red but I didn’t understand really why I was here for.

I make a try at Python and added the extension for VS code.

I took some online courses on openclassroom (in French).
I had some difficulties to get pip command working correctly but I finally could make it work using Shqush.io tutorial.

Soon enough, I figured that wasn’t what I needed for my project.

Being a little more familiar with html and css, I finally decided to make an html page. I also used chatGPT to help with the CSS adn to implement javascript programming little by little.

The first code only display a table of all the images needed for my project. I took the opportunity to rename all my images to facilitate programming. I used the rows for mood with units and columns for acceptance with tens. The addition of two set a position for a mixed smiley.

With help of chat GPT, I set a part to just define the inputs with displaying only one image of each scales and selecting it with buttons. I also add values for each images in the array.

After that, I implemented another part of script to add the values then make it display the mixed image that correspond. At first, the code added the images next to the previous one and needed to clear previous result.

<table>
    <caption>
        Mindset device
    </caption>
    <thead>
        <tr>
            <th scope="col">acceptance\mood</th>
            <th scope="col"><img src="01_smiley.jpg" width="50" /></th>
            <th scope="col"><img src="02_smiley.jpg" width="50"/></th>
            <th scope="col"><img src="03_smiley.jpg" width="50"/></th>
            <th scope="col"><img src="04_smiley.jpg" width="50"/></th>
            <th scope="col"><img src="05_smiley.jpg" width="50"/></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th scope="row"><img src="10_smiley.jpg" width="50"/></th>
            <td><img src="smiley_mix11.jpg" width="50"/></td>
            <td><img src="smiley_mix12.jpg" width="50"/></td>
            <td><img src="smiley_mix13.jpg" width="50"/></td>
            <td><img src="smiley_mix14.jpg" width="50"/></td>
            <td><img src="smiley_mix15.jpg" width="50"/></td>
        </tr>
        <tr>
            <th scope="row"><img src="20_smiley.jpg" width="50" /></th>
            <td><img src="smiley_mix21.jpg" width="50"/></td>
            <td><img src="smiley_mix22.jpg" width="50"/></td>
            <td><img src="smiley_mix23.jpg" width="50"/></td>
            <td><img src="smiley_mix24.jpg" width="50"/></td>
            <td><img src="smiley_mix25.jpg" width="50"/></td>
        </tr>
        <tr>
            <th scope="row"><img src="30_smiley.jpg" width="50"/></th>
            <td><img src="smiley_mix31.jpg" width="50"/></td>
            <td><img src="smiley_mix32.jpg" width="50"/></td>
            <td><img src="smiley_mix33.jpg" width="50"/></td>
            <td><img src="smiley_mix34.jpg" width="50"/></td>
            <td><img src="smiley_mix35.jpg" width="50"/></td>
        </tr>
        <tr>
            <th scope="row"><img src="40_smiley.jpg" width="50"/></th>
            <td><img src="smiley_mix41.jpg" width="50"/></td>
            <td><img src="smiley_mix42.jpg" width="50"/></td>
            <td><img src="smiley_mix43.jpg" width="50"/></td>
            <td><img src="smiley_mix44.jpg" width="50"/></td>
            <td><img src="smiley_mix45.jpg" width="50"/></td>
        </tr>
        <tr>
            <th scope="row"><img src="50_smiley.jpg" width="50"/></th>
            <td><img src="smiley_mix51.jpg" width="50"/></td>
            <td><img src="smiley_mix52.jpg" width="50"/></td>
            <td><img src="smiley_mix53.jpg" width="50"/></td>
            <td><img src="smiley_mix54.jpg" width="50"/></td>
            <td><img src="smiley_mix55.jpg" width="50"/></td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <th scope="row" colspan="2">Chosen mindset</th>
            <td></td>
        </tr>
    </tfoot>
</table>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Mindset Selector</title>
        <style>
            .container {
                display: flex;
                justify-content: space-around;
                margin-bottom: 20px;
            }
            .image-container {
                text-align: center;
            }
            .image-container img {
                max-width: 100%;
                max-height: 400px;
            }
            .btn-container {
                text-align: center;
                margin-bottom: 20px;
            }
            .btn {
                padding: 10px 20px;
                background-color: #007bff;
                color: #fff;
                border: none;
                cursor: pointer;
                margin: 0 10px; /* Add some spacing between buttons */
            }
        </style>
    </head>
    <body>

    <div class="container">
        <div class="image-container">
            <div id="image-container1">
                <img src="03_smiley.jpg" alt="Image" data-value="3">
            </div>
            <div class="btn-container">
                <button class="btn" onclick="previousImage(1)">Previous</button>
                <button class="btn" onclick="nextImage(1)">Next</button>
            </div>
        </div>
        <div class="image-container">
            <div id="image-container2">
                <img src="30_smiley.jpg" alt="Image" data-value="30">
            </div>
            <div class="btn-container">
                <button class="btn" onclick="previousImage(2)">Previous</button>
                <button class="btn" onclick="nextImage(2)">Next</button>
            </div>
        </div>
    </div>


    <script>
        var currentIndex1 = 2; // Index for the first image array
        var currentIndex2 = 2; // Index for the second image array
        var images1 = ["01_smiley.jpg", "02_smiley.jpg", "03_smiley.jpg", "04_smiley.jpg", "05_smiley.jpg"];
        var images2 = ["10_smiley.jpg", "20_smiley.jpg", "30_smiley.jpg", "40_smiley.jpg", "50_smiley.jpg"];
        var values1 = [1, 2, 3, 4, 5];
        var values2 = [10, 20, 30, 40, 50];

        function previousImage(containerIndex) {
            if (containerIndex === 1) {
                if (currentIndex1 === 0) {
                    return; // Do nothing if already at the first image
                }
                currentIndex1--;
                updateImage(1);
            } else if (containerIndex === 2) {
                if (currentIndex2 === 0) {
                    return; // Do nothing if already at the first image
                }
                currentIndex2--;
                updateImage(2);
            }
        }

        function nextImage(containerIndex) {
            if (containerIndex === 1) {
                if (currentIndex1 === images1.length - 1) {
                    return; // Do nothing if already at the last image
                }
                currentIndex1++;
                updateImage(1);
            } else if (containerIndex === 2) {
                if (currentIndex2 === images2.length - 1) {
                    return; // Do nothing if already at the last image
                }
                currentIndex2++;
                updateImage(2);
            }
        }

        function updateImage(containerIndex) {
            var displayedImage;
            if (containerIndex === 1) {
                displayedImage = document.getElementById("image-container1").getElementsByTagName("img")[0];
                displayedImage.src = images1[currentIndex1];            
                displayedImage.dataset.value = values1[currentIndex1];
            } else if (containerIndex === 2) {
                displayedImage = document.getElementById("image-container2").getElementsByTagName("img")[0];
                displayedImage.src = images2[currentIndex2];            
                displayedImage.dataset.value = values2[currentIndex2];
            }
        }
    </script>

    </body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mindset Selector</title>
    <style>
        .container {
            display: flex;
            justify-content: space-around;
            margin-bottom: 20px;
        }
        .image-container {
            text-align: center;
        }
        .image-container img {
            max-width: 100%;
            max-height: 400px;
        }
        .btn-container {
            text-align: center;
            margin-bottom: 20px;
        }
        .btn {
            padding: 10px 20px;
            background-color: #007bff;
            color: #fff;
            border: none;
            cursor: pointer;
            margin: 0 10px; /* Add some spacing between buttons */
        }
        #result-container {
            text-align: center;
            margin-top: 20px;
        }
    </style>
</head>
<body>

<div class="container">
    <div class="image-container">
        <div id="image-container1">
            <img src="03_smiley.jpg" alt="Image" data-value="3">
        </div>
        <div class="btn-container">
            <button class="btn" onclick="previousImage(1)">Previous</button>
            <button class="btn" onclick="nextImage(1)">Next</button>
        </div>
    </div>
    <div class="image-container">
        <div id="image-container2">
            <img src="30_smiley.jpg" alt="Image" data-value="30">
        </div>
        <div class="btn-container">
            <button class="btn" onclick="previousImage(2)">Previous</button>
            <button class="btn" onclick="nextImage(2)">Next</button>
        </div>
    </div>
</div>

<div id="result-container">
    <button class="btn" onclick="addValues()">Add Values</button>
    <div id="result"></div>
</div>

<script>
    var currentIndex1 = 2; // Index for the first image array
    var currentIndex2 = 2; // Index for the second image array
    var images1 = ["01_smiley.jpg", "02_smiley.jpg", "03_smiley.jpg", "04_smiley.jpg", "05_smiley.jpg"];
    var images2 = ["10_smiley.jpg", "20_smiley.jpg", "30_smiley.jpg", "40_smiley.jpg", "50_smiley.jpg"];
    var values1 = [1, 2, 3, 4, 5];
    var values2 = [10, 20, 30, 40, 50];
    var allImages = [
        { src: "smiley_mix11.jpg", value: 11 },
        { src: "smiley_mix12.jpg", value: 12 },
        { src: "smiley_mix13.jpg", value: 13 },
        { src: "smiley_mix14.jpg", value: 14 },
        { src: "smiley_mix15.jpg", value: 15 },
        { src: "smiley_mix21.jpg", value: 21 },
        { src: "smiley_mix22.jpg", value: 22 },
        { src: "smiley_mix23.jpg", value: 23 },
        { src: "smiley_mix24.jpg", value: 24 },
        { src: "smiley_mix25.jpg", value: 25 },
        { src: "smiley_mix31.jpg", value: 31 },
        { src: "smiley_mix32.jpg", value: 32 },
        { src: "smiley_mix33.jpg", value: 33 },
        { src: "smiley_mix34.jpg", value: 34 },
        { src: "smiley_mix35.jpg", value: 35 },
        { src: "smiley_mix41.jpg", value: 41 },
        { src: "smiley_mix42.jpg", value: 42 },
        { src: "smiley_mix43.jpg", value: 43 },
        { src: "smiley_mix44.jpg", value: 44 },
        { src: "smiley_mix45.jpg", value: 45 },
        { src: "smiley_mix51.jpg", value: 51 },
        { src: "smiley_mix52.jpg", value: 52 },
        { src: "smiley_mix53.jpg", value: 53 },
        { src: "smiley_mix54.jpg", value: 54 },
        { src: "smiley_mix55.jpg", value: 55 },
    ];

    function previousImage(containerIndex) {
        if (containerIndex === 1) {
            if (currentIndex1 === 0) {
                return; // Do nothing if already at the first image
            }
            currentIndex1--;
            updateImage(1);
        } else if (containerIndex === 2) {
            if (currentIndex2 === 0) {
                return; // Do nothing if already at the first image
            }
            currentIndex2--;
            updateImage(2);
        }
    }

    function nextImage(containerIndex) {
        if (containerIndex === 1) {
            if (currentIndex1 === images1.length - 1) {
                return; // Do nothing if already at the last image
            }
            currentIndex1++;
            updateImage(1);
        } else if (containerIndex === 2) {
            if (currentIndex2 === images2.length - 1) {
                return; // Do nothing if already at the last image
            }
            currentIndex2++;
            updateImage(2);
        }
    }

    function updateImage(containerIndex) {
        var displayedImage;
        if (containerIndex === 1) {
            displayedImage = document.getElementById("image-container1").getElementsByTagName("img")[0];
            displayedImage.src = images1[currentIndex1];            
            displayedImage.dataset.value = values1[currentIndex1];
        } else if (containerIndex === 2) {
            displayedImage = document.getElementById("image-container2").getElementsByTagName("img")[0];
            displayedImage.src = images2[currentIndex2];            
            displayedImage.dataset.value = values2[currentIndex2];
        }
    }

    function addValues() {
    var value1 = values1[currentIndex1];
    var value2 = values2[currentIndex2];
    var result = value1 + value2;

    // Find the image object with the matching value
    var resultImage = allImages.find(function(image) {
        return image.value === result;
    });

    if (resultImage) {
        var resultImageSrc = resultImage.src;
        var resultImageValue = resultImage.value; // Get the personalized value
        document.getElementById("result").innerText = "Result: " + result + " (" + resultImageValue + ")";
        document.getElementById("result-container").innerHTML += "<img src='" + resultImageSrc + "' alt='Result Image'>";
    } else {
        document.getElementById("result").innerText = "Result: Invalid";
    }
}

</script>

</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0">
    <title>Mindset Selector</title>
    <style>
        .container {
            display: flex;
            justify-content: space-around;
            margin-bottom: 20px;
            max-height: 20%;
        }
        .image-container {
            text-align: center;
        }
        .image-container img {
            max-width: 100%;
            max-height: 100px;
        }
        .btn-container {
            text-align: center;
            margin-bottom: 20px;
        }
        .btn {
            padding: 10px 20px;
            background-color: #007bff;
            color: #fff;
            border: none;
            cursor: pointer;
            margin: 0 10px; /* Add some spacing between buttons */
        }
        #result-container {
            text-align: center;
            margin-top: 20px;
        }
        #result-button-container {
            text-align: center;
            margin-bottom: 20px;
        }
        #result-image {
            max-width: 20%; /* Adjust the maximum width of the result image container */
            margin: 0 auto; /* Center the result image horizontally */
        }
        #result-image img {
            max-width: 100%; /* Ensure the result image fits within its container */
            height: auto; /* Maintain aspect ratio */
        }
    </style>
</head>
<body>

<div class="container">
    <div class="image-container">
        <h2>Mood</h2>
        <div id="image-container1">
            <img src="03_smiley.jpg" alt="Image" data-value="3">
        </div>
        <div class="btn-container">
            <button class="btn" onclick="previousImage(1)">Previous</button>
            <button class="btn" onclick="nextImage(1)">Next</button>
        </div>
    </div>
    <div class="image-container">
        <h2>Interaction acceptance</h2>
        <div id="image-container2">
            <img src="30_smiley.jpg" alt="Image" data-value="30">
        </div>
        <div class="btn-container">
            <button class="btn" onclick="previousImage(2)">Previous</button>
            <button class="btn" onclick="nextImage(2)">Next</button>
        </div>
    </div>
</div>

<div id="result-button-container">
    <button class="btn" onclick="addValues()">Set</button>
</div>

<div id="result-container">
    <h2>Mindset</h2>
    <div id="result-text"></div> 
    <div id="result-image"></div>
</div>

<script>
    var currentIndex1 = 2; // Index for the first image array
    var currentIndex2 = 2; // Index for the second image array
    var images1 = ["05_smiley.jpg", "04_smiley.jpg", "03_smiley.jpg","02_smiley.jpg", "01_smiley.jpg"];
    var images2 = ["50_smiley.jpg", "40_smiley.jpg", "30_smiley.jpg", "20_smiley.jpg", "10_smiley.jpg"];
    var values1 = [5, 4, 3, 2, 1];
    var values2 = [50, 40, 30, 20, 10];
    var allImages = [
        { src: "smiley_mix11.jpg", value: 11 },
        { src: "smiley_mix12.jpg", value: 12 },
        { src: "smiley_mix13.jpg", value: 13 },
        { src: "smiley_mix14.jpg", value: 14 },
        { src: "smiley_mix15.jpg", value: 15 },
        { src: "smiley_mix21.jpg", value: 21 },
        { src: "smiley_mix22.jpg", value: 22 },
        { src: "smiley_mix23.jpg", value: 23 },
        { src: "smiley_mix24.jpg", value: 24 },
        { src: "smiley_mix25.jpg", value: 25 },
        { src: "smiley_mix31.jpg", value: 31 },
        { src: "smiley_mix32.jpg", value: 32 },
        { src: "smiley_mix33.jpg", value: 33 },
        { src: "smiley_mix34.jpg", value: 34 },
        { src: "smiley_mix35.jpg", value: 35 },
        { src: "smiley_mix41.jpg", value: 41 },
        { src: "smiley_mix42.jpg", value: 42 },
        { src: "smiley_mix43.jpg", value: 43 },
        { src: "smiley_mix44.jpg", value: 44 },
        { src: "smiley_mix45.jpg", value: 45 },
        { src: "smiley_mix51.jpg", value: 51 },
        { src: "smiley_mix52.jpg", value: 52 },
        { src: "smiley_mix53.jpg", value: 53 },
        { src: "smiley_mix54.jpg", value: 54 },
        { src: "smiley_mix55.jpg", value: 55 },
    ];

    function previousImage(containerIndex) {
        if (containerIndex === 1) {
            if (currentIndex1 === 0) {
                return; // Do nothing if already at the first image
            }
            currentIndex1--;
            updateImage(1);
        } else if (containerIndex === 2) {
            if (currentIndex2 === 0) {
                return; // Do nothing if already at the first image
            }
            currentIndex2--;
            updateImage(2);
        }
    }

    function nextImage(containerIndex) {
        if (containerIndex === 1) {
            if (currentIndex1 === images1.length - 1) {
                return; // Do nothing if already at the last image
            }
            currentIndex1++;
            updateImage(1);
        } else if (containerIndex === 2) {
            if (currentIndex2 === images2.length - 1) {
                return; // Do nothing if already at the last image
            }
            currentIndex2++;
            updateImage(2);
        }
    }

    function updateImage(containerIndex) {
        var displayedImage;
        if (containerIndex === 1) {
            displayedImage = document.getElementById("image-container1").getElementsByTagName("img")[0];
            displayedImage.src = images1[currentIndex1];            
            displayedImage.dataset.value = values1[currentIndex1];
        } else if (containerIndex === 2) {
            displayedImage = document.getElementById("image-container2").getElementsByTagName("img")[0];
            displayedImage.src = images2[currentIndex2];            
            displayedImage.dataset.value = values2[currentIndex2];
        }
    }

    function addValues() {
        var value1 = values1[currentIndex1];
        var value2 = values2[currentIndex2];
        var result = value1 + value2;

        // Find the image object with the matching value
        var resultImage = allImages.find(function(image) {
            return image.value === result;
        });

        if (resultImage) {
            var resultImageSrc = resultImage.src;
            var resultImageValue = resultImage.value; // Get the personalized value
    //        document.getElementById("result-text").innerText = "Result: " + result + " (" + resultImageValue + ")"; //
            document.getElementById("result-image").innerHTML = "<img src='" + resultImageSrc + "' alt='Result Image'>";
        } else {
            document.getElementById("result-text").innerText = "Result: Invalid";
            document.getElementById("result-image").innerHTML = ""; // Clear previous result image
        }
    }
</script>

</body>
</html>

Running script

Mindset Selector

Mood

Image

Interaction acceptance

Image

Mindset

Adding communication

As said previously my ESP32C3 and S3 boards was not working anymore so I had to find out how to make communication with RP2040. I thought that should be easy and having a quite precise idea of what information I wanted to get from the board, I didn’t worry to much about it the first days. But I find myself struggling with it despite being telled that this should be easy.

Wandering and wondering

Webserial should have been the best start but I felt quite confused by the WebSerial Library for Arduino and thought that was only for wireless communication with ESP chips.

I search for something with RP2040 compatibilty but didn’t find really relevant information. At some point, I get to WebUSB API then to tinyUSB Library that should be compatible with RP2040.

With an example of code to upload on my board, I could make a communication with an aimed website.

/*********************************************************************
 Adafruit invests time and resources providing this open source code,
 please support Adafruit and open-source hardware by purchasing
 products from Adafruit!

 MIT license, check LICENSE for more information
 Copyright (c) 2019 Ha Thach for Adafruit Industries
 All text above, and the splash screen below must be included in
 any redistribution
*********************************************************************/

/* This sketch demonstrates WebUSB as web serial with browser with WebUSB support (e.g Chrome).
 * After enumerated successfully, Browser will pop-up notification
 * with URL to landing page, click on it to test
 *  - Click "Connect" and select device, When connected the on-board LED will litted up.
 *  - Any charters received from either webusb/Serial will be echo back to webusb and Serial
 *  
 * Note: 
 * - The WebUSB landing page notification is currently disabled in Chrome 
 * on Windows due to Chromium issue 656702 (https://crbug.com/656702). You have to 
 * go to landing page (below) to test
 * 
 * - On Windows 7 and prior: You need to use Zadig tool to manually bind the 
 * WebUSB interface with the WinUSB driver for Chrome to access. From windows 8 and 10, this
 * is done automatically by firmware.
 */

#include "Adafruit_TinyUSB.h"

// USB WebUSB object
Adafruit_USBD_WebUSB usb_web;

// Landing Page: scheme (0: http, 1: https), url
// Page source can be found at https://github.com/hathach/tinyusb-webusb-page/tree/main/webusb-serial
WEBUSB_URL_DEF(landingPage, 1 /*https*/, "example.tinyusb.org/webusb-serial/index.html");

int led_pin = LED_BUILTIN;

// the setup function runs once when you press reset or power the board
void setup()
{
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
  // Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
  TinyUSB_Device_Init(0);
#endif

  pinMode(led_pin, OUTPUT);
  digitalWrite(led_pin, LOW);

  usb_web.setLandingPage(&landingPage);
  usb_web.setLineStateCallback(line_state_callback);
  //usb_web.setStringDescriptor("TinyUSB WebUSB");
  usb_web.begin();

  Serial.begin(115200);

  // wait until device mounted
  while( !TinyUSBDevice.mounted() ) delay(1);

  Serial.println("TinyUSB WebUSB Serial example");
}

// function to echo to both Serial and WebUSB
void echo_all(uint8_t buf[], uint32_t count)
{
  if (usb_web.connected())
  {
    usb_web.write(buf, count);
    usb_web.flush();
  }

  if ( Serial )
  {
    for(uint32_t i=0; i<count; i++)
    {
      Serial.write(buf[i]);
      if ( buf[i] == '\r' ) Serial.write('\n');
    }
    Serial.flush();
  }
}

void loop()
{
  uint8_t buf[64];
  uint32_t count;

  // From Serial to both Serial & webUSB
  if (Serial.available())
  {
    count = Serial.read(buf, 64);
    echo_all(buf, count);
  }

  // from WebUSB to both Serial & webUSB
  if (usb_web.available())
  {
    count = usb_web.read(buf, 64);
    echo_all(buf, count);
  }
}

void line_state_callback(bool connected)
{
  digitalWrite(led_pin, connected);

  if ( connected )
  {
    usb_web.println("WebUSB interface connected !!");
    usb_web.flush();
  }
}

But still, it wasn’t clear and the communication didn’t work everytime.

As Luc suggested, I checked out Neil’s examples using html. We found one using RP2040 with accelerometer.

I thought at first it was only for IMU devices but Luc insisted for me to try it. I checked the source code, copied part of it into my own but it didn’t work. Luc tried it on it side and succeed but his code didn’t work with my computer.

Chrome parameters

We checked Chrome parameters to be sure the problem didn’t come from it.

You have to be connected to chrome. Guest profile don’t have access to all the parmeters.

In the settings, Go to Privacy and security > Sites settings > Permissions (deploy Additional Permissions) > Serial Ports
Here make sure the “Sites can ask to connect to serial ports” is selected. You can also check USB devices and HID devices for more options.

My parameters was okay, so the problem was something else. Luc adviced me to close all windows on my computer to be sure no other serial communication was opened. And his example finally worked !

IMU

Now that communication was working I could study the code to make it do what i wanted.

async function open_IMU() {
            try {
                // Requesting the serial port
                const port = await navigator.serial.requestPort();

                // Opening the serial port
                await port.open({ baudRate: 115200, bufferSize: 1 });

                // Getting the reader for the port
                const reader = port.readable.getReader();

                while (true) {
                    // Waiting for line end
                    let lineEnd = false;
                    let line = '';
                    while (!lineEnd) {
                        const { value, done } = await reader.read();
                        let chr = String.fromCharCode(value[0]);
                        line += chr;
                        if (chr === '\n' || done) lineEnd = true;
                    }
            } catch (error) {
                // Handling any errors that occur during the process
                console.error("An error occurred:", error);
            }
// Extracting container index (int)
const vars = line.split(',')
const containerIndex = parseInt(vars[0]) 
// Updating the container index value on the webpage
document.getElementById("container-index-value").innerText = "Container Index: " + containerIndex;

// Extracting container index (int)
const vars = line.split(',') 
const containerIndex = parseFloat(vars[0])
// Updating the container index value on the webpage
document.getElementById("container-index-value").innerText = "Container Index: " + containerIndex;


// Extracting container index (string)
const vars = line.split(',');
const containerIndex = vars[0].trim().toString(); // Convert to string
// Updating the container index value on the webpage
document.getElementById("container-index-value").innerText = "Container Index: " + containerIndex;
if (line.trim() === "SW Button pushed") {
                    // If the button is pushed, call addValues
                    addValues();
                }

Here’s the evolution of my code :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0">

</head>

<body>

<input type="button" value="open IMU" onclick="open_IMU()"> //modif Luc

<div id="container-index-value"></div>

</body>

<script>
async function open_IMU(cmd) {
    //
    // open port
    //
    port = await navigator.serial.requestPort();
    await port.open({baudRate:115200,bufferSize:1});
    var reader = port.readable.getReader();

        while (true) {
            //
            // wait for line end
            //
            while (true) {
                const {value,done} = await reader.read();
                let chr = String.fromCharCode(value[0])
                if (chr == '\n') break
                }
            //
            // accumulate line
            //
            let line = ''
            while (true) {
                const {value,done} = await reader.read();
                let chr = String.fromCharCode(value[0])
                line += chr
                if (chr == '\n') break
                }
            //
            // convert to floats
            //
            vars = line.split(',')
            //containerIndex = parseFloat(vars[0]) //modif Luc
            containerIndex = parseInt(vars[0]) //modif Luc
            //chatgpt
            document.getElementById("container-index-value").innerText = "Container Index: " + containerIndex;
            }

}
</script>


</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IMU Data and Mindset Selector</title>
    <style>
        .container {
            display: flex;
            justify-content: space-around;
            margin-bottom: 20px;
            max-height: 20%;
        }
        .image-container {
            text-align: center;
        }
        .image-container img {
            max-width: 100%;
            max-height: 100px;
        }
        .btn-container {
            text-align: center;
            margin-bottom: 20px;
        }
        .btn {
            padding: 10px 20px;
            background-color: #007bff;
            color: #fff;
            border: none;
            cursor: pointer;
            margin: 0 10px; /* Add some spacing between buttons */
        }
        #result-container {
            text-align: center;
            margin-top: 20px;
        }
        #result-button-container {
            text-align: center;
            margin-bottom: 20px;
        }
        #result-image {
            max-width: 20%; /* Adjust the maximum width of the result image container */
            margin: 0 auto; /* Center the result image horizontally */
        }
        #result-image img {
            max-width: 100%; /* Ensure the result image fits within its container */
            height: auto; /* Maintain aspect ratio */
        }
    </style>
</head>
<body>

<div class="container">
    <div class="image-container">
        <h2>Mood</h2>
        <div id="image-container1">
            <img src="03_smiley.jpg" alt="Image" data-value="3">
        </div>
        <div class="btn-container">
            <button class="btn" onclick="previousImage(1)">Previous</button>
            <button class="btn" onclick="nextImage(1)">Next</button>
        </div>
    </div>
    <div class="image-container">
        <h2>Interaction acceptance</h2>
        <div id="image-container2">
            <img src="30_smiley.jpg" alt="Image" data-value="30">
        </div>
        <div class="btn-container">
            <button class="btn" onclick="previousImage(2)">Previous</button>
            <button class="btn" onclick="nextImage(2)">Next</button>
        </div>
    </div>
</div>

<div id="result-button-container">
    <button class="btn" onclick="addValues()">Set</button>
</div>

<div id="result-container">
    <h2>Mindset</h2>
    <div id="result-text"></div> 
    <div id="result-image"></div>
</div>

<!-- Button to trigger the open_IMU function -->
<input type="button" value="Open IMU" onclick="open_IMU()">

<!-- Container to display the container index value -->
<div id="container-index-value"></div>

<!-- JavaScript code -->
<script>
    var currentIndex1 = 2; // Index for the first image array
    var currentIndex2 = 2; // Index for the second image array
    var images1 = ["05_smiley.jpg", "04_smiley.jpg", "03_smiley.jpg","02_smiley.jpg", "01_smiley.jpg"];
    var images2 = ["50_smiley.jpg", "40_smiley.jpg", "30_smiley.jpg", "20_smiley.jpg", "10_smiley.jpg"];
    var values1 = [5, 4, 3, 2, 1];
    var values2 = [50, 40, 30, 20, 10];
    var allImages = [
        { src: "smiley_mix11.jpg", value: 11 },
        { src: "smiley_mix12.jpg", value: 12 },
        { src: "smiley_mix13.jpg", value: 13 },
        { src: "smiley_mix14.jpg", value: 14 },
        { src: "smiley_mix15.jpg", value: 15 },
        { src: "smiley_mix21.jpg", value: 21 },
        { src: "smiley_mix22.jpg", value: 22 },
        { src: "smiley_mix23.jpg", value: 23 },
        { src: "smiley_mix24.jpg", value: 24 },
        { src: "smiley_mix25.jpg", value: 25 },
        { src: "smiley_mix31.jpg", value: 31 },
        { src: "smiley_mix32.jpg", value: 32 },
        { src: "smiley_mix33.jpg", value: 33 },
        { src: "smiley_mix34.jpg", value: 34 },
        { src: "smiley_mix35.jpg", value: 35 },
        { src: "smiley_mix41.jpg", value: 41 },
        { src: "smiley_mix42.jpg", value: 42 },
        { src: "smiley_mix43.jpg", value: 43 },
        { src: "smiley_mix44.jpg", value: 44 },
        { src: "smiley_mix45.jpg", value: 45 },
        { src: "smiley_mix51.jpg", value: 51 },
        { src: "smiley_mix52.jpg", value: 52 },
        { src: "smiley_mix53.jpg", value: 53 },
        { src: "smiley_mix54.jpg", value: 54 },
        { src: "smiley_mix55.jpg", value: 55 },
    ];

    async function open_IMU() {
        try {
            // Requesting the serial port
            const port = await navigator.serial.requestPort();

            // Opening the serial port
            await port.open({ baudRate: 115200, bufferSize: 1 });

            // Getting the reader for the port
            const reader = port.readable.getReader();

            while (true) {
                // Waiting for line end
                let lineEnd = false;
                let line = '';
                while (!lineEnd) {
                    const { value, done } = await reader.read();
                    let chr = String.fromCharCode(value[0]);
                    line += chr;
                    if (chr === '\n' || done) lineEnd = true;
                }

                // Extracting container index
                const vars = line.split(',');
                const containerIndex = vars[0].trim().toString(); // Convert to string

                // Updating the container index value on the webpage
                document.getElementById("container-index-value").innerText = "Container Index: " + containerIndex;
            }
        } catch (error) {
            // Handling any errors that occur during the process
            console.error("An error occurred:", error);
        }
    }

    function previousImage(containerIndex) {
        if (containerIndex === 1) {
            if (currentIndex1 === 0) {
                return; // Do nothing if already at the first image
            }
            currentIndex1--;
            updateImage(1);
        } else if (containerIndex === 2) {
            if (currentIndex2 === 0) {
                return; // Do nothing if already at the first image
            }
            currentIndex2--;
            updateImage(2);
        }
    }

    function nextImage(containerIndex) {
        if (containerIndex === 1) {
            if (currentIndex1 === images1.length - 1) {
                return; // Do nothing if already at the last image
            }
            currentIndex1++;
            updateImage(1);
        } else if (containerIndex === 2) {
            if (currentIndex2 === images2.length - 1) {
                return; // Do nothing if already at the last image
            }
            currentIndex2++;
            updateImage(2);
        }
    }

    function updateImage(containerIndex) {
        var displayedImage;
        if (containerIndex === 1) {
            displayedImage = document.getElementById("image-container1").getElementsByTagName("img")[0];
            displayedImage.src = images1[currentIndex1];            
            displayedImage.dataset.value = values1[currentIndex1];
        } else if (containerIndex === 2) {
            displayedImage = document.getElementById("image-container2").getElementsByTagName("img")[0];
            displayedImage.src = images2[currentIndex2];            
            displayedImage.dataset.value = values2[currentIndex2];
        }
    }

    function addValues() {
        var value1 = values1[currentIndex1];
        var value2 = values2[currentIndex2];
        var result = value1 + value2;

        // Find the image object with the matching value
        var resultImage = allImages.find(function(image) {
            return image.value === result;
        });

        if (resultImage) {
            var resultImageSrc = resultImage.src;
            var resultImageValue = resultImage.value; // Get the personalized value
    //        document.getElementById("result-text").innerText = "Result: " + result + " (" + resultImageValue + ")"; //
            document.getElementById("result-image").innerHTML = "<img src='" + resultImageSrc + "' alt='Result Image'>";
        } else {
            document.getElementById("result-text").innerText = "Result: Invalid";
            document.getElementById("result-image").innerHTML = ""; // Clear previous result image
        }
    }
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IMU Data and Mindset Selector</title>
    <style>
        .container {
            display: flex;
            justify-content: space-around;
            margin-bottom: 20px;
            max-height: 20%;
        }
        .image-container {
            text-align: center;
        }
        .image-container img {
            max-width: 100%;
            max-height: 100px;
        }
        .btn-container {
            text-align: center;
            margin-bottom: 20px;
        }
        .btn {
            padding: 10px 20px;
            background-color: #007bff;
            color: #fff;
            border: none;
            cursor: pointer;
            margin: 0 10px; /* Add some spacing between buttons */
        }
        #result-container {
            text-align: center;
            margin-top: 20px;
        }
        #result-button-container {
            text-align: center;
            margin-bottom: 20px;
        }
        #result-image {
            max-width: 20%; /* Adjust the maximum width of the result image container */
            margin: 0 auto; /* Center the result image horizontally */
        }
        #result-image img {
            max-width: 100%; /* Ensure the result image fits within its container */
            height: auto; /* Maintain aspect ratio */
        }
    </style>
</head>
<body>

<div class="container">
    <div class="image-container">
        <h2>Mood</h2>
        <div id="image-container1">
            <img src="03_smiley.jpg" alt="Image" data-value="3">
        </div>
        <div class="btn-container">
            <button class="btn" onclick="previousImage(1)">Previous</button>
            <button class="btn" onclick="nextImage(1)">Next</button>
        </div>
    </div>
    <div class="image-container">
        <h2>Interaction acceptance</h2>
        <div id="image-container2">
            <img src="30_smiley.jpg" alt="Image" data-value="30">
        </div>
        <div class="btn-container">
            <button class="btn" onclick="previousImage(2)">Previous</button>
            <button class="btn" onclick="nextImage(2)">Next</button>
        </div>
    </div>
</div>

<div id="result-button-container">
    <button class="btn" onclick="addValues()">Set</button>
</div>

<div id="result-container">
    <h2>Mindset</h2>
    <div id="result-text"></div> 
    <div id="result-image"></div>
</div>

<!-- Button to trigger the open_IMU function -->
<input type="button" value="Open IMU" onclick="open_IMU()">

<!-- Container to display the container index value -->
<div id="container-index-value"></div>

<!-- JavaScript code -->
<script>
    var currentIndex1 = 2; // Index for the first image array
    var currentIndex2 = 2; // Index for the second image array
    var images1 = ["05_smiley.jpg", "04_smiley.jpg", "03_smiley.jpg","02_smiley.jpg", "01_smiley.jpg"];
    var images2 = ["50_smiley.jpg", "40_smiley.jpg", "30_smiley.jpg", "20_smiley.jpg", "10_smiley.jpg"];
    var values1 = [5, 4, 3, 2, 1];
    var values2 = [50, 40, 30, 20, 10];
    var allImages = [
        { src: "smiley_mix11.jpg", value: 11 },
        { src: "smiley_mix12.jpg", value: 12 },
        { src: "smiley_mix13.jpg", value: 13 },
        { src: "smiley_mix14.jpg", value: 14 },
        { src: "smiley_mix15.jpg", value: 15 },
        { src: "smiley_mix21.jpg", value: 21 },
        { src: "smiley_mix22.jpg", value: 22 },
        { src: "smiley_mix23.jpg", value: 23 },
        { src: "smiley_mix24.jpg", value: 24 },
        { src: "smiley_mix25.jpg", value: 25 },
        { src: "smiley_mix31.jpg", value: 31 },
        { src: "smiley_mix32.jpg", value: 32 },
        { src: "smiley_mix33.jpg", value: 33 },
        { src: "smiley_mix34.jpg", value: 34 },
        { src: "smiley_mix35.jpg", value: 35 },
        { src: "smiley_mix41.jpg", value: 41 },
        { src: "smiley_mix42.jpg", value: 42 },
        { src: "smiley_mix43.jpg", value: 43 },
        { src: "smiley_mix44.jpg", value: 44 },
        { src: "smiley_mix45.jpg", value: 45 },
        { src: "smiley_mix51.jpg", value: 51 },
        { src: "smiley_mix52.jpg", value: 52 },
        { src: "smiley_mix53.jpg", value: 53 },
        { src: "smiley_mix54.jpg", value: 54 },
        { src: "smiley_mix55.jpg", value: 55 },
    ];

    async function open_IMU() {
        try {
            // Requesting the serial port
            const port = await navigator.serial.requestPort();

            // Opening the serial port
            await port.open({ baudRate: 115200, bufferSize: 1 });

            // Getting the reader for the port
            const reader = port.readable.getReader();

            while (true) {
                // Waiting for line end
                let lineEnd = false;
                let line = '';
                while (!lineEnd) {
                    const { value, done } = await reader.read();
                    let chr = String.fromCharCode(value[0]);
                    line += chr;
                    if (chr === '\n' || done) lineEnd = true;
                }

            if (line.trim() === "SW Button pushed") {
                // If the button is pushed, call addValues
                addValues();
            }

                // Extracting container index
                const vars = line.split(',');
                const containerIndex = vars[0].trim().toString(); // Convert to string

                // Updating the container index value on the webpage
                document.getElementById("container-index-value").innerText = "Container Index: " + containerIndex;
            }
        } catch (error) {
            // Handling any errors that occur during the process
            console.error("An error occurred:", error);
        }
    }

    function previousImage(containerIndex) {
        if (containerIndex === 1) {
            if (currentIndex1 === 0) {
                return; // Do nothing if already at the first image
            }
            currentIndex1--;
            updateImage(1);
        } else if (containerIndex === 2) {
            if (currentIndex2 === 0) {
                return; // Do nothing if already at the first image
            }
            currentIndex2--;
            updateImage(2);
        }
    }

    function nextImage(containerIndex) {
        if (containerIndex === 1) {
            if (currentIndex1 === images1.length - 1) {
                return; // Do nothing if already at the last image
            }
            currentIndex1++;
            updateImage(1);
        } else if (containerIndex === 2) {
            if (currentIndex2 === images2.length - 1) {
                return; // Do nothing if already at the last image
            }
            currentIndex2++;
            updateImage(2);
        }
    }

    function updateImage(containerIndex) {
        var displayedImage;
        if (containerIndex === 1) {
            displayedImage = document.getElementById("image-container1").getElementsByTagName("img")[0];
            displayedImage.src = images1[currentIndex1];            
            displayedImage.dataset.value = values1[currentIndex1];
        } else if (containerIndex === 2) {
            displayedImage = document.getElementById("image-container2").getElementsByTagName("img")[0];
            displayedImage.src = images2[currentIndex2];            
            displayedImage.dataset.value = values2[currentIndex2];
        }
    }

    function addValues() {
        var value1 = values1[currentIndex1];
        var value2 = values2[currentIndex2];
        var result = value1 + value2;

        // Find the image object with the matching value
        var resultImage = allImages.find(function(image) {
            return image.value === result;
        });

        if (resultImage) {
            var resultImageSrc = resultImage.src;
            var resultImageValue = resultImage.value; // Get the personalized value
    //        document.getElementById("result-text").innerText = "Result: " + result + " (" + resultImageValue + ")"; //
            document.getElementById("result-image").innerHTML = "<img src='" + resultImageSrc + "' alt='Result Image'>";
        } else {
            document.getElementById("result-text").innerText = "Result: Invalid";
            document.getElementById("result-image").innerHTML = ""; // Clear previous result image
        }
    }
</script>
</body>
</html>

For making the button work, just add :

if (line.trim() === "SW Button pushed") {
addValues();
}

and then I add the rotary encoder :

if (line.trim() === "SW Button pushed") {
addValues();
} else if (line.trim() === "clockwise") {
// If the rotation is clockwise, call nextImage
nextImage(1);
} else if (line.trim() === "counter-clockwise") {
// If the rotation is counter-clockwise, call previousImage
previousImage(1);
            }

I add to change the debounce for the CLK switch using milliseconds

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IMU Data and Mindset Selector</title>
    <style>
        .container {
            display: flex;
            justify-content: space-around;
            margin-bottom: 20px;
            max-height: 20%;
        }
        .image-container {
            text-align: center;
        }
        .image-container img {
            max-width: 100%;
            max-height: 100px;
        }
        .btn-container {
            text-align: center;
            margin-bottom: 20px;
        }
        .btn {
            padding: 10px 20px;
            background-color: #007bff;
            color: #fff;
            border: none;
            cursor: pointer;
            margin: 0 10px; /* Add some spacing between buttons */
        }
        #result-container {
            text-align: center;
            margin-top: 20px;
        }
        #result-button-container {
            text-align: center;
            margin-bottom: 20px;
        }
        #result-image {
            max-width: 20%; /* Adjust the maximum width of the result image container */
            margin: 0 auto; /* Center the result image horizontally */
        }
        #result-image img {
            max-width: 100%; /* Ensure the result image fits within its container */
            height: auto; /* Maintain aspect ratio */
        }
    </style>
</head>
<body>

<div class="container">
    <div class="image-container">
        <h2>Mood</h2>
        <div id="image-container1">
            <img src="03_smiley.jpg" alt="Image" data-value="3">
        </div>
        <div class="btn-container">
            <button class="btn" onclick="previousImage(1)">Previous</button>
            <button class="btn" onclick="nextImage(1)">Next</button>
        </div>
    </div>
    <div class="image-container">
        <h2>Interaction acceptance</h2>
        <div id="image-container2">
            <img src="30_smiley.jpg" alt="Image" data-value="30">
        </div>
        <div class="btn-container">
            <button class="btn" onclick="previousImage(2)">Previous</button>
            <button class="btn" onclick="nextImage(2)">Next</button>
        </div>
    </div>
</div>

<div id="result-button-container">
    <button class="btn" onclick="addValues()">Set</button>
</div>

<div id="result-container">
    <h2>Mindset</h2>
    <div id="result-text"></div> 
    <div id="result-image"></div>
</div>

<!-- Button to trigger the open_IMU function -->
<button class="btn" value="Open IMU" onclick="open_IMU()">Open IMU</button>

<!-- Container to display the container index value -->
<div id="container-index-value"></div>

<!-- JavaScript code -->
<script>
    var currentIndex1 = 2; // Index for the first image array
    var currentIndex2 = 2; // Index for the second image array
    var images1 = ["05_smiley.jpg", "04_smiley.jpg", "03_smiley.jpg","02_smiley.jpg", "01_smiley.jpg"];
    var images2 = ["50_smiley.jpg", "40_smiley.jpg", "30_smiley.jpg", "20_smiley.jpg", "10_smiley.jpg"];
    var values1 = [5, 4, 3, 2, 1];
    var values2 = [50, 40, 30, 20, 10];
    var allImages = [
        { src: "smiley_mix11.jpg", value: 11 },
        { src: "smiley_mix12.jpg", value: 12 },
        { src: "smiley_mix13.jpg", value: 13 },
        { src: "smiley_mix14.jpg", value: 14 },
        { src: "smiley_mix15.jpg", value: 15 },
        { src: "smiley_mix21.jpg", value: 21 },
        { src: "smiley_mix22.jpg", value: 22 },
        { src: "smiley_mix23.jpg", value: 23 },
        { src: "smiley_mix24.jpg", value: 24 },
        { src: "smiley_mix25.jpg", value: 25 },
        { src: "smiley_mix31.jpg", value: 31 },
        { src: "smiley_mix32.jpg", value: 32 },
        { src: "smiley_mix33.jpg", value: 33 },
        { src: "smiley_mix34.jpg", value: 34 },
        { src: "smiley_mix35.jpg", value: 35 },
        { src: "smiley_mix41.jpg", value: 41 },
        { src: "smiley_mix42.jpg", value: 42 },
        { src: "smiley_mix43.jpg", value: 43 },
        { src: "smiley_mix44.jpg", value: 44 },
        { src: "smiley_mix45.jpg", value: 45 },
        { src: "smiley_mix51.jpg", value: 51 },
        { src: "smiley_mix52.jpg", value: 52 },
        { src: "smiley_mix53.jpg", value: 53 },
        { src: "smiley_mix54.jpg", value: 54 },
        { src: "smiley_mix55.jpg", value: 55 },
    ];

    async function open_IMU() {
        try {
            // Requesting the serial port
            const port = await navigator.serial.requestPort();

            // Opening the serial port
            await port.open({ baudRate: 115200, bufferSize: 1 });

            // Getting the reader for the port
            const reader = port.readable.getReader();

            while (true) {
                // Waiting for line end
                let lineEnd = false;
                let line = '';
                while (!lineEnd) {
                    const { value, done } = await reader.read();
                    let chr = String.fromCharCode(value[0]);
                    line += chr;
                    if (chr === '\n' || done) lineEnd = true;
                }

            if (line.trim() === "SW Button pushed") {
                // If the button is pushed, call addValues
                addValues();
            } else if (line.trim() === "clockwise") {
                // If the rotation is clockwise, call nextImage
                nextImage(1);
            } else if (line.trim() === "counter-clockwise") {
                // If the rotation is counter-clockwise, call previousImage
                previousImage(1);
            }

                // Extracting container index
                const vars = line.split(',');
                const containerIndex = vars[0].trim().toString(); // Convert to string

                // Updating the container index value on the webpage
                document.getElementById("container-index-value").innerText = "Container Index: " + containerIndex;
            }
        } catch (error) {
            // Handling any errors that occur during the process
            console.error("An error occurred:", error);
        }
    }

    function previousImage(containerIndex) {
        if (containerIndex === 1) {
            if (currentIndex1 === 0) {
                return; // Do nothing if already at the first image
            }
            currentIndex1--;
            updateImage(1);
        } else if (containerIndex === 2) {
            if (currentIndex2 === 0) {
                return; // Do nothing if already at the first image
            }
            currentIndex2--;
            updateImage(2);
        }
    }

    function nextImage(containerIndex) {
        if (containerIndex === 1) {
            if (currentIndex1 === images1.length - 1) {
                return; // Do nothing if already at the last image
            }
            currentIndex1++;
            updateImage(1);
        } else if (containerIndex === 2) {
            if (currentIndex2 === images2.length - 1) {
                return; // Do nothing if already at the last image
            }
            currentIndex2++;
            updateImage(2);
        }
    }

    function updateImage(containerIndex) {
        var displayedImage;
        if (containerIndex === 1) {
            displayedImage = document.getElementById("image-container1").getElementsByTagName("img")[0];
            displayedImage.src = images1[currentIndex1];            
            displayedImage.dataset.value = values1[currentIndex1];
        } else if (containerIndex === 2) {
            displayedImage = document.getElementById("image-container2").getElementsByTagName("img")[0];
            displayedImage.src = images2[currentIndex2];            
            displayedImage.dataset.value = values2[currentIndex2];
        }
    }

    function addValues() {
        var value1 = values1[currentIndex1];
        var value2 = values2[currentIndex2];
        var result = value1 + value2;

        // Find the image object with the matching value
        var resultImage = allImages.find(function(image) {
            return image.value === result;
        });

        if (resultImage) {
            var resultImageSrc = resultImage.src;
            var resultImageValue = resultImage.value; // Get the personalized value
    //        document.getElementById("result-text").innerText = "Result: " + result + " (" + resultImageValue + ")"; //
            document.getElementById("result-image").innerHTML = "<img src='" + resultImageSrc + "' alt='Result Image'>";
        } else {
            document.getElementById("result-text").innerText = "Result: Invalid";
            document.getElementById("result-image").innerHTML = ""; // Clear previous result image
        }
    }
</script>
</body>
</html>
#define pinCLK 1       // CLK pin connected to GPIO 1
#define pinDT  2       // DT pin connected to GPIO 2
#define pinSW  3       // SW pin connected to GPIO 3

int count = 0;    // Var to know how many clicks occured (increment clockwise and decrement counter_clockwise)
int previousStateSW;           // Var to memorize previous SW state to compare it with actual state
int previousStateCLK;          // Var to memorize previous CL state to compare it with actual state

void setup() {

    Serial.begin(9600);

    pinMode(pinSW, INPUT_PULLUP);         // INPUT_PULLUP to avoid 'floating'
    pinMode(pinDT, INPUT);
    pinMode(pinCLK, INPUT);

    previousStateSW  = digitalRead(pinSW);    // initial value for SW
    previousStateCLK = digitalRead(pinCLK);   // initial value for CLK

    delay(200); // delay to stabilize signal before the loop
}

void loop() {

    int actualStateCLK = digitalRead(pinCLK); // reading CLK value
    int actualStateDT  = digitalRead(pinDT);  // reading DT value
    int actualStateSW  = digitalRead(pinSW);  // reading SW value

// *************************
// Push Button verification
// *************************

    if(actualStateSW != previousStateSW) {    // Checking if SW state has changed
        previousStateSW = actualStateSW;      // Save new state

        if(actualStateSW == LOW)
            Serial.println(F("SW Button pushed"));     // Display State on serial monitor
        else
            Serial.println(F("SW Button released"));

        delay(10); // Delay to avoid rebounce
    }

// ***************************
// Rotary encoder verification
// ***************************

    if (actualStateCLK != previousStateCLK) {
        delayMicroseconds(200); // Debounce delay
        if (digitalRead(pinCLK) == actualStateCLK) { // Check if the CLK signal has settled
            previousStateCLK = actualStateCLK;

    if(actualStateCLK == LOW) {

        if(actualStateCLK != actualStateDT) {   // comparing CLK and DT, if they're different, direction is counter-clockwise          
            count++;                            // decrement counter
            Serial.println(F("clockwise"));   // Display value on Serial Monitor
//            Serial.println(count);
        }
    else {                                   // when CLK and DT are similar, direction is clockwise            
        count--;                             // increment counter
        Serial.println(F("counter-clockwise"));   // Display value on Serial Monitor
//        Serial.println(count);
}

    }
    } 

}
}

I create an online version of the interface to test it.

I also wanted to try it on phone but Android Chrome does not allowed serial port communication

Class Archive

Impressions of the week

As stated in previous week impressions, I had the feeling that I didn’t learn enough about networking and communication and the backlash was quite harsch. I feel I learned more this week about communciations than about interfaces. I’m quite satisfied with what I ended up with but again, I’d like to find more time to control the other part of the program, make an interface for phone (even if my html is quite responsive) or display it on a output screen. In the end, I’ve made rather good progress on my project and that’as a pretty good point.