Skip to content

15. Interfacing and Application

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.

BNO-055 3D Viewer

One detail I noticed in the very long list of error messages was the following:

Multiple libraries were found for "SdFat.h"
  Used: C:\Users\lando\OneDrive\Documents\Arduino\libraries\SdFat_-_Adafruit_Fork
  Not used: C:\Users\lando\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\3.8.0\libraries\ESP8266SdFat
Multiple libraries were found for "SD.h"
  Used: C:\Users\lando\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\3.8.0\libraries\SD
  Not used: C:\Users\lando\AppData\Local\Arduino15\libraries\SD

So I changed the board from Xiao RP2040 to Arduino UNO.

After struggling even more for a signficant amount of time, I decided to switch over to a new method of interfacing the design.

Orientation Visualizer

I installed Thonny from here and used it to read the Serial data from the Arduino Monitor

import serial
import time
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# Setup Serial
ser = serial.Serial('COM12', 9600) 

# Setup matplotlib for real-time updating in 3D
plt.ion()
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
arrow = ax.quiver(0, 0, 0, 0, 0, 1)  # Initial arrow pointing along z-axis

ax.set_xlim(-2, 2)
ax.set_ylim(-2, 2)
ax.set_zlim(-2, 2)

def read_orientation():
    if ser.in_waiting > 0:
        line = ser.readline().decode('utf-8').strip()
        if line.startswith('Orientation'):
            _, values = line.split(':')
            x, y, z = map(float, values.split(','))
            return x, y, z
    return None

def update_arrow(x, y, z):
    global arrow
    arrow.remove()
    arrow = ax.quiver(0, 0, 0, x, y, z, color='blue')
    plt.draw()
    plt.pause(0.01)

while True:
    orientation = read_orientation()
    if orientation:
        x, y, z = orientation
        update_arrow(x, y, z)
        print("X: {:.2f}, Y: {:.2f}, Z: {:.2f}".format(x, y, z))
    time.sleep(1)

I also updated the sensor code to greatly simplify it so that it would only display the necessary information in the Serial monitor, which could then be translated into the correct values in Thonny.

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>

Adafruit_BNO055 bno = Adafruit_BNO055(55, 0x28, &Wire);

void setup(void) {
  Serial.begin(9600);
  while (!Serial);  // Wait for serial port to connect

  if (!bno.begin()) {
    Serial.println("No BNO055 detected ... Check your wiring or I2C ADDR!");
    while (1);
  }
  delay(1000);  // Give sensor time to stabilize
}

void loop(void) {
  sensors_event_t orientationData;
  bno.getEvent(&orientationData, Adafruit_BNO055::VECTOR_EULER);
  if (orientationData.type == SENSOR_TYPE_ORIENTATION) {
    Serial.print("Orientation: ");
    Serial.print(orientationData.orientation.x);
    Serial.print(", ");
    Serial.print(orientationData.orientation.y);
    Serial.print(", ");
    Serial.println(orientationData.orientation.z);
  }
  delay(100);  // Sampling rate delay
}

Since it was not updating, I went into the Thonny code to try and adjust the limit values, as I saw on the code that these were very low. Additionally, I found the FuncAnimation function of matplotlib, which I found could be used to display the 3D and updatable orientation data. I used ChatGPT once again to adjust the Thonny file to be the following:

Updated python Code import serial import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation from mpl_toolkits.mplot3d import Axes3D // Setup Serial ser = serial.Serial('COM12', 9600, timeout=1) // Setup matplotlib for real-time updating in 3D fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.set_xlim(-1, 361) # X goes from 0 to 360 ax.set_ylim(-91, 91) # Y goes from -90 to 90 ax.set_zlim(-181, 181) # Z goes from -180 to 180 def read_orientation(): if ser.in_waiting > 0: line = ser.readline().decode('utf-8').strip() if line.startswith('Orientation'): _, values = line.split(': ') x, y, z = map(float, values.split(', ')) return x, y, z return None def update(frame): orientation = read_orientation() if orientation: x, y, z = orientation ax.cla() # Clear the previous arrow ax.quiver(0, 0, 0, x, y, z, color='blue', length=1, normalize=True) ax.set_xlim(-1, 361) ax.set_ylim(-91, 91) ax.set_zlim(-181, 181) ax.figure.canvas.draw() ani = FuncAnimation(fig, update, interval=100) # Update the plot every 100 ms plt.show()

Group Project

Individual Contribution