Arduino 不会向 WinForms 应用程序发送数据

问题描述

我有一个 Arduino Leonardo,它的程序正在侦听串行端口并执行发送给它的命令。 Arduino 设备是一个 RFID 阅读器。

我编写了一个 WinForms 应用程序,它与 RFID 阅读器通信以验证用户身份。 Arduino 接收数据正常,但不发送任何内容。就连板上的TX二极管也不亮。

我用另一台 PC 串行监视器测试了我的阅读器,它工作正常,所以问题出在我的应用程序中。波特率为 9600,数据位为 8,奇偶校验为无。握手可能无关紧要,因为串行监视器可以处理任何握手。

我做错了什么?另一个奇怪的事情是,当我通过 RS232 将带有我的应用程序的 PC 连接到另一台带有串行监视器的 PC 时,我模拟了我的阅读器,一切正常。那么为什么只有我的应用程序和 Arduino 不工作,而所有其他组合都可以?

Arduino 设备只是 Arduino + MFRC522 读卡器。

应用代码

        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,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(),6); //Send key

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

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

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

            serial.Write(uid.ToArray(),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;
            }

完整的 Arduino 代码

#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,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,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,personal)) return;

      Serial.println("WRITING");

      for (byte i = 0; i < count[0]; i++)
      {
        byte ok = RFID_WriteBlock(data[i],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,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,personal)) return;

      Serial.println("READING");

      byte data[count[0]][16];
      for (byte i = 0; i < count[0]; i++)
      {
        byte ok = RFID_ReadBlock(data[i],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,personal)) return;

      Serial.println("READING");

      byte dataR[countR[0]][16];
      for (byte i = 0; i < countR[0]; i++)
      {
        byte ok = RFID_ReadBlock(dataR[i],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],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);
      }

      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 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::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[],&(rfid->uid));
  if (status != MFRC522::STATUS_OK) 
  {
    return 1;
  }

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

  copyArray(data,16);

  return 0;
}
// -----------------------------------------------------------------------------------------------------------
byte RFID_FormatCard(MFRC522* rfid,MFRC522::mifare_Key key)
{
  const byte data[18] = {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,&(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;
}

最小可重现示例

阿杜诺:

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
}

应用:

public static Status Authenticate(Key key,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,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;
            }

解决方法

好的,有效。我加了

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

serial.Handshake = Handshake.None;之后

无论如何,感谢您的帮助。