Christmas Lights to Music Dual Mode Code Question

Hello my first post in this forum, this forum and the community are amazingly helpful.

I am quite new to Arduino, I am trying to modify the code I found done by the baldengineer (link) it seems to work fine, the lights "dance" to music. Thanks baldengineer.com for that info. BTW I am not listening to Christmas music :slight_smile: , the LED's dance to the music placed into the audio jack. I was happy with that, I still have to attach the Arduino to solid state relays, to drive the 120V light strings (later once I get the code refined). Currently just using LED's/resistors to simulate the relays.

The thing I want to change is in the sketch, I would like to have a switch (hopefully) momentary that as the sketch is running, if I press the button the sketch will toggle between two modes.

The Modes would be lights are controlled by the MSEQ7 and music (mode 1), or the lights are all just on(mode 2).

I thought that the music control was the "bee's knees" but my wife, says she wants to have the ability to just turn all the lights on. Actually not a bad idea. LOL

So I am looking any suggestions on how I may be able to make this happen, in the sketch. I did not copy the code because I did not want to get banned from the forum, first post.

I hope I did not break any protocols, and if this was already done I apologize in advance. Please just point me in the right direction.

Thanks

I did not copy the code because I did not want to get banned from the forum, first post.

Why would one get banned for posting code? I see nothing on the linked page that forbids posting that code.

One way to do what you want is to have a flag that will represent which mode that you want. The state of the flag could be controlled by the push button switch using the state change detection (edge detect) method. Then an if statement can monitor the flag state and choose the required mode.

Here is code to toggle the state of an output pin. it can, easily, be changed to toggle the state of a flag.

// This is to illustrate using the state change detection method to
// toggle the state of a pin (Pin 13, the on board LED)
// a momentary switch (pushbutton) is wired from pin 8 to ground
// and the internal pullup enabled
// by C Goulding aka groundFungus


const int  buttonPin = 8;    // the pin that the pushbutton is attached to
const int ledPin = 13;       // the pin that the LED is attached to

boolean buttonState = 0;         // current state of the button
boolean lastButtonState = 0;     // previous state of the button

void setup()
{
   // initialize the button pin as a input with internal pullup enabled
   pinMode(buttonPin, INPUT_PULLUP);
   // initialize the LED as an output:
   pinMode(ledPin, OUTPUT);
   // initialize serial communication:
   Serial.begin(9600);
}

void loop()
{
   static unsigned long timer = 0;
   unsigned long interval = 50;  // check switch 20 times per second
   if (millis() - timer >= interval)
   {
      timer = millis();
      // read the pushbutton input pin:
      buttonState = digitalRead(buttonPin);
      // compare the buttonState to its previous state
      if (buttonState != lastButtonState)
      {
         if (buttonState == LOW)
         {
            // if the current state is LOW then the button
            // went from off to on:
            digitalWrite(ledPin, !digitalRead(ledPin)); // toggle the output
         }
      }
      // save the current state as the last state,
      //for next time through the loop
      lastButtonState = buttonState;
   }
}

I will give it a try thanks.

So I tried the suggestion I entered the code where I thought it should go? It verified and uploads to the UNO no issue. It does not seem to keep the state of the switch or I messed up something(more likely). I set up a serial print, it seems to display a one, if I press the switch it displays nothing, when I release the button it displays a box then back to 1. I added the serial print to see what was on the buttonState pin. I had lots of errors initially. When they say syntax is key are they ever right :).

When connected to this pin it showed "1" when button not pressed, and "nothing" when pressed, and a box when released? The Switch is a normally open switch. The attached data image shows a snapshot of the switch switching states if that helps.

The switch is a momentary push button, it works I metered it, connected one lead to the +5 Volt rail and the other lead to D3 originally. I actually measured the 5 volts only when the switch was pressed, prior to placing it in the header.

