Professional Documents
Culture Documents
Materials
1-Chassis:
2- Motor driver:
3-Battery:
4-IMU sensor:
5-Arduino UNO:
6-two motor:
1- Chassis: For create the main structure of the robot i used wood chassis with
some nuts and screws, two wheels with two motors, one battery socket, one
caster wheel, and even 2 little wheels for encoders.
2- Motor driver: Description: This dual bidirectional motor driver is based on the
very popular L298 Dual H-Bridge Motor Driver Integrated Circuit. The circuit will
allow you to easily and independently control two motors of up to 2A each in both
directions.
It is ideal for robotic applications and well suited for connection to a microcontroller
requiring just a couple of control lines per motor. It can also be interfaced with
simple manual switches, TTL logic gates, relays, etc.
BMU sensor:
Code: #include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#define M1rpwm 11
#define M2rpwm 4
#define M1lpwm 10
#define M2lpwm 5
#define ena 9
#define enb 3
struct AngleGyroData {
float angle;
int16_t gyro;
};
float _initAngle;
// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board)
// AD0 high = 0x69 This is the ONLY way I can make my cheap banggood.com board
work, wile also connectiong AD0 to VCC
MPU6050 mpu(0x68);
/* Connect VCC, GND, SDA, SCL and the MPU-6050's INT pin to Arduino's external
interrupt #0.
On the Arduino Uno and Mega 2560, this is digital I/O pin 2. */
// MPU control/status vars
// orientation/motion vars
bool mpu_setup() {
mpu.initialize();
Serial.print(F("ID")); Serial.println(mpu.getDeviceID());
// verify connection
Serial.println(F("Test conns"));
Serial.println(F("Init DMP"));
if (devStatus == 0) {
Serial.println(F("Enable DMP"));
mpu.setDMPEnabled(true);
packetSize = mpu.dmpGetFIFOPacketSize();
// set our DMP Ready flag so the main loop() function knows it's okay to use it
Serial.println(F("Set INTrrpts"));
return true;
} else {
// ERROR!
// 2 = DMP configuration updates failed (if it's going to break, usually the code
will be 1)
return false;
// check for overflow (this should never happen unless our code is too inefficient)
// otherwise, check for DMP data ready interrupt (this should happen frequently)
// read 1st packet from FIFO, don't bother with the rest
mpu.getFIFOBytes(fifoBuffer, packetSize);
// in case there were plenty of packets in the FIFO, only transform the last one,
to avoid wasting CPU for nothing
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetGyro(gyros, fifoBuffer);
data->angle = yawPitchRoll[2];
data->gyro = gyros[2];
return 0; // all good
}else {
// angle is in radians
void setup(){
Serial.begin(9600);
mpu_setup();
pinMode(ena, OUTPUT);
pinMode(enb, OUTPUT);
pinMode(M1rpwm, OUTPUT);
pinMode(M1lpwm, OUTPUT);
pinMode(M2lpwm, OUTPUT);
pinMode(M2rpwm, OUTPUT);
// configure the initial angle, which is assumed to be the "stable" position
delay(1000);
_initAngle = _angleData.angle;
void loop(){
currentTime = millis();
// if res != 0 the data is not yet ready or there were errors, so ignore and keep
trying
if(res == 0){
// 1. update the speed, apply PID algo (for the D, we don't need to do it
manually as the sensor already gives us the gyro value which is the derivative of
the angle)
//analogWrite(MOTOR_ENABLE_PIN, abs(speed));
digitalWrite(ena,HIGH);
digitalWrite(enb,HIGH);
digitalWrite(M1lpwm,HIGH);
digitalWrite(M2rpwm,HIGH);
Serial.println("innn");
}else{
digitalWrite(ena,HIGH);
digitalWrite(enb,HIGH);
digitalWrite(M1rpwm,HIGH);
digitalWrite(M2lpwm,HIGH);
Serial.println("outtt");
}
//Serial.print(_angleData.angle); Serial.print(" / "); Serial.print(_angleData.gyro);
Serial.print(" @ "); Serial.println(speed);
lastTime = currentTime;