RFID PN532+тормоза ардуино

clinklion
Offline
Зарегистрирован: 18.09.2014

Добрый день. Есть проект состоит из Arduino UNO R3+RFID PN532 (китаец, не от адафрут, подключен по HSU)+ethernet модуль enc28j60 (запрограммирован работать как web-server). Проблема в следующем ставлю на пинг модуль enc28j60, а RFID PN532 находится в режиме чтения карт. Когда рядом с RFID нет карты, то пинги до enc28j60 составляют от 200 до 2000мс, причем значение каждый раз плавает и на запросы через браузер ответы приходят также с задержкой до 2000мс. Стоит только RFID модуль положить карту, то пинги падают 20-30мс и сервер отвечает сразу же. Также, если отключить RFID от контроллера или снять питания, то пинги приходят быстро и сервер отвечает махом. Такое чувство, что RFID в режиме ожидания карты съедает все время процессора, в чем может быть дело?

Прикладываю код проекта

//RFID library
#include <PN532_HSU.h>
#include <PN532.h>
PN532_HSU pn532hsu(Serial);
PN532 nfc(pn532hsu);

//RFID data
uint8_t data[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};  // Data for send/recieve
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };                              // Buffer to store the returned UID
uint8_t uidLength;                                                    // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
bool writeMode =false;                                                // Write mode on RFID
uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };             // keyA

//String
String readString = String(32);
String cmdString = String(32);
String numberString = String(32);
char c;
int ind1 = 0;
int ind2 = 0;
int ind3 = 0;

#include <EEPROM.h>
#include <SPI.h>
#include <UIPEthernet.h>
byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // Мак адрес
byte ip[] = {  10, 0, 1, 200 }; // IP адрес (изменить в title)
EthernetServer server(80);
int i = 0;

//TIME
const int addrWW = 1000;
const int addrHH = 1001;
byte WW = 0;
byte HH = 0;
byte MM = 0;
unsigned long timeMillis;
unsigned long timeBuffer;
int newHHMM = 0;

//------------------------------------------------
//-------------- инициализация -------------------
//------------------------------------------------

void setup()
{
 //Старт
 Serial.begin(115200);
 //Ethernet
 Ethernet.begin(mac);
 //DHCP
// Serial.print("localIP: ");
 Serial.println(Ethernet.localIP());
// Serial.print("subnetMask: ");
// Serial.println(Ethernet.subnetMask());
// Serial.print("gatewayIP: ");
// Serial.println(Ethernet.gatewayIP());
// Serial.print("dnsServerIP: ");
// Serial.println(Ethernet.dnsServerIP());
 
 server.begin();
 //RFID
 nfc.begin();
 nfc.SAMConfig();
 //Инициализация времени
 HH = EEPROM.read(addrHH);
 WW = EEPROM.read(addrWW);
 MM = 0;
 //Info
 Serial.println("device is run");
}

//------------------------------------------------
//------------------- цикл -----------------------
//------------------------------------------------

void loop()
{
//чтение первой страницы RFID карты
//var
//RFID on
//nfc.begin(); 
uint8_t success; 
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
if (success)
  {if (writeMode)
    {unsigned long time_;
    int timeDelta;
    time_ = millis();
    // ожидание карточки 1 минуту
    timeDelta = int((time_ - timeMillis)/60000);
    if (timeDelta!=0) {writeMode = false;}
    if (writeMode)
      {success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, 1, 0, keya);
      if (success) 
        {nfc.mifareclassic_WriteDataBlock (1, data);
        writeMode = false;
        }
      }
    }
    else  
    {success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, 1, 0, keya);
    if (success)
      {success = nfc.mifareclassic_ReadDataBlock (1, data);
      if (success) 
        {//vars
        int addr = 0;
        bool whileLoopFinish = false;
        uint8_t prevEmployee = 0;
        uint8_t prevWW = 0;
        uint8_t prevHH = 0;
        //Find blank block
        while (whileLoopFinish==false)
          {//check last employee
          prevEmployee = EEPROM.read(addr);
          prevWW = EEPROM.read(addr+1);
          prevHH = EEPROM.read(addr+2);
          //Protect from dublication
          if (data[0]==prevEmployee && WW==prevWW && HH==prevHH) {whileLoopFinish = true;}
          //Write
          if (EEPROM.read(addr)==0 && EEPROM.read(addr+1)==0 && EEPROM.read(addr+2)==0 && EEPROM.read(addr+3)==0 && whileLoopFinish == false)
            {EEPROM.write(addr,data[0]);
             EEPROM.write(addr+1,WW);
             EEPROM.write(addr+2,HH);
             EEPROM.write(addr+3,MM);
             whileLoopFinish = true;
             }
          //increment
          addr = addr + 4;
          //All blocks without last block which reserved for finish point
          if (addr>=addrWW) {whileLoopFinish = true;}
          }
        }
      }
    }
  }
