5

I have this sketch:

#include <TimerOne.h>
#include <IRremote.h>
#include <RGBMood.h>
int RECV_PIN = 2; // IR-Receiver PIN
int led = 13; // Satus-LED PIN
int modus; // Modus for Interrupt-Querry 
int ledr = 11; // RGB LED red PIN
int ledg = 12; // RGB LED green PIN 
int ledb = 13; // RGB LED blue PIN
int SerialBuffer = 0; 
RGBMood m(ledr, ledg, ledb);
int timerwert = 20; // Timer time for Interrupt in ms
String readString;
// Color arrays
int black[3] = { 0, 0, 0 };
int white[3] = { 100, 100, 100 };
int red[3] = { 100, 0, 0 };
int green[3] = { 0, 100, 0 };
int blue[3] = { 0, 0, 100 };
int yellow[3] = { 40, 95, 0 };
int dimWhite[3] = { 30, 30, 30 };
int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by
// etc.
// Set initial color
int redVal = black[0];
int grnVal = black[1]; 
int bluVal = black[2];
int wait = 10; // 10ms internal crossFade delay; increase for slower fades
int hold = 0; // Optional hold when a color is complete, before the next crossFade
int DEBUG = 1; // DEBUG counter; if set to 1, will write values back via serial
int loopCount = 60; // How often should DEBUG report?
int repeat = 3; // How many times should we loop before stopping? (0 for no stop)
int j = 0; // Loop counter for repeat
// Initialize color variables
int prevR = redVal;
int prevG = grnVal;
int prevB = bluVal;
#define ON 0xF4F37A66
#define OFF 0x1363ADB4
#define BRIGHTNESS_UP 0xE6721691
#define BRIGHTNESS_DOWN 0xE9721B48
#define FLASH 0xFFF00F
#define STROBE 0xFFE817
#define FADE 0x39ED1255
#define SMOOTH 0xFFC837
#define RED 0x9D561314
#define GREEN 0XCB8E93A5
#define BLUE 0xC88E8EEC
#define WHITE 0x16DBBEE3
#define ORANGE 0xFFB04F
#define YELLOW_DARK 0xFFA857
#define YELLOW_MEDIUM 0xFF9867
#define YELLOW_LIGHT 0xFF8877
#define GREEN_LIGHT 0XFF30CF
#define GREEN_BLUE1 0XFF28D7
#define GREEN_BLUE2 0XFF18E7
#define GREEN_BLUE3 0XFF08F7
#define BLUE_RED 0XFF708F
#define PURPLE_DARK 0XFF6897
#define PURPLE_LIGHT 0XFF58A7
#define PINK 0XFF48B7
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
 pinMode(ledr, OUTPUT); // Set RGB LED Pins as Output
 pinMode(ledg, OUTPUT); // Set RGB LED Pins as Output
 pinMode(ledb, OUTPUT); // Set RGB LED Pins as Output
 pinMode(led, OUTPUT); // set Status-LED as Output 
 m.setMode(RGBMood::RANDOM_HUE_MODE); // Automatic random fade.
 m.setHoldingTime(4000); // Keep the same color for 4 seconds before fading again.
 m.setFadingSteps(150); // Fade with 150 steps.
 m.setFadingSpeed(50); // Each step last 50ms. A complete fade takes 50*150 = 7.5 seconds
 m.setHSB(random(359), 255, 255);
