Adjust brightness of LEDs? [SOLVED]

I know this has been asked before, but I couldn’t solve it based on what I have read.
I am writing a little program that will have the Arduboy alternate between blinking the GREEN_LED and the RED_LED. I have been successful, however the light is very bright. I wonder how I can lower the brightness of these lights?

I have been trying to use the setRGB() function - see the first one described here but can’t seem to be able to use it this way?

If someone could please show me how this should be written, and where to place it in the program that would be great. I am very new to programming and Arduino in general, so I appreciate your patience and any help I can get.

Let me know if you need more info. Here is the code, which is a mix and match of different tutorials and other bits I have found online:

/*
* Originally from: scrollingHelloWorld
* Original Author: Darrell Little
* Original Date: 10/15/2019
* This code was originally an example shows how to scroll a line of text
* across the screen on an Arduboy.
* The OLED screen dimensions are 128 x 60 pixels (width x height)
* It has since been modified by myself as a small Xmas exercise for my own learning.
*/


#include <Arduboy2.h>
#include <Arduboy2Core.h>
#include <ezOutput.h>
 
Arduboy2 arduboy;

// Create the variables needed
int x;
int y;
char* myGreeting = ("Merry Christmas!!! <3 <3 ~ Kitty");

ezOutput led1(GREEN_LED);
ezOutput led2(RED_LED);


// ------------------------------------------------------- Setup -------------------------------------------------------
void setup() {

  arduboy.begin();
  arduboy.setFrameRate(30);

  // *Trying* to adjust the brightness
  setRGBled()

  // The blinking setup, and duration 
  led1.blink(500, 250);       // time (ms) on, and time off
  led2.blink(1000, 500);      // time (ms) one, and time off
}

// ------------------------------------------------------- Main loop -------------------------------------------------------
void loop() {
  
  if (!(arduboy.nextFrame()))
    return;
  
  // Set the coordinates to start at the right edge of the screen
  // and midway down on the Y-axis
  x = 127;
  y = 30;
  
  // In the for() loop, use the screen width x 2
  // this allows the entire message to scroll across
  // before starting over
  for(int i = 0; i < 256; i++) {

  arduboy.clear();
  arduboy.setCursor(x, y);
  arduboy.print(myGreeting);
  arduboy.display();
  delay(75);
  
  x--;

  led1.loop();
  led2.loop();
 }
 
}

And any other feedback on how I can improve the code is also appreciate. Thanks in advance.

Did you see the note and follow it, which reads:

In order to use this function, the 3 parameter version must first be called at least once, in order to initialize the hardware.

The documentation says:

Note
In order to use this function, the 3 parameter version must first be called at least once, in order to initialize the hardware.

Which means you need to at least call arduboy.setRGBled(0, 0, 0); before you can use any other variants of it. After that, you’re able to set the brightness of the individual colour channels with e.g. arduboy.setRGBled(GREEN_LED, brightness).

Though there’s also a chance that the ‘ezOutput’ library might be causing a conflict depending on what it’s doing, so it’s best to try the native method first.


For the record, by calling display in a for loop, you’re actually bypassing the frame rate limiting mechanism, so if(!arduboy.nextFrame()) return; won’t behave as it should.

You could get a similar effect with the following:

// Set the coordinates to start at the right edge of the screen
int16_t x = 127;
int16_t step = 0;

void loop()
{
  if (!arduboy.nextFrame())
    return;

  arduboy.clear();
  arduboy.setCursor(x, 30);
  arduboy.print(myGreeting);
  arduboy.display();
  
  if(step < 256)
  {
    ++step;
    --x;
  }
  else
  {
    step = 0;
    x = 127;
  }

  led1.loop();
  led2.loop();
}

(There’s a way to get rid of step, but I left it in so you can more clearly see the relationship between this code and the for loop.)


Also this:

char* myGreeting = ("Merry Christmas!!! <3 <3 ~ Kitty");

Should be:

// A pointer to a string in RAM
const char * myGreeting = ("Merry Christmas!!! <3 <3 ~ Kitty");

Or:

// A pointer to a string in RAM
constexpr char * myGreeting = ("Merry Christmas!!! <3 <3 ~ Kitty");

(It would actually be better to use arduboy.print(F("Merry Christmas!!! <3 <3 ~ Kitty"));, or something a bit more complicated, but that’s a story for another time.)


With that all cleared up, something like this should work:

/*
* Originally from: scrollingHelloWorld
* Original Author: Darrell Little
* Original Date: 10/15/2019
* This code was originally an example shows how to scroll a line of text
* across the screen on an Arduboy.
* The OLED screen dimensions are 128 x 60 pixels (width x height)
* It has since been modified by myself as a small Xmas exercise for my own learning.
*/
#include <Arduboy2.h>
 
Arduboy2 arduboy;

// Set the coordinates to start at the right edge of the screen
int16_t x = 127;

// The counter variable
int16_t step = 0;

// The type of 'myGreeting' is inferred by the compiler
constexpr char * myGreeting = ("Merry Christmas!!! <3 <3 ~ Kitty");

// The brightness at which to flash the LED
constexpr uint8_t brightness = 63;

// Setup
void setup()
{
  arduboy.begin();

  // Initialise the analogue LED control with the setRGBled function
  arduboy.setRGBled(0, 0, 0);
}

// Track the state of the LEDs
bool greenLightOn = false;
bool redLightOn = false;

// Main loop
void loop()
{
  if (!arduboy.nextFrame())
    return;

  arduboy.clear();
  arduboy.setCursor(x, 30);
  arduboy.print(myGreeting);
  arduboy.display();
  
  // Every 1/2 a second (when the Arduboy is at 60FPS - the default)
  if(arduboy.everyXFrames(30))
  {
    // If green light is on
    if(greenLightOn)
    {
      // Turn green light off
      arduboy.setRGBled(GREEN_LED, 0);
      greenLightOn = false;
    }
    // If green light is off
    else
    {
      // Turn green light on
      arduboy.setRGBled(GREEN_LED, brightness);
      greenLightOn = true;
    }
  }
  
  // Every 2 seconds (when the Arduboy is at 60FPS - the default)
  if(arduboy.everyXFrames(120))
  {
    // If red light is on
    if(redLightOn)
    {
      // Turn red light off
      arduboy.setRGBled(RED_LED, 0);
      redLightOn = false;
    }
    // If red light is off
    else
    {
      // Turn red light on
      arduboy.setRGBled(RED_LED, brightness);
      redLightOn = true;
    }
  }
  
  if(step < 256)
  {
    ++step;
    --x;
  }
  else
  {
    step = 0;
    x = 127;
  }
}

Without knowing more about what kind of light pattern you’re aiming for, I can’t be more specific, but this should give you an idea of how it works.

Note that because setRGBled sets the individual colour channels, during the period in which both the green and red components are lit, you’ll end up with yellow - the colour that is the additive mixture of red and green. (See here for more info.)

Hopefully this code makes sense to you, but if there’s anything you don’t understand about it, feel free to ask.

2 Likes

@Pharap beat me to it but:

If you want to use setRGBled functions to control the brightness of the RGB LEDs, you can’t use the ezOutput library. The two will conflict.

You will have to control the blinking of the LEDs yourself, using some kind of timing and switching the intensities between 0 and your desired brightness levels.

2 Likes

Thank you for the quick and detailed response! :grinning: I will take a look and try these out and come back here if I have any question.

1 Like