cancel
Showing results for 
Search instead for 
Did you mean: 

How to correctly compose NDEF sensor data for writing to ST25DV EEPROM

Rajeev Piyare
Associate III

First of all, apologies for asking too many questions on the forum. This is the only way I could get some feedback and suggestions as there is not a huge community around ST25DV.

I have a custom sensor node connected to the ST25DV04K via the I2C interface. So far I am able to read and write NDEF text and URI formats flawlessly.

I am now venturing into composing the sensor data that consists of temperature, humidity, pressure and battery voltage of length 58B. The routines for the composing my data structure are shown below.

/* Copy from node_sensors_t to CompositeSensorData */
static void
copy_sensor_data_to_packet(CompositeSensorData *dest, const node_sensors_t *src)
{
  int i;
  unsigned long now;
  uint16_t temp_min, temp_max, hum_min, hum_max; //place holder for min,max calculation
 
  now = clock_seconds();
 
  dest->age = (uint16_t)((clock_seconds() - src->timestamp) / 60);
  LOG_INFO("Copy sensor data to packet, %u mins old (%lu - %lu)\n",
           dest->age, now, src->timestamp);
 
  dest->DPSTemperature = src->dps_temp;
  dest->Pressure = src->dps_pressure;
 
  /* MIN-MAX calculation for temperature data */
  /* Assume first element of Temp array as maximum and minimum */
  temp_min = temp_max = src->rawTemp_Last3Readings[0];
 
  /* Finding maximum and minimum elements in Temp array */
  for(i = 0; i < 3; i++) {
    dest->rawTemp_Last3Readings[i] = src->rawTemp_Last3Readings[i];
 
    /* If current element of array is smaller than min */
    temp_min = MIN(temp_min, src->rawTemp_Last3Readings[i]); 
    /* If current element of array is greater than max */
    temp_max = MAX(temp_max, src->rawTemp_Last3Readings[i]);
  }
  /* Put the respective temperature values to the destination */
  dest->rawTemp_min = temp_min;
  dest->rawTemp_max = temp_max;
 
  /* MIN-MAX calculation for humidity data */
  /* Assume first element as maximum and minimum */
  hum_min = hum_max = src->hum_Last3Readings[0];
 
  /* Finding maximum and minimum elements in Humidity array */
  for(i = 0; i < 3; i++) {
    dest->hum_Last3Readings[i] = src->hum_Last3Readings[i];
    hum_min = MIN(hum_min , src->hum_Last3Readings[i]);
    hum_max = MAX(hum_max , src->hum_Last3Readings[i]);
  }
  /* Put the respective humidity values to the destination */
  dest->hum_min = hum_min;
  dest->hum_max = hum_max;
 
 /* Put the sensor BatteryVoltage to the destination */
  dest->BatteryVoltage = src->BatteryVoltage;
 
}
 
/*---------------------------------------------------------------------------*/
/**
 *  Prepares DataPacket for writing of CompositeSensorData to NFC EEPROM.
 */
uint16_t
NDEF_WriteCompositeSensorData(const node_sensors_t *sensor_data)
{
  uint16_t status = NDEF_ERROR;
  uint32_t PayloadSize, Offset = 0;
 
  CompositeSensorData *composite_sensor_data = &data_packet.DataUnion.composite_sensor_data;
  copy_sensor_data_to_packet(composite_sensor_data, sensor_data);
 
  /* packet counter */
  seq_number++;
  composite_sensor_data->sequenceNumber = seq_number;
 
  /* Prepare the data using the NDEF format */
  /* TEXT : 1 + en + message */
  PayloadSize = 3 + sizeof(CompositeSensorData);
 
  LOG_INFO("Size of CompositeSensorData is: %u\n", sizeof(CompositeSensorData));
 
  /* Payload header */
  NDEF_Buffer[Offset] = 0xD1;
 
  if(PayloadSize < 256) 
  {
    NDEF_Buffer[Offset] |= 0x10;                   // Set the SR bit
    Offset++;
    NDEF_Buffer[Offset++] = TEXT_TYPE_STRING_LENGTH;
  }
 
  if(PayloadSize > 255)
  {
    NDEF_Buffer[Offset++] = (PayloadSize & 0xFF000000) >> 24;
    NDEF_Buffer[Offset++] = (PayloadSize & 0x00FF0000) >> 16;
    NDEF_Buffer[Offset++] = (PayloadSize & 0x0000FF00) >> 8;
    NDEF_Buffer[Offset++] = PayloadSize & 0x000000FF;
  }
  else
  {
    NDEF_Buffer[Offset++] = (uint8_t)PayloadSize;
  }
 
  memcpy(&NDEF_Buffer[Offset], TEXT_TYPE_STRING, TEXT_TYPE_STRING_LENGTH);
  Offset += TEXT_TYPE_STRING_LENGTH;
 
  /* TEXT payload */
  NDEF_Buffer[Offset++] = ISO_ENGLISH_CODE_STRING_LENGTH;
 
  memcpy(&NDEF_Buffer[Offset], ISO_ENGLISH_CODE_STRING, ISO_ENGLISH_CODE_STRING_LENGTH);
  Offset += ISO_ENGLISH_CODE_STRING_LENGTH;
 
  memcpy(&NDEF_Buffer[Offset], &data_packet, sizeof(data_packet));
  Offset += sizeof(data_packet);
 
  sensor_power_set(true);
  board_i2c_wakeup();
 
  status = NfcTag_WriteNDEF(Offset , NDEF_Buffer);
 
  LOG_INFO("NDEF_WriteCompositeSensorData Status: %d\n", status);
 
  sensor_power_set(false);
  board_i2c_shutdown();
 
  return status;
}
 

