Go Down

Topic: 2 servos control (Read 759 times) previous topic - next topic

kaporal_p

Apr 25, 2010, 07:53 am Last Edit: Apr 25, 2010, 08:29 am by kaporal_p Reason: 1
Ok,

I have;

1 servo on digital pin 8
1 button on digital pin 2 with external pull-down resistor
1 led on digital pin 5

when I push AND RELEASE the button;

servo goes to 90 degrees
led lights up

when I push AND RELEASE again:

servo goes back to 0 degrees
led turns off

to get this working, I modified some code I got from
http://www.kasperkamperman.com/blog/arduino/arduino-programming-state-change/

It probably looks gnarly to some of you but hey, it works!

here it is:
Code: [Select]

#include <Servo.h>

Servo myservo;                // create servo object to control a servo

const int buttonPin = 2;      // the pin that the pushbutton is attached to
const int ledPin    = 5;      // the pin that the LED is attached to

int buttonState     = 0;      // current state of the button
int lastButtonState = 0;      // previous state of the button
int ledState        = 0;      // remember current led state
int pos             = 0;      // variable to store the servo positions

void setup()
{
 myservo.attach(8);          // attaches the servo on pin 8 to the servo object
 pinMode(buttonPin, INPUT);  // initialize the button pin as a input
 pinMode(ledPin, OUTPUT);    // initialize the button pin as a output
}

void loop()
{
 buttonState = digitalRead(buttonPin); // read the pushbutton input pin
   if (buttonState != lastButtonState) // compare buttonState to previous state
   {
     if (buttonState == 1)
     {
       if(ledState == 1)
         {
           ledState = 0;
           for(pos = 0; pos <= 90; pos += 5)    // goes from 0 degrees to 90 degrees
           {                                    // in steps of 5 degrees
           myservo.write(pos);                  // tell servo to go to position 'pos'
           delay(15);        // waits 15ms for the servo to reach the position
           }
         }
       else  
         {  
           ledState = 1;
           for(pos = 90; pos >= 1; pos -= 5)    // goes from 90 degrees to 0 degrees
           {                                
           myservo.write(pos);                  // tell servo to go to position 'pos'
           delay(15);                           // waits 15ms for the servo to reach the position
           }
         }
     }
   
   lastButtonState = buttonState; // remember the current state of the button
   }
 // turns LED on if the ledState =1 or off if ledState = 0
 digitalWrite(ledPin, ledState);
 myservo.write(pos);          // goes from 0 degrees to 90 degrees

 delay(20);
}


Now

I want to double-up and eventually triple-up and so on. This means 2 servos and 2 leds first.

So I hooked up the hardware same as the first one and then I tried to double-up the code, hehe. Of course nothing works! But it was a nice try!

So now I need help. I need to know how to send unique orders to multiple subjects, if that makes any sense...

I post the code so you geniuses can compare with the first one and you will understand better than I can explain. I'm sure it can be done quite easily, computers are especially good at handling this kind of stuff so I guess it's basic programming and therefore the reason why I want to learn how to do it right!
Code: [Select]

#include <Servo.h>

Servo myservo8;                // create servo object to control servo 8
Servo myservo9;                // create servo object to control servo 9

const int buttonPin2 = 2;      // the pin that the pushbutton2 is attached to
const int buttonPin3 = 3;      // the pin that the pushbutton3 is attached to
const int ledPin5    = 5;      // the pin that the LED 5 is attached to
const int ledPin6    = 6;      // the pin that the LED 6 is attached to

int buttonState2     = 0;      // current state of the button2
int buttonState3     = 0;      // current state of the button3
int lastButtonState2 = 0;      // previous state of the button2
int lastButtonState3 = 0;      // previous state of the button3
int ledState5        = 0;      // remember current led state5
int ledState6        = 0;      // remember current led state6
int pos8             = 0;      // variable to store the servo8 positions
int pos9             = 0;      // variable to store the servo9 positions

void setup()
{
 myservo8.attach(8);          // attaches the servo on pin 8 to the servo object
 myservo9.attach(9);          // attaches the servo on pin 9 to the servo object
 pinMode(buttonPin2, INPUT);  // initialize the button2 pin as a input
 pinMode(buttonPin3, INPUT);  // initialize the button3 pin as a input
 pinMode(ledPin5, OUTPUT);    // initialize the led5 pin as a output
 pinMode(ledPin6, OUTPUT);    // initialize the led6 pin as a output
}

