Help needed with controlling a robot using obstacle avoiding sensors.

Hi,

I made a little 4wd robotic platform using Arduino for the brains who controls the 4 dc motors (Lego PF).
From trial and error I managed and learned to write a sketch what controls the movements of the bot.
It goes neetly back and forward, makes a turn etc. The next step I took was to add an IR Obstacle Avoiding Sensor to it.
After some experiments, I got the sensor working fine and mounted it on the bot. The next thing I want is that the bot
can roam my room freely without hitting obstacles. I started a fresh new sketch, but i can't get wrap my mind about what
would be the next step, this is my sketch:

//Loading libraries and stating pins
#include <legopowerfunctions.h> // Lego PF Library
LEGOPowerFunctions lego(13); // Pin for Lego PF IR Output


//Set up obstacle avoiding sensor
int sensorPinEN = 7;    // Common pin for module 
int sensorPinLO = 6;    // Left Object detected output pin
int sensorPinRO = 5;    // Right Object detected output pin   
int ledPin = 13;      // select the pin for the infrared control LED
int sensorValue = 0;  // variable to store the value coming from the sensor


void setup() {
  // Initialize Arduino Serial which will be used to communicate
  Serial.begin(9600);  

  // Set the pins of the sensor correctly
  pinMode(sensorPinEN, OUTPUT);
  pinMode(sensorPinLO, INPUT);
  pinMode(sensorPinRO, INPUT); 

  // ready the sensor
  digitalWrite(sensorPinEN, HIGH);
}

void loop() {


  lego.ComboPWM(PWM_REV4, PWM_FWD4, CH4); // 50% speed forward

    if (digitalRead(sensorPinRO) == HIGH) // obstacle on the right side
      lego.ComboPWM(PWM_FLT, PWM_FLT, CH4); // complete stop
    delay(100);

    lego.ComboMode(RED_FWD, BLUE_FWD, CH4); // turn left
    delay(10);

    if (digitalRead(sensorPinRO) == LOW) lego.ComboPWM(PWM_REV4, PWM_FWD4, CH4); // continue forward

}

I tried different commands, but i keep stuck in how to proceed.
I also did try to create a sketch this way:

//Loading libraries and stating pins
#include <legopowerfunctions.h> // Lego PF Library
LEGOPowerFunctions lego(13); // Pin for Lego PF IR Output


//Set up obstacle avoiding sensor
int sensorPinEN = 7;    // Common pin for module 
int sensorPinLO = 6;    // Left Object detected output pin
int sensorPinRO = 5;    // Right Object detected output pin   
int ledPin = 13;      // select the pin for the infrared control LED
int sensorValue = 0;  // variable to store the value coming from the sensor

void setup() {

  // Initialize Arduino Serial which will be used to communicate
  Serial.begin(9600);  

  // Set the pins correctly
  pinMode(sensorPinEN, OUTPUT);
  pinMode(sensorPinLO, INPUT);
  pinMode(sensorPinRO, INPUT); 

  // ready the sensor
  digitalWrite(sensorPinEN, HIGH);
}

void loop() {

  if (digitalRead(sensorPinLO && sensorPinRO == LOW))
    lego.ComboMode(PWM_FWD2, PWM_FWD4, CH4);

  if (digitalRead(sensorPinLO == HIGH)) lego.ComboMode(RED_FWD, BLUE_FWD,CH4);
}

The code above only makes one side run normal, the other set of wheels operate in short pulses.

So my question is, what is the right way to go? The first or second scetch? Something completely different?
Do i need to ad something like a time out function?
The kind of behaviour i'm looking for is: Robot drives slow around, detects obstacle sensor is HIGH, stops, turns wheels until sensor is LOW again, continue forward.
I would like to have some help to point me and my robot in the right direction :slight_smile:

M

The next step I took was to add an IR Obstacle Avoiding Sensor to it.

Just a random IR Obstacle Avoiding Sensor your picked up at sensors-R-Us?

if (digitalRead(sensorPinRO) == HIGH) // obstacle on the right side

The sensors I'm familiar with give you information about distance, not just "Hey, there's something there!".

No, not Sensors r us :slight_smile:
I didn't know IR sensors also could use distance. Thought an IR sensor would operate like a tv remote control on / off.
Anyway, this is the sensor I did buy: http://www.elechouse.com/elechouse/index.php?main_page=product_info&cPath=152_156&products_id=589
Hope it gives a better idea.

