The goal of this project is to balance an arduino programmed cart autonomously, to balance a Seesaw.

Group Member Names: Dalton Ellis, Jason Ross, Justin Valentine, Ken Aoyagi

Course and Quarter: ENG114

Date: 12/7/2019

Revision Number:

 

Seesaw Car

 

Problem Statement:

 

Our group chose to use an electric motor car to balance a Seesaw.

Hardware Setup

 

 

 Materials:

 

Bill of Materials:

Part Name

Purpose

Item Name

URL

Price

Redboard

Microprocessor

Arduino Uno

https://www.sparkfun.com/products/15123

$20

Arduino and

breadboard holder

Base for breadboard

Arduino and breadboard holder

https://www.sparkfun.com/products/11235

3.95

Motor driver

Controls voltage levels to motors

Dual TB6612FNG

 

https://www.sparkfun.com/products/14450

5.45

accelerometer

Sensing pitch level

MPU 92/65

https://www.banggood.com/buy/mpu-9265.html

12

Hobby gearmotor

Moves vehicle

DG01D

https://www.sparkfun.com/products/13302

4.95

Wheels

Provide rotational inertia and minimal points of contact to board

Wheel

https://www.sparkfun.com/products/13259

2.95

Seesaw

Tilt car

Seesaw

HOMEMADE

N/A

Jumper wires

Facilitates flow of electrons with minimal resistance

Jumper wires

https://www.sparkfun.com/products/11026

2.25

Mini power switch

Turns off power

Mini power switch SPDT

https://www.sparkfun.com/products/102

1.50

 

 

 

 

 

 

Hookup Guide:

 

 

Redboard

Motor Driver

Digital 11

PWMA

Digital 12

A12

Digital 13

A11

Digital 10

PWMB

Digital 8

B11

VIN

VM

5V

STBY






Left motor

Motor driver

Black wire

A02

Red Wire

A01



Right motor

Motor driver

Black wire

B02

Red Wire

B01



Accelerometer

Redboard

SCL

Analog A5

SDA

Analog A4

 

 

 

 

 

 

 

 

 

 

Arduino Code:

 

/*

SparkFun Inventor’s Kit

Circuit 5B - Remote Control Robot

 

Control a two wheeled robot by sending direction commands through the serial monitor.

This sketch was adapted from one of the activities in the SparkFun Guide to Arduino.

Check out the rest of the book at

https://www.sparkfun.com/products/14326

 

This sketch was written by SparkFun Electronics, with lots of help from the Arduino community.

This code is completely free for any use.

 

View circuit diagram and instructions at: https://learn.sparkfun.com/tutorials/sparkfun-inventors-kit-experiment-guide---v40

Download drawings and code at: https://github.com/sparkfun/SIK-Guide-Code

*/

 

#include "MPU9250.h"

 

// an MPU9250 object with the MPU-9250 sensor on I2C bus 0 with address 0x68

MPU9250 IMU(Wire,0x68);

int status;



//the right motor will be controlled by the motor A pins on the motor driver

 

const int AIN1 = 13;           //control pin 1 on the motor driver for the right motor

const int AIN2 = 12;            //control pin 2 on the motor driver for the right motor

const int PWMA = 11;            //speed control pin on the motor driver for the right motor

 

//the left motor will be controlled by the motor B pins on the motor driver

const int PWMB = 10;           //speed control pin on the motor driver for the left motor

const int BIN2 = 9;           //control pin 2 on the motor driver for the left motor

const int BIN1 = 8;           //control pin 1 on the motor driver for the left motor

 

int switchPin = 7;             //switch to turn the robot on and off

 

const int driveTime = 20;      //this is the number of milliseconds that it takes the robot to drive 1 inch

                               //it is set so that if you tell the robot to drive forward 25 units, the robot drives about 25 inches

 

const int turnTime = 8;        //this is the number of milliseconds that it takes to turn the robot 1 degree

                               //it is set so that if you tell the robot to turn right 90 units, the robot turns about 90 degrees

 

                               //Note: these numbers will vary a little bit based on how you mount your motors, the friction of the

                               //surface that your driving on, and fluctuations in the power to the motors.

                               //You can change the driveTime and turnTime to make them more accurate

 

String botDirection;           //the direction that the robot will drive in (this change which direction the two motors spin in)

String distance;               //the distance to travel in each direction

 

/********************************************************************************/

void setup()

{

  

   // serial to display data

  Serial.begin(115200);

  while(!Serial) {}

 

  // start communication with IMU 

  status = IMU.begin();

  if (status < 0) {

    Serial.println("IMU initialization unsuccessful");

    Serial.println("Check IMU wiring or try cycling power");

    Serial.print("Status: ");

    Serial.println(status);

    while(1) {}

  }

{

  pinMode(switchPin, INPUT_PULLUP);   //set this as a pullup to sense whether the switch is flipped

 

  //set the motor control pins as outputs

  pinMode(AIN1, OUTPUT);

  pinMode(AIN2, OUTPUT);

  pinMode(PWMA, OUTPUT);

 

  pinMode(BIN1, OUTPUT);

  pinMode(BIN2, OUTPUT);

  pinMode(PWMB, OUTPUT);




 

 

}

}

void rightMotor(int motorSpeed)                       //function for driving the right motor

