Combination input buttons... Please help!!

Hi guys,

I'm very new to arduino, and programming in general so I apologise if I sound like a fool and if what I am asking is really easy.

I am trying to make a track selector like the ones found on the old fashioned jukebox's. Lets say I have audio files named 001, 002, 003, 004 etc etc,

I also have buttons marked 0, 1, 2, 3, 4, 5 up to 9.

for arguements sake, if i wanted to play track number 012 i want to press button 0, then 1 then 2. which would then start playing the track titled 012.wav

I know how to play one track assigned to each button but where I get lost is when it comes to the button combinations. I just have no idea how to have it so that arduino knows what to do when buttons 0, 1 and 2 are pushed.

I assume I would have to delay the output to wait for the next button press but I dont know how then to make arduino remember the first button pressed once the second is pressed.

Again I'm sorry if this post doesn't make sense but I am completely at a loss so any help would be greatly appreciated!

Thanks
Will

see if Button Sequence question - Programming Questions - Arduino Forum is helpful

you may also want to look into a keypad instead of 3 buttons
http://www.circuitbasics.com/how-to-set-up-a-keypad-on-an-arduino/
something to try

.

Thanks for those links ieee488

Unfortunatly I am going to be fitting the hardware into a pre-existing machine. so i need to use the buttons that are already there! If theres a way to treat those buttons as if they are a keypad that would be grand as there seems to be a lot of reading materials about using keypads online!

Thanks
Will

If the user always needs to press 3 buttons it should not be difficult to use your buttons.

You need some means to know if the system is waiting for an input.
From that point if a button is pressed save its value and count how many buttons have been pressed.
When the count gets to 3 then you have all the values you need.

The complexity arises if the person does not press 3 buttons but leaves the system dangling in an unfinished state. I would deal with that by starting a timer (saving the value of millis() ) when the first button is pressed and if the 3rd button has not been pressed after (say) 5 seconds I would cancel everything and go back to the waiting-for-input state.

That would also deal with the situation where someone accidentally pressed 4 buttons.

...R

Robin2:
If the user always needs to press 3 buttons it should not be difficult to use your buttons.

You need some means to know if the system is waiting for an input.
From that point if a button is pressed save its value and count how many buttons have been pressed.
When the count gets to 3 then you have all the values you need.

The complexity arises if the person does not press 3 buttons but leaves the system dangling in an unfinished state. I would deal with that by starting a timer (saving the value of millis() ) when the first button is pressed and if the 3rd button has not been pressed after (say) 5 seconds I would cancel everything and go back to the waiting-for-input state.

That would also deal with the situation where someone accidentally pressed 4 buttons.

...R

Thanks for the reply!

The user will always be pushing 3 buttons, and theres a reset button if the wrong buttons are pressed, which i would use to set the count back to zero.

When you say "save its value" thats where I have trouble, I can assign values to the buttons i just dont know how to save the values!

Thanks
Will

Save the value just means put it in a variable. So put the number of the first button pressed into a variable called something like firstnum (so if it's button number 3 set firstnum=3). Do the same for second and third buttons into secondnum, thirdnum.

Then the real tracknumber = firstnum100 = secondnum10 + thirdnum.

It's a crude way of doing it but it should work. And when that's working and you understand it you can think about neater ways of doing it.

Steve

willjones360:
Unfortunatly I am going to be fitting the hardware into a pre-existing machine. so i need to use the buttons that are already there! If theres a way to treat those buttons as if they are a keypad that would be grand as there seems to be a lot of reading materials about using keypads online!

Assuming nothing else will be connected to the buttons, just the wires to the Arduino, you will be able to wire them in a matrix thus saving a few pins. That's basically how keypads are wired.

willjones360:
The user will always be pushing 3 buttons, and theres a reset button if the wrong buttons are pressed, which i would use to set the count back to zero.

You still need this timeout, as a user is not guaranteed to press reset or exactly three buttons.

slipstick:
Save the value just means put it in a variable. So put the number of the first button pressed into a variable called something like firstnum (so if it's button number 3 set firstnum=3). Do the same for second and third buttons into secondnum, thirdnum.

In OPs specific case I would save them in a char array, which later can be used as file name.

So you'd get something like this:

byte nPresses = 0;
const byte buttonPin[10] = {0, 1, 2, ..., 9}; // I'm lazy here. Pins that connect buttons for 0 - 9, in that order.
const byte nButtons = 10; // The number of buttons in use.
char song[3];

void loop() {
  for (byte i = 1; i < nButtons; i++) {
    if (digitalRead(buttonPin[i])) == LOW) { // Do add debouncing & state checking.
      song[nPresses] = i+48; // ASCII code for '0' - '9'
      nPresses++;
    }
  }
  if (nPresses == 3) { // Three buttons have been pressed: play the requested song.
    nPresses = 0;
    playSong(song);
  }
}

A press on the reset button will simply set nPresses back to 0, that's all you need to do there.

Now think about what to do if a song is requested when another song is being played. Ignore it? Queue it (up to how many songs)? Stop the current song, start the new one?

wvmarle:
Now think about what to do if a song is requested when another song is being played. Ignore it? Queue it (up to how many songs)? Stop the current song, start the new one?

Hi wvmarle, Thanks for that amazing reply. As for your question I would like to have ti queue up to 3 songs (and then probably have it disregard any input after that until there is space in the queue.

As usual I have no clue how to achieve this but I thought I would try and cross that bridge when It comes to it, however any help people can offer in this is greatly appreciated!!

Thanks
Will

For your queue: use an array with three elements, each which contain a song name. Basically a 2D array. Use an index variable that keeps track of which is the next to play and which is where the next entry is to be placed. These two can be the same if the array is empty (in which case you don't start playing the next song).

byte nextSongIndex = 0;
byte nextInputIndex = 0;
char songQueue[3][3];

void loop() {
  if (nPresses == 3) { // Three buttons have been pressed: play the requested song.
    // play song songQueue[nextSongIndex].
    nextSongIndex++;
    if (nextSongIndex == 3) nextSongIndex = 0; // Roll over.
  }
}

Store button presses in songQueue[nextInputIndex][nPresses].

You need some smarts to keep track of everything, this is just a starting point of course. Maybe add a queueFull boolean that tells you whether the queue is full or empty, as in both cases nextSongIndex == nextInputIndex.