Pushbutton to cycle modes

Whats up everybody. So here is my plan. I am designing a stereo that has an MP3 player, Bluetooth, Fm Tuner and Aux In. I plan on the MP3 player immediately turning on, then using the pushbutton switch to cycle "modes". IE Turn off mp3/turn on bluetooth, press again to turn off bluetooth/turn on fm tuner etc. I am using solid state relays to distribute power to the devices and arduino to control the relays.
Here is a grid of my goal.

Device = MP3 Bluetooth FM Tuner
Power Up On Off Off
Press Button Off On Off
Press again Off Off On
Press again All OFF
Press again On Off Off

Etc

I have been researching for a couple weeks and have found many similar programs but there has always been some reason it wont work for me such as using multiple buttons or whatever the case may be. I have downloaded an Arduino Command reference book, watched tutorials on youtube and though I had an understanding of the code but apparently not.

Here is my code so far just for the first 2 modes. I have uploaded and nothing happens whatsoever with my device, unfortunately as this is my first arduino project, I am completely lost and have no idea where to go or what to do. Please point me in the right direction. Any help is greatly appreciated.

I am running Arduino Uno on 5 Vdc and I am using LED's before I actually connect the relays.

void setup() {
// put your setup code here, to run once:
pinMode(2, INPUT); //Mode Switch
pinMode(5, OUTPUT); //MP3 Player
pinMode(6, OUTPUT); //Bluetooth
digitalWrite(5, HIGH); //Run MP3 on Startup
}

void loop() {
// put your main code here, to run repeatedly:

if (digitalRead == (2, HIGH)); // When Mode button is pushed...
digitalWrite(5, LOW); // Turn off MP3 Player
delay(100);
digitalWrite(6, HIGH); //Turn on Bluetooth
if (digitalRead == (2, HIGH)); // When Mode button is pushed
digitalWrite(6, LOW); //Turn off Bluetooth
delay(100);
digitalWrite(5, HIGH); //Turn on MP3 Player
}

Hi,

your if statements are incorrect to start with

I'd have a read of this - https://www.arduino.cc/en/Tutorial/StateChangeDetection

this code already has a counter up to 4 - so there are 5 states - 0 1 2 3 4. If you only need 4 just make it count up to 3 - easy.

you could then use if statements for each different number -

if (counter = 0){

do stuff here

}

if (counter = 1){

do stuff here

}

if (counter = 2){

do stuff here

}

if (counter = 3){

do stuff here

}

@geekyguru

You should post complete code (including the part before the setup() function).
You should also post code embedded in code tags

Edit your opening post and

type
** **[code]** **
before your code
type
** **[/code]** **
after your code

swisscheese has the correct approach; just be aware that the equal sign in his/her if statements means equal, not assign (and hence should be '==').

So use a variable to store the mode (mode might be a better name than counter :wink: ). The variable is updated when the button is pressed. Base whatever needs to happen on the value in the mode variable.

  if (digitalRead == (2, HIGH));

Go look very carefully at some of the examples and see if they look like this at all. You got some things mixed up there.

And if statements don’t get semicolons.

Incorrect usage of digitalRead.

int state = digitalRead(2);

Also more than one line inside 'if' condition should have braces

if(state==HIGH){
   digitalWrite(5, LOW);
   delay(100);
}

swisscheese:
if (counter = 0){

do stuff here

}

if (counter = 1){

do stuff here

}

if (counter = 2){

do stuff here

}

if (counter = 3){

do stuff here

}

What @swisscheese forgot to mention is that this is pseudocode, and bears no resemblance to actual C/C++.

Thanks to everybody who posted. I am doing my best but still not quite grasping what I need to I suppose. Here is where I am at as of now and I attached my code because it seems easier to read then in this thread format.

/* So I pasted this in addition to my original code for reference purposes. I tried to take every suggestion and make do with what I could. I went over the tutorial for state change and am still not sure how to establish the “max” number of modes(how to get it to loop back to mode 1) nor do I understand why they all “=” 0. The current error I get is ‘counter’ was not declared in this scope, see counter = 3 reference. What confuses me with that is that it is the same line of code as the previous counter states but they don’t display as an error line. I have looked over the web and found references saying I need a variable for the pin status, Using static int, int i and so forth. Would it be better to set INT instructions of mode settings up in setup instead of the separ ate lines of code in the loop section? And for the record I did toy with the state change det but tried altering it leading to the same questions. THANKS IN ADVANCE EVERYBODY!
*/

