Display kapotte wekker

[   Dit is het vervolg op deze pagina.   ]
Ik kreeg een oude kapotte wekker van onze oppas.
Het display voorzag ik van een rij pinnetjes die in een breadboard passen
Ik vond de datasheet op internet via het nummer achterop het display.
16 anodes sloot ik aan op een 1 uit 16 lijn decoder. Deze wordt weer aangestuurd door 4 inputlijnen.
2 van de 4 kathodes sloot ik via een NPN transistor aan op de output van een shiftregister.
De vier aanstuurlijnen van de lijndecoder sloot ik ook aan op de output van de shiftregistor.
De shiftregistor sloot ik aan op de arduino met een datalijn, clocklijn en zogenaamde ‘latch’.
De latch en enable-lijn (aan/uit) van de lijndecoder sloot ik ook aan op de arduino. De arduino heeft 5 GPIO’s bezet, maar in de output van de shiftregister zijn nog 2 plaatsen vrij ( 8 minus 4 van de decoder op de anodes minus 2 van de kathodes).
Vervolgens heb ik alle segmentjes in een tabel gezet met de bijbehorende aan/uit combinatie voor de shiftregister. Dat is dus de “BYTE” die de arduino naar de shiftregister stuurt, die het vervolgens in een “aan” vertaalt voor één van de 30 segmentjes van het display.
Daarna heb ik de verschillende segmentjes in een logische volgorde gezet. Deze volgorde heb ik in de Arduino IDE zo toegevoegd:

int volgOrde[] = {
  0x84, 0x48, 0xC8, 0x24, 0x28, 0x00, 0x88,
  0xA8, 0x68, 0xE8, 0xE4, 0xC4, 0xA4, 0x64,
  0x14, 0x94, 0x54, 0x58, 0xD8, 0x18, 0x98,
  0x38, 0xB8, 0x78, 0x74, 0xD4, 0x34, 0xB4,
  0x04, 0xF4 };

Je ziet hierboven 4 x 7 getallen voor elk individueel LEDtje plus twee extra getallen voor de punt en de dubbele punt.
Vervolgens heb ik per cijfer van 0-9 bepaalt welke LEDjes aan moeten en welke uit.
Deze heb ik weer in het programma in een variabele gezet. Alle getallen beginnen met een nul: dit is de ongebruikte bit van de byte (immers 7 segmenten bij een byte van 8). De volgorde van de getallen komt overeen met het plaatje hierboven.

int cijferMasker[]= {
  B00111111, B00000110, B01011011, B01001111,
  B01100110, B01101101, B01111101, B00000111,
  B01111111, B01101111 };

Toen was het zaak de boel aan elkaar te knopen. Hier de hele sketch:

int dataPin  = 3; // HC595 shiftregister
int latchPin = 4; // HC595 shiftregister
int clockPin = 5; // HC595 shiftregister

int Enable = 6; // HEF4514 [1 uit 16]
int Latch = 7;  // HEF4514 [1 uit 16]

int cijfer[4]; // de 4 te tonen cijfers

int volgOrde[] = {
  0x84, 0x48, 0xC8, 0x24, 0x28, 0x00, 0x88,
  0xA8, 0x68, 0xE8, 0xE4, 0xC4, 0xA4, 0x64,
  0x14, 0x94, 0x54, 0x58, 0xD8, 0x18, 0x98,
  0x38, 0xB8, 0x78, 0x74, 0xD4, 0x34, 0xB4,
  0x04, 0xF4 };

int cijferMasker[]= {
  B00111111, B00000110, B01011011, B01001111,
  B01100110, B01101101, B01111101, B00000111,
  B01111111, B01101111 };

void setup()
{
  Serial.begin(9600);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  pinMode(Latch, OUTPUT);
  pinMode(Enable, OUTPUT);
  digitalWrite(Enable, LOW); // zet HEF4514 aan
}

void loop(){
  long tt = millis();
  for (int t = 0; t < 9999; t++){
    schrijfGetal(t);
  }
  Serial.println(millis()-tt);
}

void schrijfGetal(int getal){
  cijfer[0] = getal/1000;
  getal = getal - (cijfer[0] * 1000);
  cijfer[1] = getal/100;
  getal = getal - (cijfer[1] * 100);
  cijfer[2] = getal/10;
  cijfer[3] = getal - (cijfer[2] * 10);
  for (int positie =0; positie < 4; positie++){
  for (int r = 0; r < 7; r++){
  if ((1 << r) & cijferMasker[cijfer[positie]]){
  digitalWrite(Latch, HIGH);
  shiftIt (volgOrde[(positie*7)+r]);
  digitalWrite(Latch, LOW);
  }
  }
}
}

void shiftIt (byte b1){
  digitalWrite(latchPin, LOW);
  for (int k=0; k < 8; k++){
    digitalWrite(clockPin, LOW);
    if ( b1 & (1 << k) ){
      digitalWrite(dataPin, HIGH);
    }
    else{
      digitalWrite(dataPin, LOW);
    }
    digitalWrite(clockPin, HIGH);
  }
  digitalWrite(latchPin, HIGH);
}

Er zijn twee functies: 1) schrijfGetal en 2) shiftIt.
De laatste is een standaard routine om een byte naar een shiftregister te krijgen.
De ‘magie’ gebeurt in de eerste routine. Maar voor ik daar over verder ga, eerst de void loop(){…}:

void loop(){
  long tt = millis();
  for (int t = 0; t < 9999; t++){
  schrijfGetal(t);
  }
  Serial.println(millis()-tt);
}

Ik laat een teller van 0 tot 9999 lopen en schrijf deze naar het display. Met tt wordt de tijd in miliseconden weergegeven die de arduino hiervoor nodig heeft.
Hier is de OUTPUT:



De output via deze opdracht:

  Serial.println(millis()-tt);

Staat in de grafiek hieronder. De klok is 158 x rond gegaan. Het duurt 30.839,5 miliseconde om van 0 tot 9999 te gaan. Dus 324 keer per seconde wordt het hele display vernieuwd. En dat terwijl er NOOIT MEER DAN 1 LEDje TEGELIJKERTIJD aan is.

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>