0

Thanks for looking into my Arduino code. I'm building an automated sliding draw, and I'm trying to activate the motor with a RFID scanner. The scanner waits for the token, and once it detects a token the motor turns and waits for a limit switch to be detected and stops the motor, then it does the same thing when it detects another RFID token but instead the motor travels in the opposite direction and waits for the opposite limit switch to be hit. I have 2 sets of code. One is just the RFID scanner code which works fine, but it only switches a relay on and off. The other code is for the motor with 2 limit switches with a activation button. That code works too, and the draw opens and closes when you press a button, but it doesn't work with a RFID scanner. So my goal is to implement the RFID scanner code into the automated draw code in order to have a motor that turns and reverses with a RFID token and stops with a limit switch. I'm using an Arduino UNO board, 2 limit switches, a L298N H Bridge motor driver, and a MFRC522 RFID scanner.

Here is a schematic picture: Schematic view of arduino board

Here is the code for the automated draw using 3 buttons (2 limit switch, 1 activation button) and the DC motor:

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 4;     // the number of the pushbutton pin
const int buttonPin3 = 1;     // the number of the pushbutton pin
const int buttonPin2 = 2;     // the number of the pushbutton pin
const int motorPin =  5;      // the number of the LED pin
const int motorPin2 =  6;      // the number of the LED pin

// variables will change:
boolean buttonState = 0;         // variable for reading the pushbutton status
boolean buttonState2 = 0;         // variable for reading the pushbutton status
boolean buttonState3 = 0;   // variable for reading the pushbutton status


int drawPosition = 2;  // Tells progam what position the draw is in


/**
 *  setup inputs for switches and outs for motor pins
 *  serial begin to read the switches to test for errors
 */
void setup() {
    // initialize the pin as an inputs:
    pinMode(motorPin, OUTPUT);
    pinMode(motorPin2, OUTPUT);
    // initialize the pushbutton pin as an input:
    pinMode(buttonPin, INPUT);
    pinMode(buttonPin2, INPUT);
    pinMode(buttonPin3, INPUT);
    Serial.begin(9600);
}

/**
 * this function turns motor foward 
 */
void drawForward() {
     // turn motor foward:
     digitalWrite(motorPin, LOW);
     digitalWrite(motorPin2, HIGH);
}

/**
 * this function turns motor backwards
 */
void drawBackward() {
     // turn motor in other direction:
     digitalWrite(motorPin, HIGH);
     digitalWrite(motorPin2, LOW);  
}

/**
 * Stop the motor form moving
 */
void stopDrawFromMoving() {
  digitalWrite(motorPin, LOW);
  digitalWrite(motorPin2, LOW);

}


/**
 * 
 */
void loop() {
   // read the state of the pushbutton value:
     buttonState = digitalRead(buttonPin);
     buttonState2 = digitalRead(buttonPin2);
   buttonState3 = digitalRead(buttonPin3);



   // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
   if (buttonState == HIGH) {
      drawPosition = 2; 
      Serial.println(F("Front button state is high draw is open")); 
      stopDrawFromMoving();
   }else if (buttonState2 == HIGH) {
      drawPosition = 1;        
      stopDrawFromMoving();
  } 

  if (buttonState3 == HIGH) {
    if( drawPosition  == 1 ){
      drawBackward(); 
      delay(100);      
      drawPosition = 2;
      delay(100);  
    }else if (drawPosition == 2 ) {
      delay(100); 
      drawForward();
      delay(100); 
      drawPosition = 1;       
    }

  }
}

And that code you just read works fine, but it only activates the motor with a push button, but I'm trying to use RFID scanners.

Here is the code where I attempted to put the RFID code and the automated draw code together:

#include <EEPROM.h>     // We are going to read and write PICC's UIDs from/to EEPROM
#include <SPI.h>        // RC522 Module uses SPI protocol
#include <MFRC522.h>  // Library for Mifare RC522 Devices