void loop()
{
 buttonState2 = digitalRead(buttonPin2); // read the pushbutton2 input pin
 buttonState3 = digitalRead(buttonPin3); // read the pushbutton3 input pin
   if (buttonState2 != lastButtonState2) // compare buttonState2 to previous state
   if (buttonState3 != lastButtonState3) // compare buttonState3 to previous state
   {
     if (buttonState2 == 1)
     if (buttonState3 == 1)
     {
       if(ledState5 == 1)
       if(ledState6 == 1)
         {
           ledState5 = 0;
           ledState6 = 0;
           for(pos8 = 0; pos8 <= 90; pos8 += 5)    // goes from 0 degrees to 90 degrees
           {                                    // in steps of 5 degrees
           myservo8.write(pos8);                  // tell servo8 to go to position 'pos8'
           delay(15);        // waits 15ms for the servo to reach the position
           }
           for(pos9 = 0; pos9 <= 90; pos9 += 5)    // goes from 0 degrees to 90 degrees
           {                                    // in steps of 5 degrees
           myservo9.write(pos9);                  // tell servo9 to go to position 'pos9'
           delay(15);        // waits 15ms for the servo to reach the position
           }
         }
       else  
         {  
           ledState5 = 1;
           ledState6 = 1;
           for(pos8 = 90; pos8 >= 1; pos8 -= 5)    // goes from 90 degrees to 0 degrees
           {                                
           myservo8.write(pos8);                  // tell servo8 to go to position 'pos8'
           delay(15);                           // waits 15ms for the servo to reach the position
           }
           for(pos9 = 90; pos9 >= 1; pos9 -= 5)    // goes from 90 degrees to 0 degrees
           {                                
           myservo9.write(pos9);                  // tell servo to go to position 'pos9'
           delay(15);                           // waits 15ms for the servo to reach the position
           }
         }
     }
   
   lastButtonState2 = buttonState2; // remember the current state of the button2
   lastButtonState3 = buttonState3; // remember the current state of the button3
   }
 // turns LEDs on if the ledStates =1 or off if ledStates = 0
 digitalWrite(ledPin5, ledState5);
 digitalWrite(ledPin6, ledState6);
 myservo8.write(pos8);          // goes from 0 degrees to 90 degrees
 myservo9.write(pos9);          // goes from 0 degrees to 90 degrees  

 delay(20);
}


Thanks  

PaulS

If you want to press the buttons independently of each other, create a function to handle the button and related servo. Pass the relevant servo, button, and LED pin to that function:

Code: [Select]
void MoveServoIfButtonPressed(int servoPin,
         int buttonPin,
         int ledPin,
         int &lastButtonState,
         int &ledState)
{
  int buttonState = digitalRead(buttonPin); // read the pushbutton input pin
  if (buttonState != lastButtonState) // compare buttonState to previous state
  {
     if (buttonState == 1)
     {
        if(ledState == 1)
        {
           ledState = 0;
           for(int pos = 0; pos <= 90; pos += 5)
           {                                    
              myservo.write(pos);
              delay(15);        // waits for servo to reach position
           }
        }
        else  
        {  
           ledState = 1;
           for(pos = 90; pos >= 1; pos -= 5)
           {                                
              myservo.write(pos);
              delay(15);
           }
        }
     }
   
     lastButtonState = buttonState; // remember the current state of the button
  }

  digitalWrite(ledPin, ledState);
}


Then, call that function for each button/LED/servo:

Code: [Select]
MoveServoIfButtonPressed(8, buttonPin2, ledPin5, lastButtonState2, ledState5);
MoveServoIfButtonPressed(9, buttonPin3, ledPin6, lastButtonState3, ledState6);


The action for one button press will be completely independent of the state of the other button.

If that's not what you want, never mind.

kaporal_p

#2
Apr 25, 2010, 03:34 pm Last Edit: Apr 25, 2010, 03:47 pm by kaporal_p Reason: 1
Oh! Yes!

That's exactly what I needed! It's perfect, up and running!

Just had to pop
Code: [Select]

digitalWrite(ledPin6, ledState6);

into the function and all is well.

That's a very elegant way of doing things, I mean creating functions!

Arduino truly rocks! and so does this Forum!

I have but 1 little question;

In the function you suggested, there are 2 ''&'' sings in front of 2 variable definitions:
Code: [Select]

void MoveServoIfButtonPressed(int servoPin,
         int buttonPin,
         int ledPin,
         int [glow]&[/glow]lastButtonState,
         int [glow]&[/glow]ledState)



What are they for?

Thanks again!


PaulS

By default, when you call a function, the value in a variable is passed to the function.

Code: [Select]
int val = digitalRead(switchPin);

The value in switchPin is passed to the digitalRead function. If the function makes any changes to the value, the changes are local to the function. The caller has no idea that the function modified the input value.

But, if you need to know that the function modified a value, as in the case of setting lastButtonState, you need to pass the address of the variable to the function, not the value currently in the variable. This is what the & does.

It is called a pass-by-reference operator or address-of operator, depending on context. In this case, it means that we want to pass the address of the variable to the function, not the value of the variable.

Go Up