Random Pin, random fade times, with limits

Hello and thank you for your time! I am recently getting back into this programming thing because I wanted to make a dress that “twinkles with stars” for a girl I like. I have worked out most of the code, but am a bit stuck on part of it.

I am working with the Arduino Lilypad and have recently added the PlatisSoft PWM library into my project, as I need to be able to fade up/down all of the LED’s on my project.

My code explains most of my problem, and where I am stuck. I really need to know how to be able to set a limit of 7 pins being on at any given time, and to pick a random pin to fade up/down for a random time. I have all of the variables I need ( I think) and all of the code that really needs looked at is towards the end, where I commented about being stuck.

/* JOJO'S DRESS CODE
 *  This code is designed to connect the Arduino 328 (Lilypad clone)
 *  which contains 17 LED's (one red pin 13, and 16 on dress)
 *  Using 2 switches, a possibile 4 options can be built into this code. 
 *  
 *                     Mine are as follows: 
 *                       [-----------]
 *                       [   0 | 0   ]Option 1: No Lights
 *                       [   0 | 1   ]Option 2: HeartPulse only
 *                       [   1 | 0   ]Option 3: Starlight Fading random time, max 7 @ once
 *                       [   1 | 1   ]Option 4: Flash random pin, random (200,1000) max 7 @ once
 *                       [-----------]
 */

#include <PalatisSoftPWM.h>

SOFTPWM_DEFINE_CHANNEL(0, DDRD, PORTD, PORTD0);  //Arduino pin 0 - this pin is used for Serial so you will be unable to use Serial in your sketch if you use it for PWM
SOFTPWM_DEFINE_CHANNEL(1, DDRD, PORTD, PORTD1);  //Arduino pin 1 - this pin is used for Serial so you will be unable to use Serial in your sketch if you use it for PWM
SOFTPWM_DEFINE_CHANNEL(2, DDRD, PORTD, PORTD2);  //Arduino pin 2
/***************************************************************
 * PINS 3 AND 4 ARE FOR SWITCH ON LILYPAD
 * *************************************************************
 */

SOFTPWM_DEFINE_CHANNEL(5, DDRD, PORTD, PORTD5);  //Arduino pin 5
SOFTPWM_DEFINE_CHANNEL(6, DDRD, PORTD, PORTD6);  //Arduino pin 6
SOFTPWM_DEFINE_CHANNEL(7, DDRD, PORTD, PORTD7);  //Arduino pin 7
SOFTPWM_DEFINE_CHANNEL(8, DDRB, PORTB, PORTB0);  //Arduino pin 8
SOFTPWM_DEFINE_CHANNEL(9, DDRB, PORTB, PORTB1);  //Arduino pin 9
SOFTPWM_DEFINE_CHANNEL(10, DDRB, PORTB, PORTB2);  //Arduino pin 10
SOFTPWM_DEFINE_CHANNEL(11, DDRB, PORTB, PORTB3);  //Arduino pin 11
SOFTPWM_DEFINE_CHANNEL(12, DDRB, PORTB, PORTB4);  //Arduino pin 12
SOFTPWM_DEFINE_CHANNEL(13, DDRB, PORTB, PORTB5);  //Arduino pin 13
SOFTPWM_DEFINE_CHANNEL(14, DDRC, PORTC, PORTC0);  //Arduino pin A0
SOFTPWM_DEFINE_CHANNEL(15, DDRC, PORTC, PORTC1);  //Arduino pin A1
SOFTPWM_DEFINE_CHANNEL(16, DDRC, PORTC, PORTC2);  //Arduino pin A2
SOFTPWM_DEFINE_CHANNEL(17, DDRC, PORTC, PORTC3);  //Arduino pin A3
SOFTPWM_DEFINE_CHANNEL(18, DDRC, PORTC, PORTC4);  //Arduino pin A4
SOFTPWM_DEFINE_CHANNEL(19, DDRC, PORTC, PORTC5);  //Arduino pin A5

SOFTPWM_DEFINE_OBJECT(18);

