2023 Group 4 – Angel Hat and Glove Set

Created by Nimat Choudhury, Sahra Yusuf, Shahd Ahmed

Do you wish to make heads turn everytime you step in the room? Well, we’ve got you covered with our newest release: The Angelic Hat and Magic Glove set! With a cute design and unique never-before-seen features, this hat will quickly become the most prized item in your wardrobe. Interactions such as moving your head to flap the wings or triggering a colour change with a single touch are sure to make everyone jealous of the power you’ll possess after owning this set.

Motion Tracking Fashionable Wearable

We chose to create a motion-tracking fashionable wearable, in the form of a hat and glove, syncing wirelessly. Our brief was to design a garment capable of tracking body movement and provide outputs based on collected data, whilst also focusing on being practical for everyday use and maintaining aesthetics. Our project revolves around a hat with wings and LEDs, which are controlled by movement, and the wearer pressing sensors on a glove. The sensors control the LED colour and light sequence, and head movement makes the wings flap. A hat perfect for making heads turn!

Design Blog

Week 7

Brainstorming

Brainstorming Session Notes

After choosing our brief, we began brainstorming and expanding on initial ideas.

We came up with numerous ideas such as a dress, a skirt, a glove, a hat, and glasses. After discussion, we decided to use a hat as our project base. Designs included a costume-style hat, similar to Captain Hook, with large feathers and suitable for dress-up parties, a ship’s captain-style hat with matching gloves, and various styles of hats with wings.

A sketch of the finalised idea

Ultimately, we went with a casual hat suitable for everyday wear. We also wanted to combine a scrapped idea with this hat, so we brought back the glove. The glove, along with the addition of wings, will communicate with the hat wirelessly through hand gestures. The end product would give the wearer an accessory to wear on any occasion, whilst having unique features, adding interactive elements, as well as customisation.

Week 8

Components Research

After completing the design of our project, we researched components that we would utilise to develop a better understanding of how they work and how to implement them with Arduino.

Wireless Module

We researched wireless modules and how they can be used with Arduino, so we can use them to make our hat and glove communicate with each other. We ended up ordering a NRF24L01, a good module for wireless communication between 2 Arduinos with close proximity.

Gyroscope

A gyroscope to be used to detect movement in angles, which will determine the movements of the wings on the hat. Specified angle ranges would result in different wing movements. We decided the MPU6050 module would be most suitable to meet our task’s goals as it can detect angles and acceleration.

Mini Servo

We saw mini servos as the best way to make the wings move and most suitable for the movements we wanted to implement. They would also be small enough to fit into the hat while also managing to hold up the wings.

NeoPixel Ring 16

We wanted to add LEDs placed in the shape of a heart on our hat and glove, but instead we found that a NeoPixel Ring would be much more efficient to use as it would connect to one pin, as opposed to multiple LEDs which would be a hassle to keep control of. The NeoPixel can have various colours and different light animations, which would work well with our project and can be controlled with sensors in the glove.

GSR Sensor

We knew we wanted additional features that would add a small health aspect to our product. Because of this, we also chose to incorporate a GSR sensor which measures the amount of sweat produced. Along with being able to indicate if someone has just done exercise, the amount of sweat can also correspond to the user’s emotional state. We plan to use this to manage change in hues of the NeoPixel on the glove.

Week 9

Prototype

Bottom – first prototype, Middle – second prototype, Top – final wing, chosen.

We began prototyping the wings first, in order to attach them to servos and test their movement. The wings were crocheted by Sahra, and originally were white and light blue. The next wing prototype was a larger size, to better match the hat. After considering our hat’s aesthetics and asking a couple stakeholders on their preference, we decided to use wings with brown stitching instead of light blue, to better match the colour scheme.

Testing the gyroscope with servo motors

Week 10

After prototyping, we started to implement the real functionalities of the final product. To ensure a proper functionality of each component, each was tested separately and then each functionality was combined with another until all functionalities are working out simultaneously. Unfortunately, not all features worked well with the wireless module. The servo and animation feature would not send from transmitter to receiver so we had to compromise by limiting servo movements to the gyroscope and switching animations from being triggered by the glove sensors to being activated by a button on the hat.

Testing the wireless communication between the force sensor and the ring
Testing the mood ring with the stress measuring sensor
Testing the wireless communication between the force sensor and the ring Testing multitasking of the microcontroller with two features: wirelessly changing colour with force sensors and altering animation by a button

Week 11

We were working on combining multiple features and debugging errors we came across. Further investigation of enhancing the code and using more comprehensive commands has been done to enable the better functionality performance.

Combining wireless colour changing feature with wings flapping controlled by servos and gyroscope, making sure they can function sumultaneously
Testing all functionalities together

It was hard to get many videos of the hat working using batteries because the Arduino drained them so quickly. Here we manage to show the hat’s light animation and servo feature working with the Arduino inside of the hat and a battery powering it. As you can see, pressing the button flicks through a variety of animations, while moving your head causes the wings attached to the servos to move.

Project Task List

WeekTaskMember(s)
7Topic selection
Project brainstorm, exploring ideas
All members
8Research components:
Wireless module
Gyroscope/Servo
Galvanic sensors, LDR
All members
Shahd
Sahra
Nimat
9Prototypes
Order components
Hard coding, testing separate functions and components
All members
10Assembling circuits
Making wings
Coding functions
Order components
Plan/organise portfolio
All members
Sahra
All members
Shahd
Nimat
11Debugging
Further assembling of components
Combining materials to components
Portfolio/design blog
Testing
Sahra, Shahd
All members
Sahra
Nimat
Sahra, Shahd
Task List
Gantt Chart

Maker Manual

Overview

Tools and Components

Glove (Transmitter)

  • 1 NeoPixel Ring 16 
  • 1 NRF24L01 (Wireless module) 
  • 1 10uF Capacitor
  • 1 GSR sensor 
  • 2 round force sensitive resistors 
  • 4 AA 1.5V batteries 
  • 1 Arduino Uno 
  • 1 Breadboard 
  • Wires 

Hat (Receiver)

  • 1 NeoPixel Ring 16 
  • 1 NRF24L01 (Wireless module) 
  • 1 10uF Capacitor
  • 1 MPU6050 (Gyroscope/Accelerometer) 
  • 2 mini servos 
  • 1 button 
  • 4 AA 1.5V batteries 
  • 1 Arduino Uno 
  • 1 Breadboard 
  • Wires 

Circuit Layout

Transmitter

Receiver

How To Build

Code

Transmitter

// Code 1: Sending Text (Transmitter)
#include <SPI.h>
#include <RF24.h> //Wireless Module Libraries
#include <nRF24L01.h>
#include <Adafruit_NeoPixel.h> //RGB 16 LED Ring Library
RF24 radio(9, 8); //Pins for wireless module (CE, CSN)
const byte address [10] = "ADDRESS01"; //Address for radio communication
char color [][7] = {"C0", "C1", "C2", "C3", "C4", "C5"}; //Array of colour numbers to be sent to Receiver
const int FSR_THUMB = A0; //Pin for force sensor at the thumb
const int FSR_RING = A1; //Pin for force sensor at the ring finger
int thumbReading = 0; //Reading from thumb's force sensor
int ringReading = 0; //Reading from ring finger's force sensor
int countColour = 0; //Pointer for color array


const int GSR = A5; //Pin for sweat sensor
int sensorValue; //Reading from sweat sensor
int LED_PIN = 6; //NeoPixel Pin
int LED_COUNT = 16; //Number of LEDs on the NeoPixel
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); //Declare NeoPixel strip object
int brightness = 20; //brightness of NeoPixel
int ledColour; //Colour of NeoPixels
int blueColour = 0; //Blue hue of NeoPixel
int greenColour = 60; //Green hue of NeoPixel
int redColour = 60; //Red hue of NeoPixel
unsigned long timer = 0; //Variable used with millis() when tracking GSR reading


