RFID Reader Loses Range When LED Dot Matrix is Connected

Hey there, I could use some troubleshooting help with this. I have a build that uses an Arduino Nano, two led's, a piezo buzzer, an 8x64 Dot Matrix LED Display Module, and a 134.2K AGV RFID Reader. This is the type of RFID reader for animal microchips and I'm using it on a build that interacts with my dogs. More for a personal POC to see what I can do with it.

My issue is that the RFID Reader range drops in half when the dot matrix is connected. So basically, without the Dot Matrix, the range on my reader is great, exactly what I need. If I turn it off, plug in the Dot Matrix, everything works as expected, but the range cuts down significantly.

This is my first more-complex build with more than one power supply, but I'm thinking this is because there's a drop in current to the RFID Reader, right? I'm confused why that would happen when they don't share the same power supply as the RFID Reader is on its own 9v battery, while everything else is on the 5v power supply from the microcontroller. I've looked all over for why this might be happening, but can't seem to figure it out, so I thought I would reach out to the community for help.

Thanks, y'all. Below is a schematic I made with some of the more obscure pieces pasted in as photos. The RFID reader and Dot matrix are both linked above for reference.

I'll also post my code below, even though I don't think it's as relevant. To give you a brief overview, my loop is constantly looking for a RFID signal. When it gets one, it reads it, parses it into a decimal ID, then checks it against my hard-coded decimal values for my dogs. Depending on which dog (or a test chip I have) it picks up, it will flash a light for that dog, display their name on the LED matrix, and play a song from the piezo buzzer.

/*************************************************
   NOTE FREQUENCYS
   *************************************************/
#define B0  31
#define C1  33
#define CS1 35
#define D1  37
#define DS1 39
#define E1  41
#define F1  44
#define FS1 46
#define G1  49
#define GS1 52
#define A1  55
#define AS1 58
#define B1  62
#define C2  65
#define CS2 69
#define D2  73
#define DS2 78
#define E2  82
#define F2  87
#define FS2 93
#define G2  98
#define GS2 104
#define A2  110
#define AS2 117
#define B2  123
#define C3  131
#define CS3 139
#define D3  147
#define DS3 156
#define E3  165
#define F3  175
#define FS3 185
#define G3  196
#define GS3 208
#define A3  220
#define AS3 233
#define B3  247
#define C4  262
#define CS4 277
#define D4  294
#define DS4 311
#define E4  330
#define F4  349
#define FS4 370
#define G4  392
#define GS4 415
#define A4  440
#define AS4 466
#define B4  494
#define C5  523
#define CS5 554
#define D5  587
#define DS5 622
#define E5  659
#define F5  698
#define FS5 740
#define G5  784
#define GS5 831
#define A5  880
#define AS5 932
#define B5  988
#define C6  1047
#define CS6 1109
#define D6  1175
#define DS6 1245
#define E6  1319
#define F6  1397
#define FS6 1480
#define G6  1568
#define GS6 1661
#define A6  1760
#define AS6 1865
#define B6  1976
#define C7  2093
#define CS7 2217
#define D7  2349
#define DS7 2489
#define E7  2637
#define F7  2794
#define FS7 2960
#define G7  3136
#define GS7 3322
#define A7  3520
#define AS7 3729
#define B7  3951
#define C8  4186
#define CS8 4435
#define D8  4699
#define DS8 4978
#define Silence 0

// DEFINITION FOR LED MATRIX
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 8
#define CS_PIN 3

// FOR THE PIEZO:
#include <LowPower.h>
#include <Wire.h>

// FOR THE LED MATRIX DISPLAY:
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

MD_Parola ledMatrix = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

int val; // variable for analogread piezo
int knockPin = 2; //interrupt on pin 2 or 3
volatile int interruptSwitch = 0;

int redLedPin = 7;
int blueLedPin = 8;
int lastPin1State,lastPin2State;

int anastasiaMelody[] = {
  FS4, G4, FS4, A4, G4, E4, G4, E4, FS4, D4, B3, E4, FS4,
  FS4, G4, FS4, FS4, B4, E4, G4, E4, FS4, D4, B3, CS4, D4, B3,
};

// note durations: 2 = whole note, 3 = dotted half note, 4 = half note, 8 = quarter note, 16 = eighth note, etc.:
int anastasiaNoteDurations[] = {
  4, 8, 3, 4, 8, 3, 4, 8, 6, 16, 8, 3, 3,  
  4, 8, 3, 4, 8, 3, 4, 8, 6, 16, 8, 4, 8, 3
};

int gotMelody[] = {
    G4, C4, DS4, F4, G4, C4, DS4, F4, G4, C4, DS4, F4, G4, C4, DS4, F4,
    G4, C4, E4, F4, G4, C4, E4, F4, G4, C4, E4, F4, G4, C4, E4, F4, 
    G4, C4, DS4, F4, G4, C4, DS4, F4, D4,
};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int gotNoteDurations[] = {
  8, 8, 16, 16, 8, 8, 16, 16, 8, 8, 16, 16, 8, 8, 16, 16,
  8, 8, 16, 16, 8, 8, 16, 16, 8, 8, 16, 16, 8, 8, 16, 16,
  3, 3, 16, 16, 4, 4, 16, 16, 1,
};

