gutierrezps / gwiot7941e

A simple library to interface with Gwiot 7941E RFID reader
GNU General Public License v3.0
7 stars 5 forks source link

Multiple readers #1

Closed Vodny86 closed 4 years ago

Vodny86 commented 4 years ago

Good day.

Thank you for this library is very good.

Can this library be used for multiple readers to one Arduino?

I have 5 readers defined but only one works (last defined) "xy.begin (pin number)"

gutierrezps commented 4 years ago

Hi. I'm afraid that's not possible. This library uses Arduino's built-in SoftwareSerial library, and according to its documentation:

Limitations

  • If using multiple software serial ports, only one can receive data at a time.

For this number of readers, I suggest you move to Arduino Mega which has 4 hardware Serial ports. Then you can use SoftwareSerial for the fifth reader.

What you can try to do, but probably will lead to data loss, is to use one reader with SoftwareSerial and another with AltSoftSerial, as shown below. I didn't test it, if you do please update this issue.

#include <Gwiot7941e.h>
#include <AltSoftSerial.h>

#define READER2_RX_PIN 10

// AltSoftSerial
Gwiot7941e reader1;
AltSoftSerial altSoftSerial;    // RX pin: 8 (fixed)

// SoftwareSerial
Gwiot7941e reader2;

void setup()
{
    Serial.begin(115200);

    altSoftSerial.begin(GWIOT_7941E_BAUDRATE);
    reader1.begin(&altSoftSerial);

    reader2.begin(READER2_RX_PIN);

    Serial.println("\nPlace RFID tag near any of the readers...");
}

void loop()
{
    // if non-zero tag_id, update() returns true - a tag was read!
    if (reader1.update()) {
        Serial.print("Reader1: ");
        Serial.println(reader1.getLastTagId(), HEX);
    }

    // if non-zero tag_id, update() returns true - a tag was read!
    if (reader2.update()) {
        Serial.print("Reader2: ");
        Serial.println(reader2.getLastTagId(), HEX);
    }

    delay(10);
}
Vodny86 commented 4 years ago

Hello.

`Limitations

If using multiple software serial ports, only one can receive data at a time.`

I don't mind this limit. I do not think that the reading overlaps. There will be low traffic on the reader. It is enough if only one works at a time.

This should not be a problem with SoftwareSerial

gutierrezps commented 4 years ago

The problem is that you can only listen to one reader at a time, and this particular RFID reader only sends the reading once (unlike the RDM6300). If you place a card on a reader that you're not listening at the exact time, the RFID data reading will be lost, or even worse, it could bug the reader that's active at the moment.

If you still wish to attempt, you must use the methods begin() and end() to enable and disable a reader. Here's a code I've written (again, not tested). Adjust k_readerMaxActiveTimeMs to fit your needs.

#include <Arduino.h>
#include <Gwiot7941e.h>

// number of readers being used
#define NUM_RFID_READERS  5

// Serial RX pins of each reader
const byte k_readerPins[NUM_RFID_READERS] = {4, 5, 6, 7, 8};

// how long each reader should be active, in milliseconds
const uint32_t k_readerMaxActiveTimeMs = 1000;

// reader objects
Gwiot7941e g_reader[NUM_RFID_READERS];

void setup()
{
    Serial.begin(115200);

    Serial.println("\nPlace RFID tag near any of the readers...");
}

void loop()
{
    static byte activeReader = 0;
    static bool swapReader = true;      // on first run, initializes reader 0
    static uint32_t activeTimer = 0;    // tracks how long a reader is active

    if (swapReader) {
        if (activeReader == 0) {
            g_reader[NUM_RFID_READERS - 1].end();   // disconnect last reader
        }
        else {
            g_reader[activeReader].end();       // disconnect previous reader
        }

        activeReader++;
        if (activeReader == NUM_RFID_READERS) activeReader = 0;

        // connect next reader
        g_reader[activeReader].begin(k_readerPins[activeReader]);

        // reset active timer
        swapReader = false;
        activeTimer = millis();
    }

    if (g_reader[activeReader].update()) {      // true when a tag is read
        Serial.print("Reader ");
        Serial.print(activeReader, DEC);
        Serial.print(": ");
        Serial.println(g_reader[activeReader].getLastTagId(), HEX);
    }

    // swap reader if it's active for more than the specified time
    swapReader = millis() - activeTimer > k_readerMaxActiveTimeMs;

    // your code below
    // ...

    delay(10);
}
gutierrezps commented 4 years ago

Any updates @Vodny86 ?

Vodny86 commented 4 years ago

Hello.

I was not successful. I am currently trying it on Arduino MEGA where there is more HW serial port.

Thank you for your interest

gutierrezps commented 4 years ago

Thanks for the feedback.