How do I eliminate flickering of 12v led strips driven by arduino PWM?

Hello,

I've been working on a project which involves an arduino driving 4 12v led strips with PWM. each of the four strips is run through a TIP122 and can be turned on and off with a momentary switch and can be faded with a potentiometer. When I use the existing code (will post below) for one led strip, it works great. When I scale this up to all 4 strips, there is a flickering or twitching that occurs when I push the momentary switch in. I'm a bit stumped at this point as to how to eliminate this flickering and know that it probably has to do with my code. any suggestions/help would be greatly appreciated.

code>

#include <Bounce.h>

const int buttonPin1  = 2; // the number of the button pin
const int buttonPin2 = 3;
const int buttonPin3 = 4;
const int buttonPin4 = 7;
const int buttonPin5 = 8;

const int transistorPin1 = 5; // the number of digital transistor pin
const int transistorPin2 = 6;
const int transistorPin3 = 9;
const int transistorPin4 = 10;
const int transistorPin5 = 11;

// variables will change:

int buttonPushCounter = 0;

int buttonState1 = 0; // variable for reading the pushbutton status
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int buttonState5 = 0;

int lastButtonState = 0;

int potPin1 = A0; // select the input pin for the potentiometer
int potPin2 = A1;
int potPin3 = A2;
int potPin4 = A3;
int potPin5 = A4;

int val = 0; // variable to store the value coming from the sensor

Bounce bouncer1 = Bounce(buttonPin1, 20);
Bounce bouncer2 = Bounce(buttonPin2, 20); // When bouncing another pin change initiator before =
Bounce bouncer3 = Bounce(buttonPin3, 20);
Bounce bouncer4 = Bounce(buttonPin4, 20);
Bounce bouncer5 = Bounce(buttonPin5, 20);


void setup() {
  pinMode(transistorPin1, OUTPUT); // declare the ledPin as an OUTPUT
  pinMode (potPin1, OUTPUT);
  pinMode (buttonPin1, INPUT);

  pinMode(transistorPin2, OUTPUT); // declare the ledPin as an OUTPUT
  pinMode (potPin2, OUTPUT);
  pinMode (buttonPin3, INPUT);

  pinMode(transistorPin3, OUTPUT); // declare the ledPin as an OUTPUT
  pinMode (potPin3, OUTPUT);
  pinMode (buttonPin3, INPUT);

  pinMode(transistorPin4, OUTPUT); // declare the ledPin as an OUTPUT
  pinMode (potPin4, OUTPUT);
  pinMode (buttonPin4, INPUT);
 
   pinMode(transistorPin5, OUTPUT); // declare the ledPin as an OUTPUT
  pinMode (potPin5, OUTPUT);
  pinMode (buttonPin5, INPUT);

  Serial.begin(9600);
}

