Screen brightness?

I don’t suppose anyone knows how this person got such a brightness range out of a monochrome oled screen?

There isn’t really any cluesabout which screen it is, nor any source code.

I have got only a small range of brightness using the following…

void setContrast(uint8_t contrast)
{
  arduboy.LCDCommandMode();
  SPI.transfer(0x81); // contrast command
  SPI.transfer(contrast);
  arduboy.LCDDataMode();
}

But I can’t get the brightness all of the way down. A nice fade-in/out function would be grate on the Arduboy. Maybe switching the display on/off with a timer might do it?

I did some experiments with the set fade out and blinking (0x23) command to see if it might be useful to add a blink screen function to the Arduboy2 library. It turned out to have the same limited brightness range as the contrast command. (It likely uses the same hardware.) So, I didn’t bother doing it.

For the same reason, as you discovered, I didn’t feel it was useful to add a contrast control function to the library.

@Dreamer3 (aka yyyc514 on GitHub) did some work a while back on using a combination of contrast and charge pump control to extend the range of brightness control. I haven’t looked at how successful he was or how well it works.

Yeah it doesn’t seem the contrast has much effect. It may be that since we don’t use a proper power regulator on our voltage supply so that the voltage/current is allowed to fluctuate according to the current consumption?

It’s just the way the display works. Even my home made system, with the display running at a constant regulated 3.3V, has about the same range of contrast control.

So no clues as to how the guy in the video did it?

No clues beyond what I’ve mentioned above. Note that the display in the video has an I2C interface instead of SPI but that probably doesn’t matter.

I tinkered a little bit with this command. The key is to reduce the pre charge time to a minimum. I am not an expert for these displays but it works pretty well, so before you set the contrast (once after boot is enough) do this:

    LCDCommandMode();                                                       
    SPI.transfer(0xd9); /* pre charge period */                                  
    SPI.transfer(0x11); /* 1/1 DCLK for phase 1 and 2 */ 

A video how this looks is here however in reality is looks much more awesome. Probably I should have used more white :blush:

4 Likes

Nice work. I wasn’t sure what the pre-charge period referred to (?) but then found this guide: http://www.osram-os.com/Graphics/XPic2/00032223_0.pdf/4-Bit%20Driver%20Basic%20Register%20Setup.pdf
Also from the actual OLED panel manufacturer: http://educypedia.karadimov.info/library/OLED%20Driver%20IC%20Optimizes%20Display%20Performance.pdf
Of interest, is a reference to inconsistent display (as is commonly seen on the Arduboy):

It should be noted that the skew rate usually drops as the loading goes up. The pre-charging loading of a row with a bright horizontal line on the display is very different from a row with only a few lit pixels. To determine the pre-charge period and the driving strength, the slowest skew rate has to be accommodated, otherwise some rows with more ON-pixels would not have enough pre- charge, and they would appear to be dimmer than other rows. The display brightness would become uneven.

1 Like

Holy smokes this means you could theoretically fix the banding artifacts! You would have to precompute the value from the row and adjust on the fly but, it’s possible! Wow amazing work! I’ve got to admit I’ve always been a bit puzzled by some of the OLED commands. Great stuff!

1 Like

Great work, although it still isn’t full-off to full-on. It’s a shame whoever made that youtube video vanished without even saying what controller was on the screen, or what it was being used with.
But that idea about fixing the banding sounds interesting, my fame suffers from it a lot as my backgrounsd are mostly big blocks of black or white.

When I set the contrast to 0 and the pre charge period to a minimum on my arduboy the logo (this is my test) is almost not visible. The brightness is very low. If you want less than that you need to turn the screen off. (sorry for the poor quality, too much coffee)

Can you share a picture of your arduboy with the same configuration but maybe with your picture?

1 Like

@veritazz could you do an experiment ?

could you add 2 white squares and show them alternating ?
BUT:

  • when left one is on you set contrast to half
  • when the right one is on you set it to full ?

I would love to see what happens :stuck_out_tongue:

1 Like

I tested it and it suffers the scanlines & flickering issue.
Anyway, contrast change works great for screen fade in/out. :+1:

I did a quick test changing the charge pump during update, but it caused a lot of flickering, not sure what direction to go in from that point.

1 Like

Just tried a little more. If you add this line to the pre charge change:

    SPI.transfer(0xdb);                                                     
    SPI.transfer(0x00);  

It starts from complete black. So that’s what you meant I guess. Now from complete black to very bright. Now the fade is really smooth.

1 Like

Actually this gives the best result for me. The picture is more crisp:

    SPI.transfer(0xd9);                                                     
    SPI.transfer(0x2f);                                                     
    SPI.transfer(0xdb);                                                     
    SPI.transfer(0x00);

I even think we can tune it if we make the pre charge changes dependent of the contrast to be set.

@JO3RI I did the experiment. Actually the two rectangles have a different colors (one is white the other grey, depends on the contrast) but the problem is the tearing. It is visible very much during this test. Till now I did not find any solution to reduce the tearing without the FR pin.

@veritazz Okay and what if you limit the refresh rate using
arduboy.setFrameRate(60); in setup

and

if (!(arduboy.nextFrame())) return; in loop

probably will not help, but … you never know

PS: could you upload the test to github as a demo ? (so we can all give it a try)

@JO3RI Did it but unfortunately it does not make a difference. I uploaded the test to github:

I think getting rid of the tearing without the FR is almost impossible as according to the datasheet the only way to be in sync with the controller when it writes to the display is the FR pin. Even if we would find a timing that looks like it fits there is still a drift either by the clocks or just by jitter on the AVR due to interrupts.
However I look forward that some smart people find creative solutions.

Thanks a lot for this! I implemented a screen fade-out into the ending of my game, it looks really cool for a device normally only capable of black or white :smile:

1 Like