Go Down

Topic: Servo Control with three buttons. (resolved and working!!!) (Read 786 times) previous topic - next topic

PaulS

Quote
In the end I am going to build a coin operated salt and pepper dispenser. When a coin is put in the slot, it will trigger a momentary button (buttonA). After that, I want the customer to have the option to choose between salt and pepper (buttonB and buttonC). The problem is that the current code states that if the coin button (buttonA) is pressed, then the user needs to select their seasoning (buttonB or buttonC) simultaneously in order for the servo to turn. I would like to allow the user to insert a coin, and then take their own sweet time to choose from salt or pepper, similar to modern day pop machines. How could I do this?

Create a boolean variable, armed, initialized to false. Read the state of switch 1. If it is pressed, set armed to true.

Read the state of switches 2 and 3. If either is pressed and armed is true, move the servo, do whatever else needs to be done, AND set armed to false.

Robin2

There is absolutely no need for interrupts - buttons are slow.

You have said you want to press BtnA and a short time later press BtnB or BtnC. It seems to me that BtnA is just an unnecessary complication. Why not reduce the code to just two buttons?

If there is a need for BtnA it makes the logic a great deal more complex. What happens if neither BtnB or BtnC is pressed?

Perhaps you need a program that ignores BtnB and BtnC if BtnA has not been pressed. Then a press of BtnA is recorded in a variable and that allows BtnB or BtnC to be recognized. However if neither B nor A is pressed within X seconds the variable set by A is unset and BtnA will need to be pressed again if anything is to happen.

But this all seems unnecessarily complicated.

...R

JimboZA

#17
Feb 16, 2014, 05:40 pm Last Edit: Feb 16, 2014, 05:44 pm by JimboZA Reason: 1
Yeah sorry I agree, my interrupt idea is crazy....



Create a boolean variable, armed, initialized to false. Read the state of switch 1. If it is pressed, set armed to true.

Read the state of switches 2 and 3. If either is pressed and armed is true, move the servo, do whatever else needs to be done, AND set armed to false.


That's basically what he has, come to think of it. Button A's state of high, is armed, and he's checking B and C only inside the if A is high part anyway, so the thinking is good I reckon.

Just cheat and add a couple of delays for now, between the state checks, else button B will be false becasue the user was too slow. As I said earlier, remember to set them low once the move is done.

And you already have them set low at the beginning.

For real life you might want a coin return if the money is inserted but they change their mind. So have a button D that forces button A's state low when pressed, and cancels the transaction.

EDIT.... but take those extra {  } pairs out just in case
My hovercraft is full of eels.

No PMs for help please.
DO NOT power servos from Arduino 5V: give them their own power and connect the grounds.

JimboZA



Perhaps you need a program that ignores BtnB and BtnC if BtnA has not been pressed. Then a press of BtnA is recorded in a variable and that allows BtnB or BtnC to be recognized.


That's basically what he has: B and C are only tested inside an if, when A's state is high.

I'm thinking his problem right now is a combination of no delays to give time to press B or C, and not resetting the states after the servo moves..... and maybe those extra {} pairs.
My hovercraft is full of eels.

No PMs for help please.
DO NOT power servos from Arduino 5V: give them their own power and connect the grounds.

icecats

#19
Feb 16, 2014, 05:49 pm Last Edit: Feb 16, 2014, 05:51 pm by icecats Reason: 1
You mean like this?
Code: [Select]

if (AState == HIGH){
   delay(1000);
       if (BState == HIGH){
         myservo.write(50);
         delay(1000);
         myservo.write(111);
         delay(1000);
       
       }
     }
     else
       myservo.write(90);

JimboZA

No that won't work, I think I mean (  8) ) between the lines where the buttons are actually read, so that after A is read it pauses and hopefully by the time the delay is over, the finger will be on B or C
My hovercraft is full of eels.

No PMs for help please.
DO NOT power servos from Arduino 5V: give them their own power and connect the grounds.

icecats

