1
votes

I have an Arduino Leonardo with a program that is listening on a serial port and executes commands sent to it. The Arduino device is an RFID reader.

I wrote a WinForms app that communicates with the RFID reader to authenticate users. The Arduino receives data fine, but does not send anything. Even the TX diode on the board does not light up.

I tested my reader with an other PC serial monitor, and it works fine, so the problem is in my app. The Baud rate is 9600, data bits is 8 and parity is none. Handshaking probably does not matter, because the serial monitor worked with any handshaking.

What am I doing wrong? Another strange thing is, that when I connected the PC with my app via RS232 to an other PC with a serial monitor, and I simulated my reader, everything works. So why are only my app and the Arduino not working, when all other combinations are?

Arduino device is only Arduino + MFRC522 reader.

App code:

        public static Status Authenticate(Key key, Passsword passwd, UID uid, string port)
        {
            SerialPort serial = new SerialPort(port, 9600, Parity.None, 8, StopBits.One);
            serial.Handshake = Handshake.None;

            serial.Open();

            byte[] cmd = { 1 };

            serial.Write(cmd, 0, 1); //Send command

            if (serial.ReadLine() != "START") //Device is ready
            { serial.Close(); return Status.Err; }

            if (serial.ReadLine() != "KEY") //Device requires key
            { serial.Close(); return Status.Err; }

            serial.Write(key.ToArray(), 0, 6); //Send key

            if (serial.ReadLine() != "PASSWD") //Device requires password
            { serial.Close(); return Status.Err; }

            serial.Write(passwd.ToArray(), 0, 16); //Send password

            if (serial.ReadLine() != "UID") //Device requires card UID
            { serial.Close(); return Status.Err; }

            serial.Write(uid.ToArray(), 0, 4); //Send UID

            if (serial.ReadLine() != "WAIT-CARD") //Wait
            { serial.Close(); return Status.Err; }

            if (serial.ReadLine() != "CARD-PRESENT") //User presented card
            { serial.Close(); return Status.Err; }

            string stat = serial.ReadLine(); //Receive authorization status

            serial.Close();

            switch (stat) //Check status
            {
                case "OK": return Status.OK;
                case "ERR-PASS": return Status.Inc_passwd;
                case "ERR-UID": return Status.Inc_uid;
                case "ERR-KEY": return Status.Inc_key;
                default: return Status.Err;
            }

Full Arduino code:

#include <MFRC522.h>
#include <SPI.h>
#include <EEPROM.h>

#define SECTORS_14

// ----------------------------------------------------------------------------------------------------

#ifdef SECTORS_15
const byte permittedBlocks[] = {8, 9, 10, 12, 13, 14, 16, 17, 18, 20, 21, 22, 24, 25, 26, 28, 29, 30, 32, 33,
  34, 36, 37, 38, 40, 41, 42, 44, 45, 46, 48, 49, 50, 52, 53, 54, 56, 57, 58, 60, 61, 62};
#endif

#ifdef SECTORS_14
const byte permittedBlocks[] = {8, 9, 10, 12, 13, 14, 16, 17, 18, 20, 21, 22, 24, 25, 26, 28, 29, 30, 32, 33,
  34, 36, 37, 38, 40, 41, 42, 44, 45, 46, 48, 49, 50, 52, 53, 54, 56, 57, 58};
#endif

typedef struct codes
{
  byte uid[4];
  byte passwd[16];
  MFRC522::MIFARE_Key key;
} personalData;

void setup() 
{
  Serial.begin(9600);
  SPI.begin();
  delay(1000);
}

void loop() 
{
  byte cmd;
  
  while (!Serial.available());
  cmd = Serial.read();

  switch (cmd)
  {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    case 1:
    {
      digitalWrite(13, HIGH);
      Serial.println("START");
      
      personalData personal = RFID_GetPersonalData();
      
      MFRC522 rfid(10, 9);
      rfid.PCD_Init();

      if (RFID_WaitForCard(&rfid, personal)) return;

      Serial.println("OK");
      rfid.PICC_HaltA();
      rfid.PCD_StopCrypto1();
      
      break;
    }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    case 2:
    {
      Serial.println("START");
      
      personalData personal = RFID_GetPersonalData();
      
      Serial.println("NEW-PASSWD");

      byte newPasswd[16];
      getArray(newPasswd, 16);

      MFRC522 rfid(10, 9);
      rfid.PCD_Init();

      if (RFID_WaitForCard(&rfid, personal)) return;

      Serial.println("CHANGING");

      byte ok = RFID_ChangePasswd(newPasswd, &rfid, personal.key);

      if (ok == 1)      {Serial.println("ERR-KEY");    return;}
      else if (ok == 2) {Serial.println("ERR-WRITE");    return;}

      Serial.println("OK");

      rfid.PICC_HaltA();
      rfid.PCD_StopCrypto1();
      
      break;
    }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    case 3:
    {
      Serial.println("START");
      
      personalData personal = RFID_GetPersonalData();

      Serial.println("TO-WRITE");

      byte count[1];
      getArray(count, 1);

      byte blocks[count[0]][1];
      byte data[count[0]][16];

      for (byte i = 0; i < count[0]; i++)
      {
        Serial.println("BLOCK");

        getArray(blocks[i], 1);

        if (!isBlockPermitted(blocks[i][0])) {Serial.println("BLOCK-INVALID"); return;}

        Serial.println("DATA");

        getArray(data[i], 16);
      }
      

      MFRC522 rfid(10, 9);
      rfid.PCD_Init();

      if (RFID_WaitForCard(&rfid, personal)) return;

      Serial.println("WRITING");

      for (byte i = 0; i < count[0]; i++)
      {
        byte ok = RFID_WriteBlock(data[i], &rfid, personal.key, blocks[i][0]);

        if (ok == 1)      {Serial.println("ERR-KEY");    return;}
        else if (ok == 2) {Serial.println("ERR-WRITE");    return;}
      }
      
      Serial.println("OK");

      rfid.PICC_HaltA();
      rfid.PCD_StopCrypto1();
      
      break;
    }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    case 4:
    {
      Serial.println("START");
      
      personalData personal = RFID_GetPersonalData();

      MFRC522 rfid(10, 9);
      rfid.PCD_Init();

      if (RFID_WaitForCard(&rfid, personal)) return;
      
      Serial.println("FORMATTING");

      byte ok = RFID_FormatCard(&rfid, personal.key);

      if (ok == 1)      {Serial.println("ERR-KEY");    return;}
      else if (ok == 2) {Serial.println("ERR-WRITE");    return;}

      Serial.println("OK");

      rfid.PICC_HaltA();
      rfid.PCD_StopCrypto1();
      
      break;
    }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    case 5:
    {
      Serial.println("START");
      
      personalData personal = RFID_GetPersonalData();

      Serial.println("TO-READ");

      byte count[1];
      getArray(count, 1);

      byte blocks[count[0]][1];

      for (byte i = 0; i < count[0]; i++)
      {
        Serial.println("BLOCK");

        getArray(blocks[i], 1);

        if (!isBlockPermitted(blocks[i][0])) {Serial.println("BLOCK-INVALID"); return;}
      }

      MFRC522 rfid(10, 9);
      rfid.PCD_Init();

      if (RFID_WaitForCard(&rfid, personal)) return;

      Serial.println("READING");

      byte data[count[0]][16];
      for (byte i = 0; i < count[0]; i++)
      {
        byte ok = RFID_ReadBlock(data[i], &rfid, personal.key, blocks[i][0]);

        if (ok == 1)      {Serial.println("ERR-KEY");    return;}
        else if (ok == 2) {Serial.println("ERR-READ");    return;}
      }
      
      for (byte i = 0; i < count[0]; i++)
      {
        Serial.println("BLOCK-" + blocks[i][0]);
        for (byte i2 = 0; i2 < 16; i2++)
          Serial.println(data[i][i2]);
      }

      Serial.println("OK");

      rfid.PICC_HaltA();
      rfid.PCD_StopCrypto1();
      
      break;
    }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    case 6:
    {
      Serial.println("START");
      
      personalData personal = RFID_GetPersonalData();

      Serial.println("TO-READ");

      byte countR[1];
      getArray(countR, 1);

      byte blocksR[countR[0]][1];

      for (byte i = 0; i < countR[0]; i++)
      {
        Serial.println("BLOCK");

        getArray(blocksR[i], 1);

        if (!isBlockPermitted(blocksR[i][0])) {Serial.println("BLOCK-INVALID"); return;}
      }

      Serial.println("TO-WRITE");

      byte countW[1];
      getArray(countW, 1);

      byte blocksW[countW[0]][1];
      byte dataW[countW[0]][16];

      for (byte i = 0; i < countW[0]; i++)
      {
        Serial.println("BLOCK");

        getArray(blocksW[i], 1);

        if (!isBlockPermitted(blocksW[i][0])) {Serial.println("BLOCK-INVALID"); return;}

        Serial.println("DATA");

        getArray(dataW[i], 16);
      }

      MFRC522 rfid(10, 9);
      rfid.PCD_Init();

      if (RFID_WaitForCard(&rfid, personal)) return;

      Serial.println("READING");

      byte dataR[countR[0]][16];
      for (byte i = 0; i < countR[0]; i++)
      {
        byte ok = RFID_ReadBlock(dataR[i], &rfid, personal.key, blocksR[i][0]);

        if (ok == 1)      {Serial.println("ERR-KEY");    return;}
        else if (ok == 2) {Serial.println("ERR-READ");    return;}
      }

      for (byte i = 0; i < countR[0]; i++)
      {
        Serial.println("BLOCK-" + blocksR[i][0]);
        for (byte i2 = 0; i2 < 16; i2++)
          Serial.println(dataR[i][i2]);
      }

      Serial.println("WRITING");

      for (byte i = 0; i < countW[0]; i++)
      {
        byte ok = RFID_WriteBlock(dataW[i], &rfid, personal.key, blocksW[i][0]);

        if (ok == 1)      {Serial.println("ERR-KEY");    return;}
        else if (ok == 2) {Serial.println("ERR-WRITE");    return;}
      }

      Serial.println("OK");

      rfid.PICC_HaltA();
      rfid.PCD_StopCrypto1();
      
      break;
    }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    case 7:
    {
      Serial.println("START");
      Serial.println("TO-WRITE");

      byte count[1];
      getArray(count, 1);
      byte addr[count[0]][1];
      byte val[count[0]][1];

      for (byte i = 0; i < count[0]; i++)
      {
        Serial.println("ADDR");
        getArray(addr[i], 1);

        Serial.println("VAL");
        getArray(val[i], 1);
      }

      for (byte i = 0; i <count[0]; i++)
        EEPROM.put(addr[i][0], val[i][0]);

      Serial.println("OK");
    }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    case 8:
    {
      Serial.println("START");
      Serial.println("TO-READ");

      byte count[1];
      getArray(count, 1);
      byte addr[count[0]][1];
      byte val[count[0]][1];

      for (byte i = 0; i < count[0]; i++)
      {
        Serial.println("ADDR");
        getArray(addr[i], 1);
      }

      for (byte i = 0; i <count[0]; i++)
      {
        EEPROM.get(addr[i][0], val[i][0]);
        Serial.print("READ-"); Serial.println(addr[i][0]);
        Serial.println(val[i][0]);
      }
      
      Serial.println("OK");
    }

    case 9:
    {
      Serial.println("START");
      Serial.println("TO-READ");

      byte countR[1];
      getArray(countR, 1);
      byte addrR[countR[0]][1];
      byte valR[countR[0]][1];

      for (byte i = 0; i < countR[0]; i++)
      {
        Serial.println("ADDR");
        getArray(addrR[i], 1);
      }

      Serial.println("TO-WRITE");

      byte countW[1];
      getArray(countW, 1);
      byte addrW[countW[0]][1];
      byte valW[countW[0]][1];

      for (byte i = 0; i < countW[0]; i++)
      {
        Serial.println("ADDR");
        getArray(addrW[i], 1);

        Serial.println("VAL");
        getArray(valW[i], 1);
      }

      for (byte i = 0; i <countR[0]; i++)
      {
        EEPROM.get(addrR[i][0], valR[i][0]);
        Serial.print("READ-"); Serial.println(addrR[i][0]);
        Serial.println(valR[i][0]);
      }

      for (byte i = 0; i <countW[0]; i++)
        EEPROM.put(addrW[i][0], valW[i][0]);
      
      Serial.println("OK");
    }
  }
}
// -----------------------------------------------------------------------------------------------------------
inline bool compareArray(byte a1[], byte a2[], byte aSize)
{
  for (byte i = 0; i < aSize; i++)
    if (a1[i] != a2[i]) return false;
  return true;
}
// -----------------------------------------------------------------------------------------------------------
inline void copyArray(byte a1[], byte a2[], byte aSize)
{
  for (byte i = 0; i < aSize; i++)
    a1[i] = a2[i];
}
// -----------------------------------------------------------------------------------------------------------
inline void getArray(byte a[], byte len)
{
  for (byte i = 0; i < len; i++)
  {
    while (!Serial.available());
    a[i] = Serial.read();
  }
}
// -----------------------------------------------------------------------------------------------------------
inline MFRC522::MIFARE_Key RFID_GetKey()
{
  MFRC522::MIFARE_Key key;
  byte rawKey[6];
  for (byte i = 0; i < 6; i++)
  {
    while (!Serial.available());
    rawKey[i] = Serial.read();
  }

  for (byte i = 0; i < 6; i++)
    key.keyByte[i] = rawKey[i];
  return key;
}
// -----------------------------------------------------------------------------------------------------------
byte RFID_Auth(personalData data, MFRC522* rfid)
{
      if (!compareArray(data.uid, rfid->uid.uidByte, 4))
      {
        return 1;
      }

      MFRC522::StatusCode status;
      status = rfid->PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 1, &data.key, &(rfid->uid));
      if (status != MFRC522::STATUS_OK) 
      {
        return 2;
      }

      byte buff[18];
      byte len = 18;
      status = rfid->MIFARE_Read(1, buff, &len);
      if (status != MFRC522::STATUS_OK) 
      {
        return 3;
      }

      if (!compareArray(buff, data.passwd, 16))
      {
        return 4;
      }

      return 0;
}
// -----------------------------------------------------------------------------------------------------------
inline byte RFID_ChangePasswd(byte newPasswd[], MFRC522* rfid, MFRC522::MIFARE_Key key)
{
  return RFID_WriteBlock(newPasswd, rfid, key, 1);
}