void loop(){

  bouncer1.update();
  bouncer2.update();
  bouncer3.update();
  bouncer4.update();
  bouncer5.update();

  buttonState1 =  bouncer1.read(); //read the bouncing momentary switches- each associated with the separate switch conditions below.
  buttonState2 =  bouncer2.read();
  buttonState3 =  bouncer3.read();
  buttonState4 =  bouncer4.read();
  buttonState5 =  bouncer5.read();

  if (buttonState1 != lastButtonState){
    if (buttonState1 == HIGH){
      buttonPushCounter++;
      Serial.println ("on");
      Serial.println ("number of button pushes: ");
      Serial.println (buttonPushCounter);
    }
    else {
      Serial.println ("off");
    }
  }

  lastButtonState = buttonState1;
  if (buttonPushCounter % 2 == 0) {
    digitalWrite(transistorPin1, HIGH);
      }
  else
  {
    // read the potentiometer:
    int sensorValue = analogRead(A0);
    // map the sensor value to a range from 0 - 255:
    int outputValue = map(sensorValue, 0, 1023, 0, 255);
    // use that to control the transistor:
    analogWrite(transistorPin1, outputValue);
      }
  if (buttonState2 != lastButtonState){
    if (buttonState2 == HIGH){
      buttonPushCounter++;
      Serial.println ("on");
      Serial.println ("number of button pushes: ");
      Serial.println (buttonPushCounter);
    }
    else {
      Serial.println ("off");
    }
  }

  lastButtonState = buttonState2;
  if (buttonPushCounter % 2 == 0) {
    digitalWrite(transistorPin2, HIGH);
      }
  else
  {
    // read the potentiometer:
    int sensorValue = analogRead(A1);
    // map the sensor value to a range from 0 - 255:
    int outputValue = map(sensorValue, 0, 1023, 0, 255);
    // use that to control the transistor:
    analogWrite(transistorPin2, outputValue);
      }
  if (buttonState3 != lastButtonState){
    if (buttonState3 == HIGH){
      buttonPushCounter++;
      Serial.println ("on");
      Serial.println ("number of button pushes: ");
      Serial.println (buttonPushCounter);
    }
    else {
      Serial.println ("off");
    }
  }

  lastButtonState = buttonState3;
  if (buttonPushCounter % 2 == 0) {
    digitalWrite(transistorPin3, HIGH);
      }
  else
  {
    // read the potentiometer:
    int sensorValue = analogRead(A2);
    // map the sensor value to a range from 0 - 255:
    int outputValue = map(sensorValue, 0, 1023, 0, 255);
    // use that to control the transistor:
    analogWrite(transistorPin3, outputValue);
      }

  if (buttonState4 != lastButtonState){
    if (buttonState4 == HIGH){
      buttonPushCounter++;
      Serial.println ("on");
      Serial.println ("number of button pushes: ");
      Serial.println (buttonPushCounter);
    }
    else {
      Serial.println ("off");
    }
  }

  lastButtonState = buttonState4;
  if (buttonPushCounter % 2 == 0) {
    digitalWrite(transistorPin4, HIGH);
      }
  else
  {
    // read the potentiometer:
    int sensorValue = analogRead(A3);
    // map the sensor value to a range from 0 - 255:
    int outputValue = map(sensorValue, 0, 1023, 0, 255);
    // use that to control the transistor:
    analogWrite(transistorPin4, outputValue);
      }
     }

<code

sort by: active | newest | oldest
Shouldn't each button have a counter ?
daleruisky (author)  steveastrouk3 years ago
Ya, caught that last night for the last button state also. I'm starting to wonder if it has to do with the fact that I haven't added a resistor to the base of the transistor or the fact that I haven't added decoupling capacitors to the circuit?
led_driver_schematic.jpg
Both would be a good idea, but it wouldn't explain why one channel works, but multiple ones flicker when the button is pressed. What tends to happen when the caps are missing is more random, but a quick test with a scope will soon tell you .

If you work out how much stuff you're sticking out through the serial port, that could well be a major issue.

daleruisky (author)  steveastrouk3 years ago
Here's an update on my coding Steve:

I've reworked most of the code and eliminated the serial commands. In response to your first comment about the serial communication getting in the way, I found that this didn't change the flickering. I started to have a hunch about the delays and have found that they are doing some funny things to the light strips. when I change different delays I still get the flickering, but the light is at different intensities. I've also thrown out the dimming functionality in all but one (put in a subroutine for the dimming for the fourth led strip).

I've got all of the lights working on command besides one at this point that still flickers. I've troubled you enough, but if you have the time would you tell me what you think about my reworked code? Really appreciate your help man!

*>code
/*
Set a state of a variable when you press a pushbutton ( the
button went from off to on ).

created 01-12-3009 by kasperkamperman.com
based on example 'State change detection' by Tom Igoe
*/

const int buttonPin1 = 2; // the pin that the pushbutton is attached to
const int transistorPin1 = 5; // the pin that the LED is attached to

const int buttonPin2 = 3; // the pin that the pushbutton is attached to
const int transistorPin2 = 6;

const int buttonPin3 = 4; // the pin that the pushbutton is attached to
const int transistorPin3 = 9;

const int buttonPin4 = 7; // the pin that the pushbutton is attached to
const int transistorPin4 = 10;

const int buttonPin5 = 8; // the pin that the pushbutton is attached to
const int transistorPin5 = 11;



const int transistorPins1[]={
5,6,9,10,11}; //An array of pin numbers attached to transistorPins
const int pinCount1=5; // Number of pins contained within the array.

int transistorPins2[]={
5,6,9}; //An array of pin numbers attached to transistorPins
int pinCount2=3; // Number of pins contained within the array.

int buttonPushCounter =0;

int buttonState1 = 0; // current state of the button
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int buttonState5 = 0;

