Using a stepper motor and rfid with motor shield

I'm very new to arduinos (started this week) and I'm working on a project where I want to control a NEMA FLAT 01 Stepper motor using rfid tags (I'm using JOYIT RFID-RC522). I have a motor shield v3 that i'm using to control the motor. I tested the motor and the rfid seperatly and they both work but when I put the code together they don't. I know that they share pins 13, 12, and 11. But I read that the SPI can be turned off so the pins can be used by multiple things.
This is my code:

#include <SPI.h>
#include <MFRC522.h>
#include <Stepper.h>

#define pwmA 3
#define pwmB 11
#define brakeA 9
#define brakeB 8
#define dirA 12
#define dirB 13
#define SS_PIN 10  // Changed to avoid conflict
#define RST_PIN 7

byte nuidPICC[4];
int firstNum = 0;
int pathNum = 0;
const int stepsPerRevolution = 200;
bool junctionFree = 1;
int waitTime = 10000;

Stepper myStepper = Stepper(stepsPerRevolution, dirA, dirB);
MFRC522 rfid(SS_PIN, RST_PIN);

MFRC522::MIFARE_Key key;

void setup() { 
  pinMode(pwmA, OUTPUT);
  pinMode(pwmB, OUTPUT);
  pinMode(brakeA, OUTPUT);
  pinMode(brakeB, OUTPUT);

  digitalWrite(pwmA, HIGH);
  digitalWrite(pwmB, HIGH);
  digitalWrite(brakeA, LOW);
  digitalWrite(brakeB, LOW);
  
  myStepper.setSpeed(60);  
  
  Serial.begin(9600);
  SPI.begin();

  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }

  Serial.println(F("This code scans the MIFARE Classsic NUID."));
  Serial.print(F("Using the following key: "));
  printHex(key.keyByte, MFRC522::MF_KEY_SIZE);

  pinMode(SS_PIN, OUTPUT);
  digitalWrite(SS_PIN, HIGH);  // Ensure RFID is disabled by default
  pinMode(RST_PIN, OUTPUT);
  digitalWrite(RST_PIN, HIGH);  // Ensure RFID is disabled by default
  rfid.PCD_Init();
}
 
void loop() {
  // Start SPI transaction
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));

  // Check if a new card is present
  if (!rfid.PICC_IsNewCardPresent()) {
    SPI.endTransaction();  // End SPI transaction
    delay(50);  // Small delay to prevent SPI bus overload
    return;
  }

  // Verify if the NUID has been read
  if (!rfid.PICC_ReadCardSerial()) {
    SPI.endTransaction();  // End SPI transaction
    delay(50);  // Small delay to prevent SPI bus overload
    return;
  }

  Serial.print(F("PICC type: "));
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  Serial.println(rfid.PICC_GetTypeName(piccType));

  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."));
    SPI.endTransaction();  // End SPI transaction
    delay(50);  // Small delay to prevent SPI bus overload
    return;
  }

  if (rfid.uid.uidByte[0] != nuidPICC[0] || 
      rfid.uid.uidByte[1] != nuidPICC[1] || 
      rfid.uid.uidByte[2] != nuidPICC[2] || 
      rfid.uid.uidByte[3] != nuidPICC[3] ) {
    Serial.println(F("A new card has been detected."));

    for (byte i = 0; i < 4; i++) {
      nuidPICC[i] = rfid.uid.uidByte[i];
    }

    Serial.println(F("The NUID tag is:"));
    Serial.print(F("In hex: "));
    printHex(rfid.uid.uidByte, rfid.uid.size);
    Serial.println();
    Serial.print(F("In dec: "));
    printDec(rfid.uid.uidByte, rfid.uid.size);
    Serial.println();
  } else {
    Serial.println(F("Card read previously."));
  }

  firstNum = rfid.uid.uidByte[0];
  Serial.println(F("PathNum is: "));
  
  if (firstNum == 195) pathNum = 1;
  if (firstNum == 51) pathNum = 2;
  if (firstNum == 179) pathNum = 3;
  if (firstNum == 163) pathNum = 4;
  if (firstNum == 131) pathNum = 5;

  rfid.PICC_HaltA();
  rfid.PCD_StopCrypto1();
  digitalWrite(SS_PIN, HIGH);
  digitalWrite(RST_PIN, LOW);

  SPI.endTransaction();  // End SPI transaction

  delay(50);  // Small delay to allow SPI bus to stabilize

  Serial.print(pathNum);
  switch (pathNum) {
    case 0:
      Serial.println(F("case 0"));
      break;
    case 1:
      Serial.println(F("case 1"));
      junctionFree = 0;
      myStepper.step(44.16 / 1.8);  // Rotate CCW by 44.16 degrees
      Serial.println(F("CCW"));
      delay(waitTime / 10);
      myStepper.step(-44.16 / 1.8); // Rotate CW back to original position
      Serial.println(F("CW"));
      delay(waitTime / 5);
      junctionFree = 1;
      pathNum = 0;
      break;
    case 2:
      Serial.println(F("case 2"));
      junctionFree = 0;
      myStepper.step(32.48 / 1.8);  // Rotate CCW by 32.48 degrees
      delay(waitTime);
      myStepper.step(-32.48 / 1.8); // Rotate CW back
      delay(waitTime / 5);
      junctionFree = 1;
      pathNum = 0;
      break;
    case 3:
      Serial.println(F("case 3"));
      junctionFree = 0;
      delay(waitTime);  // No motor movement, just delay
      junctionFree = 1;
      pathNum = 0;
      break;
    case 4:
      Serial.println(F("case 4"));
      junctionFree = 0;
      myStepper.step(-32.48 / 1.8);  // Rotate CW by 32.48 degrees
      delay(waitTime);
      myStepper.step(32.48 / 1.8); // Rotate CCW back
      delay(waitTime / 5);
      junctionFree = 1;
      pathNum = 0;
      break;
    case 5:
      Serial.println(F("case 5"));
      junctionFree = 0;
      myStepper.step(-90 / 1.8);  // Rotate CW by 90 degrees
      delay(waitTime);
      myStepper.step(90 / 1.8);  // Rotate CCW back
      delay(waitTime / 5);
      junctionFree = 1;
      pathNum = 0;
      break;
  }
}

void printHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

void printDec(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(' ');
    Serial.print(buffer[i], DEC);
  }
}

And it outputs this:
This code scans the MIFARE Classsic NUID.

Using the following key: FF FF FF FF FF FFPICC type: MIFARE 1KB

A new card has been detected.

The NUID tag is:

In hex: C3 D6 43 93

In dec: 195 214 67 147

PathNum is:

1case 1

CCW

CW

The 3 pins run clock, data and chip select. Clock and data can be shared but different chip select pins must be used.

Which one is the chip select: SCK, MOSI, MISO? How do I go about changing the pin? I used code from an example from the MFRC522 library and there they only define SS and RST which I changed to free pins but I'm not sure how to do that for the chip select. Thank you for the help!

Please post datasheet links of the 2 devices.

Chip Select is commonly referred to as the SS pin. Each device on the SPI bus must have a unique pin. This pin gets asserted to inform the device that the communication is intended for them.

1 Like

Thanks! That was what I thought.

Where did you read that? SCK, MOSI and MISO can be shared between several SPI devices ( SPI is a bus ), that are selected by different SS pins. But your stepper isn't a SPI device.

1 Like

The case where you can actually do what you say you have done is so rare, I don't think I have ever seen it work. You need to design a totally separate, new, program that has the logic you want to have, but includes what you learned and the bit of code logic you tested for both devices. And write and test the new program one step at a time.

Stepper Motor: https://joy-it.net/files/files/Produkte/NEMA-FLAT01/NEMA-FLAT01_Datasheet_2022-10-21.pdf

RFID Module: https://joy-it.net/files/files/Produkte/SBC-RFID-RC522/SBC-RFID-RC522_Datasheet_2023-09-11.pdf

Motor shield schematic: https://www.arduino.cc/en/uploads/Main/arduino_MotorShield_Rev3-schematic.pdf

I connected the NSS of the RFID to pin 10 (I also tried it with pin 4 both did not work)
I connected the RST of the RFID to pin 7
MISO -> pin 12
MOSI -> pin 11
SCK -> pin 13

That is a 3.3V RFID device. What board are you using? A Uno? If so, you need a level shifter between the two.

Im using a arduino uno with a motor shield. I connected the RFID module to the 3.3V pin and GND and the steper motor to the 5v pin and GND. is this ok or do i still need a level shifter?

Apart from the fact that you cannot share the SPI pins with the stepper pins, the motorshield V3 isn't an suitable driver for your stepper. This stepper needs a current controlling driver like the A4988.

You still need a level shifter for the digital I/O lines