Objective of the Project
The project is implementation of a smart gate that can be opened either with the proper RFID tag or using a smartphone. When the RFID card is shown to the reader or when the digital button is pressed in smartphone, the door opens. As soon as the card is removed or the switch turned off, the door closes.
Hardware Components
- Arduino Uno 🙂
- ESP8266 WiFi Module
- Stepper Motor
- RFID Reader
- Object Sensor
Software Components
The libraries used are attached below. The zip files have to be unzipped in the Documents/Arduino/Library directory. Apart from these regular Uno IDE, and libraries for Stepper, WiFi, RFID we also need the Blynk app in smartphone. It is available for iPhone from app store and Google play store.
Setup
The UNO is connected to the various components (refer circuit details section below). The physical setup involves a gate on a groove which converts the rotation of stepper motor to the linear movement. The linear groove is attached to a wooden gate and has aluminium panels for aiding the slide motion. The Blynk app is installed and a new project is created. A switch is added to the project with D4 pin as the receiver of the action. The auth code of your blynk project has to be modified in the code. It is better to send a mail and copy it to your code (refer to code section below). Also WiFi details need to be modified in the code. When you download code using Arduino IDE, detach the Rx (otherwise it doesn’t allow download and reports sync errors). Don’t forget to attach the Rx again, otherwise WiFi will not work. Have the serial monitor enabled in Arduino IDE to understand what is going wrong. Also when you run your Blynk project, it should not report that you Arduino is Offline (it means your Arduino is not connected to WiFi and/or your blynk authentication fails)
How it works
The project works as two parts and both are always active.
RFID Mode: It constantly reads from RFID reader for a card. Once a card is sensed, it tries to read the tag of the card and if it is valid, then the door open code is executed. If the tag does not match with intended code, the serial monitor reports error that it is not a valid card.
IOT Mode: Press the switch in blynk and the door opens. If the switch is turned off, then the door closes.
Circuit
Arduino | Components |
5V | Object Sensor (5V), Motor (+) |
GND | GND of WiFi, RFID, Motor (-), Object Sensor |
3.3V | WiFi (VCC, Reset, one more), RFID Reader (3.3V) |
Rx | WiFi Tx |
Tx | WiFi Rx |
2 | Motor (IN1) |
3 | Motor (IN2) |
4 | LED (gets input from Blynk) |
5 | RFID Reader (RST) |
6 | Motor (IN3) |
7 | Object Sensor (DOut) |
9 | Motor (IN4) |
10 | RFID Reader (SDA) |
11 | RFID Reader (MOSI) |
12 | RFID Reader (MISO) |
13 | RFID Reader (SCK) |
Code
#include <Stepper.h> //#define BLYNK_DEBUG #include <AddicoreRFID.h> #include <SPI.h> #define BLYNK_PRINT Serial #include <ESP8266_HardSer.h> #define EspSerial Serial #include <BlynkSimpleShieldEsp8266_HardSer.h> #define uchar unsigned char #define uint unsigned int #define STEPS_PER_MOTOR_REVOLUTION 32 #define STEPS_PER_OUTPUT_REVOLUTION 32 * 64 //2048 //#include <SD.h> //4 bytes tag serial number, the first 5 bytes for the checksum byte uchar serNumA[5]; char auth[] = "authcodefromblynk"; uchar fifobytes; uchar fifoValue; const int chipSelect = 4; AddicoreRFID myRFID; // create AddicoreRFID object to control the RFID module ESP8266 wifi(EspSerial); const int motor=4; const int chipSelectPin = 10; const int NRSTPD = 5; const int ledPin = 8; //Pin for the LED control const int senPin = 7; volatile int dir = 1; String devid = "v169F26D74AB8610"; // change this to fit the number of steps per revolution // for your motor //Maximum length of the array #define MAX_LEN 16 Stepper small_stepper(STEPS_PER_MOTOR_REVOLUTION, 2, 6, 3, 9); int Steps2Take; void setup() { Serial.begin(9600); // start the SPI library: SPI.begin(); EspSerial.begin(115200); pinMode(chipSelectPin,OUTPUT);// Set digital pin 10 as OUTPUT to connect it to the RFID /ENABLE pin digitalWrite(chipSelectPin, LOW); // Activate the RFID reader pinMode(NRSTPD,OUTPUT); // Set digital pin 10 , Not Reset and Power-down digitalWrite(NRSTPD, HIGH); attachInterrupt(0, switchDirection, CHANGE); Blynk.begin(auth, wifi, "WiFi SSID","password"); pinMode(motor,OUTPUT); myRFID.AddicoreRFID_Init(); } void loop() { uchar i, tmp, checksum1; uchar status; uchar internet; uchar str[MAX_LEN]; uchar RC_size; uchar blockAddr; //Selection operation block address 0 to 63 String mynum = ""; str[1] = 0x4400; //Find tags, return tag type status = myRFID.AddicoreRFID_Request(PICC_REQIDL, str); Blynk.run(); internet=digitalRead(motor); if (status == MI_OK ) { Serial.println("RFID tag detected"); Serial.print(str[0],BIN); Serial.print(" , "); Serial.print(str[1],BIN); Serial.println(" "); } //Anti-collision, return tag serial number 4 bytes status = myRFID.AddicoreRFID_Anticoll(str); if (status == MI_OK || internet == HIGH ) { if (status == MI_OK){ checksum1 = str[0] ^ str[1] ^ str[2] ^ str[3]; Serial.println("The tag's number is : "); //Serial.print(2); Serial.print(str[0]); Serial.print(" , "); Serial.print(str[1],BIN); Serial.print(" , "); Serial.print(str[2],BIN); Serial.print(" , "); Serial.print(str[3],BIN); Serial.print(" , "); Serial.print(str[4],BIN); Serial.print(" , "); Serial.println(checksum1,BIN); } // Should really check all pairs, but for now we'll just use the first if(str[0] == 148 ) { myRFID.AddicoreRFID_Halt(); Serial.print("Hello Feroz!\n"); Steps2Take = - (STEPS_PER_OUTPUT_REVOLUTION+200); // Rotate CW 1 turn small_stepper.setSpeed(700); small_stepper.step(Steps2Take); /*String cmd = "AT+CIPSTART=\"TCP\",\""; cmd += "api.pushingbox.com"; // api.thingspeak.com cmd += "\",80"; EspSerial.println(cmd); if(EspSerial.find("Error")){ Serial.println("AT+CIPSTART error"); } String getStr = "GET /pushingbox?devid=v5194E0918906306"; //getStr += devid; getStr +="&status="; getStr += "gate opened through Rfid tag no: "; getStr +=str[0]; getStr += "\r\n\r\n"; // send data length cmd = "AT+CIPSEND="; cmd += String(getStr.length()); EspSerial.println(cmd); if(EspSerial.find(">")){ EspSerial.print(getStr); } else{ EspSerial.println("AT+CIPCLOSE"); // alert user Serial.println("AT+CIPCLOSE"); }*/ delay(5000); Steps2Take = STEPS_PER_OUTPUT_REVOLUTION+200; // Rotate CCW 1 turn small_stepper.setSpeed(700); small_stepper.step(Steps2Take); //software_Reset() ; digitalWrite(motor, LOW); myRFID.AddicoreRFID_Init(); } else if(internet == HIGH ) //You can change this to the first byte of your tag by finding the card's ID through the Serial Monitor { myRFID.AddicoreRFID_Halt(); Serial.print("Hello Feroz!\n"); Steps2Take = - (STEPS_PER_OUTPUT_REVOLUTION+200); // Rotate aCW 1 turn small_stepper.setSpeed(700); small_stepper.step(Steps2Take); /*EspSerial.println("AT+CIPCLOSE"); String cmd = "AT+CIPSTART=\"TCP\",\""; cmd += "api.pushingbox.com"; cmd += "\",80"; //input/Jxyjr7DmxwTD5dG1D1Kv?private_key=gzgnB4VazkIg7GN1g1qA&brewTemp=33.4 EspSerial.println(cmd); // Serial.println(cmd); if(EspSerial.find("Error")){ Serial.println("AT+CIPSTART error"); } String getStr = "GET /pushingbox?devid=v5194E0918906306"; //getStr += devid; getStr +="&status="; getStr += "Gate%opened%by%feroz%through%internet"; getStr += "\r\n\r\n"; // send data length cmd = "AT+CIPSEND="; cmd += String(getStr.length()); EspSerial.println(cmd); EspSerial.println(getStr); if(EspSerial.find(">")){ EspSerial.print(getStr); } else{ EspSerial.println("AT+CIPCLOSE"); // alert user Serial.println("AT+CIPCLOSE"); } */ delay(5000); Steps2Take = STEPS_PER_OUTPUT_REVOLUTION+200; // Rotate CCW 1 turn small_stepper.setSpeed(700); // 700 a good max speed?? small_stepper.step(Steps2Take); //software_Reset() ; digitalWrite(motor, LOW); myRFID.AddicoreRFID_Init(); } else if(str[0] == 245) { //You can change this to the first byte of your tag by finding the card's ID through the Serial Monitor Serial.print("Hello Rose!\n"); } Serial.println(); delay(1000); } myRFID.AddicoreRFID_Halt(); //Command tag into hibernation } void switchDirection() { int reading = digitalRead(senPin); dir = (reading == HIGH) ? -1 : 1; if(dir==-1) // small_stepper.stop(); delay(1000000); //digitalWrite(ledPin, !reading); } void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers { asm volatile (" jmp 0"); }
P.S: This was originally a student project