gutierrezps / gwiot7941e

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

Question regarding library usage (especially return value of update function) #6

Closed RiftRoamer closed 1 year ago

RiftRoamer commented 1 year ago

Hi,

I am quite new (unused) to asking questions on GitHub and this might be the wrong place to ask. I have successfully included this library for a project that aims to read from two GWIOT7941E readers (using SoftwareSerial and AltSoftSerial; not simultaneously) and report the read information over hardware serial interface (USB) to a PC. This works fine thanks to this library.

However the reader1.update()/reader2.update() function from issue one example returns only the 4byte tag ID, whereas the application I use (JMRI) expects 5byte tagIDs plus checksum (1byte; it also expects a start and end character, that I can take care of later). :


#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);
}

https://github.com/gutierrezps/gwiot7941e/issues/1

The afforementioned tag data is normally returned by the tag when I use an RDM6300 reader with the rdm6300.h library instead (off which this library originally had been derived, if I understood that correctly). So I assume it should be possible?

My question is: Is there a way to read the version number 1byte + tag ID 4bytes + checksum 1byte from the buffer "in one go" or at least serial.print this information via hardware serial?

I am a total coding noob, so please accept my apologies, if this question should have been solved/answered already by the supplied documentation and thank you very much for any answer.

Kind regards

gutierrezps commented 1 year ago

Hello @RiftRoamer. In fact, this library returns a tag ID with 4 bytes/32-bit (you can see the return type of getLastTagId() is uint32_t). I checked the module documentation, and it seems it is possible to read a tag ID with 5 bytes if the input pin labeled "FOR" is grounded. If this is true, then the library can be updated to read this extra byte.

Unfortunately, I no longer have access to this module neither to an Arduino. What I can do is make a branch with this update, then you would need to download it and place it in your Arduino libraries folder, and test if it works. What do you say?

RiftRoamer commented 1 year ago

Hi @gutierrezps that would be awsome. I changed my erratic use of bits above (should have been characters, I guess) and instead used your byte description. I would really appreciate this and will happily test it. Thanks for the help in advance.

RiftRoamer commented 1 year ago

Hi @gutierrezps, I just wanted to let you know, that this "issue" is solved for me. I found a good solution not using the library for my specific case. The library is great and everything is fine from my point of view. So this should be closed.

gutierrezps commented 1 year ago

Great @RiftRoamer . Can you please share how you solved it?

RiftRoamer commented 1 year ago

Hi @gutierrezps, yes I can, but it's a crude approach tailored to my needs. It's messy and as - frankly put - I am a total noob in this regard, this code potentially contains passages that are unused or unnecessary.

And I have one unsolved issue with my solution. My code somehow returns an incorrect checksum when reading the corresponding byte from the tag. Maybe only a formatting issue of the incoming data.

For the intended use I needed a correct checksum, so I just calculated my own and didn't bother to compare, as the tag ID was read correctly over the tags I have available (by comparison with other hardware).

I'm not using this in a critical application, but for model railroading. I haven't yet decided on the final hardware and came to your library since I had two readers lying around for years. I liked how easy it had been to use both with the library at first.

When I couldn't find a way to get what I wanted, I was mentally hooked inside a problem solving loop. I could not accept these readers not doing what others did (e.g. rdm6300).

Well you'll see what that made with my poor Arduino ;-) I'll append the code tonight, when I'm back from work.

