using a 4 button remote to create 4 different behavior states for 2 servos

I am super new to programming so I’m having a bit of difficulty finding what I need to do in my particular situation.

I have a 4 button remote that I want to use to activate 4 different behavior states for 2 servos with the first button/state being the default/power on state, which would be both servos being stationary and centered.

With my limited experience I have been able to use the code below to get both servos to move randomly as desired, or with a tweak here and there to get the other 3 states to work, for the servos either moving randomly or remaining stationary and centered. I am not finding, and lack the experience to come up with the code to put it all together and have the remote drive the 4 different behaviors. Any help in this matter would be greatly appreciated.


#include <Servo.h>

Servo xservo;
Servo yservo;

int xpos;
int ypos;

void setup()
{
xservo.attach(9);
yservo.attach(10);
}

void loop()
{
{
ypos = random(180); //generate random value for y-servo
yservo.write(ypos); //y-servo moves to new position
delay(500);
}
{
xpos = random(180); //generate random value for x-servo
xservo.write(xpos); //x-servo moves to new position
delay(500);

}
}

What remote do you have.
.

this is the remote and reciever module I’m using:

I’ve tried to put together something on my own to attempt to have it do what I want, It’s obviously wrong, but I have yet to find information that seems to lead to what I actually need to do. I’d also like the servos to move at the same time when they’re both set to move if that’s possible, the way it is now, one moves then the other.

This is the sum of what I have put together so far:


#include <Servo.h>

Servo xservo;
Servo yservo;

int buttonApin = 5;
int buttonBpin = 6;
int buttonCpin = 7;
int buttonDpin = 8;
int xpos;
int ypos;

void setup()
{
xservo.attach(9);
yservo.attach(10);
pinMode(buttonApin, INPUT_PULLUP);
pinMode(buttonBpin, INPUT_PULLUP);
pinMode(buttonCpin, INPUT_PULLUP);
pinMode(buttonDpin, INPUT_PULLUP);
}

void loop()
{
if (digitalRead(buttonApin) == LOW)
{
yservo.write(90); //y-servo moves to new position
delay(500);
}
{
xservo.write(90); //x-servo moves to new position
delay(500);
}
if (digitalRead(buttonBpin) == LOW)
{
yservo.write(90); //y-servo moves to new position
delay(500);
}
{
xpos = random(180); //generate random value for x-servo
xservo.write(xpos); //x-servo moves to new position
delay(500);
}
if (digitalRead(buttonCpin) == LOW)
{
ypos = random(180); //generate random value for y-servo
yservo.write(ypos); //y-servo moves to new position
delay(500);
}
{
xservo.write(90); //x-servo moves to new position
delay(500);
}
if (digitalRead(buttonDpin) == LOW)
{
ypos = random(180); //generate random value for y-servo
yservo.write(ypos); //y-servo moves to new position
delay(500);
}
{
xpos = random(180); //generate random value for x-servo
xservo.write(xpos); //x-servo moves to new position
delay(500);
}
}

I noticed when i looked the remote up on amazon that it outputs HIGH, i changed this in my code and now the remote does have an effect on the behavior of the servos, but the button needs to be held in for it to remain in that behavior state, the behavior is also not necessarily what I'm expecting

What behaviour are you expecting?

this is what I'm looking for

Servo 1 Servo 2

  1. centered/stationary centered/Stationary (default)
  2. continuously moves to random positions centered/stationary
  3. centered/stationary continuously moves to random positions
  4. continuously moves to random positions continuously moves to random positions (preferably simultaneously)

what I get is without input 1 servo moves randomly and the other is stationary. When a couple of the control buttons are pressed in both servos will move but one will move much more infrequently than the other. At not time will both stop moving, and it seems to return to the default behavior when the controller button is released.

Never got any answers, bumping this up in the hope that somebody new might see it and find it in their heart to give me a hand.

Hi

First if you add code here you need to put it in code tags so everyone can read it easily.

