Configure mode "Read once" and timeout should be 1sec & configure GEN2 settings

We have used the Sparkfun M7E Hecto module EVK in our design.
I have ported this example([Example1_Constant_Read] for my application which is in C. I want to configure mode “Read once” and timeout should be 1sec.
Apart from it I want to configure GEN2 settings which are,
RFmode: RFMODE_160_M8_20
Session: S2
Target :AB
Can you please provide APIs for that? I have checked with windows tool and these parameters are giving best results without generating mode heat.

`void read_tags(void)
{

PRINTF(“[UHF] Starting multi-tag read…\r\n”);

uint32_t start = xTaskGetTickCount();
startReading();

while ((xTaskGetTickCount() - start) < pdMS_TO_TICKS(1000))
{
    // Step 1: Receive 3-byte header
    usart_transfer_t rxHeader = {
        .data = msg,
        .dataSize = 3
    };
    if (USART_TransferReceiveNonBlocking(UHF_USART, &g_uartHandle, &rxHeader, NULL) != kStatus_Success ||
        xSemaphoreTake(uhf_rx_done_sema, pdMS_TO_TICKS(200)) != pdTRUE)
    {
        continue;
    }

    uint8_t len = msg[1];
    uint8_t opcode = msg[2];

    if (len + 7 > MAX_MSG_SIZE)
    {
        PRINTF("Invalid length %d\r\n", len);
        continue;
    }

    // Step 2: Receive remaining payload + 2 status + 2 CRC
    usart_transfer_t rxPayload = {
        .data = &msg[3],
        .dataSize = len + 4
    };
    if (USART_TransferReceiveNonBlocking(UHF_USART, &g_uartHandle, &rxPayload, NULL) != kStatus_Success ||
        xSemaphoreTake(uhf_rx_done_sema, pdMS_TO_TICKS(200)) != pdTRUE)
    {
        continue;
    }

    uint8_t fullLen = len + 7;

    // Step 3: CRC check
    uint16_t crc_calc = calculateCRC(&msg[1], fullLen - 3);
    uint16_t crc_recv = (msg[fullLen - 2] << 8) | msg[fullLen - 1];
    if (crc_calc != crc_recv)
    {
        PRINTF("Bad CRC (calc=0x%04X, recv=0x%04X)\r\n", crc_calc, crc_recv);
        continue;
    }

    // Step 4: Process tag
    if (opcode == TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE)
    {
        if (fullLen < 32) // Minimum size for valid tag packet
        {
            PRINTF("Too short for EPC\n");
            continue;
        }


        uint8_t epcLength = getTagEPCBytes();
        uint8_t epcBuf[epcLength];

        PRINTF("EPC [ ");
        for (uint8_t i = 0; i < epcLength; i++)
        {
            epcBuf[i] = msg[31 + i];
              if (epcBuf[i] < 0x10) PRINTF("0");
            PRINTF("%X ", epcBuf[i]);
        }
        PRINTF("]\r\n");
        add_to_list_if_not_present(epcBuf);
    }
    else if (opcode == RESPONSE_IS_KEEPALIVE)
    {
        PRINTF("[Keepalive]\r\n");
    }
    else
    {
        PRINTF("Unknown opcode: 0x%02X\r\n", opcode);
    }
}

stopReading();
PRINTF("[UHF] Multi-tag read complete.\r\n");

}`
I have noticed that readTagEPC(myEPC, &myEPClength, 1000); this API is giving only one tag

Please advise if someone has similar problems and have any solution.

Long time ago I started working with the M6E and created an extended library with additional functions. Functionally it contains all the same as the current Sparkfun library, but contains many more options.

As the request for GEN2 extensions has been requested a number of times I decided to give that a try and I have now added setting GEN2 Target, Session and RFMODE. I have not tested the impact, but that is a good test for you.

You need to remove the current Sparkfun RFID library and install mine from ThingMagic/Arduino_lib_special at master · paulvha/ThingMagic · GitHub. Then look at example30 how to use the functions.

look forward to your feedback

Thanks for sharing the repository. That would be very much helpful to me. I have another 2 configurations need to be added
(1) In the example of SparkFun_Simultaneous_RFID_Tag_Reader_Library/examples/Example1_Constant_Read/Example1_Constant_Read.ino at master · sparkfun/SparkFun_Simultaneous_RFID_Tag_Reader_Library · GitHub it reads the tag in continuous mode instead of it I want to read tag in “Read once” mode with 1000ms timeout. Can you please guide me how can I enable that?
(2)I want to retain configuration after power up cycle

as for request 1: look at example 2:

while (responseType != RESPONSE_SUCCESS)//RESPONSE_IS_TAGFOUND)
{
     myEPClength = sizeof(myEPC); //Length of EPC is modified each time .readTagEPC is called
 
     responseType = rfidModule.readTagEPC(myEPC, myEPClength, 500); //Scan for a new tag up to 500ms
     Serial.println(F("Searching for tag"));
 }

As for request 2: I have taken quick look at the programmers manual.
Serial Reader Autonomous Operation, for M6E and M7E modules only support this functionality currently for continuous reading only. That is already done in Example1, without the GEN2 settings. That would require making a special “blob” and thus a lot of time that I don’t have available at this moment.

Thank you for your quick response. For “read once” method, I have already tried this approach and it can scan only one EPC tag. I want to have multiple tags with single scan which I am getting with windows tool.

Tag EPC: E2 80 11 91 A5 03 00 66 B8 14 68 AD
Scanning for tags…
Tag EPC: E2 80 11 91 A5 03 00 66 B8 14 68 AD
Scanning for tags…
Tag EPC: E2 80 11 91 A5 03 00 66 B8 14 68 AD
Scanning for tags…
Tag EPC: E2 80 11 91 A5 03 00 66 B8 14 68 AD
Scanning for tags…
Tag EPC: E2 80 11 91 A5 03 00 66 B8 14 68 AD
Scanning for tags…
Tag EPC: E2 80 11 91 A5 03 00 66 B8 14 68 AD
Scanning for tags…
Tag EPC: E2 80 11 91 A5 03 00 66 B8 14 68 AD
Scanning for tags…
Tag EPC: E2 80 11 91 A5 03 00 66 B8 14 68 AD

I have put 3 tags but it is scanning only one tag. If I put one by one then it will scan but this program is not replicating windows “Read once” functionality

//Begin scanning for tags
//There are many many options and features to the nano, this sets options
//for continuous read of GEN2 type tags
void RFID::startReading()
{
disableReadFilter(); //Don’t filter for a specific tag, read all tags

//This blob was found by using the ‘Transport Logs’ option from the Universal Reader Assistant
//And connecting the Nano eval kit from Thing Magic to the URA
//A lot of it has been deciphered but it’s easier and faster just to pass a blob than to
//assemble every option and sub-opcode.
uint8_t configBlob = {0x00, 0x00, 0x01, 0x22, 0x00, 0x00, 0x05, 0x07, 0x22, 0x10, 0x00, 0x1B, 0x03, 0xE8, 0x01, 0xFF};

/*
//Timeout should be zero for true continuous reading
SETU16(newMsg, i, 0);
SETU8(newMsg, i, (uint8_t)0x1); // TM Option 1, for continuous reading
SETU8(newMsg, i, (uint8_t)TMR_SR_OPCODE_READ_TAG_ID_MULTIPLE); // sub command opcode
SETU16(newMsg, i, (uint16_t)0x0000); // search flags, only 0x0001 is supported
SETU8(newMsg, i, (uint8_t)TMR_TAG_PROTOCOL_GEN2); // protocol ID
*/

sendMessage(TMR_SR_OPCODE_MULTI_PROTOCOL_TAG_OP, configBlob, sizeof(configBlob));
}

with this API if I want to set RF on time with 50ms and RF off time with 1000ms how can I set?

As many people suffer with the M7E/M6E that only ONE tag is showing up all the time, I have taken more time to add GEN2 function that can improve the quality of reader (RFMODE, TAG-encoding) as well as improve the selection of that tags ( GEN2 Session, target and Q-setting). Examples 30 and 31 have been added to demonstrate the usage. ThingMagic/Arduino_lib_special at master · paulvha/ThingMagic · GitHub

1 Like