sketch critique

Hello, the following is a simple sketch to cycle the pwm of an LED from 0-255-0, and another LED 0-255-0 but at a different rate. The ultimate goal is RGB leds where the red changes at one rate, green at another , and blue at yet another so there a less noticable pattern. This sketch right now only controls 2, but as I write it for 3, I think it looks like a mess. What would a be a better method to explore? As a side note: This is the first sketch I have sat down and done start to finish without having to look up anything. I’m quite proud of it, so please be gentle.

// simple pwm sketch

//declare the pins
int led1=5;
int led2=6;
int led3=9;
int led4=10;
int led5=11;

//declare a few variables
boolean countUpLed1 = true;      // am i increasing or decreasing LED1
boolean countUpLed2 = true;      // increasing or decreasing LED2
int stepsLed1 = 0;            // keep count of the PWM value LED1
int stepsLed2 = 0;            // keep count of the PWM value LED2
long previousMillisLed1 = 0;  // previous millis for LED1
long previousMillisLed2 = 0;  // previous millis for LED2
long intervalLed1 = 5;       // interval to change LED1
long intervalLed2 = 10;      // interval to change LED2

//set pin modes
void setup(){
  Serial.begin(9600);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
}

void loop(){
  unsigned long currentMillisLed1 = millis();                    //       
  unsigned long currentMillisLed2 = millis();                    // test if it is time yet
  if (currentMillisLed1 - previousMillisLed1 > intervalLed1) {   //
    previousMillisLed1 = currentMillisLed1;
    if(countUpLed1 == true && stepsLed1 <= 254){  //counting up      
      Serial.println(stepsLed1);
      analogWrite(led1,stepsLed1);
      stepsLed1 = ++stepsLed1;  // increase the counter      
    }
    if (countUpLed1 == true && stepsLed1 == 255){
      Serial.println(stepsLed1);
      analogWrite(led1,stepsLed1);
      countUpLed1 = !countUpLed1;  // at 255 so now we change direction
      stepsLed1 = --stepsLed1;    // start decreasing the count
    }
    if (countUpLed1 == false && stepsLed1 >=1){
      Serial.println(stepsLed1);
      analogWrite(led1,stepsLed1);
      stepsLed1 = --stepsLed1;  // decrease count
    }
    if (countUpLed1 == false && stepsLed1 == 0){
      Serial.println(stepsLed1);
      analogWrite(led1,stepsLed1);
      countUpLed1 = !countUpLed1; // change direction again
      stepsLed1 = ++stepsLed1;  // increase count
    }
  }
  if (currentMillisLed2 - previousMillisLed2 > intervalLed2) {
    previousMillisLed2 = currentMillisLed2;
    if(countUpLed2 == true && stepsLed2 <= 254){
      Serial.println(stepsLed2);
      analogWrite(led2,stepsLed2);
      stepsLed2 = ++stepsLed2;
    }
    if (countUpLed2 == true && stepsLed2 == 255){
      Serial.println(stepsLed2);
      analogWrite(led2,stepsLed2);
      countUpLed2 = !countUpLed2;
      stepsLed2 = --stepsLed2;
    }
    if (countUpLed2 == false && stepsLed2 >=1){
      Serial.println(stepsLed2);
      analogWrite(led2,stepsLed2);
      stepsLed2 = --stepsLed2;
    }
    if (countUpLed2 == false && stepsLed2 == 0){
      Serial.println(stepsLed2);
      analogWrite(led2,stepsLed2);
      countUpLed2 = !countUpLed2;
      stepsLed2 = ++stepsLed2;
    }
  }
}
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);

5 pins for 2 RGB LEDs? Meaning names for the pin number (blueOne, redTwo, etc.) will make life easier. Why should you remember that the red LED is on pin 9 (or whatever). Let the IDE manage that.

int led1=5;
int led2=6;
int led3=9;
int led4=10;
int led5=11;

Oh wait. You did give them names (not great ones). Why aren’t you using the names?

long previousMillisLed1 = 0;  // previous millis for LED1
long previousMillisLed2 = 0;  // previous millis for LED2
  unsigned long currentMillisLed1 = millis();                    //       
  unsigned long currentMillisLed2 = millis();                    // test if it is time yet

