Skip to the content.

Gesture Controlled Robot

My project is the Gesture Controlled Robot. The robot is a car that can be controlled with gestures performed on a gauntlet that rests on your hand. Whenever you tilt the gauntlet forwards, backward, right, or left, the robot moves correspondingly. A modification that I added lets me control a robotic arm on the front of the car to pick things up. The arm is also controlled on the gauntlet, but instead of tilting, it is controlled by joysticks.

Engineer School Area of Interest Grade
Joshua L Leigh High School Mechanical Engineering Incoming Sophomore

Headstone Image

Modification

Description

Since my third milestone, I have attached a robotic arm to the top of my robot. For the first two days, I worked on constructing the hardware of the robotic arm and wiring the joysticks to the NANO shield. Afterwards, I spent a week debugging the Bluetooth connection and coding the robotic arm’s movement while also creating a 3D-designed mount that goes on top of the original robot. The robotic arm is mounted onto the gesture-controlled robot, which benefits the arm’s mobility and the gesture-controlled robot’s ability. Without being mounted onto the gesture-controlled robot, the robotic arm is stationary with little to no mobility. This restricts the capability of the arm to a 6-inch radius of reach, unlike an unlimited reach with the gesture-controlled robot.

Challenges

I faced many challenges incorporating the robotic arm into the gesture-controlled robot, but the two biggest challenges were the Bluetooth connection and broken pieces. When I first tried to connect my Bluetooth from the joystick to the arm, I didn’t realize that the HC-O5s I was using were faulty. The HC-O5s would not connect even if I set them in the correct master-slave relationships. But luckily, after swapping the HC-O5s out and watching a tutorial for the connection, the Bluetooth connection worked flawlessly. It turned out the HC-O5s were broken, but I was also mixing up the CMODE and ROLE commands in AT mode. The other challenge that I faced was two broken pieces. When I was trying to reset one of my servos to 90 degrees, two parts connecting the arm to the base snapped off. This stopped me from attaching the robotic arm to the gesture-controlled robot and delayed everything when I only had three days left. Another small challenge that I faced was stripped screws. When mounting the robotic arm onto my 3D printed design, I stripped two screws, so I had to drill some new holes.

What’s Next?

Next up is my demo night presentation, where I will demonstrate how my project works, what I learned, and the challenges I’ve faced.

3D Robotic arm modification

label Figure 1: Design drawing of my robotic arm mount

label Figure 2: Image of the completed project

How it works

Servos (MG90S)

label Figure 3: Diagram of an MG90S servo

This servo contains four different components: a DC motor, a gearbox, a control circuit, and a potentiometer. The DC motor is the primary component that provides the mechanical power for rotation, and the gearbox is a series of gears that reduce the motor’s speed while increasing torque, allowing for precise movement in degrees. Additionally, the control circuit is the brain of the servo. It receives signals from an external controller, in this case the NANO, processes them, and then determines the position, speed, and torque required for the motor shaft. Lastly, the potentiometer acts as a feedback mechanism, monitoring the motor’s current position and reporting it back to the control circuit. The servo uses all of these components to determine how it should move.

Joystick

label Figure 4: Image of the joystick in my project

The joystick consists of three different components: a potentiometer, a handle, and a centering mechanism. A potentiometer is the core of the joystick module. There are two potentiometers mounted at 90-degree angles to each other. One potentiometer handles movement along the X-axis (left/right), and the other handles movement along the Y-axis (up/down). Next, the handle is a physical stick that is connected to the potentiometers. Moving the handle causes the wipers of the potentiometers to move, changing their resistance. The change in resistance is then read by the analog pin, which is how the position of a joystick is determined in a computer. Lastly, the centering mechanism springs the joystick into the resting position, which is how it always returns to its original position. The joystick uses all these components to function and relay information about its position to a computer.

Final Milestone

Description

