Menu

Yet another Xmas lights project

2022-12-17
2024-12-05
  • Peter Stone

    Peter Stone - 2022-12-17

    Hi All,
    Its Xmas so I thought I would share this simple project with you.
    It is a very simple Xmas lights controller, designed to be retrofitted into a cheap battery Xmas lights system from your favourite internet shop or local junk store.
    The code should run on just about any pic/avr micro. No special peripheral hardware is need.
    My h/w consists of a cheap battery Xmas light string that my wife acquired for $3 at a local junk store.
    The electronic components are nothing more than an 8 pin PIC (12f617), a mosfet and a few resistors.
    The additional components are just soldered together and stuffed into some free space in the battery box for the Xmas lights.

    It just brittens up an otherwise dull Xmas light string. Previously the lights were just on or off. Now they illuminate to a random array of patterns.

    ;Chip Settings
    #chip 12F617,8
    #config OSC=INTOSCIO
    
    ;Defines (Constants)
    #define Lights PortA.0
    #define PWM_Out1 PortA.0
    #define PWMFrequency 10
    
    ;Variables
    Dim State As byte
    Dim Version As string * 4
    Dim cyclecount As byte
    Dim duty As Byte
    Dim Endcount As byte
    Dim Flashontime As word
    Dim Flashofftime As word
    Dim Flicker As Byte
    
    'Xmas Lights
    'Single output drive (GP0) that controls LED Xmas light string
    'Use a MOSFET as the drive component for the LED string 
    'Runs on 12F617 or similar
    'Uses s/w PWM to keep things simple and portable.
    'Designed to be a retrofit for simple $3 battery Xmas lights that you find on ebay
    Version = "1E"
    
    'Uses PWM to control LEDs
    'Different light sequences and variable light levels to add interest.
    '1B - 5/1/19. More variety of light control added.
    '1D - 17/12/22. Added candle simulation option.
    '1E - 18/12/22. Improved randomised candle flicker routine.
    '************
    
    'Start up delay for PICkit2
    Wait 200 ms
    
    'Set up I/O pins.
    Dir GPIO.0 Out
    Dir GPIO.1 Out
    Dir GPIO.2 Out
    Dir GPIO.3 In
    Dir GPIO.4 Out
    Dir GPIO.5 Out
    
    'Set lights to off
    Set Lights Off
    
    'set up timer as seed for random number generator.
    InitTimer0 Osc, PS0_1/2
    do Forever
    
        'Get a random cycle length.
        Randomize(Timer0)
        cyclecount = Random/8
    
        'Change duty cycle to steadily increase brightness
        For duty = 10 To 250 step 10
    
            'slowly get brighter
            PWMout 1, duty, cyclecount
        next
        Set Lights On
        Wait 200 ms
    
        'change duty cycle to progressively dim.
        For duty = 250 To 10 step -10
    
            'slowly dim
            PWMout 1, duty, cyclecount
        next
        Set Lights Off
        Wait 200 ms
    
        'Now do some random flashing
        Endcount = Random/32
        Flashontime = (Random/16)*100
        Flashofftime = (Random/16)*100
        For Flashcount = 0 To Endcount
            Set Lights On
            Wait Flashontime ms
            Set Lights Off
            Wait Flashofftime ms
        Next
    
        'now do some candle flicker simulation
        Repeat 150
            Flicker = Random
            duty = (Flicker & 0b11100000) | 128
            cyclecount = (Flicker & 0b00111000) + 7
            PWMOut 1, duty, cyclecount
        end repeat
    loop
    

    Feel free to use and modify as you feel fit.

    Have fun.

    Peter.

     
  • Anobium

    Anobium - 2022-12-19

    @pwstone How cool! Thank you for the great idea.

     
  • Peter Stone

    Peter Stone - 2024-11-30

    Ho Ho ho. Xmas is coming again.
    I have updated my Xmas lights code from a few years back.
    Essentially the same functionality but this time with fewer components.

    The entire project is based around just a single PIC micro.
    I used a PIC12F617, because they are small cheap and I had a few lying around.
    The new design does away with the need for an external driver transistor/mosfet.

    The code uses a slightly modified version of the standard GCB software PWM routines to enable the use of 5 outpit pins connected in parallel to provide sufficient drive for the LED string.

    I just purchased a cheap LED fairy light string from the local $2 shop.

    Here are the pin connections for the PIC chip

    Pin1 - +ve (Vdd) power direct from the battery (in my case it was only 3V)
    Pin2, Pin3, Pin5, Pin6 & Pin7 all connected together and provide the low side drive for the LED string
    Pin4 - not connected
    Pin8 - -ve (Vss) power via the existing switch in the battery box.

    There was just enough spare space in my battery box to tuck away the single IC.

    ;Chip Settings
    #chip 12F617,8
    #config OSC=INTOSCIO
    
    ;Defines (Constants)
    '#define PWMDelay 10        'wait time in ms
    
    ;Variables
    Dim State As byte
    Dim Version As string * 4
    Dim cyclecount As byte
    Dim duty As Byte
    Dim Endcount As byte
    Dim Flashontime As word
    Dim Flashofftime As word
    Dim Flicker As Byte
    Dim highTime As Byte
    Dim count As word
    Dim cycleCount As word
    
    
    'Xmas Lights
    'Single output drive, with all output pins tied together for additional current drive, that controls LED Xmas light string
    'Direct connect low level drive for lights
    'Runs on 12F617 or similar
    'Uses special s/w PWM routine to keep things simple and portable.
    'Designed to be a retrofit for simple $3 battery Xmas lights that you find on ebay
    Version = "2A"
    
    'Uses PWM to control LEDs
    'Different light sequences and variable light levels to add interest.
    '1B - 5/1/19. More variety of light control added.
    '1D - 17/12/22. Added candle simulation option.
    '1E - 18/12/22. Improved randomised candle flicker routine.
    '2A - 30/11/24. Reworked to drive 5 output pins simultaneously (GPIO 0 - 2, GPIO 4 - 5)
    '************
    
    'Start up delay for PICkit2
    Wait 200 ms
    
    'Set up I/O pins.
    'pic12f617 only has 6 pins available (8 pin device). GPIO3 (pin4) can only be set as an input.
    Dir GPIO.0 Out
    Dir GPIO.1 Out
    Dir GPIO.2 Out
    Dir GPIO.3 In
    Dir GPIO.4 Out
    Dir GPIO.5 Out
    
    'Initialise lights to off
    'Output pins set high as active low
    GPIO = 255
    
    'Special PWM routine to drive all pins on Port A. Active low outputs.
    Sub MegaPWMOut (SoftPWMDuty, SoftPWMCycles)
        ' Inputs: 
        '   - duty: Duty cycle for all pins (0-255)
        '   - cycles: Number of cycles to generate
        ' Generate the specified number of PWM cycles
    'Software PWM
    'Duty is /255, Dur is ms
      For PWMDur = 1 to SoftPWMCycles
        For DOPWM = 1 to 255
          if SoftPWMDuty > DOPWM then
            'set lights on (active low)
            GPIO = 0  ' Set all bits of PORTA low
          Else
            'set lights off
            GPIO = 255
          end if
          #IFDEF PWM_Delay
            Wait PWM_Delay
          #ENDIF
        next
      next
    end sub
    
    'set up timer as seed for random number generator.
    InitTimer0 Osc, PS0_1/2
    
    ' now kick off the endless routine
    do Forever
    
        'Get a random cycle length.
        Randomize(Timer0)
        cyclecount = Random/8
    
        'Change duty cycle to steadily increase brightness
        For duty = 10 To 250 step 10
    
            'slowly get brighter
            MegaPWMout duty, cyclecount
        next
        GPIO = 0
        Wait 200 ms
    
        'change duty cycle to progressively dim.
        For duty = 250 To 10 step -10
    
            'slowly dim
            MegaPWMout duty, cyclecount
        next
        GPIO = 0
        Wait 200 ms
    
        'Now do some random flashing
        Endcount = Random/32
        Flashontime = (Random/16)*100
        Flashofftime = (Random/16)*100
        For Flashcount = 0 To Endcount
            GPIO = 0
            Wait Flashontime ms
            GPIO = 255
            Wait Flashofftime ms
        Next
    
        'now do some candle flicker simulation
        Repeat 150
            Flicker = Random
            duty = (Flicker & 0b11100000) | 128
            cyclecount = (Flicker & 0b00111000) + 7
            MegaPWMOut duty, cyclecount
        end repeat
    loop
    

    Enjoy

    Peter.

     
    • Anobium

      Anobium - 2024-11-30

      Video!! Then we can we see the effect.

       
      ❤️
      1
      • Peter Stone

        Peter Stone - 2024-12-05

        I have attached an image that shows the little 8pin PIC stuffed inside the battery box.
        I have also attached a short video to show the light effects. I think I managed to capture the candle flickering effect, but not sure how well it will come up in the video. Unfortunately, these cheap battery lights just have all the leds connected in series, so no real opportunity to to drive multiple outputs. The idea could easily be adapted to lights with multiple circuits.
        Peter.

         
  • Peter Stone

    Peter Stone - 2024-12-05

    Ho Ho ho. Xmas is coming again.
    I have updated my Xmas lights code from a few years back.
    Essentially the same functionality but this time with fewer components.

    The entire project is based around just a single PIC micro.
    I used a PIC12F617, because they are small cheap and I had a few lying around.
    The new design does away with the need for an external driver transistor/mosfet.

    The code uses a slightly modified version of the standard GCB software PWM routines to enable the use of 5 outpit pins connected in parallel to provide sufficient drive for the LED string.

    I just purchased a cheap LED fairy light string from the local $2 shop.

    Here are the pin connections for the PIC chip

    Pin1 - +ve (Vdd) power direct from the battery (in my case it was only 3V)
    Pin2, Pin3, Pin5, Pin6 & Pin7 all connected together and provide the low side drive for the LED string
    Pin4 - not connected
    Pin8 - -ve (Vss) power via the existing switch in the battery box.

    There was just enough spare space in my battery box to tuck away the single IC.

    ;Chip Settings
    #chip 12F617,8
    #config OSC=INTOSCIO
    
    ;Defines (Constants)
    '#define PWMDelay 10        'wait time in ms
    
    ;Variables
    Dim State As byte
    Dim Version As string * 4
    Dim cyclecount As byte
    Dim duty As Byte
    Dim Endcount As byte
    Dim Flashontime As word
    Dim Flashofftime As word
    Dim Flicker As Byte
    Dim highTime As Byte
    Dim count As word
    Dim cycleCount As word
    
    
    'Xmas Lights
    'Single output drive, with all output pins tied together for additional current drive, that controls LED Xmas light string
    'Direct connect low level drive for lights
    'Runs on 12F617 or similar
    'Uses special s/w PWM routine to keep things simple and portable.
    'Designed to be a retrofit for simple $3 battery Xmas lights that you find on ebay
    Version = "2A"
    
    'Uses PWM to control LEDs
    'Different light sequences and variable light levels to add interest.
    '1B - 5/1/19. More variety of light control added.
    '1D - 17/12/22. Added candle simulation option.
    '1E - 18/12/22. Improved randomised candle flicker routine.
    '2A - 30/11/24. Reworked to drive 5 output pins simultaneously (GPIO 0 - 2, GPIO 4 - 5)
    '************
    
    'Start up delay for PICkit2
    Wait 200 ms
    
    'Set up I/O pins.
    'pic12f617 only has 6 pins available (8 pin device). GPIO3 (pin4) can only be set as an input.
    Dir GPIO.0 Out
    Dir GPIO.1 Out
    Dir GPIO.2 Out
    Dir GPIO.3 In
    Dir GPIO.4 Out
    Dir GPIO.5 Out
    
    'Initialise lights to off
    'Output pins set high as active low
    GPIO = 255
    
    'Special PWM routine to drive all pins on Port A. Active low outputs.
    Sub MegaPWMOut (SoftPWMDuty, SoftPWMCycles)
        ' Inputs: 
        '   - duty: Duty cycle for all pins (0-255)
        '   - cycles: Number of cycles to generate
        ' Generate the specified number of PWM cycles
    'Software PWM
    'Duty is /255, Dur is ms
      For PWMDur = 1 to SoftPWMCycles
        For DOPWM = 1 to 255
          if SoftPWMDuty > DOPWM then
            'set lights on (active low)
            GPIO = 0  ' Set all bits of PORTA low
          Else
            'set lights off
            GPIO = 255
          end if
          #IFDEF PWM_Delay
            Wait PWM_Delay
          #ENDIF
        next
      next
    end sub
    
    'set up timer as seed for random number generator.
    InitTimer0 Osc, PS0_1/2
    
    ' now kick off the endless routine
    do Forever
    
        'Get a random cycle length.
        Randomize(Timer0)
        cyclecount = Random/8
    
        'Change duty cycle to steadily increase brightness
        For duty = 10 To 250 step 10
    
            'slowly get brighter
            MegaPWMout duty, cyclecount
        next
        GPIO = 0
        Wait 200 ms
    
        'change duty cycle to progressively dim.
        For duty = 250 To 10 step -10
    
            'slowly dim
            MegaPWMout duty, cyclecount
        next
        GPIO = 0
        Wait 200 ms
    
        'Now do some random flashing
        Endcount = Random/32
        Flashontime = (Random/16)*100
        Flashofftime = (Random/16)*100
        For Flashcount = 0 To Endcount
            GPIO = 0
            Wait Flashontime ms
            GPIO = 255
            Wait Flashofftime ms
        Next
    
        'now do some candle flicker simulation
        Repeat 150
            Flicker = Random
            duty = (Flicker & 0b11100000) | 128
            cyclecount = (Flicker & 0b00111000) + 7
            MegaPWMOut duty, cyclecount
        end repeat
    loop
    

    Enjoy

    Peter.

     
  • Peter Stone

    Peter Stone - 2024-12-05

    Ho Ho ho. Xmas is coming again.
    I have updated my Xmas lights code from a few years back.
    Essentially the same functionality but this time with fewer components.

    The entire project is based around just a single PIC micro.
    I used a PIC12F617, because they are small cheap and I had a few lying around.
    The new design does away with the need for an external driver transistor/mosfet.

    The code uses a slightly modified version of the standard GCB software PWM routines to enable the use of 5 outpit pins connected in parallel to provide sufficient drive for the LED string.

    I just purchased a cheap LED fairy light string from the local $2 shop.

    Here are the pin connections for the PIC chip

    Pin1 - +ve (Vdd) power direct from the battery (in my case it was only 3V)
    Pin2, Pin3, Pin5, Pin6 & Pin7 all connected together and provide the low side drive for the LED string
    Pin4 - not connected
    Pin8 - -ve (Vss) power via the existing switch in the battery box.

    There was just enough spare space in my battery box to tuck away the single IC.

    ;Chip Settings
    #chip 12F617,8
    #config OSC=INTOSCIO
    
    ;Defines (Constants)
    '#define PWMDelay 10        'wait time in ms
    
    ;Variables
    Dim State As byte
    Dim Version As string * 4
    Dim cyclecount As byte
    Dim duty As Byte
    Dim Endcount As byte
    Dim Flashontime As word
    Dim Flashofftime As word
    Dim Flicker As Byte
    Dim highTime As Byte
    Dim count As word
    Dim cycleCount As word
    
    
    'Xmas Lights
    'Single output drive, with all output pins tied together for additional current drive, that controls LED Xmas light string
    'Direct connect low level drive for lights
    'Runs on 12F617 or similar
    'Uses special s/w PWM routine to keep things simple and portable.
    'Designed to be a retrofit for simple $3 battery Xmas lights that you find on ebay
    Version = "2A"
    
    'Uses PWM to control LEDs
    'Different light sequences and variable light levels to add interest.
    '1B - 5/1/19. More variety of light control added.
    '1D - 17/12/22. Added candle simulation option.
    '1E - 18/12/22. Improved randomised candle flicker routine.
    '2A - 30/11/24. Reworked to drive 5 output pins simultaneously (GPIO 0 - 2, GPIO 4 - 5)
    '************
    
    'Start up delay for PICkit2
    Wait 200 ms
    
    'Set up I/O pins.
    'pic12f617 only has 6 pins available (8 pin device). GPIO3 (pin4) can only be set as an input.
    Dir GPIO.0 Out
    Dir GPIO.1 Out
    Dir GPIO.2 Out
    Dir GPIO.3 In
    Dir GPIO.4 Out
    Dir GPIO.5 Out
    
    'Initialise lights to off
    'Output pins set high as active low
    GPIO = 255
    
    'Special PWM routine to drive all pins on Port A. Active low outputs.
    Sub MegaPWMOut (SoftPWMDuty, SoftPWMCycles)
        ' Inputs: 
        '   - duty: Duty cycle for all pins (0-255)
        '   - cycles: Number of cycles to generate
        ' Generate the specified number of PWM cycles
    'Software PWM
    'Duty is /255, Dur is ms
      For PWMDur = 1 to SoftPWMCycles
        For DOPWM = 1 to 255
          if SoftPWMDuty > DOPWM then
            'set lights on (active low)
            GPIO = 0  ' Set all bits of PORTA low
          Else
            'set lights off
            GPIO = 255
          end if
          #IFDEF PWM_Delay
            Wait PWM_Delay
          #ENDIF
        next
      next
    end sub
    
    'set up timer as seed for random number generator.
    InitTimer0 Osc, PS0_1/2
    
    ' now kick off the endless routine
    do Forever
    
        'Get a random cycle length.
        Randomize(Timer0)
        cyclecount = Random/8
    
        'Change duty cycle to steadily increase brightness
        For duty = 10 To 250 step 10
    
            'slowly get brighter
            MegaPWMout duty, cyclecount
        next
        GPIO = 0
        Wait 200 ms
    
        'change duty cycle to progressively dim.
        For duty = 250 To 10 step -10
    
            'slowly dim
            MegaPWMout duty, cyclecount
        next
        GPIO = 0
        Wait 200 ms
    
        'Now do some random flashing
        Endcount = Random/32
        Flashontime = (Random/16)*100
        Flashofftime = (Random/16)*100
        For Flashcount = 0 To Endcount
            GPIO = 0
            Wait Flashontime ms
            GPIO = 255
            Wait Flashofftime ms
        Next
    
        'now do some candle flicker simulation
        Repeat 150
            Flicker = Random
            duty = (Flicker & 0b11100000) | 128
            cyclecount = (Flicker & 0b00111000) + 7
            MegaPWMOut duty, cyclecount
        end repeat
    loop
    

    Enjoy

    Peter.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.