2015년 5월 23일 토요일

대문열기 라즈베리파이 + Mini PN532 NFC 리더

라즈베리파이 + NFC 리더 를 이용한 대문열기.

개요 : NFC리더를 통해 스마트폰 또는 RFID 태그 의 UID 를 읽어들여 등록된 UID 인지 검증 후 문을 여는 동작을 한다.

장점 : 열쇠 없이 대문 열기

단점 : 정전시 집에 못들어감, 라즈베리파이에 문제 발생시 집에 못들어감.

하드웨어 준비

준비물 : 라즈베리파이 1개
PN532 NFC 리더 1개
NFC housing : 3D printing    http://www.thingiverse.com/thing:845134
NFC housing 3D 프린트를 원하면 클릭!! 3D Print
인터폰선(4선식) 인터폰 -> 대문 까지.
릴레이 : 1개
다이오드 : 1개
트랜지스터 BC337 : 1개 
저항 1K옴 : 1개

그림1. 전체 회로도


릴레이 부분 확대 사진.


인터폰 에서 대문까지 인터폰선을 연결(본인 집은 약 35미터), 프린팅한 하우징에 PN532 Reader를 장착하고 대문 인터폰 주변에 부착함.
좀 멀어서 통신에 문제가 있지 않을까 걱정 했지만 잘 작동함.




코딩 

NFC Library 설치 : http://gaeranking.blogspot.kr/2015/05/nfc.html 를 참조.

디렉터리 구조 : 

실행파일 
/usr/local/bin
/usr/local/bin/doornfc  >  NFC reader로 부터 수신대기.
/usr/local/bin/dooropen.py  > GPIO 제어하고 문을 연다.
/usr/local/bin/dooropen  > dooropen.py를 호출
/usr/local/bin/addnfc-uid.sh  > NFC UID 정보 수집을 위한 script, 읽은 데이터는
/var/nfc/uid.data에 저장한다.

데이터파일 
/var/nfc/uid.data  > UID 정보를 보관하는 파일.


1. uid.data 파일 만들기

$ sudo mkdir /var/nfc
$ sudo touch /var/nfc/uid.data
$ sudo chown pi /var/nfc/uid.data


2. 실행 스크립트 작성.

$ cat dooropen.py
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.OUT)
GPIO.output(23, True)
time.sleep(0.2)
GPIO.output(23, False)
GPIO.cleanup()
time.sleep(1)
print ("OK")


$ cat dooropen
sudo python /usr/local/bin/dooropen.py 


