Пример MFRC522 ReadNUID перезагружается, если я не включу оператор null if
Я новичок в Arduino (и C), но не во встроенной электронике и программировании.
Я использую модуль MFRC522 (обычный) с Nano и получаю странные результаты. Они находятся на очень простой заказной печатной плате, которую я сделал (единственные части на ней, за исключением пары светодиодов на D4 и D5). Я использую SS_PIN на 8 и RST_PIN на 7, который изменен с 10 & 9, потому что на плате также будет использоваться модуль NRF24L01 на шине SPI (еще не установлен).
И я использую библиотеку MFRC522. Пример DumpInfo в библиотеке работает нормально, но не пример ReadNUID.
Когда я подношу метку/карту к считывателю, скетч (иногда) получает часть своего вывода на последовательный монитор, но затем (всегда) плата перезагружается, и снова появляются сообщения о запуске. Это происходит постоянно, пока карта находится рядом.
У меня есть RFID IRQ, подключенный к контакту D3, и, думая, что это может быть причиной проблемы, и пробуя всевозможные способы, я обнаружил, что это не так. В процессе я заставил скетч работать и сократил исправление до двух, казалось бы, лишних строк кода:-
Добавлен оператор null if в начале цикла:
if (GotIRQ) {}
и определил изменчивую переменную для проверки:-
volatile boolean GotIRQ=false;
Не работает, если он не изменчив. (Подсказка?)
Что дает? Какая-то глупая ошибка новичка?
(Я мог бы опубликовать весь код, если потребуется, но я снова начал с исходного кода и сделал только 2 изменения и 2 добавления, описанные выше)
Вот код:-
/*
* -------------------------------------------------- -------------------------------------------------- ------------------
* Пример скетча/программы, показывающий, как считывать новый NUID с PICC в последовательный порт.
* -------------------------------------------------- -------------------------------------------------- ------------------
* Это пример библиотеки MFRC522; для получения дополнительной информации и других примеров см.: https://github.com/miguelbalboa/rfid
*
* Пример скетча/программы, показывающий, как считывать данные с PICC (то есть с RFID-метки или карты) с использованием RFID на основе MFRC522.
* Считыватель на интерфейсе Arduino SPI.
*
* Когда Arduino и модуль MFRC522 подключены (см. раскладку контактов ниже), загрузите этот скетч в Arduino IDE.
* затем проверьте/скомпилируйте и загрузите его. Чтобы увидеть вывод: используйте Tools, Serial Monitor IDE (нажмите Ctrl+Shft+M). Когда
* вы предъявляете PICC (т. е. RFID-метку или карту) на расстоянии считывания считывателя/PCD MFRC522, последовательный выход
* покажет тип и NUID, если была обнаружена новая карта. Примечание. Вы можете увидеть сообщения «Тайм-аут связи».
* при слишком раннем удалении PICC с расстояния чтения.
*
* @license Выпущено в общественное достояние.
*
* Используемое типичное расположение выводов:
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 10 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*/
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 8 //QQ Это изменено с 10
#define RST_PIN 7 //QQ Это изменено с 9
MFRC522 rfid(SS_PIN, RST_PIN); // Экземпляр класса
MFRC522::MIFARE_Key key;
volatile boolean GotIRQ=false; // QQ требуется для нулевого оператора if
// Массив инициализации, в котором будет храниться новый NUID
byte nuidPICC[3];
void setup() {
Serial.begin(9600);
SPI.begin(); // Инициируем шину SPI
rfid.PCD_Init(); // Инициализация MFRC522
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
Serial.println(F("This code scan the MIFARE Classsic NUID."));
Serial.print(F("Using the following key:"));
printHex(key.keyByte, MFRC522::MF_KEY_SIZE);
}
void loop() {
if (GotIRQ) {} //QQ Если это не включено, плата сбрасывается при обнаружении метки RFID
// Ищем новые карты
if ( ! rfid.PICC_IsNewCardPresent())
return;
// Проверяем, был ли прочитан NUID
if ( ! rfid.PICC_ReadCardSerial())
return;
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
Serial.println(rfid.PICC_GetTypeName(piccType));
// Проверяем, что это PICC типа Classic MIFARE
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println(F("Your tag is not of type MIFARE Classic."));
return;
}
if (rfid.uid.uidByte[0] != nuidPICC[0] ||
rfid.uid.uidByte[1] != nuidPICC[1] ||
rfid.uid.uidByte[2] != nuidPICC[2] ||
rfid.uid.uidByte[3] != nuidPICC[3] ) {
Serial.println(F("A new card has been detected."));
// Сохраняем NUID в массив nuidPICC
for (byte i = 0; i < 4; i++) {
nuidPICC[i] = rfid.uid.uidByte[i];
}
Serial.println(F("The NUID tag is:"));
Serial.print(F("In hex: "));
printHex(rfid.uid.uidByte, rfid.uid.size);
Serial.println();
Serial.print(F("In dec: "));
printDec(rfid.uid.uidByte, rfid.uid.size);
Serial.println();
}
else Serial.println(F("Card read previously."));
// Остановить PICC
rfid.PICC_HaltA();
// Остановить шифрование на PCD
rfid.PCD_StopCrypto1();
}
/**
* Helper routine to dump a byte array as hex values to Serial.
*/
void printHex(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
/**
* Helper routine to dump a byte array as dec values to Serial.
*/
void printDec(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], DEC);
}
}
Хорошо, попытка сократить до минимального примера оказалась полезной. Кажется, проблема вызвана циклом, в котором хранится NUID, но не в том случае, если присутствует лишний оператор if. Код: -
// Урезанная версия библиотеки MFRC522, пример ReadNUID, который демонстрирует странгл
// проблема перезагрузки платы при поднесении карты к считывателю.
// Но только если:-
// * включен цикл Store NUID
// и
// * лишнего оператора "if" в начале цикла() НЕТ.
// Отличия от исходного примера обозначены комментариями, начинающимися с "//QQ"
// (плюс много удаленного кода)
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 8 //QQ Это изменено с 10
#define RST_PIN 7 //QQ Это изменено с 9
MFRC522 rfid(SS_PIN, RST_PIN); // Экземпляр класса
MFRC522::MIFARE_Key key;
volatile boolean GotIRQ=false; // QQ требуется для нулевого оператора if
// Массив инициализации, в котором будет храниться новый NUID
byte nuidPICC[3];
void setup() {
Serial.begin(9600);
SPI.begin(); // Инициируем шину SPI
rfid.PCD_Init(); // Инициализация MFRC522
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
Serial.println(F("This code scan the MIFARE Classsic NUID."));
}
void loop() {
// if (GotIRQ) {} //QQ Если это не включено, плата сбрасывается при обнаружении метки RFID
// Ищем новые карты
if ( ! rfid.PICC_IsNewCardPresent())
return;
// Проверяем, был ли прочитан NUID
if ( ! rfid.PICC_ReadCardSerial())
return;
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
Serial.println(rfid.PICC_GetTypeName(piccType));
// Сохраняем NUID в массиве nuidPICC // QQ не завершается ошибкой, если этот цикл исключен
for (byte i = 0; i < 4; i++) {
nuidPICC[i] = rfid.uid.uidByte[i];
}
// Остановить PICC
rfid.PICC_HaltA();
// Остановить шифрование на PCD
rfid.PCD_StopCrypto1();
}
@bertoid, 👍1
Обсуждение2 ответа
Я предполагаю, что дополнительный байт в массиве необходим, возможно, для нулевого терминатора или чего-то еще, и что в примере кода есть ошибка. У меня больше не было проблем после изменения NUID[3] на NUID[4], так что я остановлюсь на этом.
Вы определили, что этот массив состоит из трех элементов:
byte nuidPICC[3];
эти три элемента пронумерованы 0, 1 и 2.
В этом цикле for:
for (byte i = 0; i < 4; i++) {
nuidPICC[i] = rfid.uid.uidByte[i];
}
вы пишете в позицию 3, которая находится за пределами этого массива.
После записи за пределы массива поведение не определено. Сброс является одним из распространенных результатов. Но все могло случиться.
- Эмуляция стандартного периферийного USB-устройства Mifare с помощью RFID-RC522
- Библиотека I2C MIFARE RC522
- Использование контакта RST в качестве внешнего переключателя питания
- Считыватель Rfid и экран SD-карты не работают вместе
- Случайный сброс Arduino Nano
- Ошибка прерывания проекта Arduino?
- Сброс arduino nano после отключения tx/rx
- Есть ли способ заставить вывод RESET работать в обратном направлении?
Пожалуйста, вы можете опубликовать минимальный проверяемый пример кода. Извините, но просто добавление двух строк ничего не значит., @Code Gorilla
Добро пожаловать в Ардуино SE. Обязательно посетите тур, чтобы увидеть, как здесь все работает: https://arduino.stackexchange.com/Tour, @SDsolar
«минимальный проверяемый пример кода». Я хотел использовать код, с которым многие были бы знакомы, и просто показать простое изменение, которое я сделал, которое вызывает проблему. Я попытаюсь уменьшить его, но тогда у нас нет знакомой отправной точки. просто добавление двух строк ничего не значит., @bertoid
Эта система комментариев сбивает с толку. Я просто хотел начать новую строку, но она продолжала публиковаться каждый раз, поэтому мой комментарий мог быть тарабарщиной, а затем время истекло для меня., @bertoid
Добавлен мой модифицированный код примера и его минимальная версия. Кажется, что цикл, в котором хранится NUID, вызывает проблему (новая проблема), и включение оператора null if исправляет ее (исходная проблема)., @bertoid
Я включил этот код в другой скетч, также используя SPI для связи с NRF24L01, и снова появляется (другая) проблема, когда присутствует код для хранения NUID. "я=0; я<4;" означает, что цикл выполняется 4 раза с i=0,1,2,3. Правильный? Но если я изменю объявление массива на «byte NUID [4]», проблема исчезнет. Но ведь это 5 байт, не так ли? Значит, не должно быть переполнения с NUID[3]?, @bertoid