This is the final milestone of my project, excluding the modifications, and it turned out well. Since my previous milestone, I have 3D printed cases for my circuit boards so they attach to the base. The reason for this is that they would keep sliding around, and these 3D cases hold them in place. Furthermore, I was able to 3D print a frame that encases the robot. To incorporate this into my robot, I plastic-welded the joints (as seen in Figures 5 and 6) so they stuck together nicely. The plastic welding process starts with a soldering iron to heat both sections until they melt into each other. Then, you would have to use buffering tools to create a clean finish. The frame will let me attach modifications on top of the car and hide all the wires inside.

Since this is the last regular milestone of my project, I will explain how my gesture-controlled robot works. The first step to this is understanding the drivetrain. The drivetrain consists of four components: the base, motors, wires, and wheels. The motors are attached to the base plate and have two soldered wires - one positive and one negative - which are connected to the four ports on the right and left sides of the L280N. These are the input ports that enable the motors to be programmed through simple high/low commands(as shown at the bottom of the website).

The L280N is crucial for the robot’s functionality, which brings us to the second major system, the circuit boards. My project includes one L280N, one Arduino UNO, one MPU-6050, and one NANO board. Each circuit board controls its sector of my project, but they interact in unique ways. For example, the movement of the car is controlled by four main boards. The Arduino UNO, L280N, NANO, and MPU-6050. Both the UNO and L280N boards are located on the Gesture-controlled robot’s drivetrain, while the MPU-6050 and NANO boards are situated on a separate console. The reason for this is that the MPU-6050 is what makes my project “gesture-controlled,” and it is wirelessly connected to the robot so it can read the tilt of someone’s hand. This tilt information is processed by the NANO and sent to the UNO board, which sends the data to the L280N. The L280N then takes in the data to control the motor movement.

Another important part of this project is Bluetooth. The Bluetooth allows wireless communication, and in my project, I used 2 HC-O5s to communicate via Bluetooth (explanation of an HC-O5 shown in Figure 6). One HC-O5 is wired to the Arduino UNO, and one is connected to the NANO. The HC-O5 wired to the NANO board sends the information of the accelerometer over to the HC-O5 on the UNO board, which then runs it through the code. The resulting data is then sent over to the L280N (through analog), and the motors move in a direction depending on the data sent over.

This whole process is happening simultaneously and is how the gesture-controlled robot functions.

Challenges

A challenge I faced was when I was putting on the frame of the robot. The orientation of the Arduino UNO case was positioned in a way so that the ports were not accessible when I put the frame on. So, I turned the UNO case around, but I had a new problem: the frame didn’t fit. Luckily, after filing the UNO case, the frame fit in its place.

What’s Next?

Now that I have finished the non-modified robot, I will spend the rest of my time on modifications such as a robotic arm and LEDs.

CAD 3D Designs

label Figure 5: Design drawing for Arduino Case label

Figure 6: Case for the Arduino UNO - screw holes go through the lip on the right side of the case.

label Figure 7: Design drawing for L280N case label

Figure 8: Case for the L280N - dips on the right, left, and front allow the wires to pass through. label Figure 11: Design drawing of the back part of the frame label

Figure 9: This is the back section of my frame. The arcs give the wheels space to move, and the joints connect the two parts.

label Figure 10: Design drawing of the front part of the frame label

Figure 11: This is the front section of my frame that will go on my robot. The arcs on the side give the wheels space to turn, and the joints on the end help connect the front and back sections.

Frame installed on the robot

logo

Second Milestone

Description

Since my first milestone, I have worked on the Bluetooth connection and the code that allows the Bluetooth to control the DC motors. I was able to connect the Bluetooth modules to the motors, and now, by simply tilting the second Bluetooth module, I can move the robot forward, backward, right, and left as demonstrated in the code at the bottom of the website. The accelerometer in the MPU-6050 sends the acceleration data to the NANO, which converts the raw acceleration data to AccX, AccY, and AccZ. This data is sent over to the HC-O5 on the robot and used to determine if the robot should stop, turn right, turn left, move forward, or move backward using if-else statements.. During this process, I was surprised by how much easier it became to debug my code once I understood it more.

Challenges

