Shop OBEX P1 Docs P2 Docs Learn Events
Dimming a 74HC595 with the Output Enable pin? — Parallax Forums

Dimming a 74HC595 with the Output Enable pin?

eagletalontimeagletalontim Posts: 1,399
edited 2014-04-09 20:58 in Propeller 1
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

  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2014-04-09 17:45
    Hi eagletalontim;
    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.
    Yes it would, assuming appropriate LED connections to either directly or an external driver.
    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
  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-04-09 17:58
    I have two active projects using my 2x 74HC595 pwm object, but you don't want individual control, just overall control -- right?

    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%.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2014-04-09 18:21
    I have it working with some code I found that was posted in another thread a long time ago. The display level does not change much between 100% and 50%, but lower than that, it changes dramatically.
    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 * SCALE
    
  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-04-09 19:02
    I believe some of this has to do with the way out eye works; we don't see linear changes in a linear manner. This is why professional lighting systems allow curves to be applied to fixtures; it allows fade-up and fade-down commands to look right.

    A guy who used to work for Disneyland told me that he would often do a pseudo-log curve with this formula:

    level * level / range
  • Clock LoopClock Loop Posts: 2,069
    edited 2014-04-09 19:08
    The display level does not change much between 100% and 50%, but lower than that, it changes dramatically.

    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.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-04-09 20:46
    When attempting a Larson scanner type display with a strand of WS2801 LEDs, I wanted the main LED to be surrounded by LEDs which faded in brightness with increased distance from the main LED. A linear fade did not look good. I ended up halving the brightness with each LED position away from the main LED. This logrithmic fade looked much better than a linear fade.

    I'll need to try the Disneyland fade next time.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-04-09 20:58
    I used the same technique for dimming the 7-segment daughterboard displays that Parallax used to sell. The schematic is attached.

    -Phil
Sign In or Register to comment.