int testMelody[] = {
  C5
};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int testNoteDurations[] = {
  32
};

int unknownMelody[] = {
  C2, C2,
};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int unknownNoteDurations[] = {
  8, 2,
};

int anastasiaMelodyLength = sizeof(anastasiaMelody)/sizeof(anastasiaMelody[0]);
int gotMelodyLength = sizeof(gotMelody)/sizeof(gotMelody[0]);
int testMelodyLength = sizeof(testMelody)/sizeof(testMelody[0]);
int unknownMelodyLength = sizeof(unknownMelody)/sizeof(unknownMelody[0]);
int tempo = 2100;


// interrupt function
void Interrupt ()
{
  interruptSwitch = 1;
  detachInterrupt (knockPin);
}

char message[35];
unsigned long lastSignal = 0;
bool transmission = false;
byte state = 1;
int pos;

unsigned long testCard = 2152500911;
unsigned long picaId = 2855817755;
unsigned long theoId = 2861165065;

void setup() {
  Serial.begin(9600);
  lastSignal = millis();
  ledMatrix.begin();
  ledMatrix.setIntensity(0);
  ledMatrix.displayClear();
  pinMode(13, OUTPUT);
  pinMode(redLedPin, OUTPUT);
  pinMode(blueLedPin, OUTPUT);
  ledMatrix.setTextAlignment(PA_CENTER);
  ledMatrix.print("PRESENTING:");
}

void loop() {
  switch (state) {
    case 1: {
        if (Serial.available() > 0) {
          lastSignal = millis();
          pos = 0;
          state = 2;
        }
        break;
      }
    case 2: {
        // Reading of message
        if (Serial.available() > 0 && pos < 35) {
          lastSignal = millis();
          message[pos] = Serial.read();
          pos++;
        }
        if (millis() - lastSignal > 100) {
          state = 3;
        }
        if (pos >= 35) {
          delay(300);
          state = 1;
        }
      break;
      }
    case 3: {
        // checksum
        Serial.println();
        byte check = message[1];
        for (int i = 2; i < 27; i++) {
          check = check ^ message[i];
        }
        Serial.println();
        if (check == message[27]) {
          unsigned long id = hexInDec(message, 1, 10);
          int countryNbr = hexInDec(message, 11, 4);

          Serial.print("CardNumber=");
          Serial.println(id);
          Serial.print("Country=");
          Serial.println(countryNbr);

          if (id == testCard) {
            Serial.println("Test Card Scanned");
            ledMatrix.setTextAlignment(PA_CENTER);
            ledMatrix.print("TEST OK");
            blinkLedTest(blueLedPin, redLedPin);
            for (int thisNote = 0; thisNote < testMelodyLength; thisNote++) {
              int noteDuration = tempo / testNoteDurations[thisNote];
              tone(2, testMelody[thisNote], noteDuration);
              int pauseBetweenNotes = noteDuration * 1.30;
              delay(pauseBetweenNotes);
              noTone(8);
            }
            delay(1000);
            ledMatrix.print("PRESENTING:");
          }
          else if (id == picaId) {
            Serial.println("Pica Scanned");
            ledMatrix.setTextAlignment(PA_CENTER);
            ledMatrix.print("PICA");
            blinkLed(blueLedPin);
            for (int thisNote = 0; thisNote < anastasiaMelodyLength; thisNote++) {
              int noteDuration = tempo / anastasiaNoteDurations[thisNote];
              tone(2, anastasiaMelody[thisNote], noteDuration);
              int pauseBetweenNotes = noteDuration * 1.30;
              delay(pauseBetweenNotes);
              noTone(8);
            }
            ledMatrix.print("PRESENTING:");
          }
          else if (id == theoId) {
            Serial.println("Theo Scanned");
            ledMatrix.setTextAlignment(PA_CENTER);
            ledMatrix.print("THEO");
            blinkLed(redLedPin);
            for (int thisNote = 0; thisNote < gotMelodyLength; thisNote++) {
              int noteDuration = tempo / gotNoteDurations[thisNote];
              tone(2, gotMelody[thisNote], noteDuration);
              int pauseBetweenNotes = noteDuration * 1.30;
              delay(pauseBetweenNotes);
              noTone(8);
            }
            ledMatrix.print("PRESENTING:");
          }
          else {
            Serial.println("Unrecognized ID Scanned");
            ledMatrix.setTextAlignment(PA_CENTER);
            ledMatrix.print("UNKNOWN");
            for (int thisNote = 0; thisNote < unknownMelodyLength; thisNote++) {
              int noteDuration = tempo / unknownNoteDurations[thisNote];
              tone(2, unknownMelody[thisNote], noteDuration);
              int pauseBetweenNotes = noteDuration * 1.30;
              delay(pauseBetweenNotes);
              noTone(8);
            }
            ledMatrix.print("PRESENTING:");
          }
          state = 4;
        }
        break;
      }
    case 4: {
        delay(2000);
        state = 1;
        break;
      }
  }
}

void blinkLed(int pin) {
    digitalWrite(pin, HIGH);
    delay(500);
    for(int i = 0; i < 3; i++) {
      digitalWrite(pin, LOW);
      delay(100);
      digitalWrite(pin, HIGH);
      delay(100);
    }
    digitalWrite(pin, LOW);
}

void blinkLedTest(int pin1, int pin2) {
    digitalWrite(pin1, HIGH);
    digitalWrite(pin2, HIGH);
    delay(500);
    for(int i = 0; i < 3; i++) {
      digitalWrite(pin1, LOW);
      digitalWrite(pin2, LOW);
      delay(100);
      digitalWrite(pin1, HIGH);
      digitalWrite(pin2, HIGH);
      delay(100);
    }
    digitalWrite(pin1, LOW);
    digitalWrite(pin2, LOW);
}

unsigned long hexInDec(char message[], int beg , int len) {
  unsigned long mult = 1;
  unsigned long nbr = 0;
  byte nextInt;

  for (int i = beg; i < beg + len; i++) {
    nextInt = message[i];
    if (nextInt >= 48 && nextInt <= 57) {
      nextInt = map(nextInt, 48, 57, 0, 9);
    }
    if (nextInt >= 65 && nextInt <= 70) {
      nextInt = map(nextInt, 65, 70, 10, 15);
    }
    if (nextInt >= 97 && nextInt <= 102) {
      nextInt = map(nextInt, 97, 102, 10, 15);
    }
    nextInt = constrain(nextInt, 0, 15);
    nbr = nbr + (mult * nextInt);
    mult = mult * 16;
  }
  return nbr;
}

EDIT: Accidentally initially posted this to the wrong forum

Get you DVM out and begin to measure voltages and current draw as you change things.

Better dont use the 5V output of the Arduino board as the power supply for the led matrix. I also doubt the 9V battery will last long; it's better to use a power supply that can source more current. I best that rfid module is pretty inefficient and as a result can probably draw a surprisingly high (momentary) current.

1 Like

How close is the display to the reader? You may be getting RF interference from the display. The scan rate is in the audio range, but the sharp current pulses driving the LEDs could be a problem. The MAX7219 data sheet suggests bypassing the power with 10uf and 0.1uf capacitors. The first is for the bulk power and the second may help with RF. I have never seen these on the common cheap displays.

As noted above, the 9 volt battery will not last long with the 120ma current draw of the reader. It would be better to get another 6xAA battery holder like you are using on the Arduino.

1 Like

That LED display can pull upwards of 2A at max brightness with all LEDs let. You're NOT going to be able to run that off AA batteries. Get a REAL AC/DC power supply. I like these:


I get them from Jameco for $22 each. They really make a difference when powering your projects. I added an ammeter:

and matching 2.1x5.5mm plugs and jacks so everything just snaps together.
2_1x5mm
You're also going to need an isolation switch in the USB RED wire. This will prevent your project from trying to power up your computer via the USB port if you turn on your project before the computer,

Would a Schottky diode be an acceptable substitute for a switch?

If you put in a blocking diode you'll lose .7V (instead of 5.0V, you get 4.3V) when powered by the USB port. This can cause some devices to get silly.
I 3D printed a box and used a $2 SPDT toggle switch.

Apparently you have not looked! :thinking:


See that capacitor in the bottom left ? That i s the 0.1 µF on every module. No, they don't have the 10 µF on the FC-16 modules as they do on the old ones.

Not if you want to light up many LEDs. A completely lit (8 by 8) matrix would be about 320 mA and the regulator on the UNO would almost certainly shut down. Let alone eight matrices as madmark mentions.

Which devices?

The diode is exactly what the Nano uses. Mind you, it is supposed to be a Schottky.

IR receiver for one is very fussy about supply voltages. Different devices react differently and can kick in and out, dynamically altering the load. A relay, for instance can chatter when it kicks in it loads down the PS to the point where it drops out, the load goes away and the PS recovers only to repeat the cycle.

Yes RFID readers can be prone to interference from many sources. Basically they are a low frequency radio receivers and so by definition are trying to pick up the sort of interference your are generating by the Dot matrix multiplexing.

You need good supply decoupling on the power input to your RFID reader for a start see http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html
Maybe even use the schematics with inductors. The other thing is you must keep your display well away from your coil antenna.

I used to design RFID readers for a living so I know how much interference can deafen your RFID receiving of signals. We could always get a great range on the bench with the micro controller doing the decoding was separated from the coil. But the marketing lads always wanted a compact reader which inevitably meant putting the coil round the electronics which drastically reduced the range. So what you are seeing is only to be expected.

The other thing is that you could change your display to one that didn't produce so much interference. Like an LCD or the ultimate in lack of emissions is the ePaper display Electronic paper, because they only produce emissions when they change what is being displayed so any interference they cause is only temporary.

There are a variety of these available like this one. inky phat

1 Like

I ended up doing just this. I tried distancing the dot matrix from the antenna, but still didn't get the range I wanted, so I switched my display to a classic 16x2 LCD display, which is fine for now. Thanks for the help!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.