int lastButtonState1 = 0; // previous state of the button
int lastButtonState2 = 0;
int lastButtonState3 = 0;
int lastButtonState4 = 0;
int lastButtonState5 = 0;

int transistorState1 = 0; // remember current led state
int transistorState2 = 0;
int transistorState3 = 0;
int transistorState4 = 0;
int transistorState5 = 0;

void setup() {
for (int thisPin=0;thisPin pinMode(transistorPins1[thisPin], OUTPUT);
}

pinMode(buttonPin1, INPUT); // initialize the button pin as a input
//pinMode(transistorPin1, OUTPUT); // initialize the button pin as a output

pinMode(buttonPin2, INPUT); // initialize the button pin as a input
//pinMode(transistorPin2, OUTPUT);

pinMode(buttonPin3, INPUT); // initialize the button pin as a input
//pinMode(transistorPin3, OUTPUT);

pinMode(buttonPin4, INPUT); // initialize the button pin as a input
//pinMode(transistorPin4, OUTPUT);

pinMode(buttonPin5, INPUT); // initialize the button pin as a input
//pinMode(transistorPin5, OUTPUT);


}

void loop() {
// read the pushbutton input pin
buttonState1 = digitalRead(buttonPin1);
buttonState2 = digitalRead(buttonPin2);
buttonState3 = digitalRead(buttonPin3);
buttonState4 = digitalRead(buttonPin4);
buttonState5 = digitalRead(buttonPin5);

{
redDimRoutine();
}


// Fifth Strip condition --------------------------------------------------------------------

// read the pushbutton input pin:
buttonState5 = digitalRead(buttonPin5);

// compare the buttonState to its previous state
if (buttonState5 != lastButtonState5) {
// if the state has changed, increment the counter
if (buttonState5 == HIGH) {
// if the current state is HIGH then the button
// wend from off to on:
buttonPushCounter++;

}
}
// save the current state as the last state,
//for next time through the loop
lastButtonState5 = buttonState5;



// turns on the LED every two button pushes by
// checking the modulo of the button push counter.
// the modulo function gives you the remainder of
// the division of two numbers:
if (buttonPushCounter % 2 == 0) {
digitalWrite(transistorPins2[0], LOW);
digitalWrite(transistorPins2[1], LOW);
digitalWrite(transistorPins2[2], LOW);
//digitalWrite(transistorPins2[1], LOW);
//digitalWrite(transistorPins2[2], LOW);
}
if (buttonPushCounter % 3 == 0) {
//Superstitious routine-------------------
/* digitalWrite(transistorPins2[0], HIGH);
digitalWrite(transistorPins2[1], HIGH);
digitalWrite(transistorPins2[2], HIGH);
//delay (300);

digitalWrite(transistorPins2[0], LOW);
digitalWrite(transistorPins2[1], LOW);
digitalWrite(transistorPins2[2], LOW);
//delay(300);

digitalWrite(transistorPins2[0], HIGH);
digitalWrite(transistorPins2[1], HIGH);
digitalWrite(transistorPins2[2], HIGH);
//delay (300);

digitalWrite(transistorPins2[0], LOW);
digitalWrite(transistorPins2[1], LOW);
digitalWrite(transistorPins2[2], LOW);
//delay(300);

digitalWrite(transistorPins2[0], HIGH);
digitalWrite(transistorPins2[1], HIGH);
digitalWrite(transistorPins2[2], HIGH);
//delay (300);

digitalWrite(transistorPins2[0], LOW);
digitalWrite(transistorPins2[1], LOW);
digitalWrite(transistorPins2[2], LOW);
//delay(5000);
*/

//Training procedure (similar to superstitious)---

digitalWrite(transistorPins2[0], HIGH);
digitalWrite(transistorPins2[1], HIGH);
digitalWrite(transistorPins2[2], HIGH);
delay (300);

digitalWrite(transistorPins2[0], LOW);
digitalWrite(transistorPins2[1], LOW);
digitalWrite(transistorPins2[2], LOW);
delay(300);

digitalWrite(transistorPins2[0], HIGH);
digitalWrite(transistorPins2[1], HIGH);
digitalWrite(transistorPins2[2], HIGH);
delay (300);

digitalWrite(transistorPins2[0], LOW);
digitalWrite(transistorPins2[1], LOW);
digitalWrite(transistorPins2[2], LOW);
delay(300);
}

else {
digitalWrite(transistorPins2[0,1,2], LOW);
}
delay (20);
//First LED Strip ----------------------------------------------------------------------------------

// check if the button is pressed or released
// by comparing the buttonState to its previous state
if (buttonState1 != lastButtonState1) {

// change the state of the led when someone pressed the button
if (buttonState1 == 1) {
if(transistorState1==1) transistorState1=0;
else transistorState1=1;
}

// remember the current state of the button
lastButtonState1 = buttonState1;
}

// turns LED on if the transistorState=1 or off if the transistorState=0
digitalWrite(transistorPin1, transistorState1);

// adding a small //delay prevents reading the buttonState to fast
// ( debouncing )
delay(10);





// Second LED Strip -----------------------------------------------------------------------------------------

// check if the button is pressed or released
// by comparing the buttonState to its previous state
if (buttonState2 != lastButtonState2) {

// change the state of the led when someone pressed the button
if (buttonState2 == 1) {
if(transistorState2==1) transistorState2=0;
else transistorState2=1;
}

// remember the current state of the button
lastButtonState2 = buttonState2;
}

// turns LED on if the transistorState=1 or off if the transistorState=0
digitalWrite(transistorPin2, transistorState2);

// adding a small //delay prevents reading the buttonState to fast
// ( debouncing )
delay(10);





// Third LED Strip ------------------------------------------------------------------------------------------------------

// check if the button is pressed or released
// by comparing the buttonState to its previous state
if (buttonState3 != lastButtonState3) {

// change the state of the led when someone pressed the button
if (buttonState3 == 1) {
if(transistorState3==1) transistorState3=0;



else transistorState3=1;
}

// remember the current state of the button
lastButtonState3 = buttonState3;
}

// turns LED on if the transistorState=1 or off if the transistorState=0
digitalWrite(transistorPin3, transistorState3);

// adding a small //delay prevents reading the buttonState to fast
// ( debouncing )
delay(5);






// Fourth LED Strip -------------------------------------------------------------------------------------------------------

// check if the button is pressed or released
// by comparing the buttonState to its previous state
if (buttonState4 != lastButtonState4) {

// change the state of the led when someone pressed the button
if (buttonState4 == 1) {
if(transistorState4==1) transistorState4=0;


else transistorState4=1;
}

// remember the current state of the button
lastButtonState4 = buttonState4;
}

// turns LED on if the transistorState=1 or off if the transistorState=0
digitalWrite(transistorPin4, transistorState4);

// adding a small //delay prevents reading the buttonState to fast
// ( debouncing )
//(0);
}

