Created
January 5, 2014 16:37
-
-
Save Wicker25/8270414 to your computer and use it in GitHub Desktop.
Rpi-hw C++: electronic door lock with Raspberry Pi (prototype)
http://youtu.be/yyIZsaoNUmE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Title --- electronic_lock.cpp [example] | |
Copyright (C) 2013 Giacomo Trudu - wicker25[at]gmail[dot]com | |
This file is part of Rpi-hw. | |
Rpi-hw is free software: you can redistribute it and/or modify | |
it under the terms of the GNU Lesser General Public License as published by | |
the Free Software Foundation version 3 of the License. | |
Rpi-hw is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU Lesser General Public License for more details. | |
You should have received a copy of the GNU Lesser General Public License | |
along with Rpi-hw. If not, see <http://www.gnu.org/licenses/>. | |
*/ | |
#include <memory> // `unique_ptr` | |
// Add the Rpi-hw headers | |
#include <rpi-hw.hpp> | |
#include <rpi-hw/time.hpp> | |
#include <rpi-hw/driver/mcp23s17.hpp> | |
#include <rpi-hw/gpio.hpp> | |
#include <rpi-hw/iface/output.hpp> | |
#include <rpi-hw/keypad/matrix.hpp> | |
#include <rpi-hw/display/hd44780.hpp> | |
#include <rpi-hw/motor/stepper.hpp> | |
// Define the PIN used to unlock the door | |
#define MY_PIN "123456" | |
// Use Rpi-hw namespace | |
using namespace rpihw; | |
/** Class of my application **/ | |
class MyApp { | |
public: | |
// Define the keymap | |
const std::vector< uint8_t > keymap = { | |
'1', '2', '3', 'A', | |
'4', '5', '6', 'B', | |
'7', '8', '9', 'C', | |
'*', '0', '#', 'D' | |
}; | |
/** Constructor method **/ | |
MyApp() | |
// Build the controllers | |
: m_lcd ( new display::hd44780( 100, 101, 102, 103, 104, 105 ) ) | |
, m_keypad ( new keypad::matrix( { 108, 109, 110, 111 }, { 112, 113, 114, 115 }, keymap ) ) | |
, m_motor ( new motor::stepper( 4096, 14, 15, 18, 23 ) ) | |
, m_leds ( new iface::output( { 106, 107 } ) ) { | |
// Initialize the 16x2 LCD | |
m_lcd->init( 16, 2 ); | |
// Add the keypad event listener | |
m_keypad->addEventListener( std::bind( &MyApp::eventListener, this, std::placeholders::_1 ) ); | |
// Set the motor speed | |
m_motor->setSpeed( 10.0 ); | |
} | |
/** Destructor method **/ | |
~MyApp() {} | |
/** The keypad event listener **/ | |
void eventListener( keypad::base &dev ) { | |
// When user press "1", "2", ..., "9" buttons add the pressed number to the current PIN | |
for ( char c = '1'; c <= '9'; ++c ) { | |
if ( m_keypad->keyPressed( c ) ) { | |
m_pin.push_back( c ); | |
// Add an asterisk to the screen | |
m_lcd->write('*'); | |
} | |
} | |
// When user press the "A" button check if the PIN is correct | |
if ( m_keypad->keyPressed('A') ) { | |
// Clear the screen | |
m_lcd->clear(); | |
// Check the PIN | |
if ( m_pin == MY_PIN ) | |
unlock(); | |
else | |
display_error(); | |
// Reset the current pin | |
m_pin.clear(); | |
// Clear the screen | |
m_lcd->clear(); | |
m_lcd->write( "Insert PIN:\n" ); | |
} | |
} | |
/** Display error message **/ | |
void display_error() { | |
// Turn on the red LED | |
m_leds->write( 0, HIGH ); | |
// Display the error message | |
m_lcd->write( "Incorrect PIN!" ); | |
// Wait some seconds | |
time::sleep(2); | |
// Turn off the red LED | |
m_leds->write( 0, LOW ); | |
} | |
/** Open the door **/ | |
void unlock() { | |
// Turn on the green LED | |
m_leds->write( 1, HIGH ); | |
// Say to the user that the door is opening | |
m_lcd->write( "Opening door...\n" ); | |
// Move the stepper motor to unlock the door | |
m_motor->rotate( -90.0 ); | |
time::sleep(1); | |
m_motor->rotate( 90.0 ); | |
// Say to the user that the door is opened | |
m_lcd->write( "Done." ); | |
// Wait some seconds | |
time::sleep(2); | |
// Turn off the green LED | |
m_leds->write( 1, LOW ); | |
} | |
/** Main loop **/ | |
void run() { | |
m_lcd->write( "Insert PIN:\n" ); | |
for ( ;; ) { | |
/* ... Other works ... */ | |
time::msleep( 100 ); | |
} | |
} | |
private: | |
// LCD controller | |
std::unique_ptr< display::hd44780 > m_lcd; | |
// Keypad controller | |
std::unique_ptr< keypad::matrix > m_keypad; | |
// Stepper motor controller | |
std::unique_ptr< motor::stepper > m_motor; | |
// LEDs interface | |
std::unique_ptr< iface::output > m_leds; | |
// The current pin number | |
std::string m_pin; | |
}; | |
int | |
main( int argc, char *args[] ) { | |
// Add the I/O expander to the standard GPIO connector | |
driver::mcp23s17 expander( "/dev/spidev0.0", 0 ); | |
gpio::get().expand( 100, expander ); | |
// Run the application | |
MyApp app; app.run(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment