其实这是第一个实用项目,而且背后的原理不是很难。不过可能因为东西比较多,功能相对完善点吧。
操作是刷卡,如果通过,绿灯亮,蜂鸣器,电机操作。如果失败,红灯亮,蜂鸣器。
核心是一个RFID Card Reader,芯片MFRC522,NXP的。网上有MFRC522的Arduino库,可以直接用。SPI通信。
可以读取到卡号,卡内数据。不过本次为了简单,直接用卡号判断。判断部分不由Arduino直接处理,而是通过串口通信由raspberry pi判断。目的是模拟实际的刷卡系统,Arudino作为IO控制系统,没有直接的网络通信部分,本次由raspberry pi模拟。
Arduino的部分,两个LED灯和蜂鸣器。加上蜂鸣器之后,整体感觉就不太一样。
拍得不是很好,坐上角的是MFRC522读卡器。Arduino和Raspberry Pi通过USB串口通信。
舵机和LCD显示屏,有卡号和通过状态与否的显示。
Raspberry Pi部分的代码不难
import sys
import serial
CARD_IDS = set(['00E1F2A4'])
def determine_device():
'''
determine device with command line arguments
'''
args = sys.argv
if len(args) > 1:
return args[1]
else:
return '/dev/ttyACM0'
def loop(s):
'''
loop
'''
line = s.readline()
if line and line.startswith('CARD_ID: '):
card_id = line[9:-1].strip()
print 'card: [' + card_id + ']'
if card_id in CARD_IDS:
print 'passed'
s.writelines(['T'])
else:
print 'failed'
s.writelines(['F'])
# main function
if __name__ == '__main__':
# wait 1 second
s = serial.Serial(determine_device(), 9600, timeout = 1)
s.open()
try:
while True:
loop(s)
except KeyboardInterrupt:
s.close()
Arduino部分的代码比较多
/******************************
* DOOR LOCK SYSTEM
* Author: XnnYygn
* Date: 2014-10-31
*
******************************
* PIN data sheet
* ===========
* RFRC522 PIN
*
* RST D9
* SS D10
* MOSI D11
* MISO D12
* SCK D13
* ============
* Servo PIN
*
* DATA D6
* ============
* LED PIN
*
* PASSED(green) D7
* FAILED(red) D8
* ============
* BUZZ PIN
*
* VCC D3
* ============
* LCD I2C PIN
*
* SDA A4
* SCL A5
* ============
******************************
* Enjoy~
*/
#include <Servo.h>
#include <SPI.h>
#include <MFRC522.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// SWF stands for STATUS_WAITING_FOR
#define SWF_CARD 0
#define SWF_RESULT 1
#define RFID_SS_PIN 10
#define RFID_RST_PIN 9
#define SERVO_DATA_PIN 6
#define LED_PASSED_PIN 7 // green
#define LED_FAILED_PIN 8 // red
#define BUZZ_PIN 3
////////////////////////////////////////
// variables
////////////////////////////////////////
int workingStatus = SWF_CARD;
int validationResult;
// create MFRC522 controller
MFRC522 mfrc522(RFID_SS_PIN, RFID_RST_PIN);
// servo controller
Servo myServo;
// LCD I2C
LiquidCrystal_I2C lcd(0x27,16,2);
////////////////////////////////////////
// methods
////////////////////////////////////////
void setup() {
// set serial to 9600, same to raspberry pi pySerial
Serial.begin(9600);
// initialize MFRC522
SPI.begin();
mfrc522.PCD_Init();
// initialize servo
// myServo.attach(SERVO_DATA_PIN);
// set pin for LEDs
pinMode(LED_PASSED_PIN, OUTPUT);
pinMode(LED_FAILED_PIN, OUTPUT);
// set pin for buzz
pinMode(BUZZ_PIN, OUTPUT);
// initialize the lcd
lcd.init();
lcd.print("ALL CLEAR!");
}
void loop() {
switch(workingStatus) {
case SWF_CARD:
waitingForCard();
break;
case SWF_RESULT:
waitingForResult();
break;
}
}
void waitingForCard() {
if (!mfrc522.PICC_IsNewCardPresent()) {
return;
}
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
// show card id on LCD
lcd.backlight();
lcd.clear();
// send card id to serial and LCD
Serial.print("CARD_ID: ");
for (byte i = 0; i < mfrc522.uid.size; i++) {
if(mfrc522.uid.uidByte[i] < 0x10) {
Serial.print("0");
lcd.print("0");
}
Serial.print(mfrc522.uid.uidByte[i], HEX);
lcd.print(mfrc522.uid.uidByte[i], HEX);
}
Serial.println();
// change working status
workingStatus = SWF_RESULT;
mfrc522.PICC_HaltA();
}
void waitingForResult() {
if(Serial.available()) {
validationResult = Serial.read();
Serial.print("VALIDATION RESULT: ");
Serial.println(validationResult);
// buzz
analogWrite(BUZZ_PIN, 128);
delay(500);
analogWrite(BUZZ_PIN, LOW);
// set LCD cursor to next line
lcd.setCursor(0, 1);
if(validationResult == 84 /* T */) {
onValidationPassed();
} else {
onValidationFailed();
}
// delay 1 second before next operation
delay(1000);
// return to init status
workingStatus = SWF_CARD;
lcd.noBacklight();
lcd.clear();
lcd.print("ALL CLEAR");
}
}
void onValidationPassed() {
lcd.print("PASSED");
// turn on passed LED
digitalWrite(LED_PASSED_PIN, HIGH);
// turn servo
myServo.attach(SERVO_DATA_PIN);
delay(1000);
myServo.write(180);
delay(1000);
myServo.write(0);
delay(1000);
myServo.detach();
// turn off passed LED
digitalWrite(LED_PASSED_PIN, LOW);
}
void onValidationFailed() {
lcd.print("FAILED");
// turn on failed LED
digitalWrite(LED_FAILED_PIN, HIGH);
delay(1000);
// turn off failed LED
digitalWrite(LED_FAILED_PIN, LOW);
}
总的来说,这个作品简单但是实用。



