Way to halt and resume program where it halted at

Ok…so I’ve got my robot moving around, following its code, and have figured out how to get the Ultrasonic range finder sensor to detect objects in front and stop program, drive around the object, but now I’m having trouble resuming the program where it stopped to drive around the object. Any suggestions on resuming program? The few books I have dont mention anything about this. My robot is set to follow an exact pattern, not roam around aimlessly. Its a robot lawnmower. Basically start in the corner of the yard, go forward X number of seconds to other side of yard, stop, run right motor to turn around 180* and make next pass. Only obstacles in the yard are trees. If he starts the forward X number of seconds over after going around the tree, he will drive out of my yard lol, and get way off pattern. Also, lets say he drives forward 5 sec, stops at a tree, drives around it, and resumes at 5 sec to drive a complete run of 10 sec, he will be off pattern by however much distance he took to get around the tree…If anyone has any suggestions that would be great. (I’m very new to programming and robotics so thank you very much for any help the you guys can provide)

You need to post your code, otherwise we're just playing guessing games and wasting time

Please understand this code is not finished, I’m still working on it and tweaking it. I also realize at the end of Ultrasonic_Sensor function there isnt anything after the }else{ statement, thats where I’m stuck trying to get the robot back on track after going around an obstacle. Thank you!

/ARC Test Code

#include <SoftwareSerial.h> //Include Serial Library
#define rxPin 2 //Sabertooth Motor Controller Recieve Pin
#define txPin 3 //Sabertooth Motor Controller Transmit Pin
#define M1_for 127 //Sabertooth Motor 1 Forward
#define M1_stop 64 //Sabertooth Motor 1 Stop
#define M1_rev 1 //Sabertooth Motor 1 Reverse
#define M2_for 255 //Sabertooth Motor 2 Forward
#define M2_stop 192 //Sabertooth Motor 2 Stop
#define M2_rev 128 //Sabertooth Motor 2 Reverse

SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);

//name digital input & output pins
#define BUTTON 7 //Start Button Pin
#define Echo 11 //Ultrasonic Sensor Pin In
#define Trig 10 //Ultrasonic Sensor Pin Out

long pwmRange, inch; //Declare values for Ultrasonic Sensor

int val = 0; //val stores the state of the input pin
int old_val = 0; //stores the previous value of “val”
int state = 0; //0 = motor off and 1 = motor on

void setup() {
Serial.begin(9600); //Begin Serial at 9600 baud rate
pinMode(rxPin, INPUT); //Set rxPin as an Input
pinMode(txPin, OUTPUT); //Set txPin as an Output
mySerial.begin(9600); //Begin mySerial at 9600 baud rate
pinMode(BUTTON, INPUT); //Set BUTTON as an Input
pinMode(Echo, INPUT); //Set Echo as an Input
pinMode(Trig, OUTPUT); //Set Trig as an Output
}

void loop(){
val = digitalRead(BUTTON); //Check if BUTTON was pushed
if ((val == HIGH) && (old_val == LOW)){
state = 1 - state;
delay(20);
}

old_val = val; //val is now old lets store it
if (state == 1) { //If BUTTON was pushed, start program
delay(3000); //Wait 3 seconds
Ultrasonic_Sensor(); //Sensor funtion
Forward_Frontlawn(); //Forward funtion
Turn_Left(); //Turn left function
Forward_Frontlawn(); //Forward function
Turn_Right(); //Turn right funtion
}
}
void Forward_Frontlawn(){
mySerial.write(M1_for); //Run motor1 forward
mySerial.write(M2_for); //Run motor2 forward
delay(4000); //Run both motors 4 seconds
mySerial.write(M1_stop); //Stop motor1
mySerial.write(M2_stop); //Stop motor2
delay(1000); //Wait 1 second
}
void Turn_Left(){
mySerial.write(M2_for); //Run motor2 forward(Turn Left 180*)
delay(2000); //Run motor2 2 seconds
mySerial.write(M2_stop); //Stop motor2
delay(1000); //Wait 1 second
}
void Turn_Right(){
mySerial.write(M1_for); //Run motor1 forward(Turn Right 180*)
delay(2000); //Run motor1 2 seconds
mySerial.write(M1_stop); //Stop motor1
delay(1000); //Wait 1 second
}