Then I thought I remembered something weird about D3(?) pin so I connected to D6 changed the sketch and it still seems to only change states when the switch is held in the depress position. It is now a 1 or 0 which is an improvement but it does not seem to hold the state, and the "dancing" lights rock on. Even if I hold the switch on for several seconds(20+) the lights still "dance".

This time I have tried to upload the code, any suggestions are truly appreciated.

#define msg7RESET 11 // reset Pin 11
#define msg7Strobe 10  // Strobe Pin 10
#define msg7DCout A0  // DC out from MSG7

const int ModeButton = 6; // the pin the pushbutton is connected to 
const int LEDpins[7] = {2,4,5,7,8,12,13};  // there are 7 freq bands.  


boolean buttonState = 0;         // current state of the button
boolean lastButtonState = 0;     // previous state of the button

void setup() 
{ 
   
  // initialize the digital pin as an output.
  // Pin 13 has an LED connected on most Arduino boards:
  for (int x=0; x<7; x++) 
  {
  pinMode(LEDpins[x], OUTPUT);
  pinMode(msg7RESET, OUTPUT);
  pinMode(msg7Strobe, OUTPUT);
  // initialize the ModeButton as a input with internal pullup enabled
  pinMode(ModeButton, INPUT_PULLUP);
  Serial.begin(9600);
  }
}

void loop()
{
   static unsigned long timer = 0; // no idea what this does
   unsigned long interval = 50;  // check switch 20 times per second
   if (millis() - timer >= interval)
  
   timer = millis();
      // read the pushbutton input pin:
      buttonState = digitalRead(ModeButton);
      // compare the buttonState to its previous state
      if (buttonState != lastButtonState)
      {
         if (buttonState == HIGH)
         
            // if the current state is HIGH then the toggle on all relays:
            digitalWrite(LEDpins[2,4,5,7,8,12,13], HIGH); // toggle the output set all relays to ON
        }


  digitalWrite(msg7RESET, HIGH);  // reset the MSGEQ7's counter
   delay(5);      //delay 5 uSeconds
  
  digitalWrite(msg7RESET, LOW); //Sets the reset pin to LOW

  for (int x = 0; x < 7; x++)
  {
    digitalWrite(msg7Strobe, LOW);    // output each DC value for each freq band
    delayMicroseconds(35);           // to allow the output to settle (35)
    int spectrumRead = analogRead(msg7DCout);

    int PWMvalue = map(spectrumRead, 0, 1024, 0, 255);  // scale analogRead's value to Write's 255 max
    if (PWMvalue < 50)
      PWMvalue = PWMvalue / 2;    // bit of a noise filter, so the LEDs turn off at low levels

    analogWrite(LEDpins[x], PWMvalue);
    digitalWrite(msg7Strobe, HIGH);
      }
      Serial.println(buttonState);
    // save the current state as the last state,for next time through the loop
            lastButtonState = buttonState;
   }

Loving and Learning the Arduino (At least trying)

Thanks in advance

data.PNG

 if (buttonState != lastButtonState)
   {
      if (buttonState == HIGH)

         // if the current state is HIGH then the toggle on all relays:
         digitalWrite(LEDpins[2, 4, 5, 7, 8, 12, 13], HIGH); // toggle the output set all relays to ON
   }

You just need to toggle the mode flag here. And that is not how to set the states pins in an array. You change them one at a time by index in a for loop.

const int LEDpins[7] = {2,4,5,7,8,12,13};  // there are 7 freq bands.

If you are going to use PWM (analogWrite()) you must use PWM enabled pins (2,3,5,6,9,10,11 on an Uno). I don't think that you said which board that you have. Check your board for PWM pins.

Here is code to illustrate what I meant. It will toggle between showing the MSGEQ7 output and all lights on. I wired up a MSGEQ7 and LEDs to my Uno to test and the code works. Since I have only 6 PWM outputs I changed the pins around. Make sure that your setup matches before trying the code.

const byte msg7RESET = 13; 
const byte msg7Strobe = 12; 
const byte msg7DCout = A0;  // DC out from MSG7
const byte ModeButton = 7; // the pin the pushbutton is connected to

