Power supply woes

Evening,
I'm having a bit of trouble using an RFID-RC522 sensor in my project. The sensor works fine when my Arduino is powered from my laptop, or from a USB 5V power supply, but when I try and use a generic 12v, 1A power supply I've used in countless other projects, I get very very odd behaviour.

The intended way for the system to work, is that 5 different RFID tags are to be passed over the sensor in order, and as they are some RGB Leds light up. This works fine while on a 5V supply, but at 12V I find that the ardunio hangs/crashes/becomes unresponsive, always consistently 3-4 seconds after I scan the 3rd RFID tag. Once in this state I can't get the arduino to recover by pressing he rest button on it, so have to cycle the power.

I've used this same equipment before in previous projects, that used multiple RFID sensors over SPI and were more about placing a specific tag on a specific sensor, and those ran fine off of my 12V 1A supply, so I really don't know what is happening. Any insight would be great.

/*
* "LUMOS" Puzzle
*
* This puzzle requires the player to place 5 runes that represnt the
* letters of lumos in the correct sequence ontop of a sensor, at which 
* point the RFID tag embedded in the rune is detected by a sensor.
* When all 5 runes have be placed in the right sequence, the puzzle is solved.
*/

// LIBRARIES
// Standard SPI library comes bundled with the Arduino IDE
#include <SPI.h>
// Download and install from https://github.com/miguelbalboa/rfid
#include <MFRC522.h>
//library for controling adressable RGB LED strips via PWM
#include <FastLED.h>

// CONSTANTS
// Reader's Slave Select pin
const byte ssPin = 10;
// Reset pin
const byte resetPin = 9;
// The sequence of NFC tag IDs required to solve the puzzle
const String correctIDs[] = {"704a6d59","30af6d59","10d16d59", "0336e59", "705a6e59"};
// The number of LEDs in the Strip
#define NUM_LEDS 25
// The data pin for the RBG LEDS
#define DATA_PIN 6
// Define the array of leds
CRGB leds[NUM_LEDS];

// GLOBALS
// Initialise a MFRC522 instance representing the reader
MFRC522 mfrc522;
// The tag ID currently detected by the reader
String currentID;
// Running total of how many letters have been solved
int score = 0;
//sawtooth array
int saw[20] = {-2,-1,0,1,2,3,4,5,4,3,2,1,0,-1,-2,-3}; 
//places in saw array
int sawCount1 = 0;
int sawCount2 = 9;
int sawCount3 = 3;
int sawCount4 = 12;
int sawCount5 = 6;

void setup() {

  // Initialise serial communications channel with the PC
  Serial.begin(9600);
  Serial.println(F("Serial communication started"));
  
  // Set the lock pin as output and secure the lock
  pinMode(3, OUTPUT);
  digitalWrite(3,LOW);
  
  // Initialise the SPI bus
  SPI.begin();

  // Initialise the reader
  mfrc522.PCD_Init(ssPin, resetPin);
  
  // Dump some debug information to the serial monitor
  Serial.print(F("Reader #1"));
  Serial.print(F(" initialised on pin "));
  Serial.print(String(ssPin));
  Serial.print(F(". Antenna strength: "));
  Serial.print(mfrc522.PCD_GetAntennaGain());
  Serial.print(F(". Version : "));
  mfrc522.PCD_DumpVersionToSerial();
 
  delay(100);

  FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical

  mfrc522.PCD_Init();
  
  Serial.println(F("--- END SETUP ---"));
}

/**
 * Main loop
 */
