Konvertera ett ZX82 spektrum tangentbord till ett utbyggbart USB-tangentbord med Arduino (3 / 3 steg)
Steg 3: Bygga tangentbordet Arduino programvara
Först jag ska köra genom matriser så kan du se teorin och sedan ska jag visa dig hur föraren är skrivet med hjälp av Arduino IDE. Om du är en säker programmerare och vill hoppa över detta, kan du få en kopia av den fullständiga koden på sidan resurser i min hemsida, AltoidsDrone.com.
För att sammanfatta, var nyckelinformation för att skriva det program som vi samlat i det sista steget:
- Filma med 5 kontakter har Data linjer
- Raderna Data använder stiftA0-A4 och har pull-up motstånd till + 5V
- Filmen med 8 kontakter har postadress linjer och använder digital stift 2-9
- Tangentbordet är ordnade i en 5 × 8 matris (Data x adress)
Hur fungerar ett tangentbord matris
Ett tangentbord matris finns ett rutnät av ledningar, till exempel adress och Data linjer rutnätet 5 x 8 i spektrumet. Varje nyckel är en knapp som korsar en rad med en kolumn (korsar på nätet) och alla knappar hålls fysiskt öppna som standard. Detta innebär att raderna och kolumnerna inte är ansluten och ingen ström (eller spänning) överförs från en rad till en kolumn eller vice versa.
Det finns två typer av matrix, pull-up och pull-down. Du kan läsa mer om operativa skillnader här. Ursprungliga spektrum tangentbordet används en pull-up konfiguration. Den sak att komma ihåg är att på är låg i vår matris, inte högt. Så när det trycker på en knapp är en låg spänning som vi måste sätta igång och leta efter. Den första bilden visar hur matrisen fungerar.
I ovanstående fyra rutnäten trycker på knappen ansluta den andra kolumnen till den andra raden. Till att börja med hålls allt hög. Den första kolumnen ändras till låg och styrenheten kontrollerar spänningen på varje rad för att se om det finns en droppe (första rutnät). Inga knappar på kolumnen trycks så alla rader bo på 5V. Returnerar den första kolumnen hög och den andra kolumnen skickas låg (andra bilden). Raderna kontrolleras numreras löpande igen. På pressande knappen på den andra raden är att ansluta den + 5V leverans av den andra raden till 0V i den andra kolumnen via motståndet (tredje bilden). Styrenheten upptäcker 0V på den raden och vet att den andra knappen för den andra kolumnen är bokstaven "j" utgångar så en "j" tangenttryckning. Cykla sedan bär på i raderna och längs kolumnerna, sedan upprepas (fjärde bild).
I ett nötskal, är det så en matris fungerar. Så i praktiken är alla våra tangentbordsdrivrutin har att göra utföra samma cykel att sänka varje kolumn och numreras löpande kontrollera rader i kolumnen för 0V. Sedan kan det look-up som tangenttryckningar till utgång till USB.
Skrift mjukvaran
Jag tillhandahålla komplett programvara föraren här för dig att titta på som vi kör genom att sätta ihop. Om du är ny till kodning för Arduino, har en tom skiss öppna och du kan sätta koden tillsammans när vi går. Denna handledning finns även med full syntaxmarkering via denna länk.
Vad detta program kommer att ge oss är bokstäverna A-Z i övre och gemener, siffrorna 0-9, ett utrymme, Backsteg, CAPS-LOCK och avkastning. Detta täcker grunderna i vad du behöver använda en dator. tro mig, med en liten space knappen i det nedre hörnet, skulle inte du göra ordbehandling på detta tangentbord. Alla våra nycklar kommer att vara fast och svarade för så om du vill göra varje funktion på arbetet som tangentbord, kan du lägga dem i programmet senare.
Fiirst, ändra din styrelse till Leonardo eller LeoStick. Gå till verktyg > styrelse och välj den som du använder.
Vi börjar med grundläggande skiss struktur:
void setup()
{
}
void loop()
{
}
Ovanför setup() måste vi deklarera vår variabler och skriva våra nyckel kartläggning data.
CONST int dataNo = 5;
CONST int addressNo = 8;
int dataPin [dataNo] = {A0, A1, A2, A3, A4};
int adress [addressNo] = {2,3,4,5,6,7,8,9}.
char tangentlayout [dataNo] [addressNo] [2] =
{/ / 2 3 4 5 6 7 8 9 << adress linjer
{{"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
{{är ", är"}, {"k", "K"}, {'x', 'X'}, {"i", "I"}, {'8', '8'}, {hade ", hade '}, {"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
};
Ange antalet rader och kolumner av heltal 'dataNo' och 'addressNo'. Som sådan är "Tangentlayout" karaktär matrisen 8 över av 5 ner (matchning våra tangentbord membran kontakter) och två djupt för övre och lägre fall. "DataPin" och "adress" arrayer matcha våra lödde pin-koder och används till lätt setup och använder tangentbord-anslutningarna (eller enkelt ändra dem utan att ändra funktionella koden). Tomma utrymmen i botten är utrymmet (A4, 2), returnera (A4, 3), Backsteg (A3, 2) och CAPS-LOCK (A4, 4).
Obs: Denna drivrutin fungerar för alla tangentbord matris. Allt du behöver göra för ett annat tangentbord ligger storlek variabler, pins och viktiga karta för tangentbordet i ovanstående kod. Resten kommer att fungera som är. Om du använder en konfiguration för pull-down, helt enkelt byta alla toppar och dalar över, som vi kommer till snart.
Nu behöver vi bara att förklara några fler variabler för våra programmets logik. Boolesk variabel, "wasReleased" kommer att bidra till att tangentbordet utgångar en knapptryckning per press, vilket ger dig "n" i stället för "nnnnnnnnnnnnnn". Pop dem i direkt under ovanstående kod.
booleska wasReleased = sant;
int återutgivningen = 0;
int kapital = 0;
Nu kan vi gå in i den setup() delen av skissen. I detta avsnitt vi behöver att installera stiften och sätta dem i en redo stat om det behövs, sedan inleda vår tangentbord funktion. Stället för att ange varje pin individuellt, kan vi använda för loopar för att spara upprepning, därav dessa matriser, 'dataPin' och 'adress' innehåller vår pin-koder som vi kan hänvisa till här. Den första öglan går igenom våra digitala stift (adress linjer). Dessa är de vi inställd på hög eller låg, så vi förklara vart som en utgång och ställa in den till hög standardtillståndet.
för (int en = 0; en < addressNo; a ++)
{
pinMode (adress [a], OUTPUT);
digitalWrite (adress [a], hög).
}
Likaså andra slingan går genom analog stiften (våra data linjer) och förklarar vart som indata.
för (int d = 0; d < dataNo; d ++)
{
pinMode (dataPin [d], ingång);
}
Slutligen, vi initiera USB-gränssnittet för att användas som en enhet.
Keyboard.BEGIN();
Det är i slutet av vår setup() avsnitt. Vi kan nu gå vidare till loop(), där resten av koden kommer att finnas. Vi gå, jag sätter '...' där nästa bit av koden kommer att gå. Loop() kommer att cykla adressraderna och kontrollera data rader, då utgång lämplig tangenttryckningen. I princip kommer vi åter använda efter loopar med följande struktur:
A för loop att cykla adressraderna, som cyklar adressraden använder låg från början och tillbaka till hög i slutet:
för (int aCyc = 0; aCyc < addressNo; aCyc ++)
{
digitalWrite (adress [aCyc], låg).
...
digitalWrite (adress [aCyc], hög).
}
Adressraden är låga, måste vi köra igenom data linjer att se om någon av dem är låg, som anger en knapptryckning. Så, där den '...' är, vi kommer att använda en annan for-loop.
för (int tData = 0; tData < dataNo; tData ++)
{
...
}
Nu måste vi läsa varje data raden. En pressad knapp kommer att skicka datalinje låg, som i binär är heltal 0 (och således hög skulle vara en 1). Som sådan, tilldelas det heltal "tryckte" det binära värdet av data linjen. Vi kan då testa detta värde med if() uttalande "if(pressed == 0)". "Ny utgåva" heltalet ökas för att hålla en beräkning av hur många datalinje kontroller görs mellan knapptryckningar, gör att vi kan se om alla knapparna kommer innan du tillåter mer tangenttryckningar.
int tryckte = digitalRead(dataPin[tData]);
IF(Pressed == 0)
{
...
}
ny utgåva ++;
På denna punkt vi går in i en knapptryckning upptäcks. En knapptryckning bara får en gång per knapptryckning (om det är först för att tryck på knapp), vilket ger oss 'n' och inte "nnnnnnnnnnnnn". Därför testar vi den booleska "wasReleased" med en annan if() uttryck.
om (wasReleased == true)
{
...
}
Keyboard.releaseAll();
om (kapital > 1) kapital = 0;
wasReleased = false;
Återutgivning = 0;
Om vi skickar ett via USB, behöver vi göra lite städning här. Metoden "Keyboard.releaseAll()" ser till att alla tangenttryckningar skickas till USB är avvecklad. "Kapital" heltalet skiftar platser på matrisen "tangentlayout" innersta ställning. Som sådan, om det är att vara nere för andra gången att växla av, måste det återställas till gemener läge 0. Slutligen, om en knapptryckning har upptäckts, måste låsa ute skicka mer tangenttryckningar tills alla nycklar har släppts. Följaktligen måste "ny utgåva" räkningen återställas till 0 och våra "wasReleased" inställd på false.
Förutsatt att, den nuvarande cykeln är först av denna tryckning (så "wasReleased" är sant), vi kommer att registrera våra tangenttryckning till USB.
om ((aCyc == 2) & & (tData == 4)) kapital ++;
annars om ((aCyc == 0) & & (tData == 3)) Keyboard.write(KEY_BACKSPACE);
annars om ((aCyc == 1) & & (tData == 4)) Keyboard.write(KEY_RETURN);
annat Keyboard.print(keyMap[tData][aCyc][capital]);
Specialtecken, CAPS-LOCK, Backsteg och avkastning passar inte in i en rad tecken och så måste hanteras individuellt. Som sådan har en if() uttalande pekar på den specifika kombinationen av adress och data för nyckeln. Den första linjen steg "huvudstaden" att skifta fallet position när CAPS-LOCK används. "Annan" på nästa rad innebär att CAPS-LOCK är CAPS-LOCK och inte SKIFT. Detta matchar knappetiketten och förenklar vår nyckel pressa logik. Om den trycker på en tangent är en skrivelse, antal eller utrymme, refererar den sista raden aktuella data nummer, adress nummer och kapital staten för att välja det lämpliga brevet från vår viktiga karta.
Slutligen är det sista som vi måste göra aktivera våra tangenttryckningar om alla nycklar har släppts, så denna bit går före finalen "}" i slutet av loop().
om (återutgivning > (dataNo * addressNo))
{
wasReleased = sant;
}
Detta helt enkelt kontrollerar att våra ny utgåva räknas är större än storleken på matrisen "tangentlayout" (och så har fick passerade nyckeln det upptäcktes förra gången). Om så är fallet, ändrar det 'wasReleased' true, re-möjliggöra tangenttryckningar skickas till USB.
Det är komplett tangentbord drivrutinen. Enkelt ansluta Arduino till datorn via USB och överför skissen till din arduino. När startade om, bör du omedelbart kunna skriva med hjälp av det spektrum gamla gummi tangentbord.
För att se hur jag fik den här till min spektrum tillsammans med en Raspberry Pi, inbyggd stöder Wifi och VGA kassan denna länk på AltoidsDrone.com.
Acknowldgements:
- Stort tack till 1000bit.it för deras scheman och heltäckande guide till vintage datorvärlden.