void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(address); //Set destination address
  radio.setPALevel (RF24_PA_MIN); //Adjust power level to minimum as modules will be close together
  radio.stopListening(); //The Transmitter does not receive data
  strip.begin();
}
void loop(){
  sweatBlue(); //Call function for using GSR sensor
  sensorTapping(); //Call function for reading force sensors and sending data to receiver
}
void showColour(uint32_t color, int brightness) { //Function to show a given colour and brightness
  for (int i = 0; i < strip.numPixels(); i++) {
    uint8_t red = (color >> 16) & 0xFF;
    uint8_t green = (color >> 8) & 0xFF;
    uint8_t blue = color & 0xFF;


    strip.setPixelColor(i, strip.Color(red * brightness / 255, green * brightness / 255, blue * brightness / 255));
    strip.show();
  }
}
void sweatBlue() { //Function to change colour of NeoPixel on glove to display level of sweat
  if (millis() - timer >= 100) { //This should happen every 100ms
    sensorValue=analogRead(GSR);
    blueColour = map(sensorValue, 0, 800, 255, 0); //Map the sweat sensor value to be used as the blue hue for the NeoPixel's colour
    Serial.println(sensorValue);
    ledColour = strip.Color(redColour, greenColour, blueColour);
    showColour(strip.Color(redColour, greenColour, blueColour), brightness); //Put the new blue value into the NeoPixel
    timer = millis(); //Update timer
  }
}
void sensorTapping() { //Function to check if ring finger and thumb are pressed together
  thumbReading = analogRead(FSR_THUMB);
  ringReading = analogRead(FSR_RING);
  Serial.println("thumb" + String(thumbReading)); //Used for testing if sensors are being read correctly
  Serial.println("ring" + String(ringReading));
  delay(1000); //Delay of 1 second to make sure one finger tap isnt registered as multiple taps
  if ((thumbReading > 400) && (ringReading > 400)) { //Colour change when force exceeds 400
    if (countColour < 5) {
      countColour++; //Increment pointer in color array
    } 
    else {
      countColour = 0; //reset pointer to index 0 when it exceeds index 4
    }
    radio.write(&color[countColour], sizeof(color[countColour])); //Send the new colour to Receiver
    Serial.print("Text: ");
    Serial.println(color[countColour]); //Used to test if pointer at color array has been changed
    delay(500); //Delay of 0.5 seconds to make sure one finger tap isnt registered as multiple taps
  }
}

Receiver

// Code 1: Sending Text (Receiver)
// Library: TMRh20/RF24 (https://github.com/tmrh20/RF24/)
#include <SPI.h>
#include <RF24.h> //Wireless Module Libraries
#include <nRF24L01.h>
#include <Adafruit_NeoPixel.h>//RGB 16 LED Ring Library
#ifdef __AVR__
#include <avr/power.h> //Required for 16 MHz Adafruit Trinket
#endif
#define LED_PIN    6 //NeoPixel pin
#define LED_COUNT 16 //Number of LEDs on the NeoPixel
#define BUTTON_PIN   7 //Pin for button
#include <Servo.h> //Servo Library
#include <MPU6050_tockn.h> //Gyroscope/Accelerometer module
#ifdef __AVR__
 #include <avr/power.h> //Required for 16 MHz Adafruit Trinket
#endif
bool oldState = HIGH; //Variable to store the button's old state
int showType = 0; //Variable for the animation number used to as an argument for startshow function


Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); //Declare NeoPixel strip object


int pos = 0; //Initialise position of servo
int brightness = 50; //Initialise brightness of NeoPixel
RF24 radio (9, 8); //CE and CSN pins
const byte address [10] = "ADDRESS01"; //Variable for the host and receiver
int animation_count = 0; //Pointer for animation array
int countColour = 0; //Pointer for colours array
uint32_t colours[] = { //Array of colours to be 
  strip.Color(0, 255, 0), //Green
  strip.Color(255, 0, 0), //Red
  strip.Color(0, 0, 255), //Blue
  strip.Color(255, 255, 0), //Yellow
  strip.Color(255, 0, 255), //Magenta
  strip.Color(0, 0, 0) //Off
};


MPU6050 mpu6050(Wire); //Creating MPU6050 object
float x; //x rotation value from MPU6050 module
float y; //y rotation value from MPU6050 module
float z; //z rotation value from MPU6050 module
float prevX; //Saving the x rotation value from the previous 1/2 second
float prevY; //Saving the y rotation value from the previous 1/2 second
float prevZ; //Saving the z rotation value from the previous 1/2 second
float xDiff; //Difference in x rotation within 1 second
float zDiff; //Difference in z rotation within 1 second
unsigned long timer = 0; 
unsigned long timer2 = 0; //Variables to be used when implementing millis() for multitasking
unsigned long timer3 = 0;


//Class for multitasking servos reused from https://learn.adafruit.com/multi-tasking-the-arduino-part-1/overview


class Sweeper { //Declaring a class for the servos to work with multitasking


  Servo servo; //The servo 
  int pos; //Current servo position  
  int increment; //Increment to move for each interval 
  int  updateInterval; //Interval between updates 
  unsigned long lastUpdate; //Last update of position 


public:
  Sweeper(int interval, int inputIncrement) { //Method to create instance of Sweeper class
    updateInterval = interval;
    increment = inputIncrement;
  } 


  void Attach(int pin) { //Method that causes wings to move
    servo.attach(pin); //Attach servo in order to move
  } 


  void Detach() { //Method that causes wings to stop moving
    servo.detach(); //Detach servo in order to halt it
  } 


  void Update() {  //Increment servo using the argument
    if((millis() - lastUpdate) > updateInterval) { //Using millis() to allow for multitasking
      lastUpdate = millis(); 
      pos += increment; //Move wing forwards until it reaches 80 degrees
      servo.write(pos); 
      if ((pos >= 80) || (pos <= 0)) { //Wing moves 80 degrees backwards
        increment = -increment; //Reverse direction 
      } 
    } 
  } 
};


Sweeper sweeper1(5, 5); //Left wing will move 5 degrees every 5 milliseconds
Sweeper sweeper2(5, 5); //Right wing will move 5 degrees every 5 milliseconds