bool isBlockPermitted(byte block)
{
#ifdef SECTORS_15
  if (block > 62) return false;
#endif

#ifdef SECTORS_14
  if (block > 58) return false;
#endif

  if (block < 8) return false;

  bool is = false;
  
  for (byte i = 0; i < 
#ifdef SECTORS_15
  42;
#endif
#ifdef SECTORS_14
  39;
#endif
  i++)
    if (block == permittedBlocks[i]) is = true;

  return is;
}
// -----------------------------------------------------------------------------------------------------------
byte RFID_WriteBlock(byte data[], MFRC522* rfid, MFRC522::MIFARE_Key key, byte block)
{
  MFRC522::StatusCode status;
  status = rfid->PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(rfid->uid));
  if (status != MFRC522::STATUS_OK) 
  {
    return 1;
  }

  byte data2[18];
  for (byte i = 0; i < 16; i++)
    data2[i] = data[i];
  
  status = rfid->MIFARE_Write(block, data2, 16);
  if (status != MFRC522::STATUS_OK) 
  {
    return 2;
  }

  return 0;
}
// -----------------------------------------------------------------------------------------------------------
byte RFID_ReadBlock(byte data[], MFRC522* rfid, MFRC522::MIFARE_Key key, byte block)
{
  MFRC522::StatusCode status;
  status = rfid->PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(rfid->uid));
  if (status != MFRC522::STATUS_OK) 
  {
    return 1;
  }

  byte buff[18];
  byte len = 18;
  
  status = rfid->MIFARE_Read(block, buff, &len);
  if (status != MFRC522::STATUS_OK) 
  {
    return 2;
  }

  copyArray(data, buff, 16);

  return 0;
}
// -----------------------------------------------------------------------------------------------------------
byte RFID_FormatCard(MFRC522* rfid, MFRC522::MIFARE_Key key)
{
  const byte data[18] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  
  for (byte i = 0; i < 
#ifdef SECTORS_15
  42;
#endif
#ifdef SECTORS_14
  39;
#endif
  i++)
  {
    byte block = permittedBlocks[i];

    MFRC522::StatusCode status;
    status = rfid->PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(rfid->uid));
    if (status != MFRC522::STATUS_OK) 
    {
      return 1;
    }

    status = rfid->MIFARE_Write(block, const_cast<byte*>(data), 16);
    if (status != MFRC522::STATUS_OK) 
    {
      return 2;
    }
  }

  return 0;
}
// -----------------------------------------------------------------------------------------------------------
inline personalData RFID_GetPersonalData()
{
  personalData data;
  
  Serial.println("KEY");
      
  data.key = RFID_GetKey();

  Serial.println("PASSWD");

  getArray(data.passwd, 16);

  Serial.println("UID");

  getArray(data.uid, 4);

  return data;
}

