Stap 4: Stap 4: Code
Code
Dit project maakt gebruik van rechttoe-rechtaan Arduino code en de standaard bibliotheek voor de Arduino EEPROM. Kopieer en plak de code hieronder in een nieuwe schets en upload het aan uw Trinket.
Code kopiëren
/ * Geheime Knock Trinket Code voor het uitvoeren van een geheim klop lock op de Adafruit Trinket. Versie 13.10.31 gebouwd met Arduino IDE 1.0.5 By Steve Hoefer http://grathio.com licentie onder Creative Commons Attribution-Noncommercial-Share Alike 3.0 http://grathio.com (In het kort: doen wat je wilt, zolang je me krediet niet relicense het en niet verkopen of gebruik het in om het even wat u verkoopt zonder contact met me)---bedrading---Pin 0: Record A nieuwe Knock knop. Pin 1: (maakt gebruik van de ingebouwde LED) Pin 2 (analoge 1): een piezo-element voor piepen en sensing stoten. Pin 3: Verbindt met een transistor dat opent een solenoïde wanneer vergrendelen HIGH.* / #include const byte eepromValid = 123; Als de eerste byte in eeprom dit is dan is de gegevens geldig. / * Pin definities * / const int programButton = 0; Record A nieuwe Knock button.const int ledPin = 1; Gebouwd in LEDconst int knockSensor = 1; (Analoog 1) voor het gebruik van de piezo als een input device. (aka klop sensor) const int audioOut = 2; (Digial 2) voor het gebruik van de peizo als een uitvoerapparaat. (Ding dat pieptoon gaat.) Const int lockPin = 3; De pin dat de veiligheidsvergrendeling vergrendelen activeert. / * Tuning constanten. De onderstaande waarden wijzigt, wordt het gedrag van de device.*/int drempel = 3; Minimale signaal van de piezo te registreren als een knock. Hoger = minder gevoelig. Typische waarden 1 - 10const int rejectValue = 25; Als een afzonderlijke knock is uitgeschakeld door dit percentage van een knock die we niet ontgrendelen. Typische waarden 10-30const int averageRejectValue = 15; Als de gemiddelde timing van alle de stoten is uitgeschakeld door deze procent die we niet ontgrendelen. Typische waarden 5-20const int knockFadeTime = 150; Milliseconden we toestaan dat een klop te verdwijnen voordat we naar een andere luisteren. (Ontdendering timer.) Const int lockOperateTime = 2500; Milliseconden dat we actief de veiligheidsvergrendeling vergrendelen klink voor het vrijgeven van it.const int maximumKnocks = 20; Maximum aantal stoten te luisteren for.const int knockComplete = 1200; Langste tijd om te wachten op een knock, voordat we aannemen dat het klaar. (milliseconden) byte secretCode [maximumKnocks] = {50, 25, 25, 50, 100, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; Basisinstellingen: "Scheren en een kapsel, twee bits." int knockReadings [maximumKnocks]; Wanneer iemand klopt deze matrix wordt gevuld met de vertragingen tussen knocks.int knockSensorValue = 0; Laatste lezing van de knock-sensor.boolean-programModeActive = false; Deze eigenschap is True als we proberen om te programmeren van een nieuwe knock. void setup {pinMode (ledPin, OUTPUT); pinMode (lockPin, OUTPUT); readSecretKnock(); / / de geheime knock laden (indien aanwezig) van EEPROM. doorUnlock(500); / / ontgrendelen van de deur voor een beetje wanneer we de nodige energie. Voor systeemcontrole en aan een manier in als wordt de sleutel vergeten. delay(500); Deze vertraging is hier omdat de veiligheidsvergrendeling vergrendelen terug te keren naar plaatsen kan anders trigger en onbedoelde knock.} void loop {/ / luisteren naar een klop op all. knockSensorValue = analogRead(knockSensor); als (digitalRead(programButton) == HIGH) {/ / is de programmaknop ingedrukt? delay(100); Goedkope ontdendering. Als (digitalRead(programButton) == HIGH) {als (programModeActive == false) {/ / als we niet in programmeermodus te activeren, zet hem op. programModeActive = true; / / onthouden we in programmering modus. digitalWrite (ledPin, hoge); / / inschakelen van de rode licht ook zo de gebruiker weet we programmering. Tjilpen (500, 1500); / / en spelen van een Toon in het geval dat de gebruiker kan niet zien de Tjilpen LED. (500, 1000);} anders {/ / als we in de programing modus , zwenking op vandoor. programModeActive = false; digitalWrite (ledPin, laag); Tjilpen (500, 1000); Uitschakelen van de programmering LED en een droevige noot speelt. Tjilpen (500, 1500); delay(500); } terwijl (digitalRead(programButton) == HIGH) {delay(10); / / rondhangen totdat de knop wordt losgelaten.}} delay(250); Een andere goedkope ontdendering. Langer omdat het loslaten van de knop kan soms worden aangevoeld als een knock. } Als (knockSensorValue > = drempel) {als (programModeActive == true) {/ / de LED knipperen wanneer we zin een knock. digitalWrite (ledPin, laag);} else {digitalWrite (ledPin, hoge);} knockDelay(); als (programModeActive == true) {/ / VN-blink het LED. digitalWrite (ledPin, hoge);} else {digitalWrite (ledPin, laag);} listenToSecretKnock(); / / hebben We onze eerste knock. Gaan en zien wat andere stoten zijn in de winkel...} } / / Records de timing van knocks.void listenToSecretKnock() {int ik = 0; / / eerste reset het luisteren matrix. voor (ik = 0; ik < maximumKnocks; i ++) {knockReadings [i] = 0;} int currentKnockNumber = 0; / / positie van de teller voor de int startTime matrix. = millis(); / / referentie voor toen deze knock. int nu = millis(); doen {/ / luisteren naar de volgende knock of wachten tot het te timeout. knockSensorValue = analogRead(knockSensor); als (knockSensorValue > = drempel) {/ / hier is een ander knock. De tijd tussen stoten besparen. Now=Millis(); knockReadings [currentKnockNumber] = nu - startTime; currentKnockNumber ++; startTime = nu; Als (programModeActive == true) {/ / de LED knipperen wanneer we zin een knock. digitalWrite (ledPin, laag);} else {digitalWrite (ledPin, hoge);} knockDelay(); Als (programModeActive == true) {/ / VN-blink het LED. digitalWrite (ledPin, hoge);} else {digitalWrite (ledPin, laag);}} nu = millis(); Stoppen met luisteren als er teveel stoten of er teveel tijd tussen stoten is. } terwijl ((nu-startTime < knockComplete) & & (currentKnockNumber < maximumKnocks)); We got onze knock opgenomen, laat zien of het geldig is als (programModeActive == false) {/ / dit alleen doen als we niet een nieuwe knock. opneemt als (validateKnock() == true) {doorUnlock(lockOperateTime);} else {/ / knock is ongeldig. De LED knipperen als een waarschuwing aan anderen. voor (ik = 0; ik < 4; i ++) {digitalWrite (ledPin, hoge); delay(50); digitalWrite (ledPin, laag); delay(50);}} } else {/ / als we bij de programmering van de modus die we nog steeds de vergrendeling valideren omdat daarin enkele nummers die we nodig hebben, we gewoon niet doen niets met de terugkeer. validateKnock();}} Ontsluit de door.void doorUnlock (int delayTime) {digitalWrite (ledPin, hoge); digitalWrite (lockPin, hoge); delay(delayTime), digitalWrite (lockPin, LOW), digitalWrite (ledPin, laag); delay(500); / / deze vertraging is hier omdat het vrijgeven van de vergrendeling kan veroorzaken een trilling die zal worden aangevoeld als een knock.} / / controleert of onze knock komt overeen met de secret.// retourneert waar als het is een goede klop, valse als het is not.boolean validateKnock() {int ik = 0; int currentKnockCount = 0; int secretKnockCount = 0; int maxKnockInterval = 0; / / wij dit later gebruiken om te normaliseren de times. voor (ik = 0; i 0) {currentKnockCount ++;} als (secretCode [i] > 0) {secretKnockCount ++;} als (knockReadings [i] > maxKnockInterval) {/ / normalisatie gegevens verzamelen terwijl we bent looping. maxKnockInterval = knockReadings [i];}} Als we een nieuwe klop aan het opnemen bent, slaat u de info en get out of here. Als (programModeActive == true) {voor (ik = 0; ik < maximumKnocks; i ++) {/ / normaliseren van de tijd tussen stoten. (de langste tijd = 100) secretCode [i] = kaart (knockReadings [i], 0, maxKnockInterval, 0, 100); } saveSecretKnock(); Sla het resultaat EEPROM programModeActive = false; playbackKnock(maxKnockInterval); return false; } Als (currentKnockCount! = secretKnockCount) {/ / makkelijkste eerst controleren. Als het aantal stoten klopt, niet ontgrendelen. return false; } / * Nu we de relatieve intervallen van onze klopt, niet de absolute tijd ertussen vergelijken. (dwz: als jij hetzelfde patroon langzaam of snel het moet de deur worden geopend.) Dit maakt het minder kieskeurig, waardoor en maakt het minder veilig kan ook het minder van een pijn om te gebruiken als je tempo is een beetje traag of snel. * / int totaltimeDifferences = 0; int timeDiff = 0; voor (ik = 0; ik < maximumKnocks; i ++) {/ / Normalize de tijden knockReadings [i] = kaart (knockReadings [i], 0, maxKnockInterval, 0, 100); timeDiff = abs (knockReadings [i] - secretCode[i]); if (timeDiff > rejectValue) {/ / individuele waarde te ver uit whack. Geen toegang voor deze knock! return false; } totaltimeDifferences += timeDiff; } / / Het ook kan mislukken als het hele ding ook onjuist is. Als (totaltimeDifferences / secretKnockCount > averageRejectValue) {return false;} terug waar;} leest de geheime knock vanaf EEPROM. (indien van toepassing.) VOID readSecretKnock() {byte lezing; int ik; lezing = EEPROM.read(0); als (lezen == eepromValid) {/ / EEPROM alleen lezen als de handtekening byte klopt. voor (int ik = 0; ik < maximumKnocks; i ++) {secretCode [i] = EEPROM.read(i+1);}}} //saves een nieuw patroon te eepromvoid saveSecretKnock() {EEPROM.write (0, 0); / / leeghalen van de handtekening. Op die manier weten we als we het schrijven niet voltooid. for (int i = 0; ik < maximumKnocks; i ++) {EEPROM.write (i + 1, secretCode[i]);} EEPROM.write (0, eepromValid); alle goed. De handtekening schrijven dus zullen we weten dat it 's all good.} Speelt terug het patroon van de knock in knippert en beepsvoid playbackKnock (int maxKnockInterval) {digitalWrite (ledPin, laag); delay(1000); digitalWrite (ledPin, hoge); Tjilpen (200, 1800); voor (int ik = 0; ik < maximumKnocks; i ++) {digitalWrite (ledPin, laag); / / alleen inschakelen als er zich een vertraging als (secretCode [i] > 0) {vertraging (kaart (secretCode [i], 0, 100, 0, maxKnockInterval)); / / uitbreiden van tijd terug naar wat het was. Ongeveer. digitalWrite (ledPin, hoge); Tjilpen (200, 1800); {}} digitalWrite (ledPin, laag);} Behandelt de knock vertraging thingy.void knockDelay() {int itterations = (knockFadeTime / 20); / / wachten op de piek te verdrijven voordat het luisteren naar volgende. voor (int ik = 0; ik < itterations; i ++) {delay(10); analogRead(knockSensor); / / Dit is gedaan in een poging om het bezweren van de analoge sensor condensator dat valse lezingen op hoge impedantie sensoren. delay(10) geeft;}} / / een niet-muzikale Toon speelt op de piezo. / / playTime = milliseconden om te spelen de Toon / / delayTime = tijd in microseconden tussen teken. (kleinere = hogere toonhoogte Toon.) VOID Tjilpen (int playTime, int delayTime) {lange loopTime = (speeltijd * 1000L) / delayTime; pinMode(audioOut, OUTPUT); voor (int ik = 0; ik < loopTime; i ++) {digitalWrite (audioOut, hoge); delayMicroseconds(delayTime); digitalWrite (audioOut, laag);} pinMode (audioOut, INPUT);}
Voor de nieuwsgierigen, hier is een korte samenvatting van wat de code doet: het initialiseert alles, stelt u de juiste input en de output pinnen en ladingen de opgeslagen klop patroon (indien van toepassing) vanaf EEPROM. Nadat alles is geïnitialiseerd, het luistert naar een piek op de piëzo-sensor.
Wanneer haar boven een bepaalde drempel het telt als een "klop".
Wanneer het hoort een klop start een timer en luistert dan voor meer stoten.
Wanneer het wordt een ander knock bespaart het de tijd tussen stoten naar een matrix.
Wanneer er niet meer klopt (er is ten minste 1,2 seconden zonder een klop) gecontroleerd als de volgorde klopt.
Het doet dit door het normaliseren van de tijd tussen klopt, dat is waardoor ze ten opzichte van elkaar, niet de exacte milliseconden tussen hen. Dus de langste tijd tussen stoten wordt 100, half dat tijd 50 wordt, enz.
Gebruik van de taal van muziek zijn geheel notities 100, half notities zijn 50, kwartnoten zijn 25, enz.
Het vergelijkt deze waarden naar de opgeslagen knock.
Als ze overeenkomen met (of bijna overeenkomt met) het slot opent voor een paar seconden en gaat dan terug naar #2. Als de klop niet overeenkomen, het knippert een licht voor mislukking en vervolgens gaat terug tot #2.It doet andere dingen ook, zoals lezen de knop om te zien als het een nieuwe knock, enz programmeren moet.
De code is royaal heeft gereageerd en, maar hier een paar dingen die u wellicht geïnteresseerd zijn in het wijzigen van:
Code kopiëren
int drempel = 3; (lijn 29)
Als de klop sensor te gevoelig is kunt u proberen deze waarde te verhogen. Waarden onder de 10 werken meestal het beste, maar waarden tot 250 zijn gekend om te werken. (Als u wilt verhogen dit boven 250 dan hebt u wellicht iets mis is met uw circuit of componenten.)
Code kopiëren
Const int rejectValue = 25; const int averageRejectValue = 15; (lijn 30-ish)
Deze twee percentages geven hoe nauwkeurig de knock moet worden om te ontgrendelen. Verhoging van deze nummers kan een sloppier klop te werken. Verlagen van hen vereist een meer strikte klop.