Hey guys, i am trying to add the last feature to my NFC Door lock but i am stumped. I wan to implement a button that locks the door (turns the servo) if the door is unlocked. The button will be on the inside of the door and allow me to only lock it from the unlocked position. Can you all point me in the right direction for this function, i have attempted the implementation in my code below:(it allows nothing to happen)
#include <Wire.h>
#include<Servo.h>
#include<SPI.h>
#include<Adafruit_PN532.h>
#include "Servo.h"
#include "Wire.h"
#include "SPI.h"
#include "Adafruit_PN532.h"
#define PN532_IRQ (7)
#define PN532_RESET (3)
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
Servo myservo; // create servo object to control a servo
int servoPin = 9; // servo pin on Arduino
int lockState = 2; // IMPORTANT: if state = 1; locked, state = 2; unlocked
int buttonLock = 5;
int doorLock;
void setup() {
//test this
pinMode(buttonLock, INPUT);
myservo.attach(9);
digitalWrite(5,INPUT_PULLUP); //enable pullups to make pin high
//end test
Serial.begin(115200);
Serial.println("Hello!");
// find Adafruit RFID/NFC shield
nfc.begin();
uint32_t versiondata = nfc.getFirmwareVersion();
if (! versiondata) {
Serial.print("Didn't find PN532 board");
while (1); // halt
}
// Got ok data, print it out!
Serial.print("Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX);
Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC);
Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC);
// Set the max number of retry attempts to read from a card
// This prevents us from waiting forever for a card, which is
// the default behaviour of the PN532.
//nfc.setPassiveActivationRetries(0xFF);
// configure board to read RFID tags
nfc.SAMConfig();
}
//test this
void manuallyUnlock(){
digitalRead(9);
if (lockState == 2){
myservo.write(0); // lock the door
delay(500); // move servo for X second(s)
lockState = 1;
}
}
//end test
//***********LOOP************
unsigned digit = 0;
void loop(void) {
uint8_t success;
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
// Wait for an ISO14443A type cards (Mifare, etc.). When one is found
// 'uid' will be populated with the UID, and uidLength will indicate
// if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
uint32_t cardidentifier = 0;
if (success) {
// Display some basic information about the card
Serial.println("Found an ISO14443A card");
Serial.println("Card detected #");
// turn the four byte UID of a mifare classic into a single variable #
cardidentifier = uid[3];
cardidentifier <<= 8; cardidentifier |= uid[2];
cardidentifier <<= 8; cardidentifier |= uid[1];
cardidentifier <<= 8; cardidentifier |= uid[0];
Serial.println(cardidentifier);
Serial.println("Add this tag # to code");
// repeat this for as many times as you have RFID cards
switch (cardidentifier) {
case 1303311769: // these are the tags numbers
lockUnlock();
delay(2000); // do not allow the card to read for x second(s)
break;
case 1694073287:
lockUnlock();
delay(2000); // do not allow the card to read for x second(s)
break;
case 1694526935:
lockUnlock();
delay(2000); // do not allow the card to read for x second(s)
break;
case 1304635385:
lockUnlock();
delay(2000); // do not allow the card to read for x second(s)
break;
case 1245611012:
lockUnlock();
delay(2000); // do not allow the card to read for x second(s)
break;
case 3723402814:
lockUnlock();
delay(2000); // do not allow the card to read for x second(s)
break;
}
}
}
void lockUnlock() { // locks or unlocks door
myservo.attach(servoPin);
if (lockState == 1) {
myservo.write(180); // unlock the door
delay(500); // move servo for X second(s)
lockState = 2;
}
else if (lockState == 2) {
myservo.write(0); // lock the door
delay(500); // move servo for X second(s)
lockState = 1;
}
myservo.detach();
}
myservo.attach(9);
digitalWrite(5, INPUT_PULLUP); //enable pullups to make pin high
This isn't how you set a pin mode to INPUT_PULLUP. Read the documentation again.
Additionally, you had a good name for the pin, then you use "5"???
void manuallyUnlock() {
digitalRead(9);
You create this function. But it's not called from anywhere. How is the loop() supposed to know when to call it?
Additionally, what did you expect the digitalRead(9) to do? You read the pin and then do nothing with the value.
9 is your servo pin. Reading from it is meaningless. This is why you should always use names for pins. Then it's obvious that you're reading from an output.
Maybe I am misunderstanding you, this is my update. Compilation completes but no servo movement is generated with the button press
#include <Wire.h>
#include<Servo.h>
#include<SPI.h>
#include<Adafruit_PN532.h>
#define PN532_IRQ (7)
#define PN532_RESET (3)
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
Servo myservo; // create servo object to control a servo
int servoPin = 9; // servo pin on Arduino
int lockState = 2; // IMPORTANT: if state = 1; locked, state = 2; unlocked
int buttonLock = 5;
int doorLock;
void setup() {
//test this
pinMode(buttonLock, INPUT_PULLUP);
myservo.attach(servoPin);
//end test
Serial.begin(115200);
Serial.println("Hello!");
// find Adafruit RFID/NFC shield
nfc.begin();
uint32_t versiondata = nfc.getFirmwareVersion();
if (! versiondata) {
Serial.print("Didn't find PN532 board");
while (1); // halt
}
// Got ok data, print it out!
Serial.print("Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX);
Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC);
Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC);
// Set the max number of retry attempts to read from a card
// This prevents us from waiting forever for a card, which is
// the default behaviour of the PN532.
//nfc.setPassiveActivationRetries(0xFF);
// configure board to read RFID tags
nfc.SAMConfig();
}
//test this
void manuallyUnlock(){;
if (lockState == 2){
myservo.write(0); // lock the door
delay(500); // move servo for X second(s)
lockState = 1;
}
}
//end test
//***********LOOP************
unsigned digit = 0;
void loop(void) {
uint8_t success;
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
// Wait for an ISO14443A type cards (Mifare, etc.). When one is found
// 'uid' will be populated with the UID, and uidLength will indicate
// if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
uint32_t cardidentifier = 0;
if (success) {
// Display some basic information about the card
Serial.println("Found an ISO14443A card");
Serial.println("Card detected #");
// turn the four byte UID of a mifare classic into a single variable #
cardidentifier = uid[3];
cardidentifier <<= 8; cardidentifier |= uid[2];
cardidentifier <<= 8; cardidentifier |= uid[1];
cardidentifier <<= 8; cardidentifier |= uid[0];
Serial.println(cardidentifier);
Serial.println("Add this tag # to code");
// repeat this for as many times as you have RFID cards
switch (cardidentifier) {
case 1303311769: // these are the tags numbers
lockUnlock();
delay(2000); // do not allow the card to read for x second(s)
break;
case 1694073287:
lockUnlock();
delay(2000); // do not allow the card to read for x second(s)
break;
case 1694526935:
lockUnlock();
delay(2000); // do not allow the card to read for x second(s)
break;
case 1304635385:
lockUnlock();
delay(2000); // do not allow the card to read for x second(s)
break;
case 1245611012:
lockUnlock();
delay(2000); // do not allow the card to read for x second(s)
break;
case 3723402814:
lockUnlock();
delay(2000); // do not allow the card to read for x second(s)
break;
}
}
if (manuallyUnlock){
digitalRead(buttonLock);
}
}
void lockUnlock() { // locks or unlocks door
myservo.attach(servoPin);
if (lockState == 1) {
myservo.write(180); // unlock the door
delay(500); // move servo for X second(s)
lockState = 2;
}
else if (lockState == 2) {
myservo.write(0); // lock the door
delay(500); // move servo for X second(s)
lockState = 1;
}
myservo.detach();
}
if (directionState == 0){
if (buttonState == HIGH) {
directionState = 1;
for(pos = 0; pos < 180; pos += 1)
{
myservo.write(pos);
delay(15); // waits 15ms to reach the position
}
}
} else if (directionState == 1) {
if (buttonState == HIGH) {
directionState = 0;
for (pos = 180; pos>=1; pos -=1)
{
myservo.write(pos);
delay(15);
}
}
}
Why are you testing buttonState inside the if block and inside the else block? You don't want to do anything unless the switch is pressed, so you should test that FIRST.
Of course, LOW means pressed, when the mode is INPUT_PULLUP, so this code will move the servo when the switch is NOT pressed, which is clearly not what you want to do.