Button problems.

Hi

I have written a little code to control a servo with a magnetic switch.
The problem that arises is that arduinon not react to the magnetic switch is broken or not.
The reaction is only when RFID is used.

I hope you understand my problem, thanks for your replies!

#include <SoftwareSerial.h>
#include <Servo.h> 
#define TAG_LEN 12

char tag[12] = {'0', '8', '0', '0', 'E', '1', '1', 'A', '3', 'A'};

Servo myservo;
int  val = 0;
int pos = 0;
char code[12]; 
int bytesread = 0; 
int ledRed =  7;
int ledGrn =  12;
const int buttonPin = 4;     // the number of the pushbutton pin
                             // variables will change:
int buttonState = 0;         // variable for reading the pushbutton status
 

#define rxPin 8
#define txPin 9

// RFID reader SOUT pin connected to Serial RX pin at 2400bps to pin8
SoftwareSerial RFID = SoftwareSerial(rxPin,txPin); 
  
void setup()
{ 
  Serial.begin(9600);           // Hardware serial for Monitor 9600bps
  RFID.begin(2400);
  pinMode(2,OUTPUT);            // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin 
  digitalWrite(2, LOW);         // Activate the RFID reader 
  myservo.attach(9);
  pinMode(ledRed, OUTPUT);
  pinMode(ledGrn, OUTPUT);
  pinMode(buttonPin, INPUT);    // initialize the pushbutton pin as an input:  
}


