Author Topic: Can STLED316 brightness be PWM-controlled?  (Read 1654 times)

0 Members and 1 Guest are viewing this topic.

Offline peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 6029
  • Country: gb
  • Doing electronics since the 1960s...
Can STLED316 brightness be PWM-controlled?
« on: May 20, 2026, 05:16:18 pm »
https://www.st.com/resource/en/datasheet/stled316s.pdf

The brightness is software-set with 3 bits. The steps are not very even.

There is also a resistor, Rset, which programs it linearly



and basically the range is 360R to 1.5k. Less than 360R exceeds the max rated segment current, and more than 1.5k has - according to the DS - little or no effect.

In my project I use both the 3 bits and Rset (which I switch 360R or 1.5k according to the MSB of the 4 bit brightness value)

Code: [Select]


/**
  * Write formatted datablock to STLED316S
  *
  * *** this is the only function which accesses the display ***
  *
  * @param  DisplayData_t data Array of STLED316S_DISPLAY_MEM (6) bytes (starting at address 0)
  *
  * The data is ASCII characters. All 6 get written to the chip but the number which appears obviously depends
  * on how many 7-seg LEDs are installed. The 655 board has an option for 5, if the light sensor position is used.
  *
  * There are two ways to display a decimal point:
  *
  * 1) if bit 7 = 1 then DP will be illuminated for that character
  *
  * 2) if a (non-first) char is '.' then the previous char's bit 7 is set, and remaining bytes are shuffled left, until 0x00
  * Only 1 decimal point is supported within the display string, and it must not be the 1st char (e.g  .1234)
  *
  * Note that sprintf puts a 0x00 at the end, so one needs the source buffer to be longer than the
  * 6 max digits of the STLED316. This function gets an address of the buffer only, so it doesn't care if the
  * source buffer has been overrun :) If printing decimal points, you will need 2 extra bytes (1 for the dp and 1 for the 0x00
  * which sprintf puts in at the end)
  *
  * With GCC v11+ the compiler warns if inputbuffer is shorter than the memcpy length of 8, so any call to this function
  * like
  * display_formatted_string((uint8_t *) "SENSOR  ", 15);
  * need to supply an 8 byte string (8 including the 0x00 terminator)
  * [url]https://gcc.gnu.org/gcc-11/changes.html[/url]
  * Option -Wstringop-overread is enabled by default.
  *
  * Brightness: integer 0-15
  *
  */

uint8_t last_655_buf[STLED316S_DISPLAY_MEM+2] = {0};


void display_formatted_string(uint8_t *inputbuffer, uint8_t brightness)
{
int i;
bool dpfound=false;
uint8_t tempbuffer[STLED316S_DISPLAY_MEM+2];  // use local buffer to avoid corrupting the input buffer
static uint8_t dispbuffer[STLED316S_DISPLAY_MEM+3];  // this holds the raw segment format for the STLED316 chip
static const uint8_t brt_translate[16]  = { 0,1,2,8,3,9,4,5,6,7,10,11,12,13,14,15 };

if (g_lcd) return; // exit if LCD display selected in config.ini

brightness &= 0x0F;  // limit value 0..15
memcpy(tempbuffer,inputbuffer,STLED316S_DISPLAY_MEM+2);  // make a local copy of the display data

if (tempbuffer[0]==0x00) return;  // abandon if 1st char is a null

if (memcmp(last_655_buf,inputbuffer,STLED316S_DISPLAY_MEM+2)==0)
{
memcpy(last_655_buf,inputbuffer,STLED316S_DISPLAY_MEM+2);
return; // return if data not changed since last call
}

// Handle lone DP char detection and left shuffling

i=1;  // skip 1st char

do
{
if ( tempbuffer[i]=='.' ) { dpfound=true; }
i++;
}
while ( ( i < STLED316S_DISPLAY_MEM+2 ) && ( tempbuffer[i] != 0x00 ) && ( dpfound == false ) );

i--;  // if a DP was found, i now points at the DP char

if ( dpfound )
{
tempbuffer[i-1]|=0x80; // set the DP on previous digit
while ( ( i < STLED316S_DISPLAY_MEM+2 ) && ( tempbuffer[i] != 0x00 ) )
{
tempbuffer[i]=tempbuffer[i+1];  // shuffle 1 left
i++;
}
}

// Convert ASCII characters via the font table; without regard for any bit 7 set, and replacing < 20h with blank digits
// We fill dispbuffer after 1st byte

for (i = 0; i < STLED316S_DISPLAY_MEM; i++)
{
if ( tempbuffer[i] >= 0x20 )
{
dispbuffer[i+1] = FONT_7S[ ( tempbuffer[i] & 0x7F ) - 0x20];
}
else  // invalid char
{
dispbuffer[i+1] = 0x00;  // 0x00 to blank the digit
}
if ( tempbuffer[i] & 0x80 )
{
dispbuffer[i+1] |= 0x80;  // if bit 7 was set on input byte, set it now in the output
}
}


// re-order brightness values to get a monotonic rise
brightness = brt_translate[brightness];

// Values 0 to 7 select low current (10mA), 8 to 15 high current (40mA)
display_set_current(brightness > 7);

SPI3_Lock();

// STLED316S display duty cycle values for brightness are 0 to 7
display_set_global_brightness(brightness % 8);

// This delay (10us just works) is needed after loading the brightness data, before the rest
hang_around_us(20);

dispbuffer[0] = (STLED316S_ADDR_WR_CMD | STLED316S_IDX(STLED316S_DIG_PAGE, 0x00)); // Set Address at 0

// Write all digits in one go

display_cs(0);
hang_around_us(STLED_GEN_WAIT);

SPI3_DMA_TransmitReceive(dispbuffer, NULL, STLED316S_DISPLAY_MEM+1, true, false, RTOS_YIELD);

hang_around_us(STLED_GEN_WAIT);
display_cs(1);
hang_around_us(STLED_GEN_WAIT); // Min CS=1 time

SPI3_Unlock();

}


and then I have a 16 element lookup table which sorts the 16 values into a monotonic-brightness sequence, with the brightness determined by displaying a fixed pattern and measuring the total current.

Anyway, the end result works but the steps are very uneven, which is not great if you are doing auto brightness control based on ambient light. The other problem is that the lowest brightness is too bright for many applications.

The DS is silent on this but it seems obvious to me that Rset is just a branch of a current mirror, whose other branches sink the segment current (of the common-anode displays)



The counter argument to the above is that Rset values above 1.5k do nothing, which suggests some weird circuit... can anyone imagine what it would be? One hint is in one of the appnotes:

Current matching on each segment is guaranteed to be within 3%. When no digit and
segment are ON, STLED consumes much less current of around 200 µA which is achieved
by turning OFF internal current mirror circuitry


I wondered whether pulling down Rset with a MOSFET driven from some suitably fast PWM (fast to not beat with the display muxing) would work?

Obviously there are 1000 ways to do this job but this chip is really handy for stuff like this


« Last Edit: May 20, 2026, 06:01:12 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline cv007

  • Super Contributor
  • ***
  • Posts: 1061
Re: Can STLED316 brightness be PWM-controlled?
« Reply #1 on: May 20, 2026, 06:18:54 pm »
Quote
Rset values above 1.5k do nothing
do nothing little effect.

I would think you could control the iset current by sourcing the rset resistor from a dac or pwm instead of directly to ground. Less voltage across the R = less iset. Would be easy enough to try.
 

Offline peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 6029
  • Country: gb
  • Doing electronics since the 1960s...
Re: Can STLED316 brightness be PWM-controlled?
« Reply #2 on: May 20, 2026, 07:54:40 pm »
Looking at that Rset graph, 360R/40mA and 1450R/10mA is exactly in proportion per ohm's law. The fact that this is 14.5V when the chip is powered from 5V just means the current mirror is not 1:1. I've only just noticed that. Why did they publish a graph when a trivial formula would have been clear?

