A walking light is a row of lamps which are lighted one by one. This gives the impression that a light walks along the row. In this assignment we will make a walking light from 8 LEDs. With appropriate hardware (optocouplers and triacs) the same programs can be used to control 8 lamps.
A small problem is that for simplicity we want to use the pins of port b and when we connect a LED directly to pin B6 or B7 this would prevent in-circuit programming of the PIC. Hence we use - for these pins only - a buffer transistor.
The program for a light which always walks in the same direction is quite simple:
include 16c84_10 include jlib port_b_direction = all_output var byte x = 0b_0000_0001 forever loop port_b = ! x delay_100ms( 2 ) x = x << 1 if x == 0b_0000_0000 then x = 0b_0000_0001 end if end loop
After the include lines (remember to adapt the first one to the 16x84 chip and crystal you use) we first make all pins of port B outputs. Just before the forever loop we declare a variable which we initisalize to 0b_0000_0001, which means all bits off except the lowest one which is on.
The exclamation mark in port_b = ! x means that the value which is written to port B has all bits inverted. This is necessary because the LEDs are connected between the ouput pins and the + which makes the output pins active low.
Within the loop we first write the (inverted) value of x to port B and we wait 2 * 100 ms = 0.2 seconds. Next we shift the value in x one position to the left. When we do this often enough the one bit which is on will shift out at the left while off bits shift in at the right, producing a value of all bits off (all zero's). When this is the case we set x back to its initial value of 0b_0000_0001.
Build the circuit and program the 16x84.
Instead of a single LED which is on we can of course take another pattern and shift it. Change the program to have 2 LEDs on at any time. You must change both the initial values and the test.
Instead of shifting a pattern we can also create an expanding bar: first only LED 0, then LED 0 and LED 1, etc. The trick to achieve this is a code line
The | means OR: each bit in x will be shiften one position to the left and then the lowest will be set. The net effect is that the light grows from right to left.
x = ( x << 1 ) | 0b_0000_0001
Adapt the program. You will have to change the IF condition too. The best effect will likely require that you put the shifting in the else part of the if statement.
The Nightrider car shows a light which bounces back and forth. To achieve this effect we must remember, besides the current value of x, also the current direction in which the light moves. When the light hits the left or right border the direction must be reversed.
.. const bit to_left = low const bit to_right = high var bit direction = to_left .. if x == 0b_0000_0001 then direction = to_left end if if x == 0b_1000_0000 then direction = to_right end if if direction == to_left then x = x << 1 else x = x >> 1 end if ..
Only the new parts of the program are shown. Try to understand how these parts work and change your program.
Change your program to let two LEDs light up.
Symmetrical patterns often look nice. A simple symmetrical pattern consists of two light which move from the edges towards the middle. This pattern has only five steps (the last one is 'all LEDs off), so its is easy to write out all steps:
forever loop port_b = .. delay.. port_b = .. delay .. port_b = .. delay.. port_b = .. delay.. port_b = .. delay.. end loop
Write the new program, filling in the missing parts. Almost nothing of the previous program is left.
The last program can be simplified a bit by creating a procedure which takes one argument which it writes to port b and then delays. Within the loop you just call this procedure 5 times.
Change your program to let the lights touch in the middle and then move out again. Leave out the 'all LEDs off' step. This pattern has 6 steps.