Hello, I am a newbie to the Arduino world and C programming as well. I have been going for the last few days building a circuit, designing what I want from it, then improving and adding new features. I have one large program that I am trying out smaller sections of first as their own. In this example, I have 5 Leds, and at the press of a button up to two will be randomly selected and turn on. Just turning on is fine and they turn on at the same time, but when I put in the code to have them fade up from 0 to 255 it happens one Led at a time.
I know what is wrong, it is going through the For loop for each Led at a time. How would I go about having them fade up at the same time?
//quickly fading the Leds on
void randomLedUpdate(int ledPin)
{
for (int i = 0; i<=255; i++)
{
analogWrite(ledPin, i);
delay(1);
}
}
and then later..
//if button is pressed, then turn on the two random Leds
if ((buttonState == HIGH) && (firstLoop == 0))
{
digitalWrite(randomLed1, LOW); //first turn off any previously lit Leds
digitalWrite(randomLed2, LOW);
randomLed1 = ledArray[random(0,5)]; //assign the two Random leds from
randomLed2 = ledArray[random(0,5)]; //two available from the Led Array
randomLedUpdate(randomLed1); //send these random values to the randomLedUpdate
randomLedUpdate(randomLed2); //function to have them fade on
firstLoop = 1; //set it so that the 2nd and every other time the loop repeats, it does not
} //get new random numbers.
I see that I am sending one Led to fade up, then the 2nd is going to the function to fade up, how would I put it so that they are both fading up at the same time?
edit And as soon as I posted this I realized where I was going wrong. I sent both randomLed1 & 2 up to the function, and just added another analogWrite line for ledPin2.
void randomLedUpdate(int ledPin1, int ledPin2)
{
for (int i = 0; i<=255; i++)
{
analogWrite(ledPin1, i);
analogWrite(ledPin2, i);
delay(1);
}
}
your for loop "blocks" (or uses) the programm until it is finished.
you might consider to use a classical "BlinkWithoutDelay"
you could combine that with the "State Change Detection"
Everything is in the IDE.
some steps further you might declare some objects, and come up with a sketch - making everything very expandable, still readable and easy to maintain.
I would try following:
a class for smooth LEDs
a class for buttons
two arrays for the pins
that's more or less all you need.
/*
Dim several LEDs in parallel
https://forum.arduino.cc/t/leds-not-coming-on-at-the-same-time/899626
by noiasca
*/
// a dimmable Led
class SmoothLed {
const byte ledPin; // a GPIO for the LED
uint16_t currentBrightness = 0; // actual brightness of Pin
const uint16_t maxBrightness = 255; // native PWM is only 8 bit
uint8_t interval = 15; // delay for each step
unsigned long previousMillis; // last timestamp
byte state = 0; // 0 off, 1 on
public:
SmoothLed(byte ledPin) : ledPin(ledPin)
{}
void begin() {
pinMode(ledPin, OUTPUT);
}
void on() { // switch smooth on
state = 1;
}
void off() { // switch smooth off
state = 0;
}
void toggle() { // switch on or off
state = !state;
}
void setInterval(uint8_t newInterval)
{
interval = newInterval;
}
void update() {
if (state == 1 && currentBrightness < maxBrightness && millis() - previousMillis > interval)
{
currentBrightness++;
analogWrite(ledPin, currentBrightness);
previousMillis = millis();
}
else if (state == 0 && currentBrightness > 0 && millis() - previousMillis > interval)
{
currentBrightness--;
analogWrite(ledPin, currentBrightness);
previousMillis = millis();
}
}
};
class Button // a simple class for buttons based on the "state change detection" example
{
const byte buttonPin;
const byte debounceDelay = 50; // the debounce time; increase if the output flickers
bool lastButtonState = HIGH; // the previous reading from the input pin
byte lastDebounceTime = 0; // the last time the output pin was toggled - we check only ONE byte, so I didn't mess around with unsigned long
public:
Button(byte attachTo) : buttonPin(attachTo) {}
void begin() {
pinMode(buttonPin, INPUT_PULLUP);
}
// returns HIGH if button was clicked since last call - debounce
bool wasPressed() {
bool buttonState = LOW; // the current reading from the input pin
byte reading = LOW;
if (digitalRead(buttonPin) == LOW) reading = HIGH; // if we are using INPUT_PULLUP we are checking invers to LOW Pin
if (((millis() & 0xFF ) - lastDebounceTime) > debounceDelay) // If the switch changed, AFTER any pressing or noise
{
if (reading != lastButtonState && lastButtonState == LOW) // If there was a change and and last state was LOW
{
buttonState = HIGH;
}
lastDebounceTime = millis() & 0xFF;
lastButtonState = reading;
}
return buttonState;
}
};
SmoothLed smoothLed[] {3, 5, 6, 9}; // PWM pins UNO are 3, 5, 6, 9, 10, 11
Button button[] {A0, A1, A2, A3}; // button connects pin with GND, "active LOW"
const size_t noOfLeds = sizeof(smoothLed) / sizeof(smoothLed[0]); // how many LEDs are used
void setup() {
Serial.begin(115200);
for (auto &i : smoothLed) i.begin();
for (auto &i : button) i.begin();
smoothLed[0].setInterval(5); // just as demo how to set a different speed/interval
smoothLed[1].setInterval(10);
smoothLed[0].on(); // switch LED on smoothly
randomSeed(analogRead(A6));
}
void loop() {
if (button[0].wasPressed())
{
byte rnd = random(2); // 0 or 1
smoothLed[rnd].toggle();
}
if (button[2].wasPressed()) smoothLed[2].toggle(); // check button index 2 if necessary, toggle the LED
if (button[3].wasPressed()) smoothLed[3].toggle(); // check button index 3 if necessary, toggle the LED
for (auto &i : smoothLed) i.update(); // call each LED for update
}