Input Devices


Objectives for Week 11

  1. Measure something: Add a sensor to the microcontroller board that you have designed and read it
  2. Group Assignment:
    • Probe an input device's analog levels and digital signals


This week is about using an input device and I chose gyroscope as I will be using it for my final project. In my final project, I plan to create a die having gyroscope and bluetooth connectivity so that once the die is rolled, the corresponding number can be detected by the system for further process of moving the token.

MPU-6050

mpu6050
PinOut

MPU-6050 sensor module is a combination of 3-axis accelerometer and 3-axis gyroscope. It is widely used for applications such as orientation detection, motion tracking and gesture detection.

Key Features

To know more about MPU-6050 and the working principle of accelerometer and gyroscope, click on the link Last Minute Engineers

Microcontroller Board

ATtiny1614 Board

During 'Output Devices; week, I designed an ATtiny1614 microcontroller board to house the DRV8825 driver module for running a stepper motor. While doing the schematic, I took out the SDA, SCL, Power line(5V) and Ground using a 2x2pos Conn Header.

SDA and SCL are two important lines used in the I2C (Inter-Integrated Circuit) communication protocol, which is widely used for connecting low-speed devices in embedded systems. These two lines enable multiple devices (such as sensors, microcontrollers, displays, etc.) to communicate with each other over a simple, two-wire interface.

Refer Week 9 documentation for details on the microcontroller board that I had created.

Working with MPU-6050

Requirements:

  1. ATtiny1614 Microcontroller board
  2. MPU-6050 Module
  3. Jumper Wires
  4. Quentorres board (as Programmer)
  5. FTDI to UPDI Convertor
  6. Type-C Cable

Connections:


For Programming:

I'm using Arduino IDE for programming. Since, ATtiny board cannot be directly connected, I am using the Quentorres board I have made in Electronics Production week as the Programmer. Refer Week 9 to know how to burn bootloader and how to use Quentorres board as programmer and also to know the parameters set to use ATtiny1614 board.

For the MPU6050 module, I installed "MPU6050_light" library from the Library Manager in Arduino IDE.

mpu6050_light

I took an example code from the library I installed.

mpu6050_light

Here's the code:

    /* Get all possible data from MPU6050
 * Accelerometer values are given as multiple of the gravity [1g = 9.81 m/s²]
 * Gyro values are given in deg/s
 * Angles are given in degrees
 * Note that X and Y are tilt angles and not pitch/roll.
 *
 * License: MIT
 */

#include "Wire.h"
#include 

MPU6050 mpu(Wire);

long timer = 0;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  
  byte status = mpu.begin();
  Serial.print(F("MPU6050 status: "));
  Serial.println(status);
  while(status!=0){ } // stop everything if could not connect to MPU6050
  
  Serial.println(F("Calculating offsets, do not move MPU6050"));
  delay(1000);
  mpu.calcOffsets(true,true); // gyro and accelero
  Serial.println("Done!\n");
  
}

void loop() {
  mpu.update();

  if(millis() - timer > 1000){ // print data every second
    Serial.print(F("TEMPERATURE: "));Serial.println(mpu.getTemp());
    Serial.print(F("ACCELERO  X: "));Serial.print(mpu.getAccX());
    Serial.print("\tY: ");Serial.print(mpu.getAccY());
    Serial.print("\tZ: ");Serial.println(mpu.getAccZ());
  
    Serial.print(F("GYRO      X: "));Serial.print(mpu.getGyroX());
    Serial.print("\tY: ");Serial.print(mpu.getGyroY());
    Serial.print("\tZ: ");Serial.println(mpu.getGyroZ());
  
    Serial.print(F("ACC ANGLE X: "));Serial.print(mpu.getAccAngleX());
    Serial.print("\tY: ");Serial.println(mpu.getAccAngleY());
    
    Serial.print(F("ANGLE     X: "));Serial.print(mpu.getAngleX());
    Serial.print("\tY: ");Serial.print(mpu.getAngleY());
    Serial.print("\tZ: ");Serial.println(mpu.getAngleZ());
    Serial.println(F("=====================================================\n"));
    timer = millis();
  }

}

  

While running the code, I faced a problem. The connection was irregular and I started receiving data only after couple of tries of removing and connecting the module. I'm not able to understand the root cause of this issue. Even when the module starts giving data, the data is improper. Therefore, I thought of using another module,i.e., Seeed Studio XIAO nRF52840 Sense.



Seeed Studio XIAO nRF52840 Sense

mpu6050_light

The Seeed Studio XIAO nRF52840 Sense is a compact development board equipped with a powerful Nordic nRF52840 MCU which integrates Bluetooth 5.0 connectivity. It is integrated with two extra onboard sensors. One of them is a Pulse Density Modulation (PDM) Digital Microphone. It can receive audio data in real-time which allows it to be used for audio recognition. The other one is a 6-axis Inertial Measurement Unit (IMU), this IMU can be very useful in TinyML projects like gesture recognition.

The first thing to note is that the Near Field Communication (NFC) interface is functional on the board. Secondly, there is a tiny reset button on the side of the Type-C interface. On the other side, there is a 3-in-one LED (User LED) along with a Charge LED to indicate the charging status when a battery is connected. There are 11 digital I/O that can be used as PWM pins and 6 analog I/O that can be used as ADC pins. It supports all three common serial interfaces such as UART, I2C, and SPI.

Working with XIAO nRF52840 Sense

I referred seeed studio tutorial on Getting Started with Seeed Studio XIAO nRF52840 (Sense).

Navigate to File > Preferences and paste the link https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json in Additional Boards Manager URLs.