?????
Code: [Select]
{
  AState = digitalRead(buttonA); // read and save to the variable "AState" the actual state of button
  delay(1000);
    BState = digitalRead(buttonB); // read and save to the variable "BState" the actual state of button
   
      CState = digitalRead(buttonC); // read and save to the variable "CState" the actual state of button

When I ran this it did not work at all. How confusing.

JimboZA

You make any other changes at the same time? Maybe post the whole code again.

My hovercraft is full of eels.

No PMs for help please.
DO NOT power servos from Arduino 5V: give them their own power and connect the grounds.

wildbill

No need for any delays. Re-read reply #15. PaulS gave you the necessary algorithm there.

icecats

#24
Feb 16, 2014, 06:11 pm Last Edit: Feb 16, 2014, 06:16 pm by icecats Reason: 1
We did it, we did it!!! I ended up using PaulS's boolean variable idea.
Quote
Create a boolean variable, armed, initialized to false. Read the state of switch 1. If it is pressed, set armed to true.

Read the state of switches 2 and 3. If either is pressed and armed is true, move the servo, do whatever else needs to be done, AND set armed to false.


Here is the working code for those who are interested. Thank you to everyone who helped me, especially PaulS and JimboZA! I hope to finish this project this weekend and start making a small profit next week. Thanks so much. -icecats-
Code: [Select]
#include <Servo.h>

Servo myservo; // creating myservo object
int buttonA = 2; // one side of buttonA attached to pin 2 and 10K resistor to ground, while other is on +5V
int buttonB = 3; // one side of buttonB attached to pin 3 and 10K resistor to ground, while other is on +5V
int buttonC = 4;  // one side of buttonC attached to pin 4 and 10K resistor to ground, while other is on +5V
int servoPin = 11;  //servo attached to pin 11
int AState = 0; // set AState
int BState = 0; // set BState
int CState = 0; // set CState
int armed = false;

void setup()
{
  myservo.attach(servoPin);
  pinMode(buttonA, INPUT);
  pinMode(buttonB, INPUT);
  pinMode(buttonC, INPUT);
}


void loop()
{
  AState = digitalRead(buttonA); // read and save to the variable "AState" the actual state of button

  BState = digitalRead(buttonB); // read and save to the variable "BState" the actual state of button

  CState = digitalRead(buttonC); // read and save to the variable "CState" the actual state of button
  if (AState == HIGH){
    armed = true;
  }
  if (BState == HIGH && armed == true){
    armed = false;
    myservo.write(50);
    delay(1000);
    myservo.write(111);
    delay(1000);

  }
  else
    myservo.write(90);

  if(CState == HIGH && armed == true){
    armed = false;
    myservo.write(130);
    delay(1000);
    myservo.write(70);
    delay(1000);
  }
  else
    myservo.write(90);

}





JimboZA


No need for any delays. Re-read reply #15. PaulS gave you the necessary algorithm there.


And he's doing that already.

BUT, as soon as A is pressed it checks B right away. The OP doesn't want them to have to press them simultaneously, so if the user isn't infinetsimally quick on B, it'll read B as low.
My hovercraft is full of eels.

No PMs for help please.
DO NOT power servos from Arduino 5V: give them their own power and connect the grounds.

JimboZA


We did it, we did it!!! 


Excellent.

Quote
Here is the working code for those who are interested.


Um.... where?
My hovercraft is full of eels.

No PMs for help please.
DO NOT power servos from Arduino 5V: give them their own power and connect the grounds.

icecats

Sorry... I'm forgetful today... first the question and now the code. I have added it to the my post #24. Thankyou

JimboZA

Slapping myself for just twigging to the fact that A being set high near the top of loop() isn't persistent through subsequent visits, while of course the armed variable is, until it's deliberately reset. Sorry PaulS, wildbill and Robin2....

Now I'm interested to hear how many doses of salt and pepper the OP is going to have to sell to recoup the cost of an Arduino, servo, coin machine and so on....
My hovercraft is full of eels.

No PMs for help please.
DO NOT power servos from Arduino 5V: give them their own power and connect the grounds.

icecats

#29
Feb 16, 2014, 06:46 pm Last Edit: Feb 16, 2014, 06:48 pm by icecats Reason: 1
I already had all  of the parts, as electronics and Arduino is my hobby. However, I see your point. I plan on eventually making this permanent using a bare bones arduino such as Cheapduino($5:00 a piece). http://www.dfrobot.com/index.php?route=product/product&product_id=899#.UwDq8_ldV5p
Maybe eventually, I will make a small profit :). Thanks for all of your input, and for helping me complete this project.
-icecats-
May middle schoolers forever have seasoning...

Go Up