Erratic Blink instead of Smooth Fade

I've just written a sketch (or I should say I've adapted a couple of existing sketches into one) to blink two leds at different rates to each other whilst fading two other leds at different speeds to each other.

However, one of the fading leds is not behaving as expected. In the attached sketch, the led designated led_F_Fade (on UNO pin 11) is not fading up and down, it is simply changing brightness to seemingly random levels unpredictably in a digital fashion.

I've double and triple checked the wiring, and all is connected properly and each element (jumper wires, breadboard, resistor and led) are all fine. If I change the pin allocation to a different pwm pin, it makes no difference.

I wonder if anyone could explain what sort of programming error I could have made for this to be occurring?


// Adapted from SeveralThingsAtTheSameTimeRev1.ino

//=======

// ----CONSTANTS (won't change)

// the pin numbers for the LEDs
const int onBoardLedPin =  13;
const int led_A_Blink = 8;
const int led_B_Blink = 9;
const int led_C_Fade = 10;
const int led_D_Fade = 11;
float value, value2;

// number of millisecs between blinks
const int led_A_Interval = 2500;
const int led_B_Interval = 4500;
const int period = 2000;
const int displace = 500;

// number of millisecs that Led's are on - both blinking leds use this
const int blinkDuration_onBoard = 500;
const int blinkDuration_A = 250;
const int blinkDuration_B = 150;

//------- VARIABLES (will change)
             
byte led_A_State = LOW;          // used to record whether the blinking LEDs are on or off
byte led_B_State = LOW;          // LOW = off

unsigned long time = 0;         // stores the value of time() in each iteration of loop()
unsigned long previousLed_A_time = 0; // will store last time the fading LED was updated
unsigned long previousLed_B_time = 0;

//========

void setup() {

  // set the Led pins as output:
  pinMode(led_A_Blink, OUTPUT);
  pinMode(led_B_Blink, OUTPUT);
  pinMode(led_C_Fade, OUTPUT);
  pinMode(led_D_Fade, OUTPUT);
}

//=======

void loop() {

  time = millis();   // capture the latest value of time()
  
  updateLed_A_State();
  updateLed_B_State();
  switchLeds();
  fadeLeds();
}

//=======

void updateLed_A_State() {

  if (led_A_State == LOW) {
    if (time - previousLed_A_time >= led_A_Interval) {
      led_A_State = HIGH;
      previousLed_A_time += led_A_Interval;
    }
  }
  else {
    if (time - previousLed_A_time >= blinkDuration_A) {
      led_A_State = LOW;
      previousLed_A_time += blinkDuration_A;
    }
  }
}

//=======

void updateLed_B_State() {

  if (led_B_State == LOW) {
    if (time - previousLed_B_time >= led_B_Interval) {
      led_B_State = HIGH;
      previousLed_B_time += led_B_Interval;
    }
  }
  else {
    if (time - previousLed_B_time >= blinkDuration_B) {
      led_B_State = LOW;
      previousLed_B_time += blinkDuration_B;
    }
  }
}

//========

void switchLeds() {
  // this is the code that actually switches the LEDs on and off
  digitalWrite(led_A_Blink, led_A_State);
  digitalWrite(led_B_Blink, led_B_State);
}

//=======

void fadeLeds() {
  // sine wave fading method
  value = 128 + 127 * cos(2 * PI / period * time);
  value2 = 128 + 127 * cos(5 * PI / period * (displace - time));
  analogWrite(led_C_Fade, value);           // sets the value (range from 0 to 255)
  analogWrite(led_D_Fade, value2);          // sets the value (range from 0 to 255)
}
//=====END

What method are you using to fade the LEDs? Are you changing the current value or are you changing the on/off ratio?

It's the duty cycle that's being altered each pass through the loop.
One led performs exactly as expected, the other doesn't for some reason.
If I edit out the blinking routine for the other two leds, the fading works on both the fader leds

Try

//value2 = 128 + 127 * cos(5 * PI / period * (displace - time));
value2 = 128 + 127 * cos(5* PI / period * (time - displace));

There is no such LED defined. Did you mean led_D_Fade?

const int led_D_Fade = 11;

Why don't you write value2 to the serial monitor so you can see what it contains?
value2 = 128 + 127 * cos(5 * PI / period * (displace - time));

1 Like

The return I get reading value2 reflects what I'm seeing. The value2 is jumping all over the place whereas value returns a smooth rise and fall.

value 2 seems to stick at a value for around 500ms then changes to a different value. ie 85.75 folleowed by 64.97 followed by 252.64, 65.63, 16.74 etc etc. It does seem to be rising and falling, but pausing every 1/2 second or so

displace is an integer... what happens when you subtract a number bigger than 32,767 ?

1 Like

Thanks @red_car that was it.
Changed (both period and) displace to float(s). Works just fine now. :+1:
Thinking about it, having the variable displace is a nice to have, rather than essential for the purpose I want this sketch for, so I could just remove it entirely.

However, I still don't understand why this section as a standalone gives no problem:

const int led_A_Pin = 12;
const int led_B_Pin = 11;


float value, value2 ;
int ledpin = 10;                           // light connected to digital pin 10
int ledpin2 = 11;                           // light connected to digital pin 11
long time=0;

int period = 2000;
int displace = 500;

void setup() 
{ 
  // nothing for setup 
} 

void loop() 
{ 
  time = millis();
  value = 128+127*cos(2*PI/period*time);
  value2 = 128+127*cos(5*PI/period*(displace-time));
  analogWrite(ledpin, value);           // sets the value (range from 0 to 255) 
  analogWrite(ledpin2, value2);           // sets the value (range from 0 to 255) 
}

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