cancel
Showing results for 
Search instead for 
Did you mean: 

How to add data to an NDEF message?

GThab.1
Associate II

Hi,

I'm using an ST25DV04KC tag with the STM32L476 microcontroller as the host. I can write and read from the tag without issues through I2C. However, I'd like to inquire about the feasibility of gradually adding data to an existing NDEF message stored in the tag's memory.

I looked into some older topics, and I saw that this might be implemented in future versions. Has this been implemented in any library?

I see that it is possible by completely rewriting the message with the new aggregated data. However, this would wear down the memory unnecessarily. So, I would like to simply add the new data to the end of the previous message. I know that to achieve this, I will need to modify the NDEF header to identify these new data. I'd like to know if I should implement this myself or if ST already provides this feature in any library.

1 ACCEPTED SOLUTION

Accepted Solutions

HI,

the NDEF message of a type 5 tag is embedded inside a TLV (Type - Length-Value) structure. When adding a new NDEF record into an existing NDEF message the L-field of this TLV structure has to be updated. This L-field is 1 byte when the length is between 00h-FEh otherwise it is 3 bytes. So, if your V-field  increases, it may be needed to recopy it to allow the L-field to grow from 1-byte to 3-bytes. Each record has a header with Message Begin (MB) and Message End (ME) bits. When appending a new record, the header of the previous one has to be modified from ME=1 to ME=0.

I would personally not add new record nor append new data to an existing record. I would rather have a fixed NDEF with pre-allocated room for the 24 hrs data with a kind of simple time stamp between each data and use this as a circular buffer.

Also, the ST25DV04KC has a 256 bytes mailbox (volatile memory) that is typically used by application exchanging sensor data. See for example https://community.st.com/t5/st25-nfc-rfid-tags-and-readers/fast-transfer-mode-mailbox-how-many-write-cycles-can-it-handle/td-p/364860. I feel that the ST25DV04KC mailbox can be used for your application.

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

12 REPLIES 12
Brian TIDAL
ST Employee

Hi

can you provide more information about your application and your needs: do you want to append a new record to the current NDEF message or do you want to change the payload of the last record of the NDEF? 

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi Brian,

Sure, I want to add a new record to the current NDEF message, I am collecting data from the sensors every minute, and I would like to progressively aggregate the data in the NDEF message.

I believe that rewriting the entire message every minute could quickly wear out the NFC tag's memory. Therefore, I would prefer to simply accumulate data in the current message; I think that's the best approach. Please, if you have any recommendations, let me know.

My goal is to always keep the last 24 hours of data. Once the required dataset is reached, I intend to start removing the older data.

Thank you.

 

HI,

the NDEF message of a type 5 tag is embedded inside a TLV (Type - Length-Value) structure. When adding a new NDEF record into an existing NDEF message the L-field of this TLV structure has to be updated. This L-field is 1 byte when the length is between 00h-FEh otherwise it is 3 bytes. So, if your V-field  increases, it may be needed to recopy it to allow the L-field to grow from 1-byte to 3-bytes. Each record has a header with Message Begin (MB) and Message End (ME) bits. When appending a new record, the header of the previous one has to be modified from ME=1 to ME=0.

I would personally not add new record nor append new data to an existing record. I would rather have a fixed NDEF with pre-allocated room for the 24 hrs data with a kind of simple time stamp between each data and use this as a circular buffer.

Also, the ST25DV04KC has a 256 bytes mailbox (volatile memory) that is typically used by application exchanging sensor data. See for example https://community.st.com/t5/st25-nfc-rfid-tags-and-readers/fast-transfer-mode-mailbox-how-many-write-cycles-can-it-handle/td-p/364860. I feel that the ST25DV04KC mailbox can be used for your application.

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi Brian,

Thank you for your considerations and explanations.

I understand that data aggregation will also consume a significant amount of memory, especially in the areas responsible for TLV's L registers, as I'll need to rewrite with each record.

Regarding the approach you mentioned with the circular buffer, should I initialize all my data and only update the values? This way, I wouldn't need to change the TLV structure; I would just traverse the buffer and replace the data as needed, right? Is there already a function that allows me to write in this manner, indicating only the memory position for data replacement in an NDEF message? I've noticed that NDEF write functions often end up overwriting and initializing with the TLV structure.

The mailbox approach is not suitable for this project, as I cannot afford to lose data. While I could maintain a copy of the data in the microcontroller's flash or the tag's EEPROM, the data volume is 2880 bytes, and the tag's RAM size is insufficient. Is it possible to use both the mailbox and NDEF message simultaneously? Would it be feasible to differentiate the data and retrieve it distinctly from the reader's side?

Brian TIDAL
ST Employee

Hi,

"the data volume is 2880 bytes", ST25DV04KC has  4-Kbit of EEPROM.  I believe ST25DV64KC with 64Kbit of EEPROM should be considered.

