Permalänk
Medlem

Knock activated power switch

Ett litet galleri om hurt man kan få sin dator att starta genom att knacka i skrivbordet

Bakgrund:
Satte ihop en mini- itx dator åt en kompis som sedan gömdes bakom skrivbordet.
Problemet vara bara att det är lite jobbigt att behöva sträcka sig till power knappen varje gång man ska sätta på eller stänga av datorn.

En power switch kortsluter helt enkelt två pins på moderkortet vilket drar igång bootningen av datorn. Så när du trycker på knappen så sluter du två kablar som i sin tur kommer från två pins på moderkortet.

Man skulle ju kunna förlänga kabeln till power switchen så att man når den framför skrivbordet men hur kul är det

Såg för ett tag sedan ett klipp där en snubbe hade gjort en dörr som låser upp sig om man knackar en rätt melodi. Och därifrån fick jag idén att låsa upp daotrn på samma sätt

Googlade runt lite och såg att adafruit hade en fin guide för dörrupplåsning med deras trinket (arduinokompatibel microcontroller) så jag köpte hem en sådan för att se om det går att modifiera en aning...

Hårdvara:
Trinket
Male-male jumper cables:
1 MOhm resistorer
Piezo buzzer
TO-92 NPN transistor
Gammal motorola mobilladdare (5-12 V mini USB laddare behövs till trinket)

Alla grejerna förutom trinket är ganska standard på radio shack liknande ställen. Går att köpa in allt man behöver från adafruit ifall man vill

Kanske lite svårt att se den modifierat elektronik men fråga ifall ni undrar något.

Mjukvaran:
Det enda jag gjort är att ta bort startöppningen, tiden för transistor switchen och optimerat threshold för knackningen.

http://learn.adafruit.com/secret-knock-activated-drawer-lock

/* Secret Knock Trinket
Code for running a secret knock lock on the Adafruit Trinket.

Version 13.10.31 Built with Arduino IDE 1.0.5

By Steve Hoefer http://grathio.com
Licensed under Creative Commons Attribution-Noncommercial-Share Alike 3.0
http://creativecommons.org/licenses/by-nc-sa/3.0/us/
(In short: Do what you want, as long as you credit me, don't relicense it, and don't sell it or use it in anything you sell without contacting me.)

------Wiring------
Pin 0: Record A New Knock button.
Pin 1: (uses the built in LED)
Pin 2 (Analog 1): A piezo element for beeping and sensing knocks.
Pin 3: Connects to a transistor that opens a solenoid lock when HIGH.
*/

#include <EEPROM.h>
const byte eepromValid = 123; // If the first byte in eeprom is this then the data is valid.

/*Pin definitions*/
const int programButton = 0; // Record A New Knock button.
const int ledPin = 1; // The built in LED
const int knockSensor = 1; // (Analog 1) for using the piezo as an input device. (aka knock sensor)
const int audioOut = 2; // (Digial 2) for using the peizo as an output device. (Thing that goes beep.)
const int lockPin = 3; // The pin that activates the solenoid lock.

/*Tuning constants. Changing the values below changes the behavior of the device.*/
int threshold = 5; // Minimum signal from the piezo to register as a knock. Higher = less sensitive. Typical values 1 - 10
const int rejectValue = 25; // If an individual knock is off by this percentage of a knock we don't unlock. Typical values 10-30
const int averageRejectValue = 15; // If the average timing of all the knocks is off by this percent we don't unlock. Typical values 5-20
const int knockFadeTime = 150; // Milliseconds we allow a knock to fade before we listen for another one. (Debounce timer.)
const int lockOperateTime = 1000; // Milliseconds that we operate the lock solenoid latch before releasing it.
const int maximumKnocks = 20; // Maximum number of knocks to listen for.
const int knockComplete = 1200; // Longest time to wait for a knock before we assume that it's finished. (milliseconds)