void Ultrasonic_Sensor(){
digitalWrite(Trig, LOW);
delay(2);
digitalWrite(Trig, HIGH);
delay(10);
digitalWrite(Trig, LOW);
pwmRange = pulseIn(Echo, HIGH);

inch = pwmRange / 147;
delay(500);

if (inch < 12){ //Check if an object is within 12 inches of mower
mySerial.write(M1_stop); //Stop motor1
mySerial.write(M2_stop); //Stop motor2
delay(2000); //Wait 2 seconds
mySerial.write(M2_rev); //Run motor2 in reverse(Turn Right 90*)
delay(2000); //Run motor2 for 2 seconds
mySerial.write(M2_stop); //Stop motor2
delay(2000); //Wait 2 seconds
mySerial.write(M1_for); //Run motor1 forward
mySerial.write(M2_for); //Run motor2 forward
delay(2000); //Run both motors 2 seconds
mySerial.write(M1_stop); //Stop motor1
mySerial.write(M2_stop); //Stop motor2
delay(2000); //Wait 2 seconds
mySerial.write(M2_for); //Run motor2 forward(Turn Left 90*)
delay(2000); //Run motor2 for 2 seconds
mySerial.write(M2_stop); //Stop motor2
delay(2000); //Wait 2 seconds
mySerial.write(M2_for); //Run motor2 forward
mySerial.write(M1_for); //Run motor1 forward
delay(2000); //Run both motors 2 seconds
mySerial.write(M1_stop); //Stop motor1
mySerial.write(M2_stop); //Stop motor2
delay(2000); //Wait 2 seconds
mySerial.write(M2_for); //Run motor2 forward(Turn Left 90*)
delay(2000); //Run motor2 2 seconds
mySerial.write(M2_stop); //Stop motor2
delay(2000); //Wait 2 seconds
mySerial.write(M1_for); //Run motor1 forward
mySerial.write(M2_for); //Run motor2 forward
delay(2000); //Run both motors 2 seconds
mySerial.write(M1_stop); //Stop motor1
mySerial.write(M2_stop); //Stop motor2
delay(2000); //Wait 2 seconds
mySerial.write(M2_rev); //Run motor2 reverse(Turn right 90*)
delay(2000); //Run motor2 2 seconds
mySerial.write(M2_stop); //Stop motor2
delay(2000); //Wait 2 seconds
}else{
}
Serial.print(inch);
Serial.println(" inches");
}

Two usual items of advice 1) post your code using code tags (the # icon on the editors toolbar) 2) learn to get rid of calls to delay

I did’nt know about the code tags, (I beleive I see it now) Tyvm. And by “calls to delay” your referring to the “delay(2000)” between my motor commands? And I’m also new to posting on forums, lol. So thank you for your patience.

/ARC Test Code

#include <SoftwareSerial.h>    //Include Serial Library
#define rxPin 2      //Sabertooth Motor Controller Recieve Pin
#define txPin 3      //Sabertooth Motor Controller Transmit Pin
#define M1_for 127   //Sabertooth Motor 1 Forward
#define M1_stop 64   //Sabertooth Motor 1 Stop
#define M1_rev 1     //Sabertooth Motor 1 Reverse
#define M2_for 255   //Sabertooth Motor 2 Forward
#define M2_stop 192  //Sabertooth Motor 2 Stop
#define M2_rev 128   //Sabertooth Motor 2 Reverse

SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);

//name digital input & output pins
#define BUTTON 7   //Start Button Pin
#define Echo 11    //Ultrasonic Sensor Pin In
#define Trig 10    //Ultrasonic Sensor Pin Out

long pwmRange, inch;   //Declare values for Ultrasonic Sensor

int val = 0;      //val stores the state of the input pin
int old_val = 0;  //stores the previous value of "val"
int state = 0;    //0 = motor off and 1 = motor on

void setup() {
  Serial.begin(9600);       //Begin Serial at 9600 baud rate
  pinMode(rxPin, INPUT);    //Set rxPin as an Input
  pinMode(txPin, OUTPUT);   //Set txPin as an Output
  mySerial.begin(9600);     //Begin mySerial at 9600 baud rate
  pinMode(BUTTON, INPUT);   //Set BUTTON as an Input
  pinMode(Echo, INPUT);     //Set Echo as an Input
  pinMode(Trig, OUTPUT);    //Set Trig as an Output
}