const int LEDpins[7] = {2, 3, 5, 6, 9, 10, 11}; // there are 7 freq bands but 6 pwm pins, so 2.

boolean buttonState = 0;         // current state of the button
boolean lastButtonState = 0;     // previous state of the button

byte mode = 0;

void setup()
{
  Serial.begin(115200);
   for (int x = 0; x < 7; x++)
   {
      pinMode(LEDpins[x], OUTPUT);
   }
      pinMode(msg7RESET, OUTPUT);
      pinMode(msg7Strobe, OUTPUT);   
      // initialize the ModeButton as a input with internal pullup enabled
      pinMode(ModeButton, INPUT_PULLUP);
     
   
}

void loop()
{
   checkButton();
   if(mode == 0)
   {
      outputMSG7();
   }
   else
   {
      outputWhite();
   }
}


void outputWhite()
{
   for(int x = 0; x < 7; x++)
   {
       analogWrite(LEDpins[x], 255);  // all lines full on
   }
}
  
void outputMSG7()
{
   for (int x = 0; x < 7; x++)
   {
      digitalWrite(msg7Strobe, LOW);    // output each DC value for each freq band
      delayMicroseconds(35);           // to allow the output to settle (35)
      int spectrumRead = analogRead(msg7DCout);

      int PWMvalue = map(spectrumRead, 0, 1024, 0, 255);  // scale analogRead's value to Write's 255 max
      if (PWMvalue < 50)
         PWMvalue = PWMvalue / 2;    // bit of a noise filter, so the LEDs turn off at low levels

      analogWrite(LEDpins[x], PWMvalue);
      digitalWrite(msg7Strobe, HIGH);
   }
  
}

void checkButton()
{
   static unsigned long timer = 0;
   unsigned long interval = 50;  // check switch 20 times per second
   if (millis() - timer >= interval)
   {
      timer = millis();
      // read the pushbutton input pin:
      buttonState = digitalRead(ModeButton);
      // compare the buttonState to its previous state
      if (buttonState != lastButtonState)
      {
         if (buttonState == LOW)
         {
            // if the current state is LOW then the button
            // went from off to on:
            mode = !mode;  //  toggle the mode state ************************
         }
      }
      // save the current state as the last state,
      //for next time through the loop
      lastButtonState = buttonState;
   }
}

WOW, thanks I may have mentioned I have an UNO (clone). So I wired it up as per your sketch and it seems to work. The lights dance, and I press the button they all stay on. Press it again and they dance again. How long have you been doing this, you seem like a sketch Yoda :o . I have so much to learn. The sketch is named GROUNDFUNGUS as it your sketch.

I guess because pin 2 is not PWM it flashes and the others LEDs seem to pulse, if that makes sense.

The reason the PWM instructions were in there was it was in the original sketch. I had no idea how to change that. I am ultimately going to try drive some solid state relays to be controlled by the UNO and switch the 120 V for the LED Christmas lights.

My wife will be so happy, that it has the two modes.

Thanks so much.

I do not know how solid state relays react to PWM. They may be OK, I just don't know. Anyone out there have an answer?

I added a mode to use digitalWrite() to the LED pins. So mode 0 is PWM to the pins, mode 1 is all on and mode 2 is using digitalWrite() on the pins with a threshold of 300 ADC counts (of course you can adjust the number as needed).

const byte msg7RESET = 13;
const byte msg7Strobe = 12;
const byte msg7DCout = A0;  // DC out from MSG7
const byte ModeButton = 7; // the pin the pushbutton is connected to

const int LEDpins[7] = {2, 3, 5, 6, 9, 10, 11}; // there are 7 freq bands but 6 pwm pins, so 2.

boolean buttonState = 0;         // current state of the button
boolean lastButtonState = 0;     // previous state of the button

byte mode = 0;

int digitalThreshold = 300;  // for the digital output function 

