Arduino PWM for 12V LED Lights

I am trying to do a sunrise/sunset led light effect for my aquariums. I found the code online and it looks like it's working very well. But the light is flickering. I bought these 2 MOSFETS(picture and description in the image below), but the light is flickering. On 1 MOSFET I am using Pin 6 and the ground pin and on the other MOSFET I am using the 5V, pin6 for pwm and ground. Power is through another power supply and tried attaching the ground together but it still flickers. I tried using a 12V 50W Power supply which would be enough to power a 6W led light and the arduino. Any ideas what could be the problem?

http://forum.arduino.cc/index.php?topic=219680.0

That is the link of where I code the code from.

Show a schematic and an image of the wiring.

.

Here is a simple circuit diagram. Pin6 and Ground are going to the MOSFET Board. Than the external 12V power supply is connected to the input power of the MOSFET Board and the ground is connected to the Arduino's ground. The output is connected to the 6W LEDs.

If the MOSFETs are IRF520 these are not recommended as they are not logic level switchable.

What do you mean by flicker?

.

Question regarding flickering:

Is the flickering continuous (like looking at a bulb through a fan)?

Or is it more random like a loose wire? (not suggesting your problem is a loose wire.)

LarryD is of course correct regarding the IRF520 but if you have a light enough load you can usually get by. A good test would be to change the "PWM signal to the MOSFET module" to a pin on the arduino that is always 5V. If the LED's stay on all the time then you have a good chance you can get by with the 4.? volts the arduino is able to supply. I say good chance because depending on your PWM frequency and desired dutycycle you may have some dynamic issues.

Two other questions:

  1. Can you better explain your statement "on the other MOSFET I am using the 5V, pin6 for pwm and ground"?

  2. this may seem far out but... can fish sense PWM at a higher frequency than humans. Even if you can't see the flicker would it bother the fish. Sounds far out but think of how dogs can hear things we cannot.

JohnRob

LarryD:
What do you mean by flicker?

I am seeing the light switching from on to off to on at a high frequency from when it starts the "sunrise" till the "sunset".

JohnRob:
Question regarding flickering:

Is the flickering continuous (like looking at a bulb through a fan)?

Or is it more random like a loose wire? (not suggesting your problem is a loose wire.)

Flickering is continuous from the sunset till sunrise and yes exactly like looking at a bulb through a fan.

JohnRob:
LarryD is of course correct regarding the IRF520 but if you have a light enough load you can usually get by. A good test would be to change the "PWM signal to the MOSFET module" to a pin on the arduino that is always 5V. If the LED's stay on all the time then you have a good chance you can get by with the 4.? volts the arduino is able to supply. I say good chance because depending on your PWM frequency and desired dutycycle you may have some dynamic issues.

Two other questions:

  1. Can you better explain your statement "on the other MOSFET I am using the 5V, pin6 for pwm and ground"?

I am trying an IRF520 and an AOD4184A MOSFET. The IRF520 has 3 inputs. 1 5V, 1 Ground and 1 PWM signal. The AOD4184A has 2 inputs. 1 Ground and 1 PWM.

I tried using the AOD4184A and used 5V and a ground, and the light did not flicker.

Data sheet of AOD4184A: http://www.aosmd.com/pdfs/datasheet/AOD4184A.pdf

Code I am using:

/* Aquarium Light Controller

Written by John Dimo

Sets turn on time, turn off time, power loss failsafe, adjustable sunset/sunrise
times, smooth fading LED on/off, override button, max brightness control,etc.

Arduino Pin 6 is the output for lights.
Arduino Pin 12 is for the override button.
Arduino Pins A0 and A1 are for the RTC module.

Version 1.0 - Initial Version. Basic light timer, with adjustable 
              ramp up/down and total running time.
Version 1.1 - Added code for LCD display to show diagnostic messages.
Version 1.2 - Added adjustable max brightness control.
Version 1.3 - Removed all the delays so that code can loop through and do other 
              stuff during sunrise and sunset timing code.
Version 1.4 - Added Override Button to turn lights on and off.
Version 1.5 - Added RTC module. Now has daily adjustable start time.
Version 1.6 - Added alarm for daily adjustable off time. Added failsafe to restart
              lights in the event of power loss.
Version 1.7 - Added smooth on/off for the lights when using override button or
              when recovering from power loss.

*////////////////////////////////////////////////////////////////////
// user adjustable timing
int rampTime = 5; //Time in minutes to turn on/off the lights
int maxBrightness = 100; //Brightness in percentage
byte alarmOn[] = {12, 00}; // set the hour and minutes to start and stop the
byte alarmOff[] = {19, 00}; // timer, must use 24 hour time format
//////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////
/////// Change nothing below here !!! ////////////////////////////
//////////////////////////////////////////////////////////////////
#include <Time.h>  
#include <Wire.h>  
#include <DS1307RTC.h>

// global variables
int stage = 0; // set initial timing stage
int buttonState;
int lastbuttonState = HIGH;
unsigned long oldButtontime = 0;
unsigned long oldRamptime = 0;
int lightOutput = 0;
int lightSetpoint = 0;
int overridelights = LOW;