I have tried to mimic the payload format (L:72 onwards) from the NDEF_WriteText() library.

What I am unclear and not able to do is to compose the Payload with the correct NDEF header format so that it can be written via the I2C and read properly by any reader. The aim is to also append the messages on the tag as new sensor data gets in and is written to the EEPROM. Finally, the full data set will be read out of the NFC chip.

In short, it is unclear to me how the header frame should be set and the offset to be adjusted so that data is not corrupted and is standardized.

Any hint, suggestions and directions will be a great help in accomplishing the above.

Thanks

1 ACCEPTED SOLUTION

Accepted Solutions
Rene Lenerve
ST Employee

Hi @Rajeev Piyare​ ,

First thing I see on your code is that you are setting the NDEF header as short record (bit SR =1) with the first byte (0xD1) but in case of standard record the first byte is overwritten. Second thing is that you are not defining the ID length after payload size. If you don't have an ID for you record you must set the ID Length to 0, otherwise you will have a missing field in your header.

/* Payload header */
  NDEF_Buffer[Offset] = 0xD1;  //=> Msg Begin, Msg End, Short Record, TNF =1
 
  if(PayloadSize < 256)
  {
    NDEF_Buffer[Offset] |= 0x10;                   // Set the SR bit
    Offset++;
    NDEF_Buffer[Offset++] = TEXT_TYPE_STRING_LENGTH;
  }
 
  if(PayloadSize > 255) // In that case first byte is overwritten as offset is not incremented
  { //Type length is not defined here (or takes the msb payload size value)
    NDEF_Buffer[Offset++] = (PayloadSize & 0xFF000000) >> 24;
    NDEF_Buffer[Offset++] = (PayloadSize & 0x00FF0000) >> 16;
    NDEF_Buffer[Offset++] = (PayloadSize & 0x0000FF00) >> 8;
    NDEF_Buffer[Offset++] = PayloadSize & 0x000000FF;
  }
  else
  {
    NDEF_Buffer[Offset++] = (uint8_t)PayloadSize;
  } 
 
//ID length must be 0 if no ID present in the record's header, before type field
 
  memcpy(&NDEF_Buffer[Offset], TEXT_TYPE_STRING, TEXT_TYPE_STRING_LENGTH);
  Offset += TEXT_TYPE_STRING_LENGTH;

Hope this can help,

Best Regards.

View solution in original post

2 REPLIES 2
Rene Lenerve
ST Employee

Hi @Rajeev Piyare​ ,

First thing I see on your code is that you are setting the NDEF header as short record (bit SR =1) with the first byte (0xD1) but in case of standard record the first byte is overwritten. Second thing is that you are not defining the ID length after payload size. If you don't have an ID for you record you must set the ID Length to 0, otherwise you will have a missing field in your header.

/* Payload header */
  NDEF_Buffer[Offset] = 0xD1;  //=> Msg Begin, Msg End, Short Record, TNF =1
 
  if(PayloadSize < 256)
  {
    NDEF_Buffer[Offset] |= 0x10;                   // Set the SR bit
    Offset++;
    NDEF_Buffer[Offset++] = TEXT_TYPE_STRING_LENGTH;
  }
 
  if(PayloadSize > 255) // In that case first byte is overwritten as offset is not incremented
  { //Type length is not defined here (or takes the msb payload size value)
    NDEF_Buffer[Offset++] = (PayloadSize & 0xFF000000) >> 24;
    NDEF_Buffer[Offset++] = (PayloadSize & 0x00FF0000) >> 16;
    NDEF_Buffer[Offset++] = (PayloadSize & 0x0000FF00) >> 8;
    NDEF_Buffer[Offset++] = PayloadSize & 0x000000FF;
  }
  else
  {
    NDEF_Buffer[Offset++] = (uint8_t)PayloadSize;
  } 
 
//ID length must be 0 if no ID present in the record's header, before type field
 
  memcpy(&NDEF_Buffer[Offset], TEXT_TYPE_STRING, TEXT_TYPE_STRING_LENGTH);
  Offset += TEXT_TYPE_STRING_LENGTH;

Hope this can help,

Best Regards.

Thanks for the feedback @Rene Lenerve​.

Much appreciated.