"Regarding the approach you mentioned with the circular buffer, should I initialize all my data and only update the values? " yes this would be the idea. If I understand well, you have 2 bytes of sensor data every minutes (x 60 min * 24 hrs ==> 2880 bytes).  I would combine 2 consecutive data into a 4 bytes word to update a single block of EEPROM memory (the EEPROM memory is organized in blocks of 4 bytes) every 2 minutes. The next block can be written with 00000000 or FFFFFFF as end of valid data marker (depending on the valid range the data from the sensor). Which NDEF type do you plan to use ? On the reader side, is it based on an android phone? do you plan to have your own application? How do you plan to read the data?

"The mailbox approach is not suitable for this project". Usually the mailbox is used with data being fragmented in ~256-byte chunks (see the FTM  example inside the ST25R embedded lib). Thus, if the 2880 bytes of data are available on the MCU, the mailbox can be used to to exchange those 2880 bytes with the NFC reader by several read/write inside the mailbox.

"Is it possible to use both the mailbox and NDEF message simultaneously?" From reader perspective, yes: this depends only on the application on reader side (thus my previous questions on the reader side)

"Would it be feasible to differentiate the data and retrieve it distinctly from the reader's side?" Same answer.

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi Brian,

Yes, I intend to use the ST25DV64KC. My testing is starting with the ST25DV04KC as it is what I have available at the moment.

Regarding the data, you understood correctly. Thank you for the suggestion to accumulate 2 readings to fill complete memory blocks (4 bytes). To use this approach, should I call the function NDEF_WriteNDEF(...) to allocate the total buffer with the TLV structure to make it a valid NDEF message, right? To keep rewriting this buffer, what's the recommended function? I see that there's the function NDEF_Wrapper_WriteData(...) in which I could write a specific position in memory, but this function will rewrite a new TLV, correct?

I plan to read the data through a proprietary application, which could be on an Android or iOS smartphone.

I didn't know that the mailbox approach could work this way. Does the library currently support automatic transmission of larger data in 256-byte fragments? Are there any examples of using this approach besides FTM, which is focused on firmware updates?

Thank you.

Brian TIDAL
ST Employee

Hi,

"I plan to read the data through a proprietary application" In that case you can get rid of the NDEF structure and write your data directly into the tag memory. Or you can just keep a simple NDEF in area 1 with for example an AAR record to launch the android App and then have your 2880-bytes of sensor data stored in area 2. Is there any particular reason to store your sensor data inside an NDEF? I believe this is just an application design choice. If you want to use the NDEF structure to store your data, make sure to design your record in a way to align the sensor data on a block frontier. Which NDEF Record type do you plan to use for this? NDEF_WriteNDEF can be used to write the NDEF message. NDEF_Wrapper_WriteData does not rewrite the TLV but just write data at a specific position.

I let one of my colleague answer to your question about the FTM.

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi Brian,

The intention of using NDEF would be more to have a well-defined protocol, as the application is not exclusive to this product, it is shared with other products that currently utilize NDEF. However, for my specific use case, I'm not seeing an advantage in retaining NDEF.

One of the drawbacks I noticed is related to your question; I realize that I don't have a suitable record type for this. The approach I found most viable would be to convert my values to strings and write using NDEF_WriteText, as I noticed that if I write integers, the NDEF is not recognized by the application (I'm still conducting tests with NFC Tap). Another point is related to NDEF_WriteNDEF (...), regardless of what I write with this function, the application never considers it as a valid NDEF.

Now, discussing what worked and can assist those reading this thread: using NDEF_WriteText (...) to format the NDEF and create the total buffer, and later progressively adding data with NDEF_Wrapper_WriteData (...) at the buffer's starting positions works. Regardless of the number of data additions, it remains a valid and recognized NDEF message. Automatically, the application disregards anything that comes after the last data written by the NDEF_Wrapper_WriteData (...) function.

Olivier L
ST Employee
Hi,
I'm jumping in the discussion. 
 
I think that the discussion is going to the right direction: I fully agree that NDEF has no added value here and I also agree that it is wise to use multiple area in this use case.
You can have a first area where you put some NDEF content (your sensor data would NOT be here), then you could have an area dedicated to your sensor data. The content of this area would not be formatted as NDEF content because NDEF doesn't bring any added value here. It would simply be an array of data. Your sensor data is 2 bytes long. As indicated by Brian, it is wise to put each data in a separate block (on ST25DV, block size is 4 bytes) so that the writting of each data is independent of other data (no risk to corrupt a previous data).
 
In ST25SDK, you can read of write raw data with:
    public byte[] readBytes(int area, int offsetInBytes, int sizeInBytes) throws STException;
public void writeBytes(int area, int offsetInBytes, byte[] data) throws STException;
 
You will have to increment the offset 4 by 4 to move from block to block.
ST25DV areas are numbered from 1 to 4. AREA1 would be for the NDEF data and AREA2 for your sensor data.
When calling readBytes() and writeBytes(), you can use the constant defined in com.st.st25sdk.MultiAreaInterface.AREA2.
 
Concerning FTM, is there some remaining points where I could help?
 
Regards
Olivier