void setup() {
  PalatisSoftPWM.begin(60);  // begin with 60 Hz PWM frequency
pinMode(3,INPUT);//switch 1 on Lilypad for control of LED function
pinMode(4,INPUT);//switch 2 on Lilypad for control of LED function
digitalWrite(3,LOW);
digitalWrite(4,LOW);
}

void loop() {

const byte LEDArray[] = {0, 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19};
int pinCount = 17;
int switchA = 3;
int switchB = 4;

//FIRST CASE, SWITCH 00, OPTION 1---------------------------------------------------

if(digitalRead(switchA)==LOW){
  if(digitalRead(switchB)==LOW){
   //-----------------ALL OFF-----------
      PalatisSoftPWM.allOff();
      digitalWrite(13,LOW);
    }
  }

//SECOND CASE, SWITCH 01, OPTION 2---------------------------------------------------

if(digitalRead(switchA) ==LOW){
  if(digitalRead(switchB)==HIGH){
    PalatisSoftPWM.allOff();

    //MAKE 13 PULSE
    int brightness = 0;
    analogWrite(13,brightness);
    if(brightness ==0 || brightness < 255){
      analogWrite(13,brightness);
      brightness = brightness +1;
      delay(10);
    }
      else if(brightness <= 255 && brightness > 0){
        brightness = brightness -3;
        analogWrite(13,brightness);
        delay(5);
      }
    }   
  }

//THIRD CASE, SWITCH 10, OPTION 3--------------------------------------------------
if(digitalRead(switchA)==HIGH){
  if(digitalRead(switchB)==LOW){
    int MaxOn = 7;
    int TimeOn = random(500,2001);
    int RPin = LEDArray[random(0,18)];
    //if number of pins on is not > 7 or MaxOn-----HOW DO I EXPRESS THIS?
    //Trying to fade up/down on a random pin (((time for either total fade or fade up is TimeOn)))
    //I don't know how to say this using the "PlatisSoftPWM.set(channel_idx, value)" command
  }
}

  
}

agrady1995:
if number of pins on is not > 7 or MaxOn-----HOW DO I EXPRESS THIS?