void loop(){
  val = digitalRead(BUTTON);     //Check if BUTTON was pushed       
  if ((val == HIGH) && (old_val == LOW)){
    state = 1 - state;
    delay(20);
  }
  
  old_val = val;           //val is now old lets store it
  if (state == 1) {        //If BUTTON was pushed, start program
    delay(3000);           //Wait 3 seconds
    Ultrasonic_Sensor();   //Sensor funtion
    Forward_Frontlawn();   //Forward funtion
    Turn_Left();           //Turn left function
    Forward_Frontlawn();   //Forward function
    Turn_Right();          //Turn right funtion
  }
}
void Forward_Frontlawn(){
  mySerial.write(M1_for);   //Run motor1 forward
  mySerial.write(M2_for);   //Run motor2 forward
  delay(4000);              //Run both motors 4 seconds
  mySerial.write(M1_stop);  //Stop motor1
  mySerial.write(M2_stop);  //Stop motor2
  delay(1000);              //Wait 1 second
}
void Turn_Left(){
  mySerial.write(M2_for);   //Run motor2 forward(Turn Left 180*)
  delay(2000);              //Run motor2 2 seconds
  mySerial.write(M2_stop);  //Stop motor2
  delay(1000);              //Wait 1 second
}
void Turn_Right(){
  mySerial.write(M1_for);   //Run motor1 forward(Turn Right 180*)
  delay(2000);              //Run motor1 2 seconds
  mySerial.write(M1_stop);  //Stop motor1
  delay(1000);              //Wait 1 second
}

void Ultrasonic_Sensor(){
  digitalWrite(Trig, LOW);
  delay(2);
  digitalWrite(Trig, HIGH);
  delay(10);
  digitalWrite(Trig, LOW);
  pwmRange = pulseIn(Echo, HIGH);
  
  inch = pwmRange / 147;
  delay(500);
  
  if (inch < 12){              //Check if an object is within 12 inches of mower
    mySerial.write(M1_stop);   //Stop motor1
    mySerial.write(M2_stop);   //Stop motor2
    delay(2000);               //Wait 2 seconds
    mySerial.write(M2_rev);    //Run motor2 in reverse(Turn Right 90*)
    delay(2000);               //Run motor2 for 2 seconds
    mySerial.write(M2_stop);   //Stop motor2
    delay(2000);               //Wait 2 seconds
    mySerial.write(M1_for);    //Run motor1 forward
    mySerial.write(M2_for);    //Run motor2 forward
    delay(2000);               //Run both motors 2 seconds
    mySerial.write(M1_stop);   //Stop motor1
    mySerial.write(M2_stop);   //Stop motor2
    delay(2000);               //Wait 2 seconds
    mySerial.write(M2_for);    //Run motor2 forward(Turn Left 90*)
    delay(2000);               //Run motor2 for 2 seconds
    mySerial.write(M2_stop);   //Stop motor2
    delay(2000);               //Wait 2 seconds
    mySerial.write(M2_for);    //Run motor2 forward
    mySerial.write(M1_for);    //Run motor1 forward
    delay(2000);               //Run both motors 2 seconds
    mySerial.write(M1_stop);   //Stop motor1
    mySerial.write(M2_stop);   //Stop motor2
    delay(2000);               //Wait 2 seconds
    mySerial.write(M2_for);    //Run motor2 forward(Turn Left 90*)
    delay(2000);               //Run motor2 2 seconds
    mySerial.write(M2_stop);   //Stop motor2
    delay(2000);               //Wait 2 seconds
    mySerial.write(M1_for);    //Run motor1 forward
    mySerial.write(M2_for);    //Run motor2 forward
    delay(2000);               //Run both motors 2 seconds
    mySerial.write(M1_stop);   //Stop motor1
    mySerial.write(M2_stop);   //Stop motor2
    delay(2000);               //Wait 2 seconds
    mySerial.write(M2_rev);    //Run motor2 reverse(Turn right 90*)
    delay(2000);               //Run motor2 2 seconds
    mySerial.write(M2_stop);   //Stop motor2
    delay(2000);               //Wait 2 seconds
  }else{
  }
  Serial.print(inch);
  Serial.println(" inches");
}

You can't really expect a lawnmower to follow a specific path, if all it knows is how long to go straight and how long to spend turning. Wet grass, tall grass, rocks, the diameter of the obstacle, etc. will all cause the lawnmower to deviate from the exact path that you want it to follow, based solely on time.

You really need some way to know exactly where the robot is, relative to the area that it is to mow. This is not an easy thing to accomplish in a cost effective manner. It is also why pool cleaners and roombas do not try to follow a specific path, instead just wandering around at random, in the expectation that eventually they will cover the whole are to be cleaned/vacuumed/mowed.

