I must sound like a broken record, but thanks again Darrel. I greatly appreciate you taking the time to help me with my project.
I must sound like a broken record, but thanks again Darrel. I greatly appreciate you taking the time to help me with my project.
As the purpose of this project is to create 5 blinking LEDs that simulate old 1960's Christmas tree lights, I've added the following code to fade in/out the LED:
I'll program a 12F683 this afternoon and see what it looks like.Code:IsOn VAR BYTE[LEDCount] i VAR BYTE FOR x = 0 to (LEDCount - 1) ; set initial LED state to OFF IsOn(x) = 0 NEXT x ;----[Main Program Loop]---------------------------------------- Main: x = (x + 1) // LEDcount IF LoopLED(x) < OnTime(x) THEN IF IsOn(x) = 1 THEN READ Brightness + x, Bright(x) ELSE IsOn(x) = 1 ; Fade up LED to set brightness FOR i = 0 to Bright(x) Step 1 Bright(x) = i PAUSE 20 NEXT i ENDIF ELSE IF IsOn(x) = 1 THEN IsOn(x) = 0 ; Fade out LED FOR i = Bright(x) to 0 Step -1 Bright(x) = i PAUSE 20 NEXT i ELSE Bright(x) = 0 ENDIF ENDIF LoopLED(x) = (LoopLED(x) + 1) // (OnTime(x) + OffTime(x)) #IFDEF USE_RANDOM_SEQUENCE RandPeriod(x) = RandPeriod(x) - 1 IF RandPeriod(x) = 0 THEN READ RandPeriods+(x<<1), WORD RandPeriod(x) RANDOM RND OnTime(x) = (MAX_ON - MIN_ON)* RND.HighByte / 255 + MIN_ON OffTime(x)= (MAX_OFF - MIN_OFF)* RND.LowByte / 255 + MIN_OFF ENDIF #ENDIF IF x != (LEDcount - 1) THEN Main Waiting: IF !TMR0IF THEN Waiting TMR0 = 99 TMR0IF = 0 GOTO Main
Last edited by RossWaddell; - 29th March 2014 at 16:01.
I should've known - the PAUSE command will interfere with the on/off timings. I'll try a lower PAUSE value but then the 'ramping up/down' effect I'm trying to achieve won't really be visible.
The timing of the program is done by counting 10mS periods.
So the entire loop can't take more than 10mS.
When the LED is supposed to be ON, just add a certain amount to the dutycycle each time through the loop until it reaches the set maximum.
The amount you add will determine the speed of the fade.
Subtract some when it is supposed to be OFF, until it reaches 0 or underflows.
Don't add any pauses.
Last edited by Darrel Taylor; - 29th March 2014 at 17:14.
DT
Do you mean something like this (I'm sure there's more elegant code, but ...):
Code:temp VAR WORD ;----[Main Program Loop]---------------------------------------- Main: x = (x + 1) // LEDcount IF LoopLED(x) < OnTime(x) THEN READ Brightness + x, temp IF Bright(x) < temp THEN Bright(x) = Bright(x) + 2 ELSE Bright(x) = temp ENDIF ELSE IF Bright(x) > 0 THEN Bright(x) = Bright(x) - 2 ELSE Bright(x) = 0 ENDIF ENDIF LoopLED(x) = (LoopLED(x) + 1) // (OnTime(x) + OffTime(x)) #IFDEF USE_RANDOM_SEQUENCE RandPeriod(x) = RandPeriod(x) - 1 IF RandPeriod(x) = 0 THEN READ RandPeriods+(x<<1), WORD RandPeriod(x) RANDOM RND OnTime(x) = (MAX_ON - MIN_ON)* RND.HighByte / 255 + MIN_ON OffTime(x)= (MAX_OFF - MIN_OFF)* RND.LowByte / 255 + MIN_OFF ENDIF #ENDIF IF x != (LEDcount - 1) THEN Main Waiting: IF !TMR0IF THEN Waiting TMR0 = 99 TMR0IF = 0 GOTO Main
That's Perfect!!
May take more than 2 for the Speed, but well done!
DT
In preparation for the next step I had written this almost identical code.
There are a few differences that might be of benefit.
Code:MaxBright VAR BYTE FadeSpeed CON 20 ;----[Main Program Loop]---------------------------------------- Main: x = (x + 1) // LEDcount IF LoopLED(x) < OnTime(x) THEN READ Brightness + x, MaxBright IF Bright(x) <= (MaxBright - FadeSpeed) THEN Bright(x) = Bright(x) + FadeSpeed ELSE Bright(x) = Maxbright ENDIF ELSE IF Bright(x) >= FadeSpeed THEN Bright(x) = Bright(x) - FadeSpeed ELSE Bright(x) = 0 ENDIF ENDIF
DT
Looks like 6 is the magic number.
(If this is bad etiquette to re-open a 1-yr old thread then I'll start a new one)
Well, what was working (I think) last year isn't this year as I prepare to move this to production with a SMT version of the 12F683. The blinking still works but the brightness control doesn't - no matter what the values are for Brightness all 5 LEDs appear to not change (they're still way too bright).
As you can see, I haven't implemented Darrel's most recent suggestion (probably because a year ago this was working OK).Code:'**************************************************************** '* Name : Nacelle_Blinking_Lights_12F683_8Mhz_Int.pbp * '* Author : Ross A. Waddell * '* Notice : Copyright (c) 2015 * '* : All Rights Reserved * '* Date : 06/30/2015 * '* Version : 3.0 * '* Notes : Blinking nacelle engine lights (TOS Enterprise) * '* * '**************************************************************** ' Nacelle engine lights ' ===================== ' (a) The colours used were: red, blue, green, amber and pink, all standard ' colours they had for common Christmas lights of the time. ' (b) They were all C7 Christmas lights (too big for a 1/350). 12 by my guess. ' (c) Amber was steady (5 in a star pattern), all the rest blinked. ' For production version of this code, update config fuses to ' enable code protect (CP_ON) ' Basic blinky code provided by Darrel Taylor ' See forum posting here: ' http://www.picbasic.co.uk/forum/showthread.php?t=17299&p=116934#post116934 ' *************************************************************** ' Pin Connections ' *************************************************************** ' GP5 -> pin 2 -> R4 -> BL4 ' GP4 -> pin 3 -> R5 -> BL5 ' GP3 -> pin 4 -> MCLR (input only, 'dummy' BL6) ' GP2 -> pin 5 -> R1 -> BL1 ' GP1 -> pin 6 -> R2 -> BL2 ' GP0 -> pin 7 -> R3 -> BL3 ' *************************************************************** ' Initialization ' *************************************************************** ' If not using the MCLR pin as in input, there is no need to add an external resistor to tie it ' to VDD if the PIC has an internal pull-up. See http://www.picbasic.co.uk/forum/archive/index.php/t-872.html ' MCLR=OFF means that MCLR is handled INTERNALLY and that pin can be used for I/O (Input actually). ' Whatever you do to the pin in this instance will have no bearing on the PIC running or not. It will ' be just another INPUT pin. You could leave it floating if it was unused. #CONFIG __config _INTOSCIO & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOD_ON & _IESO_OFF & _FCMEN_OFF #ENDCONFIG DEFINE OSC 8 OSCCON = %01110000 ; 8MHz internal osc ANSEL = 0 ; All Digital CMCON0 = 7 TRISIO = 0 ; all OUTPUT OPTION_REG = %00000110 ; Timer0 prescaler 1:128 TMR0IF VAR INTCON.2 ; Timer0 Overflow bit ;----[ MIBAM Setup ]--------------------------------------------- wsave var byte $70 SYSTEM ' Alternate save location for W ssave VAR BYTE BANK0 SYSTEM ' location for STATUS register psave VAR BYTE BANK0 SYSTEM ' location for PCLATH register BAM_COUNT CON 5 ; How many BAM Pins are used? ;DEFINE BAM_INFO 1 INCLUDE "MIBAM.pbp" ; Mirror Image BAM module Bright VAR BYTE[BAM_COUNT] Br0 VAR Bright[0] Br1 VAR Bright[1] Br2 VAR Bright[2] Br4 VAR Bright[3] Br5 VAR Bright[4] ASM BAM_LIST macro ; Define PIN's to use for BAM BAM_PIN (GPIO,0, Br0) ; and the associated Duty variables BAM_PIN (GPIO,1, Br1) BAM_PIN (GPIO,2, Br2) BAM_PIN (GPIO,4, Br4) BAM_PIN (GPIO,5, Br5) endm BAM_INIT BAM_LIST ; Initialize the Pins ENDASM ;----[Setup Blinky parameters]----------------------------------- DEFINE BLINKYFREQ 100 ; 10mS periods LEDcount CON 5 ; Number of LEDs on the PORT ; BL3,BL2,BL1,BL5,BL4 ; PCB indicators OnTimes DATA 50, 22, 50, 75, 17 ; default periods for each Output OffTimes DATA 150, 45, 50, 95, 22 ; Blinky on/off info from older code ; ==================================== ' BL3,BL2,BL1,BL5,BL4 ;OnTimes DATA 50 ,22 ,50 ,75 ,17; default "on" periods for each output ;OffTimes DATA 150 ,45 ,50 ,95 ,22; default "off" periods for each output ;#IFDEF USE_RANDOM_SEQUENCE ; randomization ; RND VAR WORD : RND = 13864 ; MIN_ON CON 220 ; Minimum random ON time ; MAX_ON CON 333 ; Maximum random ON time ; MIN_OFF CON 33 ; Minimum random OFF time ; MAX_OFF CON 275 ; Maximum random OFF time ; RandPeriod VAR WORD[LEDcount] ; RandPeriods DATA WORD 1000, WORD 1250, WORD 1500, WORD 1750, WORD 2000 ;#ENDIF ; Adjust values below for the 5 blinkies re: brightness Brightness DATA 5,5,5,5,5 #DEFINE USE_RANDOM_SEQUENCE ; comment for contiuous Sequence #IFDEF USE_RANDOM_SEQUENCE RND VAR WORD : RND = 13864 MIN_ON CON 50 ; Minimum random ON time MAX_ON CON 500 ; Maximum random ON time MIN_OFF CON 50 ; Minimum random OFF time MAX_OFF CON 500 ; Maximum random OFF time RandPeriod VAR WORD[LEDcount] RandPeriods DATA WORD 1000, WORD 1250, WORD 1500, WORD 1750, WORD 2000 #ENDIF ;----[Variables used only by Blinky]----------------------------- LoopLED VAR WORD[LEDcount] OnTime VAR WORD[LEDcount] OffTime VAR WORD[LEDcount] x VAR BYTE temp VAR WORD speed CON 6 ;----[Initialize]------------------------------------------------ FOR x = 0 to (LEDcount - 1) ; load the periods from EEPROM READ OnTimes+x, OnTime(x) READ OffTimes+x, OffTime(x) #IFDEF USE_RANDOM_SEQUENCE READ RandPeriods+(x<<1), WORD RandPeriod(x) #ENDIF NEXT X ;----[Main Program Loop]----------------------------------------- Main: x = (x + 1) // LEDcount IF LoopLED(x) < OnTime(x) THEN READ Brightness + x, temp IF Bright(x) < temp THEN Bright(x) = Bright(x) + speed ELSE Bright(x) = temp ENDIF ELSE IF Bright(x) > 0 THEN Bright(x) = Bright(x) - speed ELSE Bright(x) = 0 ENDIF ENDIF LoopLED(x) = (LoopLED(x) + 1) // (OnTime(x) + OffTime(x)) #IFDEF USE_RANDOM_SEQUENCE RandPeriod(x) = RandPeriod(x) - 1 IF RandPeriod(x) = 0 THEN READ RandPeriods+(x<<1), WORD RandPeriod(x) RANDOM RND OnTime(x) = (MAX_ON - MIN_ON)* RND.HighByte / 255 + MIN_ON OffTime(x)= (MAX_OFF - MIN_OFF)* RND.LowByte / 255 + MIN_OFF ENDIF #ENDIF IF x != (LEDcount - 1) THEN Main Waiting: IF !TMR0IF THEN Waiting TMR0 = 99 TMR0IF = 0 GOTO Main
Any ideas?
Went back through my versioning of the code and found that the previous one works just fine - I must've made some tweaks in v3 that screwed things up. I'll need to go through them line-by-line to see where the discrepancy is (if only for my own benefit).
Here's the working code:
Code:'**************************************************************** '* Name : Nacelle_Blinking_Lights_12F683_8Mhz_Int.pbp * '* Author : Ross A. Waddell * '* Notice : Copyright (c) 2014 * '* : All Rights Reserved * '* Date : 03/25/2014 * '* Version : 2.0 * '* Notes : Blinking nacelle engine lights (TOS Enterprise) * '* : * '**************************************************************** ' Nacelle engine lights ' ===================== ' (a) The colours used were: red, blue, green, amber and pink, all standard colours ' they had for common Christmas lights of the time. ' (b) They were all Christmas lights (C7, too big for a 1/350). 12 by my guess. ' (c) Amber was steady (5 in a star pattern), all the rest blinked. ' For production version of this code, update config fuses to ' enable code protect (CP_ON) ' Basic blinky code provided by Darrel Taylor ' See forum posting here: ' http://www.picbasic.co.uk/forum/showthread.php?t=17299&p=116934#post116934 ' *************************************************************** ' Pin Connections ' *************************************************************** ' GP5 -> pin 2 -> R4 -> BL4 ' GP4 -> pin 3 -> R5 -> BL5 ' GP3 -> pin 4 -> MCLR (input only, 'dummy' BL6) ' GP2 -> pin 5 -> R1 -> BL1 ' GP1 -> pin 6 -> R2 -> BL2 ' GP0 -> pin 7 -> R3 -> BL3 ' *************************************************************** ' Initialization ' *************************************************************** #CONFIG __config _INTOSCIO & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOD_ON & _IESO_OFF & _FCMEN_OFF #ENDCONFIG DEFINE OSC 8 OSCCON = %01110000 ; 8MHz internal osc ANSEL = 0 ; All Digital CMCON0 = 7 TRISIO = 0 ; all OUTPUT OPTION_REG = %00000110 ; Timer0 prescaler 1:128 TMR0IF VAR INTCON.2 ; Timer0 Overflow bit ;----[ MIBAM Setup ]-------------------------------------------------------- wsave var byte $70 SYSTEM ' Alternate save location for W ssave VAR BYTE BANK0 SYSTEM ' location for STATUS register psave VAR BYTE BANK0 SYSTEM ' location for PCLATH register BAM_COUNT CON 5 ; How many BAM Pins are used? ;DEFINE BAM_INFO 1 INCLUDE "MIBAM.pbp" ; Mirror Image BAM module Bright VAR BYTE[BAM_COUNT] Br0 VAR Bright[0] Br1 VAR Bright[1] Br2 VAR Bright[2] Br4 VAR Bright[3] Br5 VAR Bright[4] ASM BAM_LIST macro ; Define PIN's to use for BAM BAM_PIN (GPIO,0, Br0) ; and the associated Duty variables BAM_PIN (GPIO,1, Br1) BAM_PIN (GPIO,2, Br2) BAM_PIN (GPIO,4, Br4) BAM_PIN (GPIO,5, Br5) endm BAM_INIT BAM_LIST ; Initialize the Pins ENDASM ;----[Setup Blinky parameters]----------------------------------- DEFINE BLINKYFREQ 100 ; 10mS periods LEDcount CON 5 ; Number of LEDs on the PORT ; BL3,BL2,BL1,BL5,BL4 ; PCB indicators OnTimes DATA 50, 22, 38, 75, 5 ; default periods for each Output OffTimes DATA 150, 45, 38, 95, 34 Brightness DATA 255,10,10, 10, 255 #DEFINE USE_RANDOM_SEQUENCE ; comment for contiuous Sequence #IFDEF USE_RANDOM_SEQUENCE RND VAR WORD : RND = 13864 MIN_ON CON 50 ; Minimum random ON time MAX_ON CON 500 ; Maximum random ON time MIN_OFF CON 50 ; Minimum random OFF time MAX_OFF CON 500 ; Maximum random OFF time RandPeriod VAR WORD[LEDcount] RandPeriods DATA WORD 1000, WORD 1250, WORD 1500, WORD 1750, WORD 2000 #ENDIF ;----[Variables used only by Blinky]----------------------------- LoopLED VAR WORD[LEDcount] OnTime VAR WORD[LEDcount] OffTime VAR WORD[LEDcount] x VAR BYTE ;----[Initialize]------------------------------------------------ FOR x = 0 to LEDcount - 1 ; load the periods from EEPROM READ OnTimes+x, OnTime(x) READ OffTimes+x, OffTime(x) #IFDEF USE_RANDOM_SEQUENCE READ RandPeriods+(x<<1), WORD RandPeriod(x) #ENDIF NEXT X ;----[Main Program Loop]---------------------------------------- Main: x = (x + 1) // LEDcount IF LoopLED(x) < OnTime(x) THEN READ Brightness + x, Bright(x) ELSE Bright(x) = 0 ENDIF LoopLED(x) = (LoopLED(x) + 1) // (OnTime(x) + OffTime(x)) #IFDEF USE_RANDOM_SEQUENCE RandPeriod(x) = RandPeriod(x) - 1 IF RandPeriod(x) = 0 THEN READ RandPeriods+(x<<1), WORD RandPeriod(x) RANDOM RND OnTime(x) = (MAX_ON - MIN_ON)* RND.HighByte / 255 + MIN_ON OffTime(x)= (MAX_OFF - MIN_OFF)* RND.LowByte / 255 + MIN_OFF ENDIF #ENDIF IF x != (LEDcount - 1) THEN Main Waiting: IF !TMR0IF THEN Waiting TMR0 = 99 TMR0IF = 0 GOTO Main
Bookmarks