November 24, 2024, 02:16:38 PM

News:

Got VSA?  Want to use your Prop-SX?  Now you can!  See the VSA section of the Library forum for Prop-SX code that works with VSA.


Controlling LEDs with the PWM command

Started by RobertB, August 13, 2009, 01:50:23 PM

Previous topic - Next topic

RobertB

I have been playing around with the PWM command on the Prop-1.  I want to bring up my LED spotlights to max brightness in about 3 to 5 seconds without the light intensity going "clunk" when I engage the HIGH command.

Do you have any recommendations for values for the FOR loop and the PWM command?

JonnyMac

Without seeing your code that's going "clunk" I can only give you recommendations.

1) The cycle time for the Prop-1 PWM is 5ms, so a 5-second fade up requires 1000 cycles -- you can get close with this:

Fade_Up:
  FOR level = 1 TO 255
    PWM Led, level, 4
  NEXT
  HIGH Led


This will actually give you about a 5.1-second fade up. (255 x 4 x 0.005).

2) Part of the clunk may be the short delay between the last level and the HIGH command.  Since PWM leaves the pin in an input state when finishing there is a *tiny* off time between the last PWM cycle and executing HIGH.  You can dampen this with a capacitor; I'd chuck a 47uF, 25v cap between the V+ and the OUTx terminal that you're using.
Jon McPhalen
EFX-TEK Hollywood Office

RobertB

The Capacitor trick didn't work as expected.  Not a big deal.  The code:

  FOR level = 0 TO 255 STEP 1                   ' ramp on
      PWM Led, level, 4
  NEXT
  HIGH Led

Seems to work well enough.

I would like to slow down the ramp on in the lower range where the brightness change is most noticeable.  With floating point math I would do:

FOR level = 0 TO 255 STEP 1
rlevel = float(level/255.) ' convert to 0.00 to 1.00
rlevel = rlevel*rlevel  'take the square to produce parabolic ramp
level = int(floor(rlevel*255)) 'convert back to integer 0 to 255 range
PWM Led, level, 4
NEXT  'etc

Anyway to do that in integer math?

JonnyMac

Have a look at this -- the second version squares the level and uses the high byte of the square; this is the same as dividing the square by 256.

' =========================================================================
'
'   File...... PWM_Test.BS1
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'              Copyright (c) 2009 EFX-TEK
'              Some Rights Reserved
'              -- see http://creativecommons.org/licenses/by/3.0/
'   E-mail.... jwilliams@efx-tek.com
'   Started...
'   Updated...
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------


' -----[ Revision History ]------------------------------------------------


' -----[ I/O Definitions ]-------------------------------------------------

SYMBOL  LED             = 0


' -----[ Constants ]-------------------------------------------------------

SYMBOL  IsOn            = 1                     ' for active-high in/out
SYMBOL  IsOff           = 0

SYMBOL  Yes             = 1
SYMBOL  No              = 0


' -----[ Variables ]-------------------------------------------------------

SYMBOL  bLevel          = B2                    ' 0..255

SYMBOL  wLevel          = W5                    ' 0..65535
SYMBOL   wLvl0          =  B10                  ' low byte of wLevel
SYMBOL   wLvl1          =  B11                  ' high byte of wLevel


' -----[ Initialization ]--------------------------------------------------

Reset:
  PINS = %00000000                              ' clear all
  DIRS = %00000001                              ' set output pins


' -----[ Program Code ]----------------------------------------------------

Main:
  FOR bLevel = 0 TO 255
    PWM Led, bLevel, 4
  NEXT
  HIGH Led
  PAUSE 1000
  LOW Led
  PAUSE 1000

  FOR bLevel = 0 TO 255
    wLevel = bLevel * bLevel                    ' square level
    PWM Led, wLvl1, 4                           ' use high byte of square
  NEXT
  HIGH Led
  PAUSE 1000
  LOW Led
  PAUSE 1000

  GOTO Main


' -----[ Subroutines ]-----------------------------------------------------


' -----[ User Data ]-------------------------------------------------------
Jon McPhalen
EFX-TEK Hollywood Office

RobertB

This is looking better.  The ramp up appears to be more linear.    Still seeing some "fluttering" of the light intensity in the second loop. This might be because of the time taken to do the square?  Whatever.

Will I get generally better results using the PWM command on a Prop-2 board because of it's faster clock?  How would this test program translate to the Prop-2?

JonnyMac

The problem is that LEDs an non-linear and the Prop-1 and Prop-2 are not able to do PWM the way you want to.  The best solution would be a Prop-SX which can PWM the pin in the background so you never have to worry about "off" bobbles between instructions.