byte secretCode[maximumKnocks] = {50, 25, 25, 50, 100, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Initial setup: "Shave and a Hair Cut, two bits."
int knockReadings[maximumKnocks]; // When someone knocks this array fills with the delays between knocks.
int knockSensorValue = 0; // Last reading of the knock sensor.
boolean programModeActive = false; // True if we're trying to program a new knock.

void setup() {
pinMode(ledPin, OUTPUT);
pinMode(lockPin, OUTPUT);
readSecretKnock(); // Load the secret knock (if any) from EEPROM.
// doorUnlock(500); // Unlock the door for a bit when we power up. For system check and to allow a way in if the key is forgotten.
delay(500); // This delay is here because the solenoid lock returning to place can otherwise trigger and inadvertent knock.
}

void loop() {
// Listen for any knock at all.
knockSensorValue = analogRead(knockSensor);

if (digitalRead(programButton) == HIGH){ // is the program button pressed?
delay(100); // Cheap debounce.
if (digitalRead(programButton) == HIGH){
if (programModeActive == false){ // If we're not in programming mode, turn it on.
programModeActive = true; // Remember we're in programming mode.
digitalWrite(ledPin, HIGH); // Turn on the red light too so the user knows we're programming.
chirp(500, 1500); // And play a tone in case the user can't see the LED.
chirp(500, 1000);
} else { // If we are in programing mode, turn it off.
programModeActive = false;
digitalWrite(ledPin, LOW);
chirp(500, 1000); // Turn off the programming LED and play a sad note.
chirp(500, 1500);
delay(500);
}
while (digitalRead(programButton) == HIGH){
delay(10); // Hang around until the button is released.
}
}
delay(250); // Another cheap debounce. Longer because releasing the button can sometimes be sensed as a knock.
}

if (knockSensorValue >= threshold){
if (programModeActive == true){ // Blink the LED when we sense a knock.
digitalWrite(ledPin, LOW);
} else {
digitalWrite(ledPin, HIGH);
}
knockDelay();
if (programModeActive == true){ // Un-blink the LED.
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}
listenToSecretKnock(); // We have our first knock. Go and see what other knocks are in store...
}

}

// Records the timing of knocks.
void listenToSecretKnock(){
int i = 0;
// First reset the listening array.
for (i=0; i < maximumKnocks; i++){
knockReadings[i] = 0;
}

int currentKnockNumber = 0; // Position counter for the array.
int startTime = millis(); // Reference for when this knock started.
int now = millis();

do { // Listen for the next knock or wait for it to timeout.
knockSensorValue = analogRead(knockSensor);
if (knockSensorValue >= threshold){ // Here's another knock. Save the time between knocks.
now=millis();
knockReadings[currentKnockNumber] = now - startTime;
currentKnockNumber ++;
startTime = now;

if (programModeActive==true){ // Blink the LED when we sense a knock.
digitalWrite(ledPin, LOW);
} else {
digitalWrite(ledPin, HIGH);
}
knockDelay();
if (programModeActive == true){ // Un-blink the LED.
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}
}

now = millis();

// Stop listening if there are too many knocks or there is too much time between knocks.
} while ((now-startTime < knockComplete) && (currentKnockNumber < maximumKnocks));

//we've got our knock recorded, lets see if it's valid
if (programModeActive == false){ // Only do this if we're not recording a new knock.
if (validateKnock() == true){
doorUnlock(lockOperateTime);
} else {
// knock is invalid. Blink the LED as a warning to others.
for (i=0; i < 4; i++){
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
}
}
} else { // If we're in programming mode we still validate the lock because it makes some numbers we need, we just don't do anything with the return.
validateKnock();
}
}

// Unlocks the door.
void doorUnlock(int delayTime){
digitalWrite(ledPin, HIGH);
digitalWrite(lockPin, HIGH);
delay(delayTime);
digitalWrite(lockPin, LOW);
digitalWrite(ledPin, LOW);
delay(500); // This delay is here because releasing the latch can cause a vibration that will be sensed as a knock.
}

// Checks to see if our knock matches the secret.
// Returns true if it's a good knock, false if it's not.
boolean validateKnock(){
int i = 0;

int currentKnockCount = 0;
int secretKnockCount = 0;
int maxKnockInterval = 0; // We use this later to normalize the times.

for (i=0;i<maximumKnocks;i++){
if (knockReadings[i] > 0){
currentKnockCount++;
}
if (secretCode[i] > 0){
secretKnockCount++;
}

if (knockReadings[i] > maxKnockInterval){ // Collect normalization data while we're looping.
maxKnockInterval = knockReadings[i];
}
}

// If we're recording a new knock, save the info and get out of here.
if (programModeActive == true){
for (i=0; i < maximumKnocks; i++){ // Normalize the time between knocks. (the longest time = 100)
secretCode[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100);
}
saveSecretKnock(); // save the result to EEPROM
programModeActive = false;
playbackKnock(maxKnockInterval);
return false;
}

if (currentKnockCount != secretKnockCount){ // Easiest check first. If the number of knocks is wrong, don't unlock.
return false;
}

/* Now we compare the relative intervals of our knocks, not the absolute time between them.
(ie: if you do the same pattern slow or fast it should still open the door.)
This makes it less picky, which while making it less secure can also make it
less of a pain to use if you're tempo is a little slow or fast.
*/
int totaltimeDifferences = 0;
int timeDiff = 0;
for (i=0; i < maximumKnocks; i++){ // Normalize the times
knockReadings[i]= map(knockReadings[i], 0, maxKnockInterval, 0, 100);
timeDiff = abs(knockReadings[i] - secretCode[i]);
if (timeDiff > rejectValue){ // Individual value too far out of whack. No access for this knock!
return false;
}
totaltimeDifferences += timeDiff;
}
// It can also fail if the whole thing is too inaccurate.
if (totaltimeDifferences / secretKnockCount > averageRejectValue){
return false;
}

return true;
}

// reads the secret knock from EEPROM. (if any.)
void readSecretKnock(){
byte reading;
int i;
reading = EEPROM.read(0);
if (reading == eepromValid){ // only read EEPROM if the signature byte is correct.
for (int i=0; i < maximumKnocks ;i++){
secretCode[i] = EEPROM.read(i+1);
}
}
}

//saves a new pattern too eeprom
void saveSecretKnock(){
EEPROM.write(0, 0); // clear out the signature. That way we know if we didn't finish the write successfully.
for (int i=0; i < maximumKnocks; i++){
EEPROM.write(i+1, secretCode[i]);
}
EEPROM.write(0, eepromValid); // all good. Write the signature so we'll know it's all good.
}

// Plays back the pattern of the knock in blinks and beeps
void playbackKnock(int maxKnockInterval){
digitalWrite(ledPin, LOW);
delay(1000);
digitalWrite(ledPin, HIGH);
chirp(200, 1800);
for (int i = 0; i < maximumKnocks ; i++){
digitalWrite(ledPin, LOW);
// only turn it on if there's a delay
if (secretCode[i] > 0){
delay(map(secretCode[i], 0, 100, 0, maxKnockInterval)); // Expand the time back out to what it was. Roughly.
digitalWrite(ledPin, HIGH);
chirp(200, 1800);
}
}
digitalWrite(ledPin, LOW);
}

// Deals with the knock delay thingy.
void knockDelay(){
int itterations = (knockFadeTime / 20); // Wait for the peak to dissipate before listening to next one.
for (int i=0; i < itterations; i++){
delay(10);
analogRead(knockSensor); // This is done in an attempt to defuse the analog sensor's capacitor that will give false readings on high impedance sensors.
delay(10);
}
}

// Plays a non-musical tone on the piezo.
// playTime = milliseconds to play the tone
// delayTime = time in microseconds between ticks. (smaller=higher pitch tone.)
void chirp(int playTime, int delayTime){
long loopTime = (playTime * 1000L) / delayTime;
pinMode(audioOut, OUTPUT);
for(int i=0; i < loopTime; i++){
digitalWrite(audioOut, HIGH);
delayMicroseconds(delayTime);
digitalWrite(audioOut, LOW);
}
pinMode(audioOut, INPUT);
}

Dold text

Bygget fungerar så att när man knackar på peizo buzzern skapas en liten spänning som man kan registrera med trinketen. Knackar man en visa på bordet så skapas ett gäng sådana med olika tidpunkter gentemot varandra. Ifall knackningarna stämmer överens med en förprogrammerad sekvens så switchar transistor vilket kommer binda ihop power pinsen från moderkortet och datorn startar. Simpelt

Här är ett klipp på slutresultatet:

I filmen är det egentligen inte knackningnarna som registreras men mer om det längre ner.

Knock activated power switch

Permalänk

härligt

du får 5/5 pga den klassiska melodin.

Visa signatur

ASUS Z87-A, Socket-1150| Intel i5 4670k| 2x msi gtx 660 Twin frozr iii | corsair 750w| corsair carbide 330r| 2x 4gb kingston 2133mhz RAM| H100i cpu kylare

Permalänk
Medlem

Mycket coolt projekt, håller själv på mycket med arduino just nu. Skall kolla lite på din hårdvara. Verkar intressant. Själv fick jag lite idér från en iOS app som låser upp en macbook genom att knacka på iPhonen.

EDIT: Skall du ha det ljudkänsligt sen då?

Visa signatur

Intel i7 8700k @ 5.0GHz | Asus Rog Strix Z370-H | FD R5 | Strix Gtx 1080 ti | 16Gb Corsair Vengeance LPX 3600Mhz | Samsung 850-Series EVO 500GB | WD Caviar Black 500Gb | WD RE4 1TB x2 i Raid 1 | MK-85 <3 Cpu-Z Gamla

Citera, annars kommer jag inte tillbaka!

Permalänk
Medlem

Det där var häftigt.

Visa signatur

Desktop|Intel i5 12600|Asus Prime B760 Plus|Nvidia RTX 3070|Corsair DDR5 2x16GB|1TB M.2/1TB SSD
Mouse|Sensei Ten|Keyboard|Xtrfy K4|Monitor|Asus PG279QM|Asus PG279QZ
Laptop|HP ProBook 4320s I3|525GB SSD|4GB DDR3|NAS|Synology 412+ 30TB
Phone|iPhone 13 128GB|Tab|Mi Pad 4 64GB|HTPC|Google TV|Server|Intel Nuc

Permalänk
Medlem

Riktigt coolt. Får mig att fundera på att göra något själv

Visa signatur

| MSI B650 Tomahawk | Ryzen 7 9800X3D | ASUS RTX 3070 | 64GB DDR5 6000MHz | MSI MPG A1000G | Samsung 970 Evo M.2 1TB + 2x WD Black SN850X 2TB|

Permalänk
Medlem

Jag gissar på att det funkar för att vi har ju en viss laddning, och när du rör ledningsbanan så registreras det, jag gissar på att nivåerna är otroligt känsliga. Ta fram en multimeter och mät så kanske du ser mönstret.

Sjukt kul med sådana här gallerier och kul idé!

Visa signatur

HTPC - Bygglogg; http://www.sweclockers.com/album/?id=2902
HTPC - Galleri; http://www.sweclockers.com/galleri/6562-htpc-galleribilder
42U - Bygglogg; http://www.sweclockers.com/galleri/7862-42u-rackskap-i-hemmet
i7 8700K, Antec kühler 620, Asus ROG Strix Z370-I Gaming, Corsair Vengeance RGB DDR4-2666 2x16GB RAM, ASUS GTX 1070

Permalänk
Medlem

Funkar detta på flickvännen också tro om man klappar rätt kod?

Visa signatur

Desktop|Intel i5 12600|Asus Prime B760 Plus|Nvidia RTX 3070|Corsair DDR5 2x16GB|1TB M.2/1TB SSD
Mouse|Sensei Ten|Keyboard|Xtrfy K4|Monitor|Asus PG279QM|Asus PG279QZ
Laptop|HP ProBook 4320s I3|525GB SSD|4GB DDR3|NAS|Synology 412+ 30TB
Phone|iPhone 13 128GB|Tab|Mi Pad 4 64GB|HTPC|Google TV|Server|Intel Nuc

Permalänk
Medlem
Skrivet av bärplockaren:

Funkar detta på flickvännen också tro om man klappar rätt kod?

Det beror på vad du menar med "klappar" och vart.

Visa signatur

HTPC - Bygglogg; http://www.sweclockers.com/album/?id=2902
HTPC - Galleri; http://www.sweclockers.com/galleri/6562-htpc-galleribilder
42U - Bygglogg; http://www.sweclockers.com/galleri/7862-42u-rackskap-i-hemmet
i7 8700K, Antec kühler 620, Asus ROG Strix Z370-I Gaming, Corsair Vengeance RGB DDR4-2666 2x16GB RAM, ASUS GTX 1070

Permalänk
Medlem
Skrivet av Swedishg33k95:

Mycket coolt projekt, håller själv på mycket med arduino just nu. Skall kolla lite på din hårdvara. Verkar intressant. Själv fick jag lite idér från en iOS app som låser upp en macbook genom att knacka på iPhonen.

EDIT: Skall du ha det ljudkänsligt sen då?

Struntar nog i ljudkänsligt och kör på det här. Passar bättre för min kompis att nudda hans golvlampa av mässing bredvid skrivbordet än att knacka i skivan

Skrivet av Tozzi:

Jag gissar på att det funkar för att vi har ju en viss laddning, och när du rör ledningsbanan så registreras det, jag gissar på att nivåerna är otroligt känsliga. Ta fram en multimeter och mät så kanske du ser mönstret.

Sjukt kul med sådana här gallerier och kul idé!

Kan vara något åt det hållet... Funderar på om jag kanske ska göra om designen med piezo buzzern och satsa på att göra en kapacativknapp av hela musmattan. Som det är nu är den alldeles för känslig, om jag inte sitter vid skrivbordet så börjar den registrera saker...

Skrivet av Tozzi:

Det beror på vad du menar med "klappar" och vart.

Brukar klappa till henne allt jag kan i bakhuvudet när hon kommer hem från jobbet. Det startar åtminstonde en av oss

Permalänk
Medlem

Ovanligt, gillar det, 5p

Visa signatur

Citera om du vill ha svar, hjälpte jag dig, gilla svaret!

Permalänk
Medlem
Skrivet av Romoes:

Brukar klappa till henne allt jag kan i bakhuvudet när hon kommer hem från jobbet. Det startar åtminstonde en av oss

Försöker undvika att väcka grannarna med mitt skratt

Kul idé! Albumet alltså

Visa signatur

#framtiden

Permalänk
Medlem

"Med samma känsla som i drömmen då man går naken till skolan visar jag nu upp min ögonsten."

Eftersom jag gillar poesi, så får du 5 stjärnor av mig!

Visa signatur

🖥️:Phanteks Enthoo Evolv X | Ryzen 7 7800X3D | Arctic Freezer II 420 | 6x Noctua NF-P14s Redux 1500 | Asus B650 ProArt Creator | 32Gb Corsair Vengeance 6000Mhz CL30| Samsung 990 Pro 2+1TB | ASUS TUF 3080 12Gb | Corsair RM1000x Shift | Acer XB27HU | Mionix Naos QG | Ducky One 3 Mini RGB |

Permalänk
Medlem

Jag tänker köpa en likadan musmatta.:D

Visa signatur

Deepcool Matrexx 30 & MSI Z87-G43 Gaming!
Intel Inside Core I7 4790K med AMD Radeon R9 390!
Rubbet strömförsörjs av Corsair RM750X!

Permalänk

Förvånar mig att ingen nämnt katten! Ser ut som en riktigt Kungkatt!

Permalänk
Medlem

Beroende på hur du har kopplat allt så misstänker jag att du får en "touch knapp" effekt på sladden. att i och med att du tar på den så minskar resistansen och du får tillräckligt med kontakt för att pull-up resistorn ska ge 1

Visa signatur

CPU: Ryzen 9 3900x Noctua NH-D14 MOBO: TUF Gaming X570-PLUS GPU: GTX 980 RAM: 32 GB 3200 MHz Chassi: R4 PSU: Corsair AX860 Hörlurar: SteelSeries 840 Mus: Logitech G502 Lightspeed V.v. nämn eller citera mig för att få svar.

Permalänk
Medlem
Skrivet av Haptic:

Beroende på hur du har kopplat allt så misstänker jag att du får en "touch knapp" effekt på sladden. att i och med att du tar på den så minskar resistansen och du får tillräckligt med kontakt för att pull-up resistorn ska ge 1

Tror du har rätt.
Beställde en riktig toch sensor från ebay jag väntar på nu