//setup loop
void setup() {
  
  ///////////////////////////////
  // Setup some pins to power the RTC. Will not be needed when building the board
  //pinMode(A3, OUTPUT); 
  //digitalWrite(A3, HIGH);
  //pinMode(A2, OUTPUT);
  //digitalWrite(A2, LOW);
  ////////////////////////////////////////////
  
  setSyncProvider(RTC.get); // tell code to get the time from RTC
  pinMode(6, OUTPUT); //setup the output pin
  pinMode(12, INPUT); // setup the input button
  pinMode(13, OUTPUT); //temp diagnostic LED
  maxBrightness = map(maxBrightness,0,100,0,255); // Map percentage to output range.
  rampTime = rampTime * 60000 / maxBrightness; // Setup ramptime delay based on max brightness setting
  
  //setup fail safe to restart lights during lights ON stage.
  if (word(hour(), minute()) >= word(alarmOn[0],alarmOn[1])) { 
    if (word(hour(), minute()) <= word(alarmOff[0],alarmOff[1])){
      lightSetpoint = maxBrightness;
      stage = 2;
    }
  }
}

//main program loop
void loop() {
  unsigned long currentTime = millis(); //set current time
  
  //override button code. ignores if you hold button down. handles hardware debounce
  int reading = digitalRead(12); 
  if (reading != lastbuttonState) { 
    oldButtontime = currentTime;
  }
  if (currentTime - oldButtontime > 50) {
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == LOW) {
        //This is the part of code that does something when button is pressed
        overridelights = !overridelights; // toggle the override
      }
    }
  }
  lastbuttonState = reading; // update the state of the button
  
  //Diagnostic LED to if we're in manual override mode or not.
  if (overridelights == HIGH) digitalWrite(13, HIGH); 
  if (overridelights == LOW) digitalWrite(13, LOW);
  
  // Stage 0. Waiting for alarm that starts lighting cycle
  if (stage == 0 && (hour() == alarmOn[0]) && (minute() == alarmOn[1])) stage = 1;
    
  // Stage 1. Sunrise Code.
  if (stage == 1 && currentTime - oldRamptime > rampTime) {
    oldRamptime = currentTime;
    lightSetpoint++;
    if (lightSetpoint == maxBrightness) stage = 2;
  }
  
  // Stage 2. Waiting for alarm that stops lighting cycle.
  if (stage == 2 && (hour() == alarmOff[0]) && (minute() == alarmOff[1])) {
    stage = 3;
  }
  
  // Stage 3. Sunset Code.
  if (stage == 3 && currentTime - oldRamptime > rampTime) {
    oldRamptime = currentTime;
    lightSetpoint--;
    if (lightSetpoint == 0) stage = 0;
  }
  
  //During lights ON stages, override turns off lights
  if (stage != 0 && overridelights == HIGH) {
    for(lightOutput; lightOutput >= 0; lightOutput--) {
      analogWrite(6, lightOutput);
      delay(4);
    }
    lightOutput = 0;
  }
  
  //During lights ON stages, set lights to current setpoint
  if (stage != 0 && overridelights == LOW) {
    if(lightOutput < lightSetpoint) {
      for(lightOutput; lightOutput <= lightSetpoint; lightOutput++) {
        analogWrite(6, lightOutput);
        delay(4);
      }
    }
    if(lightOutput > lightSetpoint) {
      for(lightOutput; lightOutput >= lightSetpoint; lightOutput--) {
        analogWrite(6, lightOutput);
        delay(4);
      }
    }
  }
  
  // During lights OFF stage, overries will turn on the lights.
  if (stage == 0 && overridelights == HIGH) {
    for(lightOutput; lightOutput <= maxBrightness; lightOutput++) {
      analogWrite(6, lightOutput);
      delay(4);
    }
  }
  
  // During lights OFF stage, turn off lights.
  if (stage == 0 && overridelights == LOW) {
    for(lightOutput; lightOutput >= 0; lightOutput--) {
      analogWrite(6, lightOutput);
      delay(4);
    }
    lightOutput = 0;
  }
  
}

I made a small programm just using pin6 for pwm but different outputs, and the light do no flicker in any of them. I am suspecting that it is flickering because of the program. Could it be?

//setup loop
void setup() {
  pinMode(6, OUTPUT); //setup the output pin
}

//main program loop
void loop() {
      analogWrite(6, 10); 
      delay(10000);
      analogWrite(6, 40); 
      delay(10000);
      analogWrite(6, 80); 
      delay(10000);
      analogWrite(6, 120); 
      delay(10000);
      analogWrite(6, 140); 
      delay(10000);
      analogWrite(6, 180); 
      delay(10000);
      analogWrite(6, 200); 
      delay(10000);
      analogWrite(6, 210); 
      delay(10000);
      analogWrite(6, 230); 
      delay(10000);
      analogWrite(6, 255);
      delay(10000);   
}

Hi dmallia

Flickering:

I suspect the software loop() function is taking too long and the LED's are being turned off and on at a rate that you can see with your eyes. You need to be over 100Hz to not see flicker. I prefer 150 Hz.

I suggest you use one of the timers in the arduino board to setup a PWM. The benefit of using the timers is the drive to the FETs is not affected by program execute time. So if you wanted to add a display or something to remind you to feed them it will not change the LED drive.

I used timer2 because I wanted to be able to power my LED's at very low levels and I needed the 16 bit timer to accomplish that. You likely don't need this and could use the built in PWM commands to setup the timers.

MOSFET:

I've attached a schematic of a typical MOSFET driven from an arduino. Looking at your original photo of the boards, there seems to be a LED in the circuit. The AOD4184A looks to be a better choice because it has a lower Gate Threshold Voltage, but there is more going on as I see two fets on the AOD4184A board (need more info).

The "Gate Threshold voltage" is the range of voltages below which the MOSFET will not conduct at all. When the Gate reaches this voltage (for the AOD4184A it ranges from 1.7 to 2.6 volts. So to be "safe" the gate must be below 1.7 volts for the MOSFET not to conduct. And must be above 2.6 to BEGIN conducting. I think at the 4.? output pin of the arduino you're safe.

good luck

JohnRob

MOSFET.jpg