RFID + IoT + Ethereum Blockchain

This is a very quick post, mostly code-only, showing how to read RFID tags on say an assembly line, process those using a WiFi IoT device (Adafruit Huzzah), extract the product serial number from the RFID tag and send that as part of a transaction to an Ethereum Blockchain.

I am using a MiFare RFID card reader, but you would want to use a long-range reader that supports low-cost sticker tags. POSTing the transaction to the blockchain takes a second or two, so don’t expect to scan 100 products/second flying past the reader and manage to submit those as transactions.

URL’s and codes are hard-baked, so consider how you want to post the transaction. I use static Ethereum addresses and stick the product ID in the data portion, you might want to read that from the RFID tags as well.

Once your product ID is in the blockchain, you might want to move that to your ERP system, or even a cool PowerApp or something. Unless you want to code X++ and mess around with your production systems, I suggest using Xalentis Fusion instead, to enable code-free integration between Ethereum and Microsoft Dynamics 365 for Finance and Operations. It also supports SMS, Email messaging, Service Bus messaging, Flow, PowerApps and Common Data Service.

Enjoy.

#include <SPI.h>
#include <MFRC522.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
 
#define RST_PIN         15
#define SS_PIN          2
#define SSID            "mywifiSSID" 
#define PASS            "password" 
 
MFRC522 mfrc522(SS_PIN, RST_PIN);
 
void setup() {
  Serial1.begin(115200);
  while(!Serial1){}
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
  WiFi.begin(SSID, PASS);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
}
 
void loop()
{
  // Using MiFare card reader here, for production use sticker tags and high-speed reader instead
  MFRC522::MIFARE_Key key; // default to FFFFFFFFFFFF
  key.keyByte[0] = 0xFF;
  key.keyByte[1] = 0xFF;
  key.keyByte[2] = 0xFF;
  key.keyByte[3] = 0xFF;
  key.keyByte[4] = 0xFF;
  key.keyByte[5] = 0xFF;
 
  // Loop until RFID tag is presented 
  if (!mfrc522.PICC_IsNewCardPresent()) return;
  if (!mfrc522.PICC_ReadCardSerial()) return;

  byte readbuffer1[18];
  byte readbuffer2[18];
  byte block;
  MFRC522::StatusCode status;
  byte len;
  byte sizeread = sizeof(readbuffer1);
  block = 0;
  
  status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid));
  if (status != MFRC522::STATUS_OK) {
    return;
  }
  else
  {
    for (int i = 0; i < 18; i++)
    {
      readbuffer1[i] = 0x00;
      readbuffer2[i] = 0x00;
    }
    // read product ID from RFID tag
    status = mfrc522.MIFARE_Read(1, readbuffer1, &sizeread);
    if (status != MFRC522::STATUS_OK)
    {
      return;
    }
    mfrc522.PICC_HaltA();
    mfrc522.PCD_StopCrypto1();
  }
 
  // convert product ID from RFID tag to hex string
  String data = "0x";
  for (int j=0; j<18;j++)
  {
    if (readbuffer1[j]=='\0') break;
    data = data + String(readbuffer1[j], HEX);
  }

  // build up our Ethereum transaction
  StaticJsonBuffer<1000> JSONbufferTwo;  
  JsonObject& uploadJSON = JSONbufferTwo.createObject(); 
  uploadJSON["jsonrpc"] = "2.0";
  uploadJSON["method"] = "personal_sendTransaction";      
  JsonArray&  uploadQueryParams = uploadJSON.createNestedArray("params");
  JsonObject& callTxParams = JSONbufferTwo.createObject();
  callTxParams["from"] = "0x27f6f763ae5c52721db57c4423c298a78de1f22a";
  callTxParams["to"] = "0xcaade3aa018d57d808fceb16824c47dfd206484c";
  callTxParams["value"] = "0x6FC23AC00"; //hex value 30 Gwei 
  callTxParams["gas"] = "0x30D40"; //hex value for 200000 -high gas limit for good measure          
  callTxParams["gasPrice"] = "0x6FC23AC00"; //hex value 30 Gwei gasprice 21gwei is typical
  callTxParams["data"] = data;
  uploadQueryParams.add(callTxParams);
  uploadQueryParams.add("bigsecretaccountpassword");
  uploadJSON["id"] = 1;
  String uploadString;
  uploadJSON.printTo(uploadString);
  callGeth(uploadString); // send for mining
}

String callGeth(String inputJSON) // thanks to https://github.com/gusgorman402
{
  HTTPClient http;
  http.begin("http://your RPC address here:8545/");
  http.addHeader("Content-Type", "application/json");
  int httpCode = http.POST(inputJSON);
  String JSONResult = http.getString(); // contains Txn
  http.end();
  return JSONResult;
}

 

Advertisements