2

Even if I don't use buttons and I do an automated thing that makes the led brighter(Even the non-rgb one)after sometime it resets itself to a dimmer light, why?*

int Gled = 5;
int Bled = 6;
int Rv;
int Gv;
int Bv;

int b1 = 7;
int b2 = 8;
void setup() 
{

  pinMode(b1, INPUT_PULLUP);
  pinMode(b2, INPUT_PULLUP);
  Rv = 0;
  Gv = 0;
  Bv = 0;
  analogWrite(Rled, Rv);
  analogWrite(Gled, Gv);
  analogWrite(Bled, Bv);

}

void loop() 
{
  
  if(digitalRead(b1) == LOW)
  {
    Rv += 10;
    analogWrite(Rled, Rv);
  }
  if(digitalRead(b2) == LOW)
  {
    Gv += 10;
    analogWrite(Gled, Gv);
  }

}
1
  • The loop is quite fast, can you imagine how many times it goes into if section, when you press the button? Also you are providing int value into analogWrite, but usual values are 0-255...
    – KIIV
    Oct 12, 2020 at 9:34

1 Answer 1

3

The described behavior stems from 2 important facts:

  1. The loop() function will run very fast (microsecond range), while the button presses of a normal human will be rather slow (in the tens or even hundreds of milliseconds). That means, that with only one button press you will enter the corresponding if statement many times, everytime adding 10 to the value. You don't have control how many times exactly the if statement will be entered, so the value, that comes out after your button press is somewhat randomly growing.

  2. While the analogWrite() function takes an int as the value parameter (16 bits on AVR), internally it assigns that value to the corresponding Timer register, which is only 8 bits big. So it can only hold values between 0 and 255 anyway. If you provide a bigger number as a parameter, the higher part will just be cut off. For example: Providing 257 will result in a value of 1 (= 257 % 256 = 257 % 2^8 --> 257 modulo 256). The higher values get wrapped around back into the range of 0 to 255.

So together you have a value, that is growing very fast and somewhat randomly, while the analogWrite() function will only take the lower 8 bit of that value. The outcome is a rather erratic, somewhat random LED brightness, which is difficult to control.

What to do now? That depends on what behavior you want to have exactly:

  • One button click (press + release) should increase the value of the corresponding LED by 10:

    • Currently you are checking, if the button is being pressed. Instead you have to look for the transition between not-pressed and pressed, so a HIGH to LOW transition. You can do that by saving the last read value in a variable at the end of the button reading part and comparing this previous value to the newly read value at the start of it. Though that still leaves you with the bounce problem. There are many measurements, that you can do, to debounce the button (you can google that easily), though here I just will suggest using the Bounce2 library. You can find it here on github or in the library manager (I think). It makes it much easier to read buttons reliably. It has good examples to learn how to use it.
  • The value should rise, while the button is pressed, and stopping to rise, when it is released again:

    • Here you should limit the rate in which the if statement is entered. You can do this by limiting the execution rate of the loop() function with a simple call to delay(), though that isn't a good coding practice and can limit you, when adding more functions to your code (because it's blocking the execution of other code). Instead you can use the non-blocking coding style involving the millis() function, that you can see in the BlinkWithoutDelay example. You use a timestamp variable to save the last time, when the if statement was executed. The if statement should then check (additionally to the button state), if enough time has passed, meaning if the difference between millis() and the timestamp is high enough. You can change the interval for this comparison to change the rate, in which the value is increased.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.