//setting up inputs for limit switches and outputs for H Bridge motor driver
const int buttonPin = 4;     // the number of the pushbutton pin
const int buttonPin2 = 2;     // the number of the pushbutton pin
const int motorPin =  6;      // the number of the motors H Bridge (L298N) pin
const int motorPin2 =  5;      // the number of the motors H Bridge (L298N) pin


// variables for the state of the limit switches
boolean buttonState = 0;
boolean buttonState2 = 0;
int drawPosition = 2;  // Tells progam what position the draw is in

//this is the function to be called inside the loop. it makes the motor turn foward
void drawForward() {
  // turn H Bridge motor driver on in the foward polarity
  digitalWrite(motorPin, LOW);
  digitalWrite(motorPin2, HIGH);
}
// and this function turns the motor backwards
void drawBackward() {
  // turn H Bridge on with the REVERSED polarity
  digitalWrite(motorPin, HIGH);
  digitalWrite(motorPin2, LOW);
}
//This function is called when the motor needs to STOP moving
void stopDrawFromMoving() {
  //turn H Bridge motor driver OFF by turning both pins to LOW
  digitalWrite(motorPin, LOW);
  digitalWrite(motorPin2, LOW);
}

// Just stuff for the RFID to work
boolean match = false;          // initialize card match to false
boolean programMode = false;  // initialize programming mode to false
int successRead;    // Variable integer to keep if we have Successful Read from Reader
byte storedCard[4];   // Stores an ID read from EEPROM
byte readCard[4];   // Stores scanned ID read from RFID Module
byte masterCard[4];   // Stores master card's ID read from EEPROM
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.

