2 switches 3 diff outputs?

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
primercore
 
Posts: 4
Joined: Fri Mar 21, 2014 2:50 pm

2 switches 3 diff outputs?

Post by primercore »

Alright, I am new to Arduino.

How/what do I need to have two push buttons when pressed at same time, go to a different input.

E.G. Pushing down on Sw1 goes to input1 and plays a wav1. Pushing down on Sw2 goes to input 2, plays a wav2. Pushing down on BOTH goes to input 3, plays wav3.

I have a board that has the audio all working from mSD card. What I don't understand is what do I need on the Arduino side to have the inputs from only 2 buttons. The outputs need to go to one (shared) ground lead, and separate 1,2,3 sw inputs on the audio player board.

Point me in right direction. And any items not in the starter kit I might need (chip, ...)

Thanks.

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: 2 switches 3 diff outputs?

Post by adafruit_support_mike »

Start with this tutorial that shows how to handle basic digital input: http://learn.adafruit.com/adafruit-ardu ... s/overview

Once you get that working, handling multiple buttons just involves playing with the data a little:

Code: Select all

boolean aPressed = (digitalRead(buttonApin) == LOW);
boolean bPressed = (digitalRead(buttonBpin) == LOW);

if ( aPressed && bPressed ) {
	//  do the 'both buttons pressed' thing
} else {
	if ( aPressed ) {
		// do the 'button A pressed' thing
	}
	if ( bPressed ) {
		// do the 'button B pressed' thing
	}
}

User avatar
Renate
 
Posts: 291
Joined: Tue Nov 13, 2012 3:21 pm

Re: 2 switches 3 diff outputs?

Post by Renate »

Pushing two buttons at the same time is difficult.
What you mean by "same time" is not the same as what the Arduino thinks it is.
No matter how exactly together you push the two buttons, the Arduino will probably think that one was pressed first.

Also, when you push a pushbutton, it makes contact, but it also bounces.
That means a single push actually produces an on-off-on-off-on-off-on-off-on-off-on-off-on----------
If the push is just supposed to turn something on, there will not be a problem.
That's because an on-off-on-off-on-off-on is the same as an on.
If the push is supposed to turn something off then the next time turn it off there will be a problem.
That's because an on-off-on-off-on is not the same as an on-off-on-off-on-off-on.

To solve your problem you need a little deeper logic in your program.
A timer interrupt to check your switches maybe?
"This button has been on for 50 milliseconds and no sign of the other button? Then it must be a single press."

Of course you could use 3 buttons and make it easier to program and operate.

User avatar
phild13
 
Posts: 247
Joined: Mon Sep 10, 2012 1:05 pm

Re: 2 switches 3 diff outputs?

Post by phild13 »

You could use a couple N/O momentary switches as toggles, then you could get
off-off - do nothing
on-off - play music 1
off-on - play music 2
on-on - play music 3

5 mSec, is enough to debounce most switches

Something like this below may be suitable. ( I did not write it, just found it awhile back somewhere; on the arduino sites forum I think) It shows a way to debounce inputs and also shows how to construct a toggle from a momentary pushbutton.You do code for both switches for debounce and toggle and then you can compare what state the toggles are in to what you want to do when in that state.

Code: Select all

/*
 *    simple debounce using delay, will block for 5mSec when state changes
 */

const uint32_t debounceTime = 5;  // 5 mSec, enough for most switches
const uint8_t switchPin     = 8;  // with n.o. momentary pb switch to ground
const uint8_t ledPin        = 13; // built-in led

const bool switchOn  = false;     // using INPUT_PULLUP
const bool switchOff = true;

bool lastState   = switchOff;
bool newState    = switchOff;
bool toggleState = false;

void setup()
{
  
  Serial.begin ( 9600 );
  Serial.println ( F ( __FILE__ ) );
  Serial.println ( F ( "Simple state change/debounce using delay." ) );
  Serial.println ( F ( "push on, push off -- with momentary contact switch" ) );
  
  pinMode ( switchPin, INPUT_PULLUP );
  pinMode ( ledPin, OUTPUT );
  
} // setup