$ cat addnfc-uid.sh 
#!/bin/bash
echo "Touch your NFC Device to reader"
NFCUID=`nfc-poll | grep UID`
CHECK_DOUBLE=`grep "$NFCUID" /var/nfc/uid.data`
if [ ${#CHECK_DOUBLE} -gt 0 ] ; then
   echo "Your UID is already registered"
else
   echo "$NFCUID" >> /var/nfc/uid.data
   echo "UID registered."
   exit 0
fi


$ cat doornfc
#!/bin/bash

echo $$ > /var/run/doornfc.pid

while [ true ]
do

#  Reading UID from NFC tag
RESULT=`nfc-poll|grep UID`
#echo NFC-READ:$RESULT

if [ ${#RESULT} -eq 0 ]; then
   echo "no data from NFC Reader try again..."
else
   CHECK=`grep "$RESULT" /var/nfc/uid.data`
   echo CHECK-DB:$CHECK

   echo LENGTH_OF_CHECK=${#CHECK}

   if [ ${#CHECK} -gt 0 ]; then
      dooropen
   fi

fi
done


NFC등록

addnfc-uid.sh 를 실행 후 NFC Reader 에 스마트폰 또는 RFID 태그 접촉.

$ addnfc-uid.sh 
Touch your NFC Device to reader
nfc_initiator_target_is_present: Target Released
UID registered.

cat /var/nfc/uid.data 에 방금 접촉한 태그의 UID가 등록 되었다.


릴레이 작동해 보기

등록된 UID 로 릴레이가 작동 하는지 확인해 보자. doornfc 를 실행.

$ /usr/local/bin/doornfc 


NFC Reader에 스마트폰이나 RFID 태그 를 접촉 시키면 릴레이 에서 "딸깍" 하는 소리가 나면 정상 작동 하는것.


2015년 5월 9일 토요일

라즈베리파이 NFC 사용

Step 1. NFC Reader 준비.
 NFC리더는 UART 사용을 위해 점퍼를 0 0 으로 설정 (본인 구매 제품은 땜질 되어 있음)
사진 좌측 상단에

1         1
s0      s1
0        0

으로 인쇄되어 있는데, 사진처럼 s0 + 0, s1 + 0 땜질 되어 있으면  0 0 임,


NFC 리더와 라즈베리파이는 다음과 같이 연결한다.
NFC tx ---> Rpi pin10 (UART rx)
NFX rx ---> Rpi pin8 (UART tx)
송/수신이 바뀔경우 아래와 같이 nfc-poll 을 실행할 경우 에러가 발생한다.(nfc-poll은 Step 1 에서 실행 할 수 없음.)
pi@doorpi ~/libnfc-1.7.1/examples $ sudo ./nfc-poll
/home/pi/libnfc-1.7.1/examples/.libs/lt-nfc-poll uses libnfc 1.7.1
error    libnfc.chip.pn53x    Unexpected PN53x reply!
error    libnfc.driver.pn532_uart    pn53x_check_communication error
lt-nfc-poll: ERROR: Unable to open NFC device.

pinout 에 대한 자세한 정보는 google 에서 검색 해 보시라...


Step 2. 라즈베리파이 UART 통신 enable
기본설정으로 라즈베리파이의 UART는 시스템의 Serial console 용으로 설정되어 외부 장치의 입/출력을 받을 준비가 되어 있지 않다. 아래의 절차를 통해 외부 입/출력이 가능하도록 수정한다.
pi@doorpi ~ $ sudo raspi-config





 8 Advanced Options 선택.


 A8 Serial 선택.


 <No> 선택



 <OK> <Finish>

Raspberry Pi 재부팅.

Step3. libnfc 컴파일


https://bintray.com/nfc-tools/sources/libnfc  에서


libnfc-1.7.1.tar.bz2 를 다운로드.

pi@doorpi ~ $ mkdir libnfc 
pi@doorpi ~ $ cd libnfc/ 
pi@doorpi ~ $ cp libnfc-1.7.1.tar.bz2 ~/libnfc/
pi@doorpi ~ $ bzip2 -d libnfc-1.7.1.tar.bz2
pi@doorpi ~ $ tar -xvf libnfc-1.7.1.tar
libnfc-1.7.1/
libnfc-1.7.1/install-sh
libnfc-1.7.1/CMakeLists.txt
libnfc-1.7.1/aclocal.m4
libnfc-1.7.1/INSTALL
-- snip --

conf 디렉터리 만들고 conf 파일 복사.

pi@doorpi ~ $ mkdir -p /etc/nfc/devices.d

pi@doorpi ~ $ cd libnfc-1.7.1/

sudo cp contrib/libnfc/pn532_uart_on_rpi.conf.sample /etc/nfc/devices.d/pn532_uart_on_rpi.conf
sudo nano /etc/nfc/devices.d/pn532_uart_on_rpi.conf
줄 맨 마지막에  아래의 내용을 추가
allow_intrusive_scan = true

아래와 같이 된다.
pi@doorpi ~ $ cat /etc/nfc/devices.d/pn532_uart_on_rpi.conf
## Typical configuration file for PN532 device on R-Pi connected using UART
## Note: to use UART port on R-Pi, you have to disable linux serial console:
##   http://learn.adafruit.com/adafruit-nfc-rfid-on-raspberry-pi/freeing-uart-on-the-pi
name = "PN532 board via UART"
connstring = pn532_uart:/dev/ttyAMA0
allow_intrusive_scan = true



라즈베리파이를 재부팅.

pi@doorpi / $ sudo reboot


pi@doorpi ~/libnfc-1.7.1 $ sh ./configure --with-drivers=pn532_uart --sysconfdir=/etc --prefix=/usr
fatal: Not a git repository (or any of the parent directories): .git
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
--snip --

Selected drivers:
   acr122_pcsc...... no
   acr122_usb....... no
   acr122s.......... no
   arygon........... no
   pn53x_usb........ no
   pn532_uart....... yes
   pn532_spi.......  no
   pn532_i2c........ no

pn532_uart 를 사용하도록 되었는지 확인.

pi@doorpi ~/libnfc-1.7.1 $ sudo make clean
Making clean in test
make[1]: Entering directory '/home/pi/libnfc-1.7.1/test'
test -z "" || rm -f
test -z "" || rm -f
rm -rf .libs _libs
test -z "" || rm -f
rm -f *.o
--snip --


pi@doorpi ~/libnfc-1.7.1 $ sudo make install all
Making install in libnfc
make[1]: Entering directory '/home/pi/libnfc-1.7.1/libnfc'
Making install in chips
make[2]: Entering directory '/home/pi/libnfc-1.7.1/libnfc/chips'
  CC     libnfcchips_la-pn53x.lo
  CCLD   libnfcchips.la
make[3]: Entering directory '/home/pi/libnfc-1.7.1/libnfc/chips'
--snip --



nfc-poll 을 실행 한 후 리더에 스마트 폰이나 nfc 를 접촉하면 데이터 가 수신된다.
pi@doorpi ~/libnfc-1.7.1 $ cd examples/
pi@doorpi ~/libnfc-1.7.1/examples $ ./nfc-poll
/home/pi/libnfc-1.7.1/examples/.libs/lt-nfc-poll uses libnfc 1.7.1
NFC reader: pn532_uart:/dev/ttyAMA0 opened
NFC device will poll during 30000 ms (20 pollings of 300 ms for 5 modulations)
ISO/IEC 14443A (106 kbps) target:
    ATQA (SENS_RES): 00  04 
       UID (NFCID1): e3  28  ca  de 
      SAK (SEL_RES): 08 
nfc_initiator_target_is_present: Target Released
Waiting for card removing...done.


이제 nfc-poll을 샘플삼아 내게 맞는 코딩을 작성하면 되겠다.

#### PN532 uart for raspberry pi 3 (2016/07/24)

Raspberry pi 3 에서 /dev/AMA0 는 bluetooth 를 위해 사용되고. GPIO를 통한 uart는 /dev/serial0 으로 바뀌었다.

/boot/config.txt 의 맨 마지막 줄에 다음과 같은 라인 추가.
core_freq=250
enable_uart=1

라즈베리파이 재부팅

/etc/nfc/devices.d/pn532_uart_on_rpi.conf  파일내 uart port 변경
pi@raspberrypi:~/libnfc-1.7.1/examples $ cat /etc/nfc/devices.d/pn532_uart_on_rip.conf
## Typical configuration file for PN532 device on R-Pi connected using UART
## Note: to use UART port on R-Pi, you have to disable linux serial console:
##   http://learn.adafruit.com/adafruit-nfc-rfid-on-raspberry-pi/freeing-uart-on-the-pi
allow_intrusive_scan=true
name = "PN532 board via UART"
connstring = pn532_uart:/dev/serial0

####  테스트
pi@raspberrypi:~/libnfc-1.7.1/examples $ ./nfc-poll
/home/pi/libnfc-1.7.1/examples/.libs/lt-nfc-poll uses libnfc 1.7.1
NFC reader: pn532_uart:/dev/serial0 opened
NFC device will poll during 30000 ms (20 pollings of 300 ms for 5 modulations)
ISO/IEC 14443A (106 kbps) target:
    ATQA (SENS_RES): 00  04
       UID (NFCID1): 83  b3  a6  ef
      SAK (SEL_RES): 08
nfc_initiator_target_is_present: Target Released
Waiting for card removing...done.