Hello, (my second topic here) I'm currently working on my first project, the SMARS Robot Car by Kevin Thomas. I' m a beginner and therefore do not have much experience and knowledge of programming. However, I wrote the sketch myself and it works. I am currently optimizing my project and have decided on the following:
-
Instead of holding Triangle, Circle, Cross and Square to execute the code, I only want to press whatever I want once (for example: if I press Triangle, obstacleavoidance should be executed permanently).
-
I still want to be able to switch between the actions after pressing another button (for example circle for followingbob) once.
-
I would like to be able to either override the actions manually or, if this is not possible, end them with Select and again be able to control it manually.
I have already tried it with a while(true) loop and ButtonPressed, but it doesn't work. I keep trying to think of new possibilities, but I think I need expert help. Unfortunately I could not find anything similar in the forum.
Here is my Sketch:
#include <PS2X_lib.h>
#include <AFMotor.h>
#define PS2_DAT 9 // data
#define PS2_CMD 10 // command
#define PS2_SEL 2 // attention
#define PS2_CLK 13 // clock
PS2X ps2x; // create PS2 Controller Class
int error = 0; // for controller-connenction
byte type = 0; // for controller-type
AF_DCMotor lmotor(1); // left motor
AF_DCMotor rmotor(2); // right motor
int echo = A1; // echo pin connected to A1
int trigger = A2; // trig pin connected to A2
long duration; // variable for ultrasonic-sensor
int theDistance = 0; // variable for ultrasonic-sensor
int keepDistance = 8; // variable for ultrasonic-sensor
int infrared = A0; // variable for infrared-sensor
//-------------------------------------------------- SETUP
void setup() {
Serial.begin(9600);
delay(400); // time to startup, before configuring it
error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT); // setup pins for PS2 Controller
if (error == 0) { // check for errors
Serial.print("PS2 Controller successfully found and configured, B.O.B. is waiting :) -> ");
} else {
Serial.print("No PS2 Controller found, try again ");
setup();
}
type = ps2x.readType(); // read type of Controller
switch (type) {
case 0:
Serial.print("Unknown Controller type found ");
break;
case 1:
Serial.print("DualShock Controller found ");
break;
}
lmotor.setSpeed(200); // left motor speed 200
rmotor.setSpeed(200); // right motor speed 200
lmotor.run(RELEASE); // release left motor
rmotor.run(RELEASE); // release right motor
pinMode(echo, INPUT); // echo as input
pinMode(trigger, OUTPUT); // trigger as output
pinMode(infrared, INPUT); // infrared as input
}
//-------------------------------------------------- LOOP
void loop() {
if (error == !0) // skip loop if no Controller found
return;
if (type == 1) { // DualShock Controller
ps2x.read_gamepad(); // read Controller
manualcontrol(); // use d-pad for manual control (already active)
if (ps2x.Button(PSB_TRIANGLE)) // hold triangle to activate obstacle avoidance
obstacleavoidance();
if (ps2x.Button(PSB_CIRCLE)) // hold circle to activate following BOB
followingbob();
if (ps2x.Button(PSB_CROSS)) // hold cross to activate black-line driving
blacklinedriving();
if (ps2x.Button(PSB_SQUARE)) // hold square to activate avoid the black
avoidtheblack();
if (ps2x.ButtonPressed(PSB_START)) // press start to activate bobby-dance
bobbydance();
}
delay(50);
}
//-------------------------------------------------- MANUAL CONTROL
void manualcontrol() {
if (ps2x.Button(PSB_PAD_UP)) { // move forward
lmotor.run(FORWARD);
rmotor.run(FORWARD);
} else if (ps2x.Button(PSB_PAD_DOWN)) { // move backward
lmotor.run(BACKWARD);
rmotor.run(BACKWARD);
} else if (ps2x.Button(PSB_PAD_LEFT)) { // turn left
lmotor.run(BACKWARD);
rmotor.run(FORWARD);
} else if (ps2x.Button(PSB_PAD_RIGHT)) { // turn right
lmotor.run(FORWARD);
rmotor.run(BACKWARD);
} else { // stop
lmotor.run(RELEASE);
rmotor.run(RELEASE);
}
}
//-------------------------------------------------- OBSTACLE AVIODANCE
void obstacleavoidance() {
theDistance = distance(); // store the measured distance
Serial.println(theDistance); // print the measured distance
if (theDistance <= 12) { // move backward and turn right if distance is less than 12cm
lmotor.run(BACKWARD);
rmotor.run(BACKWARD);
delay(500);
lmotor.run(FORWARD);
rmotor.run(BACKWARD);
delay(500);
} else { // otherwise move forward
lmotor.run(FORWARD);
rmotor.run(FORWARD);
}
}
//-------------------------------------------------- FOLLOWING BOB
void followingbob() {
theDistance = distance(); // store the measured distance
Serial.println(theDistance); // print the measured distance
if (theDistance < keepDistance && theDistance >= 0) { // move backward if the distance is less than 8cm
lmotor.run(BACKWARD);
rmotor.run(BACKWARD);
}
if (theDistance > (keepDistance + 3) && theDistance < (keepDistance + 20)) { // move forward if the distance is more than 11cm
lmotor.run(FORWARD);
rmotor.run(FORWARD);
}
if (theDistance > (keepDistance + 20)) { // turn right if the distance is more than 28cm
lmotor.run(FORWARD);
rmotor.run(BACKWARD);
}
if (theDistance >= keepDistance && theDistance <= (keepDistance + 3)) { //stop if the distance is between 8cm and 11cm
lmotor.run(RELEASE);
rmotor.run(RELEASE);
}
}
//-------------------------------------------------- IN ADDITION FOR OBSTACLE AVOIDANCE AND FOLLOWING BOB
int distance() {
int echoTime; // store the time for a ping to bounce off an object
int calculatedDistance; // store the calculated distance from the echo time
digitalWrite(trigger, HIGH); // ultrasonic pulse for 10ms
delayMicroseconds(10);
digitalWrite(trigger, LOW);
echoTime = pulseIn(echo, HIGH); // time for the pulse to bounce back to the sensor
calculatedDistance = echoTime / 2 / 29; // calculate the distance of the reflected object (half the bounce time multiplied by the speed of sound)
return calculatedDistance; // send back the calculated distance
}
//-------------------------------------------------- BLACK-LINE DRIVING
void blacklinedriving() {
int ifrstate = digitalRead(infrared); // store the state of the infrared-sensor
if (ifrstate == 1) { // move forward if black line detected
lmotor.run(BACKWARD);
rmotor.run(BACKWARD);
} else { // turn right if not on a black line
lmotor.run(FORWARD);
rmotor.run(BACKWARD);
}
}
//-------------------------------------------------- AVOID THE BLACK
void avoidtheblack() {
int ifrstate = digitalRead(infrared); // store the state of the infrared-sensor
if (ifrstate == 1) { // move backward and turn right if black line detected
lmotor.run(FORWARD);
rmotor.run(FORWARD);
delay(500);
lmotor.run(FORWARD);
rmotor.run(BACKWARD);
delay(500);
} else { // move forward if not on a black line
lmotor.run(BACKWARD);
rmotor.run(BACKWARD);
}
}
//-------------------------------------------------- BOBBY-DANCE
void bobbydance() {
lmotor.run(FORWARD);
rmotor.run(FORWARD);
delay(1000);
lmotor.run(RELEASE);
rmotor.run(RELEASE);
delay(1000);
lmotor.run(FORWARD);
rmotor.run(FORWARD);
delay(200);
lmotor.run(BACKWARD);
rmotor.run(BACKWARD);
delay(200);
lmotor.run(FORWARD);
rmotor.run(FORWARD);
delay(200);
lmotor.run(BACKWARD);
rmotor.run(BACKWARD);
delay(200);
lmotor.run(FORWARD);
rmotor.run(FORWARD);
delay(200);
lmotor.run(BACKWARD);
rmotor.run(BACKWARD);
delay(200);
lmotor.run(FORWARD);
rmotor.run(FORWARD);
delay(200);
lmotor.run(BACKWARD);
rmotor.run(BACKWARD);
delay(1200);
lmotor.run(RELEASE);
rmotor.run(RELEASE);
delay(200);
lmotor.run(BACKWARD);
rmotor.run(FORWARD);
delay(2000);
lmotor.run(FORWARD);
rmotor.run(BACKWARD);
delay(2000);
}
Thanks for helping!
Dominik Bubak