12v LED strip flash

Hi guys,
I’m trying to make a movie room lightning system for the lounge in which you press an infrared remote which sends a signal to an arduino which dims on a 12v LED strip which lights the room. When your done you just press the same button again and it dims off.
Here is my code:

#include "IRremote.h"

int receiver = 11; //infrared receiver pin
int ledPin = 9; //LED strip light
int ledState = 0; //state of LED strip light pin

IRrecv irrecv(receiver);          
decode_results results;

void setup()
{
  irrecv.enableIRIn();
  pinMode (ledPin, OUTPUT || INPUT); //declare ledPin as input and output so you can tell when light is on or off
}

void loop() 
{
  if (irrecv.decode(&results))

  {
    translateIR(); 
    irrecv.resume();
  }  //receive and translate IR
}

void translateIR()
{
  switch(results.value)

  {

  case 338831067: //button on IR remote pressed
    ledState = digitalRead (ledPin);
    if (ledState == LOW) { //read ledPin, if LOW dim LED on, if HIGH dim LED off.
    for (int brightness = 0; brightness < 256; brightness++) {
      analogWrite (ledPin, brightness);
      delay (30);
    }
    digitalWrite (ledPin, HIGH);
    }
    if (ledState == HIGH) {
      for (int brightness = 256; brightness > -1; brightness--) {
        analogWrite (ledPin, brightness);
        delay (20);
      }
      digitalWrite (ledPin, LOW); //the glitch could be in here somewhere
    }
    break;
      }
  delay(500);
}

So this code works fine but when it dims the LED strip to off it flashes off and on again really quickly before dimming to fully off. This is fine if the dim delay is quick (such as a 5 millisecond delay) but when it is longer (such as a 40 millisecond delay) it is quit a bit more noticeable.
I’m just wondering if anyone can point out what might be causing this glitch so that I can remove/fix this in the program.
I have tried changing a few variables in the program but to no success.
Thanks for your time,
nathman11

Not only is that truly awful code, you have not learned to use "Auto Format" to make the function flow legible.