I seriously hope that any and all testing done with this robot - if it actually exists, is being done with blade motors -off-; I also don't see any form of emergency stop protection for "total shutdown" (note: such an e-stop should be separate from the code and microcontroller if possible; in fact, if it can be implemented as a "pull-out" that cuts power totally - all the better).

As PaulS noted, it is naive to think that such a robot can easily follow a path or pattern somewhat "blindly". It is anything but easy, and anything but cheap. I've given a lot of hard thought to the problem, actually - I have a Friendly Robotics RL500 that I want to "upgrade" so I don't need a perimeter wire to bury. So far, what I've thought about has included:

1) Bury perimeter magnets and sense them with hall-effect sensors 2) Add fast humidity detectors to detect cut vs uncut grass (in theory, cut grass should be more humid) vs non-grass 3) Use a color sensor (and probably some optics) to detect grass vs non-grass 4) I've got this idea for a pressure flow sensor to detect the rise of a ping-pong ball based on "blockage" from un-cut grass; probably won't work... 5) I've also got ideas for using a neural network to detect grass and vegetation via a camera (there's some research on this out there if you look) 6) I've also got ideas on how to map surroundings using neural nets or other machine learning algos, via a scanning ultrasonic sensor array (and likely a compass module)

For me, though - this is all ideas; I intend to do careful study on everything, testing sub-systems, etc - before I start mounting things on the robot itself; there is a time and place for "hacking" - when it involved large robotic devices with spinning blades, that is not the time to be frivolous with safety (I've participated and helped in set up of SRL performances; despite the mayhem, their systems are actually very safe - they give a lot of thought to this, believe me).

All it takes is one "oops" - and if you are lucky, only major property damage occurs; if you aren't, then it's a trip to the hospital (or worse, depending on the robotic system, I suppose)...

First of all I'd like to say that I totally concur with the above responses, but I would like to point out that as a beginner it can be very helpful to set up a step by step path, disregarding such things as slippage, perimeter, sensors and what not. I also agree that a lawnmower running amok is pretty dangerous and testing should be done with caution. Nevertheless, it is pretty thrilling to watch a machine run by itself, that you yourself have programmed...

Before you go ahead making an autonomous robot lawnmower, maybe you could try making it remote controlled http://www.instructables.com/id/Arduino-RC-Lawnmower/

Good luck!

Cr0sh---First of all, my blade motor isnt installed yet, all testing is on the sensor and drive motors atm. Second, As I've stated above the code is not complete, I am just trying to figure out how to resume program after it avoids an object. Third, As I've stated above I am new to programming and robotics, this is my first real project, so calling me names is absolutely unnecessary and uncalled for.

You could bury a cable, run current through and try to have the mower follow that or go by some form of active guidance external to the mower but you still need sensors to detect unanticipated objects in the way including rocks, toys, pets and people. Path by dead reckoning is making some big assumptions.

In the long-ago they had self-guiding lawn mowers. They were called sheep.

jamos82: Cr0sh---First of all, my blade motor isnt installed yet, all testing is on the sensor and drive motors atm.

Glad to hear - dogs and small children shall rejoice! :D

jamos82: Second, As I've stated above the code is not complete, I am just trying to figure out how to resume program after it avoids an object.

If the code isn't complete - and even if there isn't a blade motor attached - there isn't any reason -not- to install an e-stop; you're going to need one sooner or later, so get it in now, fully tested (black-box the thing) - so you don't have to band-aid it in later.

jamos82: Third, As I've stated above I am new to programming and robotics, this is my first real project, so calling me names is absolutely unnecessary and uncalled for.

About the closest thing I can find in my post to "calling you names" is where I said - and I quote myself: "...it is naive to think that such a robot can easily follow a path or pattern..."; where I said you were "naive" - according to google:

https://www.google.com/search?&q=definition%3A+naive

The definition for "naive" is "Showing a lack of experience, wisdom, or judgment"...

You just stated that "I am new to programming and robotics"; that would fit the definition of "naive" to an extent; you did, however, show "wisdom and judgment" in not installing the blade motor, which is more than I can say for some. However, saying that you may have been "naive" is anything but calling you a name. If that really bothers you, I'm not sure what to say. There was certainly no malevolence or malice intended on my part; I merely want to impart a sense of education about these matter, especially to those who are new at such robotics projects, because once you move to a certain level, things can be dangerous really quickly.

Good luck with your project, and continue to stay safe with it.

GoForSmoke: You could bury a cable, run current through and try to have the mower follow that

There are several issues with such perimeter systems:

1) You have to do a fair amount of work to set it up 2) You have to supply it with a signal during use 3) Maintenance can be difficult - imagine locating a break in the line 4) Per 3, breakage can and does occur (plus other issues like corrosion and such)

