Maze solver robot help

Hello everyone,
I've been trying to program my robot so it could solve a maze but I failed time after time, I'm desperate and hoping to find an answer here. (My experiences with arduino are minimal.)
Basically my robot is a little car and it has 2 distance sensors (1 front, 1 back) and I want it to:

  • drive forward
  • if there's an obstacle turn 90°
  • detect what side has a wall
  • drive away from that wall till you cross another wall
    This looked quite simple in my head but I'm not able to get this into code. If you have any ideas on what functions I should use please let me know!

extra code info

#define ENABLE_A 0
#define ENABLE_B 1
#define IN1 2
#define IN2 3
#define IN3 4
#define IN4 5
#define trigpin 6
#define echopin 7
#define trigpin2 8
#define echopin2 9
#define MAX_DISTANCE 154

void setup() {
   Serial.begin(115200);
    pinMode(trigpin, OUTPUT);
    pinMode(echopin, INPUT);
    pinMode(trigpin2, OUTPUT);
    pinMode(echopin2, INPUT);
    pinMode(ENABLE_A, OUTPUT);
    pinMode(ENABLE_B, OUTPUT);
    pinMode(IN1,OUTPUT);
    pinMode(IN2,OUTPUT);
    pinMode(IN3,OUTPUT);
    pinMode(IN4,OUTPUT);

moving in direction of sensor 1:

    digitalWrite(ENABLE_A, HIGH);
    digitalWrite(ENABLE_B, HIGH);
    digitalWrite(IN1, LOW);
    analogWrite(IN2, 150);
    digitalWrite(IN3, LOW);
    analogWrite(IN4, 150);

moving in direction of sensor 2:

    digitalWrite(ENABLE_A, HIGH);
    digitalWrite(ENABLE_B, HIGH);
    analogWrite(IN1, 150);
    digitalWrite(IN2, LOW);
    analogWrite(IN3, 150);
    digitalWrite(IN4, LOW);

moving 90°

    digitalWrite(ENABLE_A, HIGH);
    digitalWrite(ENABLE_B, HIGH);
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);
    delay(1000);

Thanks for your help in advance!
Cheers

  • if there's an obstacle turn 90°

Without feedback, you are just guessing how much you have turned. You aren't planning to just guess, are you?

  • detect what side has a wall

The walls will be on the left and right, after the turn, won't they? Forward and aft sensors won't be much use then.

This looked quite simple in my head

Draw some pictures of various situations - wall ahead, can turn left or right; wall ahead, can turn left; wall ahead, can turn right; wall ahead, can't turn either direction.

Decide what to do in each case.

A maze solving robot needs to keep track of how far it traveled, and where it turned and how much, so that it can back up to a point where there was an alternate path, when it finds itself blocked.

How are you going to know how far you have traveled, or how far you have turned? How are you going to keep track of that information?

These are all things to be considered before you fire up the IDE at all.

I didn’t see anything in your code to map where it has been. Backtracking may have to be done many times before the path out of a good maze is found. A good map will save time as long as the robot can retrace past steps. It can save searching the same places twice, but you have to be able to locate the robot on the map hopefully for sure and not should be located.

What sensor(s)? Can you put the sensor(s) on a turret to perform sweep scans?
What scale is all of this? Small robot? Tabletop maze?

Inside loop()

Make code for the sensors that runs as often as you need, maybe 10/sec, and have it put the result into a variable that other sections of code may use. As long as no code in the sketch blocks execution longer than the time to the next sensor read, the read will happen on time.

The same with your motor code. Have it read variables or put it in a function that gets args but make it only motor(s) operation. And for the turret if you have one. And any other input or output.

Does the robot have a way to know its position? If so, code for that, update the variable with the result often when position changes.

Make one code that reads the sensor(s) value(s) and decides what to do based on collected data and commands those actions/outputs. This is where the map goes if you have one.

Try just making a robot that can follow a pre-planned course through a maze. Otherwise how do you know when you’re back at a certain spot?

I find it extremely off that he's attempting to analog write and also digital write to the same pin.

Notice that his post doesn't actually state the problem, aside from "it doesn't go". I'd bet that the issue is not that he can't solve a maze - it's that his robot doesn't move at all.

PaulMurrayCbr:
I find it extremely off that he's attempting to analog write and also digital write to the same pin.

And yet that's precisely what analogWrite for the AVR itself does. :wink:

Groove:
And yet that's precisely what analogWrite for the AVR itself does. :wink:

Duh! I was confusing analog write and analog read.

Carry on.

PaulMurrayCbr:
I find it extremely off that he's attempting to analog write and also digital write to the same pin.

Notice that his post doesn't actually state the problem, aside from "it doesn't go". I'd bet that the issue is not that he can't solve a maze - it's that his robot doesn't move at all.

The robot does move, but gets often stuck in the same loop in a certain situation. Like it keeps turning in circles and so on...

PaulS:
Without feedback, you are just guessing how much you have turned. You aren’t planning to just guess, are you?
The walls will be on the left and right, after the turn, won’t they? Forward and aft sensors won’t be much use then.
Draw some pictures of various situations - wall ahead, can turn left or right; wall ahead, can turn left; wall ahead, can turn right; wall ahead, can’t turn either direction.

Decide what to do in each case.

A maze solving robot needs to keep track of how far it traveled, and where it turned and how much, so that it can back up to a point where there was an alternate path, when it finds itself blocked.

How are you going to know how far you have traveled, or how far you have turned? How are you going to keep track of that information?

These are all things to be considered before you fire up the IDE at all.