///////////////////////////////////////// Setup ///////////////////////////////////
void setup() {
  // Setting up the digital read for limit switches
  buttonState = digitalRead(buttonPin);
  buttonState2 = digitalRead(buttonPin2);

  //Protocol Configuration for RIFD scanner
  Serial.begin(9600);  // Initialize serial communications with PC
  SPI.begin();           // MFRC522 Hardware uses SPI protocol
  mfrc522.PCD_Init();    // Initialize MFRC522 Hardware
  // This sets the RFID range to Maximum
  mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);
  Serial.println(F("BlueCore Tech Acces Control"));   // For debugging purposes

  // Check if master card defined, if not let user choose a master card
  if (EEPROM.read(1) != 143) {
    Serial.println(F("No Master Card Set"));
    Serial.println(F("Scan A RFID Card to Set as Master Card"));
    do {
      successRead = getID();            // sets successRead to 1 when we get read from reader otherwise 0
    }
    while (!successRead);                  // Program will not go further while you not get a successful read
    for ( int j = 0; j < 4; j++ ) {        // Loop 4 times
      EEPROM.write( 2 + j, readCard[j] );  // Write scanned PICC's UID to EEPROM, start from address 3
    }
    EEPROM.write(1, 143);                  // Write to EEPROM we defined Master Card.
    Serial.println(F("Master Card Set"));
  }
  Serial.println(F("-------------------"));
  Serial.println(F("Master Card's UID = "));
  for ( int i = 0; i < 4; i++ ) {          // Read Master Card's UID from EEPROM
    masterCard[i] = EEPROM.read(2 + i);    // Write it to masterCard
    Serial.print(masterCard[i], HEX);
  }
  Serial.println("");
  Serial.println(F("-------------------"));
  Serial.println(F("Everything Ready"));
  Serial.println(F("Waiting for Keys or cards to be scanned"));
  cycleLeds();    // Everything ready lets give user some feedback by cycling leds
}
///////////////////////////////////////// Main Loop ///////////////////////////////////
void loop () {

//this first chunk of "if" is always setting the variable from iether "1" or "2" depending on what limit switch is closed, this allows the program to REMEMBER what the position of the draw is.
  if (buttonState == HIGH) {   //if the back limit switch is closed, the draw is in the closed (or backward) position
    drawPosition = 2;    //sets the variable to "2" meaning the draw is in the closed position
    Serial.println(F("Front button state is high so draw is open"));
    stopDrawFromMoving();  //this also stopes the motor form moving foward any further
  } else if (buttonState2 == HIGH) { // same principle applies here but its just reversed:
    drawPosition = 1;
    Serial.println(F("Back button state is high draw is open"));
    stopDrawFromMoving();
  }


// THERE IS A ERROR HERE I CANNOT FIX ////////////////////////////////////////////////////////////////////////////THERE IS A ERROR HERE I CANNOT FIX/////////////////////////////////////////THERE IS A ERROR HERE I CANNOT FIX///////////////////////////////////////
//   'getID' was not declared in this scope exit status 1      this happens anywhere inside the loop where there is a mention of the 'getID' function. I though this only happens if you calling a function but it doesnt exist, but it clearly does exist becuase its at the bottom
  do {
    successRead = getID();  // sets successRead to 1 when we get read from reader otherwise 0
    if (programMode) {
    }
    else {
      normalModeOn();     // Normal mode, blue Power LED is on, all others are off
    }
  }
  while (!successRead);   //the program will not go further while you not get a successful read
  if (programMode) {
    if ( isMaster(readCard) ) { //If master card scanned again exit program mode
      Serial.println(F("Master Card Scanned"));
      Serial.println(F("Exiting Programming Mode"));
      Serial.println(F("-----------------------------"));
      programMode = false;
      return;
    }
    else {
      if ( findID(readCard) ) { // If scanned card is known delete it
        Serial.println(F("I know this key, removing..."));
        deleteID(readCard);
        Serial.println("-----------------------------");
      }
      else {                    // If scanned card is not known add it
        Serial.println(F("I do not know this key, adding..."));
        writeID(readCard);
        Serial.println(F("-----------------------------"));
      }
    }
  }
  else {
    if ( isMaster(readCard) ) {   // If scanned card's ID matches Master Card's ID enter program mode
      programMode = true;
      Serial.println(F("Hello Master - Entered Programming Mode"));
      int count = EEPROM.read(0);   // Read the first Byte of EEPROM that
      Serial.print(F("I have "));     // stores the number of ID's in EEPROM
      Serial.print(count);
      Serial.print(F(" record(s) in DATABASE"));
      Serial.println("");
      Serial.println(F("Scan a Card or key to ADD or REMOVE"));
      Serial.println(F("-----------------------------"));
    }
    else {
      if ( findID(readCard) ) {  // If not, see if the card is in the EEPROM
        Serial.println(F("Welcome, Acces Granted"));
        //this is another part from the other code that im trying to implement into the RFID code
        if ( drawPosition  == 1 ) { //if the variale is saying the draw is currently in the FOWARD position
          drawBackward();  //then return it to the BACKWARD position
          delay(100);
          drawPosition = 2;  //then make the variable a "2" so the code remembers what the position of the draw is for next time the RFID scanner is activated
          delay(100);
        } else if (drawPosition == 2 ) {  //same principle under here but its just reversed for when the draw is found in the opposite position and needs to return to the opposite position
          delay(100);
          drawForward();
          delay(100);
          drawPosition = 1;
        }
      }
      else {   // If the token is unknown, show that the ID was not valid and dont do anything else
        Serial.println(F("Acces Denied!"));
      }
    }

  }
  ///////////////////////////////////////// Get PICC's UID ///////////////////////////////////
  int getID() {
    // Getting ready for Reading PICCs
    if ( ! mfrc522.PICC_IsNewCardPresent()) { //If a new PICC placed to RFID reader continue
      return 0;
    }
    if ( ! mfrc522.PICC_ReadCardSerial()) {   //Since a PICC placed get Serial and continue
      return 0;
    }
    // There are Mifare PICCs which have 4 byte or 7 byte UID care if you use 7 byte PICC
    // I think we should assume every PICC as they have 4 byte UID
    // Until we support 7 byte PICCs
    Serial.println(F("Scanned KEY's UID:"));
    for (int i = 0; i < 4; i++) {  //
      readCard[i] = mfrc522.uid.uidByte[i];
      Serial.print(readCard[i], HEX);
    }
    Serial.println("");
    mfrc522.PICC_HaltA(); // Stop reading
    return 1;
  }
  ///////////////////////////////////////// Show reader details ///////////////////////////////////
  void ShowReaderDetails() {
    // Get the MFRC522 software version
    byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
    Serial.print(F("MFRC522 Version: 0x"));
    Serial.print(v, HEX);
    if (v == 0x91)
      Serial.print(F(" = v1.0"));
    else if (v == 0x11)
      Serial.print(F(" = BlueCore Tech. RFID Acces v2.0"));
    else
      Serial.print(F(" (unknown)"));
    Serial.println("");
    // When 0x00 or 0xFF is returned, communication probably failed
    if ((v == 0x00) || (v == 0xFF)) {
      Serial.println(F("WARNING: Communication failure, is the RFID-MFRC522 properly connected?"));
      while (true); // do not go further
    }
  }
  //////////////////////////////////////// Read an ID from EEPROM //////////////////////////////
  void readID( int number ) {
    int start = (number * 4 ) + 2;    // Figure out starting position
    for ( int i = 0; i < 4; i++ ) {     // Loop 4 times to get the 4 Bytes
      storedCard[i] = EEPROM.read(start + i);   // Assign values read from EEPROM to array
    }
  }
  ///////////////////////////////////////// Add ID to EEPROM   ///////////////////////////////////
  void writeID( byte a[] ) {
    if ( !findID( a ) ) {     // Before we write to the EEPROM, check to see if we have seen this card before!
      int num = EEPROM.read(0);     // Get the numer of used spaces, position 0 stores the number of ID cards
      int start = ( num * 4 ) + 6;  // Figure out where the next slot starts
      num++;                // Increment the counter by one
      EEPROM.write( 0, num );     // Write the new count to the counter
      for ( int j = 0; j < 4; j++ ) {   // Loop 4 times
        EEPROM.write( start + j, a[j] );  // Write the array values to EEPROM in the right position
      }
      successWrite();
      Serial.println(F("Succesfully added ID record to DATABASE"));
    }
    else {
      failedWrite();
      Serial.println(F("Failed! There is something wrong with ID or bad DATABASE"));
    }
  }
  ///////////////////////////////////////// Remove ID from EEPROM   ///////////////////////////////////
  void deleteID( byte a[] ) {
    if ( !findID( a ) ) {     // Before we delete from the EEPROM, check to see if we have this card!
      failedWrite();      // If not
      Serial.println(F("Failed! There is something wrong with ID or bad DATABASE"));
    }
    else {
      int num = EEPROM.read(0);   // Get the numer of used spaces, position 0 stores the number of ID cards
      int slot;       // Figure out the slot number of the card
      int start;      // = ( num * 4 ) + 6; // Figure out where the next slot starts
      int looping;    // The number of times the loop repeats
      int j;
      int count = EEPROM.read(0); // Read the first Byte of EEPROM that stores number of cards
      slot = findIDSLOT( a );   // Figure out the slot number of the card to delete
      start = (slot * 4) + 2;
      looping = ((num - slot) * 4);
      num--;      // Decrement the counter by one
      EEPROM.write( 0, num );   // Write the new count to the counter
      for ( j = 0; j < looping; j++ ) {         // Loop the card shift times
        EEPROM.write( start + j, EEPROM.read(start + 4 + j));   // Shift the array values to 4 places earlier in the EEPROM
      }
      for ( int k = 0; k < 4; k++ ) {         // Shifting loop
        EEPROM.write( start + j + k, 0);
      }
      successDelete();
      Serial.println(F("Succesfully removed ID record from DATABASE"));
    }
  }
  ///////////////////////////////////////// Check Bytes   ///////////////////////////////////
  boolean checkTwo ( byte a[], byte b[] ) {
    if ( a[0] != NULL )       // Make sure there is something in the array first
      match = true;       // Assume they match at first
    for ( int k = 0; k < 4; k++ ) {   // Loop 4 times
      if ( a[k] != b[k] )     // IF a != b then set match = false, one fails, all fail
        match = false;
    }
    if ( match ) {      // Check to see if if match is still true
      return true;      // Return true
    }
    else  {
      return false;       // Return false
    }
  }
  ///////////////////////////////////////// Find Slot   ///////////////////////////////////
  int findIDSLOT( byte find[] ) {
    int count = EEPROM.read(0);       // Read the first Byte of EEPROM that
    for ( int i = 1; i <= count; i++ ) {    // Loop once for each EEPROM entry
      readID(i);                // Read an ID from EEPROM, it is stored in storedCard[4]
      if ( checkTwo( find, storedCard ) ) {   // Check to see if the storedCard read from EEPROM
        // is the same as the find[] ID card passed
        return i;         // The slot number of the card
        break;          // Stop looking we found it
      }
    }
  }
  ///////////////////////////////////////// Find ID From EEPROM   ///////////////////////////////////
  boolean findID( byte find[] ) {
    int count = EEPROM.read(0);     // Read the first Byte of EEPROM that
    for ( int i = 1; i <= count; i++ ) {    // Loop once for each EEPROM entry
      readID(i);          // Read an ID from EEPROM, it is stored in storedCard[4]
      if ( checkTwo( find, storedCard ) ) {   // Check to see if the storedCard read from EEPROM
        return true;
        break;  // Stop looking we found it
      }
      else {    // If not, return false
      }
    }
    return false;
  }
  ///////////////////////////////////////// Write Success to EEPROM   ///////////////////////////////////
  void successWrite() {
    Serial.println(F("Write to EEPROM is Succsusful"));
  }
  ///////////////////////////////////////// Write Failed to EEPROM   ///////////////////////////////////
  void failedWrite() {
    Serial.println(F("Failed to write to EEPROM"));
  }
  ///////////////////////////////////////// Success Remove UID From EEPROM  ///////////////////////////////////
  void successDelete() {
    Serial.println(F("Removed from EEPROM"));
  }
  ////////////////////// Check readCard IF it is masterCard   ///////////////////////////////////
  // Check to see if the ID passed is the master programing card
  boolean isMaster( byte test[] ) {
    if ( checkTwo( test, masterCard ) )
      return true;
    else
      return false;
  }

So there's 2 main errors in the second code (the code implementing RFID with my limit switch logic and motor functions.) The first one was quite obvious in the code when I said "ERROR HERE" and the error is a "exit status 1 getID was not declared in this scope." Not sure why this happens, I cant make sense of it. Once that's fixed I can look at the main issue, and that's actually making it work. I have tested the code before I was getting that exit status error and the logic wasn't working. There is probably a better way of putting these to bits of code together but I'm fairly new to programing and I cant figure it out.

Thanks so much for your help ( :

  • The getid issue has been fixed, i simply moved all the functions to the top of the code so the compiler reads them before it gets to the loop code. But the code still isn't working in practice. The tokens are not read at all, but the master card is. The code is trying to turn the motor and do all that code once it detects a token that is known. Any help would be great. – Leeham Jun 18 '18 at 0:25
1

C++ and C only reads function declarations and globals from top to bottom, it will not look ahead to see if any others were defined.

You can put a declaration of the functions you want to use above where you want to use it.

//...
int getID();
///////////////////////////////////////// Main Loop ///////////////////////////////////
void loop () {
//...
  • Usually the Arduino IDE will attempt to generate declarations automatically. – Craig Jun 15 '18 at 20:08
  • thanks, ill try to put them all on top and let you know how it goes – Leeham Jun 16 '18 at 23:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.