Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

64-Key Prototyping Keyboard Matrix voor Arduino

Componenten en benodigdheden

Arduino UNO
× 1
1N4148 – Snel schakelen voor algemeen gebruik
× 64
Tactiele schakelaar, bovenkant bediend
× 64
Pin-headers
× 1
74HC595 Shift Register
× 1

Benodigde gereedschappen en machines

Soldeerbout (algemeen)

Apps en online services

Arduino IDE

Over dit project


Update:ik heb de code verbeterd, zie "Update" aan het einde.

Ik werk momenteel aan een project dat een geïntegreerd toetsenbord zal hebben, wat een probleem opleverde:hoe kan ik een toetsenbord opnemen in het prototype van het ontwikkelbord? Ik kan geen USB-toetsenbord of een bestaand op Arduino gebaseerd toetsenbord gebruiken, omdat het toetsenbord in het eigenlijke project rechtstreeks is aangesloten op de microcontroller die alle andere functies afhandelt. Dus ontwierp ik deze op PCB gebaseerde toetsenbordmatrix met 64 toetsen voor prototypen.

Deze print bevat geen IC's (integrated circuits). De rijen en kolommen van de toetsenbordmatrix zijn rechtstreeks verbonden met de pin-headers, zodat het toetsenbord kan worden aangesloten op een Arduino of een andere microcontroller. Het is perfect voor het maken van prototypes van uw projecten met een geïntegreerd toetsenbord.

Ik heb gedetailleerde code met veel commentaar toegevoegd om dit te laten werken met elk Arduino-compatibel ontwikkelbord dat voldoende I/O-pinnen beschikbaar heeft - 11 pinnen zijn vereist. Het toetsenbord heeft 64 toetsen, inclusief modifiers voor shift, caps, ctrl, alt, fn en "special". Er zijn ook zes extra toetsen die u kunt gebruiken voor wat u maar wilt. De functies van elke afzonderlijke toets kunnen afzonderlijk worden gedefinieerd, inclusief de functie van elke toets wanneer een modifier actief is. Naar mijn mening is dit aanzienlijk nuttiger dan bestaande toetsenbordcode die uw vermogen om toetsgedrag aan te passen ernstig beperkt.

De verstrekte code drukt tekst af naar Serial. Dit kan eenvoudig worden gewijzigd als u wilt dat de tekst ergens anders naartoe gaat.

Een opmerking over de programmagrootte:

De code die ik aanlever is behoorlijk groot, omdat het geen enkele bestaande bibliotheken gebruikt. Ik heb deze code helemaal opnieuw geschreven om de aanpasbaarheid die ik nodig had mogelijk te maken. Op een Arduino UNO zal dit 9100 bytes (28%) aan programmaopslagruimte gebruiken en globale variabelen gebruiken 394 bytes (19%) dynamisch geheugen.

Mijn code zou waarschijnlijk efficiënter kunnen zijn en hun bibliotheken en schetsen voor toetsenborden zijn zeker kleiner, maar dit is de enige manier die ik zou kunnen bedenken om volledige flexibiliteit te bieden over elke toets met elke modifier. Het houdt ook rekening met het echte toetsenbordgebruik. Als mijn code bijvoorbeeld op de Shift-toets drukt terwijl Caps Lock is ingeschakeld, resulteert dit in een kleine letter zoals het hoort. Standaard zal het niets doen als u de FN-toets ingedrukt houdt terwijl u op ESC drukt. Maar dat gedrag is volledig aanpasbaar, dus je kunt het veranderen zoals je wilt.

Benodigdheden:

  • De aangepaste printplaat
  • 6x6x5mm tactiele drukknoppen (x64)
  • 1N4148 schakeldiodes (x64)
  • 1x8 pin headers, vrouwelijk of mannelijk (x2)
  • 74HC595 schuifregister
  • Jumperdraden
  • Broodplank
  • Arduino Uno of een Arduino-compatibel microcontroller-ontwikkelbord

Stap 1:Hoe een toetsenbordmatrix werkt

