Stap 3: Bouw van het toetsenbord van Arduino software
Eerst ik zal lopen via matrices, zodat u de theorie zien kunt en dan zal ik u tonen hoe het stuurprogramma is geschreven met behulp van de Arduino IDE. Als u een vertrouwen coder en wilt overslaan, kunt u een kopie van de volledige code op de pagina resources van mijn website, AltoidsDrone.com.
Om te recapituleren, was de kerngegevens te bevatten voor het schrijven van het programma dat we verzameld in de laatste stap:
- De film met 5 contacten heeft de Data lijnen
- De Data lijnen gebruik pinnenA0-A4 en pull-up weerstanden aan + 5V
- De film met 8 contacten heeft de adresregels en maakt gebruik van de digitale pennen 2-9
- Het toetsenbord is ingedeeld in een 5 × 8-matrix (gegevens x adres)
Hoe werkt een toetsenbord matrix
Een toetsenbord matrix is een raster van draden, zoals de adres- en datalijnen vorming van het 5 x 8 raster in het Spectrum. Elke sleutel is een knop die één rij met één kolom (de kruisen op de grid) snijdt en alle knoppen zijn fysiek gehouden open standaard. Dit betekent dat de rijen en kolommen niet aangesloten zijn en geen current (of spanning) wordt doorgegeven van een rij naar een kolom of vice versa.
Er zijn twee soorten matrix, pull-up en pull-down. U vindt meer informatie over de operationele verschillen hier. Het oorspronkelijke Spectrum toetsenbord gebruikt een pull-up-configuratie. Het ding om te onthouden is dat op slinkt in onze matrix, niet hoog. Wanneer een toets wordt ingedrukt, het is dus een lage spanning moeten we trigger en zoekt. De eerste afbeelding toont hoe de matrix eigenlijk werkt.
In de bovenstaande vier rasters, is het aansluiten van de tweede kolom op de tweede rij ingedrukt. Om te beginnen met, is alles opgeheven. De eerste kolom wordt gewijzigd in laag, en de controller controleert de spanning op elke rij om te zien of er een daling (eerste raster). Geen knoppen op die kolom worden ingedrukt zodat alle rijen 5V verblijven. De eerste kolom wordt hoog, en de tweede kolom laag wordt verzonden (tweede afbeelding). De rijen worden opeenvolgend opnieuw gecontroleerd. De ingedrukte drukknop op de tweede rij is het aansluiten van de + 5V levering van de tweede rij naar de 0V van de tweede kolom via de weerstand (derde afbeelding). De controller detecteert de 0V voor die rij en weet dat de tweede knop van de tweede kolom wordt dat de letter 'j' zo een 'j' toetsaanslag uitgangen. De cyclus draagt op de rijen naar beneden en langs de kolommen, vervolgens herhaalt (vierde afbeelding).
Dat is in een notendop, de werking van een matrix. Dus, in de praktijk is alles onze toetsenbordstuurprogramma te doen uitvoeren van de dezelfde cyclus van verlagen van elke kolom en de rijen op die kolom voor 0V opeenvolgend te controleren. Dan kan het look-up die toetsaanslagen naar uitvoer naar de USB.
Schrijven van de software
Ik ben het verstrekken van de volledige software driver voor hier voor u om te kijken als we lopen door het samen brengen. Als je nieuw bent bij codering voor Arduino, een lege schets openen en kun je de code samen als we gaan. Deze tutorial is ook beschikbaar met volledige syntax-highlighting via deze link.
Wat dit programma ons zal geven is de letters A-Z in hoofdletters en kleine letters, de cijfers 0-9, een spatie, BACKSPACE, CAPS-LOCK en terugkeer. Dit bestrijkt de grondbeginselen van wat u nodig hebt om het gebruik van een computer; geloof me, met een kleine ruimte- knop in de benedenhoek, dat je zou niet willen doen tekstverwerking op dit toetsenbord. Alle onze sleutels zal worden in geschakeld en verantwoord dus als u ervoor zorgen dat elke werkt op het toetsenbord werk wilt, kunt u hen in het programma later.
Fiirst, je Board aan de Leonardo, of de LeoStick wijzigen. Ga naar extra > bestuur en kies degene die u gebruikt.
We beginnen met de fundamentele sketch structuur:
void setup() { } void loop() { }
Boven de Setup moeten we onze variabelen declareren en onze belangrijkste toewijzinggegevens schrijven.
const int dataNo = 5; const int addressNo = 8; int dataPin[dataNo] = {A0,A1,A2,A3,A4}; int address[addressNo] = {2,3,4,5,6,7,8,9}; char keyMap[dataNo][addressNo][2] = {// 2 3 4 5 6 7 8 9 << address lines {{'b','B'},{'h','H'},{'v','V'},{'y','Y'},{'6','6'},{'g','G'},{'t','T'},{'5','5'}}, // A0 {{'n','N'},{'j','J'},{'c','C'},{'u','U'},{'7','7'},{'f','F'},{'r','R'},{'4','4'}}, // A1 {{'m','M'},{'k','K'},{'x','X'},{'i','I'},{'8','8'},{'d','D'},{'e','E'},{'3','3'}}, // A2 {{' ',' '},{'l','L'},{'z','Z'},{'o','O'},{'9','9'},{'s','S'},{'w','W'},{'2','2'}}, // A3 {{' ',' '},{' ',' '},{' ',' '},{'p','P'},{'0','0'},{'a','A'},{'q','Q'},{'1','1'}} // A4 };
De gehele getallen 'dataNo' en 'addressNo' geven respectievelijk het aantal rijen en kolommen. Als zodanig, is de 'KeyMap' karakter array 8 over van 5 naar beneden (matching onze toetsenbord membraan connectors) en twee diep voor hoofdletters en kleine letters. De 'dataPin' en 'adres' arrays overeenkomen met onze gesoldeerd pin-nummers en worden gebruikt om gemakkelijk opstelling en het toetsenbord-verbindingen gebruiken (of eenvoudig wijzigen hen zonder het veranderen van de functionele code). De lege ruimten aan de onderkant zijn de ruimte (A4, 2), de terugkeer van (A4, 3), BACKSPACE (A3, 2) en CAPS-LOCK (A4, 4).
Opmerking: Dit stuurprogramma werkt voor elk toetsenbord matrix. Allen u moet doen voor een ander toetsenbord ligt de grootte variabelen, de pinnen en de belangrijkste kaart voor uw toetsenbord in de bovenstaande code. De rest zal werken zoals het is. Als u een pull-down-configuratie gebruikt, gewoon ruilen alle de hoogte- en dieptepunten, waarop wij spoedig zullen terugkomen.
Nu moeten we enkel een paar meer variabelen voor onze programmalogica declareren. De Booleaanse variabele, 'wasReleased' zal ertoe bijdragen dat het toetsenbord uitgangen één toetsaanslag per pers, waardoor u "n" in plaats van 'nnnnnnnnnnnnnn'. Pop deze direct onder de bovenstaande code.
boolean wasReleased = true; int reRelease = 0; int capital = 0;
Nu kunnen we overgaan in het Setup-gedeelte van de schets. In deze sectie we nodig te installeren van de pinnen en zet ze in een klaar staat als nodig, dan starten onze toetsenbord-functie. In plaats van elke pin individueel opgeven, we for-lussen te slaan herhaling kunt gebruiken, vandaar de bovenstaande matrices, 'dataPin' en 'pakken' bevatten onze pin-nummers die we hier kunnen noemen. De eerste lus doorloopt onze digitale pinnen (de adresregels). Dit zijn degenen die we ingesteld op hoog of laag, zodat we elk als uitgang verklaren en stel deze in op de hoge standaardstatus.
for (int a=0; a<addressNo; a++) { pinMode(address[a], OUTPUT); digitalWrite(address[a], HIGH); }
Ook de tweede lus loopt door de analoge pinnen (onze data lijnen) en verklaart elk als input.
for(int d=0; d<dataNo; d++) { pinMode(dataPin[d], INPUT); }
Ten slotte, starten we de USB-interface voor gebruik als een interfaceapparaat.
Keyboard.begin();
Dat is het einde van onze gedeelte van Setup. We kunnen nu op de loop, waarin de rest van de code wordt opgeslagen. Als we gaan, zal ik '...' waar het volgende blok van code zal gaan. De loop zal cyclus de adresregels en controleren van de data lijnen, dan uitgang van de juiste toetsaanslag. In feite, gebruiken we weer for-lussen met de volgende structuur:
A for-lus om te bladeren de adresregels, die cycli de adresregel het is met behulp van lage aan het begin en terug naar hoge eind:
for (int aCyc=0; aCyc<addressNo; aCyc++) { digitalWrite(address[aCyc], LOW); ... digitalWrite(address[aCyc], HIGH); }
Terwijl de adresregel slinkt, moeten we te lopen via de data lijnen om te zien of om het even welk van hen laag, met vermelding van een druk op de knop. Zo, waar de '...' is, zullen we een ander for-lus gebruiken.
for(int tData=0; tData<dataNo; tData++) { ... }
We moeten nu lezen van elke regel gegevens. Een ingedrukte drukknop stuurt de data lijn laag, die in binaire het gehele getal 0 is (en dus hoge zou een 1). Als zodanig is het gehele getal 'ingedrukt' de binaire waarde van de data lijn toegewezen. We kunnen vervolgens testen die waarde met de verklaring van de if() van ' if(pressed == 0)'. De 'heruitgave' integer wordt verhoogd om te houden van een telling van hoeveel data lijn controles worden uitgevoerd tussen knooppersen, zodat we kunnen zien als alle toetsen alvorens meer toetsaanslagen zijn vrijgegeven.
int pressed = digitalRead(dataPin[tData]); if(pressed == 0) { ... } reRelease++;
Op dit punt sluiten wij een zeer belangrijke pers wordt gedetecteerd. Een toetsaanslag slechts mag worden eenmaal per druk op de knop (als het is de eerste voor dat knooppers), geven ons 'n' en niet 'nnnnnnnnnnnnn'. Daarom testen we de Boole-waarde 'wasReleased' met een ander if() instructie.
if (wasReleased == true) { ... } Keyboard.releaseAll(); if(capital > 1) capital = 0; wasReleased = false; reRelease = 0;
Al of niet we een toetsaanslag via de USB sturen, moeten we doen sommige huishouden hier. De 'Keyboard.releaseAll()' methode zorgt ervoor dat alle toetsaanslagen worden verzonden naar USB zijn stopgezet. De 'hoofdstad' integer verschuift plaatsen op de binnenste positie van de matrix 'keyMap'. Als zodanig, als het wordt ingedrukt voor een tweede keer aan de weg van een knevel, het moet opnieuw worden ingesteld naar de kleine letters positie van 0. Tot slot, als een zeer belangrijke pers is geconstateerd, moet het programma te lock-out meer toetsaanslagen versturen totdat alle toetsen zijn vrijgelaten. De 'heruitgave' telling moet daarom opnieuw worden ingesteld op 0 en onze 'wasReleased' ingesteld op false.
Ervan uitgaande dat, de huidige cyclus is de eerste van deze zeer belangrijke pers (dus 'wasReleased' is waar), komen we bij het registreren van onze toetsaanslag naar de USB.
if((aCyc == 2) && (tData == 4)) capital++; else if((aCyc == 0) && (tData == 3)) Keyboard.write(KEY_BACKSPACE); else if((aCyc == 1) && (tData == 4)) Keyboard.write(KEY_RETURN); else Keyboard.print(keyMap[tData][aCyc][capital]);
Speciale tekens, CAPS-LOCK, BACKSPACE en terugkeer niet passen in een array van karakters en dus moeten individueel worden behandeld. Zo heeft elk een if() instructie verwijst naar de specifieke combinatie van adres en gegevens voor die sleutel. De eerste lijn stappen 'hoofdstad' te verschuiven van het geval plaats als de toets CAPS-LOCK wordt gebruikt. De 'anders' op de volgende regel betekent dat de CAPS-LOCK is CAPS-LOCK en niet werkperiode wordt GEFABRICEERD; Dit komt overeen met het label van de button en vereenvoudigt de logica van onze indrukken van een toets. Als het indrukken van een toets een letter, getal of de spatie is, de laatste regel verwijst naar het nummer van de huidige gegevens, adres en kapitaal staat om te selecteren van de juiste letter van onze belangrijkste kaart.
Ten slotte, het laatste ding dat we moeten doen is opnieuw in staat stellen onze toetsaanslagen als alle toetsen zijn vrijgelaten, zodat deze chunk voordat de finale gaat '}' aan het einde van de loop.
if (reRelease > (dataNo*addressNo)) { wasReleased = true; }
Dit gewoon controles die onze 'heruitgave' tellen is groter dan de grootte van de matrix 'keyMap' (en dus kreeg verstreken is de sleutel het laatst ontdekt). Als dat zo is, verandert het 'wasReleased' op true, re-machtigingswet toetsaanslagen worden verzonden naar USB.
Dat is het volledige toetsenbordstuurprogramma. Gewoon de Arduino verbinden met de computer via USB en uploaden van de schets aan de arduino. Eenmaal opnieuw is opgestart, moet u onmiddellijk kunnen via de spectrums oude rubberen toetsenbord invoeren.
Om te zien hoe ik heb dit in mijn Spectrum samen met een Raspberry Pi, ingebouwde ondersteuning Wifi en VGA-voor kassa deze link op AltoidsDrone.com.
Acknowldgements:
- Veel dank aan 1000bit.it voor hun schema's en uitgebreide gids voor de vintage computerwereld.