PWM controlled led low frequency flicker

The project is an Arduino controlled led lighting system for rc plane.

I am trying to create an led strip that can be be controlled by an external remote (flysky ai6) in order to give an afterburner effect above 60% throttle, Also included in the code is 0 delay led flashes for strobe and beacon lights.

I have taken the receiver, by monitoring ch3 and getting the PWM input I am then applying the PWM (through a map()) to send the scaled PWM signal to the led strip.

The problem is after 10s or so of running the program the led strip will flicker very visibly at a low frequency, at any PWM duty cycle(brightness level) I input through the remote. The only solution is to reboot the board.

Is this to do with the code? hardware? (I doubt its to do with the standard led strip flicker due to a 50hz power supply as it only occurs after a period of time has past) code is posted below.

//this is strobe
const char ledPinstrobe = 7;

bool blinkingstrobe = true;
byte blinksstrobe = 0;

//fade beacon
int value = 2;
int ledpin = 6;
long time=0;
int periode = 2000;


//afterburner
int ch1; // create a value to keep the rc values
int valueab = 0;
int previoustime = 0;
int eventinterval = 50;

void setup() {


  // put your setup code here, to run once:
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  
  digitalWrite(4,HIGH);
  digitalWrite(2,HIGH);
  digitalWrite(8,HIGH);

    //afterburner
  pinMode(2,INPUT); // set what mode the pin is in
  Serial.begin(9600); // what does this do?
}

void loop() {

  //strobe
  static unsigned long lastEventstrobe;
  unsigned long topLoopstrobe = millis();
  if (blinkingstrobe) {
    if (topLoopstrobe - lastEventstrobe >= 50) {
      lastEventstrobe = topLoopstrobe;
      digitalWrite(ledPinstrobe, !digitalRead(ledPinstrobe));//short for "if (digitalRead(ledPin) == HIGH) { 
      //  digitalWrite(ledPin, LOW);
      //} else {
      //  digitalWrite(ledPin, HIGH);
      // }
      if (++blinksstrobe >= 4) {//if the last event was the top loop-850ms (off) it will blink on(50)-off(50)-on(50)-off(50)
        blinkingstrobe = false;
        blinksstrobe = 0;
        //reset millis()
      }
    }
  } else if (topLoopstrobe - lastEventstrobe >= 800) {//this 800 +4x50 =1000
    blinkingstrobe = true;
  }

    
    //beacon fade
time = millis();
  value = 128+127*cos(2*PI/periode*time);
  analogWrite(ledpin, value);           // sets the value (range from 0 to 255) 




  //afterburner
  unsigned long currenttime = millis();
  ch1 = pulseIn(2, HIGH ,25000); //read the width of each channel
  
if(currenttime - previoustime >= eventinterval){
  Serial.print("Channel 1:"); //tells the board to print the rc input value in the serial viewer
  Serial.print(ch1);
if (ch1>=1600){
  valueab = ch1;
  valueab = map(valueab, 1600,2000,0,255);
  analogWrite(5,valueab);                       //sets pwm value from 0 to 255 //led afterburner
  previoustime = currenttime;
}else{
  analogWrite(5,0);
    previoustime = currenttime;}

}
   
   
  }

Thank you for any help in advance.

Hi @tomtom12s,
I'm not sure what the problem could be. Maybe try adding a 0.1uf capacitor from pin 6 to ground.

I assume you mean between pin5 and ground...surely that would short circuit the board?

Whichever pin has the LEDs on it.

Hi @.
What range of values does this line generate?

value = 128 + 127 * cos(2 * PI / periode * time);

RV mineirin

Hi @tomtom12s .
Reviewing your sketch I found this excerpt from the program.

now see, if the value of valueab is > 2000, the map function will not change the value of valueb, and it will have values outside the range of 0 to 255, which will cause confusion in PWM.

RV mineirin

Hi, @tomtom12s

You may need to use this function.
https://www.arduino.cc/reference/en/language/functions/math/constrain/

Tom... :smiley: :+1: :coffee: :australia:

@ruilviana this the range for the beacon light (red) it provides a fade effect ranging from 0 to 255 for the analogWrite() this is separate part of code that doesn't control the led strip. the issue is only with the led strip.

The only code used for the led strip comes under a '//afterburner' description.

What range of values does this line generate?

value = 128 + 127 * cos(2 * PI / periode * time);

RV mineirin

@kgray9 I have tried a capacitor and it made no difference.

I have linked a video.yt video shows problem

Hi,
How are you powering the strip?
How are you powering t he Arduino, what model Arduino are you using?

A drawing of your project in the video would help.

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

@TomGeorge
I'm powering the strip using a mosfet irf520 and a 3s lipo battery
the Arduino is powered through laptop usb
the Arduino is a arduino uno rev3

i have also added in the constrain here... this did not stop the flickering that starts.:frowning:

 //afterburner
  unsigned long currenttime = millis();
  ch1 = pulseIn(2, HIGH ,25000); //read the width of each channel
  constrain(ch1,1000,2000);
if(currenttime - previoustime >= eventinterval){
  Serial.print("Channel 1:"); //tells the board to print the rc input value in the serial viewer
  Serial.print(ch1);
if (ch1>=1600){
  valueab = ch1;
  constrain(valueab,0,255);
  valueab = map(valueab, 1600,2000,0,255);
  analogWrite(5,valueab);                       //sets pwm value from 0 to 255 //led afterburner
  previoustime = currenttime;
}else{
  analogWrite(5,0);
    previoustime = currenttime;}

}

Hi .
That's not how @TomGeorge recommended it.
constrain(valueab,0,255);
test like this:

constrain(valueab,1600 , 200);

RV mineirin

@ruilviana
do you mean this ...?
if so then it hasn't worked.

`//afterburner
unsigned long currenttime = millis();
ch1 = pulseIn(2, HIGH ,25000); //read the width of each channel
if(currenttime - previoustime >= eventinterval){
Serial.print("Channel 1:"); //tells the board to print the rc input value in the serial viewer
Serial.print(ch1);
if (ch1>=1600){
valueab = ch1;
constrain(valueab,1600,2000);
valueab = map(valueab, 1600,2000,0,255);
analogWrite(5,valueab); //sets pwm value from 0 to 255 //led afterburner
previoustime = currenttime;
}else{
analogWrite(5,0);
previoustime = currenttime;}

}`

Hi .
no
thus:
valoreab = constrain (valoreab, 1600,2000);
RV mineirin

previoustime needs to be unsigned long instead of int.

@ruilviana @david_2018
thank you. the combination of those two has solved my problem so far I've been running the strip for a few minutes with no flickering :slight_smile:

Hi,
The IRF520 is not a logic level MOSFET.
It may not be switching completely ON and as it warms the gate characteristic changes.

IRF520 begins to turn ON at Vgs of 4V, so at 5V it is not completly on.

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

@TomGeorge Ok, thank you I shall get some logic level ones like a fqp30n06l for the finished product...

at the moment I'm developing a basic working code and hardware setup.(if interested I'm going to use 1206 SMD leds and an Arduino Nano for the final thing :slight_smile: )

You started this topic because your LEDs were flickering with low frequency. This could have been caused by your use of irf520 mosfets, or maybe there is some other reason. Don't wait and hope that using the logic level mosfets will fix the problem in the finished product. Start using them now in your prototype so you know for sure if that will fix the flickering or you still have a problem to fix!

1 Like