• Announcements

    • bluehash

      Forum Upgrade   03/11/2017

      Hello Everyone, Thanks for being patient while the forums were being fixed and upgraded. Please see details and report issues in this thread. Thanks!
spirilis

[Energia Library] RF430CL - TI NFC RF430CL330H library

17 posts in this topic

I have a library I've been working on for the past month or so to give Energia and Arduino users intuitive access to the TI RF430CL330H series of NFC transponders.

 

https://github.com/spirilis/RF430CL

 

This library is composed of two logical sections:

 

1. The RF430 class which defines and manages a physical RF430CL330H NFC transponder over I2C using the "Wire" library

2. The NDEF class system which allows users to conceptually define and manage NFC NDEF data records, importing & exporting them

 

The NDEF class and subclasses (so far NDEF_URI, NDEF_TXT being the only RTD-specific subclasses implemented) maintain buffers for storing the NDEF "Type" field (a character string), "ID" field (optional, character string) and the actual payload.  The class is designed to be flexible so the user has to provide the buffer space (and maximum buffer size) for storing the Type, ID and Payload information, but some of the subclasses (and soon the base class) support defining those buffers as immutable data types (e.g. const uint8_t [] or const char [] arrays) for export usage only.

 

For importing & exporting, the NDEF class and all subclasses have two methods:

 

.sendTo(Stream &, boolean Message_Begin=true, boolean Message_End=true)

.import(Stream &)

 

sendTo writes byte-for-byte the physical NDEF record associated with that object's current state, returning an integer equal to the exact length (in bytes) of the NDEF binary record.  The two boolean arguments allow the user to customize the setting of the MB and ME bits in the NDEF header byte to support having multiple NDEF records in a single NFC memory segment.  If those boolean arguments are omitted, they default to "true" so the NDEF record will be written with both MB and ME bits set (typical usage for an NFC transponder housing only a single NDEF record).

 

import uses the read() and readBytes() feature of the Stream object supplied to read, byte for byte, and analyze (rejecting by returning -1 if read errors or for RTD-specific sub-classes, if the header or structure of the record does not match the appropriate NDEF RTD type) and import the data.  Buffers must be defined for the NDEF object using .setPayloadBuffer(<buf>, <maxlen>) and for the base (generic) NDEF class, .setTypeBuffer() and optionally .setIDBuffer() so the import function has a place to store the TYPE and (optionally, if present, i.e. the "ID" bit is set in the NDEF header byte) ID strings.

 

The RF430 class (which references the hardware) has an internal counter and I/O system which implements Arduino's "Stream" interface, so it's a valid target for the NDEF sendTo & import functions.  There are functions for changing/resetting the internal "pointer" as well as informing the RF430 library how much NDEF data is there (this must be set, or else any NFC master going to read or write to the transponder will error).

 

Several examples are provided illustrating the use of the RF430 and NDEF classes and typical application program flow.  IRQ support is there, with the ability to detect whether an NFC master (e.g. cellphone) has read from the RF430CL330H recently, or has written a new record or series of records to the RF430CL330H's SRAM.

 

There is still more work to be done to enable simpler and better-managed generic NFC importers, and I would like to make an NDEF subclass that eases the use of custom/externally-defined RTD types.

 

As of now, this does not support the TRF7970A in any way.  In theory, I could support it in the future with the NDEF class infrastructure provided here.  The RF430CL330H is a whole lot simpler/easier to understand IMO.  I have been testing this with the F5529LP and DLP-RF430BP boosterpack.

 

Here's a zip of the current codebase (from git as of 2/26/2015) - RF430CL_02262015.zip

 

And here's one of the examples, illustrating how to write "Hello World" to the RF430CL330H and use Energia's Low-Power-Mode support (suspend() aka LPM4) to put the host MCU in deep sleep, waking up only when the RF430 sees an NFC master read or write to it:

/* HelloWorld - NFC edition
 * Written for the TI RF430CL330H with Energia
 *
 * Showcases Low-Power Sleep modes in Energia and IRQ-driven wakeup of
 * the MCU based on RF430CL330H IRQs.
 *
 * 2/25/2015 Eric Brundick
 */

#include <Wire.h>
#include <RF430CL.h>
#include <NDEF.h>
#include <NDEF_TXT.h>