Here's the code translated to the Prop-2; perhaps it's fast enough to do what you want more smoothly:

' =========================================================================
'
'   File...... PWM_Test.BS1
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'              Copyright (c) 2009 EFX-TEK
'              Some Rights Reserved
'              -- see http://creativecommons.org/licenses/by/3.0/
'   E-mail.... jwilliams@efx-tek.com
'   Started...
'   Updated...
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------


' -----[ Revision History ]------------------------------------------------


' -----[ I/O Definitions ]-------------------------------------------------

Led             PIN     0


' -----[ Constants ]-------------------------------------------------------

IsOn            CON     1                     ' for active-high in/out
IsOff           CON     0

Yes             CON     1
No              CON     0


' -----[ Variables ]-------------------------------------------------------

bLevel          VAR     Byte                    ' 0..255
wLevel          VAR     Word                    ' 0..65535


' -----[ Initialization ]--------------------------------------------------

Reset:
  OUTS = $0000                                  ' clear all
  DIRS = $0001                                  ' set output pins


' -----[ Program Code ]----------------------------------------------------

Main:
  FOR bLevel = 0 TO 255
    PWM Led, bLevel, 20
  NEXT
  HIGH Led
  PAUSE 1000
  LOW Led
  PAUSE 1000

  FOR bLevel = 0 TO 255
    wLevel = bLevel * bLevel                    ' square level
    PWM Led, wLevel.HIGHBYTE, 20                ' use high byte of square
  NEXT
  HIGH Led
  PAUSE 1000
  LOW Led
  PAUSE 1000

  GOTO Main


' -----[ Subroutines ]-----------------------------------------------------


' -----[ User Data ]-------------------------------------------------------



Another thing you could try is to create a 256-element data table of brightness values to be read from the loop; this would give you absolute control of the brightness curve.
Jon McPhalen
EFX-TEK Hollywood Office

RobertB

OK.  Assuming I compute the correct values for a non-linear ramp, in Bs2 land this would be:

DATA 0,1,2,3,4,... ...253,254,255  '(for a linear ramp, 256 values)

'and read by:
FOR val = 0 TO 255
   READ val Level
   'DEBUG Level
   PWM Led, Level, 20
NEXT

Is that right?  The prop1 has 255 locations of available EPROM so could this be done on the prop1 as well using the EPROM command?

JonnyMac

August 16, 2009, 09:43:43 PM #7 Last Edit: August 17, 2009, 09:02:09 AM by JonnyMac
The Prop-1 has 256 total EEPROM locations -- this is for program and data space so you cannot have a table with that many elements.

With the BS2 it's best to use a named table; define it like this:

Brightness      DATA    000, 001, 002, 003, 004, 005, 006, 007
                DATA    008, 009, 010, 011, 012, 013, 014, 015


... etc., then read it like this:

  FOR idx = 0 TO 255
    READ Brightness + idx, level
    PWM LED, level, 20
  NEXT


By using named tables there is no ambiguity.
Jon McPhalen
EFX-TEK Hollywood Office

RobertB

August 17, 2009, 05:47:05 AM #8 Last Edit: August 17, 2009, 09:35:53 AM by JonnyMac
I'm getting a stupid syntax error here.  Jon, What silly thing am I doing wrong?  I'm new to Prop-2 syntax.


Program Edited by Jon Williams
-- DATA table corrected and moved to end of listing

' =========================================================================
'
'   File......
'   Purpose...
'   Author....
'   E-mail....
'   Started...
'   Updated...
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------


' -----[ I/O Definitions ]-------------------------------------------------

Led             PIN     0


' -----[ Constants ]-------------------------------------------------------

IsOn            CON     1                     ' for active-high in/out
IsOff           CON     0

Yes             CON     1
No              CON     0


' -----[ Variables ]-------------------------------------------------------

bLevel          VAR     Byte                    ' 0..255
wLevel          VAR     Word                    ' 0..65535
idx             VAR     Byte


' -----[ Initialization ]--------------------------------------------------

Reset:
  OUTS = $0000                                  ' clear all
  DIRS = $0001                                  ' set output pins


' -----[ Program Code ]----------------------------------------------------

Main:
  FOR bLevel = 0 TO 255
    PWM Led, bLevel, 20
  NEXT
  HIGH Led
  PAUSE 1000
  LOW Led
  PAUSE 1000


  FOR idx = 0 TO 255
    READ Brightness + idx, bLevel
    PWM Led, bLevel, 20
  NEXT

  HIGH Led
  PAUSE 1000
  LOW Led
  PAUSE 1000

  GOTO Main


