Robot Code Bug

I am in the process of building my first Arduino Robot. I have 1 IR sensor on the front and 2 micro-switches, one in each corner.

If i only have the code for the IRsensor every thing works fine, but when i add the code for the corner sensors or only have the code for the corner sensors, the robot keeps running "avoid" code.

The code is this: const int motorRight1 = 3; const int motorRight2 = 2; const int motorLeft1 = 1; const int motorLeft2 = 0; const int InfraredSensorPin = 4;

void setup() {

pinMode(motorRight1, OUTPUT); pinMode(motorRight2, OUTPUT); pinMode(motorLeft1, OUTPUT); pinMode(motorLeft2, OUTPUT); pinMode(InfraredSensorPin, INPUT); }

void loop() { if(digitalRead(InfraredSensorPin) == LOW) {avoidLeft();} else forward(); while(analogRead(A0) == HIGH) {avoidLeft();} while(analogRead(A1) == HIGH) {avoidRight();} }

// Motion routines for forward, reverse, turns, and stop void forward() { digitalWrite(motorRight1, HIGH); digitalWrite(motorRight2, LOW); digitalWrite(motorLeft1, HIGH); digitalWrite(motorLeft2, LOW); }

void reverse() { digitalWrite(motorRight1, LOW); digitalWrite(motorRight2, HIGH); digitalWrite(motorLeft1, LOW); digitalWrite(motorLeft2, HIGH); }

void turnLeft() { digitalWrite(motorRight1, HIGH); digitalWrite(motorRight2, LOW); digitalWrite(motorLeft1, LOW); digitalWrite(motorLeft2, HIGH); }

void turnRight() { digitalWrite(motorRight1, LOW); digitalWrite(motorRight2, HIGH); digitalWrite(motorLeft1, HIGH); digitalWrite(motorLeft2, LOW); }

void stopRobot() { digitalWrite(motorRight1, LOW); digitalWrite(motorRight2, LOW); digitalWrite(motorLeft1, LOW); digitalWrite(motorLeft2, LOW); }

void avoidLeft() { stopRobot(); delay(500); reverse(); delay(1500); turnLeft(); delay(1000); }

void avoidRight() { stopRobot(); delay(500); reverse(); delay(1500); turnRight(); delay(1000); }

Any help is welcomed.

Do your microswitches have pull down resistors? It sounds like the analog pins are floating and adding resistors to GND will solve that issue.

Also if they are just microswitches, why are you using analogRead instead of digitalRead? Do the switches output a value other than 1 & 0?

Hi hugoalc