void setup()
{
   Serial.begin(115200);
   for (int x = 0; x < 7; x++)
   {
      pinMode(LEDpins[x], OUTPUT);
   }
   pinMode(msg7RESET, OUTPUT);
   pinMode(msg7Strobe, OUTPUT);
   // initialize the ModeButton as a input with internal pullup enabled
   pinMode(ModeButton, INPUT_PULLUP);


}

void loop()
{
   checkButton();
   switch(mode)
   {
      case 0:
      outputMSG7Analog();
      break;
      
      case 1:
      outputWhite();
      break;
      
      case 2:
      outputMSG7Digital();
      break;
   }
}


void outputWhite()
{
   for (int x = 0; x < 7; x++)
   {
      analogWrite(LEDpins[x], 255);  // all lines full on
   }
}

void outputMSG7Digital()
{
   for (int x = 0; x < 7; x++)
   {
      digitalWrite(msg7Strobe, LOW);    // output each DC value for each freq band
      delayMicroseconds(35);           // to allow the output to settle (35)
      int spectrumRead = analogRead(msg7DCout);

      if (spectrumRead > digitalThreshold)
      {
         digitalWrite(LEDpins[x], HIGH);
      }
      else
      {
          digitalWrite(LEDpins[x], LOW);
      }
      digitalWrite(msg7Strobe, HIGH);
   }

}

void outputMSG7Analog()
{
   for (int x = 0; x < 7; x++)
   {
      digitalWrite(msg7Strobe, LOW);    // output each DC value for each freq band
      delayMicroseconds(35);           // to allow the output to settle (35)
      int spectrumRead = analogRead(msg7DCout);

      int PWMvalue = map(spectrumRead, 0, 1024, 0, 255);  // scale analogRead's value to Write's 255 max
      if (PWMvalue < 50)
         PWMvalue = PWMvalue / 2;    // bit of a noise filter, so the LEDs turn off at low levels

      analogWrite(LEDpins[x], PWMvalue);
      digitalWrite(msg7Strobe, HIGH);
   }

}

void checkButton()
{
   static unsigned long timer = 0;
   unsigned long interval = 50;  // check switch 20 times per second
   if (millis() - timer >= interval)
   {
      timer = millis();
      // read the pushbutton input pin:
      buttonState = digitalRead(ModeButton);
      // compare the buttonState to its previous state
      if (buttonState != lastButtonState)
      {
         if (buttonState == LOW)
         {
            // if the current state is LOW then the button
            // went from off to on:
            mode ++;                   // increment mode
            if (mode > 2)              // reset mode 0 if over 2 
            {
               mode = 0;
            }
         }
      }
      // save the current state as the last state,
      //for next time through the loop
      lastButtonState = buttonState;
   }
}

I went through the code and added comments to see if I actually understand the lines of code. It was awesome to get the sketch, however if I am going to get better I need to better understand the language, as it is all new to me, If someone has time and want to I attached a .pdf where I highlighted(green) the comments I made. I did this to try and explain/understand what is happening in the code. If I am way off base, in my thoughts please let me know. I would truly appreciate any feedback, like I said I need to try to understand the basics of the code to improve and maybe someday I can help others, thanks groundFungus.

Thanks

DGA

groundFungus.pdf (54.7 KB)

byte mode = 0; //sets the mode function to one byte of data

That creates a variable with the name mode and the data type of byte (uint8_t).

for (int x = 0; x < 7; x++)// sets an integer for x counts to 7, starts over

The for loop reference may make the operation more clear.

pinMode(ModeButton, INPUT_PULLUP); // Inverts the ModeButton low is high, high is low

No. That sets the pinMode of the pin. A pin can be INPUT, INPUT_PULLUP or OUTPUT. A pin set to INPUT_PULLUP has the internal pullup resistor enabled. See digital pins tutorial

The rest of the comments are close enough. The Arduino language reference is a valuable resource.

Thanks for all the help.

DGA