It also means that higher values of Rset should work and the 1.5k is probably just arbitrary.

However, to get "human eye meaningfully" low brightness you need to go into the < 1mA (average) region. I know this from LCD backlights which need a > 100:1 current range if you want to make a device to work in a low-lit room.

The 8 software steps give an 8:1 range so if Rset switching is used, that should have an 8:1 range also, but my circuit is just 4:1. But with PWM you should be able to forget the software setting, set it to max, and just use PWM on Rset.

I will do an experiment with a BSS138 on the bottom of Rset and feed it from PWM. But equally I bet a precision current sink on the Rset terminal should work equally. As in post #1 here
https://www.eevblog.com/forum/projects/any-slick-way-to-drive-four-backlight-leds-with-same-current/

The advantage of PWM is that the 32F4xx has a load of timers which can output PWM on some pin, but it has only two DACs.
« Last Edit: May 20, 2026, 09:10:53 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 6029
  • Country: gb
  • Doing electronics since the 1960s...
Re: Can STLED316 brightness be PWM-controlled?
« Reply #3 on: May 21, 2026, 07:30:54 am »
I did a test with PWM.

It does not work. You get a beat with the display mux rate. But this is set internally, at roughly 3ms per digit (so ~18ms to get around the whole lot) and will vary between chips, so you would need to dynamically measure this and the select a frequency in between :)

I also tried simply driving the bottom of the 360R Rset from the signal generator, 0 to +5V swing, and varying the duty cycle. That works too but you get horrible beat effects at most frequencies, even into the kHz region.

Then I tried using a much higher value than the DS says for Rset. 25k works just fine and produces a very dim display. So the 1.5k max suggested in the DS appears to be BS. And logically I think if one is using a MOSFET to switch that resistor value, to supplement the 8x software range, it should be 360R, or 8x360R. I picked 430 and 2k7.

I think a precision current sink would work just fine.
« Last Edit: May 21, 2026, 07:44:32 am by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline cv007

  • Super Contributor
  • ***
  • Posts: 1061
Re: Can STLED316 brightness be PWM-controlled?
« Reply #4 on: May 21, 2026, 09:04:48 am »
Quote
I also tried simply driving the bottom of the 360R Rset from the signal generator, 0 to +5V swing, and varying the duty cycle. That works too but you get horrible beat effects at most frequencies, even into the kHz region.
Varying the voltage at 100% duty with the generator, or simply varying the voltage with a power supply to simulate a dac also did not work? Would not some low pass filtering eliminate the variations in iset that is causing the problem with pwm?
 

Offline peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 6029
  • Country: gb
  • Doing electronics since the 1960s...
Re: Can STLED316 brightness be PWM-controlled?
« Reply #5 on: May 21, 2026, 10:18:41 am »
PWM does not work due to the beat effect, however I do it.

This was to be expected but I did not expect it to be so bad, and be so PWM frequency independent. One can avoid it but it needs a very careful frequency tweak, which will not work other than a one-off.

The discovery that 25k Rset works great means that an analog solution exists, as a wide range current sink.

Just in case somebody finds this one day, the 3 software brightness bits produce the following currents in mA (6 digits showing 8, Rset=1.5k )

7
11
18
40
43
46
48
52

The DS reveals a weird relationship for the brightness setting bits:

0000: pulse width is 1/16
0001: pulse width is 2/16
0010: pulse width is 4/16
0011: pulse width is 10/16
0100: pulse width is 11/16
0101: pulse width is 12/16
0110: pulse width is 13/16
0111: pulse width is 14/16

So the chip's 3-bit brightness values 0-7 do not map linearly to increasing brightness (LED current) — there's a non-linear jump between values 2 and 3 (4/16 to 10/16), skipping 5/16, 6/16, 7/16, 8/16, 9/16 entirely.

