I am definitely not a programmer. I am helping our local history museum with a display. I have a working prototype from some code an 11 year old posted! He will be a great engineer. I need to add multiple cards that get "Authorized Access". This is the working lines for that, how do I add more?
if (strID.indexOf("89:E2:7E:CB") >= 0) { //put your own tap card key;
Serial.println("");
Serial.println("Authorized Access");
Serial.println("");
digitalWrite(A0, HIGH);
delay (5000);
digitalWrite(A0, LOW);
How many cards in total do you need to grant access with ?
I assume that you know their numbers
Probably 10, this is for a museum display for kids. It only needs to light one of two LEDs. Cards need to be programmed and replaced as needed. So, how do I write in multiple cards?
The clumsy, but easy to write way is to write this section of code once for each card number
if (strID.indexOf("89:E2:7E:CB") >= 0) //put your own tap card key;
{
Serial.println("");
Serial.println("Authorized Access");
Serial.println("");
digitalWrite(A0, HIGH);
delay (5000);
digitalWrite(A0, LOW);
}
A better way would be to write
if (strID.indexOf("89:E2:7E:CB") >= 0 || strID.indexOf("second card") >= 0 || strID.indexOf("third card") >= 0) //and so on
{
Serial.println("");
Serial.println("Authorized Access");
Serial.println("");
digitalWrite(A0, HIGH);
delay (5000);
digitalWrite(A0, LOW);
}
an even better way would be to write something like
String cardIDs[] =
{
"89:E2:7E:CB",
"second card",
"third card",
//and so on
};
const byte NUMBER_OF_CARDS = sizeof(cardIDs) / sizeof(cardIDs[0]);
for (int cardNumber = 0; cardNumber < NUMBER_OF_CARDS; cardNumber++)
{
if (cardIDs[cardNumber].indexOf("89:E2:7E:CB") >= 0)
{
Serial.println("");
Serial.println("Authorized Access");
Serial.println("");
digitalWrite(A0, HIGH);
delay (5000);
digitalWrite(A0, LOW);
}
}
even better would be to use C style strings instead of Strings, but I suggest that you use one of the methods above for now
What will determine which LED is lit ?
Wow, thanks! I will play with these and one of these methods will definitely work for them. My concern, after making it work for the museum is the replacement of cards over time so I want to make it easy for them. Last time I wrote any programs was BASIC ![]()
So, there is some "project creep" going on as the requirements change
If you want the museum to be able to add and/or remove valid cards then the programming is going to get more complicated unless they are happy to edit the sketch each time, which is unlikely and undesirable
How complicated do you want things to get ?
Will the system have any form of keyboard/keypad and/or display attached ?
This is the working code. I think they are comfortable editing the card IDs in the sketch. Any other way of doing it? Thanks a lot for your insight.
#include "SPI.h"
#include "MFRC522.h"
#define SS_PIN 10
#define RST_PIN 9
#define LED_PIN A0
#define LED_PIN A1
MFRC522 rfid(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
SPI.begin();
rfid.PCD_Init();
pinMode(A0, OUTPUT);
pinMode(A1, OUTPUT);
Serial.println("I am waiting for card...");
}
void loop() {
// put your main code here, to run repeatedly:
if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial())
return;
// Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
// Serial.println(rfid.PICC_GetTypeName(piccType));
// Check is the PICC of Classic MIFARE type
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println(F("Your tag is not of type MIFARE Classic."));
return;
}
String strID = "";
for (byte i = 0; i < 4; i++) {
strID +=
(rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
String(rfid.uid.uidByte[i], HEX) +
(i != 3 ? ":" : "");
}
strID.toUpperCase();
Serial.print("Tap card key: ");
Serial.println(strID);
delay(1000);
if (strID.indexOf("89:E2:7E:CB") >= 0) { //put your own tap card key;
Serial.println("");
Serial.println("Green LED");
Serial.println("");
digitalWrite(A0, HIGH);
delay (5000);
digitalWrite(A0, LOW);
return;
}
else {
Serial.println("");
Serial.println("Red LED");
Serial.println("");
digitalWrite(A1, HIGH);
delay (5000);
digitalWrite(A1, LOW);
return;
}
}
Yes, several
If you don't want to introduce more hardware such as a keyboard/keypad or screen then one card could be dedicated as a "master" and reading that could trigger other functionality such as adding or deleting authorised cards.
This would also require the use of some storage medium, such as the EEPROM to store the current list of authorised cards so that it would not be affected by a power cut or reset.
As I said, how complicated do you want things to get ?
Let me try out your previous suggestions so I can become more familiar with the process. Then I can post more informed questions. I cannot thank you enough for the help.
Not sure where all that "String" rubbish comes from but I believe this is the project and code from which you should be starting.
Unfortunately, the website hosting the more basic and therefore, more readily adaptable versions of that code, seems to have died. If it helps, I have working version of that more basic code.
Here we go again
I have been deliberately avoiding the discussion of Strings vs strings whilst getting to the core of the requirements as @jek58 has enough to be going on with as it is without introducing more complications
Well, my point is that the code he really wants to start with, to which I linked, does not appear to use "String"s so it would appear they are entirely unnecessary in the first place. ![]()
I am trying to make it simple. That code provides all the functionality of easily adding and removing multiple tags/ cards as well as the basic validation of the correct card. It has some extra stuff to operate a servo as the actuator which can be adapted as required. ![]()
Yes, of course they are, as is the use of Arduino functions and a library if it comes to that, but he already has a starting point so why not build on it instead of the "if I wanted to get there I would not have started from here" which is so often the case with help provided on the forum
The primary aim should be to get something working, not to get something "better" working. The first thing that @jek58 said in the topic was
hence my simplistic suggestions to add more cards that you and I know can be improved on in a number of ways
Well, on the OP, he says:
But then
Well, I simply suggested the answer is to start with a working code which provides "Authorised Access" to multiple cards, which is exactly what I provided. ![]()
The code I am using works perfectly for the project requirements. It is working with only one card. The question is using that code how do they add/replace up to 10 cards?
This seems the best way to do it based on your suggestion. I must have a mistake in my typing. Maybe the pipe? At this point I only have the 2 cards that come with the card. Can you help me with this? I am going to try your first suggestion but as you say it is a bit clumsier. Thank you so much. I haven't done this since BASIC ![]()
This one worked well.
#include "SPI.h"
#include "MFRC522.h"
#define SS_PIN 10
#define RST_PIN 9
#define LED_PIN A0
#define LED_PIN A1
MFRC522 rfid(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
SPI.begin();
rfid.PCD_Init();
pinMode(A0, OUTPUT);
pinMode(A1, OUTPUT);
Serial.println("I am waiting for card...");
}
void loop() {
// put your main code here, to run repeatedly:
if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial())
return;
// Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
// Serial.println(rfid.PICC_GetTypeName(piccType));
// Check is the PICC of Classic MIFARE type
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println(F("Your tag is not of type MIFARE Classic."));
return;
}
String strID = "";
for (byte i = 0; i < 4; i++) {
strID +=
(rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
String(rfid.uid.uidByte[i], HEX) +
(i != 3 ? ":" : "");
}
strID.toUpperCase();
Serial.print("Tap card key: ");
Serial.println(strID);
delay(1000);
if (strID.indexOf("89:E2:7E:CB") >= 0) { //put your own tap card key;
Serial.println("");
Serial.println("Green LED");
Serial.println("");
digitalWrite(A0, HIGH);
delay (5000);
digitalWrite(A0, LOW);
return;
}
if (strID.indexOf("9C:35:4C:23") >= 0) { //put your own tap card key;
Serial.println("");
Serial.println("Green LED");
Serial.println("");
digitalWrite(A0, HIGH);
delay (5000);
digitalWrite(A0, LOW);
return;
}
else {
Serial.println("");
Serial.println("Red LED");
Serial.println("");
digitalWrite(A1, HIGH);
delay (5000);
digitalWrite(A1, LOW);
return;
}
}
Please follow the advice given in the link below when posting code. Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination
.....................................................................................
So, you now have a method that works by repeating the code which is, of course, very inefficient and the list of valid codes is scattered throughout the program
With that under your belt I suggest that you try the third method that I put forward that uses an array of valid card IDs. It is much more efficient as the code is not repeated and the list of valid cards is all in one place in the program so can be edited more easily
As you will have seen in this topic there are much better ways to do what you want, but I still think that it is important to get something working before improving it.
I agree completely but my knowledge of writing code is 40 years old. I like the look of the lines you wrote and can see how much more efficient it is. I haven't been able to make it work in my sketch. Probably spaces or who knows. I really appreciate the help.
Post your best effort and we will help