Edit:

 // Twin Gwiot 7941e readers on Arduino Nano
 // JMRI Compatibility by mirc 2023, https://bcnorthernrail.net
 #include <SoftwareSerial.h>
 #include <AltSoftSerial.h>

 SoftwareSerial RFID1(4, 7); // RX and TX
 AltSoftSerial RFID2;

 // AltSoftSerial always uses these pins:
 // Board          Transmit  Receive   PWM Unusable
 // -----          --------  -------   ------------
 // Arduino Uno        9         8         10
 //
 // Tag data structure:
 // Data Head = 0x02 (fixed byte)
 // Length = 0x0A (total length of the packet is 10 bytes for 125kHz fobs)
 // Card Type = 0x02 (EM4100 = 125kHz chips)
 // Card Serial = SN0~SN4 (5 bytes)
 // BCC Check = XOR Check (Except Data Head And Data End)
 // Data End = 0x03 (fixed byte)

 byte tagdata1[6];
 byte tagdata2[6];
 int checksum1 = 0;
 int checksum2 = 0;

 void setup()
 {
  RFID1.begin(9600);     // start NewSoftSerial with RFID1 reader
  RFID2.begin(9600);      // start AltSoftSerial with RFID2 reader
  Serial.begin(9600);     // start hardware serial via USB to PC

 }
 void loop()
 {
  // Poll RFID1
  // Serial.read reads byte-wise. After each read, that byte is gone. So either store byte into variable/array or it's discarded
  if (RFID1.available() > 0)
  {
    delay(100);                 //Wait time to allow data to arrive
    RFID1.read();               // discard Data Head = 0x02 (fixed byte)
    RFID1.read();               // discard Length = 0x0A (total length of the packet is 10 bytes for 125kHz fobs)
    RFID1.read();               // discard Card Type = 0x02 (EM4100 = 125kHz chips)
    tagdata1[0] = RFID1.read(); // read Card Serial = SN0~SN4 (5 bytes)
    tagdata1[1] = RFID1.read();
    tagdata1[2] = RFID1.read();
    tagdata1[3] = RFID1.read();
    tagdata1[4] = RFID1.read();
    RFID1.read();               // discard BCC Check (SN5) = XOR Check (Except Data Head And Data End); return wrong value so we calculate below!
    RFID1.read();               // discard Data End = 0x03 (fixed byte)

    // Transmit the tagdata to JMRI
    Serial.print("E");           // Open transmission with reader ID prefix (A-H or I-P)
    for (int i = 0; i < 5; i++)  // i<5 reads without checksum, i<6 with tag checksum (but returns wrong value)
    {
      if (tagdata1[i] < 16) Serial.print("0"); // checks whether tagdata would return a single character, if so we add a zero in front
      Serial.print(tagdata1[i], HEX);
    }
    // calculate and append checksum to transmitted tagdata
    tagdata1[5] = 0;
    for (byte i = 0; i < 5; i++) {
      tagdata1[5] ^= tagdata1[i];
    }
    Serial.print(tagdata1[5], HEX);

    //End trannsmission with linefeed and end char for MERG
    Serial.println("");
    Serial.print(">");
  }

  // Poll RFID2
  // Serial.read reads byte-wise. After each read, that byte is gone. So either store byte into variable/array or it's discarded
  if (RFID2.available() > 0)
  {
    delay(100);                 //Wait time to allow data to arrive
    RFID2.read();               // discard Data Head = 0x02 (fixed byte)
    RFID2.read();               // discard Length = 0x0A (total length of the packet is 10 bytes for 125kHz fobs)
    RFID2.read();               // discard Card Type = 0x02 (EM4100 = 125kHz chips)
    tagdata2[0] = RFID2.read(); // read Card Serial = SN0~SN4 (5 bytes)
    tagdata2[1] = RFID2.read();
    tagdata2[2] = RFID2.read();
    tagdata2[3] = RFID2.read();
    tagdata2[4] = RFID2.read();
    RFID2.read();               // discard BCC Check (SN5) = XOR Check (Except Data Head And Data End); return wrong value so we calculate below!
    RFID2.read();               // discard Data End = 0x03 (fixed byte)

    // Transmit the tagdata to JMRI
    Serial.print("F");           // Open transmission with reader ID prefix (A-H or I-P)
    for (int i = 0; i < 5; i++)  // i<5 reads without checksum, i<6 with checksum (but returns wrong value)
    {
      if (tagdata2[i] < 16) Serial.print("0"); // checks whether tagdata would return a single character, if so we add a zero in front
      Serial.print(tagdata2[i], HEX);
    }
    // calculate and append checksum to transmitted tagdata
    tagdata2[5] = 0;
    for (byte i = 0; i < 5; i++) {
      tagdata2[5] ^= tagdata2[i];
    }
    Serial.print(tagdata2[5], HEX);

    //End trannsmission with linefeed and end char for MERG
    Serial.println("");
    Serial.print(">");
  }
 }