VGA Blinking Lights

Pseudo Random VGA blinking lights generator

Similar projects worth following
This project consists of a a device capable of generating a (pseudo) random blinking lights pattern. The objective of this project is to turn old monitors, specially CRTs, into decorative objects.

The VGA video generation is performed by the PIC counting cycle by cycle.

At 20MHz the PIC executes one instruction cycle at each 200ns. It means that a whole VGA line (31,77us) shall last 159 cycles. This value is rounded up but close enough for a stable image (full detail)

The VGA output is impedance and amplitude controlled. It can be achieved by doing some math. The values are not critical, though. Anything about 20% of the calculated values are good enough.

The randomness is generated by using a Galois LFSR (Linear Feedback Shift Register) with a different seed for each line of 8 'dots'. The code was borrowed from PICLIST.

The timing for colour changing is done counting frames on the last blank line of a screen. The interval time is formed by adding 22 with the 4 least significant bits of one of the random variables used to control the colour of the dots. This results in a time of .36 to .63 seconds for each change.

And that's all.

  • 1 × PIC16F688 Microprocessors, Microcontrollers, DSPs / ARM, RISC-Based Microcontrollers
  • 1 × Crystal, 20MHz
  • 1 × 100nF ceramic capacitor
  • 2 × 22pf ceramic capacitor
  • 1 × 10k Ohm, 1/8W resistor

