Play a melody using pushbuttons & counter

Hi there !

I’m trying to make a menu in an LCD, this menu has 2 buttons, the first one is a selection button and the other one is an “OK” button, what I want is to select a song, and after that when I press “OK”, i’ll get, on the buzzer, a melody played by the buzzer depending on which menu I selected of course.

What I need is a synchronization between the menu I’m actually choosing and the song to be played, what I mean by that is, in my menu, the first option, for example, Queen, must actually play me a Queen song and not any of the other melodies, what I thought might be a good idea is, to make a counter, which will count everytime I press the selection button, I have 4 different bands in my menu, so the counter will go 0 1 2 3 0 1 2 3 0 and therefore, when I’ll press OK, the program will check the counter, lets suppose for instance its equal to 2 and will launch melody 2.

I know this may seem long and pretty basic, but I’m totally new to Arduino & programming so I’m trying to apply basic ideas.

My program :

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);

int RIGHT = 8; //This is the selecting button
int OK = 13; //You know what this one is for
int count = 0; //Initialising my counter
const int menuSize = 4; //how many menus i want
String menuItems[menuSize];
int currentMenu = 0; //The first menu you get when powering up the arduino
bool RIGHTLastState = HIGH; //Helps for the menu program
int buzzer = 3; //My buzzer

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
// First menu name
menuItems[0]= “QUEEN” ;
// Second menu name
menuItems[1]= “PINK FLOYD” ;
// third menu name
menuItems[2]= “MUSE” ;
// fourth menu name
menuItems[3]= “LED ZEPPELIN” ;

lcd.begin(16, 2);
lcd.print(menuItems[currentMenu]); //Printing the first menu right when we plug in the arduino
Serial.println(count);
pinMode(OK, INPUT_PULLUP);
pinMode(RIGHT, INPUT_PULLUP);
pinMode(buzzer, OUTPUT);
}

void loop() {
if(digitalRead(RIGHT) != RIGHTLastState)
{
if (RIGHTLastState = !RIGHTLastState) {
if (currentMenu>0) {
currentMenu–;
count ++;
if
(count >= 4)
{
count = 0;
}
}
else
{ currentMenu = menuSize - 1 ;
}
lcd.clear() ;
lcd.print(menuItems[currentMenu]);
Serial.println(count);
}
else {
}
}
delay(150);
}

Now I have on my LCD the name of the four bands, the selecting button is working fine, however, the counter isnt working properly, I have at init on my serial board, 0 after that when I press the OK button, i have 0 and then 1 2 3 0 sometimes 0 1 1 2 3 0 sometings 0 1 2 3 3 0 I dont know why.

So my issues are, first how do I fix this counter problem, and secondly how to make it play a melody depending on which number the counter is in, example, I want to play a Led Zeppelin melody, the country must be equal to 3, what can I add to my program to play me melody 2, knowing that I already have the melody in another program.

Don't know if this is the problem,

if (RIGHTLastState = !RIGHTLastState)

You are assigning the value of [u]not RIGHTState[/u] to RIGHTLastState there. == to compare = to assign.

Please post your properly formatted code in code tags.

groundfungus:
Don’t know if this is the problem,

if (RIGHTLastState = !RIGHTLastState)

You are assigning the value of not RIGHTState to RIGHTLastState there. == to compare = to assign.

Please post your properly formatted code in code tags.

Here is my code in a more readable form.

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);

int RIGHT = 8; //This is the selecting button
int OK = 13; //You know what this one is for
int count = 0; //Initialising my counter
const int menuSize = 4; //how many menus i want
String menuItems[menuSize];  
int currentMenu = 0; //The first menu you get when powering up the arduino
bool RIGHTLastState = HIGH; //Helps for the menu program
int buzzer = 3; //My buzzer

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
// First menu name
menuItems[0]= "QUEEN" ; 
// Second menu name
menuItems[1]= "PINK FLOYD" ; 
// third menu name
menuItems[2]= "MUSE" ;
// fourth menu name
menuItems[3]= "LED ZEPPELIN" ; 

lcd.begin(16, 2);
lcd.print(menuItems[currentMenu]);  //Printing the first menu right when we plug in the arduino
Serial.println(count);
pinMode(OK, INPUT_PULLUP);
pinMode(RIGHT, INPUT_PULLUP);
pinMode(buzzer, OUTPUT);
}