void loop() {

  // Assume that the puzzle has not been solved
  boolean puzzleSolved = false;

  // Assume that the tags have not changed since last reading
  boolean changedValue = false;

  // String to hold the ID detected by the sensor
  String readRFID = "";
  
  // If the sensor detects a tag and is able to read it
  if(mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) 
  {
    // Extract the ID from the tag
    readRFID = dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
  }
  
  // If the current reading is different from the last known reading
  if(readRFID != currentID)
  {
    // Set the flag to show that the puzzle state has changed
    changedValue = true;
    // Update the stored value for the sensor
    currentID = readRFID;
    
  }

  // If the changedValue flag has been set the sensor has changed
  if(changedValue)
  {
    // Dump to serial the current state of the sensor
    Serial.print(F("Reader #1"));
    Serial.print(F(" on Pin #"));
    Serial.print(String(ssPin));
    Serial.print(F(" detected tag: "));
    Serial.println(currentID);
    Serial.println(F("---"));
    if (currentID == correctIDs[score])
    {
      Serial.println("correct rune!, please enter next rune");
      score++;
      if (score == 5)
      {
      puzzleSolved = true;
      }
    }
    else if (currentID != NULL && currentID != correctIDs[score - 1])
    {
      Serial.println("invalid rune, reseting");
      score = 0;
    }
  }

  // If the puzzleSolved flag is set, all the tags have been detected
  if(puzzleSolved)
  {
    Serial.print("Puzzle solved!");
    digitalWrite(3,HIGH);             //release the maglock
    while(1)
    {
      twinkle();                      //twinkle forever
    }
  }

  twinkle();                          //give the current lit letters a twinkle
 
  //delay(100); 
}

/**
 * Helper function to return a string ID from byte array
 */
String dump_byte_array(byte *buffer, byte bufferSize) {
  String read_rfid = "";
  for (byte i=0; i<bufferSize; i++) {
    read_rfid = read_rfid + String(buffer[i], HEX);
  }
  return read_rfid;
}

//function to light letters that have been solved, and then twinkle them for a set period of time
void twinkle()
{
    for (int i = 0; i < 25; ++i) // blank LED values first incase of resets
    {
        leds[i] = 0;
    }
    for (int i = 0 ; i < 5 ; i++)
    {
      if (score >= 1)
      {
        leds[i] = CHSV(saw[sawCount1]+89, 255, (saw[sawCount5]*10)+200);
      }
      if (score >= 2)
      {
        leds[i+5] = CHSV(saw[sawCount2]+89, 255, (saw[sawCount3]*10)+200);
      }
      if (score >= 3)
      {
        leds[i+10] = CHSV(saw[sawCount3]+89, 255, (saw[sawCount2]*10)+200);
      }
      if (score >= 4)
      {
        leds[i+15] = CHSV(saw[sawCount4]+89, 255, (saw[sawCount1]*10)+200);
      }
      if (score >= 5)
      {
        leds[i+20] = CHSV(saw[sawCount5]+89, 255, (saw[sawCount4]*10)+200);
      }      
    }
    sawCount1++;
    sawCount2++;
    sawCount3++;
    sawCount4++;
    sawCount5++;
    if (sawCount1 >= 16) { sawCount1 = 0; }
    if (sawCount2 >= 16) { sawCount2 = 0; }
    if (sawCount3 >= 16) { sawCount3 = 0; }
    if (sawCount4 >= 16) { sawCount4 = 0; }
    if (sawCount5 >= 16) { sawCount5 = 0; }
    FastLED.show();
    delay(100);
}

Are you applying 12V to the Vin pin?

Powering through Vin or the power jack means that the Arduino and all peripherals that are on the 5V rail are powered by the onboard 5V regulator. The on board 5V regulator is not heat sinked so will supply limited current before it overheats and shuts down. The recommend max power dissipation for the regulator is 1 Watt. With 12V into the regulator the max current is about 140 mA (1W / (12V - 5V)). The Arduino uses around 50ma of that leaving less than 90mA (max) for everything else. I would use a buck converter to drop the 12V to 5V and connect that to the 5V on the Arduino, bypassing the, weak, 5V regulator. Then the rated current of the DC DC converter is available on the 5V line.

Looking at the MFRC522 data sheet the reader pulls some pretty significant current at times (see table 1 page 3).

groundFungus:
Are you applying 12V to the Vin pin?

Yeah, using the Vin Pin.

Also definitely should have mentioned previously that I am using an Arduino Nano, not an Uno.

