Skip to content

Quickstart

The goal of this page: within about fifteen minutes, you connect an NRN reader and watch EPCs print to the console every time a tag enters the read zone. You need an NRN reader, a cable to your computer, and at least one RFID tag; if the hardware has not arrived yet, read integrating with your software first, since the code side can be built without a physical reader. Every example uses the public 1.0.0 API of the Nextwaves SDK.

Before you start

  1. Install the CP210x driver from the repository's driver/ folder if your reader uses the USB-to-UART bridge.
  2. Identify the serial port: /dev/ttyUSB0 on Linux, /dev/tty.usbserial-* on macOS, COM3 on Windows.
  3. On Linux, add your account to the dialout group, or opening the port fails with a permission error.
  4. Keep the default serial settings, 115200 baud, 8 data bits, 1 stop bit, no parity, no flow control: the SDK already uses exactly these values, so change them only if your device's documentation says otherwise.

What a session looks like

Every example below, regardless of language, walks the same four steps:

See this frame once and every code sample below becomes instantly readable.

Python

bash
pip install nrn-sdk
python
import logging
import time

from nrn import create_reader

reader = create_reader("/dev/ttyUSB0", baudrate=115200, log_level=logging.INFO)
reader.open()

try:
    reader.Connect_Reader_And_Initialize()
    print(reader.Query_Reader_Information())
    print(reader.query_rfid_ability())

    reader.configure_reader_power({1: 25}, persistence=False)

    def on_tag(tag):
        print(tag["epc"], tag["rssi"], tag["antenna_id"])

    reader.start_inventory_with_mode(antenna_mask=[1], callback=on_tag)
    time.sleep(5)
    reader.stop_inventory()
finally:
    reader.close()

start_inventory_with_mode takes a list of antenna numbers counted from 1 and converts it into the antenna mask itself. It starts a background thread that receives data from the reader and calls on_tag for every tag read; stop_inventory stops that thread and tells the reader to stop.

TypeScript and Web Serial

bash
npm install @nextwaves/nrn-sdk
ts
import { createNRNReader, NRNWebSerial, type TagData } from "@nextwaves/nrn-sdk";

if (!NRNWebSerial.isSupported()) {
  throw new Error("This browser does not support the Web Serial API");
}

const reader = createNRNReader({ baudrate: 115200 });

// connect() opens the browser's port picker; it must run inside a user gesture.
await reader.connect();

try {
  console.log(await reader.queryReaderInformation());

  await reader.startInventory([1], (tag: TagData) => {
    console.log(tag.epc, tag.rssi, tag.antenna_id);
  });

  // The receive loop keeps invoking the callback until stopped.
} finally {
  await reader.stopInventory();
  await reader.disconnect();
}

Web Serial needs a secure context, meaning HTTPS or localhost, a Chromium-based browser, and a user gesture such as a button click before the port picker opens. startInventory calls stopInventory first, so restarting an inventory is safe.

Go

bash
go get github.com/Nextwaves-Industries/nextwaves-sdk/sdk/nation/go@v1.0.0
go
package main

import (
	"fmt"

	nrn "github.com/Nextwaves-Industries/nextwaves-sdk/sdk/nation/go"
)

func main() {
	reader, err := nrn.NewNRNReader("/dev/ttyUSB0", 115200)
	if err != nil {
		panic(err)
	}
	defer reader.Close()

	if err := reader.ConnectAndInitialize(); err != nil {
		panic(err)
	}

	info, err := reader.QueryReaderInformation()
	if err != nil {
		panic(err)
	}
	fmt.Println(info.SerialNumber, info.AppVersion)

	if err := reader.StartInventory(nrn.BuildAntennaMask([]int{1}), func(tag nrn.TagData) {
		fmt.Println(tag.EPC, tag.AntennaID)
	}); err != nil {
		panic(err)
	}

	_ = reader.StopInventory()
}

For continuous inventory inside a long-running service, use the complete Go receive loop in the receive loop appendix, ready to copy into your project.

Rust

toml
[dependencies]
nrn-sdk = "1.0.0"
rust
use nrn_sdk::NRNReader;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut reader = NRNReader::new("/dev/ttyUSB0", 115200)?;
    reader.connect_and_initialize()?;

    let info = reader.query_reader_information()?;
    println!("{} {}", info.serial_number, info.app_version);

    reader.start_inventory(0x0000_0001, |tag| println!("{}", tag.epc))?;
    reader.stop_inventory()?;
    Ok(())
}

The complete Rust receive loop also lives in the receive loop appendix.

C++

cmake
include(FetchContent)

FetchContent_Declare(
  nrn_sdk
  GIT_REPOSITORY https://github.com/Nextwaves-Industries/nextwaves-sdk.git
  GIT_TAG v1.0.0
  SOURCE_SUBDIR sdk/nation/cpp
)

FetchContent_MakeAvailable(nrn_sdk)

target_link_libraries(your_target PRIVATE nrn-sdk)
cpp
#include "nrn.hpp"

int main() {
    nrn::NRNReader reader("/dev/ttyUSB0", 115200);
    if (!reader.open()) {
        return 1;
    }

    reader.connect_and_initialize();
    auto info = reader.query_reader_information();

    reader.start_inventory(0x00000001, [] (const nrn::TagData& tag) {
        std::cout << tag.epc << std::endl;
    });

    std::this_thread::sleep_for(std::chrono::seconds(5));
    reader.stop_inventory();
    reader.close();
    return 0;
}

Requires C++17 and CMake 3.14 or later. The complete C++ receive loop lives in the receive loop appendix.

When you go to production, follow this order

The quickstart above deliberately skips steps so you see tags fast. A production integration walks all eight:

  1. Record the reader's model and firmware version, and keep the firmware documentation with the project.
  2. Open the serial port and initialize the connection.
  3. Query the reader's identity and abilities, and log both on every session.
  4. Configure the antenna mask, per-port power, RF band, and the channels legal at the site.
  5. Set the deduplication filter window from the business event, not the maximum read rate.
  6. Start the inventory and deduplicate EPCs over your own business window.
  7. Turn raw reads into business events that can be replayed safely.
  8. Stop the inventory, let the SDK drain what is pending, then close the serial port.

Easy Inventory operations and RFID integration documentation