M

Hmmm... this doesn't look right:

{
  if (digitalRead(sensorPinRO) == HIGH) // obstacle on the right side

first thing is review the code of the two sketches from a purely syntactical point of view. Put the braces where they belong and properly indent the code (CTRL-T in the arduino ide will do the work for you).

My 2 cents...

mromani:
My 2 cents...

Thank you for the tip! The code does indeed look better.
Now that the looks are okay, I can work on the inside :slight_smile:

I also did some more research, lots of tuts do pop up, I did try a few, but still not sure which way to follow.
Thought my approach would be a simple one, turns out it's not that simple. I've seen lot's of tuts which use a
ultrasonic sensor, but can't translate that to my IR sensor. Anyway i'm happy with the few steps I made today,
tomorrow I'll try to make the next few steps.

I also suggest you post your "cleaned up" code too. That left brace was almost certainly wrong placed, because it's very rare that you want to open a block of code without a preceding if(), while() or for()... And I'm not talking about indentation here.
:slight_smile:

Done and done.

Actually the curly braces where a left over from my attemps to create some kind of block function.

My goal was to create something like this:

  • check if the left sensor and right sensor are both low, if so, move forward.
  • when the sensor on the left or right side does "see" something and so setting the pin to high,
  • move the robot with little steps out of that direction and when the both pins are low again,
  • continue to move forward.
  • also when both pins are set to high, stop the forward movement, stop the robot and move backward.

When starting to create this, I thought it was a good idea to build this step by step.
First I learned to set the robot forward, than add the first step of detection, for example the left side.
When the detection goes well for the left side, add the code to move the robot to the right.
With this approach I hoped to end with a complete set of movements.

Sadly I'm stuck on the first step already as you can see. Cause my attemps also raised many questions who
I cannot answer. Like does it need a timing function? Between detecting, moving, detecting again. Also do
I need to time the movement of the motor, to adchieve movement with little steps, cause there is no need
to turn the robot 90 degrees when it detects something on the left or right side.
So in short, I'm lost, to many ways (options) to follow and therefore not sure where to start and proceed further :slight_smile:

Re-read, very carefully, the first"if" in "loop()", and tell us what it does.

Edit: and the second "if"

Hmm after reading it a few times, I think I told it to do this:

move forward, when a obstacle is detected (pin high) spin the wheels in a different direction with a delay of 100,
when the pin goes low again, spin the wheels in the direction stated.

This makes a continues loop? I never tell or state to stop it with the new movement again.
Is that what you mean?

if (digitalRead(sensorPinLO && sensorPinRO == LOW))

digitalRead() takes a single parameter, the number of the pin you want to read. What pin number are you reading here?

I'm reading here pin nr 5 for sensorPinLO and pin nr 6 for sensorPinRO as stated with the "int" at the beginning of the sketch. Well, that's what I think I'm doing.

Ok, couple of examples of wrong thinking.
Who said you could combine multiple reads with the && operator?
Even if you could, look carefully at the expression you're using to decide which pin to use.

Okay I'll try to make a new sketch to exclude my couple ways of wrong thinking.
About the && ... Think i mixed a few things here. I have read about && somewhere
a few days ago and thought that was a way to go here also. I was wrong :slight_smile:
Thank you all for helping so far, even if it is a steep lurning curve for me, I do enjoy it.
Will be back with my next attempt.

M

Okay created a new sketch. It does compile, but the result is not quite yet what I wanted.
But what are you thoughts about this sketch? Am I on the right "path" this way?

//Loading the library needed for the PF motors
#include <legopowerfunctions.h> // Lego PF Library

//Assign a pin for the IR output LED
LEGOPowerFunctions lego(13); // Pin for Lego PF IR Output


//configure the obstacle avoiding sensor
int sensorPinEN = 7;    // Common pin for module 
int sensorPinLO = 6;    // Left Object detected output pin
int sensorPinRO = 5;    // Right Object detected output pin   
int ledPin = 13;      // select the pin for the infrared control LED
int sensorValue = 0;  // variable to store the value coming from the sensor

void setup() {

  // Initialize Arduino Serial which will be used for communication
  Serial.begin(9600);  

  // Set the desired pin modes
  pinMode(sensorPinEN, OUTPUT);
  pinMode(sensorPinLO, INPUT);
  pinMode(sensorPinRO, INPUT); 

  // ready the sensor
  digitalWrite(sensorPinEN, HIGH);

}
/* Create an object for the initial forward movement and 
 also use this object to return to, after direction changes
 */

void start_fwd () {
  lego.ComboPWM(PWM_REV2, PWM_FWD2, CH4); // Move the robot slowly forward
}   

void stop_robot () {
  lego.ComboPWM(PWM_FLT, PWM_FLT, CH4); // stop the robot
}

void see_left () {
  digitalRead(sensorPinLO == HIGH); // see something on the left
}

void turn_left () {
  lego.ComboPWM(PWM_REV2, PWM_REV2, CH4); // move the robot to the left
}

void see_right () {
  digitalRead(sensorPinRO == HIGH); // see something on the right
}

void turn_right () {
  lego.ComboPWM(PWM_FWD2, PWM_FWD2, CH4); // move the robot to the right
}
void see_NOleft () {
  digitalRead(sensorPinLO == LOW); // no obstacle on the left side

}
void see_NOright () {
  digitalRead(sensorPinRO == LOW); // no obstacle on the right side

}

// Create and execute the code for continious movement


void loop() {

  start_fwd();

  if (see_left) {
    stop_robot();
    turn_left();
  }
  else { 
    (see_NOleft) ;
    start_fwd();
  }
}

I hope I have it right this time, thanks again for the help!

No, sorry, you have to call functions, not simply test the pointer to them.
seeleft is a pointer, and because it is non zero, will always be true.

AWOL:
seeleft is a pointer, and because it is non zero, will always be true.

allrighty... so if I understand you correctly, no matter if the pointer is high or low, it is always present so a "true" factor inside a sketch.

So what i need to do is to create a function who checks/pulls data from the "pointer" at timed intervals?
(In this way I use a pointer to guide me to the place where the changes are happening)

or

Do I create a function for the sensor? Like when the pointers are low, the robot can move forward, if one is high change direction?
(In this way the pointers, point out to the sketch there is a changed state of one sensor)

Hmm I hope I still make sense :slight_smile: Maybe I need a little break...
Thanks for the helping hand

M

Totally wrong code:

void see_NOleft () {
digitalRead(sensorPinLO == LOW); // no obstacle on the left side
}

void see_NOright () {
digitalRead(sensorPinRO == LOW); // no obstacle on the right side
}

You have to understand the difference between a function that performs some action and one that should return a value.

What you want is this instead:

boolean see_NOleft() {
return digitalRead(sensorPinLO == LOW); // no obstacle on the left side
}

boolean see_NOright() {
return digitalRead(sensorPinRO == LOW); // no obstacle on the right side
}

Then you use them like this (just an example, of course):

if (see_NOright()) {
    // code to be executed when there's no obstacle on the right side
}

if (see_NOleft()) {
    // code to be executed when there's no obstacle on the left side
}

HTH

Forget what was said about pointers. It was totally correct, but function pointers are far too complex a subject for you to understand now. Just learn to write functions and how to properly call them. I suggest you visit the Learning section of this website, as you seem to be missing a large part of basic C knowledge.
I mean, you're showing the right will to learn IMHO, but before attempting to write a moderately complex piece of code like the one you envisioned before you have to at least know the ABC of the language, otherwise issues about how to code a particular algorithm will mix up with lower level syntactical problems.

That said, feel free to ask any further question. I'll try to be helpful nonetheless (provided I have time, of course :slight_smile:

This isn't going to work either because you are doing a logical compare and sending it as the variable to digitalRead

boolean see_NOleft() {
return digitalRead(sensorPinLO == LOW); // no obstacle on the left side
}

boolean see_NOright() {
return digitalRead(sensorPinRO == LOW); // no obstacle on the right side
}

This is the format you are looking for however you may need to swap the true and false depending on your sensor output.

/*
This function tests the left sensor PIN and returns TRUE if the sensor PIN is LOW and FALSE if the sensor PIN is HIGH
This function is expecting a sensor that give a high value when it detects something in range and a low value when it does not detect something in range
*/

boolean see_NOleft(){
   boolean clear;
      if(digitalRead(sensorPinLO)  == LOW) {
         clear = TRUE;
      } else {
         clear = FALSE;
     }
   return clear;
}

Sorry for my wrong code :disappointed_relieved: :disappointed_relieved: :disappointed_relieved:

I'll take this as a hint to write less and (re)read more :stuck_out_tongue_winking_eye: