Robotic Lawn Mower

Hi,

My son is doing A level engineering and is struggling with his project, sadly I am not very good with programming so I wondered if someone would be kind enough to help.

Thanks you very much see below.
David

I’m struggling with my code for my robotic lawnmower project. I am using an Arduino board and a perimeter wire sensor kit. I am trying to make the mower move up to a perimeter wire, stop, turn 90 degrees go forward slightly and turn 90 degrees again to simulate the motions of cutting grass. At the moment I have managed to get the mower to drive up to the wire and stop however I am having trouble making it turn 90 degrees. I am using two DC motors connected via an H bridge to an ardiuno mega 2560 board. Any help would be appreciated, I have copied the code below:

const int analogInPin = A0;
const int analogOutPin = 9;
const int ENA_PIN = 11;
const int IN1_PIN = 7;
const int IN2_PIN = 6;
const int ENB_PIN = 9;
const int IN3_PIN = 5;
const int IN4_PIN = 4;
int toggleSwitchPin1 = 2;
int relaypin = 3;

int toggleSwitchState1;

int sensorValue = 0;
int outputValue = 0;
void setup() {
// initialize serial communications at 9600 bps:
Serial.begin(9600);
pinMode(ENA_PIN, OUTPUT);
pinMode(IN1_PIN, OUTPUT);
pinMode(IN2_PIN, OUTPUT);
pinMode(ENB_PIN, OUTPUT);
pinMode(IN3_PIN, OUTPUT);
pinMode(IN4_PIN, OUTPUT);
pinMode(toggleSwitchPin1, INPUT_PULLUP);
pinMode(relaypin, OUTPUT);

}