One of the biggest challenges I faced was accidentally flipping the RX and TX pin connections. Before realizing that this was the issue, I spent a lot of time changing the code and writing separate test scripts to identify the problem. When none of those worked, I finally checked the wiring and discovered that I had swapped the RX and TX pins. After correcting that, I also had to replace two dead batteries because the motors did not have enough power to start consistently. Once those two problems were fixed, the robot functioned properly.

What’s Next?

In the 3rd milestone, I will create holding structures for all my circuit boards to keep them in place, and add finishing touches such as organizing the wires and making framing for the whole robot to look aesthetically pleasing.

Flow Chart for Code

label

Figure 12: Flow chart of the code that connects gesture motions to motor movement

First Milestone

Description

My main project is the Gesture Controlled Robot, and I plan to finish it in this camp. The project includes two major components - the 4 DC motors for movement and the Bluetooth connections for control. These two components will work together to move the robot around and display the gesture-controlling feature. By this first milestone, I have completed the hardware for the robot along with the code that controls the motor movement. As seen in Figure 1, the hardware includes the drivetrain, Arduino UNO board, L280N board, Bluetooth receiver, and Bluetooth master. The code I implemented coded the motor movement for the robot. I did this by connecting the Arduino UNO and L280N boards to the motors, which allowed me to easily code the movement through the IN1, IN2, IN3, and IN4 ports. I have also connected the two Bluetooth modules - one master and one slave - so they are now ready to code and control the robot. The master module is seen in Figure 2, and the slave module is found in Figure 1.

Challenges

When configuring the motors for the first time, I realized that one motor on each side was spinning in the wrong direction. When debugging for the first time, I didn’t know what was wrong - the code seemed fine, and there were no errors. But then I realized that I had to physically change the motor polarity for them to move in the correct direction. So, I flipped the two sets of wires connected to the L280N board and was able to fix the motor polarity. Luckily, this robot has a DC motor that can change polarities easily, unlike other motors such as AC and single-phase.

What’s Next?

To finish this project, I have to code the Bluetooth to control the movement of my robot along with adding some modifications.

How it Works

label

Figure 13: Diagram of the MPU-6050

The MPU-6050 is an accelerometer and gyroscope sensor. To measure the acceleration, the accelerometer detects the force exerted on a spring system located inside the MPU-6050. When the accelerometer experiences acceleration, the mass will lag behind due to its inertia, causing a deflection of the spring. This deflection is proportional to the acceleration levels the MPU experiences. In my project, I took the acceleration data from the MPU and converted it to AccX, AccY, and AccZ (which are the levels of acceleration on the x, y, z axes). Using this data, I was able to use if-else statements (code at the bottom of the portfolio) to determine if the robot moved forward, backward, right, or left.

label

Figure 14: Close-up of a Bluetooth HC-O5 module

The HC-05 Bluetooth module is a wireless communication device that uses serial (UART) signals to send and receive data between a microcontroller (like an Arduino UNO) and another Bluetooth device, such as a smartphone or computer. It works like a wireless version of a serial cable, allowing two devices to “talk” to each other over Bluetooth instead of through physical wires. When connected, the HC-05 can receive data through its RX pin and send data through its TX pin. The module operates in either master or slave mode, and it can be reconfigured using AT commands when placed in command mode. This allows you to change things like its name, PIN, and connection settings. For example, in my project, I used an HC-05 on my robot to allow wireless control through a controller.

label

Figure 15: Diagram of the L280N in the robot

The L280N has two H-Bridges, which are electric circuits that allow a DC motor to be driven in both forward and backward directions. This is accomplished by the four switches on the outer parameters of the circuit board. By controlling which switches are on and off, you can easily control the direction the motors spin. For example, if the IN1 and IN3 switches were set to high, and the IN2 and IN4 switches were set to low, then the motors would move forward. Without the help of the L280N, which changes the way the current flows to easily change the polarity of the motor, you would have to manually change the polarity of the DC motor to change the direction it’s spinning. I used an L280N in my robot to control the direction of the four DC motors on the drivetrain and connect the batteries to all the other hardware. Each H-bridge is connected to one pair of motors on each side, which is seen in Figure 3 above.

label

Figure 16: Diagram of an Arduino UNO used in the project

