Difference between revisions of "ACKsess"
|  (linked pictures) |  (updated arduino code, removed previous "fragile" adhesive tape version) | ||
| Line 12: | Line 12: | ||
| The now working ACKsess implementation has several advantages over the old broken one, that broke. | The now working ACKsess implementation has several advantages over the old broken one, that broke. | ||
| * Heartbeat: it pulsates the LED every 5 seconds or so, to indicate it's active | * Heartbeat: it pulsates the LED every 5 seconds or so, to indicate it's active | ||
| − | * Better feedback ( | + | * Better feedback (blink if door is unlocked) | 
| − | * Brute force protection (locks 30 seconds after a failed authentication) | + | * Brute force protection (locks 30 seconds after a failed authentication, pulsates very fast as a tamper indication) | 
| * Faster response (shortened the delay for faster response) | * Faster response (shortened the delay for faster response) | ||
| * Opens on powerup/reset. This way, the reset button can be used to open the door | * Opens on powerup/reset. This way, the reset button can be used to open the door | ||
| * Various code cleanup/alignment/update | * Various code cleanup/alignment/update | ||
| + | * (NEW) it beeps (as a helping aid)! | ||
| + | |||
| ==== images ==== | ==== images ==== | ||
| Some images | Some images | ||
| Line 30: | Line 32: | ||
| ==== hardware ==== | ==== hardware ==== | ||
| − | + | The joystick contains a print that fits snugly, with an Arduino pro mini. | |
| ===== arduino Mega 1280 ===== | ===== arduino Mega 1280 ===== | ||
| − | + | The print has print connectors, so everything can pop off easy. | |
| − | |||
| − | You can  | + | You can use a USB to serial adapter (came with the pro mini) for debugging on 115200 baud. | 
| − | =====  | + | ===== Joystick PCB ===== | 
| − | The  | + | The PCB receives power, and uses a 7805 to power the Arduino. | 
| '''Arduino pins''' | '''Arduino pins''' | ||
| − | #  | + | # not used | 
| − | #  | + | # reader pin: reader 'data' pin, 4k7 pull up to 5v | 
| − | # led pin | + | # led pin: uses pwm heart beat every 5 seconds and blinks fast if the door is unlocked | 
| − | |||
| # button pin: for use for external opener, pullup (connect to ground to trigger) | # button pin: for use for external opener, pullup (connect to ground to trigger) | ||
| + | # relay pin: set high to pull relay pin to low | ||
| + | # not used | ||
| + | # not used | ||
| + | # not used | ||
| + | # buzzer pin: for audio feedback | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| * The NPN transistor used is a BC548 (goes up to 500mA), drived with a 100-300 something ohm resistor on the base (from the top of my head). | * The NPN transistor used is a BC548 (goes up to 500mA), drived with a 100-300 something ohm resistor on the base (from the top of my head). | ||
| * Note that is has a diode (1n4000 something) antiparallel between collector and emittor as coil reverse voltage protection | * Note that is has a diode (1n4000 something) antiparallel between collector and emittor as coil reverse voltage protection | ||
| Line 83: | Line 73: | ||
| #include <OneWire.h> | #include <OneWire.h> | ||
| − | const int relayPin  =  | + | const int relayPin  = 5;     // the number of the relay pin | 
| − | const int ledPin    =  | + | const int ledPin    = 3;     // the number of the LED pin (change to 13 to see the onboard led) | 
| − | const int readerPin =  | + | const int readerPin = 2;     // the number of the iButton reader pin | 
| − | const int buttonPin =  | + | const int buttonPin = 4;     // the number of the pushbutton pin | 
| + | const int buzzerPin = 9;     // the number of the buzzer pin | ||
| OneWire ds( readerPin ); | OneWire ds( readerPin ); | ||
| Line 92: | Line 83: | ||
| String keyStatus = ""; | String keyStatus = ""; | ||
| − | //  | + | byte allowedButtons[][6] = { | 
| − | byte  | + |   /* ADD YOUR BUTTONS TO AUTHORIZE HERE */ | 
| − |    /* ADD  | + | }; | 
| + | |||
| + | byte disallowedButtons[][6] = { | ||
| + |    /* ADD THE BUTTONS TO IGNORE HERE */ | ||
| }; | }; | ||
| void setup(void) | void setup(void) | ||
| { | { | ||
| − |    Serial.begin( 115200 ); | + |    Serial.begin(115200); | 
|    pinMode( buttonPin, INPUT_PULLUP ); |    pinMode( buttonPin, INPUT_PULLUP ); | ||
|    pinMode( ledPin, OUTPUT ); |    pinMode( ledPin, OUTPUT ); | ||
| Line 106: | Line 100: | ||
|    Serial.println( "ACKsess initialized" ); |    Serial.println( "ACKsess initialized" ); | ||
|    Serial.print( "number of keys: " ); |    Serial.print( "number of keys: " ); | ||
| − |    Serial.println( sizeof(  | + |    Serial.println( sizeof( allowedButtons ) / 6 ); | 
|    // Open the door upon power up and (on board) reset |    // Open the door upon power up and (on board) reset | ||
| − |    openDoor( ); | + |    openDoor( true ); | 
| } | } | ||
| byte nState = 0; | byte nState = 0; | ||
| byte nLedVal = 0; | byte nLedVal = 0; | ||
| − | + | bool bTamper = false; | |
| void loop(void) | void loop(void) | ||
| { | { | ||
| Line 124: | Line 118: | ||
|          nState++; |          nState++; | ||
| − |        analogWrite( ledPin, nLedVal ); | + |        if ( bTamper ) | 
| + |           analogWrite( ledPin, nLedVal & 32 ); | ||
| + |       else | ||
| + |           analogWrite( ledPin, nLedVal ); | ||
| + | |||
|        delay( 1 ); |        delay( 1 ); | ||
|        break; |        break; | ||
| Line 133: | Line 131: | ||
|          nState++; |          nState++; | ||
| − |        analogWrite( ledPin, nLedVal ); | + |        if ( bTamper ) | 
| − | + |         analogWrite( ledPin, nLedVal & 32 ); | |
| + |       else | ||
| + |         analogWrite( ledPin, nLedVal ); | ||
| + | |||
| + |         delay( 1 ); | ||
|        break; |        break; | ||
| Line 149: | Line 151: | ||
|    // If the external button was pushed, open the door |    // If the external button was pushed, open the door | ||
|    if ( digitalRead( buttonPin ) == LOW ) |    if ( digitalRead( buttonPin ) == LOW ) | ||
| − |      openDoor( ); | + |      openDoor( true ); | 
|    // Check keys twice each fade and on every idle state step |    // Check keys twice each fade and on every idle state step | ||
| Line 162: | Line 164: | ||
|        for( byte i = 5; i > 0; i--) |        for( byte i = 5; i > 0; i--) | ||
|        { |        { | ||
| − |          Serial.print(":"); | + |          Serial.print( ":" ); | 
|          Serial.print(addr[i], HEX); |          Serial.print(addr[i], HEX); | ||
|        } |        } | ||
| − |        Serial.println(""); | + |        Serial.println( "" ); | 
|        // Either open the door, or lock the system for 30 seconds |        // Either open the door, or lock the system for 30 seconds | ||
| − |        if ( authenticateKey( addr ) ) | + |        if ( authenticateKey( addr, false ) ) | 
|        { |        { | ||
| − |          openDoor( ); | + |         bTamper = false; | 
| + |          openDoor( false ); | ||
|        } |        } | ||
| − |        else | + |        else if ( !authenticateKey( addr, true ) ) | 
|        { |        { | ||
| + |         bTamper = true; | ||
|          Serial.println( "ACKsess denied!" ); |          Serial.println( "ACKsess denied!" ); | ||
| + |         tone( buzzerPin, 600, 3000 ); | ||
|          delay( 30000 ); |          delay( 30000 ); | ||
| + |       } | ||
| + |       else | ||
| + |       { | ||
| + |         Serial.println( "ACKsess filtered" ); | ||
| + |         tone( buzzerPin, 600, 500 ); | ||
| + |         delay( 1000 ); | ||
| + |         tone( buzzerPin, 600, 500 ); | ||
| + |         delay( 1000 ); | ||
| + |         tone( buzzerPin, 600, 1000 ); | ||
|        } |        } | ||
|      } |      } | ||
| Line 181: | Line 195: | ||
| } | } | ||
| − | void openDoor() | + | void openDoor( bool _buttonPressed ) | 
| { | { | ||
| − |    Serial.println( "ACKsess!" ); | + |    Serial.println( "ACKsess granted!" ); | 
|    // Trigger the relay |    // Trigger the relay | ||
| Line 189: | Line 203: | ||
|    // Blink the led fast for about 3 seconds |    // Blink the led fast for about 3 seconds | ||
| − |    for ( byte n = 0; n <  | + |    for ( byte n = 0; n < 3; n++ )  // 250+250*6 500+500*3 | 
|    { |    { | ||
|      digitalWrite( ledPin, HIGH ); |      digitalWrite( ledPin, HIGH ); | ||
| − |      delay(  | + |     tone( buzzerPin, 1000, 250 ); | 
| + |      delay( 250 ); | ||
|      digitalWrite( ledPin, LOW ); |      digitalWrite( ledPin, LOW ); | ||
| − |      delay(  | + |      delay( 250 ); | 
|    } |    } | ||
| Line 223: | Line 238: | ||
| } | } | ||
| − | boolean authenticateKey( byte* _button ) | + | boolean authenticateKey( byte* _button, bool _includeIgnore ) | 
| { | { | ||
|    /* SECURITY THROUGH OBSCURITY, VISIT US TO SEE SOME EXAMPLES */ |    /* SECURITY THROUGH OBSCURITY, VISIT US TO SEE SOME EXAMPLES */ | ||
| Line 231: | Line 246: | ||
| ==== todo ==== | ==== todo ==== | ||
| + | * add picture of the internals | ||
| * have battery backup (implement stand-by mode, might need a refit of the pull-up) | * have battery backup (implement stand-by mode, might need a refit of the pull-up) | ||
| * check if we need a power-on-lock or power-off-lock, and add an appropriate power design | * check if we need a power-on-lock or power-off-lock, and add an appropriate power design | ||
| − | |||
| * audit the authentication method | * audit the authentication method | ||
| * Create better method to store and revoke keys on the whole | * Create better method to store and revoke keys on the whole | ||
Revision as of 21:46, 3 March 2015
| Project: ACKsess | |
|---|---|
| Featured: | |
| State | Active | 
| Members | Vicarious, Prodigity, xopr | 
| GitHub | No GitHub project defined. Add your project here. | 
| Description | Knock knock. | 
| Picture | |
| No project picture! Fill in form Picture or Upload a jpeg here | |
Contents
synopsis
knock knock.
current implementation
The now working ACKsess implementation has several advantages over the old broken one, that broke.
- Heartbeat: it pulsates the LED every 5 seconds or so, to indicate it's active
- Better feedback (blink if door is unlocked)
- Brute force protection (locks 30 seconds after a failed authentication, pulsates very fast as a tamper indication)
- Faster response (shortened the delay for faster response)
- Opens on powerup/reset. This way, the reset button can be used to open the door
- Various code cleanup/alignment/update
- (NEW) it beeps (as a helping aid)!
images
Some images
hardware
The joystick contains a print that fits snugly, with an Arduino pro mini.
arduino Mega 1280
The print has print connectors, so everything can pop off easy.
You can use a USB to serial adapter (came with the pro mini) for debugging on 115200 baud.
Joystick PCB
The PCB receives power, and uses a 7805 to power the Arduino.
Arduino pins
- not used
- reader pin: reader 'data' pin, 4k7 pull up to 5v
- led pin: uses pwm heart beat every 5 seconds and blinks fast if the door is unlocked
- button pin: for use for external opener, pullup (connect to ground to trigger)
- relay pin: set high to pull relay pin to low
- not used
- not used
- not used
- buzzer pin: for audio feedback
- The NPN transistor used is a BC548 (goes up to 500mA), drived with a 100-300 something ohm resistor on the base (from the top of my head).
- Note that is has a diode (1n4000 something) antiparallel between collector and emittor as coil reverse voltage protection
- The onewire pull up used is 4k7 to 5v
DS9092L iButton probe
I had to reverse engineer the wiring somewhat (connector was gone), but here it is: DS9092L iButton probe datasheet Pinout:
- GND (blue)
- Data (onewire) (green)
- LED cathode (-) (yellow)
- LED anode (+) (orange)
software
Most of ACKsess.ino:
#include <OneWire.h>
const int relayPin  = 5;     // the number of the relay pin
const int ledPin    = 3;     // the number of the LED pin (change to 13 to see the onboard led)
const int readerPin = 2;     // the number of the iButton reader pin
const int buttonPin = 4;     // the number of the pushbutton pin
const int buzzerPin = 9;     // the number of the buzzer pin
OneWire ds( readerPin );
byte addr[ 8 ];
String keyStatus = "";
byte allowedButtons[][6] = {
  /* ADD YOUR BUTTONS TO AUTHORIZE HERE */
};
byte disallowedButtons[][6] = {
  /* ADD THE BUTTONS TO IGNORE HERE */
};
void setup(void)
{
  Serial.begin(115200);
  pinMode( buttonPin, INPUT_PULLUP );
  pinMode( ledPin, OUTPUT );
  pinMode( relayPin, OUTPUT );
  
  Serial.println( "ACKsess initialized" );
  Serial.print( "number of keys: " );
  Serial.println( sizeof( allowedButtons ) / 6 );
  // Open the door upon power up and (on board) reset
  openDoor( true );
}
byte nState = 0;
byte nLedVal = 0;
bool bTamper = false;
void loop(void)
{
  switch ( nState )
  {
    case 0: // forward, led fade in
      nLedVal++;
      if ( nLedVal >= 255 )
        nState++;
      if ( bTamper )
          analogWrite( ledPin, nLedVal & 32 );
      else
          analogWrite( ledPin, nLedVal );
      delay( 1 );
      break;
    case 1: // backward, led fade out
      nLedVal--;
      if ( nLedVal <= 0 )
        nState++;
      if ( bTamper )
        analogWrite( ledPin, nLedVal & 32 );
      else
        analogWrite( ledPin, nLedVal );
        delay( 1 );
      break;
    default: // idle
        nState++;
        delay( 500 );
        if ( nState >= 10 )
          nState = 0;
      break;
  };
  // If the external button was pushed, open the door
  if ( digitalRead( buttonPin ) == LOW )
    openDoor( true );
  // Check keys twice each fade and on every idle state step
  if ( (nLedVal == 127) || ( nState > 1 ) )
  {
    // Store the button info and read the keycode
    getKeyCode( );
    if( keyStatus == "ok" )
    {
      // We have a correct key type, authenticate it
      Serial.print("00");
      for( byte i = 5; i > 0; i--)
      {
        Serial.print( ":" );
        Serial.print(addr[i], HEX);
      }
      Serial.println( "" );
      // Either open the door, or lock the system for 30 seconds
      if ( authenticateKey( addr, false ) )
      {
        bTamper = false;
        openDoor( false );
      }
      else if ( !authenticateKey( addr, true ) )
      {
        bTamper = true;
        Serial.println( "ACKsess denied!" );
        tone( buzzerPin, 600, 3000 );
        delay( 30000 );
      }
      else
      {
        Serial.println( "ACKsess filtered" );
        tone( buzzerPin, 600, 500 );
        delay( 1000 );
        tone( buzzerPin, 600, 500 );
        delay( 1000 );
        tone( buzzerPin, 600, 1000 );
      }
    }
  }
}
void openDoor( bool _buttonPressed )
{
  Serial.println( "ACKsess granted!" );
  // Trigger the relay
  digitalWrite( relayPin, HIGH );
  // Blink the led fast for about 3 seconds
  for ( byte n = 0; n < 3; n++ )  // 250+250*6 500+500*3
  {
    digitalWrite( ledPin, HIGH );
    tone( buzzerPin, 1000, 250 );
    delay( 250 );
    digitalWrite( ledPin, LOW );
    delay( 250 );
  }
  // Relay off
  digitalWrite( relayPin, LOW );
}
void getKeyCode()
{
  byte present = 0;
  byte data[ 12 ];
  keyStatus="";
  if ( !ds.search( addr ) )
  {
    ds.reset_search( );
    return;
  }
  if ( OneWire::crc8( addr, 7) != addr[ 7 ] )
  {
    keyStatus = "CRC invalid";
    return;
  }
  keyStatus = "ok";
  ds.reset( );
}
boolean authenticateKey( byte* _button, bool _includeIgnore )
{
  /* SECURITY THROUGH OBSCURITY, VISIT US TO SEE SOME EXAMPLES */
  return false;
}
todo
- add picture of the internals
- have battery backup (implement stand-by mode, might need a refit of the pull-up)
- check if we need a power-on-lock or power-off-lock, and add an appropriate power design
- audit the authentication method
- Create better method to store and revoke keys on the whole