if (numberOfPinsOn <= 7 || numberOfPinsOn <= MaxOn) {

agrady1995:
//Trying to fade up/down on a random pin (((time for either total fade or fade up is TimeOn)))
//I don’t know how to say this using the “PlatisSoftPWM.set(channel_idx, value)” command

This is how I did it in my code:

PalatisSoftPWM.set(PWMchannel, max(offBrightness, min(brightnessMax, round(initialBrightness[PWMchannel] + (float)(millis() - fadeTimestamp[PWMchannel]) / fadeDuration[PWMchannel] * (targetBrightness[PWMchannel] - initialBrightness[PWMchannel])))));

The ability to set offBrightness is useful because the jump in brightness is very dramatic at the lowest few brightness levels, which makes it impossible to do smooth fades from the LED being completely off. I found the solution for my project was to always leave the LEDs dimly on from the point from which a fade could be done smoothly.

NumberOfPinsOn is not a command recognized by my Arduino IDE... I don't know how to set it up so that this is a case.

Declare a global variable named NumberOfPinsOn (or whatever you want to call it) and then write your code so that whenever a pin is turned on that variable is incremented and whenever a pin is turned off that variable is decremented.

pert: ...write your code so that whenever a pin is turned on that variable is incremented and whenever a pin is turned off that variable is decremented.

How do I do this? I am trying to get it to fade a random pin, and have it ON for a random time, then pick another random pin.

I commented out pins 0 and 1 for debug and adjusted the object size accordingly. How would I set up a random pin fade?

The example for fading an LED using the PlatisSoft Library is not very well commented.

How is the debug useful for this example?

agrady1995: How would I set up a random pin fade?

PWMchannel = random(0, PalatisSoftPWM.size());
initialBrightness[PWMchannel] = targetBrightness[PWMchannel];
targetBrightness[PWMchannel] = random(offBrightness, brightnessMax);
fadeDuration[PWMchannel] = random(fadeDurationMin, fadeDurationMax + 1);
fadeTimestamp[PWMchannel] = millis();

agrady1995: How is the debug useful for this example?

You can use debug serial prints to tell you which part of your code is running and the values of variables

Thank you so much for your help. I have been very busy with work and school the last few days and haven’t had as much time for my project as I like. Hopefully this evening or tomorrow (I work again today) I will have some more time.

for the “PWMchannel = random(0,PalatisSoftPWM.size());” command, all of the channels have to be sequential correct?

for instance;
pin 2 = channel 0;
pin 3 = channel 1;
pin 5 = channel 2;

because the random command reads “PalatisSoftPWM.size” as just a number?

I’m going to read up on this and possibly post follow up questions later… This is a bit of info. Thank you for now though!

agrady1995: for the "PWMchannel = random(0,PalatisSoftPWM.size());" command, all of the channels have to be sequential correct?

Yes, that's correct. Generally it makes sense that they would be sequential since each channel can be set to an arbitrary pin. However, if you want you could put them in an array as you did with your LEDArray and this would allow them to be non-sequential. In that case the random number would be the index of the array and you would access the channel like as PWMchannelArray[PWMchannelIndex].

The only reason I can see for that is if you wanted to temporarily disable some channels, as you will probably do for pins 0 and 1 during development to allow for debug output. A more simple solution for that specific case is:

PWMchannel = random(2, PalatisSoftPWM.size());

Do I need.... :

if(digitalRead(switchA)==LOW){
  if(digitalRead(switchB)==LOW){
   //-----------------ALL OFF-----------
      PalatisSoftPWM.allOff();
      digitalWrite(13,LOW);    //Is this needed if pin 13 is defined under the PlatisSoftPWM channel list?
    }
  }

No need to do any digitalWrite() on your PWM channels.

Remember to set your NumberOfPinsOn variable to 0 when you call PalatisSoftPWM.allOff().

if(digitalRead(switchA)==LOW){
  if(digitalRead(switchB)==LOW){
   //-----------------ALL OFF-----------
      PalatisSoftPWM.allOff();
      analogWrite(13,LOW);    //Is this needed if pin 13 is defined under the PlatisSoftPWM channel list?
    }
  }

I already answered that.

So I more or less plugged this in:

//THIRD CASE, SWITCH 10, OPTION 3--------------------------------------------------
if(digitalRead(switchA)==HIGH){
  if(digitalRead(switchB)==LOW){
    digitalWrite(13,LOW);
    int MaxOn = 0;
    int TimeOn = random(500,2001);
    int RPin = LEDArray[random(0,18)];
    if(MaxOn <= 7){
    int PWMchannel = random(0, PalatisSoftPWM.size());
initialBrightness[PWMchannel] = targetBrightness[PWMchannel];
targetBrightness[PWMchannel] = random(offBrightness, brightnessMax);
fadeDuration[PWMchannel] = random(fadeDurationMin, fadeDurationMax + 1);
fadeTimestamp[PWMchannel] = millis();
  }
}

  
}

How can I tell this code to look for any pin that is on (all the time, ceaselessly) and if it is on, add a value of 1 to the variable MaxOn, while still doing other things?
what is initialBrightness and targetBrightness (array’s?) and how do I initialize them, and what even is their purpose? Why do I need a target brightness, and how do I use it and or initalize it? can’t I just set “offBrightness” to 0 and “brightnessMax” to 255 and that’ll be that? Won’t PWMchannel be a different random value every time you look at it with each new line? How do I set up fadeDuration as a command to fade the randomly selected pin? What is “fadeTimestamp” and why is it equal to a unit of time? It isn’t even being called to do anything.

agrady1995:
How can I tell this code to look for any pin that is on (all the time, ceaselessly) and if it is on, add a value of 1 to the variable MaxOn, while still doing other things?

Define what you mean by on. Is an LED on at brightness level 1, or does it need to be 255 to qualify as on?

agrady1995:
what is initialBrightness and targetBrightness (array’s?)

initialBrightness is the brightness of the LED at the start of the fade.
targetBrightness is the brightness of the LED at the end of the fade.
This allows the same code to be used to fade up and down. It also allows you to fade to arbitrary brightnesses, not only 0 or 255.

agrady1995:
how do I initialize them

They should be globals:
byte initialBrightness[PalatisSoftPWM.size()];
byte targetBrightness[PalatisSoftPWM.size()];
globals are always initialized to zero so you don’t need to explicitly initialize them.

agrady1995:
can’t I just set “offBrightness” to 0 and “brightnessMax” to 255 and that’ll be that?

If you mean “can I get rid of the initialBrightness and targetBrightness arrays and use offBrightness and brightnessMax instead?”. The answer is no, for the reasons I just explained.

If you mean “are offBrightness and brightnessMax necessary?”. The answer is no. Those are some enhanced features from my project. I have already explained the purpose of offBrightness in reply #1:

The ability to set offBrightness is useful because the jump in brightness is very dramatic at the lowest few brightness levels, which makes it impossible to do smooth fades from the LED being completely off. I found the solution for my project was to always leave the LEDs dimly on from the point from which a fade could be done smoothly.

In general I think the reason for brightnessMax in my code is that SOFTPWM_DEFINE_OBJECT_WITH_BRIGHTNESS_LEVELS() allows you to set the number of PWM levels so I wanted a variable so that if I changed the number of levels all my code would adjust accordingly, rather than me having to change every “magic number”. As far as the use of brightnessMax in the code I shared in #1, the purpose is to prevent the brightness from ever being set higher than the maximum brightness level, which would otherwise happen when fadeDuration was exceeded. I actually think this might be better:

PalatisSoftPWM.set(PWMchannel, max(offBrightness, min(targetBrightness[PWMchannel], round(initialBrightness[PWMchannel] + (float)(millis() - fadeTimestamp[PWMchannel]) / fadeDuration[PWMchannel] * (targetBrightness[PWMchannel] - initialBrightness[PWMchannel])))));

That will prevent the brightness from exceeding the targetBrightness.

agrady1995:
Won’t PWMchannel be a different random value every time you look at it with each new line?

It will be a different random value every time you set it to a different random value. Here’s how it works:

You have one part of your code that is the fader. This sets the brightness of each of the LEDs according to the initialBrightness, targetBrightness, fadeDuration, and fadeTimestamp values for that channel. That code should be run on every loop. You could do something like this:

for(byte PWMchannel = 0; PWMchannel < PalatisSoftPWM.size(); PWMchannel++) {
  PalatisSoftPWM.set(PWMchannel, max(offBrightness, min(targetBrightness[PWMchannel], round(initialBrightness[PWMchannel] + (float)(millis() - fadeTimestamp[PWMchannel]) / fadeDuration[PWMchannel] * (targetBrightness[PWMchannel] - initialBrightness[PWMchannel])))));
}

You also have some other code that is changing the values of initialBrightness, targetBrightness, fadeDuration, and fadeTimestamp to make different LEDs fade up or down. The decision of how you want to do this is up to you, that’s where the creative part of the project comes in. That’s the nice thing about setting up a general fading system that is completely separate from the code where you “script” the action of the LEDs. The thing you have to remember is that none of your code should block the continuous running of the fading code. This mean no use of delay() is allowed and no blocking while() loops. If you want to time things use millis(), as demonstrated by File > Examples > 02.Digital > BlinkWithoutDelay. I recommend using the fading system for all control of your LEDs. If you do things like PalatisSoftPWM.allOff(); without adjusting the initialBrightness, targetBrightness, fadeDuration, and fadeTimestamp values the fading code will have no knowledge that the LEDs have been turned off. It’s better to just use the fading system to turn them on or off. You can set fadeDuration to 1 for an effectively immediate action on the LEDs:

// turn all LEDs off immediately
for(byte PWMchannel = 0; PWMchannel < PalatisSoftPWM.size(); PWMchannel++) {
  targetBrightness[PWMchannel] = 0;
  fadeDuration[PWMchannel] = 1;
  //  in this case there is no need to set the timestamp because we want the fade to finish instantly
}

The code I provided you in reply #1 was somewhat simplified to answer your question without adding extra confusion. Actually I use it in a function that returns the brightness:

byte currentBrightness(const byte LEDinput) {
  if (fadeDuration[LEDinput] == 0) {  //set immediately to the target brightness to avoid divide by 0 issues
    return targetBrightness[LEDinput];
  }
  return max(offBrightness, min(targetBrightness[PWMchannel], round(initialBrightness[PWMchannel] + (float)(millis() - fadeTimestamp[PWMchannel]) / fadeDuration[PWMchannel] * (targetBrightness[PWMchannel] - initialBrightness[PWMchannel]))));
}

as you can see, this even efficiently handles the fadeDuration being set to 0 when you want an immediate change in brightness with no fading.

agrady1995:
How do I set up fadeDuration as a command to fade the randomly selected pin?

I already told you that:

pert:

PWMchannel = random(0, PalatisSoftPWM.size());

initialBrightness[PWMchannel] = targetBrightness[PWMchannel];
targetBrightness[PWMchannel] = random(offBrightness, brightnessMax);
fadeDuration[PWMchannel] = random(fadeDurationMin, fadeDurationMax + 1);
fadeTimestamp[PWMchannel] = millis();

agrady1995:
What is “fadeTimestamp” and why is it equal to a unit of time? It isn’t even being called to do anything.

You need to take some time to really look at the code and understand it fadeTimestamp certainly does play an essential role in the fading code. If you want to do a 1 second fade you need to know when the fade started to know when it should finish and what brightness should be set at each moment between the start and finish of the fade. That’s why you need to set a timestamp variable.

You said:

” If you do things like PalatisSoftPWM.allOff(); without adjusting the initialBrightness, targetBrightness, fadeDuration, and fadeTimestamp values the fading code will have no knowledge that the LEDs have been turned off. It’s better to just use the fading system to turn them on or off.”

And by that, I asuume that you mean this bit of code is the ‘fading system’:

” for(PWMchannel = 0; PWMchannel < PalatisSoftPWM.size(); PWMchannel++) {
PalatisSoftPWM.set(PWMchannel, max(offBrightness, min(targetBrightness[PWMchannel], round(initialBrightness[PWMchannel] + (float)(millis() - fadeTimestamp[PWMchannel]) / fadeDuration[PWMchannel] * (targetBrightness[PWMchannel] - initialBrightness[PWMchannel])))));
} “

This is one HUGE line of code (the second one) what is this saying, or rather, telling the Arduino to actually do? Could you please break this down for me?

How do I set up the fadeTimestamp, and what would all of this (code so far) look like?

agrady1995:
You said:And by that, I asuume that you mean this bit of code is the ‘fading system’:

That, and the arrays that it uses.

agrady1995:
This is one HUGE line of code (the second one) what is this saying, or rather, telling the Arduino to actually do? Could you please break this down for me?

It’s telling the Arduino to calculate what the brightness of each LED should be based on the parameters that you’ve set for that PWM channel:

  • initialBrightness
  • targetBrightness
  • fadeDuration
  • fadeTimestamp

Here’s an example: Let’s say you want to fade from brightness level 0 to brightness level 100 over 10 seconds. After 1 second the brightness should be 10. After 2 seconds, 20. After 3 seconds, 30. That’s all that equation is doing. The way timing works on Arduino is it keep track of how many milliseconds since it was turned on and we can access that value via millis(). So if you want to know how long it’s been since something started you save a timestamp, which is the value of millis() at that time. Then you can compare the current value of millis() to the timestamp value:

elapsedTime = millis() - timeStamp;

agrady1995:
How do I set up the fadeTimestamp, and what would all of this (code so far) look like?

Here’s a simple example sketch that fades pin 13 to random brightnesses over random durations:

#include <PalatisSoftPWM.h>

SOFTPWM_DEFINE_PIN13_CHANNEL(0);  // configure Arduino pin 13 as PWM channel 0

const byte PWMchannelCount = 1;
const byte PWMlevelsCount = 256;

SOFTPWM_DEFINE_OBJECT_WITH_PWM_LEVELS(PWMchannelCount, PWMlevelsCount)

const byte offBrightness = 4;

byte initialBrightness[PWMchannelCount];
byte targetBrightness[PWMchannelCount];
unsigned int fadeDuration[PWMchannelCount];
unsigned long fadeTimestamp[PWMchannelCount];

void setup() {
  Serial.begin(9600);
  while (!Serial) {}
  Serial.println(F("Starting Program"));
  PalatisSoftPWM.begin(60);  // begin with 60 Hz PWM frequency
}

void loop() {
  for (byte PWMchannel = 0; PWMchannel < PWMchannelCount; PWMchannel++) {
    const byte currentBrightnessValue = currentBrightness(PWMchannel);
    PalatisSoftPWM.set(PWMchannel, currentBrightnessValue);
    if (currentBrightnessValue == targetBrightness[PWMchannel]) { // fade is complete
      // set a new fade
      Serial.println(F("Starting new fade:"));
      initialBrightness[PWMchannel] = currentBrightnessValue;
      Serial.println(F("initialBrightness="));
      Serial.println(initialBrightness[PWMchannel]);
      targetBrightness[PWMchannel] = random(offBrightness, PWMlevelsCount);
      Serial.println(F("targetBrightness="));
      Serial.println(targetBrightness[PWMchannel]);
      fadeDuration[PWMchannel] = random(500, 3000);
      Serial.println(F("fadeDuration="));
      Serial.println(fadeDuration[PWMchannel]);
      fadeTimestamp[PWMchannel] = millis();
    }
  }
}

byte currentBrightness(const byte PWMchannel) {
  if (fadeDuration[PWMchannel] == 0) {  //set immediately to the target brightness to avoid divide by 0 issues
    return targetBrightness[PWMchannel];
  }
  return initialBrightness[PWMchannel] + (float)min(fadeDuration[PWMchannel], (millis() - fadeTimestamp[PWMchannel])) / fadeDuration[PWMchannel] * (targetBrightness[PWMchannel] - initialBrightness[PWMchannel]);
}

I simplified the fade equation a bit so hopefully it’s easier to understand now. The code is overboard for a single PWM channel but it’s written so that it will work with any number of PWM channels simply by adding new channel definitions and updating the value of PWMchannelCount accordingly, no extra code is necessary.

Beautiful, beautiful code! I have updated mine using your example and adding the channels accordingly. So far:

/* JOJO'S DRESS CODE
 *  This code is designed to connect the Arduino 328 (Lilypad clone)
 *  which contains 17 LED's (one red pin 13, and 16 on dress)
 *  Using 2 switches, a possibile 4 options can be built into this code. 
 *  
 *                     Mine are as follows: 
 *                       [-----------]
 *                       [   0 | 0   ]Option 1: No Lights
 *                       [   0 | 1   ]Option 2: HeartPulse only
 *                       [   1 | 0   ]Option 3: Starlight Fading random time, max 7 @ once
 *                       [   1 | 1   ]Option 4: Flash random pin, random (200,1000) max 7 @ once
 *                       [-----------]
 *                       
 *      A signifigant help in this project was thanks to "pert" on the Arduino Forums: https://forum.arduino.cc/index.php?action=profile;u=224903
 *      for providing me with loads of help in working with and understanding the PalatisSoft library and different coding techniques/tasks in general.
 */
#include <PalatisSoftPWM.h>

SOFTPWM_DEFINE_CHANNEL(0, DDRD, PORTD, PORTD0);  //Arduino pin 0 - this pin is used for Serial so you will be unable to use Serial in your sketch if you use it for PWM
SOFTPWM_DEFINE_CHANNEL(1, DDRD, PORTD, PORTD1);  //Arduino pin 1 - this pin is used for Serial so you will be unable to use Serial in your sketch if you use it for PWM
SOFTPWM_DEFINE_CHANNEL(2, DDRD, PORTD, PORTD2);  //Arduino pin 2
/***************************************************************
 * PINS 3 AND 4 ARE FOR SWITCH ON LILYPAD
 * *************************************************************
 */

SOFTPWM_DEFINE_CHANNEL(3, DDRD, PORTD, PORTD5);  //Arduino pin 5
SOFTPWM_DEFINE_CHANNEL(4, DDRD, PORTD, PORTD6);  //Arduino pin 6
SOFTPWM_DEFINE_CHANNEL(5, DDRD, PORTD, PORTD7);  //Arduino pin 7
SOFTPWM_DEFINE_CHANNEL(6, DDRB, PORTB, PORTB0);  //Arduino pin 8
SOFTPWM_DEFINE_CHANNEL(7, DDRB, PORTB, PORTB1);  //Arduino pin 9
SOFTPWM_DEFINE_CHANNEL(8, DDRB, PORTB, PORTB2);  //Arduino pin 10
SOFTPWM_DEFINE_CHANNEL(9, DDRB, PORTB, PORTB3);  //Arduino pin 11
SOFTPWM_DEFINE_CHANNEL(10, DDRB, PORTB, PORTB4);  //Arduino pin 12
//SOFTPWM_DEFINE_CHANNEL(11, DDRB, PORTB, PORTB5);  //Arduino pin 13
SOFTPWM_DEFINE_CHANNEL(11, DDRC, PORTC, PORTC0);  //Arduino pin A0
SOFTPWM_DEFINE_CHANNEL(12, DDRC, PORTC, PORTC1);  //Arduino pin A1
SOFTPWM_DEFINE_CHANNEL(13, DDRC, PORTC, PORTC2);  //Arduino pin A2
SOFTPWM_DEFINE_CHANNEL(14, DDRC, PORTC, PORTC3);  //Arduino pin A3
SOFTPWM_DEFINE_CHANNEL(15, DDRC, PORTC, PORTC4);  //Arduino pin A4
SOFTPWM_DEFINE_CHANNEL(16, DDRC, PORTC, PORTC5);  //Arduino pin A5

const byte PWMchannelCount = 17;
const byte PWMlevelsCount = 256;

SOFTPWM_DEFINE_OBJECT_WITH_PWM_LEVELS(PWMchannelCount, PWMlevelsCount)

const byte offBrightness = 4;

byte initialBrightness[PWMchannelCount];
byte targetBrightness[PWMchannelCount];
unsigned int fadeDuration[PWMchannelCount];
unsigned long fadeTimestamp[PWMchannelCount];

void setup() {
  Serial.begin(9600);
  while (!Serial) {}
  pinMode(3,INPUT);              //switch 1 on Lilypad for control of LED function
  pinMode(4,INPUT);             //switch 2 on Lilypad for control of LED function
  digitalWrite(3,LOW);         //Switch 1 Pulldown Resistor enabled to not steal precious power!
  digitalWrite(4,LOW);        //Switch 2 Pulldown Resistor enabled to not steal precious power!
  Serial.println(F("Starting Program"));
  PalatisSoftPWM.begin(60);  // begin with 60 Hz PWM frequency
}

void loop() {
  int switchA = 3;
int switchB = 4;
//FIRST CASE, SWITCH 00, OPTION 1---------------------------------------------------
if(digitalRead(switchA)==LOW){
  if(digitalRead(switchB)==LOW){
     analogWrite(13, 0);
        // turn all  [PalatisSoft] LEDs off immediately
     for(byte PWMchannel = 0; PWMchannel < PalatisSoftPWM.size(); PWMchannel++) {
     targetBrightness[PWMchannel] = 0;
     fadeDuration[PWMchannel] = 1;
       //  in this case there is no need to set the timestamp because we want the fade to finish instantly
     }
    }
   }
   //SECOND CASE, SWITCH 01, OPTION 2---------------------------------------------------
if(digitalRead(switchA) ==LOW){
  if(digitalRead(switchB)==HIGH){
     // turn all  [PalatisSoft] LEDs off immediately
     for(byte PWMchannel = 0; PWMchannel < PalatisSoftPWM.size(); PWMchannel++) {
     targetBrightness[PWMchannel] = 0;
     fadeDuration[PWMchannel] = 1;}
       //  in this case there is no need to set the timestamp because we want the fade to finish instantly
       //MAKE 13 PULSE
         int brightness = 0;
         analogWrite(13,brightness);
         if(brightness ==0 || brightness < 255){
            analogWrite(13,brightness);
           brightness = brightness +1;
            delay(10);}
            
            else if(brightness <= 255 || brightness > 0){
             brightness = brightness -3;
             analogWrite(13,brightness);
             delay(5);}
         }
        }

     //THIRD CASE, SWITCH 10, OPTION 3-------------------------------------------------- 
 if(digitalRead(switchA)==HIGH){
  if(digitalRead(switchB)==LOW){
    
  
      for (byte PWMchannel = 0; PWMchannel < PWMchannelCount; PWMchannel++) {
       const byte currentBrightnessValue = currentBrightness(PWMchannel);
        PalatisSoftPWM.set(PWMchannel, currentBrightnessValue);
        if (currentBrightnessValue == targetBrightness[PWMchannel]) { // fade is complete
                                                                       // set a new fade
      Serial.println(F("Starting new fade:"));
      initialBrightness[PWMchannel] = currentBrightnessValue;
      Serial.println(F("initialBrightness="));
      Serial.println(initialBrightness[PWMchannel]);
      targetBrightness[PWMchannel] = random(offBrightness, PWMlevelsCount);
      Serial.println(F("targetBrightness="));
      Serial.println(targetBrightness[PWMchannel]);
      fadeDuration[PWMchannel] = random(500, 3000);
      Serial.println(F("fadeDuration="));
      Serial.println(fadeDuration[PWMchannel]);
      fadeTimestamp[PWMchannel] = millis();
    }
  }


byte currentBrightness(const byte PWMchannel) {
  if (fadeDuration[PWMchannel] == 0) {  //set immediately to the target brightness to avoid divide by 0 issues
    return targetBrightness[PWMchannel];
  }
  return initialBrightness[PWMchannel] + (float)min(fadeDuration[PWMchannel], (millis() - fadeTimestamp[PWMchannel])) / fadeDuration[PWMchannel] * (targetBrightness[PWMchannel] - initialBrightness[PWMchannel]);
}
  }
 }
}

I have one problem (so far) with compiling, and that is that I get the error of “currentBrightness” was not declared (line 110). I didn’t have a problem with this when just compiling your example.

I was also wondering why “offBrightness” was set to 4. Why not 0 (all the way off)?

agrady1995: I have one problem (so far) with compiling, and that is that I get the error of "currentBrightness" was not declared (line 110). I didn't have a problem with this when just compiling your example.

Whenever you have a problem with your code you should always do a Tools > Auto Format and then check if the automatic indentation matches your expectations. This can frequently give you a very good clue to where the problem is in your code. If you look at the definition of the currentBrightness function after doing an Auto Format you will see this:

      byte currentBrightness(const byte PWMchannel) {
        if (fadeDuration[PWMchannel] == 0) {  //set immediately to the target brightness to avoid divide by 0 issues
          return targetBrightness[PWMchannel];
        }
        return initialBrightness[PWMchannel] + (float)min(fadeDuration[PWMchannel], (millis() - fadeTimestamp[PWMchannel])) / fadeDuration[PWMchannel] * (targetBrightness[PWMchannel] - initialBrightness[PWMchannel]);
      }
    }
  }
}

The beginning of a function should never be indented to that tells you there are some missing closing braces on the lines preceding the function.

agrady1995: I was also wondering why "offBrightness" was set to 4. Why not 0 (all the way off)?

I had explained that twice already:

pert: The ability to set offBrightness is useful because the jump in brightness is very dramatic at the lowest few brightness levels, which makes it impossible to do smooth fades from the LED being completely off. I found the solution for my project was to always leave the LEDs dimly on from the point from which a fade could be done smoothly.

If that feature is not of use to you it's very easy to remove now because I took it out of the fade equation to make it easier to understand.

I used auto format and still am having the same error. What am I supposed to indent/unindent? It appears as if I have all the closing braces properly placed...