// this constant won't change:
const int MODE = 2;  // The Mode Select Button
const int MP3 = 3;  // MP3 Power Control
const int BT = 4;  // Bluetooth Power Control
const int FM = 5;  //Fm Tuner Power Control

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
    pinMode(MODE, INPUT);  //Mode Button
    pinMode(MP3, OUTPUT);  //MP3 Player Relay
    pinMode(BT, OUTPUT);  //Bluetooth Relay
    pinMode(FM, OUTPUT);  //FM Tuner Relay
    digitalWrite(MP3, HIGH);  //Automatically Turns on MP3 Player, Begin Mode 1
}


void loop() {
 
  buttonState = (MODE, HIGH);  // read the mode button

  // compare the buttonState to its previous state
 if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
 if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
if (counter = 0){
digitalWrite(MP3, LOW)  //Shuts down MP3
delay(100)
digitalWrite(BT, HIGH)  //Begins Mode 2
}

if (counter = 1){
digitalWrite(BT,LOW)  //Shuts down Bluetooth
delay(100)
digitalWrite(FM, HIGH)  //Begins Mode 3
}

if (counter = 2){
digitalWrite(FM, LOW)  //Begins Mode 4, Shuts down media source, allows use of the aux in jack without feedback from other media sources
}

if (counter = 3){  //<=======================================================ERROR LINE
digitalWrite(MP3, HIGH)  //Reverts back to Mode 1
}

 if (buttonPushCounter % 1 == 0)

[CODE/]

Power_Control_Rev_1.ino (2.6 KB)

void loop()
{

  buttonState = (MODE, HIGH);  // read the mode button

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState)
  {
    // if the state has changed, increment the counter
    if (buttonState == HIGH)
    {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;

      // limit the value of buttonPushCounter and reset after that
      if(buttonPushCounter == 10)
      {
        buttonPushCounter = 0;
      }

      ...
      ...

That will limit the value to 9.

Notes:
1)
You have buttonPushCounter and counter in the snippet that you posted; I don't see counter being changed.
2)
Do not attach code if not needed; it is small enough to be included in the post. I did not look at the attached code.
3)
Learn to properly indent (make use of tools -> autoformat in the IDE menu)

@Sterretje

So just to make sure I am following you correctly, if I wanted 4 modes, the the command line would look like

  1. if(buttonPushCounter == 4), I interpret this as count/mode - 0, 1, 2, 3, and 4 reverts back to 0.

  2. and that the command (buttonPushCounter++ ), is the actual counter changing command?

  3. Why do you add the ! in the button state command line

  4. In regards to your note 3 - does that affect programming or is it just easier to read (just curious)

  1. yes
  2. pushButtonCounter is counter/mode
  3. I did not add it
  4. Easier to read and easier to spot errors with missing curly braces or code that is not where it's supposed to be.

Hey again everybody, so I have it partially working.

So startup works correctly and turns on Mode1(MP3) however when I push my button, it turns off the MP3 player and then Bluetooth and FM tuner turn on at the same time, and only stay on momentarily when holding the button down. I assume that the counter is not properly programmed but still cant seem to figure out why. Here is the current code.

// this constant won't change:
const int MODE = 2;  // The Mode Select Button
const int MP3 = 3;  // MP3 Power Control
const int BT = 4;  // Bluetooth Power Control
const int FM = 5;  //Fm Tuner Power Control

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
int MODE1 = (buttonPushCounter = 0);  //MP3 Player On
int MODE2 = (buttonPushCounter = 1);  //Bluetooth On
int MODE3 = (buttonPushCounter = 2);  //FM Tuner On
int MODE4 = (buttonPushCounter = 3);  //All of for Aux In