void loop() {
toggleSwitchState1 = digitalRead(toggleSwitchPin1);
if (toggleSwitchState1 == HIGH) {
// read the analog in value:
sensorValue = analogRead(analogInPin);
// map it to the range of the analog out:
outputValue = map(sensorValue, 0, 1023, 0, 255);
// change the analog out value:
analogWrite(analogOutPin, outputValue);

// print the results to the Serial Monitor:
Serial.print("sensor = ");
Serial.print(sensorValue);
Serial.print("\t out put = ");
Serial.println(outputValue);
delay(5);
digitalWrite(relaypin, HIGH);
while (outputValue < 100) {
digitalWrite(IN1_PIN, HIGH);
digitalWrite(IN2_PIN, LOW);
digitalWrite(IN4_PIN, HIGH);
digitalWrite(IN3_PIN, LOW);
analogWrite(ENA_PIN, 180);
analogWrite(ENB_PIN, 180);
delay(10);

sensorValue = analogRead(analogInPin);
outputValue = map(sensorValue, 0, 1023, 0, 255);
analogWrite(analogOutPin, outputValue);

Serial.print("sensor = ");
Serial.print(sensorValue);
Serial.print("\t out put = ");
Serial.println(outputValue);
delay(5);
//digitalWrite(IN1_PIN, LOW);
//digitalWrite(IN2_PIN, LOW);
//digitalWrite(IN4_PIN, LOW);
//digitalWrite(IN3_PIN, LOW);
}

analogWrite(ENA_PIN, 100);
analogWrite(ENB_PIN, 100);
digitalWrite(IN1_PIN, LOW);
digitalWrite(IN2_PIN, HIGH);
digitalWrite(IN3_PIN, LOW);
digitalWrite(IN4_PIN, HIGH);
analogWrite(ENA_PIN, 100);
analogWrite(ENB_PIN, 100);
delay(2000);
digitalWrite(IN1_PIN, HIGH);
digitalWrite(IN2_PIN, LOW);
digitalWrite(IN3_PIN, HIGH);
digitalWrite(IN4_PIN, LOW);
delay(2000);
digitalWrite(IN1_PIN, LOW);
digitalWrite(IN2_PIN, HIGH);
digitalWrite(IN3_PIN, LOW);
digitalWrite(IN4_PIN, HIGH);
delay(2000);
digitalWrite(IN1_PIN, LOW);
digitalWrite(IN2_PIN, LOW);
digitalWrite(IN3_PIN, LOW);
digitalWrite(IN4_PIN, LOW);
}

consider

please test with LEDs first. i left my HW values in place

#define MyHW
#ifdef MyHW
# include "sim.hh"
const int ENA_PIN = 8;
const int IN1_PIN = 10;
const int IN2_PIN = 11;
const int ENB_PIN = 9;
const int IN3_PIN = 12;
const int IN4_PIN = 13;

#else
const int ENA_PIN = 11;
const int IN1_PIN = 7;
const int IN2_PIN = 6;
const int ENB_PIN = 9;
const int IN3_PIN = 5;
const int IN4_PIN = 4;
#endif

const int analogInPin = A0;
const int analogOutPin = 9;

int toggleSwitchPin1 = 2;
int relaypin = 3;

int toggleSwitchState1;

int sensorValue = 0;
int outputValue = 0;

char s [80];

// -----------------------------------------------------------------------------
enum { For = HIGH, Rev = LOW };
void
forward (
    byte dir)
{
    sprintf (s, "%s %d %s", __func__, dir, HIGH == dir ? "For" : "Rev");
    Serial.println (s);
    
    digitalWrite (IN1_PIN,   dir);
    digitalWrite (IN2_PIN, ! dir);
    digitalWrite (IN4_PIN,   dir);
    digitalWrite (IN3_PIN, ! dir);
}

// -------------------------------------
enum { Left = LOW, Right = HIGH };
void
turn (
    byte dir)
{
    sprintf (s, "%s %d %s", __func__, dir, HIGH == dir ? "Right" : "Left");
    Serial.println (s);
    
    digitalWrite (IN1_PIN,   dir);
    digitalWrite (IN2_PIN, ! dir);
    digitalWrite (IN4_PIN,   dir);
    digitalWrite (IN3_PIN, ! dir);
}

// -------------------------------------
void 
spd (
    byte val )
{
        analogWrite (ENA_PIN, val);
        analogWrite (ENB_PIN, val);
}

// -----------------------------------------------------------------------------
void loop ()
{
    if (LOW == digitalRead (toggleSwitchPin1)) {
        digitalWrite (relaypin, LOW);
        spd (0);
        return;
    }

    digitalWrite (relaypin, HIGH);
    spd (100);

    outputValue = map ( analogRead (analogInPin), 0, 1023, 0, 255);
    analogWrite (analogOutPin, outputValue);

    Serial.print (" sensor = ");
    Serial.println (outputValue);

    if (outputValue < 100) {    // reached perimeter
        turn (Left);
        delay (1000);           // time it takes to turn

        forward (For);
        delay (2000);           // parallel to perimeter

        turn (Left);            // time it takes to turn
        delay (1000);

        forward (For);
        delay (5000);           // time enough to move away from perimeter
    }

    delay (1000);               // slow output
}

// -----------------------------------------------------------------------------
void setup () {
    // initialize serial communications at 9600 bps:
    Serial.begin (9600);
    pinMode (ENA_PIN, OUTPUT);
    pinMode (IN1_PIN, OUTPUT);
    pinMode (IN2_PIN, OUTPUT);
    pinMode (ENB_PIN, OUTPUT);
    pinMode (IN3_PIN, OUTPUT);
    pinMode (IN4_PIN, OUTPUT);
    pinMode (toggleSwitchPin1, INPUT_PULLUP);
    pinMode (relaypin, OUTPUT);

    forward (For);
}

Consider posting an annotated schematic. Doing this will help your son get familiar with CAD for electronics. He can download KiCad, it is a great program that will take him from concept to a finished PCB and all in between. That will take some effort to learn but it will be well worth it in the future.

Please consider:
Using code tags, to make it easier for others to help.
Adding comments, to show intent
Getting rid of magic numbers and delays.
Putting the robot on blocks, and using Serial too help with debug

Dividing by four is simpler, and arguably more correct.

any kind of code is not done all at once.
Especially not if you are a beginner.

You should learn how to write functions. It is easy to learn.

certain combinations of your input-pins

IN1_PIN
IN2_PIN
IN3_PIN
IN4_PIN

result in driving

  • forward
  • backwards
  • turningLeft
  • turningRight

using names like "forward" "turningLeft" etc. will make it much easier to develop the code.

You can go on walking slowly on your own feet. Or you can invest time into mounting together a sportscar-kit. Which once it is build and ready to drive will drive you much faster than walking on your own feet.

It is similar with programming. Having learned the basics will make you proceed much much faster because you know what you are coding. Without this knowledge it is trial and error which will cost you three times more time than learning the basics

Take a look into this tutorial:

Arduino Programming Course

It is easy to understand and has a good mixture between explaining important concepts and example-codes to get you going. So give it a try and report your opinion about this tutorial.

When-ever you have a specific question the answers will come pretty quick.
Because specific answers are easy to give.

So as a first example I will post the question and the answer

Question: How do I code functions?

Answer most basic way is to have no result-value which is done by the word "void"
followed by the name of the function. This name should be self-descriptive
followed by open/close parenthesis
then followed by a curly opening brace

then comes your code
then a closing curly brace

// definition of the function with name "**forward**"
void foward() {
  digitalWrite(IN1_PIN, LOW);
  digitalWrite(IN2_PIN, HIGH);
  digitalWrite(IN3_PIN, LOW);
  digitalWrite(IN4_PIN, HIGH);
  analogWrite(ENA_PIN, 100);
  analogWrite(ENB_PIN, 100);
}

the function is used by writing the name without the leading "void"

//drive straight ahead
foward();

Of course you will have a lot of questions just ask them all

best regards Stefan

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.