void loop ()
{

  newState = digitalRead( switchPin );

  if( lastState != newState ) // state changed
  {
    delay( debounceTime );
    lastState = newState;
    
    // push on, push off
    if( newState == switchOn && toggleState == false )
    {
      toggleState = true;
      digitalWrite( ledPin, HIGH );
      Serial.println( F ( "Switched ON" ) );
    }
    else if( newState == switchOn && toggleState == true )
    {
      toggleState = false;
      digitalWrite( ledPin, LOW );
      Serial.println( F ( "Switched OFF" ) );
    }

  }  // if state changed

} // loop

User avatar
Renate
 
Posts: 291
Joined: Tue Nov 13, 2012 3:21 pm

Re: 2 switches 3 diff outputs?

Post by Renate »

PhilD13 wrote:5 mSec, is enough to debounce most switches
Yeah, well, 5 to 10 mS, maybe.
Still, I doubt that you can push two buttons reliably so that they both close within 1/200th of a second.
You have a better chance if the switches are adjacent and you can hit them both with one fat thumb.
Using a finger on each hand, I don't know.
I'll have to rig up a setup sometime and measure.

User avatar
phild13
 
Posts: 247
Joined: Mon Sep 10, 2012 1:05 pm

Re: 2 switches 3 diff outputs?

Post by phild13 »

There is no dispute that buttons, switches, analog relay contacts, need to be debounced for reliable operation. Please look at the code posted. The code posted creates an on/off input toggle using a momentary normally open push button. This in turn will turn on/off an output which in this example is the on board LED. The code also debounces the button push with a timer which can be adjusted as desired or necessary.

The truth table shows various combinations of switch states for the two switches that can be had with the code.

Though written differently (different language), the use of a momentary push button to toggle an input on/off is very common in many industries that use a PLC and either analog buttons or HMI (panelview) buttons to turn something on or off.

User avatar
zener
 
Posts: 4567
Joined: Sat Feb 21, 2009 2:38 am

Re: 2 switches 3 diff outputs?

Post by zener »

My initial thought was the same as stated above, which is "do it in code". I don't feel like debouncing is necessarily an issue here since you could look for the 2 button condition and start playing the wav3 at that time, and ignore further inputs while it is playing.

However, you could do it in hardware also if you wanted to, though the common wisdom will be that you are wasting the hardware since you can do it in software. One simple way would be to use double pole push button switches, although they are not so easy to find necessarily. Another way would be to use a little bit of logic to create 3 outputs out of 2 switches. Maybe it could be done with a couple of diodes and a few resistors?

User avatar
Renate
 
Posts: 291
Joined: Tue Nov 13, 2012 3:21 pm

Re: 2 switches 3 diff outputs?

Post by Renate »

Debouncing is a simple issue and not the main point that I was making.

The original case is two buttons and three commands.
My question is why jump through hoops instead of just having a third button?

Let's take this scenario to the extreme so as to be clearer.
Suppose we have 10 pushbuttons and 1023 commands.
To simplify things let's presume that the signals from the pushbuttons have been nicely debounced somehow.
If you want to select command 1023rd command you have to push all ten buttons.
It is impossible to push all ten buttons at the same times.
There will be a (small) time delay between when you push the the first button and when you push the last button.

All I'm saying, is that you will have to use some timeout logic to decide when the person has stopped pushing buttons.
Or you could have the system only react when all the buttons have been released.
Whichever system you decide on will require some logic that is somewhat independent of any logic you may use for debouncing.

(Unrelated comment: An SPDT switch can be made bounceless with a simple S/R flip-flop.)

primercore
 
Posts: 4
Joined: Fri Mar 21, 2014 2:50 pm

Re: 2 switches 3 diff outputs?

Post by primercore »

