Fingerprint Bouncer
Contents
- 1 Hacking the Xinchejian doorbot
- 1.1 How?
- 1.1.1 Installing OpenWRT via TFTP
- 1.1.2 Get OpenWRT Running on the TL-WR703
- 1.1.3 Wiring Fingerprint Scanner to the Arduino Uno
- 1.1.4 Connecting the Arduino to the TL-WR703N
- 1.1.5 Install Serial to Net (ser2net)
- 1.1.6 Start ser2net or socat
- 1.1.7 Install FTDI USB Serial
- 1.1.8 Howto: SSH to the Router
- 1.1.9 Software Serial with the Arduino
- 1.2 Troubleshooting
- 1.3 Members
- 1.4 Links
- 1.1 How?
Hacking the Xinchejian doorbot
a solution to allow members to use their fingerprint with a scanner (GT-511C3) to open the door of the xinchejian hackerspace in Shanghai. Using a small Linux Device / Router (TL-WR703N) to send a RESTful request to the bouncer (doorbot) to:
- open the door if a successful
- enroll a fingerprint to an existing XCJ user account
- remove a fingerprint from an existing XCJ user account
- deny access and do not open the door if the fingerprint is not recognised.
OpenWRT firmware we can toggle the state of GPIO pins which will be connected to the control pins of the door opener by an optoisolated relay board.
How?
Installing OpenWRT via TFTP
Install TFTP Correctly: http://www.cyberciti.biz/faq/install-configure-tftp-server-ubuntu-debian-howto/
First you install and start a TFTP server (or daemon) on your host and place the image(s) to be flashed in the <root directory> of this software (you may be required to do this as root). Example:
sudo apt-get install tftpd-hpa tftp
Configuration Edit /etc/default/tftpd-hpa, run:
vi /etc/default/tftpd-hpa
Sample configuration:
TFTP_USERNAME="tftp" TFTP_DIRECTORY="/srv/tftp" TFTP_ADDRESS="0.0.0.0:69" TFTP_OPTIONS="--secure"
How do I start / stop / restart tftpd-hpa server?
Type the following commands:
service tftpd-hpa status service tftpd-hpa stop service tftpd-hpa start service tftpd-hpa restart service tftpd-hpa force-reload
Test the server:
tftp localhost tftp> get (some file) tftp> quit cmp /var/lib/tftpboot/uboot.img uboot.img # no output other then a prompt means it worked correctly
Using the TFTP Server
Follow the installation procedure for this router + version: http://wiki.openwrt.org/toh/tp-link/tl-wr703n#tftp_install_necessary_on_v17_hardware
Generally speaking we connect to the bootloader, and tell it to get the images on your harddisk via its TFTP client Example:
telnet 192.168.0.100 Redboot> load uboot.img go
after successful installation of OpenWrt, do not forget to deactivate the TFTP server again!
Get OpenWRT Running on the TL-WR703
OpenWrt is a highly extensible GNU/Linux distribution for embedded devices. After upgrade your router to OpenWRT, your router will become much more powerful (more features) than before.
Warning: Flashing wrong version firmware will brick the router.
- Download correct firmware version
- Uppgrade firmware to Openwrt
- Open up a browser and navigate to http://192.168.1.1 (this is the default router IP)
- Enter admin for both username & password
- Status screen should appear.
- Select System Tools and Firmware upgrade
- Click on Browse button and select the Openwrt file that you downloaded
- Click on upgrade button in order to start upgrade firmware
- Restart router once the upgrade process finish
- Configure Openwrt
- TP-LINK TL-WR703N Openwrt Login
- Open up the browser and navigate to http://192.168.1.1
- Click on Login button without password
- Click on Go to password configuration in order to change the password, SSH will enabled automatically.
- Your router is ready. You can add and remove packages based on your requirement.
More info: http://wiki.openwrt.org/toh/tp-link/tl-wr703n
Wiring Fingerprint Scanner to the Arduino Uno
Pin # Fingerprint Scanner <-> Arduino Uno
1 UART_TX <-> RX (pin 4)
2 UART_RX <-> TX (pin 5)
3 GND <-> GND
4 Vin (3.3V~6V) <-> 5V
Connecting the Arduino to the TL-WR703N
Arduino Uno as a USB to TTL converter. The Arduino Uno uses a software serial port to connect to the fingerprint scanner because the only hardware serial port on the Uno is connected to the USB chip which is used as the interface to the router USB port.
Serial data is relayed between the fingerprint scanner and the router by a sketch running on the Arduino.
The Arduino is plugged into the USB port of TP-LINK TL-WR703N to allow the router to control the Arduino and to listen to serial data from the fingerprint scanner.
After upgrade router firmware to Openwrt, Login to it & change the password in order to enable SSH.
Install Serial to Net (ser2net)
Here I show you 2 different methods to control the Arduino, ser2net and socat.
To install ser2net, execute this code:
opkg install ser2net
Option 1: Install Serial to Net
To make ser2net listen on TCP port 1234, append 1 line to the end of /etc/ser2net.conf
1234:raw:0:/dev/ttyUSB0:9600
Using WinSCP to edit the configuration. The setting is added to the ser2net configuration as shown in figure below
This will open a tcp 1234 port & set to baud rate 9600. The usb serial port will be /dev/ttyUSB0
Option 2. Install socat
socat is much more powerful & features than ser2net. To install socat, enter the following command:
opkg install socat
Start ser2net or socat
You will need to start ser2net or socat before you can control the Arduino. There is two way to start ser2net & socat. You can start it manually or automatically on every reboot.
Start ser2net manually
ser2net
ser2net will start based on ser2net configuration file
Start socat manually (Arduino Duemilanove)
socat tcp-l:1234,reuseaddr,fork file:/dev/ttyUSB0,nonblock,raw,echo=0,waitlock=/var/run/tty,b9600
This will open a tcp 1234 port & set to baud rate 9600. The usb serial port will be /dev/ttyUSB0
Start socat manually (Arduino Uno R3 USB chip)
socat tcp-l:1234,reuseaddr,fork file:/dev/ttyACM0,nonblock,raw,echo=0,waitlock=/var/run/tty,b9600
This will open a tcp 1234 port & set to baud rate 9600. The usb serial port will be /dev/ttyACM0
Open the port
This is particular important, it use to prevent autoreset on initiation of serial. cat /dev/ttyUSB0
You can open the port on every router reboot
- Login to router
- Click System -> Startup
- Scroll down the screen until you see Local Startup
- Enter cat /dev/ttyUSB0 before exit 0 as shown in figure below.
Arduino Code
/* 16 Output Arduino Controller Ver. 0.1 Released on 22 Oct 2012 by ediy.com.my SerialEvent only support Arduino ver 1.00 and above serial command syntax must be ssnn or ss nn where ss is a two character command, it can be ON; OF; RS; AC where nn is the relay number, nn ranged from 1 to 16 example: ON01 or ON1 <--turn on channel1 OF02 or OF1 <--turn off channel2 RS03 or RS3 <--get the state of channel3 AC <--toggle acknowledge ON of OFF return 0 if output is low return 1 if output high return 2 if send ON successful return 3 if send OFF successful */
#define RELAY1 2 //Arduino Digital 2 #define RELAY2 3 //Arduino Digital 3 PWM #define RELAY3 4 //Arduino Digital 4 #define RELAY4 5 //Arduino Digital 5 PWM #define RELAY5 6 //Arduino Digital 6 PWM #define RELAY6 7 //Arduino Digital 7 #define RELAY7 8 //Arduino Digital 8 #define RELAY8 9 //Arduino Digital 9 #define RELAY9 10 //Arduino Digital 10 #define RELAY10 11 //Arduino Digital 11 #define RELAY11 12 //Arduino Digital 12 //#define RELAY12 13 //Do not use digital 13 since it will blink if usb serial connecting to computer
//you can use the analog pins as digital pins, by numbering them 14 - 19. #define RELAY12 14 //Arduino Digital 14 (Analog 0) #define RELAY13 15 //Arduino Digital 15 (Analog 1) #define RELAY14 16 //Arduino Digital 16 (Analog 2) #define RELAY15 17 //Arduino Digital 17 (Analog 3) #define RELAY16 18 //Arduino Digital 18 (Analog 4)
#define REL_COUNT 16 //how many relay int Relays[REL_COUNT] = {RELAY1, RELAY2, RELAY3, RELAY4, RELAY5, RELAY6, RELAY7, RELAY8, RELAY9, RELAY10, RELAY11, RELAY12, RELAY13, RELAY14, RELAY15, RELAY16};
String inputString = ""; // a string to hold incoming data boolean stringComplete = false; // whether the string is complete boolean ack = false; //whether return status after serial command received
void setup() { for (int i=0;i<REL_COUNT;i++) { pinMode(Relays[i], OUTPUT); // declare Relays as output } Serial.begin(9600); inputString.reserve(5); //reserve 6 bytes for the inputString: Serial.println("Controller Ready."); }
void loop() { // process data when a carriage return arrives: if (stringComplete) { processData(); // clear the string: inputString = ""; stringComplete = false; } }
void processData () { int thisRelay, val; char relayNumber[3], cmd[3]; char inputString2Array[6]; //hold the serial data in array form inputString.trim(); //remove whilte space inputString.toUpperCase(); //covert to upper case inputString.toCharArray(inputString2Array, 6); //convert string to array // first two character is the command cmd[0] = inputString2Array[0]; cmd[1] = inputString2Array[1]; cmd[2] = 0; //null terminate Command = Chr(data(0)) + Chr(data(1))
//next two character is the relay numner (third & forth charcter) relayNumber[0] = inputString2Array[2]; relayNumber[1] = inputString2Array[3]; relayNumber[2] = 0; // null terminate value = Chr(data(2)) + Chr(data(3))
thisRelay = atoi(relayNumber); //convert string to integer if (strcmp(cmd,"ON")==0) { digitalWrite(Relays[thisRelay-1], HIGH); if (ack) Serial.println("2"); } else if (strcmp(cmd,"OF")==0) { digitalWrite(Relays[thisRelay-1], LOW); if (ack) Serial.println("3"); } else if (strcmp(cmd,"RS")==0) { val = digitalRead(Relays[thisRelay-1]); // read the input pin, return 1 if High, return 0 if Low Serial.println(val,DEC); } else if (strcmp(cmd,"AC")==0) { ack = ! ack; if (ack) { Serial.println("Acknowledge on"); } else { Serial.println("Acknowledge off"); } } } // end of processData
/* SerialEvent occurs whenever a new data comes in the hardware serial RX. This routine is run between each time loop() runs, so using delay inside loop can delay response. Multiple bytes of data may be available. */ void serialEvent() { while (Serial.available()) { // get the new byte: char inChar = (char)Serial.read(); // add it to the inputString: inputString += inChar; // if the incoming character is a newline, set a flag // so the main loop can do something about it: if (inChar == '\r') { stringComplete = true; } } }
The above code is a 16 output Arduino Controller this gives an abstraction layer to control the arduino.
Communicate with Arduino
You have finishing install all the required modules/drivers for the router. It is time to test the Arduino.
To control from SSH, use the following code to turn on channel 3.
echo "@00 on 3/r" > /dev/ttyUSB0
RealTerm Communicate with Arduino
- Run realTerm
- Click on Port tab
- Enter 9600 for Baud since the default baud rate for the Arduino is set to 9600
- Enter 192.168.1.1:1234, where 192.168.1.1 is the router IP & 1234 is the port. Make sure it match with the ser2net or socat settings.
- Click on Open button
- Click on Send tab
- Enable +CR from EOL since the Arduino require Carriage Return as the termination.
- Enter @00 on 1 & click on Send ASCII button
You will notice that the LED1 from Arduino is turned on.
- Enter @00 of 1 & click on Send ASCII button to turn off LED1
Install FTDI USB Serial
opkg update opkg install kmod-usb-serial-ftdi
If you are using Teensy or Arduino Uno:
opkg install kmod-usb-acm
If you are using PL2303 based USB/serial adapters
opkg install kmod-usb-serial-pl2303
If you are using CP201x based USB/serial adapters
opkg install kmod-usb-serial-cp210x
Verify USB Serial driver
After install the FTDI usb serial driver, it is advise to verify the driver is installed properly. Plug in Arduino to the USB port of router and execute the following command.
dmesg | grep -i usb
FTDI USB Serial Device converter is attached to ttyUSB0 by default. Unplug the Arduino from the router will display disconnected from ttyUSB0.
Howto: SSH to the Router
- Run PuTTy
- Enter 192.168.1.1 for Host Name (this is the default IP for Openwrt set in TL-WR1043ND)
- Change connection type to SSH
- Click on Open button
- Enter your router username (username is root if you didn't change it)
- Enter your password
Software Serial with the Arduino
This allows us to use the GPIO pins on the arduino to connect to the UART interface of the fingerprint scanner and read the serialised fingerprints.
Note that the code was designed for the Atmega328P on the Arduino Uno. More information: https://www.arduino.cc/en/Reference/SoftwareSerial
Check this section of code to ensure the pins are correct as above:
FPS_GT511C3 fps(4, 5); //software serial pins for Arduino's / Atmega328P's
Troubleshooting
Scanner Not Recognizing your Fingers? There have been issues trying to enroll with the Arduino example code. This is usually due to fingers being dry and not having good contact on the scanner. The timing of your finger on the scanner is a little tricky too. I had to try enrolling a few times before it was able to enroll or identify my finger. This is common with any fingerprint scanner like the one that is on my smartphone. Try re-enrolling your finger.
Hardware Connections Resistors for Logic Level Conversion? The example code was originally used with an Arduino and the GT-511C3. Looking at the datasheet to compare, it looks like it might be 5V tolerant since it does not have 3.3V I/O limitations. If you are having issues using this fingerprint sensor with the resistors, try removing the resistors that were meant to voltage shift the signals. I had a customer that had problems using this with the resistors explained in the Instructable tutorial. When he removed it, he got it to work.
Loose Connections Make sure that there are no loose connections. The last thing to check is the connection between your scanner and Arduino. Each of the fingerprint scanners use the same command protocols so the Arduino example code in the Instructables tutorial can be used for any of the scanners.