label

Figure 17: Diagram of an Arduino Nano used in this project

Microcontrollers

In my project, I have two different microcontrollers - The Arduino UNO and Arduino NANO. The difference between the two is that the NANO is breadboard-friendly, which allows it to be portable, while the UNO is much larger and has more ports. The purpose of these microcontrollers is to process the code into the other components. They act like small specialized computers that allow the robot to function without being plugged into a laptop.

Schematics of the Hardware on my Gesture-Controlled Robot

Screenshot 2025-06-23 at 10 35 58 AM

Figure 18: Schematic of the Gesture Controlled Robot’s hardware - Arduino UNO, L280N, 4 DC motors, 4 AAA batteries, and HC-O5

Screenshot 2025-06-23 at 10 36 30 AM

Figure 19: Schematic of Bluetooth sending module (gauntlet) - HC-O5, MPU 6050, and Arduino NANO

Starter Project (Milestone)

Description

For my starter project, I chose to do the RGB slider. The reason for this is that I wanted to design headlights and taillights for my gesture-controlled robot that turn on when I move forward or backward. This project gave me experience in coding LEDs, which will help me make these modifications to my final project. The RGB slider is a small board that contains three RGB sliders, an LED, and a USB-C port. The three RGB sliders control an LED. Three colors - blue, red, and green - are mixed to display different colors on the LED. As you slide the sliders up and down, the strength of the color increases or decreases. There are almost an infinite number of color combinations I can use to light up my LED, and everything on the board is powered by a USB-C that is connected to my laptop.

Challenges

Challenges that I faced while making the RGB slider included soldering too much and soldering the whole board upside down. As easy as this project was, I forgot to ask my instructor if I was doing everything on the right side. This made me have to redo the entire RGB slider on the other side of the board. To do this, I unsoldered everything and resoldered it on the other side.

What’s Next?

The next thing I will do is create my main project - the gesture-controlled robot.

Bill of Materials

Part Note Price Link
Arduino UNO Used to interpret the information from HC-O5 and send it to the L280N for motor movement $27.60 Link
L280N Used to move the dc motors $2.50 Link
Robot drivetrain kit Used for the 4 DC motors, wheels, and base $24.54 Link
Arduino NANO Used to interpret informationn from then MPU-6050 and send to the HC-O5 $25.70 Link
HC-O5 Used for wirless communication $9.99 Link
MPU-6050 Used for its accelerometer, and it reads the gestures $1.39 Link
Breadboard Used to connect circuit boards and HC-O5’s together with help of wires $0.99 Link
Wires Used to connect everthing $0.99 Link
Robotic Arm Kit I used this as my modification and it is mounted on the top of my gesture-controlled robot $48.99 Link
4 MG90S servos used in my robotic arm joints $13.99 Link
AA battery holders (5 batteries in each holder) used to power robotic arm and gesture-controlled robot $7.99 Link

Sources

Appendix

Joystick Data Sending Code

#include <SoftwareSerial.h>       // installs the softwwareserial.h and servo.h libraries 
#include <Servo.h> 

SoftwareSerial Bluetooth(2, 3);   // Sets the RX TX pins (2 TX, 3 RX)

                                  // Servo objects
Servo servobase;
Servo servobody;
Servo servoneck;
Servo servohead;

                                  // current and target positions
float basePos = 80;
float bodyPos = 90;
float neckPos = 90;
float headPos = 90;

int baseTarget = 80;
int bodyTarget = 90;
int neckTarget = 90;
int headTarget = 90;

                                  // default servo positions
const int baseHome = 80;
const int bodyHome = 90;
const int neckHome = 90;
const int headHome = 90;

// Inactivity timer
unsigned long lastCommandTime = 0;
const unsigned long timeoutDuration = 5000;  // 5 seconds

char data;                                   // sets data variable as a char variable

void setup() {
  Serial.begin(9600);             // starts checking in buffer zone for data 
  Bluetooth.begin(9600);          // in bluetooth and serial mode

  
  servobase.attach(4);            // gives each class a pin and attaches servos
  servobody.attach(5);
  servoneck.attach(6);
  servohead.attach(7);

                                  // moves to initial positions
  servobase.write(basePos);       
  servobody.write(bodyPos);
  servoneck.write(neckPos);
  servohead.write(headPos);

  lastCommandTime = millis();  // starts timer
}

void loop() {
  // Check for Bluetooth commands
  if (Bluetooth.available()) {        // checks if bluetooth data/connection is availble
    data = Bluetooth.read();          // sets definiton for data to bluetooth.read
    Serial.print("Received: ");       // serial prints recived
    Serial.println(data);             // prints the data 
    lastCommandTime = millis();

    
    if (data == 'F') bodyTarget = constrain(bodyTarget + 10, 0, 180);       // if certain data is sent then 
    else if (data == 'B') bodyTarget = constrain(bodyTarget - 10, 0, 180);  // the servo coresponding with the information will move 10 degrees  
    else if (data == 'R') baseTarget = constrain(baseTarget + 10, 0, 180);  // forwards or backwards
    else if (data == 'L') baseTarget = constrain(baseTarget - 10, 0, 180);
    else if (data == 'O') headTarget = constrain(headTarget + 10, 0, 180);
    else if (data == 'C') headTarget = constrain(headTarget - 10, 0, 180);
    else if (data == 'U') neckTarget = constrain(neckTarget + 10, 0, 180);
    else if (data == 'D') neckTarget = constrain(neckTarget - 10, 0, 180);
  }

                                              // for smooth transition toward target positions 
  basePos += (baseTarget - basePos) * 0.1;
  bodyPos += (bodyTarget - bodyPos) * 0.1;
  neckPos += (neckTarget - neckPos) * 0.1;
  headPos += (headTarget - headPos) * 0.1;

                                              // writing (over bluetooth) smoothed positions to servos
  servobase.write((int)basePos);
  servobody.write((int)bodyPos);
  servoneck.write((int)neckPos);
  servohead.write((int)headPos);

                                              //if no input is detected for 5 secs the servos will reset
  if (millis() - lastCommandTime > timeoutDuration) {
    baseTarget = baseHome;
    bodyTarget = bodyHome;
    neckTarget = neckHome;
    headTarget = headHome;

    Serial.println("No input — resetting to default position."); // serial prints no input dected
    lastCommandTime = millis();                                   // prevents repeated resets
  }

  delay(20);                                            // delay for smoothness in controls
} ```end 

Robotic Arm Reciver Code for Modifcations

#include <SoftwareSerial.h>       // installs the softwwareserial.h and servo.h libraries 
#include <Servo.h> 

SoftwareSerial Bluetooth(2, 3);   // Sets the RX TX pins (2 TX, 3 RX)

                                  // Servo objects
Servo servobase;
Servo servobody;
Servo servoneck;
Servo servohead;

                                  // current and target positions
float basePos = 80;
float bodyPos = 90;
float neckPos = 90;
float headPos = 90;

int baseTarget = 80;
int bodyTarget = 90;
int neckTarget = 90;
int headTarget = 90;

                                  // default servo positions
const int baseHome = 80;
const int bodyHome = 90;
const int neckHome = 90;
const int headHome = 90;

// Inactivity timer
unsigned long lastCommandTime = 0;
const unsigned long timeoutDuration = 5000;  // 5 seconds

char data;                                   // sets data variable as a char variable

void setup() {
  Serial.begin(9600);             // starts checking in buffer zone for data 
  Bluetooth.begin(9600);          // in bluetooth and serial mode

  
  servobase.attach(4);            // gives each class a pin and attaches servos
  servobody.attach(5);
  servoneck.attach(6);
  servohead.attach(7);

                                  // moves to initial positions
  servobase.write(basePos);       
  servobody.write(bodyPos);
  servoneck.write(neckPos);
  servohead.write(headPos);

  lastCommandTime = millis();  // starts timer
}

void loop() {
  // Check for Bluetooth commands
  if (Bluetooth.available()) {        // checks if bluetooth data/connection is availble
    data = Bluetooth.read();          // sets definiton for data to bluetooth.read
    Serial.print("Received: ");       // serial prints recived
    Serial.println(data);             // prints the data 
    lastCommandTime = millis();

    
    if (data == 'F') bodyTarget = constrain(bodyTarget + 10, 0, 180);       // if certain data is sent then 
    else if (data == 'B') bodyTarget = constrain(bodyTarget - 10, 0, 180);  // the servo coresponding with the information will move 10 degrees  
    else if (data == 'R') baseTarget = constrain(baseTarget + 10, 0, 180);  // forwards or backwards
    else if (data == 'L') baseTarget = constrain(baseTarget - 10, 0, 180);
    else if (data == 'O') headTarget = constrain(headTarget + 10, 0, 180);
    else if (data == 'C') headTarget = constrain(headTarget - 10, 0, 180);
    else if (data == 'U') neckTarget = constrain(neckTarget + 10, 0, 180);
    else if (data == 'D') neckTarget = constrain(neckTarget - 10, 0, 180);
  }

                                              // for smooth transition toward target positions 
  basePos += (baseTarget - basePos) * 0.1;
  bodyPos += (bodyTarget - bodyPos) * 0.1;
  neckPos += (neckTarget - neckPos) * 0.1;
  headPos += (headTarget - headPos) * 0.1;

                                              // writing (over Bluetooth) smoothed positions to servos
  servobase.write((int)basePos);
  servobody.write((int)bodyPos);
  servoneck.write((int)neckPos);
  servohead.write((int)headPos);

                                              //If no input is detected for 5 seconds the servos will reset
  if (millis() - lastCommandTime > timeoutDuration) {
    baseTarget = baseHome;
    bodyTarget = bodyHome;
    neckTarget = neckHome;
    headTarget = headHome;

    Serial.println("No input — resetting to default position."); // serial prints no input dected
    lastCommandTime = millis();                                   // prevents repeated resets
  }

  delay(20);                                            // delay for smoothness in controls
} 

Bluetooth to Motor movement Code for Milestone 2


// Bluetooth to motor movement code - robot

#include <SoftwareSerial.h>        //includes library softwareserial

char data;                         //introduces variable DATA

int enA = 5;                       // sets motor pins
int in1 = 6;                       // in1, right top motor, in2 right bottom motor, in3, left top motor, in4, left bottom
int in2 = 7;
int in3 = 8;
int in4 = 9;
int enB = 10;


SoftwareSerial Bluetooth(2, 3);   //(TX , RX)

void setup() {
  Serial.begin(9600);             //begins serial monitor and sets 9600 baud
  Bluetooth.begin(9600);          //begins bluetooth search and sets 9600 baud
  
  pinMode(enA, OUTPUT);
  pinMode(in1, OUTPUT);           // Sets all ports as outputs
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  pinMode(enB, OUTPUT);
}

void loop() {
  
  if (Bluetooth.available()) {    // checks bluetooth buffezone 
    data = Bluetooth.read();      // sets variable DATA as bluetooth.read
    Serial.println(data);         // prints said DATA

   if (data == 'F') {             //If the data is F, B, L, R, or S, the motor movement aligns
      driveForward();
    } else if (data == 'B') {
      driveBackward();
    } else if (data == 'L') {
      turnLeft();
    } else if (data == 'R') {
      turnRight();
    } else {
      stopMotors();
    }
  }
}

void driveForward() {
  digitalWrite(in1, HIGH); digitalWrite(in2, LOW); analogWrite(enA, 255);  //Motor movement from in1,2,3,4, pins HIGH or LOW to deterime direction
  digitalWrite(in3, HIGH); digitalWrite(in4, LOW); analogWrite(enB, 255);
}

void driveBackward() {
  digitalWrite(in1, LOW); digitalWrite(in2, HIGH); analogWrite(enA, 255);
  digitalWrite(in3, LOW); digitalWrite(in4, HIGH); analogWrite(enB, 255);
}

void turnRight() {
  digitalWrite(in1, HIGH); digitalWrite(in2, LOW); analogWrite(enA, 255);
  digitalWrite(in3, LOW); digitalWrite(in4, HIGH); analogWrite(enB, 255);
}

void turnLeft() {
  digitalWrite(in1, LOW); digitalWrite(in2, HIGH); analogWrite(enA, 255);
  digitalWrite(in3, HIGH); digitalWrite(in4, LOW); analogWrite(enB, 255);
}

void stopMotors() {
  digitalWrite(in1, LOW); digitalWrite(in2, LOW); analogWrite(enA, 0);
  digitalWrite(in3, LOW); digitalWrite(in4, LOW); analogWrite(enB, 0);
}

// end

Accelerometer Data Code for Milestone 2


//Accelerometer Data code - gauntlet code

#include <Wire.h>              // library for I2C communication
#include <SoftwareSerial.h>    // library to use software-defined serial communication

// Set up Bluetooth communication on pins 2 (TX) and 3 (RX)
SoftwareSerial Bluetooth(2, 3); // bluetooth module connected to digital pins 2 and 3

const int MPU = 0x68;          // address of the MPU6050 accelerometer
float AccX, AccY, AccZ;        // variables to store the acceleration values
char lastCommand = ' ';        // to store the last command sent

void setup() {
  Wire.begin();                // starts IC2 communication
  Serial.begin(9600);          // starts Serial monitor communication
  Bluetooth.begin(9600);       // start Bluetooth communication

  // wakes up the MPU6050 by writing 0 
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);            // accesses the power
  Wire.write(0);               // sets it to 0 to wake up the MPU6050
  Wire.endTransmission(true);
}

void loop() {
  // request accelerometer data starting from register 0x3B
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);            
  Wire.endTransmission(false); 
  Wire.requestFrom(MPU, 6, true); // requests 6 bytes (X, Y, Z axes)

  // Combines high and low bytes to get raw acceleration data
  int16_t rawX = Wire.read() << 8 | Wire.read();  
  int16_t rawY = Wire.read() << 8 | Wire.read();  
  int16_t rawZ = Wire.read() << 8 | Wire.read(); 

  // Convert raw values to accx, y, z
  AccX = rawX / 16384.0;
  AccY = rawY / 16384.0;
  AccZ = rawZ / 16384.0;

  char command; // Command to be sent based on tilt

  // Decide which direction to move based on tilt:
  if (AccX > 0.3) 
    command = 'F';            // Tilt forward - Forward
  else if (AccX < -0.3) 
    command = 'B';            // Tilt backward - Backward
  else if (AccY > 0.3) 
    command = 'L';            // Tilt left -  Left
  else if (AccY < -0.3) 
    command = 'R';            // Tilt right - Right
  else 
    command = 'S';            // No tilt - Stop

  // Only send the command if it has changed since last time
  if (command != lastCommand) {
    Bluetooth.write(command);  // send the command to Bluetooth module
    Serial.println(command);   // also print to serial monitor for debugging
    lastCommand = command;     // update the last command
  }

  delay(100);  // Small delay to reduce how often data is sent (every 100 ms)
}
// end 

Motor Movement code for Milestone 1

// Motor movement code

int enA = 5; // sets motor pins
int in1 = 6;
int in2 = 7;
int in3 = 8;
int in4 = 9;
int enB = 10;

void driveforward(){
  digitalWrite(in1, HIGH); //sets motors to drive forwards
  digitalWrite(in2, LOW);
  analogWrite(enA, 255);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  analogWrite(enB,255);
  delay(1000);
}

void drivebackward(){
  digitalWrite(in1, LOW);  //sets motors to drive backwards
  digitalWrite(in2,HIGH);
  analogWrite(enA,255);
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  analogWrite(enB,255);
  delay(1000);
}


void stop(){
  digitalWrite(in1, LOW); //sets motors to LOW or stop
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  delay(1000);
}


void setup(){
  Serial.begin(9600);
  pinMode(enA, OUTPUT); // setting all pins to OUTPUTS
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  pinMode(enB, OUTPUT);

}

void loop(){
  
  driveforward();
  stop();
  drivebackward();
  stop();

}