First, it helps people to understand your code if you use the code tags when you post it (the # button above the smileys).

Second, you have this in your code:

while(analogRead(A0) == HIGH)  {avoidLeft();}
while(analogRead(A1) == HIGH)  {avoidRight();

As HazardsMind said, you are reading analog inputs but comparing them with HIGH as if they are digital inputs. You [u]can[/u] use them as digital inputs, if you set them up like this.

pinMode(A0, INPUT_PULLUP); // turn on internal pullup resistor, connect "normally open" switch to GND
if (digitalRead(A0) == LOW) { // etc;

Regards

Ray

while(analogRead(A0) == HIGH)  {avoidLeft();}
  while(analogRead(A1) == HIGH)  {avoidRight();}

This code is stupid. analogRead does not return High or LOW look it up it the reference section.

The whlie loop should not be used in this context.

You should never use delay() in a program - see blink without delay (in the playground) and also look at Finite State Machines.

You will also find in the playground info on how to setup and use switches/buttons.

Mark

I did what Hackscribble told me to do, but now when i press the microswitches nothing happens. Besides using "delay", i there something else wrong with the code? Thanks for the help, this is only my 6st day with the arduino.

const int motorRight1 = 3;
const int motorRight2 = 2;
const int motorLeft1 = 1;
const int motorLeft2 = 0;
const int InfraredSensorPin = 4;

void setup() {

  pinMode(motorRight1, OUTPUT);
  pinMode(motorRight2, OUTPUT);
  pinMode(motorLeft1, OUTPUT);
  pinMode(motorLeft2, OUTPUT);
  pinMode(InfraredSensorPin, INPUT);
  pinMode(A0, INPUT_PULLUP);
  pinMode(A1, INPUT_PULLUP);
} 

void loop() {
  if(digitalRead(InfraredSensorPin) == LOW) {avoidLeft();}
  else forward();
  if (digitalRead(A0) == LOW) {avoidLeft();}
  if (digitalRead(A1) == LOW) {avoidRight();}
}

// Motion routines for forward, reverse, turns, and stop
void forward() {
  digitalWrite(motorRight1, HIGH);
  digitalWrite(motorRight2, LOW);
  digitalWrite(motorLeft1, HIGH);
  digitalWrite(motorLeft2, LOW);
}

void reverse() {
  digitalWrite(motorRight1, LOW);
  digitalWrite(motorRight2, HIGH);
  digitalWrite(motorLeft1, LOW);
  digitalWrite(motorLeft2, HIGH);
}

void turnLeft() {
  digitalWrite(motorRight1, HIGH);
  digitalWrite(motorRight2, LOW);
  digitalWrite(motorLeft1, LOW);
  digitalWrite(motorLeft2, HIGH);
}

void turnRight() {
  digitalWrite(motorRight1, LOW);
  digitalWrite(motorRight2, HIGH);
  digitalWrite(motorLeft1, HIGH);
  digitalWrite(motorLeft2, LOW);
}

void stopRobot() {
  digitalWrite(motorRight1, LOW);
  digitalWrite(motorRight2, LOW);
  digitalWrite(motorLeft1, LOW);
  digitalWrite(motorLeft2, LOW);
}

void avoidLeft() {
  stopRobot();
  delay(500);
  reverse();
  delay(1500);
  turnLeft();
  delay(1000);
}

void avoidRight() {
  stopRobot();
  delay(500);
  reverse();
  delay(1500);
  turnRight();
  delay(1000);
}

How are your switches wired, are they going to GND or Vcc?

Your IF statements should be: if( . . . ) { // left } else if( . . . ) { // left again } else if( . . . ){ // right } else { //forward }

It's 1:22am here and my robot is now fully working! Thanks for the help. This is the code i am using, just have toremove the "delays" and it's done.

const int motorRight1 = 3;
const int motorRight2 = 2;
const int motorLeft1 = 1;
const int motorLeft2 = 0;
const int InfraredSensorPin = 4;
const int RightSensorPin = 5;
const int LeftSensorPin = 6;

void setup() {

  pinMode(motorRight1, OUTPUT);
  pinMode(motorRight2, OUTPUT);
  pinMode(motorLeft1, OUTPUT);
  pinMode(motorLeft2, OUTPUT);
  pinMode(InfraredSensorPin, INPUT);
  pinMode(RightSensorPin, INPUT);
  pinMode(LeftSensorPin, INPUT);
  
  digitalWrite(RightSensorPin, HIGH);
  digitalWrite(LeftSensorPin, HIGH);
} 

void loop() {
  if(digitalRead(InfraredSensorPin) == LOW) {avoidLeft();}
  if (digitalRead(RightSensorPin) == LOW) {avoidRight();}
  if (digitalRead(LeftSensorPin) == LOW) {avoidLeft();}
  else forward();
}

// Motion routines for forward, reverse, turns, and stop
void forward() {
  digitalWrite(motorRight1, HIGH);
  digitalWrite(motorRight2, LOW);
  digitalWrite(motorLeft1, HIGH);
  digitalWrite(motorLeft2, LOW);
}

void reverse() {
  digitalWrite(motorRight1, LOW);
  digitalWrite(motorRight2, HIGH);
  digitalWrite(motorLeft1, LOW);
  digitalWrite(motorLeft2, HIGH);
}

void turnLeft() {
  digitalWrite(motorRight1, HIGH);
  digitalWrite(motorRight2, LOW);
  digitalWrite(motorLeft1, LOW);
  digitalWrite(motorLeft2, HIGH);
}

void turnRight() {
  digitalWrite(motorRight1, LOW);
  digitalWrite(motorRight2, HIGH);
  digitalWrite(motorLeft1, HIGH);
  digitalWrite(motorLeft2, LOW);
}

void stopRobot() {
  digitalWrite(motorRight1, LOW);
  digitalWrite(motorRight2, LOW);
  digitalWrite(motorLeft1, LOW);
  digitalWrite(motorLeft2, LOW);
}

void avoidLeft() {
  stopRobot();
  delay(500);
  reverse();
  delay(1500);
  turnLeft();
  delay(1000);
}

void avoidRight() {
  stopRobot();
  delay(500);
  reverse();
  delay(1500);
  turnRight();
  delay(1000);
}

That’s good news :slight_smile:

const int RightSensorPin = 5;
const int LeftSensorPin = 6;

Looks like you moved the switches onto digital pins 5 and 6? If so, you can remove this:

pinMode(A0, INPUT);
pinMode(A1, INPUT);

You could also delete this …

digitalWrite(RightSensorPin, HIGH);
digitalWrite(LeftSensorPin, HIGH);

… and replace with:

pinMode(RightSensorPin, INPUT_PULLUP); // sets the pin to be digital input and enables internal pullup resistor
pinMode(LeftSensorPin, INPUT_PULLUP);

Since this is for a robot, I guess you will not be using the serial monitor. But if you ever wanted to use it (e.g. for debugging), you will need to change the following to other pins. 0 and 1 are used by serial monitor.

const int motorLeft1 = 1;
const int motorLeft2 = 0;

Regards

Ray

This part was leftovers i forgot to delete:

pinMode(A0, INPUT);
pinMode(A1, INPUT);

This i saw on example i tougth it was needed:

digitalWrite(RightSensorPin, HIGH);
digitalWrite(LeftSensorPin, HIGH);

I am going to do this now:

pinMode(RightSensorPin, INPUT_PULLUP); // sets the pin to be digital input and enables internal pullup resistor
pinMode(LeftSensorPin, INPUT_PULLUP);

And i know about the serial pins, but just like you mentioned, it's a robot and i will not monitor the serial.

Like i mentioned on the other thread: When i power my arduino with a 6v battery the program doesn't run right, but when i power it using the USB it works just fine. Tomorrow i will get an 9v bettery, do you think this will solve the problem?

Thanks for the help, Hugo

pinMode(RightSensorPin, INPUT_PULLUP);

This is a quicker way, but is the same as setting the pin to be an input and then doing a digitalWrite(... , HIGH) to turn on the internal pullups.

If you power the Arduino from a battery or other external power supply (not through USB), you need a minimum of 7V. This is because the onboard voltage regulator needs at least that much to produce 5V. 9V battery should be OK. You are powering the motors from a different supply?

The motors are powered by a 4xAA battery holder.

I was investigating the best way to power the board and found out that it's better to use a 6xAA holder than a 9v battery.

Should i really use the holder instead of the 9v battery? Because the 9v one is half the size of the holder, and the robot will not have a long time use, just for me to learn new things (arduino and electronics) and to have something to do (i am currently unemployed).

Hugo

I don't think that can make a big difference between 6xAA=6x1,5V=9V and one battery of 9V. Where you read that information?

Around the web. They didn't recomend the 9v battery because to pack 9v on such a small package, the amperage is very low and it will no last long.

Just went ahead and bought AA batteries. 8xAA is cheaper than a single 9v one. They may use more space but i will have a longer runtime, won't have to change regulary and will save a couple of cents every time i need to change them.

I am now in the processe of adding an LCD to display robot status as it goes.

The LCD program alone runs fine, but when i combine the LCD and the robot programs the robot keeps avoiding and the LCD starts to fill up with black squares.

Every arduino pin is only used for one thing, so the are no external conflicts.
Maybe there is an internal conflict?

//LCD Setup
#include <LiquidCrystal.h>
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

//PIN Naming
const int motorRight1 = 3;
const int motorRight2 = 2;
const int motorLeft1 = 1;
const int motorLeft2 = 0;
const int InfraredSensorPin = 4;
const int RightSensorPin = 5;
const int LeftSensorPin = 6;

void setup() {
//PIN Setup 
  pinMode(motorRight1, OUTPUT);
  pinMode(motorRight2, OUTPUT);
  pinMode(motorLeft1, OUTPUT);
  pinMode(motorLeft2, OUTPUT);
  pinMode(InfraredSensorPin, INPUT);
  pinMode(RightSensorPin, INPUT);
  pinMode(LeftSensorPin, INPUT);
  
//LCD Setup2  
  lcd.begin(16, 2);
//POWER On Status
  lcd.print("Ligado");
} 

void loop() {
//ROBOT behavior
  if(digitalRead(InfraredSensorPin) == LOW) {avoidLeft();}
  if (digitalRead(RightSensorPin) == LOW) {avoidRight();}
  if (digitalRead(LeftSensorPin) == LOW) {avoidLeft();}
  else forward();
}

// Motion routines
void forward() {
  digitalWrite(motorRight1, HIGH);
  digitalWrite(motorRight2, LOW);
  digitalWrite(motorLeft1, HIGH);
  digitalWrite(motorLeft2, LOW);
}

void reverse() {
  digitalWrite(motorRight1, LOW);
  digitalWrite(motorRight2, HIGH);
  digitalWrite(motorLeft1, LOW);
  digitalWrite(motorLeft2, HIGH);
}

void turnLeft() {
  digitalWrite(motorRight1, HIGH);
  digitalWrite(motorRight2, LOW);
  digitalWrite(motorLeft1, LOW);
  digitalWrite(motorLeft2, HIGH);
}

void turnRight() {
  digitalWrite(motorRight1, LOW);
  digitalWrite(motorRight2, HIGH);
  digitalWrite(motorLeft1, HIGH);
  digitalWrite(motorLeft2, LOW);
}

void stopRobot() {
  digitalWrite(motorRight1, LOW);
  digitalWrite(motorRight2, LOW);
  digitalWrite(motorLeft1, LOW);
  digitalWrite(motorLeft2, LOW);
}

void avoidLeft() {
  stopRobot();
  delay(500);
  reverse();
  delay(1500);
  turnLeft();
  delay(1000);
}

void avoidRight() {
  stopRobot();
  delay(500);
  reverse();
  delay(1500);
  turnRight();
  delay(1000);
}

I belive i can use the “A” pins (analog IO) as regular digital, is that true? And will that solve my problem?

The LCD is more to make the robot cool than to really and funcionality, i can use 3 LEDs over the sensors for the same effect…

Hugo

EDIT: Using the Analog IO pins as “regular pins” same thing happens.

Hi hugoalc

How are you powering the LCD?

You could try disconnecting the motors but running the same program, to see if the LCD works then.

Regards

Ray

Disconnecting the motors solved the problem. The screen no longer fills up with squares, but as soon as i connect one motor the problem reappears.

The LCD is powered by the arduinos +5v, along with the h-bridge IC.

What can be causing this? Is there an easy solution?

Hugo

How do you control the motors? If you keep writing something to the LCD the behaviour is the same? the LCD should not accept any data if the Enable pin don't change. If you see something new in the LCD that means that the enable pins is changing then that means that some noise is making the enable pin changing. BTW, I think that 1 LCD powered by batteries is a bad choice and even worst if you keep the backligth on.

Regards,

Luís.

I don’t have seen the new replies after I wrote mine. I had the same problem, and I “solved it” by keeping starting the LCD an writing what I want.

That could be a fix for the LDC, but my main problem is that the robot behaves like one of the sensors is HIGH.
I really like the LCD but i may have to go with the LEDs…

EDIT: Powering the LCD with the +3.3v the cubes take much longer to appear, but the robot still acts like it is avoiding something.

For testing, can you try powering the Arduino and LCD from one power source, and the motors from another?