Animation Leds, (light saber like), with millis function, passive buzzer, and a button

Hello, I'm an Arduino very beginner, and I'm trying to make an animation with 5 Leds, one piezzo buzzer and one button with the millis() function. I would wish, when i press the button, to switch on the leds one by one with differents delays, and activate the buzzer at the same time, , like a "light saber". (And after that, I did a random blinkwith the analogWrite function, (I use PWM pins)).

Actualy, with my Sketch, I managed to make a sound that ranges from high to low. But it goes on the loop, i prefered the sound start from high and goes to low, and after that stay on low. And the leds are not switching on, one by one, like i would wish.

Thanks a lot in advance for your time.

const int LED_A = 5;
const int  LED_B = 6;
const int  LED_C = 9;
const int  LED_D = 10;


const int  buttonPin = 13;
const int  buttonPin02 = 8;

const int buzzer = 12;

unsigned long TempsActuel ;
int TempsSauvegarde = 0;
int buttonState = LOW;

void setup() {



  pinMode(LED_A, OUTPUT);
  pinMode(LED_B, OUTPUT);
  pinMode(LED_C, OUTPUT);
  pinMode(LED_D, OUTPUT);


  pinMode(buttonPin, INPUT_PULLUP);


  pinMode(buzzer, OUTPUT);


}

void loop() {


  TempsActuel = millis();
  buttonState = digitalRead(buttonPin);

  if (buttonState == LOW)
  {
    TempsSauvegarde = TempsActuel;
    if (TempsActuel - TempsSauvegarde >= 0)
    {

      for (int x = 500; x > 0 ; x--) {
        tone (12, x, TempsActuel);
        delay(1);
      }
      
      digitalWrite(LED_A, HIGH);
      TempsSauvegarde = TempsActuel;
    }

    if (TempsActuel - TempsSauvegarde >= 300)
    {

      digitalWrite(LED_B, HIGH);
      TempsSauvegarde = TempsActuel;
    }
    if (TempsActuel - TempsSauvegarde >= 150)
    {

      digitalWrite(LED_C, HIGH);
      TempsSauvegarde = TempsActuel;
    }
    if (TempsActuel - TempsSauvegarde >= 150)
    {

      digitalWrite(LED_D, HIGH);
      TempsSauvegarde = TempsActuel;
    }


    analogWrite(LED_A, random(50, 255));
    analogWrite(LED_B, random(50, 255));
    analogWrite(LED_C, random(50, 255));
    analogWrite(LED_D, random(50, 255));
    delay(random(30, 120));

  }
  else
  {
    noTone (12);


    digitalWrite(LED_D, LOW);
    delay(150);
    digitalWrite(LED_C, LOW);
    delay(150);
    digitalWrite(LED_B, LOW);
    delay(150);
    digitalWrite(LED_A, LOW);
  }
}

Try each action (tones, random LEDs, et cetera) on their own, then combine them. Put similar code in a function with arguments, for example, place these lines in a function:

void randomLEDs()
{
    analogWrite(LED_A, random(50, 255));
    analogWrite(LED_B, random(50, 255));
    analogWrite(LED_C, random(50, 255));
    analogWrite(LED_D, random(50, 255));
    delay(random(30, 120));
}

and call the function from the main code....

randomLEDs();

tone(pin) and noTone(pin) could be written (not necessary) tone(buzzer) and noTone(buzzer).

Given the fact that TempsActuel is an unsigned long variable, that expression will be evaluated as unsigned long which means that it will always be true since unsigned math can not be less than 0. You should also make your TempsSauvegarde variable unsigned long since you are assigning time to it.

thank you for your answers ! It is true for the unsigned long variables, thanks.

So I try this sketch, (without the millis function for animLEDs), and juste one sound for the buzzer instead of a fade sound, to test something more simple, with "void sound", "void animLEDs" and "void randomLEDs", but the Leds are switching on and off without pressing the buton. :confused: Do you know how can I do the animation of the leds and the buzzer sound at the same time when i press the button ? thanks ! =)

const int LED_A = 5;
const int  LED_B = 6;
const int  LED_C = 9;
const int  LED_D = 10;
const int  LED_E = 8;
const int  buttonPin = 13;
const int buzzer = 12;

unsigned long TempsActuel ;
unsigned long TempsSauvegarde = 0;

int buttonState = LOW;

void setup() {

  pinMode(LED_A, OUTPUT);
  pinMode(LED_B, OUTPUT);
  pinMode(LED_C, OUTPUT);
  pinMode(LED_D, OUTPUT);
  pinMode(LED_E, OUTPUT);

  pinMode(buttonPin, INPUT_PULLUP);

  pinMode(buzzer, OUTPUT);
}

void sound ()

{

  TempsActuel = millis();
  buttonState = digitalRead(buttonPin);

  if (buttonState == LOW)
  {
    tone (buzzer, 60, TempsActuel);
  }

  else
  {
    noTone (buzzer);
  }
}

void animLEDs()

{
  buttonState = digitalRead(buttonPin);

  if (buttonState == LOW)
  {
    digitalWrite(LED_A, HIGH);
    delay(300);
    digitalWrite(LED_B, HIGH);
    delay(150);
    digitalWrite(LED_C, HIGH);
    delay(150);
    digitalWrite(LED_D, HIGH);
    delay(150);
    digitalWrite(LED_E, HIGH);
  }

  else

  {
    digitalWrite(LED_E, LOW);
    delay(150);
    digitalWrite(LED_D, LOW);
    delay(150);
    digitalWrite(LED_C, LOW);
    delay(150);
    digitalWrite(LED_B, LOW);
    delay(150);
    digitalWrite(LED_A, LOW);
  }
}

void randomLEDs ()
{

  analogWrite(LED_A, random(50, 255));
  analogWrite(LED_B, random(50, 255));
  analogWrite(LED_C, random(50, 255));
  analogWrite(LED_D, random(50, 255));

  delay(random(30, 120));
}

void loop ()

{
  sound ();
  animLEDs();
  randomLEDs ();
}

First off, you don't want to know if your button is pressed, but when your button gets pressed. Check out the State Change Detection example in the IDE (File->examples->02.digital->State Change Detection)

Second, if you want to do more than one thing at the same time, you will have to get rid off all those delay() calls. The program does nothing else while they are happening. Look at the Blink Without Delay example in the IDE (File->examples->02.digital->Blink Without Delay)

Finally, you can't do the entire animation sequence in a single call. You have to just do smalls steps and then return and do a bit more the next time through loop(). A good way of doing that is a state machine. Read this tutorial: several things at the same time

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.