Как записать целочисленное значение в RFID-метку?

Я работаю над проектом, в котором будут использоваться два Arduino. Каждый Arduino подключен к RFID-считывателю. Первый считыватель RFID должен записать целое значение в обнаруженную метку, тогда как второй считыватель RFID прочитает значение, записанное Arduino 1.

У меня возникла проблема с записью целочисленного значения в тег. Я нашел множество библиотек, включающих функции, записывающие в тег только строки или символы. Но мне нужно написать целое число. Может ли кто-нибудь помочь мне решить эту проблему?

Ниже приведен код, который я нашел и попытался отредактировать, чтобы функции записи и чтения принимали (целочисленные значения) в качестве содержимого блока. Однако, как и ожидалось, это не сработало, поскольку эти функции предназначены для приема массивов.

/******************************************
   PURPOSE:  Learn to use the MF522-AN RFID card reader
  Created by      Rudy Schlaf for www.makecourse.com
  DATE:   2/2014
*******************************************/

/*
  This sketch uses the MFRC522 Library to use ARDUINO RFID MODULE KIT   13.56 MHZ WITH TAGS SPI W AND R BY COOQROBOT.
  The library file MFRC522.h has a wealth of useful info. Please read it.
  The functions are documented in MFRC522.cpp.

  Based on code Dr.Leong   ( WWW.B2CQSHOP.COM )
  Created by Miguel Balboa (circuitito.com), Jan, 2012.
  Rewritten by Søren Thing Andersen (access.thing.dk), fall of 2013
  (Translation to English, refactored, comments, anti collision, cascade levels.)

           This library has been released into the public domain.
*/

#include <SPI.h>//подключаем библиотеку шины SPI
#include <MFRC522.h>//подключаем библиотеку RFID-считывателей

#define SS_PIN 10  // вывод выбора подчиненного устройства
#define RST_PIN 5  //сброс PIN-кода

MFRC522 rfid(SS_PIN, RST_PIN);

MFRC522::MIFARE_Key key;
char order = 49;

void setup() {
  Serial.begin(9600);        // Инициализируем последовательную связь с ПК
  SPI.begin();               // Инициализация шины SPI
  mfrc522.PCD_Init();        // Инициализация карты MFRC522 (если вам интересно, что означает PCD: устройство бесконтактной связи)
  Serial.println("Scan a MIFARE Classic card");

  // Подготовьте ключ безопасности для функций чтения и записи — все шесть байтов ключа установлены в 0xFF при поставке чипа с завода.
  // Так как карты в комплекте новые и ключи никогда не определялись, то они 0xFF
  // если бы у нас была карта, запрограммированная кем-то другим, нам нужно было бы знать ключ, чтобы получить к ней доступ. Вместо этого этот ключ необходимо будет сохранить в «key».

  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;//keyByte определен в параметре «MIFARE_Key». определение структуры в файле .h библиотеки.
  }

}

int block = 2; //это номер блока, в который мы будем записывать и затем читать. Не записывайте в блок «трейлер сектора», так как это может сделать блок непригодным для использования.

byte blockcontent[16] = {"SubScribe______"};//определен массив из 16 байт для записи в один из 64 блоков карты!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//byte blockcontent[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//все нули. Это можно использовать для удаления блока.
byte readbackblock[18];//Этот массив используется для чтения блока. Методу MIFARE_Read требуется буфер размером не менее 18 байт для хранения 16 байт блока.

void loop() {
  /*****************************************establishing contact with a tag/card**********************************************************************/
  // Ищем новые карты (если вам интересно, что означает PICC: бесконтактная интегральная плата)
  if ( ! mfrc522.PICC_IsNewCardPresent()) {//если PICC_IsNewCardPresent возвращает 1, новая карта найдена и мы продолжаем
    return;//если новая карта не найдена, возвращается '0' и мы возвращаемся к началу цикла
  }

  // Выбираем одну из карт
  if ( ! mfrc522.PICC_ReadCardSerial()) {//если PICC_ReadCardSerial возвращает 1, то "uid" struct (см. строки 238–45 MFRC522.h) содержит идентификатор прочитанной карты.
    return;// если он возвращает «0», что-то пошло не так, и мы возвращаемся к началу цикла
  }

  // Помимо прочего, метод PICC_ReadCardSerial() считывает UID и SAK (подтверждение выбора) в структуру mfrc522.uid, экземпляр которой также создается
  // во время этого процесса.
  // UID необходим в процессе аутентификации
  // Структура Uid:
  //определение типа структуры {
  //размер в байтах; // Количество байтов в UID. 4, 7 или 10.
  //байт uidByte[10]; //идентификатор пользователя в 10 байт.
  //байт сак; // Байт SAK (подтверждение выбора), возвращенный из PICC после успешного выбора.
  // Uid;

  Serial.println("card selected");

  /*****************************************writing and reading a block on the card**********************************************************************/
  writeBlock(block, blockcontent);//массив содержимого блока записывается в блок карты
  //mfrc522.PICC_DumpToSerial(&(mfrc522.uid));

  //Метод PICC_DumpToSerial «сбрасывает» весь блок данных MIFARE в последовательный монитор. Очень полезно при программировании скетча с помощью RFID-считывателя...
  //Примечания:
  //(1) Карты MIFARE скрывают ключ A во всех блоках концевика и отображают 0x00 вместо 0xFF. Это функция безопасности. Ключ B по умолчанию является общедоступным.
  //(2) Карта должна находиться на считывателе на протяжении всего времени дампа. Если он будет удален преждевременно, создание дампа прервется и появится сообщение об ошибке.
  //(3) Дамп занимает больше времени, чем время, отведенное для взаимодействия на пару между считывателем и картой, т.е. функция readBlock ниже выдаст таймаут, если
  // используется дамп.

  //mfrc522.PICC_DumpToSerial(&(mfrc522.uid));//раскомментируйте это, если хотите увидеть всю память размером 1 КБ с записанным в нее блоком.

  readBlock(block, readbackblock);//читаем блок обратно
  Serial.print("read block: ");
  for (int j = 0 ; j < 16 ; j++) {
    //печатаем содержимое блока
    Serial.write (readbackblock[j]);//Serial.write() передает числа ASCII в виде удобочитаемых символов на последовательный монитор
  }
  Serial.println("");
}

int writeBlock(int blockNumber, byte arrayAddress[]) {
  //это гарантирует, что мы записываем только в блоки данных. Каждый четвертый блок представляет собой завершающий блок с информацией о доступе/безопасности.
  int largestModulo4Number = blockNumber / 4 * 4;
  int trailerBlock = largestModulo4Number + 3; //определяем блок трейлера для сектора
  if (blockNumber > 2 && (blockNumber + 1) % 4 == 0) {
    Serial.print(blockNumber);  //номер блока — концевой блок (по модулю 4); выйти и отправить код ошибки 2
    Serial.println(" is a trailer block:");
    return 2;
  }
  Serial.print(blockNumber);
  Serial.println(" is a data block:");

  /*****************************************authentication of the desired block for access***********************************************************/
  byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
  //байт PCD_Authenticate(байтовая команда, байтовый адрес блока, MIFARE_Key *key, Uid *uid);
  //этот метод используется для аутентификации определенного блока для записи или чтения
  //команда: см. перечисления выше -> PICC_CMD_MF_AUTH_KEY_A = 0x60 (=1100000), // эта команда выполняет аутентификацию с помощью ключа A
  //blockAddr — номер блока от 0 до 15.
  //MIFARE_Key *key — это указатель на структуру MIFARE_Key, определенную выше, эту структуру необходимо определить для каждого блока. Новые карты имеют все A/B = FF FF FF FF FF FF.
  //Uid *uid — указатель на структуру UID, содержащую идентификатор пользователя карты.
  if (status != MFRC522::STATUS_OK) {
    Serial.print("PCD_Authenticate() failed: ");
    Serial.println(mfrc522.GetStatusCodeName(status));
    return 3;//вернуться "3" как сообщение об ошибке
  }
  //похоже, что аутентификацию необходимо выполнять перед чтением/записью каждого блока в определенном секторе.
  //Если аутентифицируется другой сектор, доступ к предыдущему теряется.

  /*****************************************writing the block***********************************************************/

  status = mfrc522.MIFARE_Write(blockNumber, arrayAddress, 16);//valueBlockA — номер блока, MIFARE_Write(номер блока (0–15), массив байтов, содержащий 16 значений, количество байтов в блоке (=16))
  //статус = mfrc522.MIFARE_Write(9, value1Block, 16);
  if (status != MFRC522::STATUS_OK) {
    Serial.print("MIFARE_Write() failed: ");
    Serial.println(mfrc522.GetStatusCodeName(status));
    return 4;//вернуться "4" как сообщение об ошибке
  }
  Serial.println("block was written");
}


int readBlock(int blockNumber, byte arrayAddress[]) {
  int largestModulo4Number = blockNumber / 4 * 4;
  int trailerBlock = largestModulo4Number + 3; //определяем блок трейлера для сектора

  /*****************************************authentication of the desired block for access***********************************************************/
  byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
  //байт PCD_Authenticate(байтовая команда, байтовый адрес блока, MIFARE_Key *key, Uid *uid);
  //этот метод используется для аутентификации определенного блока для записи или чтения
  //команда: см. перечисления выше -> PICC_CMD_MF_AUTH_KEY_A = 0x60 (= 1100000),
  // эта команда выполняет аутентификацию с помощью ключа A
  //blockAddr — номер блока от 0 до 15.
  //MIFARE_Key *key — это указатель на структуру MIFARE_Key, определенную выше, эту структуру необходимо определить для каждого блока. Новые карты имеют все A/B = FF FF FF FF FF FF.
  //Uid *uid — указатель на структуру UID, содержащую идентификатор пользователя карты.
  if (status != MFRC522::STATUS_OK) {
    Serial.print("PCD_Authenticate() failed (read): ");
    Serial.println(mfrc522.GetStatusCodeName(status));
    return 3;//вернуться "3" как сообщение об ошибке
  }
  //похоже, что аутентификацию необходимо выполнять перед чтением/записью каждого блока в определенном секторе.
  //Если аутентифицируется другой сектор, доступ к предыдущему теряется.


  /*****************************************reading a block***********************************************************/

  byte buffersize = 18;//нам нужно определить переменную с размером буфера чтения, поскольку приведенному ниже методу MIFARE_Read нужен указатель на переменную, содержащую размер...
  status = mfrc522.MIFARE_Read(blockNumber, arrayAddress, &buffersize);//&buffersize — указатель на переменную buffersize; MIFARE_Read требует указатель, а не просто число.
  if (status != MFRC522::STATUS_OK) {
    Serial.print("MIFARE_read() failed: ");
    Serial.println(mfrc522.GetStatusCodeName(status));
    return 4;//вернуться "4" как сообщение об ошибке
  }
  Serial.println("block was read");
}

, 👍2

Обсуждение

Было бы легче показать вам, как это сделать, если бы вы включили ссылку на библиотеку, которую используете. И фрагмент кода, который вы пытаетесь заставить работать., @Mikael Patel

@MikaelPatel Я приложил код, который пытаюсь отредактировать., @Raya

Как я уже говорил в вопросе, мне нужен код, который будет записывать и читать целые числа как содержимое блока или есть способ представлять целые числа в виде строки и при этом иметь возможность их увеличивать., @Raya


1 ответ


0

Предположим, у вас есть массив и целое число.

unsigned char blockcontent[16];
int number = 15;

Чтобы сохранить int в позиции 0 blockcontent, сделайте следующее:

memcpy(blockcontent, &number, sizeof(int));

Если вы хотите, чтобы он находился в другом месте, выполните blockcontent+offset.

Если вы хотите прочитать int из blockcontent, сделайте обратное:

memcpy(&number, blockcontent, sizeof(int));

Вот и все.

,