Dimming a 74HC595 with the Output Enable pin?
As the title states, I would like to dim the LED display with the output enable (OE) pin on the 74HC595. I have plenty of free cogs and was hoping to have a cog toggle the OE pin to dim the display based on a 0 to 100 variable.

Comments
Of course, the output enable controls all the outputs.
You could also use a cog to shift data very rapidly and get dimming that way.
Duane J
That's easily done with a fixed frequency pwm cog written in Spin. You can in fact control up to two fixed frequency PWM outputs (using both counters), so long as they can run them at the same frequency (I do this for motor control).
I knocked up this bit of code an tested it on a QuickStart. It works.
pub main | level cognew(ez_pwm(16, @duty, 500), @pwmstack) repeat repeat level from 0 to 100 set_pwm(level) waitcnt(cnt + (clkfreq / 100)) repeat level from 100 to 0 set_pwm(level) waitcnt(cnt + (clkfreq / 100)) pub set_pwm(percent) percent := 0 #> percent <# 100 duty := pwmtix * percent / 100 pri ez_pwm(pin, p_duty, freq) | t ' launch with cognew() ctra := (%00100 << 26) | pin ' PWM / NCO frqa := 1 ' setup frq for pwm dira[pin] := 1 ' make pin an output pwmtix := clkfreq / freq ' set loop timing t := cnt repeat phsa := -long[p_duty] waitcnt(t += pwmtix)Keep in mind that the 74HC595 uses an active-low OE pin, so you'll need to invert you level, that is, for 25% brightness you'll set the PWM level to 75%.
CON _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq MS_001 = CLK_FREQ / 1_000 ' LED Dimming stuff #(-1), IS_ON, IS_OFF MAX_DISPLAY_BRIGHTNESS = 99 SCALE = (posx / MAX_DISPLAY_BRIGHTNESS) << 1 DAT User_Setting20 LONG 50 ' change this to brightness %. This gets changed in the menu and the change can be visibly seen by the user. VAR LONG displayStack[100] PUB Main cognew(display_brightness, @displayStack) Display("8") ' make the display show an 8 for maximum brightness testing PUB display_brightness | t ctra := (%00110 << 26) | LED_Output_Enable ' DUTY mode on LED_output_enable pin dira[LED_Output_Enable]~~ outa[LED_Output_Enable] := 0 t := cnt repeat set_duty(100 - User_Setting20) waitcnt(t += (10 * MS_001)) pub set_duty(duty) duty := 1 #> duty <# MAX_DISPLAY_BRIGHTNESS ' limit to legal range frqa := duty * SCALEA guy who used to work for Disneyland told me that he would often do a pseudo-log curve with this formula:
level * level / range
VERY common. Find a resistor value that is so restrictive on the LED that its right on the edge of max brightness.
Also using pulses that don't maintain 40% the entire time, find a good swap.
For instance, pulse one for 25% and then do the next pulse 75% and yet the next 25% etc... Don't use linear values in your pwm output. (all one % for the given brightness) alternate between % every other beat or so.
I'll need to try the Disneyland fade next time.
-Phil