Arduino- Program Selector

Hi everyone!

So I am making a robot, using an Arduino Uno R3. The robot will have 2 modes, passive and aggressive. Each mode has it's own separate functions (In aggressive the robot follows you, in passive it just wanders around.) I have not actually wrote any code YET, because I am still in the research phase.

Anyways, here is my problem. I want you to be able to switch between modes using two buttons. When you press button 1 it switches modes to passive, and when you press button 2 it switches to aggressive. But, my question is... how do I have TWO sketches on ONE Arduino? I need a way to have each mode stored on there, but how do I do that? The modes need their own functions (voids) ! So, how do I have the two modes stored there and have them switch with the press of a button? Any and all help is greatly appreciated! :slight_smile:

You will have to have all functionality in one sketch, there is no way to swicht sketches on the fly.

You could place all routines that are different in the two moods, in two seperate arrays
and call the functions from the array, selecting the array by the mood.

Arrays only store numbers! How could I get them to store the modes??

I'm not sure you need two sketches anyway. You state you need two different modes, not sketches. Based on the switches, the state of the machine changes the way it behaves, but not how it behaves. That is, you still needs functions that drive, turn, start, and stop the robot. What's different is the way in which it performs those tasks. Stated in the most simplistic terms, one mode responds to random commands from a set of functions. The other mode uses some form of external sensor that enables it to track you. True, pointers to functions will work, but may be unnecessary.

I'd just 'if'..'then'

#define PASSIVE_PIN
#define AGGRESSIVE_PIN

enum modes{passive, aggressive} mode;

setup {....}

loop() {
if (digitalRead(PASSIVE_PIN)==LOW) mode = passive;
if (digitalRead(AGGRESSIVE_PIN)==HIGH) mode = aggressive;
if (mode == passive) dopassive(); else doaggressive();
}

// Passive loop
dopassive () {......}
doaggressive () {.....}

/////////////////////////////////////////

If both passive and aggressive modes would make more sense to have same function naming just different operation then polymorphism is probably your answer.

You'd create an Interface.h class definition with function name (prototype) file for both implementations
Both your passive class and aggressive class .cpp definitions would inherit your Interface class definition.

Then you'd make a separate passive and aggressive object and call the appropriate one using a pointer.

passive passive_obj
aggressive aggressive_obj
Interface objectptr *obj;

loop () {
if ( mode == passive ) objectptr = &passive_obj; else objectptr = &aggressive_obj;

// Now anytime you call a function on the object it will either execute passive or aggressive definition
objectptr.chase()
}

Ok... I like that idea alot! Bur, let me explain something in further detail than before. In the Passive mode, it doesn't exactly just wander around... I just used that as an example.

Mode 1:

The robot avoids obstacles, similar to an obstacle avoiding robot. Then, if it just happens to stumble upon a life form, it speaks, then turns and goes the other way.

Mode 2:

It follows any life form around, and when in range it shoots a Nerf blaster thing at the life form.

So, to spin off your idea econjack, I could have functions (void TurnAround(), void Left(), void ShootGun(), etc) Then have other functions to manipulate those functions! (void Mode1(), void Mode2(). ) But then, my question is, how do I make those functions LOOP once complete, so they keep going after they have done their stuff! (So that once the mode is done the robot does not just stop and sit there :slight_smile: )

Thanks so much for all the help!

WesleyRTech:
Arrays only store numbers! How could I get them to store the modes??

typedef void (*pvFunc)();
void one() {
  Serial.print(F("One "));
}
void two() {
  Serial.print(F("Two "));
}
void three() {
  Serial.print(F("Three "));
}
const pvFunc  pmActions[] PROGMEM = { one, two, three };

void setup() {
  Serial.begin(115200);
  (*((pvFunc) pgm_read_ptr_near(&pmActions[0])))();
  (*((pvFunc) pgm_read_ptr_near(&pmActions[1])))();
  (*((pvFunc) pgm_read_ptr_near(&pmActions[2])))();
  Serial.println();
}
void loop() {}

tgit23:
I'd just 'if'..'then'

#define PASSIVE_PIN
#define AGGRESSIVE_PIN

enum modes{passive, aggressive} mode;

setup {....}

loop() {
if (digitalRead(PASSIVE_PIN)==LOW) mode = passive;
if (digitalRead(AGGRESSIVE_PIN)==HIGH) mode = aggressive;
if (mode == passive) dopassive(); else doaggressive();
}

// Passive loop
dopassive () {......}
doaggressive () {.....}

/////////////////////////////////////////

If both passive and aggressive modes would make more sense to have same function naming just different operation then polymorphism is probably your answer.

You'd create an Interface.h class definition with function name (prototype) file for both implementations
Both your passive class and aggressive class .cpp definitions would inherit your Interface class definition.

Then you'd make a separate passive and aggressive object and call the appropriate one using a pointer.

passive passive_obj
aggressive aggressive_obj
Interface objectptr *obj;

loop () {
if ( mode == passive ) objectptr = &passive_obj; else objectptr = &aggressive_obj;

// Now anytime you call a function on the object it will either execute passive or aggressive definition
objectptr.chase()
}

But then how do I make dopassive() and doaggresive() LOOP so that once "complete" the robot does not just stop and stand still? Sorry if this is an obvious question, I'm relatively new to Arduino code!

Arduino continuously call the loop() over and over again by default. So the dopassive() and doaggressive() functions will be called over and over again.

What Arduino do you have and have you tried any of the sample programs with it? It appears that you haven't had much experience with the Arduino. The setup() function is used to establish the environment the program runs in (e.g., the baud rate for the Serial object, pin modes, etc.). As tgit23 points out, the loop() function continuously repeats itself until 1) power is removed, 2) there's a reset, or 3) there's a component failure.

econjack:
What Arduino do you have and have you tried any of the sample programs with it? It appears that you haven't had much experience with the Arduino. The setup() function is used to establish the environment the program runs in (e.g., the baud rate for the Serial object, pin modes, etc.). As tgit23 points out, the loop() function continuously repeats itself until 1) power is removed, 2) there's a reset, or 3) there's a component failure.

No, I have experience with Arduino. I know "void loop()" loops, and I know what "void setup()" does. I have made a few things with arduino. I just have not really got into creating other subroutines. (I have never created another void before :slight_smile: , I have always used the setup and loop! :slight_smile: )

I have never created another void before

And you never will. The term is FUNCTION, not VOID.

WesleyRTech:
Arrays only store numbers! How could I get them to store the modes??

Arrays can store whatever you want, any datatype.

And computers only store 0's and 1's, yet they can represent anything...