I'd like to PWM one channel of LEDS at 3 different levels, based on 1 trigger.
Is it possible to use p6 as the input trigger, LEDs wired to an HC-2 board, controlled via P0
At power up, LEDS are at 50%
p6 triggers LEDs to go to 10%
p6 triggers LEDs to go to 100%
p6 triggers program to reset to beginning of program
I have not been able to locate an existing program that does something similar to reference, and this is something I have not done before.
I could be wrong but I don't think the Prop-1 can monitor an input while executing PWM.
You could do this using 3 outputs and resistors to get 50% and 10%.
Yesterday I wrote one of the most complicated Prop-1 programs in EFX-TEK history: it scans three inputs, uses those inputs to turn a "candle" on and off (one per input), and actually keeps track of the order things were turned on and turned off (this is an escape room puzzle). Trust me, it's complicated, and yet I managed to squeeze that into a Prop-1 with 20% of the memory left using some gnarly tricks.
So... I originally agreed with Jack, but then decided to take a non-standard approach. The BS1 PWM command is only active when it is running. If you get back to it soon enough, though, you can "get away with it" because the behavior of our eyes will smooth things out.
I ran this code on a Prop-1 with a Trainer and I don't see any visible flashing. On you high-current LED, this may not be the case, so you could add a big cap to treat the LED like a giant WickLED. The key here is that I refresh the LED between every other line of code.
' =========================================================================
'
' File......
' Purpose...
' Author....
' E-mail....
' Started...
' Updated...
'
' {$STAMP BS1}
' {$PBASIC 1.0}
'
' =========================================================================
' -----[ Program Description ]---------------------------------------------
' -----[ Revision History ]------------------------------------------------
' -----[ I/O Definitions ]-------------------------------------------------
SYMBOL Trigger = PIN6 ' SETUP = DN
SYMBOL LedOut = 0
' -----[ Constants ]-------------------------------------------------------
SYMBOL Yes = 1
SYMBOL No = 0
' -----[ Variables ]-------------------------------------------------------
SYMBOL btnState = B0 ' button state
SYMBOL newBtn = BIT0
SYMBOL oldBtn = BIT1
SYMBOL ledState = B3
SYMBOL ledLevel = B4
' -----[ Initialization ]--------------------------------------------------
Reset:
PINS = %00000000 ' all off
DIRS = %00000001 ' LED is output
ledLevel = 127
' -----[ Program Code ]----------------------------------------------------
Main:
PWM LedOut, ledLevel, 3 ' refresh LED
Scan_Button:
oldBtn = newBtn ' shift last scan left
newBtn = Trigger
PWM LedOut, ledLevel, 3
Check_State:
IF btnState <> %10 THEN Main ' look for release
PWM LedOut, ledLevel, 3
ledstate = ledState + 1 // 3 ' update LED state
PWM LedOut, ledLevel, 3
LOOKUP ledState, (127, 26, 255), ledLevel ' 50%, 10%, 100%
GOTO Main
Since first posting I made a small change. Scanning the button was:
btnState = btnState * 2 | Trigger & %11
...was replaced by:
oldBtn = newBtn
newBtn = Trigger
The second takes two lines, but is far less complex than the first and will run faster. Speed is everything in this program.
Works perfect, as always. Jon, you are amazing. Thank you so much.
Always a pleasure to help. Looking forward to seeing you in St. Louis.
Just a note: I used linear values in the table for brightness, but you may find that the 10% and 50% settings don't seem to have that relationship with the 100% setting. This is due to the way LEDs work and the way our eyes respond to the light from them. When using the Propeller or other advanced processor, I have a gamma table which adjusts the normal linear output (0..255) to values that look better to our eyes.
You might try these values on the update line:
LOOKUP ledState, (42, 2, 255), ledLevel ' 50%, 10%, 100%
The gamma table dims the mid-range levels to correct their apparent brightness.
Here's the table that I use in my Propeller LED driver. This table is the same size as the Prop-1 memory!
dat { gamma table }
GammaTable byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
byte 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1
byte 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3
byte 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7
byte 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12
byte 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20
byte 20, 21, 21, 22, 22, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29
byte 30, 31, 31, 32, 33, 34, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42
byte 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57
byte 58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70, 71, 72, 73, 75
byte 76, 77, 78, 80, 81, 82, 84, 85, 86, 88, 89, 90, 92, 93, 94, 96
byte 97, 99, 100, 102, 103, 105, 106, 108, 109, 111, 112, 114, 115, 117, 119, 120
byte 122, 124, 125, 127, 129, 130, 132, 134, 136, 137, 139, 141, 143, 145, 146, 148
byte 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180
byte 182, 184, 186, 188, 191, 193, 195, 197, 199, 202, 204, 206, 209, 211, 213, 215
byte 218, 220, 223, 225, 227, 230, 232, 235, 237, 240, 242, 245, 247, 250, 252, 255
I got a PM request to set the levels based on individual inputs -- I think this will do the trick (I'm traveling this week so I cannot test the code).
' =========================================================================
'
' File...... prop-1_pwm_x3.bs1
' Purpose...
' Author....
' E-mail....
' Started...
' Updated...
'
' {$STAMP BS1}
' {$PBASIC 1.0}
'
' =========================================================================
' -----[ Program Description ]---------------------------------------------
' -----[ Revision History ]------------------------------------------------
' -----[ I/O Definitions ]-------------------------------------------------
SYMBOL Btn6 = PIN6 ' SETUP = DN
SYMBOL Btn5 = PIN5
SYMBOL Btn4 = PIN4
SYMBOL LedOut = 0
' -----[ Constants ]-------------------------------------------------------
SYMBOL Yes = 1
SYMBOL No = 0
SYMBOL X_Bright = 127 ' led levels
SYMBOL Y_Bright = 26
SYMBOL Z_Bright = 255
' -----[ Variables ]-------------------------------------------------------
SYMBOL ledLevel = B2
' -----[ Initialization ]--------------------------------------------------
Reset:
PINS = %00000000 ' all off
DIRS = %00000001 ' LED is output
ledLevel = X_Bright
' -----[ Program Code ]----------------------------------------------------
Chk_IN6:
PWM LedOut, ledLevel, 3 ' refesh LED
IF Btn6 = 0 THEN Chk_IN5 ' check button
PWM LedOut, ledLevel, 3 ' refesh LED
ledLevel = X_Bright ' set new level
Chk_IN5:
PWM LedOut, ledLevel, 3
IF Btn5 = 0 THEN Chk_IN4
PWM LedOut, ledLevel, 3
ledLevel = Y_Bright
Chk_IN4:
PWM LedOut, ledLevel, 3
IF Btn4 = 0 THEN Chk_IN6
PWM LedOut, ledLevel, 3
ledLevel = Z_Bright
PWM LedOut, ledLevel, 3
GOTO Chk_IN6
Jon,
Thank you for the update, it worked great!
What would we have to do to get it to ramp between level changes? IE, going from 0 to 100 (X and Y in the program, respectively) we would want a fade over "R" where R is ramp time in seconds.
You would need to add a FOR-NEXT loop in the mix. Would be tricky, but could be done. Programming is about specifics -- if you give me specifics, I'll see what I can do. Mind you, the Prop-1 is a very small controller and you will not get the control available from an advanced processor like the Propeller we use in the HC-8+ (which can handle multiple simultaneous fades).
Quote from: JonnyMac on May 23, 2017, 10:02:01 AM
You would need to add a FOR-NEXT loop in the mix. Would be tricky, but could be done. Programming is about specifics -- if you give me specifics, I'll see what I can do. Mind you, the Prop-1 is a very small controller and you will not get the control available from an advanced processor like the Propeller we use in the HC-8+ (which can handle multiple simultaneous fades).
Jon,
I've attached the code that I ended up using. It's identical to what you last posted, I just changed some of the values for dimming to suit our (very non linear!) LED's.
As far as the fade function, our needs are really simple. From any state change to any other state change, ramp over "R" milliseconds. IE, if the current state is "0 brightness" (Input 5, Y_Bright) and "Input 6" is selected (30, X_Bright), ramp from 0 to 30 in "R" milliseconds. If "Input 4" (160, Z_Bright) is then selected, ramp from 30 to 160 in "R" milliseconds. Then if "Input 5" (0, Y_Bright) is selected, ramp from 160 to 0 over "R" milliseconds.
Basically any state change to any other will ramp over "R" span of time. I'm completely ok with global variable that sets the fade time between any state.
' =========================================================================
'
' File...... Evilusions_Escape_Elevator_Lights_PWM_Rev2.00.bs1
' Purpose...
' Author.... Jon / EFX TEK
' E-mail....
' Started...
' Updated...
'
' {$STAMP BS1}
' {$PBASIC 1.0}
'
' =========================================================================
' -----[ Program Description ]---------------------------------------------
' -----[ Revision History ]------------------------------------------------
' R2.00 5/17/2017 - Updated version of Jon's program with independant input control. Updated level values to align with LED's
'
'
'
'
' -----[ I/O Definitions ]-------------------------------------------------
SYMBOL Btn6 = PIN6 ' SETUP = DN
SYMBOL Btn5 = PIN5
SYMBOL Btn4 = PIN4
SYMBOL LedOut = 0
' -----[ Constants ]-------------------------------------------------------
SYMBOL Yes = 1
SYMBOL No = 0
SYMBOL X_Bright = 30 ' led levels
SYMBOL Y_Bright = 0
SYMBOL Z_Bright = 160
' -----[ Variables ]-------------------------------------------------------
SYMBOL ledLevel = B2
' -----[ Initialization ]--------------------------------------------------
Reset:
PINS = %00000000 ' all off
DIRS = %00000001 ' LED is output
ledLevel = X_Bright
' -----[ Program Code ]----------------------------------------------------
Chk_IN6:
PWM LedOut, ledLevel, 3 ' refesh LED
IF Btn6 = 0 THEN Chk_IN5 ' check button
PWM LedOut, ledLevel, 3 ' refesh LED
ledLevel = X_Bright ' set new level
Chk_IN5:
PWM LedOut, ledLevel, 3
IF Btn5 = 0 THEN Chk_IN4
PWM LedOut, ledLevel, 3
ledLevel = Y_Bright
Chk_IN4:
PWM LedOut, ledLevel, 3
IF Btn4 = 0 THEN Chk_IN6
PWM LedOut, ledLevel, 3
ledLevel = Z_Bright
PWM LedOut, ledLevel, 3
GOTO Chk_IN6