From what I understand you want both servos to center when the arduino is put on?
Then button1 one can center them again if needed?
Then button2 moves servo1 to a position and servo 2 stays centered?
And vice versa for button3?
Button 4 moves both servos to positions?

First you need to change this:

pinMode(buttonApin, INPUT_PULLUP);

To this:

pinMode(buttonApin, INPUT);

And do it for all your buttons.
Because you said your receiver gives a high when the remote is pressed.

what I get is without input 1 servo moves randomly and the other is stationary. When a couple of the control buttons are pressed in both servos will move but one will move much more infrequently than the other. At not time will both stop moving, and it seems to return to the default behavior when the controller button is released.

This part of your code is wrong because the xservo is not part of your digitalread A if statement:

if (digitalRead(buttonApin) == LOW)
  {
    yservo.write(90); //y-servo moves to new position
    delay(500);
  }
  {
    xservo.write(90); //x-servo moves to new position
    delay(500);
  }

It has to look something like this:

if (digitalRead(buttonApin) == HIGH)
  {
    yservo.write(90);
    xservo.write(90); //y-servo moves to new position
    delay(500);
  }

and the next button something like this:

if (digitalRead(buttonBpin) == HIGH)
  {
    yservo.write(90);
    xpos = random(180); //generate random value for x-servo
    xservo.write(xpos); //y-servo moves to new position
    delay(500);
  }

Hope that helps
M.....

Thanks so much for the assistance, and sorry I wasn't sure how to use the code tags either. I will try this out as soon as I can

Again I am very thankful for the help. I have one further question if you could. I followed your instructions and what I came up with sorted out my motion perfectly. The only thing I would like to change is, if it’s possible to be able to hit, the A button, B button etc, and have it perform that task until another button is hit. Currently the button needs to be held in for it to perform the button C-D tasks and I imagine that will kill the battery in the remote pretty fast.

thanks

this is where I’m at currently

#include <Servo.h>

Servo xservo; 
Servo yservo; 


int buttonApin = 5;
int buttonBpin = 6;
int buttonCpin = 7;
int buttonDpin = 8;
int xpos; 
int ypos; 
 
void setup() 
{
xservo.attach(9); 
yservo.attach(10); 
  pinMode(buttonApin, INPUT);  
  pinMode(buttonBpin, INPUT);
  pinMode(buttonCpin, INPUT);  
  pinMode(buttonDpin, INPUT);   
}
 
void loop() 
{
  if (digitalRead(buttonApin) == HIGH)
{
yservo.write(90); 
xservo.write(90); 
delay(500);
}
  if (digitalRead(buttonBpin) == HIGH)
{
yservo.write(90); 
xpos = random(180); //generate random value for x-servo 
xservo.write(xpos); //x-servo moves to new position 
delay(500);
}
  if (digitalRead(buttonCpin) == HIGH)
{
ypos = random(180); //generate random value for y-servo 
yservo.write(ypos); //y-servo moves to new position 
xservo.write(90); //x-servo moves to new position 
delay(500);
}
  if (digitalRead(buttonDpin) == HIGH)
{
ypos = random(180); //generate random value for y-servo 
yservo.write(ypos); //y-servo moves to new position 
xpos = random(180); //generate random value for x-servo 
xservo.write(xpos); //x-servo moves to new position 
delay(500);
}
}

Undermentioned:
First you need to change this:

pinMode(buttonApin, INPUT_PULLUP);

To this:

pinMode(buttonApin, INPUT);

And do it for all your buttons.
Because you said your receiver gives a high when the remote is pressed.

Actually, no. The presence or absence of input pullup has nothing to do with the polarity of the input. Enabling it is redundant so it should be removed for clarity, but it really has no effect on an input if it is connected to a logic output.

jtburke42:
Again I am very thankful for the help. I have one further question if you could. I followed your instructions and what I came up with sorted out my motion perfectly. The only thing I would like to change is, if it's possible to be able to hit, the A button, B button etc, and have it perform that task until another button is hit. Currently the button needs to be held in for it to perform the button C-D tasks and I imagine that will kill the battery in the remote pretty fast.

For that you need to implement a state machine. Search for it in the box at the upper right of the forum.

ok I found the finite state machine information at

http://playground.arduino.cc/Code/FiniteStateMachine#Download

and also figured out how to download the library for it, I’m pretty sure I understood how to modify the example at the above link to work with my needs since it’s an example that relies on 4 states, but I’m struggling with figuring what to write in my void loop() to have it properly select the states. The example relies on pushing a single button instead of utilizing 4 inputs. The format I’ve attempted to write below throws me errors when I attempt to check the code so I know it isn’t correct. I’ve been google searching a ton of examples but i have yet to find what I’m looking for.

#include <FiniteStateMachine.h>
#include <Servo.h>

Servo xservo; 
Servo yservo; 


int buttonApin = 5;
int buttonBpin = 6;
int buttonCpin = 7;
int buttonDpin = 8;
int xpos; 
int ypos; 
 
//initialize states
State A = State(Astate);
State B = State(Bstate);
State C = State(Cstate);
State D = State(Dstate);
 
FSM targetStateMachine = FSM(A);     //initialize state machine, start in state: On
 
 
void setup(){ 
xservo.attach(9); 
yservo.attach(10); 
  pinMode(buttonApin, INPUT);  
  pinMode(buttonBpin, INPUT);
  pinMode(buttonCpin, INPUT);  
  pinMode(buttonDpin, INPUT);   
}
 
void loop(){
  if (digitalRead(buttonApin) == HIGH)
  {
{
case A: targetStateMachine.transitionTo(A); break;
}
  }
    if (digitalRead(buttonBpin) == HIGH)
  {
{
targetStateMachine.transitionTo(B); break;
}
  }
    if (digitalRead(buttonCpin) == HIGH)
  {
{
targetStateMachine.transitionTo(C); break;
}
  }
    if (digitalRead(buttonDpin) == HIGH)
  {
{
targetStateMachine.transitionTo(D); break;
}
  }
  targetStateMachine.update();
}}
 
//utility functions
void Astate()
{
yservo.write(90); 
xservo.write(90);
}

void Bstate()
{
yservo.write(90); 
xpos = random(180); //generate random value for x-servo 
xservo.write(xpos); //x-servo moves to new position 
delay(500);
}

void Cstate()
{ 
ypos = random(180); //generate random value for y-servo 
yservo.write(ypos); //y-servo moves to new position 
xservo.write(90); //x-servo moves to new position 
delay(500);
}

void Dstate()
{
ypos = random(180); //generate random value for y-servo 
yservo.write(ypos); //y-servo moves to new position 
xpos = random(180); //generate random value for x-servo 
xservo.write(xpos); //x-servo moves to new position 
delay(500);
}
//end utility functions

Actually, no. The presence or absence of input pullup has nothing to do with the polarity of the input. Enabling it is redundant so it should be removed for clarity, but it really has no effect on an input if it is connected to a logic output.

aarg does the pullup not pull the arduino pins high 5v and when a push button is pressed the button pulls the pin low.

So if the pins are high how will the arduino know a button is pressed if the receiver also gives a high output when activated?

Again I am very thankful for the help. I have one further question if you could. I followed your instructions and what I came up with sorted out my motion perfectly. The only thing I would like to change is, if it's possible to be able to hit, the A button, B button etc, and have it perform that task until another button is hit. Currently the button needs to be held in for it to perform the button C-D tasks and I imagine that will kill the battery in the remote pretty fast

Yes the receiver you have i would imagine is a momentary receiver you can get a toggle receiver that will do what you need or you can do it in code.

Im sorry Ive never used case statements before or this library and I dont feel like figuring them out now :slight_smile: I just normally make a variable true if the button is pressed and then use a if statement to check if the variable is true or not, you must just be careful a quick look at your code and i see way to many brackets that could be some of your errors.