zaterdag 7 maart 2020

Software - De list (3: TM1637)

Het dashboard van de Burton wordt volledig custom en digitaal. Geen analoge meters dus. Met de precieze lay-out en het design ben ik nog niet klaar, maar er komen in ieder geval grote 7-segmentdisplays in.


https://en.wikipedia.org/wiki/Seven-segment_display


En daar gaan we weer. Een 7-segmentdisplay zou zomaar - de naam verraad het al - zeven uitgangen van de microcontroller kunnen bezetten. Elk segment moet namelijk onafhankelijk aangestuurd kunnen worden. Om de snelheid van de Burton weer te kunnen geven zijn minimaal drie cijfers en dus drie van die 7-segmentdisplays nodig. Da's alleen al 21 uitgangen. Zoveel uitgangen heeft de ESP32 helemaal niet vrij, dus dat moet anders kunnen. En gelukkig kan dat ook anders. Met een I²C-bus I/O-expander bijvoorbeeld. Zou kunnen, maar in de praktijk worden vaak andere IC's gebruikt. Bijvoorbeeld de TM1637 van Titan Micro Electronics. Een speciaal IC waarmee tot zes 7-segmentdisplays aangestuurd kunnen worden.

TM1637, display driver.

Dit IC is nog tot meer in staat, maar daar maak ik geen gebruik van. Net als de I²C-bus wordt dit IC aangestuurd met een klok- en een datasignaal. Ook het communicatieprotocol lijkt erg veel op het I²C-protocol, met het verschil dat de TM1637 niet geadresseerd hoeft te worden. Je kunt maar één zo'n IC aanspreken.

Bij de NeoPixels uit het vorige bericht was de grootste uitdaging de timing van de bits die verstuurd moeten worden. Bij deze TM1637 is de timing veel minder kritisch. Zolang het klok- en datasignaal maar netjes op elkaar afgestemd zijn. In de figuur hieronder wordt dit weergegeven:


Timing van de TM1637

Elke bericht naar de TM1637 begint altijd met een start-conditie en eindigt altijd met een stop-conditie. Bij de start wordt het datalijntje (DIO) laag gemaakt terwijl de kloklijn (CLK) hoog is. Bij de stop wordt de DIO juist hoog gemaakt terwijl de CLK hoog is. Dit zijn de enige twee condities waarbij de DIO van niveau wijzigt terwijl CLK hoog is. De TM1637 kan hierdoor deze twee belangrijke condities herkennen.

Een commando of data (tussen start- en stop-conditie) wordt verstuurd in een groepje van acht bits. Ná elk zo'n byte volgt nog een Acknowledge (ACK) waarbij de TM1637 de kans krijgt om het ontvangen byte te bevestigen. De acht bits worden door de TM1637 één voor één 'ingeklokt' op het moment dat het kloksignaal van laag naar hoog beweegt. Easy peasy.

In de software worden bovenstaande condities op de volgende manier geprogrammeerd (voorbeeld van de start-conditie):

TM1637 Start-conditie

Omdat de absolute timing niet zo kritisch is kan ik gewoon gebruik maken van de eenvoudige pauzefunctie vTaskDelay(1). Hiermee wordt steeds 1 tick, ofwel 10 ms gewacht tussen de bitwisselingen. Een eeuwigheid als je het vergelijkt met de timing van de eerder genoemde NeoPixels. Een prima oplossing voor dit doeleind. Bovendien krijgen andere taken gedurende deze pauzes de tijd om hun ding te doen. Uiteindelijk gebruikt dit protocol bijzonder weinig processortijd.

Voordat de 7-segmentdisplays aangestuurd kunnen worden moet de TM1637 eerst geconfigureerd worden. Hierbij wordt een keuze gemaakt of de TM1637 gebruikt wordt voor het aansturen van een display of het uitlezen van een keyboard (het K-bit) en of de (maximaal) zes 7-segmentdisplays afzonderlijk of automatisch ná elkaar geadresseerd worden (het F-bit).

Bit:  7 6 5 4 3 2 1 0
Data: 0 1 0 0 0 F K 0

In mijn geval wordt zowel het K-bit (bit 1) als het F-bit (bit 2) laag gehouden. Dus:

Bit:  7 6 5 4 3 2 1 0
Data: 0 1 0 0 0 0 0 0

In de software ziet dit er als volgt uit:

TM1637 Configuratiebericht


Daarna wordt het display aangezet met een bepaalde helderheid:

Bit:  7 6 5 4 3 2 1 0
Data: 1 0 0 0 S A B C

Het S-bit zet het display aan. De drie bits A, B en C bepalen de helderheid van het display. De helderheid (brightness) loopt van 000 naar 111 en heeft dus acht verschillende standen. In de software gebruik ik hiervoor een eenvoudige functie:


TM1637 Brightness

Nu de TM1637 geconfigureerd is, kunnen de 7-segmentdisplays aangestuurd worden. De TM1637 wil eerst weten welke van de (maximaal) zes displays gewijzigd moet worden. We starten altijd bij display 0. Het adres wordt na het eerste cijfer automatisch opgehoogd, dat is met het F-bit (zie hierboven) zo geconfigureerd. In geval van zes cijfers worden achtereenvolgend de volgende commando's naar de TM1637 gestuurd:

  1. Start
  2. Adres ( = 0 )
  3. Ackn
  4. Cijfer 1
  5. Ackn
  6. Cijfer 2
  7. Ackn
  8. Cijfer 3
  9. Ackn
  10. Cijfer 4
  11. Ackn
  12. Cijfer 5
  13. Ackn
  14. Cijfer 6
  15. Ackn
  16. Stop

Dat is alles. Hoewel... De cijfers bestaan uit 7 segmenten. Bij elk cijfer moet een andere combinatie van segmenten oplichten. Het cijfer moet hiervoor omgezet worden naar een bitpatroon. Hiervoor is de software voorzien van een constant array met tien posities:


Van decimaal naar 7-segment

De bitpatronen weerspiegelen de op te lichten segmenten. De positie in het array bepaalt het cijfer dat gepresenteerd moet worden. Bij het achtste element (overeenkomstig het cijfer 8) is goed te zien dat alle zeven segmenten op moeten lichten.

Alle puzzelstukje bij elkaar ziet de functie om een getal (number) met al zijn cijfers (digits) te presenteren er als volgt uit:


Getal presenteren op het display


Met deze derde 'list' is het gelukt om maximaal zes cijfers op een display te tonen en hier maar twee digitale uitgangen van de microcontroller voor te gebruiken. Samen met list 1 en list 2 ben ik nu in staat om behoorlijk wat knoppen en lampjes aan te sluiten. Maar ik wil nog meer... Binnenkort list nummer vier!

Geen opmerkingen:

Een reactie posten