Which is why I was thinking about magnets (specifically rare-earth magnets); likely mounted in plastic spikes in some manner, spaced about 6 inches apart. Using a hall-effect sensor (or several, likely), you could detect this magnetic perimeter fairly easily. No signal would be needed to activate it; maintenance would be virtually eliminated.

However, there is still the possibility that something could happen to cause a "runaway" condition, thus my other ideas for grass/non-grass detection. Part of my other reasoning strategy was to be able to map mowed vs. non-mowed areas, and skip over mowed areas during "random" walks or whatnot, while turning off the blade motors to conserve battery power and increase run-time (this wouldn't be an issue with an engine powered mower, unless you had throttle control and a centrifugal clutch on the blade so that at idle, the blade doesn't turn).

GoForSmoke: or go by some form of active guidance external to the mower but you still need sensors to detect unanticipated objects in the way including rocks, toys, pets and people. Path by dead reckoning is making some big assumptions.

Fully agreed - and its a tough nut to crack. GPS isn't accurate enough (and DGPS is too expensive); affordable 2D laser rangefinders don't really exist (another project I have my thinking cap on about) - with the exception of one that I can think of (for a robot vacuum - unfortunately, you have to buy the vacuum to get the sensor, but that is still cheaper than the next cheapest 2D laser rangefinder). So - some form of ultrasonic sensor system, coupled with (maybe) a vision system, all tied together with some machine learning algorithms seems to be the best way to go. That, or "random walk" (which actually doesn't do too bad in the long run - if going by the roomba is any guide).

GoForSmoke: In the long-ago they had self-guiding lawn mowers. They were called sheep.

Unfortunately, your neighbor's grass is just as tasty as your's (and his garden, and flowers, etc)...

:D

Yes I fully intend to install a safety switch (of some sort) for the blade motor. I will not be "testing" the blades untill its pretty much rdy to start mowing. This is a work in progress, as well as learning as I go. I had thot of GPS before, but as you said, GPS that is accurate enough for this is very expensive and I imagine to advanced for me atm. I'm not a fan of the mower just randomly diving all over the yard untill it eventually mows the whole thing lol. My back yard is completely surrounded by wooden privacy fence, so the mower COULD just "bounce" back and forth from fence to fence. But my front yard has neighbors on both sides and my yard just blends into theres lol, so it need's to know when to turn around. Thx everyone for your ideas and help. I imagine I'll be posting pics when its done. I've got a few months till summer lol.

jamos82: My robot is set to follow an exact pattern, not roam around aimlessly. Its a robot lawnmower.

  1. Make the "exact pattern" take into account the trees.

  2. Failing that, if it hits an obstacle, then take into account what it did to avoid it. Say you find a tree, and you reverse 1 metre, turn right, go forwards 3 metres, etc. , then take that "branch" into account in your pattern. You could make sure you drive back to the same spot on the other side of the tree, and subtract out the width of the tree from your pattern.

cr0sh:

GoForSmoke: You could bury a cable, run current through and try to have the mower follow that

There are several issues with such perimeter systems:

Where did I say perimeter system? Why would a mower -follow- a perimeter? And yes there can be problems. Also solutions.

GoForSmoke: or go by some form of active guidance external to the mower but you still need sensors to detect unanticipated objects in the way including rocks, toys, pets and people. Path by dead reckoning is making some big assumptions.

Fully agreed - and its a tough nut to crack. GPS isn't accurate enough....[/quote]

And you have ideas but none of them match mine.

GoForSmoke: In the long-ago they had self-guiding lawn mowers. They were called sheep.

Unfortunately, your neighbor's grass is just as tasty as your's (and his garden, and flowers, etc)...

:D

It would probably take a fence to sort that out. Not that I suggest the use of sheep in suburbia.

Perhaps more trouble than it's worth, but could you do something like cell phone triangulation? Have three signal emitters somewhere in the yard (most likely corners) and it can calculate its position based on the relative strengths of the signals from each? I'm not sure whether or not that'd ultimately be any more accurate than GPS.

If it could get you to within a foot or so, though, you could map the yard as a matrix of one-foot squares (or larger, depending on the size of your deck) stored as a two-dimensional array of boolean values and check off each square as the mower passes over it. I don't think there's enough RAM on the standard Arduino, but I believe I saw one or two shields that offer extended RAM, or possibly something like progmem would be fast enough to suffice.