Serial.begin(9600);
 irrecv.enableIRIn(); // Start of IR-Recive
 Timer1.initialize(timerwert); // Initialisation of Timer-Interrupts
 Timer1.attachInterrupt(leseIR); // IR-Read from Interrupt
}
void leseIR(){
 if (irrecv.decode(&results)){
 irrecv.resume(); // Receive the next value
 switch (results.value) {
 case FADE: // Modus Fade (DIY 4)
 modus = 1; 
 break;
 case 0xFF906F: // Modus pcambi (DIY 5)
 modus = 2; 
 break;
 case ON: //Power
 modus = 0;
 crossFade(white); // RGB LEDs Off 
 break;
 case OFF: //Power
 modus = 0;
 crossFade(black); // RGB LEDs Off 
 break;
 case BLUE: //Blau 0,0,255
 modus = 0;
 crossFade(blue);
 break;
 case RED: //Rot
 modus = 0;
 crossFade(red);
 break;
 case GREEN://Grün
 modus = 0;
 crossFade(green);
 break; 
 case WHITE: //Weiss
 modus = 0;
 crossFade(white);
 break;
 case BRIGHTNESS_UP: //DIMMING
 modus = 0;
 // fade in from min to max in increments of 5 points:
 for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
 // sets the value (range from 0 to 255):
 analogWrite(ledg, fadeValue); 
 }
 break;
 case BRIGHTNESS_DOWN: //orange
 modus = 0;
 for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
 // sets the value (range from 0 to 255):
 analogWrite(ledg, fadeValue); 
 }
 break;
 case 0xFFAA55://Grün mitrtel
 modus = 0;
 break; 
 case 0xFF926D: //blau mittel
 modus = 0;
 break; 
 case 0xFF12ED: //rosa
 modus = 0;
 break; 
 } // Switch END
 } 
} 
void loop() {
if(modus==1){ // Querry pb Modus:1 
m.tick();
}
 Serial.println(results.value, HEX);
 Serial.println(DEC);
 Serial.println(DEC);
 Serial.println(DEC);
 } 
 int calculateStep(int prevValue, int endValue) {
 int step = endValue - prevValue; // What's the overall gap?
 if (step) { // If its non-zero, 
 step = 1020/step; // divide by 1020
 } 
 return step;
}
/* The next function is calculateVal. When the loop value, i,
* reaches the step size appropriate for one of the
* colors, it increases or decreases the value of that color by 1. 
* (R, G, and B are each calculated separately.)
*/
int calculateVal(int step, int val, int i) {
 if ((step) && i % step == 0) { // If step is non-zero and its time to change a value,
 if (step > 0) { // increment the value if step is positive...
 val += 1; 
 } 
 else if (step < 0) { // ...or decrement it if step is negative
 val -= 1;
 } 
 }
 // Defensive driving: make sure val stays in the range 0-255
 if (val > 255) {
 val = 255;
 } 
 else if (val < 0) {
 val = 0;
 }
 return val;
}
/* crossFade() converts the percentage colors to a 
* 0-255 range, then loops 1020 times, checking to see if 
* the value needs to be updated each time, then writing
* the color values to the correct pins.
*/
void crossFade(int color[3]) {
 // Convert to 0-255
 int R = (color[0] * 255) / 100;
 int G = (color[1] * 255) / 100;
 int B = (color[2] * 255) / 100;
 int stepR = calculateStep(prevR, R);
 int stepG = calculateStep(prevG, G); 
 int stepB = calculateStep(prevB, B);
 for (int i = 0; i <= 1020; i++) {
 redVal = calculateVal(stepR, redVal, i);
 grnVal = calculateVal(stepG, grnVal, i);
 bluVal = calculateVal(stepB, bluVal, i);
 analogWrite(ledr, redVal); // Write current values to LED pins
 analogWrite(ledg, grnVal); 
 analogWrite(ledb, bluVal); 
 delay(wait); // Pause for 'wait' milliseconds before resuming the loop
 }
 // Update current values for next loop
 prevR = redVal; 
 prevG = grnVal; 
 prevB = bluVal;
 delay(hold); // Pause for optional 'wait' milliseconds before resuming the loop
}

It's working like a charm, the fade operates smoothly using timer1, the colors appear correct on led, but I can't fix the brightness part. Can someone provide sample code to do this?

If anyone else wants to use the code, I'm using an Arduino Mega 2560, please use the same PINs as mine since timers works only on 11,12,13 on this Arduino. (link with pin info regarding several Arduino boards)

I'm using a small Xbox 360 IR control (no numbers keypad), some HEX codes are left intact from the original sketch found on internet.

original topic

asked Aug 1, 2014 at 7:31
3
  • 1
    Whats wrong with the brightness part? Commented Aug 1, 2014 at 8:50
  • i cannot set the brightness of the leds. Maybe i should use the expression "dim" instead of brightness to make it more clear. If i set the color RED, i cannot dim it up or down, same aplies for GREEN and BLUE. Commented Aug 1, 2014 at 9:04
  • 1
    No 'brightness' was clear, I just couldn't tell what wasn't working from your question. :P Commented Aug 1, 2014 at 9:43

