Single PIC to Blink 5 LEDs Independently?


Closed Thread
Results 1 to 40 of 69

Hybrid View

  1. #1


    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

  2. #2


    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.

  3. #3


    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