// -----------------------------------------------------------------------------------------------------------
inline bool RFID_WaitForCard(MFRC522* rfid, personalData personal)
{
  Serial.println("WAIT-CARD");
  
  while (!rfid->PICC_IsNewCardPresent()) { if (Serial.available()) {byte cmd = Serial.read(); if (cmd == 66) {Serial.println("CANCELED"); return true;}}}
  while (!rfid->PICC_ReadCardSerial());
  digitalWrite(13, LOW);
  Serial.println("CARD-PRESENT");

  byte ok = RFID_Auth(personal, rfid);
      
  if (ok == 1)      {Serial.println("ERR-UID");    return true;}
  else if (ok == 2) {Serial.println("ERR-KEY");    return true;}
  else if (ok == 3) {Serial.println("ERR-READ");   return true;}
  else if (ok == 4) {Serial.println("ERR-PASSWD"); return true;}

  return false;
}

Minimal reproducible example

Arduino:

void setup() 
{
  Serial.begin(9600);
}

void loop() 
{
  byte command;
  while (!Serial.available());
  command = Serial.read();
  // ...
  Serial.println("START");
  // Some operations
  byte someData;
  while (!Serial.available());
  someData = Serial.read();
  // Some operations
  Serial.println("OK");

  // Arduino receives, but not send
}