Waarom is een toetsenbordmatrix nodig?

Dit toetsenbord heeft 64 toetsen. Als je al die knoppen rechtstreeks op je ontwikkelbord zou aansluiten, zou je 64 I/O-pinnen nodig hebben. Dat is veel van pinnen en meer dan de meeste ontwikkelborden beschikbaar hebben. Om dat tot een veel redelijker aantal terug te brengen, kunnen we een toetsenbordmatrix gebruiken, waarvoor slechts een aantal pinnen nodig is dat gelijk is aan de vierkantswortel (naar boven afgerond) van het aantal toetsen.

Er is een toetsenbordmatrix ingesteld, zodat elke toetsschakelaar in een rij is aangesloten en elke toetsschakelaar in een kolom is aangesloten. Als we willen zien welke toetsen er worden ingedrukt, "activeren" we de eerste rij en controleren vervolgens elke kolom. Als een bepaalde kolom actief is, weten we dat de toets in die kolom en rij 1 is ingedrukt. Vervolgens deactiveren we rij 1 en activeren we rij 2, waarna we alle kolommen opnieuw controleren. Nadat alle rijen zijn geactiveerd, beginnen we gewoon weer bij de eerste rij.

Hoe we de toetsenbordmatrix scannen:

Omdat we met een microcontroller werken, betekent 'activeren' dat je die rij op LAAG of HOOG moet zetten. In dit geval stellen we de rij in op LAAG omdat we de ingebouwde pullup-weerstanden van de microcontroller gebruiken op onze kolominvoerpinnen. Zonder een pullup- of pulldown-weerstand zal een ingangspin onvoorspelbaar reageren als gevolg van de interface, die valse toetsaanslagen registreert.

De ATmega328P-microcontroller die in de Arduino UNO wordt gebruikt, heeft geen ingebouwde pulldown-weerstanden, alleen pullup-weerstanden. Die gebruiken we dus. De pullup-weerstanden verbinden elke ingangspen met 5V, zodat ze altijd HOOG aangeven totdat er op een knop wordt gedrukt.

Alle rijen zijn normaal gesproken ook ingesteld op HOOG, wat voorkomt dat de kolompinnen verbinding maken met de rijpinnen, of er nu een knop is ingedrukt of niet. Maar als we klaar zijn om een ​​rij te controleren, kunnen we die rij instellen op LAAG . Als er op een knop in die rij wordt gedrukt, biedt dit een pad voor de invoerpin om naar de grond te worden getrokken, wat ertoe leidt dat die kolom nu leest als LAAG .

Dus, om samen te vatten:we zetten een rij op LAAG en dan kijken we welke kolompinnen nu LAAG aangeven. Die komen overeen met ingedrukte knoppen. Dit proces gebeurt zeer snel, zodat we het hele toetsenbord vele malen per seconde kunnen scannen. Mijn code beperkt dit tot 200 keer per seconde, wat de prestaties en het stuiteren in evenwicht houdt en ervoor zorgt dat elke toetsaanslag wordt opgevangen.

Diodes, ghosting en n-key rollover:

De diodes in de schakeling zijn er om onbedoeld indrukken van toetsen te voorkomen wanneer bepaalde toetscombinaties worden ingedrukt. Diodes laten de stroom maar in één richting stromen, waardoor ghosting wordt voorkomen. Als we geen diodes gebruikten, zou het indrukken van bepaalde toetsen ertoe kunnen leiden dat een andere niet-ingedrukte toets wordt geregistreerd, omdat er stroom door de aangrenzende schakelaars vloeit. Dit wordt weergegeven in de vereenvoudigde afbeelding, waarbij op drie aangrenzende toetsen wordt gedrukt, waardoor de toets in de vierde hoek wordt geregistreerd, zelfs als deze niet wordt ingedrukt. De diodes voorkomen dat en maken 'n-key rollover' mogelijk, wat betekent dat we zonder problemen zoveel toetsen kunnen indrukken als we willen in elke gewenste combinatie.

Pinnen opslaan met een schuifregister:

De scherpzinnigen onder jullie hebben waarschijnlijk gemerkt dat ik zei dat een toetsenbordmatrix een aantal pinnen nodig heeft dat gelijk is aan de vierkantswortel van het aantal toetsen, maar dat ik ook zei dat mijn toetsenbordontwerp slechts 11 pinnen vereist. Het moet 16 zijn, toch? Nee, want we gebruiken een 74HC595 schuifregister. Met dit schuifregister kunnen we slechts drie van de I/O-pinnen van de Arduino gebruiken om maximaal acht uitgangspinnen te besturen. Met die drie pinnen kunnen we een byte (acht bits) naar het schuifregister sturen, dat de acht uitgangspinnen op HOOG of LAAG zet. Door het schuifregister te gebruiken voor de outputrij-pinnen, besparen we 5 hele I/O-pinnen!

"Dus waarom niet ook een schuifregister gebruiken voor de invoerpinnen?" je vraagt. Het eenvoudigste antwoord is dat invoer een ander soort schuifregister vereist en dat type had ik niet bij de hand. Maar het gebruik van een schuifregister voor invoer bemoeilijkt ook de manier waarop we de kolommen lezen en kan problemen veroorzaken met ruis en "stuiteren". Het volstaat te zeggen dat het hoofdpijn is die ik in dit geval niet hoefde op te lossen.

schema.pdf

Stap 2:PCB-ontwerp

Schematisch ontwerp

Nu je begrijpt hoe een toetsenbordmatrix werkt, zou mijn PCB-ontwerp eenvoudig moeten zijn. Ik ontwierp de PCB in KiCAD (sorry Eagle-rechters) en begon met het schema. Ik plaatste eenvoudig een knopsymbool en een diodesymbool, kopieerde en plakte die totdat ik mijn raster van 64 toetsen had. Vervolgens heb ik twee 1x8 pin-headersymbolen toegevoegd, één voor de rijen en één voor de kolommen. De ene kant van de knoppen was in kolommen verbonden en de andere kant van de knoppen was in rijen verbonden.

De volgende stap was om PCB-voetafdrukken toe te wijzen aan elk van die schematische symbolen. De meegeleverde footprint-bibliotheek van KiCAD had de benodigde footprints ingebouwd. Wanneer je je eigen PCB's ontwerpt, moet je heel voorzichtig zijn met het kiezen van de juiste footprints, want die komen uiteindelijk op je PCB terecht. Er zijn veel componenten met zeer vergelijkbare voetafdrukken, maar met een iets andere toonhoogte of wat dan ook. Zorg ervoor dat u degene kiest die overeenkomen met uw echte componenten.

Voetafdrukken en pinnummers

Let vooral op de pinnummers. KiCAD heeft een raar probleem waarbij de pinnummers van het schematische diodesymbool niet overeenkomen met de pincodes van de footprint. Dit heeft tot gevolg dat diodes achterwaarts zijn, wat een serieus probleem is gezien hun polariteit. Ik begreep die fout niet en moest de eerste batch PCB's die ik bestelde weggooien. Om dit probleem bij de tweede revisie op te lossen, moest ik een aangepaste diode-voetafdruk maken met de pinnummers verwisseld.

PCB-indeling

Met het schema klaar en de toegewezen footprints, ging ik naar de eigenlijke PCB-lay-out. Het bordoverzicht is gemaakt in Autodesk Fusion 360, geëxporteerd als een DXF en vervolgens geïmporteerd in KiCAD op de Edge Cuts-laag. Het overgrote deel van het werk daarna was eenvoudigweg de knoppen zo rangschikken dat ze een lay-out hadden die vergelijkbaar was met een normaal toetsenbord.

Toen werden alle sporen gerouteerd. Omdat de werkelijke knoplay-out niet overeenkomt met de nette en opgeruimde matrix in het schema, werd dit deel een beetje rommelig en moest ik op sommige plaatsen via's gebruiken. Vias kun je een spoor van de ene laag naar de andere leiden, wat erg handig is als je een 2-laags bord gebruikt met veel overlappende sporen. Ten slotte heb ik gevulde regio's toegevoegd, omdat het een goede gewoonte is.