I've spent a bit of time on this and it appears impossible to solve that gap with just one resistor being switched (i.e. two Rset values only).

So another reason to not use the software brightness, set it to 111, and drive the Rset pin from a wide range current sink. Or one of those programmable potentiometers but they aren't cheap.

Another way would be to have a R/2R/4R/8R etc network on Rset, switched from a shift register, preferably an open-drain one. That would need clock+data but there might be a cunning way to load it from the keypad scanning feature of the chip.

Unfortunately this 20 year old chip is still a very good solution, at a low price. There  is not much else out there, apart from obscure chinese chips. The old MAX7219 / MAX6950 are 10x the price. Hmmm just found the AS1115 which is rather similar, 2x more, and is an obvious "improved copy of the STLED316 and gives 16 brightness levels :)

« Last Edit: May 21, 2026, 09:48:41 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline cv007

  • Super Contributor
  • ***
  • Posts: 1061
Re: Can STLED316 brightness be PWM-controlled?
« Reply #6 on: May 21, 2026, 10:32:47 pm »
Quote
There  is not much else out there
Well, you can make your own. Pick a cheap mcu with the pins required and enough port current capability and you can create a solution that can easily be changed to another mcu whenever you want.

This was a 2 digit 14segment version-
https://goo.gl/photos/rTCwusquFnb8AfQE6

and this was using 3 digit 7 segment displays (4 displays cascaded in this case)-
https://github.com/cv007/3DigitLed/blob/master/IMG_20190423_000107.jpg
(also using an ascii table in addition to numeric/hex, and is more readable than one would think)
edit- this display was going replace the lcd in my Fluke 115, but decided against it-
https://photos.app.goo.gl/3hO0dZBFzGkW1IZG3


These both happen to be using 8bit pic because they are inexpensive and have good port current capability.

A simple protocol via uart, can send raw segment data or simply send ascii data to each addressable digit, each digit has its own brightness level 0-63. Its a low part count solution that is flexible, and the interface is simple and lets the main mcu do more useful things. Make as many or as few digits as you want for a single display, and easily string them together for more digits.
« Last Edit: May 21, 2026, 10:38:30 pm by cv007 »
 

Online PCB.Wiz

  • Super Contributor
  • ***
  • Posts: 3357
  • Country: au
Re: Can STLED316 brightness be PWM-controlled?
« Reply #7 on: May 21, 2026, 11:14:32 pm »
Quote
The counter argument to the above is that Rset values above 1.5k do nothing, which suggests some weird circuit... can anyone imagine what it would be?

Then I tried using a much higher value than the DS says for Rset. 25k works just fine and produces a very dim display. So the 1.5k max suggested in the DS appears to be BS.

LED display drivers often have this somewhat arbitrary range limit on RSET.
My take on that, is that range given is just to meet the error band specs. You can use much lower currents just fine.
ie The circuit is a simple current mirror with some gain.
 
 

Online Psi

  • Super Contributor
  • ***
  • Posts: 12640
  • Country: nz
Re: Can STLED316 brightness be PWM-controlled?
« Reply #8 on: May 21, 2026, 11:57:09 pm »
There are some other LED drivers that do internal PWM with 255 levels for matrix led arrays.
It's probably of no use to you as its BGA and needs blind vias to fanout. but the STLED524 is cool.
It even has a boost converter built in so you can drive white leds from 3V
Actually you might be able to fanout without blind vias if you dont need all the matrix channels, not sure.
But it's still an extremely small BGA. (CSP 56 bumps 0.4 mm pitch 3.4x3.0 mm)  It's intended for scrolling led matrix text displays in fitbits or watches.

https://www.st.com/en/power-management/stled524.html
« Last Edit: May 22, 2026, 06:13:54 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 6029
  • Country: gb
  • Doing electronics since the 1960s...
Re: Can STLED316 brightness be PWM-controlled?
« Reply #9 on: May 22, 2026, 06:04:53 am »
Quote
Well, you can make your own

