-
Re: Single PIC to Blink 5 LEDs Independently?
yes yours would still blink, because your controlling the primary fet's on off state with individual I/O's, and controlling a single secondary fet that just controls brightness for all blinking leds. say you set the brightness to 50%, then every led that blinks will be at 50% of its brightness, and you can change the brightness even in the middle of a blink.
Heres a basic, very basic program to do similar
this blinks the leds randomly 50% of the time, and you can randomize the brightness too.
Code:
'* Date : 1/26/2013 *
'* Version : 1.0 *
'* Notes : 12F683 Christmas Light Sample *
'* : *
'****************************************************************
DEFINE ADC_BITS 10 ' A/D number of bits
DEFINE ADC_CLOCK 1 ' Use A/D internal RC clock
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in us
RES1 Var Word ' A/D converter result
RND1 VAR WORD ' Random Result for Light #1
RND2 VAR WORD ' Random Result for Light #2
RND3 VAR WORD ' Random Result for Light #3
TRISIO.0 = 1 ' AN0 is input for Setting Brightness
TRISIO.2 = 0 ' PWM1 is output for Dimming FET
TRISIO.1 = 0 ' LED1 FET
TRISIO.4 = 0 ' LED2 FET
TRISIO.5 = 0 ' LED3 FET
AGAIN:
ADCIN 0, Res1 ' Read Channel 0 data
'Optional replace ACDIN with (RANDOM RES1)
res1 = res1 / 256
HPWM 1, res1, 1000 ' Outputs a PWM @ 1khz w/ 256 Steps
'Insert Code for turning LED's on or off here
RAndom RND1
Random rnd2
Random rnd3
if rnd1 > 32000 then
GPIO.1 = 1
else
GPIO.1 = 0
endif
if rnd1 > 32000 then
GPIO.4 = 1
else
GPIO.4 = 0
endif
if rnd1 > 32000 then
GPIO.5 = 1
else
GPIO.5 = 0
endif
pause 100
goto again
end
-
Re: Single PIC to Blink 5 LEDs Independently?
I've managed to incorporate both Darrel's blinking routine and his SPWM_INT module into the same project - the idea as it stands now is to feed each blink pin and corresponding PWM (brightness control) pin into 2 FETs connected together (source to drain in a chain). This would mean, though, that for for the 7 blinking LEDs I'll be using 14 pins on this chip and 2 FETs per blinking LED (14 in total). That's better than not having brightness control, for sure, but is there a way to combine this functionality in code?
Here's what I have so far:
Code:
' PIC16F88
' Basic blinky code provided by Darrel Taylor
' See forum posting here:
' http://www.picbasic.co.uk/forum/showthread.php?t=17299&p=116934#post116934
#DEFINE USE_LCD_FOR_DEBUG ; comment out for non-debug use
DEFINE OSC 20 ; Set oscillator 20Mhz
DEFINE BLINKYFREQ 100 ; 10mS periods
' ***************************************************************
' Device Fuses
' ***************************************************************
' PIC chip data sheets can be found here: C:\Program Files\Microchip\MPASM Suite
#CONFIG
__config _CONFIG1, _FOSC_HS & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _LVP_OFF
#ENDCONFIG
' ***************************************************************
' Initialization
' ***************************************************************
;OSCCON = %01100000 ; 4MHz internal osc (not needed when using ext crystal)
pause 100
ANSEL = 0 ; Digital only
TRISA = 0 ; PORTA all output
TRISB = %00000001 ; Make PORTB pin 0 input for flash mode button
OPTION_REG.6 = 1 ; 1=Rising edge (default) or button "PRESS";
; 0=Falling edge or button "RELEASE"
LEDcount CON 7 ; Number of blinking LEDs on PORTA
;(includes running lights, which are
; defined separately below)
' BL1,BL2,BL3,BL4,BL5,STB
OnTimes DATA 50 ,22 ,38 ,75 ,17 , 2 ; default "on" periods for each output
OffTimes DATA 150 ,45 ,38 ,95 ,22 ,48 ; default "off" periods for each output
; (Strobe flashes 2 times per second
; or every 500ms; subtract "on" time)
FlashMode_Default CON 0
EE_FlashMode DATA FlashMode_Default
FlashMode VAR BYTE
READ EE_FlashMode, FlashMode
;----------------------------------------------------------------
#DEFINE USE_RANDOM_SEQUENCE ; comment for contiuous Sequence
#IFDEF USE_RANDOM_SEQUENCE ; randomization used for BL1-5 only
RND VAR WORD : RND = 13864
MIN_ON CON 15 ; Minimum random ON time
MAX_ON CON 115 ; Maximum random ON time
MIN_OFF CON 15 ; Minimum random OFF time
MAX_OFF CON 200 ; Maximum random OFF time
RandPeriod VAR WORD[LEDcount-3]
RandPeriods DATA WORD 1000, WORD 1250, WORD 1500, WORD 1750, WORD 2000
#ENDIF
CCPR1val CON EXT : @CCPR1val = (OSC*1000000/4)/ BLINKYFREQ
;CCPR1 VAR WORD EXT : @CCPR1 = CCPR1L
;Timer1 VAR WORD EXT : @Timer1 = TMR1L
CCPIF VAR PIR1.2
LoopLED VAR BYTE[LEDcount]
OnTime VAR BYTE[LEDcount]
OffTime VAR BYTE[LEDcount]
x VAR BYTE
Old_FlashMode VAR BYTE
PRI_HULL_LGHTS_ON_MS VAR BYTE
PRI_HULL_LGHTS_OFF_MS VAR BYTE
#IFDEF USE_LCD_FOR_DEBUG
LCD_PIN VAR PORTA.4 ' Alias PORTA.4 as "LCD_PIN"
LCD_INST CON 254 ' instruction
LCD_CLR CON 1 ' Clear screen
LCD_L1 CON 128 ' LCD line 1
LCD_L2 CON 192 ' LCD line 2
LCD_BAUD CON 16780 ' Baud rate/mode for ILM-216 2x16 character display
LCD_PACE CON 1 ' Optional pace value
#ENDIF
' ***************************************************************
' Includes
' ***************************************************************
INCLUDE "DT_INTS-14.bas" ' DT's base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
' --> copy both files to PBP main folder
' (i.e. c:\pbp3)
INCLUDE "SPWM_INT.bas" ; DT's software PWM module
DEFINE SPWM_FREQ 200 ; SPWM Frequency
DEFINE SPWM_RES 256 ; SPWM Resolution
DutyVars VAR BYTE[3] ; DutyCycle Variables
DutyVar1 VAR DutyVars[0] ; group them in an array for easy access
DutyVar2 VAR DutyVars[1] ; with FOR loops etc.
DutyVar3 VAR DutyVars[2]
ASM
SPWM_LIST macro ; Define Pin's to use for SPWM
SPWM_PIN PORTA, 0, _DutyVar1 ; and the associated DutyCycle variables
SPWM_PIN PORTA, 1, _DutyVar2 ; Notice the underscore before variables
SPWM_PIN PORTA, 2, _DutyVar3
endm
SPWM_INIT SPWM_LIST ; Initialize the Pins
ENDASM
DutyVar1 = 7
DutyVar2 = 25
DutyVar3 = 255
;-- Place a copy of these variables in your Main program -------------------
;-- The compiler will tell you which lines to un-comment --
;-- Do Not un-comment these lines --
;---------------------------------------------------------------------------
;wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3
' --- IF any of these three lines cause an error ?? ------------------------
' Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using --
;wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
;wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
;wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
' --------------------------------------------------------------------------
' ***************************************************************
' ASM Interrupt Definitions
' ***************************************************************
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _Flash_Mode_Btn, PBP, yes
INT_Handler TMR1_INT, SPWMhandler, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
' ***************************************************************
;----[Initialize on/off periods & random sequencing (if enabled)]---------------
; (only randomize first 5 blinkies; 6th is strobe which must remaing constant)
; (running lights (7th) are set up separately)
FOR x = 0 to (LEDcount - 2) ; Load the periods from EEPROM
READ OnTimes+x, OnTime(x)
READ OffTimes+x, OffTime(x)
#IFDEF USE_RANDOM_SEQUENCE
IF x < 5 THEN
READ RandPeriods+(x<<1), WORD RandPeriod(x)
ENDIF
#ENDIF
NEXT X
;-- setup CCP1 and Start Timer1 --
CCPR1 = CCPR1val ; set compare value
CCP1CON = %00001011 ; compare mode, special event
Timer1 = 0 ; clear Timer1
T1CON.0 = 1 ; start Timer1
Old_FlashMode = FlashMode ; Set initial value for comparator var
GOSUB SetNavLtsFlashRates ; Set up flash rates based on saved "FlashMode" val
' Enable interrupt
INTCON = %10010000 ; Global int enabled, INTE enabled, IOCI enabled,
; INTF flag bit 0 clr, IOCI flag bit 0 clr
INTCON.1 = 0 ; Clear RB0/INT External Interrupt Flag
@ INT_ENABLE INT_INT ; INT/Ext Interrupt
@ INT_ENABLE TMR1_INT ; enable Timer1 interrupts
#IFDEF USE_LCD_FOR_DEBUG
serout2 LCD_PIN, LCD_BAUD, LCD_PACE, [LCD_INST, LCD_CLR] ; clear screen
pause 5
serout2 LCD_PIN, LCD_BAUD, LCD_PACE, ["FlashMode:", DEC FlashMode, " "]
#ENDIF
;----[Main Program Loop]----------------------------------------
Main:
' Check if flash mode has changed
IF FlashMode <> Old_FlashMode Then
Old_FlashMode = FlashMode
GOSUB SetNavLtsFlashRates
EndIF
x = (x + 1) // LEDcount
PORTB.1(x) = !!(LoopLED(x) < OnTime(x))
LoopLED(x) = (LoopLED(x) + 1) // (OnTime(x) + OffTime(x))
#IFDEF USE_RANDOM_SEQUENCE
IF x < 5 THEN
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
#ENDIF
IF x != (LEDcount - 1) THEN Main
Waiting: IF !CCPIF THEN Waiting
CCPIF = 0
GOTO Main
SetNavLtsFlashRates:
If FlashMode = 0 Then
PRI_HULL_LGHTS_ON_MS = 150
PRI_HULL_LGHTS_OFF_MS = 50
ElseIf FlashMode = 1 Then
PRI_HULL_LGHTS_ON_MS = 50
PRI_HULL_LGHTS_OFF_MS = 150
Else
PRI_HULL_LGHTS_ON_MS = 75
PRI_HULL_LGHTS_OFF_MS = 83
EndIf
OnTime(6) = PRI_HULL_LGHTS_ON_MS
OffTime(6) = PRI_HULL_LGHTS_OFF_MS
#IFDEF USE_LCD_FOR_DEBUG
serout2 LCD_PIN, LCD_BAUD, LCD_PACE, [LCD_INST, LCD_CLR] ; clear screen
pause 5
serout2 LCD_PIN, LCD_BAUD, LCD_PACE, ["FlashMode:", DEC FlashMode, " "]
#ENDIF
RETURN
END
' ***************************************************************
' [INT - interrupt handler]
' ***************************************************************
Flash_Mode_Btn:
' Toggle flash mode between the 3 values (0, 1 or 2)
FlashMode = FlashMode + 1
If FlashMode > 2 Then FlashMode = 0
' Save selected running light flash mode
WRITE EE_FlashMode, FlashMode
PAUSE 100
INTCON.1 = 0 ' Clear RB0/INT External Interrupt Flag
@ INT_RETURN
-
Re: Single PIC to Blink 5 LEDs Independently?
UPDATE: The code compiles just fine, but now PWM output on PORTA.0-2 is observed. Sigh.
-
Re: Single PIC to Blink 5 LEDs Independently?
Quote:
Originally Posted by
RossWaddell
UPDATE: The code compiles just fine, but now PWM output on PORTA.0-2 is observed. Sigh.
I meant to say **no** PWM output on pins PORTA.0-2 is observed; the pins are held low and the LEDs don't blink with the daisy chain FET approach.
Looks like I'll have to use 2 PICS: one for the blink stuff developed by Darrel, and one to control the brightness via PWM.
-
Re: Single PIC to Blink 5 LEDs Independently?
(Reviving an old thread)
I now need to simplify this a bit and put this on a 8-pin PIC. I need 5 blinkies so I'd like to use a 12F629 (knowing GP3/MCLR is input only, I'll use GP0-GP5 and if nothing happens on GP3 then that's fine).
The code won't compile because of this part:
Code:
;-- setup CCP1 and Start Timer1 --
CCPR1 = CCPR1val ; set compare value
CCP1CON = %00001011 ; compare mode, special event
Timer1 = 0 ; clear Timer1
T1CON.0 = 1 ; start Timer1
These registers exist on a 16F690 (and others) but not 12F629. I had earlier tried a 12F683 (my go-to PIC) but the .inc file for it already has a define for CCPR1 so I'd have to comment out that line in the .inc file but that makes me a wee bit uncomfortable.
Is there a way to make this work on a 12F690 or 12F683? If not, is there another 8-pin PIC I could use? I need to be able to find SMT packages as the space where the PCB is going is extremely tight (I've never soldered SMTs before so that should be fun).
Here's the whole code:
Code:
'****************************************************************
'* Name : Nacelle_Blinking_Lights_5_12F629_4Mhz_Int.pbp *
'* Author : Ross A. Waddell *
'****************************************************************
' For production version of this code, update config fuses to
' enable code protect 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
' ***************************************************************
DEFINE OSC 4 ' Set oscillator 4Mhz
DEFINE BLINKYFREQ 100 ' 10mS periods
CMCON = %0000111 'Turn off comparators
TRISIO = %00000000 'Make all GPIO pins output
' ***************************************************************
' Device Fuses
' ***************************************************************
' PIC chip data sheets can be found here: C:\Program Files\Microchip\MPASM Suite
#CONFIG
__config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _BODEN_ON & _CP_OFF & _CPD_OFF
#ENDCONFIG
LEDcount CON 6 ; Number of blinking LEDs
; (includes 'fummy' LED on GP3/MCLR pin,
; rates defined separately below)
' BL3,BL2,BL1,BL6,BL5,BL4
' --- --- --- --- --- ---
' default "on" periods for each output
OnTimes DATA 50 ,82 ,50 ,33 ,133, 2
' default "off" periods for each output
OffTimes DATA 150 ,45 ,50 ,33 ,22 ,48
;----------------------------------------------------------------
#DEFINE USE_RANDOM_SEQUENCE ; comment for contiuous Sequence
#IFDEF USE_RANDOM_SEQUENCE
RND VAR WORD : RND = 13864
MIN_ON CON 33 ; Minimum random ON time
MAX_ON CON 100 ; Maximum random ON time
MIN_OFF CON 33 ; Minimum random OFF time
MAX_OFF CON 100 ; Maximum random OFF time
RandPeriod VAR WORD[LEDcount]
RandPeriods DATA WORD 1000, WORD 1250, WORD 1500, WORD 500, WORD 2000, WORD 2000
#ENDIF
CCPR1val CON EXT : @CCPR1val = (OSC*1000000/4)/ BLINKYFREQ
CCPR1 VAR WORD EXT : @CCPR1 = CCPR1L
Timer1 VAR WORD EXT : @Timer1 = TMR1L
CCPIF VAR PIR1.2
LoopLED VAR BYTE[LEDcount]
OnTime VAR BYTE[LEDcount]
OffTime VAR BYTE[LEDcount]
x VAR BYTE
' ***************************************************************
;----[Initialize on/off periods & random sequencing (if enabled)]---------------
FOR x = 0 to (LEDcount) ; Load the periods from EEPROM
READ OnTimes+x, OnTime(x)
READ OffTimes+x, OffTime(x)
#IFDEF USE_RANDOM_SEQUENCE
IF x < 5 THEN
READ RandPeriods+(x<<1), WORD RandPeriod(x)
ENDIF
#ENDIF
NEXT X
;-- setup CCP1 and Start Timer1 --
CCPR1 = CCPR1val ; set compare value
CCP1CON = %00001011 ; compare mode, special event
Timer1 = 0 ; clear Timer1
T1CON.0 = 1 ; start Timer1
Main:
x = (x + 1) // LEDcount
GPIO.0(x) = !!(LoopLED(x) < OnTime(x))
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 !CCPIF THEN Waiting
CCPIF = 0
GOTO Main
-
Re: Single PIC to Blink 5 LEDs Independently?
The 12F629 doesn't have a CCP module.
You'll be better off with the 12F683.
Don't comment the CCPR1 line in the .inc file. Comment the one in the blinky code.
Code:
CCPR1 VAR WORD EXT : @CCPR1 = CCPR1L
-
Re: Single PIC to Blink 5 LEDs Independently?
You might also, if I follow your intent, use an AND gate to combine PWM and I/O into one PWM modulated blinking output.
-
Re: Single PIC to Blink 5 LEDs Independently?
Quote:
Originally Posted by
Darrel Taylor
The 12F629 doesn't have a CCP module.
You'll be better off with the 12F683.
Don't comment the CCPR1 line in the .inc file. Comment the one in the blinky code.
Code:
CCPR1 VAR WORD EXT : @CCPR1 = CCPR1L
Thanks Darrel!
-
Re: Single PIC to Blink 5 LEDs Independently?
Quote:
Originally Posted by
Amoque
You might also, if I follow your intent, use an AND gate to combine PWM and I/O into one PWM modulated blinking output.
Presumably I'd need 5 AND gates for the 5 outputs, right? and then connect the other input of each AND gate to a PWM from another chip?
-
Re: Single PIC to Blink 5 LEDs Independently?
Quote:
Originally Posted by
Darrel Taylor
The 12F629 doesn't have a CCP module.
You'll be better off with the 12F683.
Don't comment the CCPR1 line in the .inc file. Comment the one in the blinky code.
Code:
CCPR1 VAR WORD EXT : @CCPR1 = CCPR1L
I converted the code to use a 12F683 PIC but the LEDs come on and then stay on (although not all 5; some stay off). Is it because of the input-only GP4/MCLR?
Code:
' 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
' ***************************************************************
DEFINE OSC 8 ' Set oscillator 8Mhz
DEFINE BLINKYFREQ 100 ' 10mS periods
OSCCON = %0111
CMCON0 = %0000111 ' Turn off comparators
ANSEL.0 = 0 ' Digital only
ANSEL.1 = 0 ' Digital only
ANSEL.2 = 0 ' Digital only
ANSEL.3 = 0 ' Digital only
ADCON0.0 = 0 ' ADC is disabled
TRISIO = %00000000 ' Make all GPIO pins output
' ***************************************************************
' Device Fuses
' ***************************************************************
' PIC chip data sheets can be found here: C:\Program Files\Microchip\MPASM Suite
#CONFIG
__config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _BOD_ON & _CP_OFF & _CPD_OFF
#ENDCONFIG
LEDcount CON 6 ; Number of blinking LEDs
; (includes 'fummy' LED on GP3/MCLR pin,
; rates defined separately below)
' BL3,BL2,BL1,BL6,BL5,BL4
' --- --- --- --- --- ---
' default "on" periods for each output
OnTimes DATA 50 ,82 ,50 ,33 ,133, 2
' default "off" periods for each output
OffTimes DATA 150 ,45 ,50 ,33 ,22 ,48
;----------------------------------------------------------------
#DEFINE USE_RANDOM_SEQUENCE ; comment for contiuous Sequence
#IFDEF USE_RANDOM_SEQUENCE
RND VAR WORD : RND = 13864
MIN_ON CON 33 ; Minimum random ON time
MAX_ON CON 100 ; Maximum random ON time
MIN_OFF CON 33 ; Minimum random OFF time
MAX_OFF CON 100 ; Maximum random OFF time
RandPeriod VAR WORD[LEDcount]
RandPeriods DATA WORD 1000, WORD 1250, WORD 1500, WORD 500, WORD 2000, WORD 2000
#ENDIF
CCPR1val CON EXT : @CCPR1val = (OSC*1000000/4)/ BLINKYFREQ
;CCPR1 VAR WORD EXT : @CCPR1 = CCPR1L
Timer1 VAR WORD EXT : @Timer1 = TMR1L
CCPIF VAR PIR1.2
LoopLED VAR BYTE[LEDcount]
OnTime VAR BYTE[LEDcount]
OffTime VAR BYTE[LEDcount]
x VAR BYTE
' ***************************************************************
;----[Initialize on/off periods & random sequencing (if enabled)]---------------
FOR x = 0 to (LEDcount) ; 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
;-- setup CCP1 and Start Timer1 --
CCPR1 = CCPR1val ; set compare value
CCP1CON = %00001011 ; compare mode, special event
Timer1 = 0 ; clear Timer1
T1CON.0 = 1 ; start Timer1
Main:
x = (x + 1) // LEDcount
GPIO.0(x) = !!(LoopLED(x) < OnTime(x))
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 !CCPIF THEN Waiting
CCPIF = 0
GOTO Main
-
Re: Single PIC to Blink 5 LEDs Independently?
On the 12F683, the CCP1IF bit is PIR1.5.
Why they have to change things all the time ... I don't know.
Both the OSCCON and CMCON0 values don't have enough digits.
added: CMCON0 won't matter cause it's still 7, but to keep things consistent ...
Code:
OSCCON = %01110000 ' 8Mhz
CMCON0 = %00000111 ' Turn off comparators
Not sure how this got changed, it should be ...
Code:
FOR x = 0 to (LEDcount - 1) ; Load the periods from EEPROM
http://support.melabs.com/DT/Blinky5_683.gif
-
Re: Single PIC to Blink 5 LEDs Independently?
Again, not wholly sure what your trying to do... I have trouble following someone else's code (even my own sometimes), but a PWM output tied to one input of each (yes, 5) "AND" gate, the other input to each I/O. Toggling I/O then controls modulated output. I am thinking of IR communications where a serial data stream and 38K PWM are "ANDed" for IR transmission.
-
Re: Single PIC to Blink 5 LEDs Independently?
Quote:
Originally Posted by
Darrel Taylor
On the 12F683, the CCP1IF bit is PIR1.5.
Why they have to change things all the time ... I don't know.
Both the OSCCON and CMCON0 values don't have enough digits.
added: CMCON0 won't matter cause it's still 7, but to keep things consistent ...
Code:
OSCCON = %01110000 ' 8Mhz
CMCON0 = %00000111 ' Turn off comparators
Not sure how this got changed, it should be ...
Code:
FOR x = 0 to (LEDcount - 1) ; Load the periods from EEPROM
http://support.melabs.com/DT/Blinky5_683.gif
Thank you SOOOO much, Darrel!
BTW, what software is that you are using to test out the code?
-
Re: Single PIC to Blink 5 LEDs Independently?
Quote:
Originally Posted by
Amoque
Again, not wholly sure what your trying to do... I have trouble following someone else's code (even my own sometimes), but a PWM output tied to one input of each (yes, 5) "AND" gate, the other input to each I/O. Toggling I/O then controls modulated output. I am thinking of IR communications where a serial data stream and 38K PWM are "ANDed" for IR transmission.
I was initially intending to make the brightness of the LEDs controllable via PWM, but now the chips are moving off the main board to another PCB that will be buried deep within my model where they will only have +5V & GND wires. These boards are too small to add any other components (even SMTs) so I'll just have to breadboard them with various series-limiting resistors to get the right brightness.
Your suggestion is something I will investigate for the rest of my circuit where I do intend to provide brightness control on the main board. Right now, I'm daisy-chaining 2 NPNs which someone on SparkFun suggested but I haven't breadboarded it yet to see if it works.
-
Re: Single PIC to Blink 5 LEDs Independently?
Quote:
Originally Posted by
RossWaddell
BTW, what software is that you are using to test out the code?
It's Proteus Design Suite from Labcenter Electronics.
Quote:
Originally Posted by
RossWaddell
I was initially intending to make the brightness of the LEDs controllable via PWM, ... so I'll just have to breadboard them with various series-limiting resistors to get the right brightness.
That can be done in software using MIBAM.
The blinky's timer will have to be changed, but it's doable.
-
Re: Single PIC to Blink 5 LEDs Independently?
Spent a very happy afternoon reading up on MIBAM - can't wait to try it out (is there a later version of the .pbp code or is the v1.0 you posted on the melbas page the one I should use?).
In preparation for that, I converted the now-workiing code to use Timer2. I think that since Timer2 is 8-bit (versus 16-bit for Timer1) that I don't need to worry about using the Least Significant register as you did with Timer1 but can just use TMR2:
Code:
CCPR1val CON EXT : @CCPR1val = (OSC*1000000/4)/ BLINKYFREQ
;CCPR1 VAR WORD EXT : @CCPR1 = CCPR1L
Timer2 VAR WORD EXT : @Timer2 = TMR2
CCPIF VAR PIR1.5
And then this to turn it on:
Code:
;-- setup CCP1 and Start Timer2 --
CCPR1 = CCPR1val ; set compare value
CCP1CON = %00001011 ; compare mode, special event
Timer2 = 0 ; clear Timer2
T2CON.0 = 1 ; start Timer2
Is that it?
-
Re: Single PIC to Blink 5 LEDs Independently?
Or maybe not. The PIC12F683 data sheet seems to indicate that the Compare mode uses only Timer1, and if that's needed for MIBAM then I don't think I can use that on a PIC12F683 with this blinky code.
-
1 Attachment(s)
One little obstacle and ... it can't be done???:eek:
The CCP with Capture mode was just a simple way to get a wide range of constant periods without interrupts/reloading timers etc.
Since it seems that you are only using the original 10mS periods, it doesn't really need that "Wide Range".
10mS periods can be generated with another Timer, and you don't need the CCP module.
In this example, I'm using Timer0 ...
MIBAM uses Timer1.
The EEPROM data labeled Brightness controls the intensity of each LED.
I have 3 LED's with 330 ohms, and 2 LED's with 100 ohms. The existing values equalized their brightness (to my eyes).
Code:
;{PIC=12F683}
#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
OPTION_REG = %00000110 ; Timer0 prescaler 1:128
TMR0IF VAR INTCON.2 ; Timer0 Overflow bit
TRISIO = 0 ; all OUTPUT
;----[ 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
OnTimes DATA 50, 22, 38,75, 5 ; default periods for each Output
OffTimes DATA 150, 45, 38,95,34
Brightness DATA 150,150,150,80,80
#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
And yes, I posted a MIBAM version 1.1 several years ago ... but it seems to be gone, or I just can't find it..
Here's the latest version.
-
Re: Single PIC to Blink 5 LEDs Independently?
I must sound like a broken record, but thanks again Darrel. I greatly appreciate you taking the time to help me with my project.
-
Re: Single PIC to Blink 5 LEDs Independently?
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:
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
I'll program a 12F683 this afternoon and see what it looks like.
-
Re: Single PIC to Blink 5 LEDs Independently?
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.
-
Re: Single PIC to Blink 5 LEDs Independently?
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.
-
Re: Single PIC to Blink 5 LEDs Independently?
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!
-
Re: Single PIC to Blink 5 LEDs Independently?
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
-
Re: Single PIC to Blink 5 LEDs Independently?
Looks like 6 is the magic number.
-
Re: Single PIC to Blink 5 LEDs Independently?
(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).
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
As you can see, I haven't implemented Darrel's most recent suggestion (probably because a year ago this was working OK).
Any ideas?
-
Re: Single PIC to Blink 5 LEDs Independently?
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
-
Re: Single PIC to Blink 5 LEDs Independently?
After going through the two different versions I remembered that the last thing I wanted to implement was varying the brightness of each LED to ramp up/off to the set BRIGHTNESS level. This would simulate incandescent bulbs by 'fading' up the LED (and also fade off).
This is the suspect code:
Code:
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