//nfc.shutDown();

// Работа со временем
timeCurrent();

// Обработка запросов от сервера
EthernetClient client = server.available();
if (client)  
  {while (client.connected())
    {if (client.available()) 
      {c = client.read();
      //read char by char HTTP request
      if (readString.length() < 32)
        {//store characters to string 
        readString.concat(c); 
        }
        if (c == '\n')
          {ind1 = readString.indexOf('/');
          ind2 = readString.indexOf('=');
          ind3 = readString.indexOf('H');
          cmdString = readString.substring(ind1+1, ind2);
          numberString = readString.substring(ind2+1, ind3-1);
          // Выводим всех работников при запросе
          if (cmdString == "log")
            {client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println();
            client.println();
            client.println("<!DOCTYPE html>");
            client.println("<html>");
            client.println("<body>");
            i=0;
//            while (i<=100)
//            while (EEPROM.read(i)!=0 && EEPROM.read(i+1)!=0 && EEPROM.read(i+2)!=0 && EEPROM.read(i+3)!=0)
            while (EEPROM.read(i)!=0 && i<=addrWW)
              {client.print("<p>");
              client.print(EEPROM.read(i));
              client.print(".");
              client.print(EEPROM.read(i+1));
              client.print(".");
              client.print(EEPROM.read(i+2));
              client.print(".");
              client.print(EEPROM.read(i+3));
              client.print("</p>");
              i=i+4;
              }
            client.println("</body>");
            client.println("</html>");
            client.stop();
            }
            
          // Записываем новое время
          if (cmdString == "nt")
            {newHHMM = numberString.toInt();
            Serial.println(numberString);
            HH = int(newHHMM/100);
            MM = newHHMM - HH*100;
            EEPROM.write(addrHH, HH);
            }
          // Записываем новый день
          if (cmdString == "nd")
            {WW = numberString.toInt();
            EEPROM.write(addrWW, WW);
            }
          // Очищаем память
          if (cmdString == "clr")
            {i=0;
            for (int i=0; i<=1000; i++ ) {EEPROM.write(i,0);}
            }
          // Записываем нового пользователя
          if (cmdString == "nu")
            {data[0] = numberString.toInt();
            timeBuffer = millis();
            writeMode = true;
            }

          // передать успешную команду
          if (cmdString != "log")
            {client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println();
            client.println();
            client.println("<!DOCTYPE html>");
            client.println("<html>");
            client.println("<body>");
            client.println("<p>");
            client.println("ok");
            client.println("</p>");
            client.println("</body>");
            client.println("</html>");
            client.stop();
            }
          }
      }
    }
  }
readString="";
}

//------------------------------------------------
//-------------- текущее время -------------------
//------------------------------------------------

void timeCurrent()
{
 unsigned long time_;
 int timeDelta;
 
 time_ = millis();
 // изменение в минутах
 timeDelta = int((time_ - timeMillis)/60000);
 if (timeDelta>0)
  {timeMillis = time_;
  MM=MM+timeDelta;
  //minutes++
  if (MM>=60) 
    {MM=0;
    HH=HH+1;
    if (HH!=24)
      {EEPROM.write(addrHH, HH);
      EEPROM.write(addrWW, WW);
      }
    }
  //hours++
  if (HH>=24) 
    {HH=0;
    WW=WW+1;
    //day of week++
    if (WW>=7) {WW=0;}
    // сохранение времени
    EEPROM.write(addrHH, HH);
    EEPROM.write(addrWW, WW);
    }
  }
 // превышение счетчика времени
 if (timeDelta<0) {timeMillis = time_;}
}

 

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Проблема в том что вы используете асинхронный интерфейс Serial для чтения модуля, а он молчит и так до таймаута. Надо SPI попробовать или I2C.

clinklion
Offline
Зарегистрирован: 18.09.2014

NeiroN пишет:

Проблема в том что вы используете асинхронный интерфейс Serial для чтения модуля, а он молчит и так до таймаута. Надо SPI попробовать или I2C.

Спасибо, перешел на I2C, помогло.