You can but you need to implement 6 x 8 controllable and gated current sinks. Otherwise, yeah, it is just a shift register :)

Quote
The circuit is a simple current mirror with some gain.
 

Indeed; the AS1115 shows that explicitly, while the STLED316 does not say that (but a "mirror" is mentioned in an appnote). The AS1115 would have been a much better chip for this project, but maybe it was not known in 2016 when it was started. OTOH the STLED316 is just fine if you don't need ambient light based (continuous) brightness control.

Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 6029
  • Country: gb
  • Doing electronics since the 1960s...
Re: Can STLED316 brightness be PWM-controlled?
« Reply #10 on: May 22, 2026, 02:16:38 pm »
As an extra data point, the voltage on Rset is +1.2V which indicates that the current mirror (which hangs off the +5V supply rail) drops quite a bit of voltage.

Hence this chip cannot do 3.3V. The min is 4.5V (DS), unsurprisingly.

And here is another bizarre thing: One of the prototypes I built has green LEDs, not red. And I cannot get the brightness on this one to work monotonically. It just does weird things as I vary the Rset resistor value. So what is different?

The actual Vs is about 4.6V and green LEDs drop a lot more voltage, and I think the current mirror structure is running out of steam.

Hence I wonder how the AS1115 can be specced at min 2.7V when a green LED can drop this alone.
« Last Edit: May 22, 2026, 02:18:17 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline cv007

  • Super Contributor
  • ***
  • Posts: 1061
Re: Can STLED316 brightness be PWM-controlled?
« Reply #11 on: May 22, 2026, 10:30:54 pm »
Quote
You can but you need to implement 6 x 8 controllable and gated current sinks
Those displays I showed (2 or 3 digits in this case) are running from a single mcu with the only addition being a transistor for each digit. For a CA display the digit transistor is npn and is wired up to drive the common anode (emitter to common anode, collector to power supply). The mcu drives the base and the base current becomes 'naturally' limited so no need for a base resistor. The transistor will source the needed current for however many segments are lit so the power supply sources the current for a digit and the mcu sinks the segment pins and provides the duty cycle by whatever means is available (software, hardware, software+hardware).

A pic16f can easily handle the current requirements for all segments, some other mcu's will be more port current limited so is something to check. The brightness levels and scaling is of your own choosing so you get what you wanted. The interface to the display is of your own choosing- uart, i2c, spi, whatever, and the display mcu does the encoding of segments so you just essentially give a digit an ascii char to display.  I have each digit addressable (using uart) so multiple displays can live on the same 'bus' so doesn't matter whether I want a few digits or many and they are each multiplexing a limited number of digits so brightness levels are maintained regardless of how many digits are ultimately used. If multiplexing effects are not wanted for any reason one can also do a single mcu per digit.

As long as they keep making mcu's you will have display driver and it will make no difference when you change which mcu is used as the main mcu will be using the same protocol to communicate with the display mcu.

Whether that is the 'proper' way to do it or not these displays have been running continuously for years.
 

Offline peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 6029
  • Country: gb
  • Doing electronics since the 1960s...
Re: Can STLED316 brightness be PWM-controlled?
« Reply #12 on: May 23, 2026, 08:59:05 am »
Well, you know the downside, otherwise nobody would buy the display driver chips: somebody needs to write the code, test it, and then somebody has to maintain the development kit (sources and tools) for the expected life of the product, which could be 10-20 years. And re-spin the code when the chip is EOL (like the Atmel 90S1200 is a lot of my products). This becomes impossible in the face of OS changes; you will need to change the tools, deal with a new IDE and new error messages re coding style :) My SCH and PCB software stopped working after winXP, so I run it all in a VMWARE VM. Great for archiving, etc. But in a corporate environment this would be unacceptable. It works but is way more hassle than buying a $1 chip.
« Last Edit: May 23, 2026, 09:17:13 am by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

-->