void loop()
{ 

  if((val = RFID.read()) == 10)
  {                                  // check for header 
    bytesread = 0; 
    while(bytesread<10)
    {                                // read 10 digit code 
      val = RFID.read(); 
      if((val == 10)||(val == 13))
      {                              // if header or stop bytes before the 10 digit reading 
        break;                       // stop reading 
      } 
      code[bytesread] = val;         // add the digit           
      bytesread++;                   // ready to read next digit        
    } 

    if(bytesread == 10)
    {                                        // if 10 digit read is complete 
     
        if(strcmp(code, tag) == 0) {
          
          Serial.println("Unlock.");
          
          for(pos = 0; pos < 120; pos += 1)  // goes from 0 degrees to 120 degrees 
          {                                  // in steps of 1 degree 
            myservo.write(pos);              // tell servo to go to position in variable 'pos' 
            delay(10);                       // waits 10ms for the servo to reach the position 
          } 

          digitalWrite(ledGrn, HIGH);
          delay(3000);

          digitalWrite(ledGrn, LOW);
          
          
                                               // read the state of the pushbutton value:
        buttonState = digitalRead(buttonPin);  // check if the pushbutton is pressed.
        Serial.println(buttonState);           // if it is, the buttonState is HIGH:
        
        
        if (buttonState == HIGH) {
          
          Serial.println("Lock.");
          
          for(pos = 120; pos>=1; pos-=1)     // goes from 120 degrees to 0 degrees 
          {                                
          myservo.write(pos);                // tell servo to go to position in variable 'pos' 
          delay(10);                         // waits 10ms for the servo to reach the position 
          }
          
        } 
                 
        }
        else {
        
          Serial.println("Nu var det fel!");
          digitalWrite(ledRed, LOW);
          delay(500);
          digitalWrite(ledRed, HIGH);
        }
      
    }

    bytesread = 0; 
    delay(500);                       // wait for a second
  }

}
void loop()
{
  SoftwareSerial RFID = SoftwareSerial(rxPin,txPin);
  RFID.begin(2400);

You should not be creating a new SoftwareSerial instance, and initializing it on every pass through loop.

The loop function is called many, many, many times a second.

The first line should be moved BEFORE setup. The second line should be moved into setup.

Try that, and see if it improves the situation for you.

Thanks for the fast reply.

I tried what you said, but it did not work.
It seems that the loop would run once then it stops. And started running again when RFID is running.

I write a Serial.print in the begining of the void lopp. It only show me the massages once. :-/

void loop()
{
  if((val = RFID.read()) == 10)
  {
     // All the code...
  }
}

Nothing happens in loop unless RFID.read() returns a 10. Why not?

Even if I write above the if section so it does not work.

In my world this ex, will show me the message test in less than a second. am I wrong?
Ex,

void loop()
{

Serial.println("test");

  if((val = RFID.read()) == 10)
  {
     // All the code...
  }
}

After some research i found that some code in the void loop stops the process to repeat.
It works after deleteing all the code except the buttonstate code.
Why?

After some research i found that some code in the void loop stops the process to repeat.
It works after deleteing all the code except the buttonstate code.
Why?

What code was causing the wait?
What code did you delete?

Hi Paul.

I deleted this section.

  if((val = RFID.read()) == 10)
  {                                  // check for header 
    bytesread = 0; 
    while(bytesread<10)
    {                                // read 10 digit code 
      val = RFID.read(); 
      if((val == 10)||(val == 13))
      {                              // if header or stop bytes before the 10 digit reading 
        break;                       // stop reading 
      } 
      code[bytesread] = val;         // add the digit           
      bytesread++;                   // ready to read next digit        
    } 

    if(bytesread == 10)
    {                                        // if 10 digit read is complete 
     
        if(strcmp(code, tag) == 0) {
          
          Serial.println("Unlock.");
          
          for(pos = 0; pos < 120; pos += 1)  // goes from 0 degrees to 120 degrees 
          {                                  // in steps of 1 degree 
            myservo.write(pos);              // tell servo to go to position in variable 'pos' 
            delay(10);                       // waits 10ms for the servo to reach the position 
          } 

          digitalWrite(ledGrn, HIGH);
          delay(3000);

          digitalWrite(ledGrn, LOW);
          
          
                                               // read the state of the pushbutton value:
        buttonState = digitalRead(buttonPin);  // check if the pushbutton is pressed.
                                               // if it is, the buttonState is HIGH:        
        if (buttonState == HIGH) {
          
          Serial.println("Lock.");
          
          for(pos = 120; pos>=1; pos-=1)     // goes from 120 degrees to 0 degrees 
          {                                
          myservo.write(pos);                // tell servo to go to position in variable 'pos' 
          delay(10);                         // waits 10ms for the servo to reach the position 
          }
          
        } 
                 
        }
        else {
        
          Serial.println("Nu var det fel!");
          //digitalWrite(ledRed, LOW);
          //delay(500);
          //digitalWrite(ledRed, HIGH);
        }
      
    }

    bytesread = 0; 
    delay(500);                       // wait for a second
  }

That block of code, specifically the if test at the top, means that nothing happens until an RFID tag is seen by the RFID reader.

You could (and should) structure your code better:

void loop()
{
    // If an RFID tag was waved by
    {
        // Do something
    }

    // If a button was pushed
    {
        // Do something else
    }
}

Your are embedding the "If a button was pushed" code inside the "If an RFID tag was waved by" block.

Even if I split the rfid with the button code, it does not work.

void loop(){ 
  
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {     
    // turn LED on:    
    digitalWrite(ledRed, HIGH);

  } 
  else {
    // turn LED off:
    digitalWrite(ledRed, LOW); 
  }

  
  rfid();

}

void rfid(){

  if((val = RFID.read()) == 10)
  {                                  // check for header 
    bytesread = 0; 
    while(bytesread<10)
    {                                // read 10 digit code 
      val = RFID.read(); 
      if((val == 10)||(val == 13))
      {                              // if header or stop bytes before the 10 digit reading 
        break;                       // stop reading 
      } 
      code[bytesread] = val;         // add the digit           
      bytesread++;                   // ready to read next digit        
    } 

    if(bytesread == 10)
    {                                        // if 10 digit read is complete 
     
        if(strcmp(code, tag) == 0) {
          
          Serial.println("Unlock.");
          
          for(pos = 0; pos < 120; pos += 1)  // goes from 0 degrees to 120 degrees 
          {                                  // in steps of 1 degree 
            myservo.write(pos);              // tell servo to go to position in variable 'pos' 
            delay(10);                       // waits 10ms for the servo to reach the position 
          } 

          digitalWrite(ledGrn, HIGH);
          delay(3000);

          digitalWrite(ledGrn, LOW);
          
          
                                               // read the state of the pushbutton value:
        buttonState = digitalRead(buttonPin);  // check if the pushbutton is pressed.
                                               // if it is, the buttonState is HIGH:        
        if (buttonState == HIGH) {
          
          Serial.println("Lock.");
          
          for(pos = 120; pos>=1; pos-=1)     // goes from 120 degrees to 0 degrees 
          {                                
          myservo.write(pos);                // tell servo to go to position in variable 'pos' 
          delay(10);                         // waits 10ms for the servo to reach the position 
          }
          
        } 
                 
        }
        else {
        
          Serial.println("Nu var det fel!");
          //digitalWrite(ledRed, LOW);
          //delay(500);
          //digitalWrite(ledRed, HIGH);
        }
      
    }

    bytesread = 0; 
    delay(500);                       // wait for a second
  }

}

Even if I split the rfid with the button code, it does not work.

This code looks better. There are still some improvements that could be made, like unlocking the door in a separate function.

But, "it does not work" doesn't tell us anything, except that you are frustrated.

Specifically, what do you want to happen, what actually happens, and how does what happens or fails to happen differ from what you want to have happen?

The components used are parallax RFID reader, a servo, and a magnetic switch.
All this will be mounted on my office door.
When you sweep with RFID Tag so the door will be unlocked by using the servo. Magnetic switches will be read by the door to see if the door is open or closed. If the door is open so as not to servos locking the door. But if the magnetic switch is closed, so the door will be locked after about 4 sec.

There are magnetic switch that is my problem. With the RFID code in void loop does not work magnetic switch as it should.
I want to get it to the AVR reads the magnetic switch was 0.5 sec, but with the RFID code in the loop as read only magnetic switch when a sweep in front of RFID tag reader.

I hope this will make little clarity over the issue.

Nobody who knows?

In the rfid function, nothing happens unless an rfid tag is read. When a tag is read, and determined to be valid, you move the servo, light the green LED, and wait 3 seconds.

Then, you turn the green LED off, and read the switch.

If the switch is pressed, you move the servo.

The rfid function

In the loop function, you read the same switch state. If it is pressed, the red LED is turned on. Otherwise, the red LED is turned off.

Are you saying that with rfid() commented out, the switch and red LED operate correctly, but with the rfid function being called they do not?

Exactly.
When the RFID function is not commented. Does magnetic switch only work when a RFID tag reader sweeps past, or when power to arduinon broken and re-turned on.

Another exemple is when I enable rfid function and just write an simple Serial.print in the top of the void loop. I get only one massage from the Serial, and that is when a apply current to arduino or swep an rfid card.
In my world I should get a massages every half a sec.

Add two serial print statements to rfid.

void rfid()
{
   Serial.println("rfid ==>");

   // all the existing code

   Serial.println("rfid <==");
}

See if rfid() blocks, waiting for input. I'm betting that it does.

Yes the rfid is waiting for input.
I got only "rfid ==>"
until I swept the rfid tag and then i got the "rfid <==".
How do I get rid of the waiting for input?

You could use the NewSoftSerial library, instead of SoftwareSerial. The NewSoftSerial library has a method, available(), that determines whether there is data to read. If not, return. If there is, read it.

Data will only be available when the RFID tag has been waved by.

Hi Paul.

I'm using the NewSoftSerial library, and it works much better now.
But now I have a miner problem, I can't get the RFID reader function properly.
Every time I swep an rfid tag i get:

Wrong!
ÿÿÿÿÿÿÿÿÿÿ

Wrong!
ÿÿÿÿÿÿÿÿÿÿ

Right!
0800E11A3A

I have no idée what can be the problem.

Thank you so much so far for your help Paul!

Does it work any better if you use the hardware serial port to communicate with the RFID reader, and the software serial port to communicate with the PC?