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("*");
 } 

, 👍1

Обсуждение

«Я испробовал все возможные изменения, которые мог внести в код». Прежде всего, вы можете сделать его пригодным для повторного использования, сделав правильные отступы., @DataFiddler

arr2[u2]+=incomingStr.charAt(j); Я этого не понимаю. Но я сомневаюсь, что это то, что ты хочешь., @DataFiddler

@ user55609, пожалуйста, используйте правильные отступы при программировании. Это поможет другим легко понять ваш код., @Vaibhav

добавьте в свой код какую-нибудь тестовую точку после каждого выполнения модуля, которая поможет вам получить ошибку., @Vaibhav

какую строку вы отправили с последовательного монитора?, @Vaibhav


2 ответа


1

Прежде всего попробуйте добавить сюда эти отладочные отпечатки, чтобы увидеть, не становится ли цикл 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")**
        }
   }
,

0

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; перед вышеуказанным циклом. Но даже после этого код останется в довольно шатком состоянии.

,