App:

public static Status Authenticate(Key key, Passsword passwd, UID uid, string port)
        {
            SerialPort serial = new SerialPort(port, 9600, Parity.None, 8, StopBits.One);
            serial.Handshake = Handshake.None;

            serial.Open();

            byte[] cmd = { 1 };

            serial.Write(cmd, 0, 1); //Send command

            if (serial.ReadLine() != "START") //Device is ready. Here program is stuck, becuse it's waiting for START command that never comes
            { serial.Close(); return Status.Err; }

            serial.Write(cmd, 0, 1); //Send "someData"

            string stat = serial.ReadLine(); //Receive status

            serial.Close();

            switch (stat) //Check status
            {
                case "OK": return Status.OK;
                case "ERR-PASS": return Status.Inc_passwd;
                case "ERR-UID": return Status.Inc_uid;
                case "ERR-KEY": return Status.Inc_key;
                default: return Status.Err;
            }
1
"Arduino receives data fine" -- are you sure?canton7
The fact that you've posted a snippet of the Arduino code, and haven't created a minimal reproducible example, means it's unlikely we'll be able to find any problems in your C codecanton7
Yes, arduino receives data fine. I added full arduino codeKamil B
Oh, wait. Minimal... give me a whileKamil B
Ok, I think that now it's okKamil B

1 Answers

0
votes

Ok, works. I added

serial.DtrEnable = true;
serial.RtsEnable = true;

after serial.Handshake = Handshake.None;

Anyway, thanks for help.