View all 10 components

  • Entry for 1K contest

    danjovic11/21/2016 at 18:28 1 comment

    I am recycling this project as an entry for the 1K contest. It takes only 471 words which considering 14 bit wide instructions will give us the equivalent to 824.25 bytes .

  • PCB assembled and working

    danjovic11/29/2015 at 05:32 3 comments

    The PCB for this project is single sided, then I've decided to make it home.

    After silver bath.

    After assembly

    some defects were found and corrected.

    And now the circuit is working fine!

    And here is a video

    And now compared with #AT26-Chuck , another Through Hole project for #The Square Inch Project

  • It's alive, it's blinking!

    danjovic11/28/2015 at 12:24 0 comments

    Finally finished first working version. ?An enhancement was to make the interval between the blinkings be a random time between 0.36 and 0.63 seconds.

  • Rendering the grid of 'dots'

    danjovic11/27/2015 at 01:08 0 comments

    I've managed to render the grid of 8 x 6 'dots' on the screen whilst the pseudo random sequence generator is on the way.

  • Defining the timings

    danjovic11/26/2015 at 00:11 0 comments

    Just defined timing for each colour pattern as well as the quantity of 'color dots' on the screen.

    Assuming that most CRT monitors have a 4:3 or 5:5 aspect ratio as well as the execution speed constraints, the amount of 'color dots' shall be 8 in horizontal and 6 in the vertical.

    The ratio between color dots and spacing shall be 6:1 and the color dots shall be 12 cycles wide by 2 cycles of black screen.

    In the picture below the lower part of the screen has stripes and intervals that correspond to the numbers presented above.

  • Code is cheap, show me the wires

    danjovic11/25/2015 at 00:26 0 comments

    Well, continuing from the last log, here are the results. Each colour stripe takes exactly 16 cycles.

    The circuit is assembled on a proto-board.

    Next step is to turn this stripe pattern into a beautiful dot color matrix.

  • Generating video, one cycle at a time

    danjovic11/25/2015 at 00:23 0 comments

    The base of the project is the cycle-by-cycle generation of VGA video signal borrowed from Tic Tac X, a previous project of mine.

    A standard VGA frame (640x480@60Hz) has 525 lines of video. Each line takes 31.77us to happen.

    When using a PIC running at 20MHz each instruction takes 200ns.

    Divinding the numbers and rounding up to the next integer we have 159 cycles. Such amount of clock cycles shall be precisely counted in order to have a jitter free picture.

    To form a frame you have to issue

    • 2 lines front porch
    • 2 lines vertical sync
    • 25 lines back porch
    • 8 lines top border
    • 480 lines video
    • 8 lines bottom border

    The sum of it all gives exactly 525 lines or 83475 clock cycles

    Considering that the back porch, top border and bottom border lines are all blank lines (1 hsync and black video after) we can rearrange the frame as:

    • 2 lines vertical sync
    • 33 lines back porch + top border
    • 480 lines video
    • 10 lines bottom border + front porch

    The next trick is to split the 480 lines of visible video into 2 halves of 240 lines. Now that fits into an 8 bit counter:

    • 2 lines vertical sync
    • 33 lines back porch + top border
    • 240 first half of lines video
    • 240 second half of lines of video
    • 10 lines bottom border + front porch

    Next challenge was harder: Cascading loops! After finishing a loop (for example between the two halves of the visible we must load again a new value on the counter and it takes 2 instructions. The problem is that we have only one cycle time free that is caused by the skip of the 'goto' instruction that close the loop. I have spent some time trying to figure out a solution until it was given me by the mindset I got after TRIZ training: Use of 'preliminary action' as well as 'the other way out': I've inverted the order of the loading of a new value on the W register prior to test if the loop reached zero. Then if there is still more iterations this value is not used, otherwise I only spend 1 instruction time to save the pre-loaded value on the register used for counting.

    The last problem is on the frame loop. I still have only one spare cycle and I need 2 for the 'goto' instruction that closes the loop.

    The solution is philosophically similar: The last line was not called from a loop, so I do not have to test for the end of the loop (with decfsz) thus saving one instruction time that I need to jump again to the beginning of the loop.

    (full explanation - in portuguese - here)

    My final VGA frame is then:

    • 2 lines vertical sync
    • 33 lines back porch + top border
    • 240 first half of lines video
    • 240 second half of lines of video
    • 9 lines bottom border + front porch
    • 1 line bottom border + front porch

    Talk is cheap, show me the code

    Well, there it goes:

    ; ** Render a VGA Frame
        movlw 2 ; Initialize amount of Vsync Lines
        movwf Conta 
        call Vsync_line
        movlw .33         ; amount of lines for next loop. Was placed here to 
        decfsz Conta,f   ; equalize timing of all loops that make the frame
        goto Vsync_loop  ; each loop takes exactly 8 cycles + call time
                       ; at 20Mhz we have 159 cycles per VGA line (31.8us)
        movwf Conta      ; 25lines backporch plus 8 lines top border
        call Blank_line
        movlw .240        ; first half of vilible lines
        decfsz Conta,f
        goto VBackPorch_Loop
        movwf Conta      ; 240 lines
        call Visible_line
        movlw .240        ; second half of vilible lines
        decfsz Conta,f
        goto VFirst_Visible_Loop
        movwf Conta      ; 240 lines
        call Visible_line
        movlw .9       ; last 10 blank lines minus one
        decfsz Conta,f
        goto VSecond_Visible_Loop
        movwf Conta      ; 8 lines bottom plus 2 frontporch 
    VFrontPorch_Loop:  ; minus one to equalize timing
        call Blank_line
        movlw .2        ;  dummy
        decfsz Conta,f
        goto VFrontPorch_Loop
        nop              ; dummy for equalize timing
        call Blank_line  ;  last is called outside a loop 
        movlw .2         
        goto VGA_Frame ;

  • Generating video with correct amplitude and output impedance

    danjovic11/24/2015 at 02:26 0 comments

    For generating the video signals for this project we are going to use simple voltage dividers to provide the correct amplitude and output impedance.
    To calculate such values we should start by analyzing the voltages and currents involved.

    We are considering signals with a peak voltage of 0.8Volts with a 75 Ohms load because this is the amplitude of the video portion of a standard 1Vpp composite video signal (being the 0.2Volts below zero the amplitude of the sync tip). Without any load the peak amplitude of the video shall be twice that value (1.6V)
    On the calculation we must also consider the output voltage of the microcontroller which is typically below Vcc.

    After the calculation we came close to two standard resistor values.

View all 8 project logs

  • 1
    Step 1

    VGA Blinking Lights connection. The power supply is rated at least 50mA but the circuit should not drain that much. Nevertheless most of the mobile phone chargers shall work with the circuit (I do not recommend using cheap chinese chargers though).

View all instructions

Enjoy this project?



Grazfather wrote 12/09/2016 at 00:18 point

Do you have a lot of spare clock cycles? I'd love to do this with my collection of 12f683. They have 5 general purpose GPIO which should be enough, but then it would require to run off the internal oscillator. Not sure if the accuracy or the speed (1MIPS) would cut it.

  Are you sure? yes | no

danjovic wrote 12/09/2016 at 01:02 point

The main problem would be the speed. It is possible to use an external oscillator though.

  Are you sure? yes | no

Grazfather wrote 12/09/2016 at 01:14 point

Yeah, the problem is that using a crystal would take up one of the five GPIOs, with none to spare (GPIO is MCLR and thus input only)

  Are you sure? yes | no

danjovic wrote 12/10/2016 at 04:51 point

Indeed, I have forgot about the MCLR pin being only an input.
Maybe some monitors can work with composite sync. It will require changing the definition of the Sync and Shelf levels.

  Are you sure? yes | no

FIRAT DEVECİ wrote 12/06/2016 at 21:33 point

This project is my favourite!

  Are you sure? yes | no

danjovic wrote 12/06/2016 at 21:38 point

Thanks again :)!

  Are you sure? yes | no

MortenW wrote 12/05/2016 at 16:54 point

With an analog input you might be able to make this respond to sound / music in addition to the "random mode" ?

  Are you sure? yes | no

clothier.bruce wrote 11/24/2016 at 22:38 point

Wheres the code

  Are you sure? yes | no

danjovic wrote 11/24/2016 at 22:59 point

There is a link for the github repository on the project's main page.

  Are you sure? yes | no

Hacker404 wrote 04/26/2016 at 11:14 point

Love it!! I am going to do this in VHDL tomorrow. It's Just so cool and I love the 8 bit colors especially when there is the first eight only. 

  Are you sure? yes | no

danjovic wrote 04/26/2016 at 15:35 point

Thanks! Please post photos of your build !

  Are you sure? yes | no

Michele Perla wrote 01/07/2016 at 15:51 point

Really nice feat! +1 Skull for you.

  Are you sure? yes | no

alpha_ninja wrote 12/07/2015 at 00:59 point

[verified: no design files missing]

  Are you sure? yes | no

danjovic wrote 12/07/2015 at 01:14 point


  Are you sure? yes | no

alpha_ninja wrote 12/07/2015 at 02:56 point


  Are you sure? yes | no

alpha_ninja wrote 12/02/2015 at 00:44 point
This is your one-week reminder to upload design documents:

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates