Difference between revisions of "Arduino - 1-digit LED Segment Display"

From SPAD-it Wiki
Jump to: navigation, search
(Created page with "===Een Segment Display=== Een segment display bevat een aantal langwerpige elementen, meestal LED's, die voornamelijk bedoeld zijn om cijfers weer te geven, maarin principe ku...")
 
(Beetje spelen)
 
(One intermediate revision by the same user not shown)
Line 4: Line 4:
 
{|class="wikitable"
 
{|class="wikitable"
 
|-
 
|-
|[[File:105px_segment_display-animated.gif|155px]]
+
|[[File:105px-Seven_segment_display-animated.gif|155px]]
 
|-
 
|-
 
|Cijfers en primitieve letters in een segment display
 
|Cijfers en primitieve letters in een segment display
Line 120: Line 120:
  
 
===Beetje spelen===
 
===Beetje spelen===
 +
Als je hier wat wilt spelen kun je de teller omkeren: in plaats van aftellen gaat hij dan van 0 naar 9. Leuker is het wellicht om hem te laten aftellen en bij 0 aangekomen alle lampjes een paar keer snel aan en uit te laten gaan.
 +
 +
Zoals uitgelegd zijn de cijfers als patronen gedefinieerd. Maar je kunt op dezelfde manier ook andere patronen maken, zoals de letters van het alfabet. Onderstaand zie je een voorbeeld van hoe je cijfers en de meeste letters zou kunnen maken met dit display (met soms een kleine in plaats van een hoofdletter). Met al deze patronen kun je het programma ook woorden laten spellen. Eventueel kun je de nog ontbrekende letters ook toevoegen, maar dan wordt de X al snel hetzelfde als de H (tenzij je een kleine letter h gebruikt) en de V hetzelfde als de U. Tja, voor het alfabet blijft het met dit display een beetje behelpen.
 +
 +
{|class="wikitable"
 +
|-
 +
|[[File:letter_display.jpg|500px]]
 +
|-
 +
|Cijfers en letters in het segment display
 +
|}
  
 
===Navigatie===
 
===Navigatie===

Latest revision as of 13:20, 7 December 2020

Een Segment Display

Een segment display bevat een aantal langwerpige elementen, meestal LED's, die voornamelijk bedoeld zijn om cijfers weer te geven, maarin principe kunnen er ook eenvoudige letters mee worden gemaakt.

105px-Seven segment display-animated.gif
Cijfers en primitieve letters in een segment display

Het display uit bovenstaand voorbeeld heeft 8 LED's: drie horizontale streepjes, twee vertikale streepjes boven, twee vertikale streepjes onder en de punt. Elk segment kan apart worden aan- en uitgezet. Bij de aansturing van een segment display ontstaan de cijfers (en letters) door de juiste combinatie van segmenten aan te zetten. De pootjes van zo'n display zijn verbonden met de 8 individuele LEDjes, terwijl er meestal een gemeenschappelijke plus is (common annode), of juist een gemeenschappelijke min (common cathode). Hoewel ze in principe gelijkwaardig zijn, werkt een common cathode iets gemakkelijker omdat de LEDjes daarvan aangaan als de plus-kant van dat LEDje hoog wordt. Bij een common annode is het plus signaal altijd aanwezig en gaat een LEDje juist aan als de andere kant laag wordt. Voor veel mensen is dat net iets minder logisch. Een 8 segment display, zoals boven, heeft dus 8 connecties voor elke LED plus een common annode (plus) of cathode (min).

SegmentDisplay CC PinConfig.png
Common Cathode Segment Display - pin cofiguratie

De letters geven aan om welke LED het gaat. Zet je bijvoorbeeld a,b,c,d en g aan, dan krijg je het cijfer 3. De punt is verbonden met pootje 5. Net als bij andere LED's moet de stroom door de LED's van een segment display worden beperkt met een weerstand. Je moet dan voor elke LED een eigen weerstand gebruiken omdat de LED-jes anders elkaar beinvloeden. Zie je overigens dat zowel pootje 3 als 8 aan de common cathode zitten? Het volstaat dus om een van de twee pootjes met de nul te verbinden.

De schakeling

Extra benodigdheden:

  • 1 1-digit segment display met common cathode (= gemeenschappelijke min)
  • 8 weerstanden van 180Ω-220Ω
1DigitSegmentDisplay.png
Schakeling voor 1 digit segment display

Het programma

Het volgende programma bevat een paar nieuwe elementen. Upload het eerst maar naar je Arduino. Het wordt hieronder in detail besproken.

byte LEDs[8];          // lijst met alle LED-pins a,b,c,d,e,f,g, en de punt
byte patronen[10];     // lijst met bit patronen voor alle cijfers, de punt, en de '-'
byte point=B00000001;  // de punt
byte minus=B00000010;  // de "-"
int wachttijd = 100;   // tijdsduur van elk cijfer

void setup()
{
  // maak een lijstje van de LED pins in volgorde van hun functie (functies 'a', 'b', etc) 
  LEDs[0]=7;  // a - zit aan pin 7 van de Arduino
  LEDs[1]=6;  // b - zit aan pin 6 van de Arduino
  LEDs[2]=5;  // c - etc.
  LEDs[3]=10; // d
  LEDs[4]=11; // e
  LEDs[5]=8;  // f
  LEDs[6]=9;  // g
  LEDs[7]=4;  // punt
  // vul de tabel met aan/uit patronen voor elk van de cijfers
  // "B" is de "binary formatter": B10000010 => alleen het eerste en een-na-laatste bit staan aan
  // het eerste bit is voor de "a" LED, het tweede voor de "b" LED, enz. Het laatste is voor de punt
  // pattern = Babcdefgp;
  patronen[ 0]=B11111100;
  patronen[ 1]=B01100000;
  patronen[ 2]=B11011010;
  patronen[ 3]=B11110010;
  patronen[ 4]=B01100110;
  patronen[ 5]=B10110110;
  patronen[ 6]=B10111110;
  patronen[ 7]=B11100000;
  patronen[ 8]=B11111110;
  patronen[ 9]=B11110110;
  // zet alle LED-pins op output mode
  for (int i=0; i<8; i++)
    pinMode(LEDs[i],OUTPUT);
  // test patroon
  for (int i=0; i<4; i++)
  {
    byte patroon = B10000000;
    for (byte j=0; j<6; j++)
    {
      showPattern(patroon >> j);  // schuif patroon j plekken naar rechts
      delay(50);
    }
  }
  showPattern(B11111111);
  delay(1000);
}

void showPattern(byte patroon) // deze functie toont het gegeven LED patroon
{
  byte first = B10000000;  // the first bit that refers to LED "a"
  for (byte i=0; i<8; i++)
    // ">>" shifts B10000000 a number of bits to the right (so "B10000000 >> 2" makes "B00100000")
    // "&" performs a bitwise AND on the numbers
    digitalWrite(LEDs[i], patroon & (first>>i) ); 
}

void loop()
{
  for (int i=9; i>=0; i--)
  {
    showPattern(patronen[i]);
    delay(wachttijd);
  }
}

Uitleg

Het eerste statement begint al met iets nieuws: byte LEDs[8]; maakt LEDs geen gewone variabele van het type byte, maar een lijst van 8 bytes. LEDs[0] is dan de eerste byte uit die lijst, LEDs[1] de tweede, en zo voort, zodat de laatste LEDs[7] is. Met een enkel statement kunnen we dus een hoop variabelen definieren. Daarbij zijn die variabelen via een loop om beurten te benaderen. Daar komen we later op terug. Het tweede statement is nu beter te begrijpen: het definieert tien bytes in een statement byte patronen[10];. Regel drie lijkt een gewone byte te definieren met de naam point. Maar de waarde van die byte is doet vreemd aan: B00000001. Met die B wordt bedoeld dat de waarde binair wordt opgegeven. We zijn gewend om waarden decimaal op te geven, 12, 349, en zo voort. Omdat het hier om een byte gaat, bestaat elke waarde in de processor uit 8 eentjes en nulletjes, en dat is nu precies wat we met Bxxxxxxxx doen: elk eentje en nulletje wordt opgegeven. Voor de processor maakt het niet uit of je 12 opgeeft, of B00001100 - van binnen is het exact hetzelfde. De punt bestaat dus uit allemaal nullen, behalve de laatste bit die 1 is.

In de setup() worden de lijsten van waarden voorzien. De lijst LEDs[] geeft precies aan welk LEDje aan welke pin van de Arduino zit. LEDs[0] is dus de pin van de LED die overeenkomt met positie a van het segment display. LEDs[1] is de pin van positie b, en zo voort. In het commentaar staat Babcdefgp: waarmee wordt aangegeven dat de eerste bit voor a is, de tweede voor b, en zo voort. De lijst patronen[] wordt helemaal gevuld met waarden die bitsgewijs worden opgegeven. Door dat bitgewijs opgeven van de getallen kun je heel gemakkelijk opgeven welke LEDjes er aan moeten staan voor elk patroon. Zo zie je dat voor patroon[0] alle LEDjes behalve de laatste twee aan staan. Als je nu kijkt naar de pin-configuratie kun je waarschijnlijk snel zien dat het hier gaat om het cijfer 0. Met een beetje moeite kun je ook de andere cijfers herkennen. De lijst patronen[] geeft dus aan welke LEDjes er aan en uit moeten staan voor elk van de cijfers.

Het volgende deel van de setup() zet alle pins van de LED's op output mode. Dit gaat met een for-loop waarbij de loop-variabele i wordt gebruikt om alle LEDs langs te lopen.

Dan volgt er een stukje code waarmee alle lampjes om beurten snel achter elkaar worden aangezet. Dan volgt er een for-loop die 4 keer wordt doorlopen. Eerst wordt er een byte gedefinieerd met alleen een 1 op de positie van LED a. In de for-loop die volgt worden patronen op de pins van de Arduino gezet met de functie showPattern(). Het bijzondere is dat er geen vast patroon wordt meegegeven met deze functie, maar een patroon dat wisselt met j. de parameter is namelijk patroon >> j. Dit >> teken staat ervoor dat patroon j plaatsen naar rechts opschuift. Als we beginnen met B10000000 en we schuiven dat 3 plaatsen op (j is dan 3), dan krijgen we patroon B00010000. Dit is dan het patroon dat wordt doorgegeven aan showPattern() functie.

Tenslotte worden alle lichtjes gedurende een seconde aangezet door aanroep van de showPattern() functie met B11111111 als parameter.

De loop() functie is relatief eenvoudig. In een for loop, die van 9 naar 0 aftelt, wordt showPattern() aangeroepen met patronen[i], waarna het programma wachttijd pauzeert. Het resultaat zal dus zijn dat het display steeds opnieuw aftelt van 9 naar 0.

Blijft over om de werking van de functie showPattern() uit te leggen. Gelukkig heeft de functie maar twee statements. Het eerste statement is gemakkelijk: de byte first wordt definieerd met een patroon waarvan alleen het eerste bit aan staat. Daarna volgt een for-loop waarbij i oploopt van 0 tot en met 7 (kleiner dan 8) en waarbinnen een digitalWrite() plaatsvindt op pin LEDs[i]. Dat is dus de pin van de i-de LED van het display. Omdat het een digitalWrite() is, wordt naar die LED natuurlijk een 1 of een 0 gestuurd. Laten we eerst vaststellen dat (first>>i) een patroon is waarvan precies één bit aan staat en wel bit i+1. Als i=0 is het gewoon de byte first. Als i=1 is het de byte B01000000 (tweede bit staat aan). Bij i=2 wordt het byte B00100000 (derde bit staat aan). En zo voort. Net als in de setup() wordt dit gedaan door de >> operator die de byte een aantal posities naar rechts opschuift. Deze byte wordt vervolgens gecombineerd met het patroon dat als parameter wordt meegegeven aan de functie. Die combinatie wordt gemaakt met het '&' teken dat wijst op een bitwise AND. Er ontstaat dan een nieuwe byte die op elke positie alleen een 1 heeft als beide operanden op die positie een 1 hebben. Die operanden zijn dus patroon en (first>>i). Van die laatste weten we inmiddels dat precies een bit 1 is en alle anderen 0 zijn. Het resultaat van patroon & (first>>i) is dan ook een byte die alleen groter zal zijn dan 0 als de i-de bit van patroon ook een 1 is. Als het resultaat ongelijk is aan 0 geldt dat als digitale 1. LEDs[i] zal daardoor aan worden gezet als de overeenkomstige bit in patroon 1 is en anders wordt de LED uit gezet. Het resultaat is dus dat de LEDs worden aan- en uitgezet volgens het opgegeven patroon. En dat heel compact en efficient geprogrammeerd.

Beetje spelen

Als je hier wat wilt spelen kun je de teller omkeren: in plaats van aftellen gaat hij dan van 0 naar 9. Leuker is het wellicht om hem te laten aftellen en bij 0 aangekomen alle lampjes een paar keer snel aan en uit te laten gaan.

Zoals uitgelegd zijn de cijfers als patronen gedefinieerd. Maar je kunt op dezelfde manier ook andere patronen maken, zoals de letters van het alfabet. Onderstaand zie je een voorbeeld van hoe je cijfers en de meeste letters zou kunnen maken met dit display (met soms een kleine in plaats van een hoofdletter). Met al deze patronen kun je het programma ook woorden laten spellen. Eventueel kun je de nog ontbrekende letters ook toevoegen, maar dan wordt de X al snel hetzelfde als de H (tenzij je een kleine letter h gebruikt) en de V hetzelfde als de U. Tja, voor het alfabet blijft het met dit display een beetje behelpen.

Letter display.jpg
Cijfers en letters in het segment display

Navigatie