' -----[ Subroutines ]-----------------------------------------------------


' -----[ User Data ]-------------------------------------------------------

Brightness      DATA    000, 000, 000, 000, 000, 000, 000, 000
                DATA    000, 000, 000, 000, 000, 000, 000, 000
                DATA    001, 001, 001, 001, 001, 001, 001, 002
                DATA    002, 002, 002, 002, 003, 003, 003, 003
                DATA    004, 004, 004, 004, 005, 005, 005, 005
                DATA    006, 006, 006, 007, 007, 007, 008, 008
                DATA    009, 009, 009, 010, 010, 010, 011, 011
                DATA    012, 012, 013, 013, 014, 014, 015, 015
                DATA    016, 016, 017, 017, 018, 018, 019, 019
                DATA    020, 020, 021, 021, 022, 023, 023, 024
                DATA    025, 025, 026, 026, 027, 028, 028, 029
                DATA    030, 030, 031, 032, 033, 033, 034, 035
                DATA    036, 036, 037, 038, 039, 039, 040, 041
                DATA    042, 043, 043, 044, 045, 046, 047, 048
                DATA    049, 049, 050, 051, 052, 053, 054, 055
                DATA    056, 057, 058, 059, 060, 061, 062, 063
                DATA    064, 065, 066, 067, 068, 069, 070, 071
                DATA    072, 073, 074, 075, 076, 077, 078, 079
                DATA    081, 082, 083, 084, 085, 086, 087, 089
                DATA    090, 091, 092, 093, 095, 096, 097, 098
                DATA    100, 101, 102, 103, 105, 106, 107, 108
                DATA    110, 111, 112, 114, 115, 116, 118, 119
                DATA    121, 122, 123, 125, 126, 127, 129, 130
                DATA    132, 133, 135, 136, 138, 139, 141, 142
                DATA    144, 145, 147, 148, 150, 151, 153, 154
                DATA    156, 157, 159, 160, 162, 164, 165, 167
                DATA    169, 170, 172, 173, 175, 177, 178, 180
                DATA    182, 183, 185, 187, 189, 190, 192, 194
                DATA    196, 197, 199, 201, 203, 204, 206, 208
                DATA    210, 212, 213, 215, 217, 219, 221, 223
                DATA    225, 226, 228, 230, 232, 234, 236, 238
                DATA    240, 242, 244, 246, 248, 250, 252, 254

livinlowe

IDx doesnt have to a word if you are just doing 256 levels. And I don't think you can list your data elements like that ( I've never seen it done that way)
Shawn
Scaring someone with a prop you built -- priceless!

JonnyMac

I corrected the listing above; it works now.  I also corrected my suggestion post to give you better detail on constructing a DATA table with the Prop-2.  Please keep in mind that the editor has online Help and with a button click you can always get the correct syntax.

Notes:
1) Please don't post programs with my name on them -- if you modify something I write, take my name off
    -- espeically if the program is broken
2) Be careful with LOOOOONNNNGGG listings as they really make the forum hard to read -- attach long listings
Jon McPhalen
EFX-TEK Hollywood Office

RobertB

I was able to shorten down the loop to just this:

  FOR idx = 0 TO 255
    PWM Led, brightness+idx, 20
  NEXT

This actually works.  The ramp curve looks good and the flickering of the LED is all but gone. 

Thanks for all your help, Jon.

JonnyMac

August 17, 2009, 09:33:21 AM #12 Last Edit: August 17, 2009, 09:36:58 AM by JonnyMac
That is not doing what you think -- Brightness is an compiler-generated constant that will be set to zero because you only have one DATA table and data tables start at address $00 in the EEPROM.  In effect, you've gone back to the old [linear] loop.  PBASIC is not as sophisticated as other versions of BASIC and you cannot "shortcut" the language as some PC versions allow. 
Jon McPhalen
EFX-TEK Hollywood Office

RobertB

One last question:   If all I want is say, a 5 second fade up, using 12 volts, could I do it simpler with a big capacitor and just turn the circuit on?  How large a cap would I need?  I know there is an equation for that someplace...

JonnyMac

No, that's not a good idea.  Caps have a very non-linear charge curve and you would be forced to buffer the output through an op-amp or similar device.  Use PWM in a loop and one of the OUTx outputs.  I've done this for "monster eyes" on many props.
Jon McPhalen
EFX-TEK Hollywood Office