The robot I'm working on is supposed to move forward if there's no obstacle (>20 cm) in front of the robot, and to turn left if the front is free.

Is there a difference between "free" and "no obstacle"? I can't see one.

//proximity sensors
const int echo1 = A0; //left sensor
const int trig1 = A1; //left sensor
const int echo2 = A2; //middle sensor
const int trig2 = A3; //middle sensor
const int echo3 = A4; //right sensor
const int trig3 = A5; //right sensor
long duration1 ; //left sensor
long duration2 ; //middle sensor
long duration3 ; //right sensor

When you start adding suffixes, it's time to think arrays instead. You MUST understand arrays if you are going to have the robot map the maze, so you can solve it.

You should have a function that takes a trigger pin number and an echo pin number and returns a distance. You should NOT repeat code three times because you have three sensors.

You absolutely need to understand how to write functions, AND how to limit the scope of variables, if you are going to complete this project.

You really should look at the NewPing() library, instead of blocking using pulseIn().

Finally, you haven't a hope in hell of mapping the maze when you have no idea how long you travel forward, or how far you've traveled, or how much you've turned.

Using delay() in the hopes that you'll have turned enough just isn't going to cut it.

Doesn’t a wall following maze solver stick to the wall even if it’s clear ahead?

See pic: blue are the walls, red are the travel.

So if you’re travelling from right to left along the top of a T, you make a left down the upright (solid red arrow) even though you could cross the intersection and keep straight (dotted red)?

wall follow.GIF

  if(cm[1]<20 && cm[2]<20 && cm[3]<20){       // DEAD END     		0 0 0

Array indices start at 0, not 1.

you've also said that using delay() isn't the best way for coding the way the robot turns. Would you give a hint for the better one?

How do you drive to school? Do you back out of the garage at a fixed speed for a fixed period of time? Or, do use some sort of feedback?

When out of the garage, it the drive to school a series of timed moves at specific speeds that can be done blindfolded?

Of course not. You need to start moving, and then stop/slow/turn when there is a problem (obstruction) in front of you. You move forward for unknown periods of time.

After reading this article I think there's a way to implement the millis() and for() functions for this.

I don't like the term multi-tasking, since the Arduino really can't perform more than one task at a time. However, most of the "tasks", like reading a ping sensor, don't take much time, so it can appear, to us slow humans, that the Arduino is doing several things at once.

But, the concepts are sound.

I put 400 cm as the MAX_DISTANCE, shouldn't the sensors read up to 400 cm distance?

If you put 8 lightyears as the MAX_DISTANCE, would you expect the sensor to return a distance of 5.5 lightyears? If so, how long would you have to wait for the reading?

There are restrictions on the sensor; yours may not be capable of reading 400 centimeters.

The reading of 0 means that the distance was unlimited - nothing reflected the wave that was sent. You can use that information to know that balls-to-the-wall is a fine speed for a while.

But when I uploaded the code, while the sensors would read the correct values and the supposed "state" of the robot (Moving Forward, Turning Left etc) also prints fine, the and functions somehow doesn't work; the motors won't rotate at all!

Without the ping sensors being read, do the motors work?

I tried the code anyway and the motor also works

So, adding the NewPing library, and using it's features, causes the motors to stop working?

If that is the case, then I suspect that the problem is that NewPing uses a timer, which disables PWM on two pins (timer 1 controls pins 9 and 10) which are probably the pins that the motors are being driven by.

If that is the case, perhaps NewPing could be modified to use a different timer.