void redDimRoutine(){
if (transistorState4 == 0){


// read the potentiometer:
int sensorValue = analogRead(A3);
// map the sensor value to a range from 0 - 255:
int outputValue = map(sensorValue, 0, 1023, 0, 255);
// use that to control the transistor:
analogWrite(transistorPin4, outputValue);
}

}


<*
daleruisky (author)  daleruisky3 years ago
Solution to the flashing problem:

It turns out that the "else" condition called in the "5th strip condition (last few lines)" was trying to bring the transistor pins low while in the 1-3 strip conditions I was trying to bring them high every time the code looped and therefore caused the flashing. The code is working great now.

I want to thank you for helping me in my moments of coding distress steveastrouk. Thanks to you, I have taught myself to use arrays, subroutines and have a better set of arduino debugging skills now!
Possibly because, at the default baud rate, all your serial data takes long enough for flicker to happen.

Your code would be a lot cleaner if you put the same stuff into a subroutine and pass the buttonstate and affected pins to it.
daleruisky (author)  steveastrouk3 years ago
Hello Steveastrouk,

I really appreciate your response and guidance concerning my code. I'm sure you know very well, when I get stumped with code it seems to be the only thing I can think about until I figure it out.

I found this resource for working subroutines into my code:

http://arduino.cc/en/Reference/FunctionDeclaration

Can you recommend any other great sources on the internet for learning to write subroutines ? Also, do you have any suggestions for links to the "catch condition" you mentioned in your latest comment.

Your help is greatly appreciated!!
I retract the comment about the catch, because its looked after by your "buttonstate" check.

Mask off all your serial println and see if it still flcikers