Why are you mixing long and unsigned long? The correct type is unsigned long. The comment is wrong and silly.

    if(countUpLed1 == true && stepsLed1 <= 254){  //counting up      
      Serial.println(stepsLed1);
      analogWrite(led1,stepsLed1);
      stepsLed1 = ++stepsLed1;  // increase the counter      
    }
    if (countUpLed1 == true && stepsLed1 == 255){

You should nest the if statements.

if(countUpLed1)
{
   if(stepsLed1 < 255)
   {
   }
   else
   {
   }
}
else
{
}

Notice that the == true is not needed, and that the logic is much more obvious (at least to me).

Notice, too, that the code for dealing with the second LED is almost identical to the code for the first LED. This just cries out for a function that takes a few variables (pin numbers, etc.).

5 pins for 2 RGB LEDs? Meaning names for the pin number (blueOne, redTwo, etc.) will make life easier. Why should you remember that the red LED is on pin 9 (or whatever). Let the IDE manage that.

Yeah that was me adding more leds to see how I would do the code. They can be omitted from the sketch. As for the name, I don’t care which is red, blue or green. I want them to all cycle. But point taken and I’ll start that habit now.

long previousMillisLed1 = 0;  // previous millis for LED1
long previousMillisLed2 = 0;  // previous millis for LED2
  unsigned long currentMillisLed1 = millis();                    //       
  unsigned long currentMillisLed2 = millis();                    // test if it is time yet

Why are you mixing long and unsigned long? The correct type is unsigned long. The comment is wrong and silly.

Because this is how the “blink without delay” tutorial is written. I assumed it was correct.

    if(countUpLed1 == true && stepsLed1 <= 254){  //counting up      
      Serial.println(stepsLed1);
      analogWrite(led1,stepsLed1);
      stepsLed1 = ++stepsLed1;  // increase the counter      
    }
    if (countUpLed1 == true && stepsLed1 == 255){

You should nest the if statements.

Will do.

if(countUpLed1)
{
   if(stepsLed1 < 255)
   {
   }
   else
   {
   }
}
else
{
}

Notice that the == true is not needed, and that the logic is much more obvious (at least to me).

I didn’t know I could to that. That will help alot.

Notice, too, that the code for dealing with the second LED is almost identical to the code for the first LED. This just cries out for a function that takes a few variables (pin numbers, etc.).

Then functions are where I’m heading next. Thank you, thats actually given me a few things to explore that seem to be a logical progression.

void loop(){
  unsigned long currentMillisLed1 = millis();

As i rework this with the above suggestions, I am questioning this. Why would/should I create the variable inside void loop() instead of outside the function?

a_m_922:

void loop(){

unsigned long currentMillisLed1 = millis();




As i rework this with the above suggestions, I am questioning this. Why would/should I create the variable inside void loop() instead of outside the function?

I think it's because outside of the function implies a global variable and you really only want to use it locally?

Brad.

Is this better? Not looking for perfect yet, just aiming for clarity.

void loop(){
	unsigned long currentMillisLed1 = millis();					       
	unsigned long currentMillisLed2 = millis();					
  if (currentMillisLed1 - previousMillisLed1 > intervalLed1) {	
    previousMillisLed1 = currentMillisLed1;
    if(countUpLed1)							// verify we are counting up
		{     
		Serial.println(stepsLed1);				// print what step it is on
		analogWrite(led1,stepsLed1);			        // adjust the PWM to the LED
			if (stepsLed1 == 255)				// test if at 255
				{
				countUpLed1 = !countUpLed1;	// if at 255, reverse direction
				stepsLed1 = --stepsLed1;		// begin counting down
				}
			else							// if not at 255
				{
				stepsLed1 = ++stepsLed1;		// keep counting up	
				}
		}
    }
	
	if(!countUpLed1)							// test if counting down
		{
		Serial.println(stepsLed1);				// print what step it is on
		analogWrite(led1,stepsLed1);			        // adjust the PWM to the LED
			if(stepsLed1 == 0)				// test if a zero
				{
				countUpLed1 = !countUpLed1;	// if at 0, reverse direction
				stepsLed1 = ++stepsLed1;		// begin counting up
				}
			else							// if not at 0
				{
				stepsLed1 = --stepsLed1;		// keep counting down
				}
		}
}

Edit: I wrote this using Notepad++, is that why the whitespace looks odd when pasted here?

a_m_922:

Why are you mixing long and unsigned long? The correct type is unsigned long. The comment is wrong and silly.

Because this is how the “blink without delay” tutorial is written. I assumed it was correct.

No, the tutorial is wrong. Pity we tell everyone to look at it.

You can use the auto-format in the IDE to get a better result:

void loop(){
  unsigned long currentMillisLed1 = millis();					       
  unsigned long currentMillisLed2 = millis();					
  if (currentMillisLed1 - previousMillisLed1 > intervalLed1) {	
    previousMillisLed1 = currentMillisLed1;
    if(countUpLed1)							// verify we are counting up
    {     
      Serial.println(stepsLed1);				// print what step it is on
      analogWrite(led1,stepsLed1);			        // adjust the PWM to the LED
      if (stepsLed1 == 255)				// test if at 255
      {
        countUpLed1 = !countUpLed1;	// if at 255, reverse direction
        stepsLed1 = --stepsLed1;		// begin counting down
      }
      else							// if not at 255
      {
        stepsLed1 = ++stepsLed1;		// keep counting up	
      }
    }
  }

  if(!countUpLed1)							// test if counting down
  {
    Serial.println(stepsLed1);				// print what step it is on
    analogWrite(led1,stepsLed1);			        // adjust the PWM to the LED
    if(stepsLed1 == 0)				// test if a zero
    {
      countUpLed1 = !countUpLed1;	// if at 0, reverse direction
      stepsLed1 = ++stepsLed1;		// begin counting up
    }
    else							// if not at 0
    {
      stepsLed1 = --stepsLed1;		// keep counting down
    }
  }
}

These comments are just annoying:

    if(stepsLed1 == 0)				// test if a zero

Make the comment tell you something. It’s like putting:

a = 1;  // move 1 to a

These comments are just annoying:

As long as the comments are correct, I’d rather see them in there. It shows, at least, that the programmer understands the basics. I know that, with time, the programmer will stop putting the obvious comments in.

        stepsLed1 = ++stepsLed1;		// keep counting up

This, on the other hand, shows that the programmer does not understand the basics. OP, you need to understand just what ++n and n++ do, and when to use each one. They are not interchangeable in all cases. They also do not need to have the result assigned to the variable that the ++ operator (pre-fix or post-fix) modifies.

It can be helpful to use upper case characters in constant names. It's fairly conventional and allows you to distinguish constants from variables more easily when looking through code.

Also, though not essential, I would declare the LED constants 'const'. It prevents you from accidentally assigning to them. So I would change these:

int led1=5;
int led2=6;
int led3=9;
int led4=10;
int led5=11;

... to:

const int LED_1 = 5;
const int LED_2 = 6;
const int LED_3 = 9;
const int LED_4 = 10;
const int LED_5 = 11;

I would put an underscore between 'LED' and the number because I think it helps readability, but that's just personal taste.

As someone else has pointed out, the names could be improved. It would be better if the names reflected what the LEDs were for, or their colours etc. to avoid the extra level of mental translation that you have to do.

I don't think you need to call millis() twice at the start of loop(), do you? You could do this:

void loop() {
unsigned long currentMillis = millis();

... and use the one value in the calculation for both LEDs.

It's fairly conventional and allows you to distinguish constants from variables more easily when looking through code.

Actually, the convention is that all upper case names are reserved for #define names. Mixed case names are variables (const or otherwise).

Write a state machine and get rid of all the code :grin:

You have six values that are doing one of two different things -- going up or going down. Ignore the LED completely. It's all just data. It can be done as a for-loop and a couple (as in, probably exactly two) if-then-else statements.

And it generalizes to a zillion LEDs! (or 20-something if you use an ATmega 2560 or so).

        stepsLed1 = ++stepsLed1;		// keep counting up

This, on the other hand, shows that the programmer does not understand the basics. OP, you need to understand just what ++n and n++ do, and when to use each one. They are not interchangeable in all cases. They also do not need to have the result assigned to the variable that the ++ operator (pre-fix or post-fix) modifies.

My understanding is that ++n increments n before returning the value, and n++ returns n then increments. Correct? And I like that I can do ++n instead of n = ++n. It flows much better that way.

I don't think you need to call millis() twice at the start of loop(), do you? You could do this:

void loop() {
unsigned long currentMillis = millis();

... and use the one value in the calculation for both LEDs.

Since it replaces the currentMillis in the first loop, wouldn't it throw off the 2nd interval using
the same currentMillis variable?

Write a state machine and get rid of all the code

You have six values that are doing one of two different things -- going up or going down. Ignore the LED completely. It's all just data. It can be done as a for-loop and a couple (as in, probably exactly two) if-then-else statements.

And it generalizes to a zillion LEDs! (or 20-something if you use an ATmega 2560 or so).

This looks like more than I can tackle just yet. Looking at the replies, I haven't even mastered using comments...

My understanding is that ++n increments n before returning the value, and n++ returns n then increments. Correct?

Yes.

And I like that I can do ++n instead of n = ++n. It flows much better that way.

Good. Because it looks better, too. The postfix operator is the more normally used version, if the actual value doesn't matter. In the case of ++n; or n++; the actual value of n doesn't matter, so n++ is usually used.

In the case of buff[n++] = 0; or buff[++n] = 1, the actual value of n does matter, so you need to choose prefix or postfix notation carefully.

Looking at the replies, I haven't even mastered using comments...

You are doing a good job as a beginner using comments. When I try to teach something, like flying a hot-air balloon, I always ask my students to talk continuously. Knowing what they are thinking, or planning to do, before they do it gives me an opportunity to offer alternatives if I think appropriate. Without knowing what the student is think, or what decisions they are making, I can't do that.

Your comments are like you talking continuously about what you are doing, and are a good thing. After a while, you'll learn what comments are useful, and which aren't.

I've got this working and I think it is much improved from where I began. My semi-final version if directly below. Works great, exactly as I expect. But if I delete or comment out the serial.print lines it stops fading down. It will gradually go from off to full bright, then immed. back to off. Can you see what I'm missing or at least give me nudge in a direction?
Edit: Non-working code in next post due to length.

Working sketch

// simple pwm sketch

//declare the pins
const int BlueLed=5;
const int GreenLed=6;
const int RedLed=9;

//declare a few variables
boolean BlueLedCountUp = true;								// am i increasing or decreasing BlueLed
boolean GreenLedCountUp = true;				                // increasing or decreasing GreenLed
boolean RedLedCountUp = true;								// increasing or decreasing RedLed
int BlueLedSteps = 0;						        		// keep count of the PWM value BlueLed
int GreenLedSteps = 0;						        		// keep count of the PWM value GreenLed
int RedLedSteps = 0;										// keep count of the PWM value RedLed
unsigned long previousMillisBlueLed = 0;					// previous millis for BlueLed
unsigned long previousMillisGreenLed = 0;					// previous millis for GreenLed
unsigned long previousMillisRedLed = 0;					// previous millis for RedLed
long BlueLedInterval = 5;					                // interval to change BlueLed
long GreenLedInterval = 10;					                // interval to change GreenLed
long RedLedInterval = 15;									// interval to change RedLed

//set pin modes
void setup(){
  Serial.begin(9600);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(9,OUTPUT);
}

void loop(){
	unsigned long currentMillisBlueLed = millis();					       
	unsigned long currentMillisGreenLed = millis();
	unsigned long currentMillisRedLed = millis();
	
  if (currentMillisBlueLed - previousMillisBlueLed > BlueLedInterval) {	
    previousMillisBlueLed = currentMillisBlueLed;
    if(BlueLedCountUp)							// verify we are counting up
    {     
      Serial.println(BlueLedSteps);			        	// print what step it is on
      analogWrite(BlueLed,BlueLedSteps);			                // adjust the PWM to the LED
      if (BlueLedSteps == 255)				                // test if at 255
      {
        BlueLedCountUp = !BlueLedCountUp;		                        // if at 255, reverse direction
        BlueLedSteps--;		                                        // begin counting down
      }
      else								// if not at 255
      {
        BlueLedSteps++;		                                        // keep counting up	
      }
    }
  }

  if(!BlueLedCountUp)							// test if counting down
  {
    Serial.println(BlueLedSteps);				                // print what step it is on
    analogWrite(BlueLed,BlueLedSteps);			                // adjust the PWM to the LED
    if(BlueLedSteps == 0)					                // test if a zero
    {
      BlueLedCountUp = !BlueLedCountUp;		                        // if at 0, reverse direction
      BlueLedSteps++;		                                        // begin counting up
    }
    else								// if not at 0
    {
      BlueLedSteps--;		                                        // keep counting down
    }
  }
  if (currentMillisGreenLed - previousMillisGreenLed > GreenLedInterval) {	
    previousMillisGreenLed = currentMillisGreenLed;
    if(GreenLedCountUp)							// verify we are counting up
    {     
      Serial.println(GreenLedSteps);				        // print what step it is on
      analogWrite(GreenLed,GreenLedSteps);			                // adjust the PWM to the LED
      if (GreenLedSteps == 255)				                // test if at 255
      {
        GreenLedCountUp = !GreenLedCountUp;		                        // if at 255, reverse direction
        GreenLedSteps--;		                                        // begin counting down
      }
      else								// if not at 255
      {
        GreenLedSteps++;		                                        // keep counting up	
      }
    }
  }

  if(!GreenLedCountUp)							// test if counting down
  {
    Serial.println(GreenLedSteps);				                // print what step it is on
    analogWrite(GreenLed,GreenLedSteps);			                // adjust the PWM to the LED
    if(GreenLedSteps == 0)					                // test if a zero
    {
      GreenLedCountUp = !GreenLedCountUp;		                        // if at 0, reverse direction
      GreenLedSteps++;		                                        // begin counting up
    }
    else								// if not at 0
    {
      GreenLedSteps--;		                                        // keep counting down
    }
  }
  if (currentMillisRedLed - previousMillisRedLed > RedLedInterval) {	
    previousMillisRedLed = currentMillisRedLed;
    if(RedLedCountUp)							// verify we are counting up
    {     
      Serial.println(RedLedSteps);				        // print what step it is on
      analogWrite(RedLed,RedLedSteps);			                // adjust the PWM to the LED
      if (RedLedSteps == 255)				                // test if at 255
      {
        RedLedCountUp = !RedLedCountUp;		                        // if at 255, reverse direction
        RedLedSteps--;		                                        // begin counting down
      }
      else								// if not at 255
      {
        RedLedSteps++;		                                        // keep counting up	
      }
    }
  }

  if(!RedLedCountUp)							// test if counting down
  {
    Serial.println(RedLedSteps);				                // print what step it is on
    analogWrite(RedLed,RedLedSteps);			                // adjust the PWM to the LED
    if(RedLedSteps == 0)					                // test if a zero
    {
      RedLedCountUp = !RedLedCountUp;		                        // if at 0, reverse direction
      RedLedSteps++;		                                        // begin counting up
    }
    else								// if not at 0
    {
      RedLedSteps--;		                                        // keep counting down
    }
  }
}

Non-working

// simple pwm sketch

//declare the pins
const int BlueLed=5;
const int GreenLed=6;
const int RedLed=9;

//declare a few variables
boolean BlueLedCountUp = true;								// am i increasing or decreasing BlueLed
boolean GreenLedCountUp = true;				                // increasing or decreasing GreenLed
boolean RedLedCountUp = true;								// increasing or decreasing RedLed
int BlueLedSteps = 0;						        		// keep count of the PWM value BlueLed
int GreenLedSteps = 0;						        		// keep count of the PWM value GreenLed
int RedLedSteps = 0;										// keep count of the PWM value RedLed
unsigned long previousMillisBlueLed = 0;					// previous millis for BlueLed
unsigned long previousMillisGreenLed = 0;					// previous millis for GreenLed
unsigned long previousMillisRedLed = 0;					// previous millis for RedLed
long BlueLedInterval = 5;					                // interval to change BlueLed
long GreenLedInterval = 10;					                // interval to change GreenLed
long RedLedInterval = 15;									// interval to change RedLed

//set pin modes
void setup(){
//  Serial.begin(9600);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(9,OUTPUT);
}

void loop(){
	unsigned long currentMillisBlueLed = millis();					       
	unsigned long currentMillisGreenLed = millis();
	unsigned long currentMillisRedLed = millis();
	
  if (currentMillisBlueLed - previousMillisBlueLed > BlueLedInterval) {	
    previousMillisBlueLed = currentMillisBlueLed;
    if(BlueLedCountUp)							// verify we are counting up
    {     
//      Serial.println(BlueLedSteps);			        	// print what step it is on
      analogWrite(BlueLed,BlueLedSteps);			                // adjust the PWM to the LED
      if (BlueLedSteps == 255)				                // test if at 255
      {
        BlueLedCountUp = !BlueLedCountUp;		                        // if at 255, reverse direction
        BlueLedSteps--;		                                        // begin counting down
      }
      else								// if not at 255
      {
        BlueLedSteps++;		                                        // keep counting up	
      }
    }
  }

  if(!BlueLedCountUp)							// test if counting down
  {
//    Serial.println(BlueLedSteps);				                // print what step it is on
    analogWrite(BlueLed,BlueLedSteps);			                // adjust the PWM to the LED
    if(BlueLedSteps == 0)					                // test if a zero
    {
      BlueLedCountUp = !BlueLedCountUp;		                        // if at 0, reverse direction
      BlueLedSteps++;		                                        // begin counting up
    }
    else								// if not at 0
    {
      BlueLedSteps--;		                                        // keep counting down
    }
  }
  if (currentMillisGreenLed - previousMillisGreenLed > GreenLedInterval) {	
    previousMillisGreenLed = currentMillisGreenLed;
    if(GreenLedCountUp)							// verify we are counting up
    {     
//      Serial.println(GreenLedSteps);				        // print what step it is on
      analogWrite(GreenLed,GreenLedSteps);			                // adjust the PWM to the LED
      if (GreenLedSteps == 255)				                // test if at 255
      {
        GreenLedCountUp = !GreenLedCountUp;		                        // if at 255, reverse direction
        GreenLedSteps--;		                                        // begin counting down
      }
      else								// if not at 255
      {
        GreenLedSteps++;		                                        // keep counting up	
      }
    }
  }

  if(!GreenLedCountUp)							// test if counting down
  {
//    Serial.println(GreenLedSteps);				                // print what step it is on
    analogWrite(GreenLed,GreenLedSteps);			                // adjust the PWM to the LED
    if(GreenLedSteps == 0)					                // test if a zero
    {
      GreenLedCountUp = !GreenLedCountUp;		                        // if at 0, reverse direction
      GreenLedSteps++;		                                        // begin counting up
    }
    else								// if not at 0
    {
      GreenLedSteps--;		                                        // keep counting down
    }
  }
  if (currentMillisRedLed - previousMillisRedLed > RedLedInterval) {	
    previousMillisRedLed = currentMillisRedLed;
    if(RedLedCountUp)							// verify we are counting up
    {     
//      Serial.println(RedLedSteps);				        // print what step it is on
      analogWrite(RedLed,RedLedSteps);			                // adjust the PWM to the LED
      if (RedLedSteps == 255)				                // test if at 255
      {
        RedLedCountUp = !RedLedCountUp;		                        // if at 255, reverse direction
        RedLedSteps--;		                                        // begin counting down
      }
      else								// if not at 255
      {
        RedLedSteps++;		                                        // keep counting up	
      }
    }
  }

  if(!RedLedCountUp)							// test if counting down
  {
//    Serial.println(RedLedSteps);				                // print what step it is on
    analogWrite(RedLed,RedLedSteps);			                // adjust the PWM to the LED
    if(RedLedSteps == 0)					                // test if a zero
    {
      RedLedCountUp = !RedLedCountUp;		                        // if at 0, reverse direction
      RedLedSteps++;		                                        // begin counting up
    }
    else								// if not at 0
    {
      RedLedSteps--;		                                        // keep counting down
    }
  }
}

And one other question. If

if(BlueLedCountUp == true)

can be

if(BlueLedCountUp)

and

BlueLedSteps = ++BlueLedSteps

can be

BlueLedSteps++

why won't

BlueLedCountUp = !BlueLedCountUp

replaced with

!BlueLedCountUp

work?

if ( BlueLedCountUp )

Anything zero is 'false'.
Anything non false while not 'exactly' true can be considered not 'false'

!BlueLedCountUp

Doesn't modify 'BlueLedCountUp' it only evaluates it.

Well, why doesn't

BlueLedSteps++

just evaluate it too? That's the question.

I suppose the answer is "that's the way C/C++ works".

Probably in the early days the authors of C wanted to make a couple of features that could translate into machine code, like the old INC and DEC instructions in assembler. (That incremented and decremented a variable by one). This would be frequently used in loops which count things.

Thus you have the rather strange feature of foo++ which not only adds 1 to foo, it changes foo as well. This unfortunately gives the ability to have expressions which modify the "right-hand side", eg.

a = b++;  // a takes the value of b, b gets one added to it

You can also get undefined behaviour like:

c = a++ + ++a + ++a + ++a;

I believe there is no defined place here for when a gets incremented (eg. is it in the middle of the expression, at the start, at the end, etc.?).

You can also get undefined behaviour like:

There is nothing undefined about it. The expression is evaluated left to right, in the absence of parentheses.

So, with

c = a++ + ++a + ++a + ++a;

a is used, then incremented. Then a is incremented and used, three times. If a starts at 0, it will end at 4, and the expression will be c = 0 + 2 + 3 + 4.