Difference between revisions of "ACKsess"

From Hackerspace ACKspace
Jump to: navigation, search
(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 (fast blink if door is unlocked)
+
* 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 ====
[[User:Xopr|Xopr]] placed his Arduino mega 1280 (clone) to get it working quickly (still took him all day to get back on track).
+
The joystick contains a print that fits snugly, with an Arduino pro mini.
  
 
===== arduino Mega 1280 =====
 
===== arduino Mega 1280 =====
Used the arduino to get it working quickly, new design should be underway (by someone else).
+
The print has print connectors, so everything can pop off easy.
[[User:Xopr|Xopr]] made a mini prototype shield where the onewire pullup sits, the NPN transistor (to switch the 12Vin via the relay to ground), the LED, external button and some extra ground connections.
 
  
You can add a usb A to B cable for debugging on 115200 baud.
+
You can use a USB to serial adapter (came with the pro mini) for debugging on 115200 baud.
  
===== proto shield =====
+
===== Joystick PCB =====
  
The shield fetches power and uses some of the digital I/O 0 to 7.
+
The PCB receives power, and uses a 7805 to power the Arduino.
  
 
'''Arduino pins'''
 
'''Arduino pins'''
# TxD, not used
+
# not used
# relay pin, set high to pull breakout pin X to low
+
# 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
+
# led pin: uses pwm heart beat every 5 seconds and blinks fast if the door is unlocked
# reader pin: the onewire data pin
 
 
# 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
  
breakout pins:
 
<pre>
 
,_________
 
|
 
|o external open (pullup, connect to ground to trigger)
 
|o onewire data (probe green)
 
|o led + (probe orange)
 
|o Vin (12v for relay) (bundle-with-orange)
 
|o door-open (GND-switch) (bundle-with-blue)
 
|o GND (currently not connected, for use with external button)
 
|o GND (probe orange)
 
|o GND (probe blue)                  o o o
 
|                                    e b c NPN transistor
 
'__________
 
</pre>
 
 
* 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  = 3;    // the number of the relay pin
+
const int relayPin  = 5;    // the number of the relay pin
const int ledPin    = 4;    // the number of the LED pin (change to 13 to see the onboard led)
+
const int ledPin    = 3;    // the number of the LED pin (change to 13 to see the onboard led)
const int readerPin = 5;    // the number of the iButton reader pin
+
const int readerPin = 2;    // the number of the iButton reader pin
const int buttonPin = 6;    // the number of the pushbutton pin
+
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 = "";
  
// Buttons, first defense
+
byte allowedButtons[][6] = {
byte but[][6] = {
+
  /* ADD YOUR BUTTONS TO AUTHORIZE HERE */
   /* ADD YOUR BUTTONS HERE */
+
};
 +
 
 +
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( but ) / 6 );
+
   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 )
          delay( 1 );
+
        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 < 15; n++ )
+
   for ( byte n = 0; n < 3; n++ ) // 250+250*6 500+500*3
 
   {
 
   {
 
     digitalWrite( ledPin, HIGH );
 
     digitalWrite( ledPin, HIGH );
     delay( 100 );
+
    tone( buzzerPin, 1000, 250 );
 +
     delay( 250 );
 
     digitalWrite( ledPin, LOW );
 
     digitalWrite( ledPin, LOW );
     delay( 100 );
+
     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
* someone needs to make a 2.0 version that fits in the designated casing (the awesome joystick), but up until that time, the current implementation will suffice.
 
 
* 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


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

  1. not used
  2. reader pin: reader 'data' pin, 4k7 pull up to 5v
  3. led pin: uses pwm heart beat every 5 seconds and blinks fast if the door is unlocked
  4. button pin: for use for external opener, pullup (connect to ground to trigger)
  5. relay pin: set high to pull relay pin to low
  6. not used
  7. not used
  8. not used
  9. 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:

  1. GND (blue)
  2. Data (onewire) (green)
  3. LED cathode (-) (yellow)
  4. 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