Next, I installed the boards from Boards Manager. It is recommanded to use the Seeed nRF52 Boards library if you want to apply Bluetooth function and "Low Energy Cost Function". It is recommanded to use the Seeed nRF52 mbed-enabled Boards library if you want to use it in embedded Machine Learning Applications or apply "IMU & PDM advanced function". Both libraries support very well when it comes to the basic usage, such as LED, Digital, Analog, Serial, I2C, SPI.

seeed

I selected the board and port as shown.

seeed

I uploaded the example Blink code from Arduino to see if the module is working.




It was working fine.

Next step is to check the gyroscope and temperature data of the module. For that I followed seeed studio tutorial on The 6-Axis IMU Usage on Seeed Studio XIAO nRF52840 Sense.

I followed the tutorial on adding a new library.

seeed
seeed

For example code, navigate to File > Examples > Seeed Arduino LSM6DS3 > HighLevelExample to open the HighLevelExample.

seeed
        /*****************************************************************************/
//  HighLevelExample.ino
//  Hardware:      Grove - 6-Axis Accelerometer&Gyroscope
//	Arduino IDE:   Arduino-1.65
//	Author:	       Lambor
//	Date: 	       Oct,2015
//	Version:       v1.0
//
//  Modified by:
//  Data:
//  Description:
//
//	by www.seeedstudio.com
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
//
/*******************************************************************************/

#include "LSM6DS3.h"
#include "Wire.h"

//Create a instance of class LSM6DS3
LSM6DS3 myIMU(I2C_MODE, 0x6A);  //I2C device address 0x6A

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  while (!Serial)
    ;
  //Call .begin() to configure the IMUs
  if (myIMU.begin() != 0) {
    Serial.println("Device error");
  } else {
    Serial.println("Device OK!");
  }
}

void loop() {
  //Accelerometer
  Serial.print("\nAccelerometer:\n");
  Serial.print(" X1 = ");
  Serial.println(myIMU.readFloatAccelX(), 4);
  Serial.print(" Y1 = ");
  Serial.println(myIMU.readFloatAccelY(), 4);
  Serial.print(" Z1 = ");
  Serial.println(myIMU.readFloatAccelZ(), 4);

  //Gyroscope
  Serial.print("\nGyroscope:\n");
  Serial.print(" X1 = ");
  Serial.println(myIMU.readFloatGyroX(), 4);
  Serial.print(" Y1 = ");
  Serial.println(myIMU.readFloatGyroY(), 4);
  Serial.print(" Z1 = ");
  Serial.println(myIMU.readFloatGyroZ(), 4);

  //Thermometer
  Serial.print("\nThermometer:\n");
  Serial.print(" Degrees C1 = ");
  Serial.println(myIMU.readTempC(), 4);
  Serial.print(" Degrees F1 = ");
  Serial.println(myIMU.readTempF(), 4);

  delay(1000);
}

      



Dice Orientation

For my final project, I have to determine each orientation of the dice. For that, I need a code. I was not able to find any sample code for the same and also the codes given by ChatGPT wasn't satisfactory. My instructor, Saheen, shared an exercise code for a mouse click here. I modified the code to match my requirements. First I gave some random ranges and after testing I added the proper range of values.

#include "LSM6DS3.h"
#include "Wire.h"

//Create an instance of class LSM6DS3
LSM6DS3 myIMU(I2C_MODE, 0x6A);  //I2C device address 0x6A

void setup() {
  // Initialize serial communication at 9600 baud rate
  Serial.begin(9600);
  // Call .begin() to configure the IMU
  if (myIMU.begin() != 0) {
    Serial.println("Device error");
  } else {
    Serial.println("Device OK!");
  }
}

float vector_2_degrees(float x, float y) {
  float angle = atan2(y, x) * 180.0f / PI;

  if (angle < 0) {
    angle += 360;
  }

  return angle;
}

void loop() {
  // Accelerometer
  float x = myIMU.readFloatAccelX();
  float y = myIMU.readFloatAccelY();
  float z = myIMU.readFloatAccelZ();

  float angle_xz = vector_2_degrees(x, z);
  float angle_yz = vector_2_degrees(y, z);

  // Determine orientation and print it
  String Face = Orientation(angle_xz, angle_yz);
  Serial.println("Orientation: " + Face);
  // Serial.print("angle_xz:");
  // Serial.print(angle_xz);
  // Serial.print(",");
  // Serial.print("angle_yz:");
  // Serial.println(angle_yz);

  delay(1000);
}

String Orientation(float xz, float yz) {
  if ((80 < xz && xz < 100) && (80 < yz && yz < 100)) return "Top";
  if ((240 < xz && xz < 290) && (240 < yz && yz < 290)) return "Bottom";
  if (((60 < xz && xz < 110) || (240 < xz && xz < 360)) && ((340 < yz && yz < 360) || (0 < yz && yz < 12))) return "Right";
  if ((60 < xz && xz < 100) && (160 < yz && yz < 190)) return "Left";
  if (((340 < xz && xz < 360) || (0 < xz && xz < 12)) && ((170 < yz && yz < 190) || (240 < yz && yz < 360))) return "Front";
  if ((160 < xz && xz < 190) && (75 < yz && yz < 100)) return "Back";
  return "Unknown";
}

    



The results were pretty accurate and for my final project all I have to do is to change each orientation to its corresponding numbers on dice when rolled. That can be done once the dice is designed.

Group Assignment

This week's group assingment was to probe an input device's analog levels and digital signals. We chose Hall Effect sensor as the input device. Hall Effect Sensor

For further details, click on the link below.

Group Assignment-Week 11



Download Files

MPU6050 Arduino Code(zip)XIAO Arduino Code(zip)Dice Orientation Code (zip)