2 Answers 2

2

You don't have a delay in the fade loop, this goes from 0 to 255 almost instantly:

for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
 // sets the value (range from 0 to 255):
 analogWrite(ledg, fadeValue); 
}

But I'm not sure you want to fade from off to on in one go. If you want to just increment and decrement the brightness:

First notice that prevR, prevG, prevB hold the current led values. So we shall use them.

Change the switch case to:

case BRIGHTNESS_UP:
 modus = 0;
 int c[3];
 // decrease by 0.9*value but also take off 2 so we get to zero
 c[0] = (prevR-2) * 90 / 100;
 c[1] = (prevG-2) * 90 / 100;
 c[2] = (prevB-2) * 90 / 100;
 for( int j = 0; j < 3; j++ ) {
 if (c[j] < 0) c[j] = 0;
 }
 crossFade(c);
 break;
case BRIGHTNESS_DOWN:
 modus = 0;
 int c[3];
 // increase value by 1/0.9 but also add 2 so we get off zero
 c[0] = (prevR+2) * 100 / 90 + 2;
 c[1] = (prevG+2) * 100 / 90 + 2;
 c[2] = (prevB+2) * 100 / 90 + 2;
 for( int j = 0; j < 3; j++ ) {
 if (c[j] > 100) c[j] = 100;
 }
 crossFade(c);
 break;

I can't check this to see if it works see please test and see.

Edit

Different approach:

Global variable for brightness:

int brightness = 100;
int c[3];

Change this value each time:

case BRIGHTNESS_UP:
 modus = 0;
 brightness += 5;
 if (brightness > 255) brightness = 255;
 c[0] = prevR; c[1] = prevG; c[2] = prevB;
 crossFade(c);
 break;
case BRIGHTNESS_DOWN:
 modus = 0;
 brightness -= 5;
 if (brightness < 0) brightness = 0;
 c[0] = prevR; c[1] = prevG; c[2] = prevB;
 crossFade(c);
 break;

Then in crossFade we change the last few lines:

analogWrite(ledr, redVal * brightness / 255); // Write current values to LED pins
analogWrite(ledg, grnVal * brightness / 255); 
analogWrite(ledb, bluVal * brightness / 255); 

Edit 2:

I think that what might be happening is that the color is reduced by brightness, then that reduced value is saved in prevR/G/B when actually it should just be the full brightness value. Try changing last bit of crossFade to :

prevR = color[0]; 
prevG = color[1]; 
prevB = color[2];
answered Aug 1, 2014 at 10:07
11
  • IDE reports that there is redeclaration of 'int c [3] Commented Aug 1, 2014 at 10:11
  • Try move int c[3] outside leseIR() and make it global. Delete all instances in the switch statement. Commented Aug 1, 2014 at 10:33
  • you might want to muck around with the ratios too, say use 80 instead of 90 and 5 instead of 2 etc. I tried to use a ratio because our eyes perceive brightness on a log scale, so a small change in low brightness is like a large change in high brightness. Commented Aug 1, 2014 at 10:36
  • i removed it, code compiled, but, when i press the brighntess up button the color fades to black (switches off) and when i press the brightness down then the color brights up to white after several button presses. Commented Aug 1, 2014 at 10:37
  • oops, i got BRIGHTNESS_UP and BRIGHTNESS_DOWN round the wrong way Commented Aug 1, 2014 at 10:49
1

I've moved the analogWrite part of the code inside the switch case BRIGHTNESS_UP & BRIGHTNESS_DOWN and it's working. I also removed the crossFade(c); line.

Here's the working code:

#include <TimerOne.h>
#include <IRremote.h>
#include <RGBMood.h>
int RECV_PIN = 2; // IR-Receiver PIN
int led = 13; // Satus-LED PIN
int modus; // Modus for Interrupt-Querry 
int ledr = 11; // RGB LED red PIN
int ledg = 12; // RGB LED green PIN 
int ledb = 13; // RGB LED blue PIN
int SerialBuffer = 0; 
int c[3];
//RGB Pins Array
int CH[3] = {11, 12, 13};
int val[3] = {0, 0, 0}; // led brightness 0-255
RGBMood m(ledr, ledg, ledb);
int timerwert = 20; // Timer time for Interrupt in ms
String readString;
// Color arrays
int black[3] = { 0, 0, 0 };
int white[3] = { 100, 100, 100 };
int red[3] = { 100, 0, 0 };
int green[3] = { 0, 100, 0 };
int blue[3] = { 0, 0, 100 };
int yellow[3] = { 40, 95, 0 };
int dimWhite[3] = { 30, 30, 30 };
int brightness = 100; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by
// etc.
// Set initial color
int redVal = black[0];
int grnVal = black[1]; 
int bluVal = black[2];
int wait = 10; // 10ms internal crossFade delay; increase for slower fades
int hold = 0; // Optional hold when a color is complete, before the next crossFade
int DEBUG = 1; // DEBUG counter; if set to 1, will write values back via serial
int loopCount = 60; // How often should DEBUG report?
int repeat = 3; // How many times should we loop before stopping? (0 for no stop)
int j = 0; // Loop counter for repeat
// Initialize color variables
int prevR = redVal;
int prevG = grnVal;
int prevB = bluVal;
#define ON 0xF4F37A66
#define OFF 0x1363ADB4
#define BRIGHTNESS_UP 0xE6721691
#define BRIGHTNESS_DOWN 0xE9721B48
#define FLASH 0xFFF00F
#define STROBE 0xFFE817
#define FADE 0x39ED1255
#define SMOOTH 0xFFC837
#define RED 0x9D561314
#define GREEN 0XCB8E93A5
#define BLUE 0xC88E8EEC
#define WHITE 0x16DBBEE3
#define ORANGE 0xFFB04F
#define YELLOW_DARK 0xFFA857
#define YELLOW_MEDIUM 0xFF9867
#define YELLOW_LIGHT 0xFF8877
#define GREEN_LIGHT 0XFF30CF
#define GREEN_BLUE1 0XFF28D7
#define GREEN_BLUE2 0XFF18E7
#define GREEN_BLUE3 0XFF08F7
#define BLUE_RED 0XFF708F
#define PURPLE_DARK 0XFF6897
#define PURPLE_LIGHT 0XFF58A7
#define PINK 0XFF48B7
#define MAX 255 
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
 pinMode(ledr, OUTPUT); // Set RGB LED Pins as Output
 pinMode(ledg, OUTPUT); // Set RGB LED Pins as Output
 pinMode(ledb, OUTPUT); // Set RGB LED Pins as Output
 pinMode(led, OUTPUT); // set Status-LED as Output 
 //initiate rgb pins output
 for (int i=0; i<3; i++)
 {
 pinMode(CH[i], OUTPUT);
 }
 m.setMode(RGBMood::RANDOM_HUE_MODE); // Automatic random fade.
 m.setHoldingTime(4000); // Keep the same color for 4 seconds before fading again.
 m.setFadingSteps(150); // Fade with 150 steps.
 m.setFadingSpeed(50); // Each step last 50ms. A complete fade takes 50*150 = 7.5 seconds
 m.setHSB(random(359), 255, 255);
Serial.begin(9600);
 irrecv.enableIRIn(); // Start of IR-Recive
 Timer1.initialize(timerwert); // Initialisation of Timer-Interrupts
 Timer1.attachInterrupt(leseIR); // IR-Read from Interrupt
}
void leseIR(){
 if (irrecv.decode(&results)){
 irrecv.resume(); // Receive the next value
 switch (results.value) {
 case FADE: // Modus Fade (DIY 4)
 modus = 1; 
 break;
 case 0xFF906F: // Modus pcambi (DIY 5)
 modus = 2; 
 break;
 case ON: //Power
 modus = 0;
 crossFade(white); // RGB LEDs Off 
 break;
 case OFF: //Power
 modus = 0;
 crossFade(black); // RGB LEDs Off 
 break;
 case BLUE: //Blau 0,0,255
 modus = 0;
 crossFade(blue);
 break;
 case RED: //Rot
 modus = 0;
 crossFade(red);
 break;
 case GREEN://Grün
 modus = 0;
 crossFade(green);
 break; 
 case WHITE: //Weiss
 modus = 0;
 crossFade(white);
 break;
 case BRIGHTNESS_UP: //DIMMING UP
 modus = 0;
 brightness += 5;
 if (brightness > 255) brightness = 255;
 c[0] = prevR; c[1] = prevG; c[2] = prevB;
 analogWrite(ledr, redVal * brightness / 255); // Write current values to LED pins
 analogWrite(ledg, grnVal * brightness / 255); 
 analogWrite(ledb, bluVal * brightness / 255);
 break;
 case BRIGHTNESS_DOWN: //DIMMING DOWN
 modus = 0;
 brightness -= 5;
 if (brightness < 0) brightness = 0;
 c[0] = prevR; c[1] = prevG; c[2] = prevB;
 analogWrite(ledr, redVal * brightness / 255); // Write current values to LED pins
 analogWrite(ledg, grnVal * brightness / 255); 
 analogWrite(ledb, bluVal * brightness / 255);
 break;
 case 0xFFAA55://Grün mitrtel
 modus = 0;
 break; 
 case 0xFF926D: //blau mittel
 modus = 0;
 break; 
 case 0xFF12ED: //rosa
 modus = 0;
 break; 
 } // Switch END
 } 
} 
void loop() {
if(modus==1){ // Querry pb Modus:1 
m.tick();
}
if(modus==2){ // Querry pb Modus:1 
}
 Serial.println(prevR);
 Serial.println(prevG);
 Serial.println(prevB);
// Serial.println(results.value, HEX);
// Serial.println(DEC);
// Serial.println(DEC);
// Serial.println(DEC);
// Serial.print("channel 1,2,3 values:"); // sends brightness values to the serial monitor
 // for(int i=0; i<3; i++){ // every time the remote is pressed
 // Serial.print(CH[i]);
// Serial.print(" ");
 // } 
 } 
 int calculateStep(int prevValue, int endValue) {
 int step = endValue - prevValue; // What's the overall gap?
 if (step) { // If its non-zero, 
 step = 1020/step; // divide by 1020
 } 
 return step;
}
/* The next function is calculateVal. When the loop value, i,
* reaches the step size appropriate for one of the
* colors, it increases or decreases the value of that color by 1. 
* (R, G, and B are each calculated separately.)
*/
int calculateVal(int step, int val, int i) {
 if ((step) && i % step == 0) { // If step is non-zero and its time to change a value,
 if (step > 0) { // increment the value if step is positive...
 val += 1; 
 } 
 else if (step < 0) { // ...or decrement it if step is negative
 val -= 1;
 } 
 }
 // Defensive driving: make sure val stays in the range 0-255
 if (val > 255) {
 val = 255;
 } 
 else if (val < 0) {
 val = 0;
 }
 return val;
}
/* crossFade() converts the percentage colors to a 
* 0-255 range, then loops 1020 times, checking to see if 
* the value needs to be updated each time, then writing
* the color values to the correct pins.
*/
void crossFade(int color[3]) {
 // Convert to 0-255
 int R = (color[0] * 255) / 100;
 int G = (color[1] * 255) / 100;
 int B = (color[2] * 255) / 100;
 int stepR = calculateStep(prevR, R);
 int stepG = calculateStep(prevG, G); 
 int stepB = calculateStep(prevB, B);
 for (int i = 0; i <= 1020; i++) {
 redVal = calculateVal(stepR, redVal, i);
 grnVal = calculateVal(stepG, grnVal, i);
 bluVal = calculateVal(stepB, bluVal, i);
 analogWrite(ledr, redVal); // Write current values to LED pins
 analogWrite(ledg, grnVal); 
 analogWrite(ledb, bluVal); 
 delay(wait); // Pause for 'wait' milliseconds before resuming the loop
 }
 // Update current values for next loop
 prevR = redVal; 
 prevG = grnVal; 
 prevB = bluVal;
 delay(hold); // Pause for optional 'wait' milliseconds before resuming the loop
}

thanks geometrikal for your support! You believe it's possible to manipulate the dimming of the fade effect too? It's using the RGBMood class to create a HSB color mix.

answered Aug 2, 2014 at 6:21

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.