GoForSmoke:
I didn’t see anything in your code to map where it has been. Backtracking may have to be done many times before the path out of a good maze is found. A good map will save time as long as the robot can retrace past steps. It can save searching the same places twice, but you have to be able to locate the robot on the map hopefully for sure and not should be located.

What sensor(s)? Can you put the sensor(s) on a turret to perform sweep scans?
What scale is all of this? Small robot? Tabletop maze?

Inside loop()

Make code for the sensors that runs as often as you need, maybe 10/sec, and have it put the result into a variable that other sections of code may use. As long as no code in the sketch blocks execution longer than the time to the next sensor read, the read will happen on time.

The same with your motor code. Have it read variables or put it in a function that gets args but make it only motor(s) operation. And for the turret if you have one. And any other input or output.

Does the robot have a way to know its position? If so, code for that, update the variable with the result often when position changes.

Make one code that reads the sensor(s) value(s) and decides what to do based on collected data and commands those actions/outputs. This is where the map goes if you have one.

Try just making a robot that can follow a pre-planned course through a maze. Otherwise how do you know when you’re back at a certain spot?

Thanks for your info but this is my first arduino project and I was thinking of something easier to begin with. You are talking about the possibility of going the wrong way. But the ‘maze’ I’ll make for now will only have 1 way and corners of 90°. I just need the robot to avoid walls and following the path without crushing anything. The problem is I only have 2 sensors (1 on the back and 1 on the front). I tried writing a code something like this:

void loop()
{
calculate distance
if (distance1 < ...)
{
go forward
}
else 
{
turn 1/4
  if distance1 < ...)
  {
  go forward
  }
  else 
  {
  go backward untill distance2 < ...
  }
}
}

I know this code doesn’t work (by testing it out and reading it now), but I simply don’t know the commands I should use. If you don’t understand what I’m trying to accomplish here please ask your question and if you do I’ld be very glad to hear what you think I should try.

Thanks again!

Charles, to achieve a similar thing on my robot, I mounted an ultrasonic sensor on an inverted servo. The servo horn is attached to the robot car’s base plate. (There’s a pic of the servo/sensor setup attached.)

The servo swings side to side, so the US sensor can take distance measurements at 5 points - left, mid-left, centre, mid-right and right. Then when it encounters an object directly ahead, it turns 90 degrees to the side that has the longest clear path. It alos uses side measurements to keep more than a set distance from side obstacles.

It’s not a maze robot, just obstacle-avoiding, but it’s a similar situation.
(And I’m just guessing 90 degrees of turn using timing too. That’s plenty good enough for mine.)

Perhaps you could do similar, but with a servo/sensor assembly at each end of your robot?

Robot Car Head.JPG

OldSteve:
Charles, to achieve a similar thing on my robot, I mounted an ultrasonic sensor on an inverted servo. The servo horn is attached to the robot car's base plate. (There's a pic of the servo/sensor setup attached.)

The servo swings side to side, so the US sensor can take distance measurements at 5 points - left, mid-left, centre, mid-right and right. Then when it encounters an object directly ahead, it turns 90 degrees to the side that has the longest clear path. It alos uses side measurements to keep more than a set distance from side obstacles.

It's not a maze robot, just obstacle-avoiding, but it's a similar situation.
(And I'm just guessing 90 degrees of turn using timing too. That's plenty good enough for mine.)

Perhaps you could do similar, but with a servo/sensor assembly at each end of your robot?

As it happens I recently ordered 2 servos to upgrade a claw on my robot. I think I could use one of those to simulate your robot. I'll try it out, thanks!

CharlesCarron:
As it happens I recently ordered 2 servos to upgrade a claw on my robot. I think I could use one of those to simulate your robot. I’ll try it out, thanks!

No problem. It works well on my little car, and it rarely runs into anything now. Still happens occasionally though, with narrow chair legs etc, but with solid maze walls you should have no issues.

I just have the servo stop momentarily at each of the 5 positions I want to measure at. Just for a few milliseconds, and barely noticeable to the eye when watching it. I haven’t tried it without stopping at each position, but it might not be necessary. I chose to err on the side of caution.

CharlesCarron:
Thanks for your info but this is my first arduino project and I was thinking of something easier to begin with. You are talking about the possibility of going the wrong way. But the ‘maze’ I’ll make for now will only have 1 way and corners of 90°. I just need the robot to avoid walls and following the path without crushing anything.

That means a simpler processing task. It is still simpler and easier to have independent code modules run the sensors and motors, small and debugged, and do what your code below does in a processing module that reads sensor output, makes decisions and signals motors to change behavior when the motor code module runs.
This puts the function of each element outside of the workings of any other. They interact through variables like a sensor module updating a variable the other modules use when it reads X times per second. It’s like blinking a led but you read the sensor instead. There need be no coordination between the sensor module and whatever uses the sensor data, it simply reads and updates every so many millis (without using delay) and the processing module gets whatever’s in the variable when it runs.

Do this right and loop() will run well over 10,000x/second, everything will appear to work simultaneous because it just about will.

The problem is I only have 2 sensors (1 on the back and 1 on the front). I tried writing a code something like this:

void loop()

{
calculate distance
if (distance1 < …)
{
go forward
}
else
{
turn 1/4
  if distance1 < …)
  {
  go forward
  }
  else
  {
  go backward untill distance2 < …
  }
}
}




I know this code doesn't work (by testing it out and reading it now), but I simply don't know the commands I should use. If you don't understand what I'm trying to accomplish here please ask your question and if you do I'ld be very glad to hear what you think I should try.

Thanks again!

You have an Arduino with unused pins? How about adding reflective IR sensing with leds and detectors? At least it will know which turns are blocked.