groundFungus:
Powering through Vin or the power jack means that the Arduino and all peripherals that are on the 5V rail are powered by the onboard 5V regulator. The on board 5V regulator is not heat sinked so will supply limited current before it overheats and shuts down. The recommend max power dissipation for the regulator is 1 Watt. With 12V into the regulator the max current is about 140 mA (1W / (12V - 5V)). The Arduino uses around 50ma of that leaving less than 90mA (max) for everything else. I would use a buck converter to drop the 12V to 5V and connect that to the 5V on the Arduino, bypassing the, weak, 5V regulator. Then the rated current of the DC DC converter is available on the 5V line.

Looking at the MFRC522 data sheet the reader pulls some pretty significant current at times (see table 1 page 3).

That all makes sense to me and is definitely what I will try next, however I'm still a bit confused. I am powering the MFRC522 via the 3.3v pin, as it is a lot more stable at 3.3V than 5v, but all the other I/O pins to it are still 5V. From looking online this is quite a common practice, so I don't feel this disparity is the issue.

I also don't see why the reader would spike in current draw specifically on the third sensor read, or why when I've had up to 5 of these readers connected simultaneously in prior projects I haven't encountered this issue before.
Again this is probably a good shout, will report back my findings, but I get the feeling this could be something weirder.

Iain531:
Yeah, using the Vin Pin.
Also definitely should have mentioned previously that I am using an Arduino Nano, not an Uno.

That makes things worse (assuming original/classic Nano).
It has almost no heatsink at all.

With 12volt on V-in you can't draw anything from the 5volt pin.
If you do, the regulator shuts down within seconds (if you're lucky), and the Nano will reboot.
Put a print statement, like "booting" in setup(), and you will see.

The 3.3volt pin is internally powered from the 5volt pin, so the above is also valid for that pin.

Don't power anything significant from the 3.3volt pin of a Nano.
It does not have a proper 3.3volt regulator (the Uno does).
You can't draw more than about 30mA from that pin (so no RFID).
Leo..

groundFungus:
The recommend max power dissipation for the regulator is 1 Watt.

But that would assume it had a heat sink!

Iain531:
I am powering the MFRC522 via the 3.3v pin, as it is a lot more stable at 3.3V than 5v, but all the other I/O pins to it are still 5V. From looking online this is quite a common practice, so I don't feel this disparity is the issue.

Don't you? Well, it will probably work until it fails. :grinning:

Let's get this straight! According to the datasheet, the MFRC522 should not be powered with more than 3.6 V and the inputs should not be subjected to more than this.

While I have not done a great deal so far with these, I successfully use one of these level converters to both derive the 3.3 V supply and interface with the correct levels (on the MFRC522 inputs - the outputs drive the Arduino directly).


General advice:
The point is this:

You have an ATmega328 microprocessor chip.

It is intended to run on 5 V. That is the design voltage, at least to use a 16 MHz clock which is what the Nano has. To use USB, it also has a USB interface chip which is - generally - designed to run on the USB voltage which is 5 V. That is 5 V OK? :astonished:

I repeat my "stock" explanation to this question every time. The "Vin" - or "Barrel jack" on a UNO - is nothing more than a legacy "novelty" from the times ten or twenty years ago when 5 V switchmode power supplies were not common as they now are. It allowed you to use unregulated 9 V "plug packs" (US: "Wall warts") which were the common supply for computer "phone" modems and ADSL boxes which contained heat-sinked 7805 regulators. But the regulator on a tiny Nano or even the UNO board has minimal heat-sinking and is only suitable for simple demonstrations of the basic board and a few LEDs.

For protection, there is a diode between the USB connector and the 5 V supply line (which is also the "5V" pin) in the Nano, so plugging 5 V power into the USB jack loses a significant part of a Volt before it gets to the 5 V line. According to the original circuit, this would be a SS1P3L with only 350 mV drop and capable of passing one Amp, but depending on what clone you have, this may be quite different.

So you can simply forget the on-board regulator and "Vin" and when you have a nice regulated supply of 5 V - generally from a switchmode "buck" regulator - you want to convey it to where it is actually required - the "5V" pin and your relay module. :grinning: