16x84 opdracht 2 : looplicht

Een looplicht is en rij lampen die een voor een aan gaan. Het lijkt dan of er een licht rondloopt. In deze opdracht maken we een looplicht van 8 LED's. Met het zelfde programma in de 16x84 en geschikte koppelingen (optocouplers en triacs) zouden we ook 8 lampen kunnen aansturen.

looplicht schema

Een klein probleem is dat als we een LED direct aanluiten op pin B6 of B7 we de 16x84 niet meer kunnen programmeren zonder hem uit de schakeling te halen. Daarom gebruiken we voor deze twee pinnen een buffer transistor.

Het programma voor een licht dat steeds de zelfde kant op loopt is niet erg ingewikkeld:

   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

Na de include regels (let er op dat je de eerste include aanpast aan de processor en het kristal dat je gebruikt) maken we eerst all pinnen van poort B uitgang. Voor we de eeuwige loop in gaan declareren we nog een byte x die we gebruiken om de waarde die we telkens naar poort B schrijven berekenen. De begin waarde van x is 0b_0000_0001, dus alle bitjes op 0 bevalve het laagste.

De ! in port_b = ! x betekent in de waarde die naar port_b wordt geschreven alle bitjes geinverteerd zijn. Dit is nodig omdat de LEDs tussen de + end de uitgang zitten waardoor de uitgangen actief-laag zijn.

In de loop schrijven we eerst de waarde van x naar poort B en we wachten 2 * 100mS = 0.2 seconde. Vervolgend schuiven we de waarde in x een positie naar links. Als we dit vaak genoeg doen schuift de 1 er aan de linkerkant uit. Als dit het geval is (de waarde van x is dan 0b_0000_0000 geworden) dan zetten we x weer terug op 0b_0000_0001.

opdracht loop1.jal
Bouw de schakeling en programmeer de 16x84.

opdracht loop2.jal
In plaats van een enkele LED aan kunnen we natuurlijk ook een ander patroon laten schuiven. Verander het programma zodat er steeds 2 LEDs aan zijn. Je moet behalve de beginwaarden ook de if voorwaarde aanpassen, anders brand soms alleen de laatste LED. Pas ook de weerstanden die in serie met de transistoren staan aan zodat alle LEDs even fel branden. Hint: over een LED valt ongeveer 2 volt, over een PIC uitgang 0.7 volt en over een transistor ook 0.7 volt.

In plaats van opschuiven kan je ook zorgen dat er steeds meer LEDs gaan branden, dus eerst alleen de eerste, dan de eerste 2, dan de eerste 3 etc. De truuk hiervoor is de opdrachtregel

   x = ( x << 1 ) | 0b_0000_0001
De | hierin beteken OR (of): ieder bitje in x wordt 1 positie naar links geschoven en het laagste (meest rechtse) bitje wordt 1. Het effect is dus dat het licht aangroeit (steeds een LED meer aan).

opdracht loop3.jal
Pas het programma aan. Denk ook aan de conditie van het if statement. Om het beste effect te krijgen zal je het veranderen van de x waarde in de else tak van het if statement moeten zetten.

De auto van de Nightrider en de ogen van StarWars robots hebben een lichtje dat heen en weer schiet. Om dit te bereiken moet je behalve de x waarde die aan geeft welk LEDje brand ook bijhouden of je naar links of naar rechts aan het schuiven bent. Als het lichtje de linker of de rechter kan 'raakt' keert de richting om.

   ..
   const bit naar_links = low
   const bit naar_rechts = high
   var bit richting = naar_links
   ..
      if x == 0b_0000_0001 then
         richting = naar_links
      end if
      if x == 0b_1000_0000 then
         richting = naar_rechts
      end if
      if richting == naar_links then
         x = x << 1
      else
         x = x >> 1
      end if
   ..

opdracht loop4.jal
Alleen de nieuwe stukken in het programma zijn aangegeven. Probeer te begrijpen wat er gebeurt en pas je programma aan.

opdracht loop5.jal
Verander het programma zodanig dat er steeds 2 LEDs aan zijn.

Symmeterische patronen zien er vaak leuk uit. Een eenvoudig symmetrisch patroon bestaat uit twee lichtjes die steeds vanuit de zijkanten naar het midden toe bewegen. Dit patroon heeft maar 5 stappen (inclusief 'alles uit'), dus het is eenvoudig om de stappen gewoon uit te schrijven:

   forever loop
      port_b = ..
      delay..
      port_b = ..
      delay ..
      port_b = ..
      delay..
      port_b = ..
      delay..
      port_b = ..
      delay..
   end loop

opdracht loop6.jal
Voer het nieuwe programma in. Er blijft bijna niets het zelfde.. Vul zelf de ontbrekende delen in.

opdracht loop7.jal
Het vorige programma kunnen we wat mooier maken door het schijven naar poort B en het wachten in een procedure op te nemen en in de eeuwige lus 5 keer die procedure aan te roepen. Pas je programma aldus aan.

opdracht loop8.jal
Pas je programma zodanig aan dat de lichtjes als ze elkaar in het midden raken ze weer uit elkaar bewegen. Het is mooier om 'alles uit' nu weg te laten. Dit patroon heeft 6 stappen.