{

  if (motorSpeed > 0)                                 //if the motor should drive forward (positive speed)

  {

    digitalWrite(AIN1, HIGH);                         //set pin 1 to high

    digitalWrite(AIN2, LOW);                          //set pin 2 to low

  }

  else if (motorSpeed < 0)                            //if the motor should drive backward (negative speed)

  {

    digitalWrite(AIN1, LOW);                          //set pin 1 to low

    digitalWrite(AIN2, HIGH);                         //set pin 2 to high

  }

  else                                                //if the motor should stop

  {

    digitalWrite(AIN1, LOW);                          //set pin 1 to low

    digitalWrite(AIN2, LOW);                          //set pin 2 to low

  }

  analogWrite(PWMA, abs(motorSpeed));                 //now that the motor direction is set, drive it at the entered speed

}

 

/********************************************************************************/

void leftMotor(int motorSpeed)                        //function for driving the left motor

{

  if (motorSpeed > 0)                                 //if the motor should drive forward (positive speed)

  {

    digitalWrite(BIN1, HIGH);                         //set pin 1 to high

    digitalWrite(BIN2, LOW);                          //set pin 2 to low

  }

  else if (motorSpeed < 0)                            //if the motor should drive backward (negative speed)

  {

    digitalWrite(BIN1, LOW);                          //set pin 1 to low

    digitalWrite(BIN2, HIGH);                         //set pin 2 to high

  }

  else                                                //if the motor should stop

  {

    digitalWrite(BIN1, LOW);                          //set pin 1 to low

    digitalWrite(BIN2, LOW);                          //set pin 2 to low

  }

  analogWrite(PWMB, abs(motorSpeed));                 //now that the motor direction is set, drive it at the entered speed

}

/********************************************************************************/

void loop(){

  

  if(digitalRead(7) == LOW){

  IMU.readSensor();  // read the sensor

  float y =  IMU.getAccelY_mss(); 

  while (y!=-2.501){ 

  IMU.readSensor();  // read the sensor

  Serial.print("AccelY: ");  

  Serial.print(IMU.getAccelY_mss(),6);

  Serial.print("  ");

  Serial.println();

  delay(100);

  float y =  IMU.getAccelY_mss();

  Serial.print(y);

  Serial.print("  ");

  Serial.println();   

/*The following section of code is designed to create a running average of values from the accelerometer. This was necessary to eliminate spikes in torque that created problems that caused t

 *the car to jerk back and forth in a way that did not allow for proper balance. 

*/

      float prev_y1 = y; 

      delay(10);

      float prev_y2 = y; 

      delay(10);      

      float prev_y3 = y;

      delay(10);

      float prev_y4 = y;

      delay(10);

      float prev_y5 = y;

      delay(10);      

      float prev_y6 = y;

      delay(10);

      float prev_y7 = y;

      delay(10);

      float prev_y8 = y;

      delay(10);      

      float prev_y9 = y;

      delay(10);

      float prev_y10 = y;

      delay(10);

      float prev_y11 = y;

      delay(10);      

      float prev_y12 = y;

      delay(10);

      float prev_y13 = y;

      delay(10);

      float prev_y14 = y;

      delay(10);      

      float prev_y15 = y;

      delay(10);

      float prev_y16 = y;

      delay(10);

      float prev_y17 = y;

      delay(10);      

      float prev_y18 = y;

 

      float avg_y = (prev_y1 + prev_y2 + prev_y3 + prev_y4 + prev_y5 + prev_y6 + prev_y7 + prev_y8 + prev_y9 + prev_y10 + prev_y11 + prev_y12 + prev_y13 + prev_y14 + prev_y15 + prev_y16 + prev_y17 + prev_y18) / 18;

 

      

      if (avg_y >= -2.8 && avg_y <= -2.2)                  // if statement to decide direction, seems to not recieve data from the accelerometer

    {

        rightMotor(0);                                    // drive the right wheel forward

        leftMotor(0); 

        Serial.println("motorstuff");                     // drive the left wheel forward

        // delay(driveTime * distance.toInt());           // drive the motors long enough travel the entered distance

        // rightMotor(0);                                 // turn the right motor off

        // leftMotor(0);

    }

      else if (avg_y > -2)

    {

        rightMotor(80);                                   // drive the right wheel forward

        leftMotor(80);                                    // drive the left wheel forward

       

        

    }

      else if (avg_y < -3)

    {

        rightMotor(-80);                                  // drive the right wheel backward

        leftMotor(-80);                                   // drive the left wheel backward

       

    }

      else

    {

      continue;

    }

  }

}

}

/********************************************************************************/

 

Results:

 

Our result was that after some experimenting with the mechanics of the seesaw and the code we were able to successfully make our car automatically move to balance the seesaw.  

 



Future Work:

 If a future group wanted to improve on this project they could do it in a number of ways. Our group was able to make the seesaw function as planned but we did have to include some rubber bands to create tension under the board that makes the seesaw move slower. A future group could improve on our project by gradually increasing the speed of each motor immediately after a direction change so that the wheels don’t peel out and the car could theoretically balance the motor faster. 

They could also incorporate  a certain amount of machine learning so that the car could learn on it’s own when to correct direction. 

They could also incorporate code to correct for motor directionality so that the car could stay straight without human correction.

 

 

License

    Electric Car for Balancing a Seesaw

    Copyright (C) 2019 J. Valentine, K. Aoyagi, D. Ellis, J. Ross

 

    This program is free software: you can redistribute it and/or modify

    it under the terms of the GNU General Public License as published by

    the Free Software Foundation, either version 3 of the License, or

    (at your option) any later version.

 

    This program 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 General Public License for more details.

 

    You should have received a copy of the GNU General Public License

    along with this program.  If not, see <https://www.gnu.org/licenses/>.