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?

    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?

  2. #2
    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!!!

  3. #3
    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.

  4. #4


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    I will indeed try that out with a 1fF1825. Could you please clarify for me where I set the individual on/off values for each of the 8 LEDs? In my existing implementation (5 separate 12F683's) I have code like this:

    Code:
    ' Changing the value for "Cycle" will change the time it takes
    ' to fade from 100% to 0% (or 0% to 100% if duty is increasing)
    ' Lower number = faster fade in/out
    Cycle = 1
    
    ' Higher step value produces faster fade, but too high a value
    ' will introduce flicker
    STEP_CNTR = 2
    
    Main:
        ' Fade in
        For Duty = 0 TO 255 step STEP_CNTR
            PWM LED_0, Duty, Cycle
        Next
    
        ' Stay on LGHTS_ON_MS
        HIGH LED_0
        Pause LGHTS_ON_MS
    
        ' Fade out
        For Duty = 255 TO 0 STEP -STEP_CNTR
            PWM LED_0, Duty, Cycle
        Next
    	
        ' Stay off for LGHTS_OFF_MS
        Pause LGHTS_OFF_MS
    
        ' Fade in
        For Duty = 0 TO 255 step STEP_CNTR
            PWM LED_0, Duty, Cycle
        Next
    
        ' Stay on LGHTS_ON_MS
        HIGH LED_0
        Pause (LGHTS_ON_MS - 200)
    
        ' Fade out
        For Duty = 255 TO 0 STEP -STEP_CNTR
            PWM LED_0, Duty, Cycle
        Next
    	
        ' Stay off for LGHTS_OFF_MS
        Pause (LGHTS_OFF_MS + 100)
    
        GOTO Main
    (In actuality, I extend the fade in/stay on/fade out/stay off with various timings to randomize the effect. Old 1960's Christmas tree lights did not have constant blink rates).

  5. #5


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    I've tried adapting Darrel's example from this thread, but no luck with a PIC16F1825 - PORTC.0-3 do not blink (PORTC.0-2 are off; PORTC.3 is on) but PORTC.4 blinks properly. What am I doing wrong here? I've had to adapt Darrel's code for the PIC16F1825 and reduced the number of blinkies to 5 from 8.

    Code:
    '****************************************************************
    '*  Name    : UNTITLED.BAS                                      *
    '*  Author  : Ross Waddell                                      *
    '*  Notice  : Copyright (c) 2012 [select VIEW...EDITOR OPTIONS] *
    '*          : All Rights Reserved                               *
    '*  Date    : 10/27/2012                                        *
    '*  Version : 1.0                                               *
    '*  Notes   : PIC16F1825                                                 *
    '*          :                                                   *
    '****************************************************************
    
    DEFINE OSC 4
    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_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF
       __config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
    #ENDCONFIG
    
    OSCCON   = %01101000        ' 4MHz internal osc
    
    
    DATA 50,22,38,75,17;,40,62,13  ; default periods for each Output
    ;----------------------------------------------------------------
    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[5]
    LoopCON   VAR BYTE[5]
    x         VAR BYTE
    
    ;----[Initialize]------------------------------------------------
    FOR x = 0 to 4         ; load the periods from EEPROM
        READ x, LoopCON(x)
    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
    
    ANSELC = 0
    TRISC = 0              ; PORTC all OUTPUT
    
    ;----[Main Program Loop]----------------------------------------
    Main: 
        ;x = (x + 1) // 8
        x = (x+1)&4
        PORTC.0(x) = !(LoopLED(x) < LoopCON(x))
        LoopLED(x) = (LoopLED(x) + 1) // (LoopCON(x) << 1)
        IF x != 4 THEN Main
    
    Waiting: IF !CCPIF THEN Waiting
        CCPIF = 0
    GOTO Main
    Last edited by RossWaddell; - 28th October 2012 at 18:35. Reason: correction

  6. #6


    Did you find this post helpful? Yes | No

    Default Re: Single PIC to Blink 5 LEDs Independently?

    Ok, so I answered my own question.

    This works:
    Code:
    x = (x + 1) // 5
    This doesn't:
    Code:
    x = (x+1)&4
    The question now becomes: is there a way to set the on/off periods individually for each of the 5 LEDs? The code above has the LEDs blink with the same on time as off; I need to be able to make some of the 'off' times longer than the 'on' and vice versa.
    Last edited by RossWaddell; - 28th October 2012 at 18:43.

  7. #7
    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 question now becomes: is there a way to set the on/off periods individually for each of the 5 LEDs?
    Yes, but you have to create the individual ON/OFF periods.
    That code only has 1 period, for a 50% dutycycle.

    So many things you can do.
    So little time to explain.
    Twinkle Twinkle little tree ...
    Code:
    DEFINE OSC 4
    DEFINE BLINKYFREQ 100  ; 10mS periods
    
    ' ***************************************************************
    ' Device Fuses
    ' ***************************************************************
    #CONFIG
       __config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF
       __config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
    #ENDCONFIG
    
    OSCCON   = %01101000        ' 4MHz internal osc
    
    ;----------------------------------------------------------------
    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
    
    ;----------------------------------------------------------------
    #DEFINE USE_RANDOM_SEQUENCE     ; comment for contiuous Sequence
    #IFDEF USE_RANDOM_SEQUENCE
        RND     VAR WORD : RND = 13864
        MIN_ON  CON 10                  ; Minimum random ON time
        MAX_ON  CON 100                 ; Maximum random ON time
        MIN_OFF CON 10                  ; 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 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
    
    ;----[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
    
    ;-- 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
    
    ANSELC = 0
    TRISC = 0              ; PORTC all OUTPUT
    
    ;----[Main Program Loop]----------------------------------------
    Main: 
        x = (x + 1) // LEDcount
        PORTC.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
    DT

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