make pwm output non linear

Non sure if I'm phrasing this well, but is there a way to take a pwm signal to drive an led, and using external components, introduce a non linear curve into the effective current that flows through an led?

The desire is to apply gamma correction to a dimmable led setup, but I dont' want to do it in software, as there is not enough resolution in 8bits to have a smooth 'bottom end' when using this (ie lookup table on arduino) method.

So basically, is there a hardware way to allow me to make more use of those precious 8 bits?

Use a look-up table to do the conversion.

Like I said, if I use a look up table when I only have 8 bits of resolution, the 'jumps' between steps at the bottom of the range are massive, and very noticable

You can extend it a couple more bits by switching between PWM values.

eg. Do PWM 1 0 1 0 1 0 to get brightness "0.5"

This only works well if you do it in sync with the PWM cycle, but you don't say what hardware is involved.

The way to do it in hardware fully is to output an analog voltage and run that voltage through a logrithmic V-I converter to drive an led.

A V-I converter can be an opamp; but the simplest would be to utilize a transistor's b-e junction non-linearity. Simple as that.

Hi dhenry.

Can you point me towards any example circuits that show how to 'utilize a transistor's b-e junction non-linearity' in this way? Also how do you work out the curve that a particular transistor would give you?

Btw, I plant use this if possible in two scenarios -

One is pwm source > non linear correction > mosfet (to control 12 led strip)

The other is pwm source > non linear correction > transistor + constant current source (to control a single hight power led)

Do you think your example can integrate with both these systems?

Many thanks

It is simple: the b-e junction is a diode, so the diode equation applies to its V-I relationship (exponential / logarithmic) in that when you apply a voltage on the b-e junction, the current through the collector goes up exponentially. If you put a led on the collector, that means the led's current goes up exponentially and its brightness goes up linearly.

So take your pwm, pass it through a low-pass filter, and apply it to a npn's base (through a resistor). This creates a linear voltage. And put the led on the collector (to be safe, you can put a small resistor there in case your mcu runs fully cycle on the pwm pin).

You can incorporate this with your other options but quite frankly that makes the whole thing more complicated than it needs to be.

dhenry:
The way to do it in hardware fully is to output an analog voltage and run that voltage through a logrithmic V-I converter to drive an led.

A V-I converter can be an opamp; but the simplest would be to utilize a transistor's b-e junction non-linearity. Simple as that.

That would introduce a hardware derived nonlinearity, however, matching that to a gamma curve would be the challenging part and not as "simple as that". That is the difference between a neat idea and a functioning concept.

Also, gamma correct ion is similar but not entirely correct LED Brightness to your eye, Gamma correction – No! | HP LED Shield

On the other hand, you could use a DAC. These usually have a voltage output and you could use that as the input to a linear I-V converter.
Similar restrictions as above apply, however. The ratio between drive current and light output also is not linear, so now you really have to do some math :sweat_smile:

That's just another neat idea. Of course :zipper_mouth_face:

mrboni:
Hi dhenry.

Can you point me towards any example circuits that show how to 'utilize a transistor's b-e junction non-linearity' in this way? Also how do you work out the curve that a particular transistor would give you?

Btw, I plant use this if possible in two scenarios -

One is pwm source > non linear correction > mosfet (to control 12 led strip)

The other is pwm source > non linear correction > transistor + constant current source (to control a single hight power led)

Do you think your example can integrate with both these systems?

Many thanks

All the analog routes are going to be less efficient than PWM, but fortunately for LEDs only a little bit less efficient
due to the small changes in forwards voltage with current (so that the wasted volts at low current aren't much more than
at full current). Logarithmic converters are prone to temperature sensistivity unless a rather complex circuit using two
transistors and an opamp are used - suggests the proper route is to find a specialised IC that does the appropriate
gamma correction and PWM drive all in one unit - but they don't seem to exist.

The timer1 on standard Arduinos can be set to any cycle count from 2 to 2^16 so much higher PWM resolutions are possible
(on pins 9 and 10 only). Arduino Megas have mainly 16 bit timer/counter units so much more capable.

The problem with the log converters is that you loose the PWM signal. This means there is a dead region where you are not outputting enough voltage to turn the LED on. So you end up with the same sort of precision as if you had used software, perhaps even worse.

The answer is to use an external LED driver chip with more bits.

I was just thinking about the implications of not having pwm anymore.

Do you know of any drivers or pwm generators that are similar to the ws2801? Ie can be daisy chained on the spi bus or similar? I really like how modular and expandable these chips are.

I was just thinking about the implications of not having pwm anymore.

None. The analog approach requires a linear voltage input, that can be (but doesn't have to be) generated by the pwm pins.

Headroom:
On the other hand, you could use a DAC. These usually have a voltage output and you could use that as the input to a linear I-V converter.
Similar restrictions as above apply, however. The ratio between drive current and light output also is not linear, so now you really have to do some math :sweat_smile:

That's just another neat idea. Of course :zipper_mouth_face:

You're going to use a DAC for every single LED...?

All the other brilliant schemes are in the same boat, the idea of adding extra transistors and filters to every single LED is a bit, um, "impractical".

mrboni:
Do you know of any drivers or pwm generators that are similar to the ws2801? Ie can be daisy chained on the spi bus or similar? I really like how modular and expandable these chips are.

I don't think there's any with more than 8-bit PWM resolution.

Did you try my suggestion of interpolation? Refresh the string as fast as you can and alternate between the two PWM values nearest to the output value you really want.

eg. For PWM value 0.5 alternate between 0 and 1.

It should give you a tiny bit more resolution. You could even try extending it to a cycle of four values so (ie. you can output "0.25" by cycling 1000100010001000 in PWM).

I've done it with a TLC5940 and it works very well. It might not work as well with a WS2801 though because you can't sync the changes to the chip's internal PWM cycle.

OTOH I imagine alternating between 0 and 1 will work and that's enough to give you 64 output steps instead of 32 (8-bit PWM only translates to about 32 linear steps after gamma correction).

I don't think there's any with more than 8-bit PWM resolution.

Yes there are:-
The TLC series for a start, TCL5940 the old favorite and then there is the easier to use TCL5945 and TCL5947 these are 12 bit PWM with an SPI like interface and constant current outputs.

The PCA9685 is also a 12 bit PWM but with an I2C interface, it has not got constant current output so you either need to include a resistor in line with the LED.

Thsi board available from Adafruit Adafruit 16-Channel 12-bit PWM/Servo Driver - I2C interface [PCA9685] : ID 815 : $14.95 : Adafruit Industries, Unique & fun DIY electronics and kits employs the PCA9685
.
Or get something similar (I guess ) therough Grumpy Mike:
Arduino Forum

Grumpy_Mike:

I don't think there's any with more than 8-bit PWM resolution.

Yes there are:-
The TLC series for a start, TCL5940 the old favorite and then there is the easier to use TCL5945 and TCL5947 these are 12 bit PWM with an SPI like interface and constant current outputs.

Yes, of course....but they're not really "similar to the ws2801". The amount of wire you'd need to make a long string of RGB LEDs using TLC5940s is ridiculous.