PCB-fabricage

Met het bord ontworpen, heb ik eenvoudig alle lagen geplot en toegevoegd aan een zip-map. Die map wordt hier verstrekt en kan rechtstreeks worden geüpload naar een PCB-fabricageservice zoals JLCPCB.

Hier is de link naar de PCB Gerber-bestanden:https://drive.google.com/file/d/10YriLLtghV0Sb84Wm...

Stap 3:PCB-assemblage

Dit is de gemakkelijkste, maar meest vervelende stap in het hele project. Soldeer gewoon alle componenten op hun plaats. Het zijn allemaal doorlopende componenten en zijn gemakkelijk te solderen. Let vooral op de richting van de diodes. De markering op de diodes moet overeenkomen met de markeringen op de printplaat.

In mijn ervaring was het het gemakkelijkst om de printplaat met een derde hand op zijn plaats te houden en eerst alle diodes te plaatsen. Draai vervolgens het bord om en soldeer ze allemaal, en klem vervolgens de draden vast. Plaats vervolgens alle knoppen en soldeer die. Soldeer vervolgens de pin-headers op hun plaats. U kunt vrouwelijke of mannelijke pin-headers gebruiken, het is helemaal aan u. Als je mannelijk hoofd gebruikt en dan onder . plaatst het bord, de afstand is correct om ze rechtstreeks in een breadboard te plakken.

Stap 4:sluit het toetsenbord aan op uw Arduino

De bedrading ziet er ingewikkeld uit, maar valt echt mee als je goed oplet waar alles heen gaat.

Acht jumperdraden gaan van de kolomkop rechtstreeks naar de volgende Arduino-pinnen:

  • Kolom 1> A0
  • Kolom 2> A1
  • Kolom 3> A2
  • Kolom 4> A3
  • Kolom 5> A4
  • Kolom 6> A5
  • Kolom 7> 5
  • Kolom 8> 6

Plaats vervolgens het 74HC595-ploegregister op uw breadboard, spreid over de middenpauze. Let op de oriëntatie van de chip! De stip geeft Pin 1 aan

Bekijk het bedradingsschema om te zien waar de 5V- en massa-aansluitingen naartoe gaan. Het schuifregister heeft twee pinnen die zijn aangesloten op 5V en twee pinnen die zijn aangesloten op aarde.

Er zijn slechts drie draden nodig om het schuifregister op de Arduino aan te sluiten. Dit zijn:

  • Shift (Klok) 11> 4
  • Shift (Vasthoudend) 12> 3
  • Shift (gegevens) 14> 2

Om de een of andere domme reden zijn de uitgangspinnen van het schuifregister op een contra-intuïtieve manier gerangschikt. Besteed speciale aandacht aan het schuifregister-pinout-diagram wanneer u deze aansluit op uw rij-pinnen. Dit zijn:

  • Rij 1> Shift (Q0) 15
  • Rij 2> Shift (Q1) 1
  • Rij 3> Shift (Q2) 2
  • Rij 4> Shift (Q3) 3
  • Rij 5> Shift (Q4) 4
  • Rij 6> Shift (Q5) 5
  • Shift 7> Shift (Q6) 6
  • Shift 8> Shift (Q7) 7

Er is niets aangesloten op de Arduino 0 of 1 pinnen, omdat die ook voor de seriële poort worden gebruikt en conflicten veroorzaken.

Stap 5:Flash de Arduino-code

Flash uw Arduino met de hier verstrekte code. Hier is niets bijzonders aan, upload de code gewoon zoals je zou doen met elk ander Arduino-project.

Alles in de code heeft gedetailleerde opmerkingen die je kunt lezen, dus ik zal hier niet in detail treden. Kortom, de pinnen zijn ingesteld als in- en uitgangen. De hoofdlus bevat alleen een timerfunctie. Elke 5 ms roept het de functie op om het toetsenbord te scannen. Die functie roept een aparte functie aan om het schuifregister in te stellen voordat de kolommen worden gecontroleerd. Ingedrukte toetsen printen hun waarde naar Serieel.