Thanks for your replies and suggestions!
(I've ordered the kit and waiting to try them).

As far as using three buttons, this is not my call. The original art project that my friend made was over 20 years ago, using analog tape players. He used two buttons (door bell) and when both are pushed it trips a third tape player to play.
One button plays a tape loop on one, second button if pushed plays the 2nd audio loop tape player. Both buttons pressed at same time plays the third tape loop.
Analog works but it is old, belts are stretched/worn and there is considerable hum.

This is what I need the arduino for: to have two inputs control the sounds of this Pricom dreamplayer mk2
http://www.pricom.com/Trains/DreamPlayerMK2.shtml

When I get the kit, I'll try your helpful suggestions (I read the digital line, thanks adafruit monitor) and see if this works.
(at this point, i can get two buttons, two sounds, but not third. And I cannot use a third button. That is the deal breaker) :D

User avatar
Renate
 
Posts: 291
Joined: Tue Nov 13, 2012 3:21 pm

Re: 2 switches 3 diff outputs?

Post by Renate »

If you really wanted to do this thing elegantly you could just modify the code on the Dream Player.
I don't know whether they release the code for that.
If not, it would be a bit more work to disassemble and patch it.
You could try asking the guys there to make it an option in the config file.

That way you would not need another microprocessor, just wire the switches.

User avatar
phild13
 
Posts: 247
Joined: Mon Sep 10, 2012 1:05 pm

Re: 2 switches 3 diff outputs?

Post by phild13 »

You could ask the Dream Player team if they could modify the code like Renate mentioned. They also have a 4 switch board that can be used, though that does not meet the parameters of only using 2 switches.

I'm not good at this stuff, but I did put together some code that works fairly well as an example. Can it be done more efficient or better? I'm sure it can.

It is probably easier to just load the sketch and set up the a breadboard of 3 leds and 2 n,o. push button switches than to explain the states but here is an attempt to explain the states.

if sw1 and sw2 are off then no output is on
pressing switch 1 will toggle on output 1 and pressing sw1 again will toggle output 1 off
pressing switch 2 will toggle on output 2 and pressing sw2 again will toggle output 2 off
if both sw1 and sw2 are pressed at about the same time then output 3 will turn on
if sw1 is on and sw2 is pressed, then output 3 will turn on and output 1 will turn off, output 2 will remain off
if sw2 is on and sw1 is pressed, then output 3 will turn on and output 2 will turn off, output 1 will remain off
if output 3 is on and sw1 is pressed then output 2 will turn on
if output 3 is on and sw2 is pressed then output 1 will turn on
if output 3 is on and both sw1 and sw2 are pressed then all outputs turn off

Code: Select all

/*
     *    use 2 N/O momentary switches to turn on 3 outputs 
     *    includes a simple 5mSec debounce delay to debounce the two switches
     *    
 */
// initialize constants
const uint32_t debounceTime = 5;  // 5 mSec, enough for most switches
 // 500 mSec, (1/2 second) pause long enough for most peoples switch selections
const uint32_t pauseTime = 500; 
const uint8_t switch1     = 7;  // with n.o. momentary pb switch to ground
const uint8_t switch2     = 8;  // with n.o. momentary pb switch to ground
const uint8_t outputPin1  = 11; // output 1 for music loop 1
const uint8_t outputPin2  = 12; // output 2 for music loop 2
const uint8_t outputPin3  = 13; // output 3 for music loop 3

const bool switchOn  = false;     // using INPUT_PULLUP
const bool switchOff = true;

const bool switchOn2  = false;     // using INPUT_PULLUP
const bool switchOff2 = true;

// Variables:

// for switch 1
int buttonPushCounter = 0;   // counter for the number of button presses switch 1
bool lastState   = switchOff;
bool newState    = switchOff;
bool toggleState = false;

// for switch 2
int buttonPushCounter2 = 0;   // counter for the number of button presses switch 2
bool lastState2   = switchOff;
bool newState2    = switchOff;
bool toggleState2 = false;

// do the setup stuff
void setup()
{
// setup and print header for serial monitor window
  Serial.begin ( 9600 );
  Serial.println ( F ( __FILE__ ) );
  Serial.println ( F ( "Simple state change/debounce using delay." ) );
  Serial.println ( F ( "push on, push off -- with momentary contact switch" ) );

  // set input pinmodes
  pinMode ( switch1, INPUT_PULLUP );
  pinMode ( switch2, INPUT_PULLUP );
  // set output pinmodes
  pinMode ( outputPin1, OUTPUT );
  pinMode ( outputPin2, OUTPUT );
  pinMode ( outputPin3, OUTPUT );

} // setup

void loop ()
{
  // begin read switch 1 state
  newState = digitalRead( switch1 );

  if( lastState != newState ) // state changed
  {
    delay( debounceTime );
    lastState = newState;

    // switch 1 push on, push off
    if( newState == switchOn && toggleState == false)
    {
      toggleState = true;
      buttonPushCounter++;
      Serial.println( F ( "Output 1 Switched ON" ) );
    }
    else if( newState == switchOn && toggleState == true )
    {
      toggleState = false;
      buttonPushCounter = 0;
      Serial.println( F ( "Output 1 Switched OFF" ) );
    }
  }  // end if switch 1 state changed

  // begin read switch 2 state
  newState2 = digitalRead( switch2 );
  if( lastState2 != newState2 ) // state changed
  {
    delay( debounceTime );
    lastState2 = newState2;

    // switch 2 push on, push off
    if( newState2 == switchOn2 && toggleState2 == false )
    {
      toggleState2 = true;
      buttonPushCounter2++;
      Serial.println( F ( "Output 2 Switched ON" ) );
    }
    else if( newState2 == switchOn2 && toggleState2 == true )
    {
      toggleState2 = false;
      buttonPushCounter2 = 0;
      Serial.println( F ( "Output 2 Switched OFF" ) );
    }  
  } // end if switch 2 state changed

  // check counters and turn on output
  if ((buttonPushCounter == 1) && (buttonPushCounter2 == 1)) {
    digitalWrite(outputPin3, HIGH);
  } 
  else {
    digitalWrite(outputPin3, LOW);
  }
  if ((buttonPushCounter == 0) && (buttonPushCounter2 == 1)) {
    digitalWrite(outputPin2, HIGH);
  } 
  else {
    digitalWrite(outputPin2, LOW);
  }
  if ((buttonPushCounter == 1) && (buttonPushCounter2 == 0)) {
    digitalWrite(outputPin1, HIGH);
  } 
  else {
    digitalWrite(outputPin1, LOW);
  }
  // set a short delay to make it easier to turn on output 3
  // must hold desired swirches for delay time to change state
  delay(500);
} // loop
The code is commented fairly well if someone wants to use it or modify it.

primercore
 
Posts: 4
Joined: Fri Mar 21, 2014 2:50 pm

Re: 2 switches 3 diff outputs?

Post by primercore »

I "appreciate" all the help and code! I had to get a new breadboard (bigger) and got some 2 lead pushbutton switches (the blue and yellow arcade buttons from here).

However, can two-lead buttons be used or do I need to use those little black buttons that came with kit (4 leads)? Every board example on the web shows that 4 pin tiny button not a 2 lead. Rgggh..wish I had more bread! :)

PhilD13- thank you so much for the code. I am trying to get time to do this. Sorry for late response...and will try that code. if successful or not, I'll post back!

Yesh, I wish DreamPlayer made the code a bit better but they have it for one switch at a time... but there has to be an Arduino-way! :)

primercore
 
Posts: 4
Joined: Fri Mar 21, 2014 2:50 pm

Re: 2 switches 3 diff outputs?

Post by primercore »

Not working right.
If I hit one button, it is playing output 3
If I hit other button, still playing output 3 then might go to output 2.

I tried checking wires. I have grd output to bboard.
I have jumped ground to each button then output wire across revine on Bboard.
Then output of button1 to 7 on Arduino
repeat with other switch but output of button2 to 8 on arduino
11,12,13 to 1,2,3 on the dreamplayer.
grnd to dreamplayer from GND on digital side.

Not working properly... :*(

Locked
Please be positive and constructive with your questions and comments.

Return to “General Project help”