void setup() {
  pinMode(BUTTON_PIN, INPUT); //Set button pin mode to input
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address); //Set up radio to listen on pipe 0 with address "ADDRESS01"
  radio.setPALevel(RF24_PA_MIN); //Adjust power level to minimum as modules will be close together
  radio.startListening(); //The Transmitter does not receive data
  Wire.begin();
  mpu6050.begin();
  mpu6050.calcGyroOffsets(true); //Used to remove the other forces acting on the gryoscope
  sweeper1.Attach(3); //Attach left servo to pin 3
  sweeper2.Attach(5); //Attach right servo to pin 5
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  strip.begin();
  strip.show();
  showColour(strip.Color(255, 255, 255), 50); //Start program by setting colour to white and brightness to 50
  strip.setBrightness(50); //Set the LEDs brightness to 50
}
void loop() {
  changecolor(); //Call function that changes colour when a message is sent from the transmitter
  gyroServo(); //Call function that combines MPU6050 and servos
  animationButton(); //Call function that uses a button to change light animations
}
void changecolor() { //Function to change the colour of light when message is sent from the transmitter
  while (radio.available()) { //While the transmitter and receiver are connected
    char txt[4] = ""; //Create a blank array of characters where the message sent from the transmitter will be stored
    radio.read(&txt, sizeof(txt)); //Read the message being sent from transmitter and store it in the txt array
    Serial.println(txt); //Display to see if anything is being sent from the transmitter
    if (txt[0] == 'C') { //If a colour change is being initiated...
      if (txt[1] == '1') { //(Number corresponds to how many times user has pressed force sensor)
        Serial.print("text: "); 
        Serial.print(txt[0]); //Display to see if what's being sent from the transmitter is being received
        Serial.println(txt[1]);
        showColour(colours[0], 50); //Display the appropriate colour from the array according to the number that's being received
      } else if (txt[1] == '2') {
        Serial.print("text: ");
        Serial.print(txt[0]); //Display to see if what's being sent from the transmitter is being received
        Serial.println(txt[1]);
        showColour(colours[1], 50); //Display the appropriate colour from the array according to the number that's being received
      } else if (txt[1] == '3') {
        Serial.print("text: ");
        Serial.print(txt[0]); //Display to see if what's being sent from the transmitter is being received
        Serial.println(txt[1]);
        showColour(colours[2], 50); //Display the appropriate colour from the array according to the number that's being received 
      } else if (txt[1] == '4') {
        Serial.print("text: ");
        Serial.print(txt[0]); //Display to see if what's being sent from the transmitter is being received
        Serial.println(txt[1]);
        showColour(colours[3], 50); //Display the appropriate colour from the array according to the number that's being received
      } else if (txt[1] == '5') {
        Serial.print("text: ");
        Serial.print(txt[0]); //Display to see if what's being sent from the transmitter is being received
        Serial.println(txt[1]);
        showColour(colours[4], 50); //Display the appropriate colour from the array according to the number that's being received
      } else if (txt[1] == '0') {
        Serial.print("text: ");
        Serial.print(txt[0]); //Display to see if what's being sent from the transmitter is being received
        Serial.println(txt[1]);
        showColour(colours[5], 50); //Display the appropriate colour from the array according to the number that's being received
      }
    }
  }
}
void showColour(uint32_t color, int brightness) { //Function to show a given colour and brightness
  for (int i = 0; i < strip.numPixels(); i++) {
    uint8_t red = (color >> 16) & 0xFF;
    uint8_t green = (color >> 8) & 0xFF;
    uint8_t blue = color & 0xFF;
    strip.setPixelColor(i, strip.Color(red * brightness / 255, green * brightness / 255, blue * brightness / 255));
    strip.show();
  }
}
void gyroServo() { //Function to move servos according to the gyroscope movements
  sweeper1.Update(); 
  sweeper2.Update(); //Update state of servos everytime the gyroscope is checked
  mpu6050.update();  //Update gyroscope to check position of the board(hat)
  x = mpu6050.getAngleX(); //Read rotation on x axis
  y = mpu6050.getAngleY(); //Read rotation on y axis
  z = mpu6050.getAngleZ(); //Read rotation on z axis
  if (millis() - timer > 500) { //Every 1/2 second, record the gyroscope position
    prevX = x;
    prevZ = z;
    timer = millis();
  }
  if (millis() - timer2 > 1000) { //Every second, record the difference between the previous gyroscope position and current one
    xDiff = prevX - x;
    zDiff = prevZ - z;
    timer2 = millis();
  }
  if (zDiff>15 || zDiff<-15) { //Move both wings when the hat is moved at least 15 degrees on the z axis in a second
    sweeper1.Attach(3);
    sweeper2.Attach(5);
    Serial.println(zDiff);
  } else if (xDiff>20 || xDiff<-20) { //Move both wings when the hat is moved at least 15 degrees on the z axis in a second
    sweeper1.Attach(3);
    sweeper2.Attach(5);
    Serial.println(xDiff);
  } else if (y>30) { //Rotating hat past 30 degrees to the right on the y axis causes left wing to move
    sweeper1.Attach(3);
  } else if (y<-30) { //Rotating hat past 30 degrees to the left on the y axis causes right wing to move
    sweeper2.Attach(5);
  } else { //If none of these conditions are met, wings do not move
    sweeper1.Detach();
    sweeper2.Detach();
  }
  if (millis() - timer3 > 3000) { //Used to see if gyroscope is responding and working correctly
    Serial.print("angleX : ");Serial.print(x);
    Serial.print("  angleY : ");Serial.print(y);
    Serial.print("  angleZ : ");Serial.print(z);
    Serial.println("");
    timer3 = millis(); //millis() used instead of delay() to not interfere with multitasking features
  } 
}
void animationButton() { //Function that changes animation when button is pressed
  bool newState = digitalRead(BUTTON_PIN); //Get current button state
  if (newState == LOW && oldState == HIGH) { //Check if button is pressed
    delay(20); //Short delay to debounce button
    newState = digitalRead(BUTTON_PIN); //Check if button is still low after debounce
    if (newState == LOW) { //If button is pressed, increment variable that keeps track of the animation type
      showType++; 
      if (showType > 9) //Theres 9 animations, so reset variable to 0
        showType=0;
      startShow(showType);
    }
  }
  oldState = newState; //Set the last button state to the old state
}
void startShow(int i) { //Function used to display different animations
  switch(i){
    case 0: colorWipe(strip.Color(0, 0, 0), 50); //Off
            break;
    case 1: colorWipe(strip.Color(255, 0, 0), 50); //Red
            break;
    case 2: colorWipe(strip.Color(0, 255, 0), 50); //Green
            break;
    case 3: colorWipe(strip.Color(0, 0, 255), 50); //Blue
            break;
    case 4: theaterChase(strip.Color(127, 127, 127), 50); //White
            break;
    case 5: theaterChase(strip.Color(127,   0,   0), 50); //Red
            break;
    case 6: theaterChase(strip.Color(  0,   0, 127), 50); //Blue
            break;
    case 7: rainbow(20);
            break;
    case 8: theaterChaseRainbow(50);
            break;
  }
}


