Arduino 不向 WinForms 应用程序发送数据
Arduino does not send data to WinForms app
我有一个 Arduino Leonardo,其程序正在侦听串行端口并执行发送给它的命令。 Arduino 设备是一个 RFID reader.
我编写了一个与 RFID reader 通信的 WinForms 应用程序来验证用户身份。 Arduino 接收数据正常,但不发送任何内容。连板上的TX二极管都不亮
我用其他 PC 串行监视器测试了我的 reader,它工作正常,所以问题出在我的应用程序中。波特率为9600,数据位为8,奇偶校验为none。握手可能无关紧要,因为串行监视器可以处理任何握手。
我做错了什么?另一件奇怪的事情是,当我通过 RS232 将带有我的应用程序的 PC 连接到另一台带有串行监视器的 PC 时,我模拟了我的 reader,一切正常。那么为什么只有我的应用程序和 Arduino 不工作,而所有其他组合都在工作?
Arduino 设备只有 Arduino + MFRC522 reader.
应用代码:
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;
}
完整的 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, 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;
}
最小可重现示例
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
}
应用程序:
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;
}
好的,有效。我加了
serial.DtrEnable = true;
serial.RtsEnable = true;
在serial.Handshake = Handshake.None;
之后
无论如何,谢谢你的帮助。
我有一个 Arduino Leonardo,其程序正在侦听串行端口并执行发送给它的命令。 Arduino 设备是一个 RFID reader.
我编写了一个与 RFID reader 通信的 WinForms 应用程序来验证用户身份。 Arduino 接收数据正常,但不发送任何内容。连板上的TX二极管都不亮
我用其他 PC 串行监视器测试了我的 reader,它工作正常,所以问题出在我的应用程序中。波特率为9600,数据位为8,奇偶校验为none。握手可能无关紧要,因为串行监视器可以处理任何握手。
我做错了什么?另一件奇怪的事情是,当我通过 RS232 将带有我的应用程序的 PC 连接到另一台带有串行监视器的 PC 时,我模拟了我的 reader,一切正常。那么为什么只有我的应用程序和 Arduino 不工作,而所有其他组合都在工作?
Arduino 设备只有 Arduino + MFRC522 reader.
应用代码:
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;
}
完整的 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, 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;
}
最小可重现示例
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
}
应用程序:
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;
}
好的,有效。我加了
serial.DtrEnable = true;
serial.RtsEnable = true;
在serial.Handshake = Handshake.None;
无论如何,谢谢你的帮助。