Problem with method in Arduino

Hello

I am a beginner at programming so I have some troubles with coding.
I have some troubles with a method.

This is my method

  String aStatus(String stat){
     if (stat == "OUT") {
      stat = "IN";
      Serial.print(stat);
     } else if(stat == "IN") {
      stat = "OUT";
      Serial.print("OUT");
     }

I want it to print IN when it is OUT and vice versa.
Am I wrong that if I write

Serial.println(aStatus(OUT))

and run it twice, then the output has to be
IN
OUT

That is what I want it to do atleast.

BTW, I am doing a RFID project, where the system has to note if a tag is checked IN or OUT. If the tag is checked in, it will be checked out when it is read again.

First of all be careful with the String class, it can use up a lot of memory (particularly if you use it the way you do)

Serial.println(aStatus(OUT))

this probably doesn't compile unless you have a 'String' variable called 'OUT' , i figure you mean

Serial.println(aStatus("OUT"))

Then at least your function should print "IN" to the serial port, and anything that is returned from the function (which i don't know, you haven't shown what it returns.
Keep in mind that

String aStatus(String stat){

stat becomes a local variable, and any modifications to it are lost when you exit the function (and the variable is destroyed)
Just at first glance char* would work a lot better for you.

One other thing to be aware of is line-endings.
You may think your String is "OUT", but in fact it is "OUT\n", so the comparison will fail.

The following is my code. I am not sure how I change from String to char, but I just tried to change the String to char, but it did not print anything at the serial monitor.

#include <SPI.h>
#include <MFRC522.h>
#include "SoftwareSerial.h"
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
SoftwareSerial ser(2,3); // RX, TX 
void setup() 
{
  Serial.begin(9600);   // Initiate a serial communication
  ser.begin (115200);
  SPI.begin();      // Initiate  SPI bus
  mfrc522.PCD_Init();   // Initiate MFRC522
  Serial.println("Put RFID Card to Scan...");

 
}
void loop() 
{

  String STATUS = "OUT";
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  {
    return;
  }
  //Show UID on serial monitor
  
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
     
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
     content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  Serial.print(" - Name/Status:    ");
  content.toUpperCase();
  if (content.substring(1) == "FA 65 3A 29" ) //UID of White card
  {
    Serial.print("Ninus Picantus - ");
    Serial.println(aStatus("OUT"));
    delay(3000);
  }
   if (content.substring(1) ==  "6D 91 DD 17" ) // UID of Study card
  {
    Serial.println("Mickey Mouse");
    delay(3000);
  }
   if (content.substring(1) == "9C 3D 51 18" ) // UID of blue tag
  {
    Serial.println("Someone Else");
    
    delay(3000);
  }
   if (content.substring(1) == "C9 17 AF E3" ) //change here the UID of the card/cards that you want to give access
  {
    Serial.println("4-Simon Jones");
    ser.write(4);
    Serial.println();
    
    delay(3000);
  }
   if (content.substring(1) == "D9 4D 0C 1B" ) //change here the UID of the card/cards that you want to give access
  {
    Serial.println("5-Dimitri Levrock");
    ser.write(5);
    Serial.println();
    
    delay(3000);
  }
    if (content.substring(1) ==  "3B 06 A9 1B" ) //change here the UID of the card/cards that you want to give access
  {
    Serial.println("6-Jasmine Joseph");
    ser.write(6);
    Serial.println();
    
    delay(3000);
  }
  }

  char aStatus(char stat){
     if (stat == "OUT") {
      stat = "IN";
      Serial.print(stat);
     } else if(stat == "IN") {
      stat = "OUT";
      Serial.print("OUT");
     }
  }

I want it to print "IN" beside 'Ninus Picantus', when the tag is read. When the tag is read again, it has to print "OUT". I guess the necessary code is the method at the bottom and Ninus Picantus.

BTW, the method has been changed to char, but was String before.

Why don't you use something like

enum status { IN, OUT };

void printStatus(status &stat) {
  if (stat == OUT) {
    stat = IN;
    Serial.println("IN");
  } 
  else {
    stat = OUT;
    Serial.println("OUT");
  }
}

And then

   status stat = IN;
   printStatus(stat);
   printStatus(stat);

to toggle status. Without String at all.

Where should I write this code?
In the setup or like the method?
I tried to write it instead of the method, but it gives an error.

But you shared neither the code, nor the error.

I have shared the code in earlier post.
I would like to know where I should write the code Boffin has written.

However, I will share what I have so far:

#include <SPI.h>
#include <MFRC522.h>
#include "SoftwareSerial.h"
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
SoftwareSerial ser(2,3); // RX, TX 
void setup() 
{
  Serial.begin(9600);   // Initiate a serial communication
  ser.begin (115200);
  SPI.begin();      // Initiate  SPI bus
  mfrc522.PCD_Init();   // Initiate MFRC522
  Serial.println("Put RFID Card to Scan...");

 
}
void loop() 
{

  String STATUS = "OUT";
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  {
    return;
  }
  //Show UID on serial monitor
  
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
     
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
     content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  Serial.print(" - Name/Status:    ");
  content.toUpperCase();
  if (content.substring(1) == "FA 65 3A 29" ) //UID of White card
  {
    Serial.print("Nisanth Elangkumaran - ");
    //Serial.print(aStatus(STATUS));
    delay(3000);
  }
   if (content.substring(1) ==  "6D 91 DD 17" ) // UID of Study card
  {
    Serial.println("Mickey Mouse");
    delay(3000);
  }
   if (content.substring(1) == "9C 3D 51 18" ) // UID of blue tag
  {
    Serial.println("Someone Else");
    
    delay(3000);
  }
   if (content.substring(1) == "C9 17 AF E3" ) //change here the UID of the card/cards that you want to give access
  {
    Serial.println("4-Simon Jones");
    ser.write(4);
    Serial.println();
    
    delay(3000);
  }
   if (content.substring(1) == "D9 4D 0C 1B" ) //change here the UID of the card/cards that you want to give access
  {
    Serial.println("5-Dimitri Levrock");
    ser.write(5);
    Serial.println();
    
    delay(3000);
  }
    if (content.substring(1) ==  "3B 06 A9 1B" ) //change here the UID of the card/cards that you want to give access
  {
    Serial.println("6-Jasmine Joseph");
    ser.write(6);
    Serial.println();
    
    delay(3000);
  }
  }


  enum status {IN, OUT};

  void printStatus(status &stat) {
    if (stat==OUT) {
      stat = IN;
      Serial.println("IN");
    } else {
      stat = OUT;
      Serial.println("OUT");
    }
  }

/*  char aStatus(String stat){
     if (stat == "OUT") {
      stat = "IN";
      Serial.print(stat);
     } else if(stat == "IN") {
      stat = "OUT";
      Serial.print("OUT");
     }
  }*/

The error is

Arduino: 1.8.13 (Windows 10), Board: "Arduino Uno"

Arduino_Uno:90:18: error: variable or field 'printStatus' declared void

void printStatus(status &stat) {

              ^~~~~~

Arduino_Uno:90:18: error: 'status' was not declared in this scope

C:\Users\Bruger\OneDrive\Dokumenter\Arduino\Arduino_Uno\Arduino_Uno.ino:90:18: note: suggested alternative: 'static'

void printStatus(status &stat) {

              ^~~~~~

              static

Arduino_Uno:90:26: error: 'stat' was not declared in this scope

void printStatus(status &stat) {

                      ^~~~

C:\Users\Bruger\OneDrive\Dokumenter\Arduino\Arduino_Uno\Arduino_Uno.ino:90:26: note: suggested alternative: 'strcat'

void printStatus(status &stat) {

                      ^~~~

                      strcat

Multiple libraries were found for "MFRC522.h"

Used: C:\Program Files (x86)\Arduino\libraries\MFRC522-1.4.8

Not used: C:\Program Files (x86)\Arduino\libraries\rfid-master

exit status 1

variable or field 'printStatus' declared void

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

I think you know the structure of Arduino sketch.
enum status and function printStatus() place before setup()
Function call put inside loop() where you need.

I am new at Arduino :slight_smile:
However, it does not do what I want it to do.

My code is shown below

#include <SPI.h>
#include <MFRC522.h>
#include "SoftwareSerial.h"
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
SoftwareSerial ser(2,3); // RX, TX 


  enum status {IN, OUT};

  void printStatus(status &stat) {
    if (stat==OUT) {
      stat = IN;
      Serial.println("IN");
    } else {
      stat = OUT;
      Serial.println("OUT");
    }
  }

void setup() 
{
  Serial.begin(9600);   // Initiate a serial communication
  ser.begin (115200);
  SPI.begin();      // Initiate  SPI bus
  mfrc522.PCD_Init();   // Initiate MFRC522
  Serial.println("Put RFID Card to Scan...");

 
}
void loop() 
{

  String STATUS = "OUT";

  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  {
    return;
  }
  //Show UID on serial monitor
  
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
     
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
     content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  Serial.print(" - Name/Status:    ");
  content.toUpperCase();
  if (content.substring(1) == "FA 65 3A 29" ) //UID of White card
  {
    Serial.print("Ninus Picantus - ");
    status stat = IN;
    printStatus(stat);
    printStatus(stat);
    //Serial.print(aStatus(STATUS));

    delay(3000);
  }
   if (content.substring(1) ==  "6D 91 DD 17" ) // UID of Study card
  {
    Serial.println("Mickey Mouse");
    delay(3000);
  }
   if (content.substring(1) == "9C 3D 51 18" ) // UID of blue tag
  {
    Serial.println("Someone Else");
    
    delay(3000);
  }
   if (content.substring(1) == "C9 17 AF E3" ) //change here the UID of the card/cards that you want to give access
  {
    Serial.println("4-Simon Jones");
    ser.write(4);
    Serial.println();
    
    delay(3000);
  }
   if (content.substring(1) == "D9 4D 0C 1B" ) //change here the UID of the card/cards that you want to give access
  {
    Serial.println("5-Dimitri Levrock");
    ser.write(5);
    Serial.println();
    
    delay(3000);
  }
    if (content.substring(1) ==  "3B 06 A9 1B" ) //change here the UID of the card/cards that you want to give access
  {
    Serial.println("6-Jasmine Joseph");
    ser.write(6);
    Serial.println();
    
    delay(3000);
  }
  }




/*  char aStatus(String stat){
     if (stat == "OUT") {
      stat = "IN";
      Serial.print(stat);
     } else if(stat == "IN") {
      stat = "OUT";
      Serial.print("OUT");
     }
  }*/

My output is:
14:20:36.903 -> Put RFID Card to Scan...
14:20:45.496 -> - Name/Status: Ninus Picantus - OUT
14:20:45.496 -> IN
14:20:50.385 -> - Name/Status: Ninus Picantus - OUT
14:20:50.385 -> IN

When I remove one of the printStatus line, it will print OUT two times instead of IN one of the times.
I would like my output to be like this:
14:20:45.496 -> - Name/Status: Ninus Picantus - OUT
14:20:50.385 -> - Name/Status: Ninus Picantus - IN
14:20:55.461 -> - Name/Status: Ninus Picantus - OUT
14:21:00.285 -> - Name/Status: Ninus Picantus - IN

I don't know how you define the status.
The question was about the work of the status output function.
You can use

printStatus(stat);

or

printStatus(IN);

or

printStatus(OUT);

wherever you need it. The status changes every time the function is called.

I have defined it as stat, which is IN.

My output is the following, when I only have one line of printStatus(stat);
14:42:13.175 -> - Name/Status: Ninus Picantus - OUT
14:42:18.931 -> - Name/Status: Ninus Picantus - OUT
EDIT: The RFID reader has read the tag two times in this case. The second time the tag is read, it has to print 'IN' instead of 'OUT'

This is my code

#include <SPI.h>
#include <MFRC522.h>
#include "SoftwareSerial.h"
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
SoftwareSerial ser(2,3); // RX, TX 


  enum status {IN, OUT};

  void printStatus(status &stat) {
    if (stat==OUT) {
      stat = IN;
      Serial.println("IN");
    } else {
      stat = OUT;
      Serial.println("OUT");
    }
  }

void setup() 
{
  Serial.begin(9600);   // Initiate a serial communication
  ser.begin (115200);
  SPI.begin();      // Initiate  SPI bus
  mfrc522.PCD_Init();   // Initiate MFRC522
  Serial.println("Put RFID Card to Scan...");

 
}
void loop() 
{

  String STATUS = "OUT";

  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  {
    return;
  }
  //Show UID on serial monitor
  
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
     
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
     content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  Serial.print(" - Name/Status:    ");
  content.toUpperCase();
  if (content.substring(1) == "FA 65 3A 29" ) //UID of White card
  {
    Serial.print("Ninus Picantus - ");
    status stat = IN;
    printStatus(stat);
    //Serial.print(aStatus(STATUS));

    delay(3000);
  }
   if (content.substring(1) ==  "6D 91 DD 17" ) // UID of Study card
  {
    Serial.println("Mickey Mouse");
    delay(3000);
  }
   if (content.substring(1) == "9C 3D 51 18" ) // UID of blue tag
  {
    Serial.println("Someone Else");
    
    delay(3000);
  }
   if (content.substring(1) == "C9 17 AF E3" ) //change here the UID of the card/cards that you want to give access
  {
    Serial.println("4-Simon Jones");
    ser.write(4);
    Serial.println();
    
    delay(3000);
  }
   if (content.substring(1) == "D9 4D 0C 1B" ) //change here the UID of the card/cards that you want to give access
  {
    Serial.println("5-Dimitri Levrock");
    ser.write(5);
    Serial.println();
    
    delay(3000);
  }
    if (content.substring(1) ==  "3B 06 A9 1B" ) //change here the UID of the card/cards that you want to give access
  {
    Serial.println("6-Jasmine Joseph");
    ser.write(6);
    Serial.println();
    
    delay(3000);
  }
  }




/*  char aStatus(String stat){
     if (stat == "OUT") {
      stat = "IN";
      Serial.print(stat);
     } else if(stat == "IN") {
      stat = "OUT";
      Serial.print("OUT");
     }
  }*/

Based on your first post, I'd expect that you would keep an array of status for the various cards to know whether they're in or out. Having a local variable with that information doesn't make much sense.

Also, it's confusing to have a function called printStatus that changes the status.

This code always prints OUT.
Define status stat = IN; outside of loop() as a global variable just after enum.
Then it will be IN and OUT after each call of function.

What does your stat variable mean?
You have not one RFID card. Maybe you need an array of status variables - one per card.
I don' know logic of your program.

That helped a lot. Thank you very much. It prints out what I wanted it to print out. :slight_smile:
But I think I am solving my problem wrong.

I am making an attendance system, so I have different cards.
The stat variable means whether the person is in or out of for example work/school etc.

How do I save my the variables in an array?
Can the timestamp be saved in an array as well?

Take a look at an array of struct - you can store the card Id, the timestamp and the current status that way. I'm not sure what the timestamp will do for you though.

I use the timestamp to show when the card is registered in and out of the system.

You set the task incorrectly from the very beginning.
If you have multiple cards, you need an array to store your data. Each element of an array is a structure that contains the card's ID and status (and maybe a time, name, or whatever).

struct RFIDcard {
    long id;
    status stat;
   ...
}

I agree with @wildbill that the printStatus () function should not change the status. This is called a side-effect function. This is bad practice.
When you read an RFID card, you change appropriate status.
The printStatus () function should only print the status.

Yes, I see it went wrong, when reading the other cards.
Should this method be before setup as well?