#define RF430CL330H_BOOSTERPACK_RESET_PIN  8
#define RF430CL330H_BOOSTERPACK_IRQ_PIN    12

RF430 nfc(RF430CL330H_BOOSTERPACK_RESET_PIN, RF430CL330H_BOOSTERPACK_IRQ_PIN);

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

  Serial.println("Hello World - NFC edition!");
  Serial.println("Here we will post the text \"Hello World\" to the RF430CL330H.");

  Serial.println("Initializing I2C and RF430CL330H-");
  Wire.begin();  // Initialize I2C subsystem
  nfc.begin();   // Format RF430CL330H, prepare for data
  // Register interrupt to wake MCU when RF430CL330H INTO (IRQ) line triggers
  attachInterrupt(RF430CL330H_BOOSTERPACK_IRQ_PIN, wake_up, FALLING);

  Serial.println("Creating NFC NDEF_TXT object-");
  NDEF_TXT helloWorld("en", "Hello World");  // English

  Serial.println("Posting to RF430CL330H-");
  size_t ndef_size;

  ndef_size = helloWorld.sendTo(nfc);  // Write NDEF data to NFC device memory
  nfc.setDataLength(ndef_size);  // Inform NFC device memory how much data is there

  Serial.println("Activating RF430CL330H RF link-");
  nfc.enable();  // Now we're live!
}

void loop() {
  if (nfc.loop()) {
    if (nfc.wasRead()) {
      Serial.println("Something has read the NFC device!");
    }
    if (nfc.available()) {
      Serial.println("Something has re-written the NFC device!");
      nfc.flush();
    }
    nfc.enable();  // If nfc.loop() returns true, it will have disabled the RF link as a side-effect.
  }

  Serial.println("<low power sleep>");
  Serial.flush();  // wait for unsent UART data to flush out before going into low-power sleep
  suspend();  // Enter indefinite sleep (LPM4 on MSP430, DEEPSLEEP on ARM)
  Serial.println("<wake up>");
}

void wake_up()
{
  wakeup();  // Signal Energia to wake the MCU upon IRQ exit
}

Share this post


Link to post
Share on other sites

Do you know if this library will function with the cc3200?

I think it should but you need to make sure the correct I2C pins on the cc3200 are connected to the RF430 chip. Haven't tested it myself.

 

Sent from my Galaxy Note II using Tapatalk

Share this post


Link to post
Share on other sites

I think it should but you need to make sure the correct I2C pins on the cc3200 are connected to the RF430 chip. Haven't tested it myself.

 

Sent from my Galaxy Note II using Tapatalk

It does not appear that they match up. Im kind of new to reading schematics, but I found another post that says the cc3200 uses pins 9 and 10 for i2c, and I believe Im reading correctly, that that is not what the rf430 uses. 

Share this post


Link to post
Share on other sites

It does not appear that they match up. Im kind of new to reading schematics, but I found another post that says the cc3200 uses pins 9 and 10 for i2c, and I believe Im reading correctly, that that is not what the rf430 uses.

Sounds right. Pins 9 & 10 are the "new standard" location for I2C. Might be worth trying to jumper the boosterpack's pins over or coming up with some other solution.

 

Sent from my Galaxy Note II using Tapatalk

Share this post


Link to post
Share on other sites

Sounds right. Pins 9 & 10 are the "new standard" location for I2C. Might be worth trying to jumper the boosterpack's pins over or coming up with some other solution.

 

Sent from my Galaxy Note II using Tapatalk

 

Ti employee using jumpers. Though probably not using energia for this. 

Share this post


Link to post
Share on other sites

tried the fr430CL330h booster pack on the cc3200 launchpad and it hung on nfc.begin  using energia 16.  the example code uses the following pins.

#define RF430CL330H_BOOSTERPACK_RESET_PIN  8

#define RF430CL330H_BOOSTERPACK_IRQ_PIN    12
 
Do you have any further instructions on what was done with the jumpers and example code in the above example to make it work.    

Share this post


Link to post
Share on other sites

I never tested it with a CC3200, just MSP430F5529 and TM4C129 launchpads IIRC. Make sure the RF430 bpak is connected to the right pins for I2C support on the CC3200.

 

Sent from my Galaxy Note II using Tapatalk

Share this post


Link to post
Share on other sites