//Animation function - Reused from Adafruit NeoPixel example code 'strandtest'


void colorWipe(uint32_t color, int wait) { //Animation 1
  for(int i=0; i<strip.numPixels(); i++) { //For each pixel in strip...
    strip.setPixelColor(i, color); //Set pixel's color (in RAM)
    strip.show(); //Update strip to match
    delay(wait);
  }
}
void theaterChase(uint32_t color, int wait) { //Animation 2
  for(int a=0; a<10; a++) {  // Repeat 10 times...
    for(int b=0; b<3; b++) { //'b' counts from 0 to 2...
      strip.clear(); //Set all pixels in RAM to 0 (off)
      //'c' counts up from 'b' to end of strip in steps of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color); //Set pixel 'c' to value 'color'
      }
      strip.show(); //Update strip with new contents
      delay(wait);  //Pause for a moment
    }
  }
}
void rainbow(int wait) { //Animation 3
  for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
    strip.rainbow(firstPixelHue);
    strip.show(); //Update strip with new contents
    delay(wait);
  }
}
void theaterChaseRainbow(int wait) { //Animation 4
  int firstPixelHue = 0; //First pixel starts at red (hue 0)
  for(int a=0; a<30; a++) { //Repeat 30 times...
    for(int b=0; b<3; b++) { //'b' counts from 0 to 2...
      strip.clear(); //Set all pixels in RAM to 0 (off)
      //'c' counts up from 'b' to end of strip in increments of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        //hue of pixel 'c' is offset by an amount to make one full
        //revolution of the color wheel (range 65536) along the length
        //of the strip (strip.numPixels() steps):
        int      hue   = firstPixelHue + c * 65536L / strip.numPixels();
        uint32_t color = strip.gamma32(strip.ColorHSV(hue)); //hue -> RGB
        strip.setPixelColor(c, color); //Set pixel 'c' to value 'color'
      }
      strip.show(); //Update strip with new contents
      delay(wait); //Pause for a moment
      firstPixelHue += 65536 / 90; //One cycle of color wheel over 90 frames
    }
  }
}
uint32_t Wheel(byte WheelPos) { //Animation 4
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else if(WheelPos < 170) {
    WheelPos -= 85;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
}

Testing & Shortcomings

Multitasking with Arduino

Servo Rotation

Initially we utilized For loops in order to make the servos move. However, this proved to not work very well in the grand scheme of the project, as we had many features that required multitasking. In order to combat this issue, we added a Sweeper class that used millis() in one of the methods. Using millis(), the servo is incremented by 5 degrees every 5 milliseconds after creating 2 Sweeper objects such that Sweeper sweeper1(5, 5) and Sweeper sweeper2(5, 5).

Screenshot 1 code snippet with for loops()

Animation Control

Each animation is a sequence of LEDs with changing colors. There is a delay for each sequence to be displayed. We tried to use millis(), but it could not break out of the while or for loops when the button is triggered. To overcome this limitation, we opted to reduce the animation duration instead of endlessly looping, in order to allow the button to trigger a change in the animation sequence. The animation functions are called in switch cases instead of while loops.

Screenshot 1 code snippet with While loops
Screenshot 2 code snippet with switch case

Wireless Communication

The NRF24L01 transceiver disconnected while testing. The two microcontrollers for the host and transmitter had to be reset before starting to send texts. When another functionality was implemented to change the color animation based on a different text message, the receiver could not configure it. The communication lagging happened due to various reason such as noise interference and short distance between the host and receiver.

For future improvements, ESP-01 WiFi or HC-12 SI4463 is recommended to establish the wireless communication because of the high noise prevention. Additionally, instead of altering animations using a button, another force sensor can be implemented on the glove so that with thumb and index tapping, the ring displays various animations.

Components and Batteries Assembly:

The weight of components is not convenient for a hat-glove set, so it is recommended to design a PCB that has all components mounted to it. The glove would also benefit if an Arduino Nano was used instead of an Uno, but our Nano had compatibility issues which is why we stuck to using an Uno. The batteries assembly is unsafe to be right next to the wearer’s head or hand as they might explode. For safety, a couple of fuses or battery switches should implemented.