top of page
admin

Introduction to Impinj R700-series RFID Readers using MQTT and TallyFlow

Introduction

In recent versions of the Impinj firmware, Impinj added support for IoT to their fixed RFID readers. In addition to Kafka, Webhooks and HTTP, Impinj added support for MQTT. MQTT (Message Queuing Telemetry Transport) is a lightweight, publish-subscribe message communication system designed primarily for Internet of Things (IoT) environments. It consists of a broker and one or more clients who issue commands on, and listen to specific communication topics. The broker disseminates the messages to the listening clients.


An Impinj R7xx reader that is configured to use MQTT is an MQTT client. It will connect to a broker such as RabbitMQ, Mosquitto, EMQX, Rumqqtd or others. The TallyFlow-IoT software is also a client that connects to the same broker. The broker will pass the messages between the clients based on the message topic queues. If you already understand the basics of a MQTT Broker setup, skip to the Reader Configuration section.


The MQTT client implementation from Impinj is currently only for tag data and other reader events. It does not listen for commands. Therefore, our implementation uses a combination of MQTT and HTTP. Check with the SDG support team for the latest information on our Impinj implementation.


Running a MQTT demo


MQTT Setup

To use the MQTT features of the Impinj R7xx reader, you will need a MQTT broker. MQTT testing can be done with the EMQX MQTT docker image. For example:

docker run -d --name emqx -e EMQX_LISTENER__TCP__EXTERNAL=1883 -p 18083:18083 -p 1883:1883 emqx/emqx:latest

You can also use the Rust rumqttd broker, which works well. You can run rumqttd with the following build command:

git clone https://github.com/bytebeamio/rumqtt.git	
cd rumqtt/rumqttd
cargo run --release -- -c rumqttd.toml

Additionally, you can use Mosquitto or other MQTT brokers.


Here is a sample Rust app that will verify that the EMQX docker or rumqttd service is running correctly. E.g. use `cargo new mqtt`, then put the code into the resulting src/main.rs file.

use rumqttc::{MqttOptions, AsyncClient, QoS, Event, Incoming};
use serde::{Serialize, Deserialize};
use std::time::Duration;
#[derive(Serialize, Deserialize, Debug)]
struct TestCommand {
    msg: String,
}
#[tokio::main]
async fn main() {
    let mut mqtt_options = MqttOptions::new("localhost", "127.0.0.1", 1883);
    mqtt_options.clean_session();
    mqtt_options.set_keep_alive(Duration::from_secs(5));
    let (client, mut eventloop) = AsyncClient::new(mqtt_options, 10);
    // Assuming the response will be on the topic "Impinj/rfid/response"
    client.subscribe("testtopic/#", QoS::AtLeastOnce).await.unwrap();
    let command = TestCommand {
        msg: "hello ".to_string(),
    };
    let cmd2 = TestCommand {
        msg: "world!".to_string(),
    };
    let payload = serde_json::to_string(&command).unwrap();
    println!("publishing: {:?}", payload);
    let pay2 = serde_json::to_string(&cmd2).unwrap();
    println!("publishing: {:?}", pay2);
    let topic = "testtopic/test";
    client.publish(topic, QoS::AtLeastOnce, false, payload).await.unwrap();
    client.publish(topic, QoS::AtLeastOnce, false, pay2).await.unwrap();
    // let mut interval = time::interval(Duration::from_secs(1));
    while let Ok(event) = eventloop.poll().await {
        println!("Received = {:?}", event);
        match event {
            Event::Incoming(pkt) => {
                match pkt {
                    Incoming::Publish(pubpack) => {
                        let item: TestCommand = serde_json::from_slice(&pubpack.payload).unwrap();
                        println!("Packet = {:?}", item);
                    },
                    _ => {},
                }
            },
            _ => {},
        }
    }
}

In your Cargo.toml file, you will need the following dependencies:

[dependencies]
rumqttc = "0.22.0"
tokio = { version = "1", features = ["full"] }
serde = { version = "^1.0", features = ["derive"] }
serde_derive = "^1.0"
serde_json = "^1.0"

Reader Configuration

Several aspects of the reader must be configured to use the TallyFlow IoT software. These include MQTT (minimally), but should also include HTTP and Events to receive.


MQTT Configuration

MQTT must be enabled for TallyFlow IoT. For general compatibility with what we’re doing on the Zebra IoT units, let’s create the following MQTT topic. We recommend using unique names for each reader. The broker can listen for an individual reader or for all of them.


  • /R70015DB97/data/events (R700 + unique MAC addresses bytes)


HTTP Configuration

Our version 0.1 plugin for Impinj support does not support HTTP authentication, but basic auth can be added. Please let us know if this is required.


Event Configuration

The Impinj reader allows you to configure which fields to see on the events. Here is our current testing configuration; however EPC Hex is not required. Other configurations may be supported. We can discuss the needs at the time of a new customer implementation.


Conclusion

The support for MQTT and other IoT mechanisms greatly modernizes and enhances the Impinj R7xx RFID readers.


We are offering sample Rust code to communicate with the Impinj reader at no cost. If you are interested in obtaining access to this code, please contact us. 


To obtain a broader introduction to the Impinj R7xx firmware and IoT configuration, 

Impinj documentation may be found here:


9 views0 comments

Comments


bottom of page