void setup() {
  pinMode(MODE, INPUT);  //Mode Button
  pinMode(MP3, OUTPUT);  //MP3 Player Relay
  pinMode(BT, OUTPUT);  //Bluetooth Relay
  pinMode(FM, OUTPUT);  //FM Tuner Relay
  digitalWrite(MP3, HIGH);  //Automatically Turns on MP3 Player, Begin Mode 1
  if (buttonPushCounter == 4)  //Reset counter from 4 back to 0
  {
    buttonPushCounter = 0;
  }
}
void loop() {

  buttonState = digitalRead(MODE);  // read the mode button


  if (buttonState != lastButtonState) {  // compare the buttonState to its previous state

    if (buttonState == HIGH) {  // if the state has changed, increment the counter

      { // if the current state is HIGH then the button went from off to on
        buttonPushCounter++;
      }
    }
    if (MODE1) {
      digitalWrite(MP3, HIGH);
      digitalWrite(BT, LOW);
      digitalWrite(FM, LOW);
    }
    if (MODE2) {
      digitalWrite(MP3, LOW);
      digitalWrite(BT, HIGH);
      digitalWrite(FM, LOW);
    }
    if (MODE3) {
      digitalWrite(MP3, LOW);
      digitalWrite(BT, LOW);
      digitalWrite(FM, HIGH);
    }
    if (MODE4) {
      digitalWrite(MP3, LOW);
      digitalWrite(BT, LOW);
      digitalWrite(FM, LOW);
    }
  }
}
[CODE/]

Don't use 4 mode variables. pushButtonCounter is your mode variable.

geekyguru:
Hey again everybody, so I have it partially working.

So startup works correctly and turns on Mode1(MP3) however when I push my button, it turns off the MP3 player and then Bluetooth and FM tuner turn on at the same time, and only stay on momentarily when holding

There is a special tool that can help you with your “Mode” or State called the enum. Enums make reading and understanding your code very easy by allowing you to create descriptive names for states (or for other variable types).

You can use an enum to traverse through different states with the push of a button. Here is a way to use enum to help with your issue.

A couple points:

  1. I used INPUT_PULLUP on the buttonPin, not knowing if your rig included a pullup or pulldown resistor.
  2. I added debouncing, not knowing how you were going to handle that.

here is the code (compiled but not tested):

enum DeviceMode{
  OFF_MODE,
  MP3_MODE,
  BLUTOOTH_MODE,
  FM_MODE,
  MODES_MAX
};

DeviceMode deviceMode = MP3_MODE;

const int modeButton = 2;  // The Mode Select Button

const int MP3 = 3;  // MP3 Power Control
const int BT = 4;  // Bluetooth Power Control
const int FM = 5;  //Fm Tuner Power Control

void setup() 
{
  Serial.begin(9600);
  pinMode(modeButton, INPUT_PULLUP);
  
  pinMode(MP3, OUTPUT);  //MP3 Player Relay
  pinMode(BT, OUTPUT);  //Bluetooth Relay
  pinMode(FM, OUTPUT);  //FM Tuner Relay
  digitalWrite(MP3, HIGH);  //Automatically Turns on MP3 Player, Begin in MP3_MODE
}

void loop() 
{
  static byte lastButtonState = HIGH;
  static unsigned long lastPressTime = 0;
  byte buttonState = digitalRead(modeButton);
  if(buttonState != lastButtonState && buttonState == LOW && millis() - lastPressTime > 50)
  {
    byte currentMode = static_cast<int>(deviceMode); // convert deviceMode to an integer
    deviceMode = static_cast<DeviceMode>(++currentMode % MODES_MAX);  // increment the integer, roll it over to max number of modes and convert back to the enum
    switch (deviceMode)
    {
      case OFF_MODE:
        Serial.println(F("I'm in OFF Mode"));
        digitalWrite(MP3, LOW);
        digitalWrite(BT, LOW);
        digitalWrite(FM, LOW);
        break;
      case MP3_MODE:
        Serial.println(F("I'm in MP3 Mode"));
        digitalWrite(MP3, HIGH);
        digitalWrite(BT, LOW);
        digitalWrite(FM, LOW);
        break;
      case BLUTOOTH_MODE:
        Serial.println(F("I'm in BT Mode"));
        digitalWrite(MP3, LOW);
        digitalWrite(BT, HIGH);
        digitalWrite(FM, LOW);
        break;
      case FM_MODE:
        Serial.println(F("I'm in FM Mode"));
        digitalWrite(MP3, LOW);
        digitalWrite(BT, LOW);
        digitalWrite(FM, HIGH);
        break;
    }
    lastButtonState = buttonState;
    lastPressTime = millis();  // debouncing
  }
}

You never set lastButtonState to the last button state that was read so it will always equal zero.