Als u wilt wijzigen wat er wordt afgedrukt wanneer u op een toets drukt, wijzigt u gewoon de Serial.print("_"); in het if-statement dat overeenkomt met de voorwaarde. U kunt bijvoorbeeld instellen wat er wordt afgedrukt wanneer u FN ingedrukt houdt en op N drukt. Hetzelfde geldt voor elke andere toets met elke wijziging.

Veel sleutels doen helemaal niets in deze code, omdat het gewoon naar serieel afdrukt. Dat betekent dat de backspace-toets geen effect heeft, omdat u niet kunt verwijderen van de seriële monitor - die gegevens zijn al ontvangen. U bent echter vrij om dat te wijzigen als u dat wilt.

Het toetsenbord gebruiken met uw eigen projecten

Het is leuk om naar serieel te printen, maar dat is niet echt de bedoeling van dit toetsenbord. Het doel van dit toetsenbord is het maken van prototypes van complexere projecten. Daarom is het eenvoudig om de functionaliteit te wijzigen. Als u bijvoorbeeld de getypte tekst op een OLED-scherm wilt afdrukken, kunt u eenvoudig elke Serial.print( vervangen) met display.print( of wat uw specifieke display ook nodig heeft. Alles vervangen . van de Arduino IDE tool is geweldig om die allemaal in één snelle stap te vervangen.

Bedankt voor het lezen en ik hoop dat dit toetsenbord je helpt bij je projecten!

ProtoKeyboardV1.1-Shifted.ino



30/01/21 Update:

​Deze nieuwe code is volledig herschreven en presteert beter dan de originele code. Dit werd meestal gedaan om een ​​probleem met mijn algoritme aan te pakken dat ervoor zorgde dat er geen tekens werden ingevoerd telkens wanneer er op een toets werd gedrukt. De originele code gecontroleerd om er zeker van te zijn dat een bepaalde sleutel niet de laatste . was toets in te drukken. Dit veroorzaakte een probleem als 2 of meer toetsen werden ingedrukt, waardoor iets als "fgfgfgfgfgfgfgfgfgfg" zou worden ingevoerd. Dit weerhield je er ook van om steeds weer snel dezelfde sleutel in te voeren, zoals wanneer je de twee m's typt in het woord 'bummer'.

De nieuwe code lost beide problemen op en is ook eleganter. In plaats van de laatst ingedrukte toets bij te houden, controleren we de status van het hele toetsenbord en vergelijken deze met de hele toetsenbordstatus in de laatste lus. Dit betekent dat de lus veel sneller kan lopen, en je kunt dezelfde sleutel ook heel snel steeds opnieuw invoeren. De prestaties zijn drastisch verbeterd. Alle tekens staan ​​ook bovenaan in arrays, zodat u ze gemakkelijk kunt vinden en wijzigen. Er zijn onafhankelijke arrays voor elke modifier. De code is ook veel korter.

Het enige nadeel van deze nieuwe aanpak is dat het meer dynamisch geheugen gebruikt, hoewel het aanzienlijk minder programmaruimte gebruikt. Op een Arduino Uno gebruikt het nu:3532 bytes (10%) aan programma-opslagruimte en 605 bytes (29%) dynamisch geheugen.

Als een toegevoegde bonus werkt deze code net zo goed op snelle microcontrollers zoals de ARM Cortex-M4. De intervaltimer om het toetsenbord te controleren is in microseconden, dus het zal hetzelfde doen op elk bord. Je kunt ook eenvoudig aanpassen hoe vaak het toetsenbord wordt gecontroleerd. Standaard wordt er elke 500 microseconden één lus uitgevoerd. Het duurt 8 lussen om het toetsenbord te controleren, in totaal 4000 microseconden (4 milliseconden of 250 keer per seconde), hoewel het langer kan duren als de micro niet snel genoeg is om de code zo snel uit te voeren.

Code

  • ProtoKeyboardV1.1-Shifted.ino
  • ProtoKeyboardV1-Bits.ino
ProtoKeyboardV1.1-Shifted.inoArduino
Geen voorbeeld (alleen downloaden).
ProtoKeyboardV1-Bits.inoArduino
Bijgewerkte Arduino-code
/* Sketch for Prototyping Keyboard V1.2 * door Cameron Coward 1/30/21 * * Getest op Arduino Uno. Vereist aangepaste PCB * en een 74HC595 schuifregister. * * Meer info:https://www.hackster.io/cameroncoward/64-key-prototyping-keyboard-matrix-for-arduino-4c9531 */const int rowData =2; // shift register Data pin voor rowsconst int rowLatch =3; // schuifregister Vergrendelpen voor rowsconst int rowClock =4; // schuifregister Klokpin voor rijen// dit zijn onze kolominvoerpinnen. Pin 0 en Pin 1 worden niet gebruikt,// omdat ze problemen veroorzaken (vermoedelijk omdat ze TX en RX zijn) const int colA =A0; const int colB =A1; const int colC =A2; const int colD =A3;const int colE =A4;const int colF =A5;const int colG =5;const int colH =6;// shiftRow is de vereiste schuifregisterbyte voor elke rij, rowState bevat ingedrukte toetsen voor elke rowconst byte shiftRow[] ={B01111111, B10111111, B11011111, B11101111, B11110111, B11111011, B11111101, B11111110};byte rowState[] ={B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000};Statbyte ] ={B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000};// ASCII-codes voor toetsen waarvoor geen modificaties zijn ingedrukt. Modifiers zijn NULL (0),// omdat we die afzonderlijk zullen controleren en hun waarden niet moeten worden afgedrukt.const char key[] ={ 0, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 0, 9, 113, 119, 101, 114, 116, 121, 117, 105, 111, 112, 91, 93, 92, 7, 97, 115, 100, 102, 103, 104, 106, 107, 108, 59, 39, 0, 0, 122, 120, 99, 118, 98, 110, 109, 44, 46, 47, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0};// ASCII-codes voor toetsen met shift ingedrukt EN hoofdletters zijn actiefconst char capsShiftKey [] ={0, 33, 64, 35, 36, 37, 94, 38, 42, 40, 41, 95, 43, 0, 9, 113, 119, 101, 114, 116, 121, 117, 105, 111, 112, 123, 125, 124, 7, 97, 115, 100, 102, 103, 104, 106, 107, 108, 58, 22, 0, 0, 122, 120, 99, 118, 98, 110, 109, 44, 46, 47, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0};// ASCII-codes voor toetsen met shift ingedrukt.const char shiftKey[] ={ 0, 33, 64, 35, 36, 37, 94, 38, 42, 40, 41, 95, 43, 0, 9, 81, 87, 69, 82, 84, 89, 85, 73, 79, 80, 123, 125, 124, 7, 65, 83, 68, 70, 71, 72, 74, 75, 76, 58, 22, 0, 0, 90, 88, 67, 86, 66, 78, 77, 44, 46, 47, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0};// ASCII-codes voor toetsen met ctrl ingedrukt.const char ctrlKey[] ={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0};// ASCII-codes voor toetsen met spcl ingedrukt.const char spclKey[] ={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};// ASCII-codes voor toetsen met alt ingedrukt.const char altKey[] ={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};// ASCII-codes voor toetsen met fn ingedrukt.const char fnKey[] ={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};// ASCII-codes voor sleutels met hoofdletters is activeconst char capsKey [] ={ 0, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 0 , 9, 81, 87, 69, 82, 84, 89, 85, 73, 79, 80, 91, 93, 92, 7, 65, 83, 68, 70, 71, 72, 74, 75, 76, 59 , 39, 0, 0, 90, 88, 67, 86, 66, 78, 77, 44, 46, 47, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0 };lange vorigeKeyboardMicros =0; // slaat de laatste keer op dat het toetsenbord werd gecontroleerd // de volgvariabelen zijn lang omdat de tijd, gemeten in milliseconden,// snel een groter getal wordt dan kan worden opgeslagen in een int.long keyboardInterval =500; // interval om toetsenbord te controleren (microseconden) in rowToCheck =0; // We controleren één rij per lus van checkKeyboard(), dit gecombineerd met keyboardInterval // geeft de shiftRegister de tijd om volledig bij te werken tussen rij checksbool caps =false; // staat caps lock aan? bool shift =false; // is linker of rechter shift ingedrukt?bool capsShift =false; // zijn shift AND caps actief?bool ctrl =false; // is de ctrl-toets ingedrukt?bool spcl =false; // is de spcl-toets ingedrukt? bool alt =false; // is de alt-toets ingedrukt?bool fn =false; // is de functietoets ingedrukt? Void setup () { Serial.begin (9600); // stel alle kolompen in als ingangen met interne pullup-weerstanden pinMode (colA, INPUT_PULLUP); pinMode (colB, INPUT_PULLUP); pinMode(colC, INPUT_PULLUP); pinMode(colD, INPUT_PULLUP); pinMode (colE, INPUT_PULLUP); pinMode(colF, INPUT_PULLUP); pinMode(colG, INPUT_PULLUP); pinMode(colH, INPUT_PULLUP); // de uitgangen die nodig zijn om de 74HC595 schuifregister pinMode (rowLatch, OUTPUT) te besturen; pinMode (rijklok, UITGANG); pinMode(rijData, UITGANG); updateShiftRegister(B11111111); // zorg ervoor dat het shift-register helemaal begint HOOG}void loop() { mainTimer();}void mainTimer() { unsigned long currentMicros =micros(); // hoeveel microseconden heeft de Arduino gedraaid? if (currentMicros - previousKeyboardMicros> keyboardInterval) { // als de verstreken tijd sinds de laatste controle het interval overschrijdt // sla de laatste keer op dat het toetsenbord werd gecontroleerd previousKeyboardMicros =currentMicros; checkToetsenbord(); // controleer alle sleutels en druk de resultaten af ​​naar serieel }}void updateShiftRegister (byte rij) { // deze functie stelt het schuifregister in volgens de byte die eraan is doorgegeven digitalWrite (rowLatch, LOW); // zet latch op laag zodat we een hele byte tegelijk kunnen schrijven shiftOut (rowData, rowClock, MSBFIRST, row); // schrijf die byte digitalWrite (rowLatch, HIGH); // zet de vergrendeling terug naar hoog zodat het schuifregister stabiel blijft tot de volgende wijziging} void checkKeyboard () {// stel het schuifregister in op de bytewaarde van de huidige rij, van de shiftRow [] bytearray updateShiftRegister (shiftRow [rowToCheck]); // Controleer elke kolom als (digitalRead (colA) ==LAAG) { bitSet (rowState [rowToCheck], 0); } else { bitClear(rowState[rowToCheck], 0); } if (digitalRead (colB) ==LAAG) { bitSet (rowState [rowToCheck], 1); } else { bitClear(rowState[rowToCheck], 1); } if (digitalRead(colC) ==LAAG) { bitSet(rowState[rowToCheck], 2); } else { bitClear(rowState[rowToCheck], 2); } if (digitalRead(colD) ==LAAG) { bitSet(rowState[rowToCheck], 3); } else { bitClear(rowState[rowToCheck], 3); } if (digitalRead(colE) ==LAAG) { bitSet(rowState[rowToCheck], 4); } else { bitClear(rowState[rowToCheck], 4); } if (digitalRead(colF) ==LAAG) { bitSet(rowState[rowToCheck], 5); } else { bitClear(rowState[rowToCheck], 5); } if (digitalRead(colG) ==LAAG) { bitSet(rowState[rowToCheck], 6); } else { bitClear(rowState[rowToCheck], 6); } if (digitalRead(colH) ==LAAG) { bitSet(rowState[rowToCheck], 7); } else { bitClear(rowState[rowToCheck], 7); } // zet alle schuifregisterpinnen op HOOG, dit zorgt ervoor dat waarden niet "bloeden" naar de volgende lus-updateShiftRegister (B1111111); rowToCheck =rowToCheck + 1; // ga door naar de volgende rij // controleer na het controleren van de 8e rij de toestanden (druk op de knop) en begin opnieuw op de 1e rij if (rowToCheck> 7 ) { checkPressedKeys(); rijToCheck =0; }}void checkPressedKeys() { // controleer of een van de shift-toetsen is ingedrukt if (bitRead(rowState[5], 1) | bitRead(rowState[6], 4)) { shift =true; } else { shift =onwaar; } // controleer of een van de ctrl-toetsen is ingedrukt if (bitRead(rowState[6], 5) | bitRead(rowState[7], 3)) { ctrl =true; } anders { ctrl =onwaar; } // controleer of een van de spcl-toetsen is ingedrukt if (bitRead(rowState[6], 6) | bitRead(rowState[7], 2)) { spcl =true; } anders { spcl =onwaar; } // controleer of een van de alt-toetsen is ingedrukt if (bitRead(rowState[6], 7) | bitRead(rowState[7], 1)) { alt =true; } anders { alt =onwaar; } // controleer of de FN-toets is ingedrukt if (bitRead(rowState[7], 4)) { fn =true; } anders { fn =onwaar; } // controleer of caps actief is en shift is ingedrukt als (shift ==true &&caps ==true) { capsShift =true; } else { capsShift =onwaar; } for (int i =8; i>=0; i--) { // itereer door elke rij for (int j =7; j>=0; j--) { // itereer door elk bit in die rij bool newBit =bitRead(rijState[i], j); // controleer de staat van die bit bool prevBit =bitRead (prevRowState [i], j); // controleer de vorige status van dat bit if ((newBit ==1) &&(prevBit ==0)) { // staat alleen het indrukken van de knop toe als de status is veranderd in true int thisChar =(i * 8) + j; // bereken welke positie in char-array moet worden geselecteerd als (capsShift ==true) { processKey (capsShiftKey [thisChar]); } else if (shift ==true) { processKey (shiftKey [thisChar]); } else if (ctrl ==true) { processKey (ctrlKey [thisChar]); } else if (alt ==true) { processKey (altKey [thisChar]); } else if (spcl ==true) { processKey (spclKey [thisChar]); } else if (fn ==true) { processKey(fnKey[thisChar]); } else if (caps ==true) { processKey(capsKey[thisChar]); } else { processKey(key[thisChar]); } } if (newBit ==1) { bitSet(prevRowState[i], j); // stel de vorige bitstatus in op waar als een toets wordt ingedrukt } else { bitClear (prevRowState [i], j); // stel de vorige bitstatus in op false als de toets niet is ingedrukt, zodat deze opnieuw kan worden ingedrukt } } }} void processKey (char ontvangenKey) {if (receivedKey ==7) {// controleer op dezelfde manier op speciale functies as caps (voeg nieuwe "else if" statements toe) caps =!caps; } else { Serial.print(receivedKey); // als char niet overeenkomt met een speciale functie, print die char dan gewoon }}

Aangepaste onderdelen en behuizingen

Upload het volledige .zip-bestand naar uw PCB-fabricageservice keyplots_4xipOSLHzg.zip

Schema's


Productieproces

  1. LCD-paneel met Arduino voor Flight Simulator
  2. Schakel/LED-paneel met Arduino voor FS2020
  3. Arduino + LED's + MIDI Keyboard + MuseScore =Piano Tutor
  4. Een LED-matrix besturen met Arduino Uno
  5. SMART temperatuurbewaking voor scholen
  6. 8-bit IO-poortbibliotheek voor Arduino
  7. TFT Shield voor Arduino Nano - Start
  8. Een geïsoleerde analoge ingang voor Arduino
  9. Arduino-rekenmachine
  10. Tricks voor het besturen van gelijkstroommotoren
  11. Robot voor supercoole indoornavigatie