void loop() {
if(digitalRead(RIGHT) != RIGHTLastState)
{
if (RIGHTLastState = !RIGHTLastState) {
if (currentMenu>0) {
  currentMenu--;
  count ++;
  if 
  (count >= 4) 
  {
    count = 0;
  }
}
else 
{ currentMenu = menuSize - 1 ;
}
lcd.clear() ;
lcd.print(menuItems[currentMenu]);
Serial.println(count);
}
else {
}
}
delay(150);
}

I dont see any issue with it, I want the program to compare the value of the last state with the one of the button, if there is a change in the state, than assign that change to RightLastState and make a change in the value of current menu.This part of the program isnt mine, I took it and changed it to my taste, to I might be wrong in my thinking.

if(digitalRead(RIGHT) != RIGHTLastState)
{
if (GHTRILastState = !RIGHTLastState) {

Do you see the difference in the two if statements. The top one says "is the state of the button not equal to the last state?" A comparison. The second assigns the value of the inverse of the last state to the last stare. The order of ! an = matters. != is a not equal comparison. = ! is an [u]assignment[/u] of the inverse. == ! is a comparison with the inverse.

I don't see what the second if is trying to accomplish, how can the state equal not the state in comparison and you can not make an assignment in an if statement.

groundfungus: if(digitalRead(RIGHT) != RIGHTLastState) { if (RIGHTLastState = !RIGHTLastState) {

Do you see the difference in the two if statements. The top one says "is the state of the button not equal to the last state?" A comparison. The second assigns the value of the inverse of the last state to the last stare. The order of ! an = matters. != is a not equal comparison. = ! is an [u]assignment[/u] of the inverse. == ! is a comparison with the inverse.

I don't see what the second if is trying to accomplish, how can the state equal not the state in comparison and you can make an assignment in an if statement.

I understand now what you wanted to say and I erased the second statement because the first one is enough, since RightLastState is a bool data type it was unnecessary to assign the opposite value since there is only 2 values it can take and so the first if does the job, thanks for the helping hand, however it didnt change the problem I get in the serial monitor, still getting 0 0 1 2 3 0 1 1 2 3 ...

I think it would be better to focus more on the second issue, I can play a melody using a button, but to play a melody depending on a button and a counter is tricky form e.

Still hoping for some help !

Having a counter and an index looks overly complicated to me. I simulated your setup using serial input instead of a button, typing "1’ to switch bands.

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);

int RIGHT = 8; //This is the selecting button
int OK = 13; //You know what this one is for
int count = 0; //Initialising my counter
const int menuSize = 4; //how many menus i want
String menuItems[menuSize];
int currentMenu = 0; //The first menu you get when powering up the arduino
bool RIGHTLastState = HIGH; //Helps for the menu program
int buzzer = 3; //My buzzer

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  // First menu name
  menuItems[0] = "QUEEN" ;
  // Second menu name
  menuItems[1] = "PINK FLOYD" ;
  // third menu name
  menuItems[2] = "MUSE" ;
  // fourth menu name
  menuItems[3] = "LED ZEPPELIN" ;

  lcd.begin(16, 2);
  lcd.print(menuItems[currentMenu]);  //Printing the first menu right when we plug in the arduino
  Serial.println("Starting ... ");
  Serial.println(menuItems[currentMenu]);
  pinMode(OK, INPUT_PULLUP);
  pinMode(RIGHT, INPUT_PULLUP);
  pinMode(buzzer, OUTPUT);
}

void loop() {
  if ( Serial.available() && Serial.read() == '1')
    // if (digitalRead(RIGHT) != RIGHTLastState)
  {

    // increment index, wrap to first band
    ++currentMenu %= 4;
    

    lcd.clear() ;
    lcd.print(menuItems[currentMenu]);
    Serial.print("Selected:  ");Serial.println(menuItems[currentMenu]);

  }
  delay(150);
}

Serial monitor:

Starting ... 
QUEEN
Selected:  PINK FLOYD
Selected:  MUSE
Selected:  LED ZEPPELIN
Selected:  QUEEN
Selected:  PINK FLOYD
Selected:  MUSE
Selected:  LED ZEPPELIN
Selected:  QUEEN
Selected:  PINK FLOYD
Selected:  MUSE
Selected:  LED ZEPPELIN
Selected:  QUEEN