Single PIC to Blink 5 LEDs Independently?


Closed Thread
Results 1 to 40 of 69

Hybrid View

  1. #1

    Default Single PIC to Blink 5 LEDs Independently?

    I'm in the final stages of a project I've been working off-and-on for the past 8 months. The final stage before submitting my board is to see if I can reduce the number of components by combining functionality into 1 chip.

    Currently, I have 5 12F629's which each blink 1 LEDs with separate on/off timings, with some randomization in the on/off cycles. I use PWM to fade in/out the LEDs as they must simulate old incandescent Christmas tree lights. Can I do this all with 1 pic (say, 16F1825)? I've been looking at Darrel's SPWM_INT - Multiple Software PWM but not sure if I can code in the needed PAUSEs while the LEDs are fully on or off (to get the right blinky look).

    Am I on the right path here, or does anyone have some suggestions for me? Going from 5 chips to 1 would be a big win for me.

  2. #2
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,867


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    I went on Microchip and looked for a PIC with at least 5 timers: PIC18F24J11.

    http://www.microchip.com/ParamChartS...g=en&pageId=74

    (That page might load properly, or not.)

    I'd try to use that along with DT-INTs; best way to blink LEDs.

    Robert

    EDIT:

    http://darreltaylor.com/DT_INTS-18/home.html

    TMR0_INT -- TMR0 Overflow
    TMR1_INT -- TMR1 Overflow
    TMR2_INT -- TMR2 to PR2 Match
    TMR3_INT -- TMR3 Overflow
    TMR4_INT -- TMR4 Overflow

    EDIT SOME MORE:

    There are 16F models if that makes things easier for you: PIC16F1782

    http://www.microchip.com/ParamChartS...=en&pageId=74#

    Use the Show/Hide Column feature to speed browsing.
    Last edited by Demon; - 27th October 2012 at 00:42. Reason: DT-INT has at least 5 timers

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    Thanks Robert. 16Fs do make things easier for me. Looks like the 16F1782 has (4) 8bit timers and (1) 16bit timer so I'll pick up some of those.

    I'm wondering, though, if I could use a 12F683 (2 x 8-bit, 1 x 16-bit) and the unused ports of a 16F1825 (I have RC4 and RA3-5 ports available) which has 4 x 8-bit and 1 x 16-bit timers. Some of the TMRs on the 16F1825 are already used, I'm sure, since I'm using CCP1 & CCP2.

    How can I tell which TMRs are being used? Here's my code:

    Code:
    '****************************************************************
    '*  Name    : Nacelle_Motors_16F1825_32Mhz_Int_SN754410.pbp     *
    '*  Author  : Ross A. Waddell                                   *
    '*  Notice  : Copyright (c) 2012                                *
    '*          : All Rights Reserved                               *
    '*  Date    : 10/20/2012                                        *
    '*  Version : 2.0                                               *
    '*  Notes   : Motor control for TOS E engines using SN754110    *
    '*          : motor driver, plus steady-on amber lights         *
    '****************************************************************
    
    ' ***************************************************************
    ' TODOs
    ' ***************************************************************
    ' 1. Need to calibrate motor RPMs so they spin at the same rate
    '    -> Separate "MotorRPM" EEPROM variables?
    ' 2. Add power isolation as blinking running lights seem to increase electrical noise
             
    DEFINE OSC 32                ' Set oscillator 32 Mhz
    
    ' ***************************************************************
    ' Device Fuses
    ' ***************************************************************
    #CONFIG
       __config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF
       __config _CONFIG2, _PLLEN_ON & _STVREN_ON & _BORV_LO & _LVP_OFF
    #ENDCONFIG
    
    ' ***************************************************************
    ' Initialization
    ' ***************************************************************
    
    OSCCON   = %11110000        ' 32 MHz internal osc (8 Mhz with 4x SPLLEN enabled)
    
    pause 100                   ' As advised by Darrel Taylor for EEPROM issue
    
    DEFINE CCP2_REG PORTC       ' Only need to define CCP2 pin as there are 2
    DEFINE CCP2_BIT 3           ' possible choices: RA5 or RC3
    
    PORTA    = 0                ' Set initial value of PORTA to 0
    PORTC    = 0                ' Set initial value of PORTC to 0
    ;ADCON0   = 7
    ;ADCON1   = 7
    ANSELA.0 = 0                ' Digital only on rotary encoder B pin
    ANSELA.1 = 0                ' Digital only on rotary encoder A pin
    ANSELA.2 = 0                ' Digital only on rotary encoder's button
    ANSELC.0 = 0                ' Digital only on Stbd motor direction signal (Motor 1)
    ANSELC.1 = 0                ' Digital only on Port motor direction signal (Motor 2)
    ANSELC.2 = 0                ' Digital only on LED_0 pin (steady-on amber lights)
    ANSELC.3 = 0                ' Digital only on CCP2 pin (Port engine)
    ANSELC.5 = 0                ' Digital only on CCP1 pin (Stbd engine)
    
    TRISA    = %00000111        ' Make PORTA pins 0-2 input for rotary encoder
    TRISC    = %00000000        ' Make all PORTC pins output
    
    ' The INTEDG bit of the OPTION_REG register determines on which edge the 
    ' interrupt will occur. When the INTEDG bit is set, the rising edge will 
    ' cause the interrupt. When the INTEDG bit is clear, the falling edge will 
    ' cause the interrupt. 
    OPTION_REG.6 = 1             ' 1=Rising edge (default) or button "PRESS";
                                 ' 0=Falling edge or button "RELEASE"
    
    Old_Bits       VAR BYTE
    New_Bits       VAR BYTE
    RotEncDir      VAR BIT       ' 1=CW, 0=CCW
                                 ' Rot Enc pin A connected to PortA.1;
                                 ' Rot Enc pin B connected to PortA.0
    Old_RPM        VAR BYTE
    I              VAR BYTE
    
    LED_0          VAR PORTC.2   ' Alias PORTC.2 as "LED_0"
    
    MOTOR_1_DIR    VAR PORTC.0   ' Alias PORTC.0 as "MOTOR_1_DIR"
    MOTOR_1_PWM    VAR PORTC.5   ' Alias PORTC.5 as "MOTOR_1_PWM"
    MOTOR_2_DIR    VAR PORTC.1   ' Alias PORTC.1 as "MOTOR_2_DIR"
    MOTOR_2_PWM    VAR PORTC.3   ' Alias PORTC.3 as "MOTOR_2_PWM"
    
    ButtonPress    VAR PORTA.2   ' Alias PORTA.2 as "ButtonPress"
    TimeCnt        VAR Word      
    
    LOW LED_0
    LOW MOTOR_1_DIR
    LOW MOTOR_1_PWM
    LOW MOTOR_2_DIR
    LOW MOTOR_2_PWM
    
    ' ***************************************************************
    ' Pin Connections
    ' ***************************************************************
    
    ' RA0                        -> B pin of rotary encoder
    ' RA1                        -> A pin of rotary encoder
    ' RA2                        -> Button switch pin of rotary encoder
    ' RC0                        -> Stbd motor direction signal (motor 1)
    ' RC1                        -> Port motor direction signal (motor 2)
    ' RC2                        -> Steady-on LED
    ' RC3/CCP2                   -> Port motor PWM output (motor 2)
    ' RC5/CCP1                   -> Stbd motor PWM output (motor 1)
    
    ' ***************************************************************
    ' Includes
    ' ***************************************************************
    
    INCLUDE "DT_INTS-14.bas"    ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas"    ' Include if using PBP interrupts
                                ' --> copy both files to PBP main folder 
                                ' (i.e. c:\pbp3)
    INCLUDE "EE_Vars.PBP"       ' copy file to PBP main folder (i.e. c:\pbp3)
    
    ' ***************************************************************
    ' EEPROM Variables
    ' ***************************************************************
    
    MotorRPM VAR BYTE        :  @  EE_var        _MotorRPM, BYTE, 150
    PortEngDir VAR BYTE      :  @  EE_var      _PortEngDir, BYTE, 0
                                                                      
    ' ***************************************************************
    ' ASM Interrupt Definitions
    ' ***************************************************************
                                                                      
    ASM
    INT_LIST  macro    ; IntSource,            Label,  Type, ResetFlag?
            INT_Handler    IOC_INT,    _RotEncAdjust,   PBP,  yes
    ;        INT_Handler    INT_INT,  _RotEncBtnPress,   PBP,  yes
        endm
        INT_CREATE     ; Creates the interrupt processor
    ENDASM
    
    ' ***************************************************************
    ' Set default values
    ' ***************************************************************
    
    Old_RPM = MotorRPM
    Old_Bits = PORTA & (%00000011)
    
    HIGH LED_0                  ' Turn on steady-on LEDs
    
    LOW MOTOR_1_DIR             ' Set stbd motor (motor 1) to fwd (CW)
                                ' (always spins in the same direction)
    IF PortEngDir = 0 THEN
        LOW MOTOR_2_DIR         ' Set port motor (motor 2) to fwd (CCW)
    ELSE
        HIGH MOTOR_2_DIR        ' Set port motor (motor 2) to rev (CW)
    ENDIF
    
    ' Spin up motors to saved value of _MotorRPM
    ' (Below a cycle of 66, the motors don't move at all)
    IF MotorRPM > 66 THEN
        FOR I = 65 to MotorRPM
            pause 30             
            HPWM 1, I, 20000            ' Stbd engine (CCP1)
            IF PortEngDir = 0 THEN
                HPWM 2, I, 20000        ' Port engine (CCP2), fwd (CCW)
            ELSE
                HPWM 2, (255-I), 20000  ' Port engine (CCP2), rev (CW)        
            ENDIF
        NEXT I
    EndIf
    HPWM 1, MotorRPM, 20000             ' Stbd engine (CCP1)
    IF PortEngDir = 0 THEN              
        HPWM 2, MotorRPM, 20000         ' Port engine (CCP2)
    ELSE
        HPWM 2, (255-MotorRPM), 20000   ' Port engine (CCP2)
    ENDIF
    
    ' Enable interrupts on RPM control now that motors are fully spun up
    ;INTCON   = %10011000        ' Global int enabled, INTE enabled, IOCI enabled, 
                                ' INTF flag bit 0 clr, IOCI flag bit 0 clr
    INTCON   = %10001000        ' Global int enabled, IOCI enabled, 
                                ' INTF flag bit 0 clr, IOCI flag bit 0 clr
    IOCAP.0  = 1                ' Enable positive (rising edge) change
    IOCAP.1  = 1                ' Enable positive (rising edge) change
    IOCAN.0  = 1                ' Enable negative (falling edge) change
    IOCAN.1  = 1                ' Enable negative (falling edge) change
    IOCAF.0  = 0                ' Clear interupt-on-change flag
    IOCAF.1  = 0                ' Clear interupt-on-change flag
    ;INTCON.1 = 0                ' Clear RA2/INT External Interrupt Flag
    
    @ INT_ENABLE   IOC_INT      ; Interrupt-on-Change interrupt
    ;@ INT_ENABLE   INT_INT      ; INT/Ext Interrupt
    
    Main:
        ' Check if motor RPM has changed
        IF MotorRPM <> Old_RPM Then
            Old_RPM = MotorRPM
            GOSUB ChngMotorHPWM
        EndIF   
       
        TimeCnt = 0
    	While ButtonPress = 0
    	    TimeCnt = TimeCnt + 1
    	    Pause 10
    	    If TimeCnt > 500 Then BtnAction
    	Wend
     
        BtnAction:
            If TimeCnt > 0 and TimeCnt < 200 Then
                PortEngDir = PortEngDir + 1
                If PortEngDir > 1 Then PortEngDir = 0
    @ EE_write_var _PortEngDir        ; save the new number to EEPROM
                
                GOSUB ReversePortEng
            ElseIf TimeCnt >= 200 Then
    @ EE_write_default _MotorRPM        
            EndIf
     
        GOTO Main
    
    ReversePortEng:
        LOW MOTOR_2_DIR                    ' Electrically stop motor 2
        LOW MOTOR_2_PWM
    
        pause 100
    
        IF PortEngDir = 0 THEN
            LOW MOTOR_2_DIR                ' Set port motor (motor 2) to fwd (CCW)
        ELSE
            HIGH MOTOR_2_DIR               ' Set port motor (motor 2) to rev (CW)
        ENDIF
    
        IF PortEngDir = 0 THEN
            HPWM 2, MotorRPM, 20000        ' Port engine (motor 2), fwd (CCW)
        ELSE
            HPWM 2, (255-MotorRPM), 20000  ' Port engine (motor 2), rev (CW)    
        ENDIF
    
        RETURN
        
    
    ChngMotorHPWM:
        HPWM 1, MotorRPM, 20000  ' Stbd engine (motor 1)
                                 ; Tried 245 Hz but it made the motor too loud.
                                 ; Supposedly, anything above 20kHz is above 
                                 ; human hearing
    
        IF PortEngDir = 0 THEN
            HPWM 2, MotorRPM, 20000        ' Port engine (motor 2), fwd (CCW)
        ELSE
            HPWM 2, (255-MotorRPM), 20000  ' Port engine (motor 2), rev (CW)    
        ENDIF
        
        RETURN
    end
    
    ' ***************************************************************
    ' [IOC - interrupt handler]
    ' ***************************************************************
    RotEncAdjust:
        New_Bits = PORTA & (%00000011)
        IF (New_Bits & %00000011) = (Old_Bits & %00000011) Then DoneRotEnc
    
        RotEncDir = New_Bits.1 ^ Old_Bits.0
        IF RotEncDir = 1 Then
            ; CW rotation - increase speed but only to a max of 255
            IF MotorRPM < 255 then MotorRPM = MotorRPM + 1
        Else
            ' CCW rotation - decrease speed to a min of 0
            IF MotorRPM > 0 Then MotorRPM = MotorRPM - 1
        EndIF
    
    @ EE_write_var _MotorRPM        ; save the new number to EEPROM
    
    DoneRotEnc:
        Old_Bits = New_Bits
        
        IOCAF.0 = 0      ' Clear interrupt flags
        IOCAF.1 = 0
    
    @ INT_RETURN
    
    ' ***************************************************************
    ' [INT - interrupt handler]
    ' ***************************************************************
    ;RotEncBtnPress:
        ' Restore MotorRPM to default value
    ;@ EE_write_default _MotorRPM
    
    ;    INTCON.1  = 0    ' Clear RA2/INT External Interrupt Flag
    
    ;@ INT_RETURN
    Nacelle_Motors_16F1825_32Mhz_Int_SN754410_FINAL.txt

    Also, would adding the blinkies to this project (which already uses Darrel's DT_INST-14.bas to handle a quadrature rotary encoder inputs) affect the existing functionality?

  4. #4


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    Do you see any (major) difference between the 16G1782 and the 16F1825? The latter has only 14 pins (compared to the former's 28) and that would help a lot; I only need 5 outputs. Plus, I have a bunch of those around.

    Ok, so let's say I use 1 dedicated 16F1825 chip to do the 5 independent blinks - should I use the SPWM include from Darrel? How do I configure the 5 timers with different on/off frequencies?

  5. #5
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    Why pay for overpriced toys when you can have
    professional grade tools for FREE!!!

  6. #6
    Join Date
    May 2009
    Posts
    40


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    You do not need a seperate hardware timer for each led. A single timer would do the job. Adapt the following code to suit your needs.
    Code:
    #config
      __CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_ON & _IESO_ON & _BOR_ON & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_ON & _XT_OSC
      __CONFIG    _CONFIG2, _WRT_OFF & _BOR40V
    #endconfig
    
    TIMER0  VAR  BYTE
    TIMER1  VAR  BYTE
    TIMER2  VAR  BYTE
    TIMER3  VAR  BYTE
    TIMER4  VAR  BYTE
    TIMER5  VAR  BYTE
    TIMER6  VAR  BYTE
    TIMER7  VAR  BYTE
     
    LED0   VAR  PORTB.0  
    LED1   VAR  PORTB.1  
    LED2   VAR  PORTB.2  
    LED3   VAR  PORTB.3  
    LED4   VAR  PORTB.4  
    LED5   VAR  PORTB.5  
    LED6   VAR  PORTB.6  
    LED7   VAR  PORTB.7  
    
    wsave    VAR  BYTE $70 SYSTEM
    ssave    VAR  BYTE $71 SYSTEM
    psave    VAR  BYTE $72 SYSTEM
    
    
    GOTO  START:
    DEFINE INTHAND MYINT
    ASM
    MYINT 
                movwf   wsave        ; <=2k codespace 
                swapf   STATUS,W     ; <=2k codespace
                clrf    STATUS       ; <=2k codespace
                movwf   ssave        ; <=2k codespace
                movf    PCLATH,W     ; <=2k codespace 
                movwf   psave        ; <=2k codespace
                TSTF    _TIMER0      ;test timer0
                BTFSS   STATUS,Z     ;skip if zero
                DECF    _TIMER0,F    ;decrement timer 0
                TSTF    _TIMER1
                BTFSC   STATUS,Z
                DECF    _TIMER1,F
                TSTF    _TIMER2
                BTFSC   STATUS,Z
                DECF    _TIMER2,F
                TSTF    _TIMER3
                BTFSC   STATUS,Z
                DECF    _TIMER3,F
                TSTF    _TIMER4
                BTFSC   STATUS,Z
                DECF    _TIMER4,F
                TSTF    _TIMER5
                BTFSC   STATUS,Z
                DECF    _TIMER5,F
                TSTF    _TIMER6
                BTFSC   STATUS,Z
                DECF    _TIMER6,F
                TSTF    _TIMER7
                BTFSC   STATUS,Z
                DECF    _TIMER7,F
                BCF     PIR1,0
                MOVF    psave,W
                MOVWF   PCLATH
                SWAPF   ssave,W
                MOVWF   STATUS
                SWAPF   wsave,F
                SWAPF   wsave,W
                RETFIE
    ENDASM
    
    START:
    ANSEL=0         'all pins are digital 
    ANSELH=0  
    TRISB=$00       'all outputs
    PORTB=0
    OPTION_REG=$80
    T1CON=$01       'interrupt every 65.5 ms
    PIE1=$01        'enable timer 1 interrupts
    INTCON=$C0      'enable interrupts
    AGAIN:
    IF TIMER0=0 THEN
       TIMER0=10
       TOGGLE LED0
    ENDIF
    IF TIMER1=0 THEN
       TIMER1=9
       TOGGLE LED1
    ENDIF
    IF TIMER2=0 THEN
       TIMER2=5
       TOGGLE LED2
    ENDIF
    IF TIMER3=0 THEN
       TIMER3=7
       TOGGLE LED3
    ENDIF
    IF TIMER4=0 THEN
       TIMER4=12
       TOGGLE LED4
    ENDIF
    IF TIMER5=0 THEN
       TIMER5=6
       TOGGLE LED5
    ENDIF
    IF TIMER6=0 THEN
       TIMER6=8
       TOGGLE LED6
    ENDIF
    IF TIMER7=0 THEN
       TIMER7=11
       TOGGLE LED7
    ENDIF
    GOTO AGAIN
    pic used is a 16F882.

  7. #7
    Join Date
    Dec 2012
    Location
    Tennessee
    Posts
    262


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    I've looked at your schematic, and im not sure what you are doing with those transistors. Are you using them just to turn on and off the leds? is your pots there, to tune the current for the leds?
    I use N-Mosfets, instead of transistors, they act more like a switch, transistors turn on more the more voltage/current their fed, but a fet can be turned on fully with a minimal of power. You can drive a FET directly from the chip, no resistor needed. heres what I would do, +5v to Pot Pin 1, Gnd to Pot Pin 3, Pot Pin 2 goes to LED +, LED- goes to FET Drain, FET Source goes to GND, FET Gate goes directly to PIC PIN. this allows to to turn on and off your LEDs with very little to no current/voltage loss on the FET, all FETs will be turned on the same ammount. FETs do not get as warm as regular transistors and can usually handle more current.
    The only thing I see a problem with is how many LEDs in parallel you hook up to each POT, You can turn on a LED with 10-25ma, if you have 5 turned on and running at 125ma, that may cause a wattage problem for the POT. But this may not be a problem, It all depends on application and use.
    #1 though, you shouldnt be sinking or driving LEDs to the PIC directly, its fine to do this on a breadboard for testing and such, however if your using many leds, its good to throw in a resistor. That notice on how much the chip can sink current wasnt placed there so you could sink current from leds, its a electrical rating for the chip for all outputs, when you hook up a button with a debounce circuit, the chip has to sink som of that current, each pin that has a high input with a resistor that the pic makes low, has to sink current. all these add up, if you start adding LEDs thats alot more it has to handle. It can make the chip work eratic, or fail, it may not happen today or tomarrow. best to just use the pins for data or drive another device to handle the voltage/current.
    OH there is also another good reason to use FETs, you can use a seperate voltage source of a much higher voltage, you could drive 12volt headlights on a car using the right FET and they would behave just like the LED, or a Motor, or lots of things. Like I said a FET is like a 1-Direction Switch, either on or off.
    Have fun, your project sounds interesting. I did the same type of project a few months back with very little code, not much different than yours. I just now read your thread so I didnt have a chance to post code before you got it working the way you wanted. good luck.

  8. #8


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    The transistors are there so I can drive up to 10 LEDs per PIC pin. The trim pots are to control the LED brightness (via current change).

  9. #9
    Join Date
    Dec 2012
    Location
    Tennessee
    Posts
    262


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    try the N-Mosfets out, I think you will end up liking them better than transistors. if you have a company name and a .com email you can get free samples from Fairchild Semiconductor to test them out. their "BS270" is very good, handles 400ma with a 5ohm resistance, but up to 2 amps with pulses. thats enough without the pulses to drive 25 leds.
    below is an example of how to hook them up, very easy and once you get into MOSFETS they tend to end up in tons of your projects

    this is not my schematic, but it looks like a circuit i would build.

  10. #10


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    I have some BS170's so I'll give those a try.

    If I still want to implement LED brightness control with the code Darrel came up with earlier in this thread, I wonder if there is a way to combine this with his SPWM_INT.bas module; instead of just setting the port pin high (on), send a SWPM at a user-adjustable duty cycle for the duration of the 'on' period.

  11. #11
    Join Date
    Dec 2012
    Location
    Tennessee
    Posts
    262


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    you can do that easily if you want them all to dim at the same rate using the PICs PWM going into the gate of a seperate FET with its drain tied to all the fets, sources. and its source to ground, this adds a ~.5v voltage drop but you can compensate by adjusting your pots.

    I did this on a guys truck, he wanted 2 sets of floorboard lights, operated from a single pushbutton, but he also wanted to control their brightness, it was easy enought to set a 2 bit binary output to 2 FETS, and have them tied to a 3rd FET that was drivin by the PWM pin. and I just used a POT to set the PWM, and a button to select the lights (left, right, both, off).

  12. #12


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    Quote Originally Posted by wdmagic View Post
    you can do that easily if you want them all to dim at the same rate using the PICs PWM going into the gate of a seperate FET with its drain tied to all the fets, sources. and its source to ground, this adds a ~.5v voltage drop but you can compensate by adjusting your pots.

    I did this on a guys truck, he wanted 2 sets of floorboard lights, operated from a single pushbutton, but he also wanted to control their brightness, it was easy enought to set a 2 bit binary output to 2 FETS, and have them tied to a 3rd FET that was drivin by the PWM pin. and I just used a POT to set the PWM, and a button to select the lights (left, right, both, off).
    But did the LEDs blink? It sounds like your LEDs were steady-on with brightness control. For my application, I need to control the brightness of blinking LEDs. You can see the full code file above (created by Darrel) but I think the relevant portion is:

    Code:
    CCPR1val      CON EXT      : @CCPR1val = (OSC*1000000/4)/ BLINKYFREQ
    ;CCPR1         VAR WORD EXT : @CCPR1 = CCPR1L
    Timer1        VAR WORD EXT : @Timer1 = TMR1L
    CCPIF         VAR PIR1.2
    
    ;----[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
    
    ;----[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

  13. #13


    Did you find this post helpful? Yes | No

    Default 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

  14. #14
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default 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
    DT

  15. #15
    Join Date
    Apr 2011
    Location
    Welches, Oregon
    Posts
    198


    Did you find this post helpful? Yes | No

    Default 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.

  16. #16


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    Quote Originally Posted by Darrel Taylor View Post
    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!

  17. #17


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    Quote Originally Posted by Darrel Taylor View Post
    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

  18. #18
    Join Date
    Dec 2012
    Location
    Tennessee
    Posts
    262


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    you could also use the pulseout ant treat the FET's like a servo, and adjust duty cycle from 0 to 100,
    also have a look at my post about adding PWMs to pics that have none or need more.

  19. #19
    Join Date
    Dec 2012
    Location
    Tennessee
    Posts
    262


    Did you find this post helpful? Yes | No

    Default 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

  20. #20


    Did you find this post helpful? Yes | No

    Default 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

  21. #21


    Did you find this post helpful? Yes | No

    Default 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.

  22. #22


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    Quote Originally Posted by RossWaddell View Post
    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.

Similar Threads

  1. Single button function
    By DynamoBen in forum mel PIC BASIC Pro
    Replies: 40
    Last Post: - 4th April 2020, 18:33
  2. How to blink 8 LEDs at different rates- concurrently?
    By rmteo in forum mel PIC BASIC Pro
    Replies: 14
    Last Post: - 26th April 2010, 23:47
  3. single sided PCB
    By schu4647 in forum General
    Replies: 1
    Last Post: - 10th December 2008, 18:22
  4. Can't Blink 2 LEDs
    By dfort in forum mel PIC BASIC
    Replies: 2
    Last Post: - 5th March 2008, 22:36
  5. Tx and Rx of Single Pin PIC's
    By Dwayne in forum Code Examples
    Replies: 0
    Last Post: - 26th May 2004, 14:55

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts