Serial.available работает только в первый раз
Я работаю над RFID. Я отправляю данные через последовательный монитор, и Serial. available не идентифицирует данные после первого раза, он отлично работает только один раз после повторного открытия comport.
Я перепробовал все возможные изменения, которые мог внести в код. Я хочу, чтобы при запуске этого кода после ввода данных в последовательный монитор отображалось «Сканировать карту mifare», а после сканирования карты выполнялось действие чтения или записи.
#include <SPI.h>//включаем библиотеку шины SPI
#include <MFRC522.h>//включить библиотеку считывателя RFID
#define SS_PIN 10 //выбор ведомого контакта
#define RST_PIN 9 //сбросить пин
MFRC522 mfrc522(SS_PIN, RST_PIN); // создание объекта считывателя MFRC522.
MFRC522::MIFARE_Key key;//создаем структуру MIFARE_Key с именем 'key', в которой будет храниться информация о карте
void setup()
{
Serial.begin(9600); // Инициализируем последовательную связь с ПК
SPI.begin(); // Инициируем шину SPI
mfrc522.PCD_Init();
//пока(!Серийный); // Подождите, пока серийный номер не будет готов - Леонардо
//Serial.println("Введите данные");
}
String incomingStr;
byte blockcontent[16];
int count=0;
String arr2[6];
int arr3[6];
int u2=0;
String arr[16];
int arr1[16];
int u=0;
int y;
char action;
//int newc=0;
void loop()
{
// Serial.println("бахар");
if (Serial.available())
{
doReceive();
int newc=0;
while(newc==0)
{
if ( ! mfrc522.PICC_IsNewCardPresent())
{
if(count==0)
{
Serial.println("Scan your mifare card %");
count++;
}
}
else
{
newc=1;
}
}
if ( ! mfrc522.PICC_ReadCardSerial())
{
return;
}
if(action=='%')
{
doWrite();
}
else if(action=='$')
{
doRead();
}
else if(action=='^')
{
for (byte i = 0; i < mfrc522.uid.size; ++i)
{ // читаем id (по частям)
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
}
Serial.print("*");
}
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
Serial.flush();
}
}
void doReceive()
{
incomingStr = Serial.readString();
int sto=incomingStr.indexOf(')');
action=incomingStr.charAt(sto+1);
y=sto+2;
for(int j=0;j<sto;j++)
{
if(incomingStr.charAt(j)!= ' ')
{
//Serial.print(incomingStr.charAt(j));
//arr[u]=arr[u].concat(incomingStr.charAt(j));
arr2[u2]+=incomingStr.charAt(j);
}
else
{
//Serial.println(arr[u]);
u2++;
}
}
for(u2=0;u2<6;u2++)
{
arr3[u2]=arr2[u2].toInt();
key.keyByte[u2]=arr3[u2];
//Serial.println(key.keyByte[u2]);
}
}
void doWrite()
{
int block=1;
for(int i=0;i<incomingStr.length();i=i+16)
{
if(block == 3 || block ==7 || block ==11 || block ==15 || block ==19 || block ==23 || block ==27 || block ==31 || block ==35 || block ==39 || block ==43 || block ==47 || block ==51 || block ==55 || block ==59 || block ==63)
{
block=block+1;
}
for(int u=0;u<16;u++)
{
blockcontent[u]=0;
//Serial.println(arr1[u]);
}
String s1=incomingStr.substring(y+i,y+16+i);
s1.getBytes((char *) blockcontent, 30);
writeBlock(block, blockcontent);
block=block+1;
}
Serial.println("Data written successfully*");
}
void doRead()
{
int block=1;
for(int i=0;i<4;i++)
{
if(block == 3 || block ==7 || block ==11 || block ==15 || block ==19 || block ==23 || block ==27 || block ==31 || block ==35 || block ==39 || block ==43 || block ==47 || block ==51 || block ==55 || block ==59 || block ==63)
{
block=block+1;
}
byte readbackblock[18];
readBlock(block, readbackblock);//читаем блок назад
//Serial.print("Блок содержит: ");
for (int j=0 ; j<16 ; j++)//выводим содержимое блока
{
Serial.write (readbackblock[j]);//Serial.write() передает числа ASCII в виде удобочитаемых символов на последовательный монитор
}
//Серийный.println();
block=block+1;
}
Serial.println("*");
}
@user55609, 👍1
Обсуждение2 ответа
Прежде всего попробуйте добавить сюда эти отладочные отпечатки, чтобы увидеть, не становится ли цикл while бесконечным:
while(newc==0)
{
if ( ! mfrc522.PICC_IsNewCardPresent())
{
if(count==0)
{
Serial.println("Scan your mifare card %");
count++;
**Serial.println("test0")*
}
}
else
{
newc=1;
**Serial.println ("newc=1")**
}
}
arr2
имеет размер 6
. Вы убедились, что здесь
...
for(int j=0;j<sto;j++)
{
if(incomingStr.charAt(j)!= ' ')
{
arr2[u2]+=incomingStr.charAt(j);
}
else
{
u2++;
}
}
...
Вы не пишете за пределами этого массива?
Более того, вы никогда не устанавливаете начальное значение u2
явно перед запуском этого цикла — все, что осталось в глобальной переменной u2
от предыдущих использований, будет служить начальным значением для этого цикла.
Судя по беглому изучению остального кода, только самый первый вызов doReceive
начнет этот цикл с u2 == 0
. После этого каждый раз, когда вы будете вызывать doReceive
, вы будете начинать этот цикл с u2 == 6
, однозначно переполняя массив и уничтожая содержимое соседних ячеек памяти. Поведение не определено.
Я предполагаю, что это ситуация типа "глобальные переменные снова бьют". С какой стати u2
сделали глобальной переменной???
Вполне возможно, что вы можете "исправить" свой код, просто добавив u2 = 0;
перед вышеуказанным циклом. Но даже после этого код останется в довольно шатком состоянии.
- Использование прерываний с RC522
- Проблема совместного использования MISO с несколькими RFID-считывателями RC522
- rfid_default_keys проверить с помощью RC522
- MFRC522: прошивка неизвестна
- MFRC522 не сканируется карта
- RFID-RC522 не работает, горит красный светодиод
- Считывание одновременно RFID-МЕТКИ с помощью нескольких RFID-считывателей [MFRC522]
- Arduino Uno - Как записать персональные данные в NTAG213 с помощью RFID-RC522
«Я испробовал все возможные изменения, которые мог внести в код». Прежде всего, вы можете сделать его пригодным для повторного использования, сделав правильные отступы., @DataFiddler
arr2[u2]+=incomingStr.charAt(j);
Я этого не понимаю. Но я сомневаюсь, что это то, что ты хочешь., @DataFiddler@ user55609, пожалуйста, используйте правильные отступы при программировании. Это поможет другим легко понять ваш код., @Vaibhav
добавьте в свой код какую-нибудь тестовую точку после каждого выполнения модуля, которая поможет вам получить ошибку., @Vaibhav
какую строку вы отправили с последовательного монитора?, @Vaibhav