Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed Motor LSM9DS1_Library_cal PinDetect HC_SR04_Ultrasonic_Library
main.cpp
- Committer:
- uwang3
- Date:
- 2018-12-10
- Revision:
- 12:f57a51ec8399
- Parent:
- 11:f95294698901
- Child:
- 13:dd2ac39ba5ba
File content as of revision 12:f57a51ec8399:
#include "mbed.h"
#include "LSM9DS1.h" // IMU
#include "ultrasonic.h" // Ultrasonic Sensor
#include "Motor.h" // Motor Drivers
#include "PinDetect.h" // Pin Detect (for switch)
// Global Variables:
bool tr = true;
bool turnflag = false;
int leftdistancestarting= 0;
int leftdistanceending= 0;
//---------------------|
// PIN INITIALIZATIONS |
//---------------------|
// Debug LED pin:
//DigitalOut led(p25);
DigitalIn sw(p20);
Serial pc(USBTX,USBRX);
// Setup Motor Driver pins:
Motor Lfront(p21, p6, p5); // PWM to p21, forward to p5, reverse to p6...
Motor Rfront(p22, p8, p7); // PWM to p22, forward to p7, reverse to p8...
Motor Lback(p23, p10, p9); // PWM to p23, forward to p10, reverse to p9...
Motor Rback(p24, p12, p11); // PWM to p24, forward to p12, reverse to p11...
LSM9DS1 imu(p28, p27, 0xD6, 0x3C);
Timer t;
//-----------------------|
// CLASS INITIALIZATIONS |
//-----------------------|
class mctrl {
public:
// Stop all motors:
void stop(void) {
Lfront.speed(0);
Lback.speed(0);
Rfront.speed(0);
Rback.speed(0);
wait(0.55);
};
// Go forward at constant speed:
void fwd(void){
//stop();
Lfront.speed(0.85);
Lback.speed(0.85);
Rfront.speed(0.85);
Rback.speed(0.85);
wait(0.02);
};
// Reverse at constant speed:
void rev(void){
stop();
Lfront.speed(-1);
Lback.speed(-1);
Rfront.speed(-1);
Rback.speed(-1);
wait(0.02);
};
// Turn left 90 degrees:
void turnLeft(){
stop();
float degree = 0.0, angularV = 0.0;
float currt = t.read();
while(degree < 90) {
while(imu.gyroAvailable());
imu.readGyro();
angularV = imu.gz;
Lfront.speed(-1);
Lback.speed(-1);
Rfront.speed(1);
Rback.speed(1);
if(angularV > 50.0 || angularV <-50.0) {
degree += (abs(angularV))/100.00;
}
wait(.45);
}
stop();
wait(0.02);
};
// Turn right 90 degrees:
void turnRight(){
stop();
float degree = 0.0, angularV = 0.0;
float currt = t.read();
while(degree < 90) {
while(imu.gyroAvailable());
imu.readGyro();
angularV = imu.gz;
Lfront.speed(1);
Lback.speed(1);
Rfront.speed(-1);
Rback.speed(-1);
if(angularV > 50.0 || angularV <-50.0) {
degree += (abs(angularV))/100.00;
}
wait(.45);
}
stop();
wait(0.02);
};
// Turn L or R, "mag" of turn prop. to dist. from wall
// motor speed values are normalized to -1 to 1 (aka no 1.25)
void turnLeftScaled(double scale) {
// try commenting out this stop otherwise robot will stop before correcting
stop();
Lfront.speed(-1 * scale);
Lback.speed(-1 * scale);
Rfront.speed(1 * scale);
Rback.speed(1 * scale);
//stop();
wait(0.02);
};
void turnRightScaled(double scale) {
stop();
Lfront.speed(1 * scale);
Lback.speed(1 * scale);
Rfront.speed(-1 * scale);
Rback.speed(-1 * scale);
//stop();
wait(0.02);
};
} mctrl;
//------------------|
// HELPER FUNCTIONS |
//------------------|
// PUT CODE HERE TO TRIGGER WHEN DISTANCE READS LESS THAN 15cm
void dist(int distance) // NOTE: by default "distance" is in mm...
{
if (distance < 150) {
mctrl.stop();
// Turn 90 degrees
float currt = t.read();
if (tr) {
mctrl.turnRight();
} else {
mctrl.turnLeft();
}
// Go forward 1.25 seconds... is it though???
// change dstance???? globals?? to make sure it doesnt hit wall later on
currt = t.read();
while ((t.read() - currt) < 1.25) {
mctrl.fwd();
}
// Turn 90 degrees
currt = t.read();
if (tr) {
mctrl.turnRight();
} else {
mctrl.turnLeft();
}
tr = !tr;
} else {
// Continue forward until wall.
mctrl.fwd();
}
}
// nonsense so far
void dist2(int distance) // left sensor interrupt
{
leftdistanceending = distance;
//pc.printf(" Distance %d mm\r\n", distance);
}
// nonsense so far
void dist3(int distance) // right sensor interrupt
{
/*if (distance < 150) {
pc.printf("Right Sensor trigg");
}
else {
pc.printf("Right Sensor echo");
}*/
//rightdistance = distance;
}
//------------------------------|
// PIN INITIALIZATIONS (cont'd) |
//------------------------------|
// Setup Ultrasonic Sensor pins:
ultrasonic usensor(p15, p16, .07, 1, &dist); // trigger to p13, echo to p14...
// update every .07 secs w/ timeout after 1 sec...
// call "dist" when the distance changes...
ultrasonic usensor2(p15, p26, .07, 1, &dist2); // left sensor trigger
ultrasonic usensor3(p15, p25, .07, 1, &dist3); //right sensor trigger
//---------------|
// MAIN FUNCTION |
//---------------|
int main() {
// Use internal pullup for the switch:
sw.mode(PullUp);
// Initialize the Ultrasonic Sensor:
usensor.startUpdates();
usensor2.startUpdates();
usensor3.startUpdates();
wait(0.5);
// obtain and print starting distances
int forwardDist = usensor.getCurrentDistance();
int leftDist = usensor2.getCurrentDistance();
int rightDist = usensor3.getCurrentDistance();
wait(0.5);
pc.printf("Current Forward Starting Distance %d mm\r\n", forwardDist);
pc.printf("Current Left Starting Distance %d mm\r\n", leftDist);
pc.printf("Current Right Starting Distance %d mm\r\n", rightDist);
// Initialize the Timer:
t.start();
//while(1) {
while (!sw) {
// if front sonar detects a change in the distace measured, dist is called
usensor.checkDistance();
// obtain the distance measurements for the left and right sonars
int currLeftDist = usensor2.getCurrentDistance();
int currRightDist = usensor3.getCurrentDistance();
// if the left and right sonars detect distances greater than 100mm
// (10 cm or 3.93 inches), just go forward aka ignore path corr.
if (currLeftDist > 100 && currRightDist > 100) {
mctrl.fwd();
} else {
// if left side of robot is nearer to the wall...
if (currLeftDist < currRightDist) {
//if robot has drifted toward the wall by a lot, scale R turn proportionally
if ((leftDist - currLeftDist) > 40) {
// take a right turn with a greater speed
// (trying to emulate a "big" turn, may need to be changed)
mctrl.turnRightScaled(1);
// this is an attempt to go forward (may need to change)
mctrl.fwd();
//if drifted toward wall a little (less than 40 but greater than 5 mm), scale accordingly
} else if ((leftDist - currLeftDist) > 5) {
mctrl.turnRightScaled(0.75);
mctrl.fwd();
//if drift away from wall a lot, scale L turn accordingly
} else if ((currLeftDist - leftDist) > 40) {
mctrl.turnLeftScaled(1);
mctrl.fwd();
} else if ((currLeftDist - leftDist) > 5) {
mctrl.turnLeftScaled(0.75);
mctrl.fwd();
// if drift if less than 5 mm in either direction (away or toward wall), go forward normally...
// last meeting i had this commented out, see how the robot behaves this time!!
} else {
mctrl.fwd();
}
} else if (currLeftDist > currRightDist) {
//if robot has drifted toward the wall by a lot, scale L turn by a lot
if ((rightDist - currRightDist) > 40) {
mctrl.turnLeftScaled(1);
mctrl.fwd();
//if drifted toward wall a little, scale accordingly
} else if ((rightDist - currRightDist) > 5) {
mctrl.turnLeftScaled(0.75);
mctrl.fwd();
//if drift away a lot, scale R turn accordingly
} else if ((currRightDist - rightDist) > 40) {
mctrl.turnRightScaled(1);
mctrl.fwd();
} else if ((currRightDist - rightDist) > 5) {
mctrl.turnRightScaled(0.75);
mctrl.fwd();
} else {
mctrl.fwd();
}
}
// update the left and right distances that will the next values will be compared to. may be weird so maybe wait/etc.
leftDist = currLeftDist;
rightDist = currRightDist;
}
}
// if switch flipped, stop robot
mctrl.stop();
}