Sarjaporttiohjattu 7-segmenttinäyttö
Tämän rakentelun idea syntyi erään toisen projektin ohella. Kyseisessä projektissa tarvitaan näyttää käyttäjälle useampinumeroinen luku ja sitä lukua pitäisi pystyä ohjaamaan mahdollisimman pienellä vaivalla, sekä IO-määrällä.
En ole vielä koskaan rakentanut sarjaporttiohjattavaa näyttöä, vaikka sellaisia olen kyllä muuten ohjaillut, niin tässä oli sopiva haaste myös toteuttaa kyseinen ajatus ihan käytännössä.
Määrittelin mielessäni suurinpiirteisen kuvan siitä, millainen näytön tulee olla ja millaisilla komennoilla sitä ohjattaisiin. Lopulta ideaksi muodostui käyttää vähävirtaista 16-bittistä mikrokontrolleria (MSP430G2211) sekä muutamaa logiikkapiiriä sekä 7-segmentti dekooderia. 7-segmenttinäytöksi valitsin harmaalla pohjalla olevia punaisia näyttöjä, joita tulee 4 kappaletta rinnakkain (KINGBRIGHT SA56-11SRWA). Ohjaaminen tapahtuisi siis multipleksaamalla. Harmi vain, että omistamani näytöt ovat yhteisanodinäyttöjä, joten näitä ei voi suoraan ohjata dekooderipiirillä vaan tarvitaan ohjauksen invertointi, sekä yhteisanodien syöttöjännitteen ohjaus.
Mikroprosessorissa on vain 2 kilotavua flash-muistia ja 128 bittiä RAM-muistia, sekä vain 12 IO-nastaa. Tämä asetti omat haasteensa näytön ohjaamiseen sekä siihen, millaisia ominaisuuksia laitteella olisi. Vähäisen IO-määrän sekä porttipinnien rajoitetun virrananto-ominaisuuksien vuoksi kytkentään tuli mukaan logiikkapiirejä. Lopuksi lisäsin vielä LT1461 3.0 voltin LDO (Low DropOut) regulaattorin, mikä mahdollistaa näyttöyksikön käyttämisen myös 5 voltin käyttöjännitteellä (Arduino yhteensopiva siis - wink wink).
Mikroprosessorin ohjelmointi tapahtui MSP-EXP430FR5969 Launchpad -ohjelmointialustalla ja IDE:nä toimi Code Composer Studio. Mikäli vähävirtaiset prosessorit kiinnostavat, kannattaa vilkaista kirjoittamaan MSPP430 Launchpad -opasta.
Rakentelin näyttöyksikön palanen kerrallaan, ensin koekytkentäalustalle, sen jälkeen näkkärille ja lopulta piirilevyksi. Aluksi kuitenkin muutama sananen käytetyistä piireistä ja tekniikoista.
7-segmenttinäyttö
7-segmenttinäyttö on helppokäyttöinen ja näyttävä komponentti silloin, kun halutaan esittää numeroita nollasta yhdeksään. Näytön ohjaaminen on myös varsin yksinkertaista, sillä käytännössä ohjataan yksittäisiä segmenttejä eli ledejä. 7-segmenttinäyttöhän on pohjimmiltaan tiettyyn muotoon aseteltujen ledien joukko.
Yksittäisen näytön ohjaaminen on siis helppoa, mutta homma mutkistuu hieman silloin, kun tarvitaan esimerkiksi 4 kappaletta 7-segmenttinäyttöjä (jotta saadaan näytettyä luku 0000 - 9999). Vielä jos tämän lisäksi mikro-ohjaimelta (MCU) jää IO-pinnit vähiin, kuten tässä tapauksessa, niin tarvitsee keksiä jotakin muuta elektroniikkaa näytönohjaukseen. Tässä kohtaa kehiin astuu BCD-dekooderipiiri. Aluksi kuitenkin selvitetään, mikä on BCD-luku.
BCD -luku
Termi BCD tulee sanoista Binary Coded Decimal ja sillä tarkoitetaan binäärimuotoista esitystapaa yksittäiselle desimaalimuotoiselle kymmenjärjestelmän luvulle. Luku on tietotekniikkaan perehtyneelle helppo ymmärtää, koska BCD-luvun muuttamisessa kymmenjärjestelmään lasketaan 2:n potenssit yhteen, joten puhutaan ihan tavallisesti binääriluvuista.
Esimerkiksi BCD-luku 1001 vastaa numeroa 9:n. Tämä saadaan kun lasketaan yhteen 20+ 23 = 1 + 8 = 9.
BCD-luvussa mahdollisia kymmenjärjestelmän lukuja on näin ollen vain 0 - 9, vaikka neljällä bitillä saadaan laskettua binäärisesti aina 15:toista asti. Alle on taulukkoon merkitty, kuinka BCD-luvut, binääriluvut, desimaaliluvut ja 2:n potenssit kytkeytyvät toisiinsa:
Desimaaliluku | BCD-luku
(ABCD) |
Binääriluku | 2:n potenssien summa |
0 | 0000 | 0000 | - |
1 | 0001 | 0001 | 20 |
2 | 0010 | 0010 | 21 |
3 | 0011 | 0011 | 21 + 20 |
4 | 0100 | 0100 | 22 |
5 | 0101 | 0101 | 22 + 20 |
6 | 0110 | 0110 | 22 + 21 |
7 | 0111 | 0111 | 22 + 21 + 20 |
8 | 1000 | 1000 | 23 |
9 | 1001 | 1001 | 23 + 20 |
BCD-luku on siis sama kuin vastaava binääriluku, millä voidaan esittää haluttu desimaaliluku. Siitä syystä sen nimikin on Binary Coded Decimal.
BCD - 7-segmentti dekooderi
Dekooderipiiriä tarvitaan, kun halutaan ohjata 7-segmenttinäyttöä binäärimuotoisesti tai kun halutaan vähentää ohjaukseen tarvittavien signaaleiden määrää. Dekooderipiirejä on saatavilla eri valmistajilta ja kenties yleisimpiä käytetyimpiä piirejä on 74LS47 (5-voltin eli TTL logiikkajännite), CD74HC4511/HCF4511BE (2 - 6 voltin eli CMOS-jännitetaso) tai MC14543 (3-18 V jännitetaso) sekä näiden variaatiot (mm. eri kotelotyypit). Dekooderipiirejä on toki myös muitakin olemassa, mutta tässä vain muutama esimerkki.
Alta nähdään esimerkki dekooderipiirin kytkennästä 7-segmenttinäytön ohjauksessa:
Kytkennässä ohjataan 7:ää eri segmenttiä, eli lediä. Ledeille on oltava etuvastus virranrajoittamiseksi (kuvasta puuttuu). Haluttu virta riippuu hieman ledistä, sekä kytkennän käyttötarkoituksesta. Minulla on kuitenkin nyrkkisääntönä, että rajoitan tavallisten ledien virran maksimissaan 15:toista milliampeeriin (mA), harvoin myös 30 mA. Vähävirtaisissa sovelluksissa puolestaan pidän virtarajana 1-5 mA. Tässä valitsin ledeille 470 ohmisen etuvastuksen, joka antaa 3 voltilla ledeille virraksi n. 2 mA, koska: (I = (U - Uled) / R)
Piiri muuttaa tulonsa A-D vastaaviksi numeroiksi, joita 7-segmenttinäytöllä voidaan näyttää. Esimerkiksi luku 1 (BCD = 0001) näytetään 7-segmenttinäytöllä niin, että sytytetään segmentit B ja C. Vastaavasti numero 8 (BCD = 1000) ohjaa kaikki segmentit A - F päälle. Alla oleva taulukko esittää, mitkä ohjaukset ovat kulloinkin päällä, kun jokin numero näytölle muodostetaan:
Numero | BCD-koodi (ABCD) | Aktiiviset segmentit |
0 | 0000 | a, b, c, d, e, f |
1 | 0001 | b, c |
2 | 0010 | a, b, d, e, g |
3 | 0011 | a, b, c, d, g |
4 | 0100 | b, c, f, g |
5 | 0101 | a, c, d, f, g |
6 | 0110 | a, c, d, e, f, g |
7 | 0111 | a, b, c |
8 | 1000 | a, b, c, d, e, f, g |
9 | 1001 | a, b, c, d, f, g |
7-segment dekooderipiirillä on myös kolme muutakin tuloa, joita voidaan käyttää näytön testaamiseen, kirkkauden säätämiseen (PWM-signaalin avulla) tai lähtöjen aktivoimiseen/deaktivoimiseen. Näiden pinnien toimintaa kannattaa kuitenkin tutkia joko käytännössä, tai sitten dekooderipiirin datalehdestä, joten tästä ei tämän enempää.
Näyttöjen ja dekooderin kytkentä
Alla olevasta kuvasta nähdään dekooderin kytkentä 7-segmenttinäyttöihin (4 kpl). Piirikaaviossa on mukana muutakin komponenttia. ULN2003 piiriä käytetään yhteisanodinäyttöjen ohjaamiseen signaalinkääntöpiirinä. Toisin sanoen, dekooderipiirin "1" ohjaa kyseisen segmentin virran kulkemaan maahan. Tämä kääntäminen johtuu siitä, että näyttöjen ledien plus-napa on kytketty yhteen ja miinusnavan maadoitus ohjaa segmentin päälle. Jos näyttönä olisi yhteiskatodinäyttö, niin ULN2003-piiriä ei tarvittaisi.
Klikkaamalla alla olevaa kuvaa voit nähdä kytkennän PDF-tiedostona.
Tarkkaavainen lukija huomaa myös käytetyt logiikkapiirit 74HC14 (Schmitt-trigger invertteri) ja 74HC08 (AND-piiri). Näitä piirejä käytetään muodostamaan 2:4 dekooderi, jonka avulla näyttöjen anodiin ohjataan positiivinen käyttöjännite. Koska ledien virrat on mitoitettu pieneksi, voidaan AND-logiikkapiirin lähtö kytkeä suoraan ledeille. Näyttöjä ohjataan siis yksi kerrallaan aina vuorotellen. Vuorottelu tapahtuu kuitenkin niin nopeasti, että ihmissilmä ei vuorottelua havaitse.
Näytön ja kytkentöjen rakennus
Aivan aluksi minun tarvitsi tietenkin kytkeä rinnakkain neljä 7-segmenttinäyttöä. Tämä onnistui teippaamalla näytöt samansuuntaisesti vierekkäin ja yhdistämällä näyttöjen katodit toisiinsa. Alla olevassa kuvassa nähdään tekeillä oleva näyttöjen yhdistäminen. Käytin yhdistämiseen emaloitua lankaa (ts. kaiuttimen lakattua käämilankaa) ja pyöritin sitä aina kunkin yhdistettävän katodin kohdalle. Tämän jälkeen kuumensin juottimella lankaa hetken aikaa, että siinä oleva eriste sulaa ja tinasin langan paikoilleen. Tällä tavalla tehtynä ei tarvitse huolehtia eristeistä tai katkoa irtojohtoja, koska emaloitu kaiutinjohto on eristettyä jo valmiiksi ja juottaminen tapahtuu suhteellisen nopeasti lakkapinnankin läpi.
Näytön kokoamisen jälkeen aloin tekemään ohjauskytkentää yksi osa kerrallaan. Ensin BCD-dekooderi ja ULN2003 piiri, sen jälkeen toinen dekooderi ja lopuksi mikro-ohjaimen liittäminen kytkentään sekä LDO-piiri.
Alla olevassa kuvassa nähdään kytkentä kokonaisuudessaan koekytkentäalustalla.
Kun kytkentä oli kasassa, näytön pystyi helposti testaamaan syöttämällä "1"-jännite BCD-piirin ohjaukseen. Alla olevassa kuvassa kaikki HCF4511BE-piirin BCD-tulot on nollassa, joten näytössäkin näkyy nolla. Alla olevassa kuvassa nähdään testivaihe, milloin testasin kunkin 7-segmenttinäytön yksi kerrallaan.
Kytkennän testauksen jälkeen liitin ohjelmointityökalun mikrokontrollerille ja aloitin kirjoittamaan C-kielistä ohjelmaa mikroprosessorille.
Muutaman illan istumisen jälkeen koodi alkoi olla valmista ja näytölle pystyi tulostamaan sarjaportista syötettyjä numeroita. Tästä kuva alla, kun MCU:lle on syötetty sarjaportin kautta "2016".
Kun protokytkentä koekytkentäalustalla alkoi toimimaan halutulla tavalla, oli aika siirtyä kompaktimpaan ja liikuteltavampaan muotoon. Rakensin näytönohjaimen palaset jälleen yksi kerrallaan näkkärille pintaliitoskomponenteista sekä jalallisista komponenteista. Alla olevissa kuvissa nähdään kytkentä näkkäripiirilevyn päältä sekä pohjasta.
AND-piirin 2:4 dekooderia en alkanut enää näkkärille väkertämään, koska ajattelin sen olevan liian virhealtista. Ongelmia oli jo koekytkentäalustallakin saada johtimet oikeisiin paikkoihin, joten ajattelin että tehdään kytkentä suoraan piirilevylle. Näinpä siis, kun näytöt olivat valmiit ja elektroniikka ohjauksen ympärillä toimi, aloitin suunnittelemaan piirilevyä.
Piirilevyn valmistus: valotusmaskin teko
Piirilevyn suunnitteluun meni aikaa noin 2 tuntia ja piirikaaviota olin tietokoneellani jo aiemmin alkanut tekemään, joten kokonaisaikaa on paha mennä sanomaan. Sanotaan kuitenkin, että noin yhdessä työpäivässä tämän sai tehtyä. Piirilevyn suunnittelin PADS-ohjelmistolla, joka on myös työpaikalla käytetty ohjelmisto näihin hommiin.
Suunnitteluvaiheesta en kirjoittele sen enempää, mutta käyn lyhyesti läpi piirilevyn tekoprosessin, kun käytetään valotusmenetelmää sen teossa.
Ensi töiksi täytyy siis valotusmaski saada tulostettua, mielellään läpinäkyvälle pinnalle. Tässä tapauksessa piirtoheitinkalvolle. Siirtokuvan tulisi olla mahdollisimman tummalla musteella tulostettu, eli tulostimesta kannattaa laittaa kaikista eniten mustetta kuluttava asetus päälle. Tulostin kuvan 1200 dpi:n tarkkuudella kahdelle eri kalvolle ja yhdistin kuvat päällekkäin, koska oma tulostimeni ei saanut yhdelle kalvolle tarpeeksi tummaa kuvaa mielestäni.
Kalvosta trimmataan ylimääräiset muovit pois ja jäljelle jäävä siirtokuva asetetaan UV-lakalla päällystetyn piirilevyn päälle.
Sininen suojakalvo poistetaan ja päälle asetetaan vielä lasi pitämään valotusmaski paikoillaan ja kohtisuorassa piirilevyyn nähden. Lasina voi käyttää esimerkiksi valokuvakehyksestä löytyvää lasilevyä.
Piirilevyn valmistus: valotus ja kehitys
Valotuslaitteena käytin nippusiteillä kiinnitettyä LED-työvaloa, teholtaan 10 Wattia. Valotusajaksi tuli noin 12-15 minuuttia (suurinpiirtein katsoin kelloa).
Valotuksen jälkeen piirilevy kehitetään natriumhydroksidiliuoksessa (arkikielessä lipeäliuos), jolloin emäksinen natriumhydroksidi liuottaa UV-valolle altistuneen lakan pois piirilevyn pinnasta. Sekoitusliuos muuttuu myös liuenneen lakan väriseksi.
Kehittyneessä piirilevyssä nähdään haaleasti jäljelle jäävä syövytysmaski. Kehityksen jälkeen levy on huuhdeltava hyvin.
Piirilevy asetetaan syöpymään natriumpersulfaatti- (syövytyssulfaatti) tai ferrikloridiliuokseen, tyyli on vapaa, mutta natriumpersulfaattiliuos on kirkasta eikä sotke paikkoja, joten käytin sitä. Piirilevyn syövytysastiaa kannattaa lämmittää ja hölskytellä, mikä nopeuttaa syöpymistä huomattavasti. Käytin tässä apuna 3D-tulostinta.
Piirilevyn valmistus: Ulkoistetaan syövytys 3D-tulostimelle
Kirjoitin C# -ohjelmointikielellä ja MS:n Visual Studiolla pienen ohjelmanpätkän, joka asettaa tulostusalustan 60 C asteeseen ja käskyttää tulostinta liikuttelemaan alustaa edestakaisin yhteensä 20 mm:n matkan. Alustan päälle asetetaan syövytysallas, joka liikkuu tulostinalustan mukana samalla absorboiden lämpöä alustasta. Alla videopätkä tästä prosessista.
Kun piirilevy on syöpynyt, tarkistetaan ettei johtimia ole mennyt poikki, eikä oikosulkuja ole. Tämä onnistuu yleismittarilla ja johtimien korjaaminen juottimella/hyppylangoilla.
Lopuksi piirilevyyn porataan reiät, mistä komponenttien jalat on tarkoitus pudottaa. IC-piirien jalkoille tuli 0,8mm reiät ja piikkirimaliittimille 1mm. Reikien poraamiseen käytin akkukäyttöistä Dremel 8100 miniporakonetta.
Komponenttien ladonta
Levystä ei saanut täysin hyppylangatonta versiota, mutta koska tämä on kertaluontoinen rakenteluprojekti, niin se ei haittaa. Piirilevyllä on komponentit kuparipuolella tarkoituksellisesti, vaikka se on hieman hankalaa juottamisen kannalta.
Alla kuvia lopputuloksesta.
Piirilevy on kaksipuolinen, koska yksipuoliset olivat päässeet loppumaan. Tämän vuoksi toiselle puolelle levyä täytyi porata avaukset komponenttien jalkojen ympärille (ennen komponenttien asettelua tietenkin), etteivät ne olisi oikosulussa kuparipintaan. Hyödynsin kaksipuoleista kuparointia kuitenkin niin, että käytin toisen puolen kuparia maa-alueena (tämä vähensi hyppylankojen tarvetta entisestään).
Laitteen ohjelmointi ja ohjelman toiminta
Piirilevystä tuli hieman erilainen kuin koekytkentäalustalle tehty, joten tämä täytyi ohjelmoinnissa ottaa huomioon (IO-nastojen uudelleen sijoittelua). Kun muutokset koodiin oli tehty, ohjelma toimi täsmälleen samoin kuin koekytkiksellä.
Lisäsin ohjelmaan ja kytkentään myös desimaalipisteen ohjauksen, koska kooditilaa (Flash-muistia) oli mikroprosessorissa vielä hieman jäljellä.
Ohjelma toimii hyvin yksinkertaisilla komennoilla, kolmessa eri moodissa. Moodia vaihdetaan näytöstä yksinkertaisesti lähettämällä sarjaporttiin kirjaimet "d0", "d1" tai "d2". Alla hieman näiden toimintatilojen tarkoituksesta:
Mode d0 = näytön ja numeron valinta erikseen. Tässä moodissa valitaan ensin segmentti (1-4) ja sen jälkeen syötetään haluttu numero. Tätä voidaan käyttää jos halutaan esimerkiksi animoida jokin numero liikkumaan laidasta laitaan, tai miten vaan.
Mode d1 = näytettävä numero syötetään sarjaportista ja painetaan enter. Tässä moodissa numero syötetään normaalisti, kuten esimerkiksi taskulaskimeen syötetään ja lähetetään enter (ASCII 13). Tässä moodissa luvun edessä olevat nollat (leading zeroes) näkyvät. Jos syötetään viisinumeroinen luku, niin ensimmäisenä syötetty häviää bittiavaruuteen.
Mode d2 = näytettävä numero syötetään sarjaportista ja painetaan enter. Tässä moodissa numero syötetään normaalisti, kuten esimerkiksi taskulaskimeen syötetään ja lähetetään enter (ASCII 13). Tässä moodissa luvun edessä olevat nollat (leading zeroes) eivät näy. Jos syötetään viisinumeroinen luku, niin ensimmäisenä syötetty häviää bittiavaruuteen. Eli toiminta on samanlaista kuin d1-modessa, mutta turhia nollia ei näytetä.
Näytöllä on myös muutama muu komento:
df = näytön sammutus. Tämä komento sammuttaa 7-segmenttinäytöt.
dn = näytön aktivointi. Tämä komento asettaa näytöt takaisin päälle. Numero, joka on aiemmin lähetetty näkyy, eli luku ei häviä muistista.
dp = desimaalipiste päälle tai pois. Tämä komento ohjaa desimaalipisteen päälle tai pois.
Alla olevassa kuvassa nähdään näytölle syötetty luku 2017 tietokoneen USB-sarjaporttimuuntimen kautta.
Loppuyhteenveto
Tämä projekti oli varsin monelle illalle venyvä, sillä aikaa oli käytössä vain muutama tunti kerrallaan ja välillä piti pysähtyä myös tätä juttua kirjoittamaan. Valmista kuitenkin tuli ja voin siirtyä muissa hommissa eteenpäin.
Koekytkennässä käytetyt näytöt eivät päätyneet piirilevylle mukaan, vaan jouduin käyttämään toisenlaisia 7-segmenttinäyttöjä, koska näitä minulla oli riittävästi, enkä halunnut purkaa jo olemassa olevaa viritelmää.
Tämän näytön kohtalona tulee olemaan asennus erääseen toiseen laitteeseen, mutta siitä ehkä sitten joskus toiste lisää.
Linkkejä ja lähteitä:
http://www.electronics-tutorials.ws/combination/comb_6.html
https://create.arduino.cc/projecthub/Arduino_Scuola/how-to-drive-7-segment-display-with-hcf4511-5bfe29
https://fi.wikipedia.org/wiki/BCD-koodi
http://macao.communications.museum/eng/exhibition/secondfloor/MoreInfo/Displays.html