@spirilis  helloo !! 

can you give me insteructions for read (data pins) with my Phone (NFC), how to write RF430BP with this data and read them in my phone.

I'm using TM4C123GH6PM
helps please !!

regardas. Insert other media

Share this post


Link to post
Share on other sites
8 hours ago, Rei Vilo said:

So unfortunately, don't expect others to do your homework. Instead, they may provide you pointers. 

See Netiquette for Newbies

nooooo !!! 

It's not what I'm looking for, I just need to be guided, I don't want you to do my homework.

 What I usually do is take examples and modify them for my need.

I mean that I have covered the code provided above, but it does not work for me, so I asked. To know if something I am doing wrong. Then when communication works, I will change things my way.

thank you for your answer.

Greetings.

Share this post


Link to post
Share on other sites

hello !! 

Everything in order, it works.

now what I need to know is, can I send float type data? If so, how?

 

Share this post


Link to post
Share on other sites

my code is : 

 

#include "NDEF.h"
#include "NDEF_TXT.h"
#include <RF430CL.h>
#include <Wire.h>


#define RF430CL330H_BOOSTERPACK_RESET_PIN  8
#define RF430CL330H_BOOSTERPACK_IRQ_PIN    12

RF430 nfc(RF430CL330H_BOOSTERPACK_RESET_PIN, RF430CL330H_BOOSTERPACK_IRQ_PIN);

double randomDouble(double min, double max, int numCasas){
  long _min = min * pow(10, numCasas) + 0.1; 
  long _max = max * pow(10, numCasas) + 0.1;
  return (double) random(_min, _max) / pow(10, numCasas) ; 
}       

        double Freq = randomDouble(10.71, 10.79, 2)+1839755.00;
        double voltage_1 = randomDouble(0.82, 0.88, 2);
        double temperature = randomDouble(18.30, 20.00, 2);
        double vol = randomDouble(3.10, 3.29, 2);
        
void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("Initializing I2C and RF430CL330H-");
  Wire.begin();                                                              // Initialize I2C subsystem
  nfc.begin();                                                              // Format RF430CL330H, prepare for data
  attachInterrupt(RF430CL330H_BOOSTERPACK_IRQ_PIN, wake_up, FALLING);      // Register interrupt to wake MCU when RF430CL330H INTO (IRQ) line triggers

  Serial.println("Creating NFC NDEF_TXT object-");
   
  String Value = "El valor actual de F_Tiva es de "; 
  Value = Value + (Freq/1000000) + " MHz. El V_Tiva detectado es de " + voltage_1;
  Value = Value + ", la temperatura_Nodo1 es" + temperature + ", el voltaje_Nodo1 es" + vol;
  Value = Value + ", la temperatura_Nodo2 es" + temperature + ", el voltaje_Nodo2 es" + vol + ". El informe de estado del equipo ha terminado. Hasta pronto.";
  
  Serial.println("Posting to RF430CL330H-");
  size_t ndef_size;

  ndef_size = Value.sendTo(nfc);                                       // Write NDEF data to NFC device memory
  nfc.setDataLength(ndef_size);                                            // Inform NFC device memory how much data is there

  Serial.println("Activating RF430CL330H RF link-");
  nfc.enable();  // Now we're live!
}

void loop() {
  if (nfc.loop()) {
    if (nfc.wasRead()) {
      Serial.println("Something has read the NFC device!");
    }
    if (nfc.available()) {
      Serial.println("Something has re-written the NFC device!");
      nfc.flush();
    }
    nfc.enable();  // If nfc.loop() returns true, it will have disabled the RF link as a side-effect.
  }

  Serial.println("<low power sleep>");
  Serial.flush();  // wait for unsent UART data to flush out before going into low-power sleep
  suspend();  // Enter indefinite sleep (LPM4 on MSP430, DEEPSLEEP on ARM)
  Serial.println("<wake up>");
}

void wake_up()
{
  wakeup();  // Signal Energia to wake the MCU upon IRQ exit
}

I've errors .... 

nfc_1.cpp: In function 'void setup()':
nfc_1.cpp:40:21: error: 'class String' has no member named 'sendTo'
   Value = Value + (Freq/1000000) + " MHz. El V_Tiva detectado es de " + voltage_1;
                     ^

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now