You are pounding the ledPin alternately with analogWrite and digitalWrite. Make your mind up! I am passably sure that will foul things up somewhere. Use ledState purely as a toggle (i.e., read it and invert it, but don't read anything else) to determine which function - fade up or fade down - to perform, and use analogWrite to do it; leave it at that.

nathman11: I'm trying to make a movie room light*n*ing system

You'll need more than LED strips to do that!

Hi Paul,
Would you say that this code is better?

#include "IRremote.h"

int receiver = 11;
int ledPin = 9;
int ledState = 0;

IRrecv irrecv(receiver);          
decode_results results;

void setup()
{
  irrecv.enableIRIn();
  pinMode (ledPin, OUTPUT || INPUT);
}

void loop() 
{
  if (irrecv.decode(&results))

  {
    translateIR(); 
    irrecv.resume();
  }
}

void translateIR()
{
  switch(results.value)

  {

  case 338831067:
    ledState = digitalRead (ledPin);
    if (ledState == LOW) {
      for (int brightness = 0; brightness < 256; brightness++) {
        analogWrite (ledPin, brightness);
        delay (30);
      }

    }
    if (ledState == HIGH) {
      for (int brightness = 256; brightness > -1; brightness--) {
        analogWrite (ledPin, brightness);
        delay (20);
      }
    }
    break;
  }
  delay(500);
}

I removed the digitalWrite from the code so that there is just analogWrite and it doesn’t make any difference, there is still a flash as it dims down.
Any more help would be appreciated!

You’ll need more than LED strips to do that!

Its only a small movie room so an LED strip will be plenty.

Thanks,
nathman11

PS. The code has been Auto Formatted this time.

May be a problem here

pinMode (ledPin, OUTPUT || INPUT);

might be better with....

pinMode (ledPin, OUTPUT);

Strangely, that may not be the problem.

Why not test without the IR part using the serial monitor.

Your delay is different (30 vs 20) in the 2 for loops.

(I presume you are not powering the LED strip from the Arduino and is the GND common?)

Hi, The only reason I have this:

pinMode (ledPin, OUTPUT || INPUT);

Is so that it reads if the led is HIGH and if it is it dims it off but if it is LOW it dims it to HIGH.

I could change it to that (pinMode (ledPin, OUTPUT);)but if I did the code wouldn't do what I want it to.

I have tried testing this with a button instead of the IR with the same result so I'm not sure what to do. Should I just put up with it or is there a way that I maybe able to change it to work better?

The only reason my delays are different is because to be able to get the dims roughly the same the dim to HIGH needs to have a slightly longer delay then the dim to LOW.

Yes I'm using a high amp transistor to run my LED's. They do all have a common ground.

Thanks heaps for your help guys! nathman11

Don't be silly, that pin mode assignment is not doing what you think, what ever it is. Can you explain what you think it is doing for you?

A pin mode call sets a pin to be an input or an output, it can not be both at the same time. What you end up with is one or the other. If for some reasion you need to change a pin over you need another pin mode call.

But that is an odd thing to want to do anyway and if you don't know what you are doing you could damage your Arduino or the thing that it is attached to.

As to your code. Why are you using a case statement with only one case in it? You should use an if statement.

Use a variable in your code to act as a flag rather than using the read of an output pin. Yes you can read the output register but it is bad practise as you set that pin in the first place so you should know what state it is in.

Hi,

Ok, I’ll explain what I want to do and you can tell me if my way of doing it is better?

I set it as an Input and an Output because I wanted the LED to go LOW if the ledPin is HIGH and the LED to go HIGH if the ledPin originally LOW.

I have one ‘case’ in the code that I posted because I just wanted to figure out the problem, in the final code I want to have a few ‘case’s’ so that I can have different IR buttons that will change the speed of dim or of the fade.

Because I’m planning on having a few IR signals in the code I want any button to be able to make the LED HIGH if it was originally LOW and LOW if it was originally HIGH.

I had another look through the program and did a bit of editing using your advice, is this a better way of doing the same thing? I’ve also added another ‘case’ to show a bit more of what I’m planning.

#include "IRremote.h"


int receiver = 11;
int ledPin = 6;
int ledState = 0;
IRrecv irrecv(receiver);          
decode_results results;



void setup()
{
  irrecv.enableIRIn();
  pinMode (ledPin, OUTPUT);
}


void loop() 
{
  if (irrecv.decode(&results))

  {
    translateIR(); 
    irrecv.resume();
  }  
}


void translateIR()
{
  switch(results.value)

  {

  case 338831067: 
    ledState = 0;
    if (ledState == 0) { 
      for (int brightness = 0; brightness < 256; brightness++) {
        analogWrite (ledPin, brightness);
        delay (40);
        ledState = 1;
      }
    }
    if (ledState == 1) {
      for (int brightness = 256; brightness > -1; brightness--) {
        analogWrite (ledPin, brightness);
        delay (30);
        ledState = 0;
      }
    }
    break;
  case 924466310: 
    ledState = 0;
    if (ledState == 0) { 
      for (int brightness = 0; brightness < 256; brightness++) {
        analogWrite (ledPin, brightness);
        delay (10);
        ledState = 1;
      }
    }
    if (ledState == 1) {
      for (int brightness = 256; brightness > -1; brightness--) {
        analogWrite (ledPin, brightness);
        delay (5);
        ledState = 0;
      }
    }
    break;
  }
}

I tested this code and there is still a flash before it fades down.
Also now it will fade up but then as soon as it has fully finished fading up it will dim down again instantly. Why is it doing this?

My programming skill aren’t too advanced so once again any help is appreciated!
Thanks for your help,
nathman11

You put:-

   ledState = 0;
    if (ledState == 0) {

Now is there any way that ledState can not be equal to zero?

Then you do:-

        ledState = 1;

256 times!!!

This then causes the

if (ledState == 1) {

to always execute.

Your other problem is that the analogWrite function goes from 0 to 255. Feeding 256 to this function is exactly the same as feeding 0 to it.

pinMode refers to the electrical characteristics of the pin i.e. INPUT or OUTPUT etc. You should read the docs on this. (See Learning->Reference in the menu above)

You can always read the state of a digital pin, whether it is an input or output.

As you are controlling the state of the output pin, you should just set it once in setup() and keep a variable to record the state. No real need to read the pin state as it only slows things down.

Another suggestion: now that you have 4 x 'for loops' it is time to think about moving them to functions like: void fadeUp(int delay); and fadeDown(int delay);

This will make your code easier to maintain, debug, improve and read.

Another tip is to use 'Serial.println("useful text here") as a tool to help in debugging when things are not behaving as you expect.

However, rather than making loads of changes it might be better to focus on the problem you are having first.

You are making great progress on this...keep up the good work :)

When you read the LEDpin digitalread() the pin sets to an output with some random high or low and flashes.

The analog write function is using PWM. digitalread will read 0 or 1. Not the PWM setting as you expect. You must use a state flag variable and set the iintial value in setup. The brightness needs to be set there as well to match your flag setting. Then change the flag in your fade routines to reflect the current state on exit.

Also the LED pin mode must be output. You are logically ORing the input and output values. This returns a true and sets it as input (if I’m remembering corrctly). In either case it isn’t doing what you want. The pin must be an output.

this summaries the previous posts.
1 set pin mode to output
2 control the state with a state flag variable do not read the pin
3 change flag on exit from fade routines

I was going through your code in order to test it myself on board. It has 2 lines that will flash as you describe just after your fade up and down routines.

digitalWrite(ledPin, HIGH);

and

digitalWrite(ledPin, LOW);

These will do it and are not doing what you want. By using the same pin to test the state, and to run the LED strip you are mixing CPU functions, and it doesn’t work. It needs to run as an Input, or an Output. As an OUtput it can be steady state (digitalWrite(ledPIn,HIGH)) or a varying (PWM) signal for brightness or analogWrite(ledPin, value);

ledState needs to be set by program as each state changes.

Also, use an If Else for your state test.

rep