-1

[稍后编辑] 我有一个 Arduino Uno 和一个 RFID-RC522、一个伺服电机和一些 LED + 我还做了一个铝箔三明治/开关。这是铝制开关之前的代码,一切正常:

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

#define SS_PIN 10 // SLAVE SELECT la DIGITAL 10
#define RST_PIN 9 // PIN RESET la DIGITAL 9
#define LED_V 5 //LED_Verde la D5
#define LED_R 4 //LED_Rosu la D4
#define BUZZER 2 //BUZZER la D2
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Creaza instanta MFRC522.
Servo bariera; //defineste nume Servo

void setup() 
{
  Serial.begin(9600);   // Incepe comunicatia seriala cu PC-ul
  SPI.begin();      // Initializeaza bus-ul SPI
  mfrc522.PCD_Init();   // Initializeaza MFRC522
  bariera.attach(3); //servo pin
  bariera.write(0); //servo pozitie start
  pinMode(LED_V, OUTPUT);
  pinMode(LED_R, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  noTone(BUZZER);
  Serial.println("Apropie cartela...[x][][]");
  delay(2500);
  Serial.println("Apropie cartela...[x][x][]");
  delay(3500);
  Serial.println("Apropie cartela...[x][x][x]");
  delay(4500);
  Serial.println("Astept raspuns utilzator!");
  Serial.println();

}
void loop() 
{
  // Cauta cartele noi
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }
  // Selecteaza una dintre cartele
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  {
    return;
  }
  //Arata UID pe monitorul serial
  Serial.print("ID Tag/Cartela: ");
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
     Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
     Serial.print(mfrc522.uid.uidByte[i], HEX);
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
     content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  Serial.println();
  Serial.print("Mesaj : ");
  content.toUpperCase();
  if (content.substring(1) == "A0 B9 8D 7C") //aici schimbam ID-ul (UID-ul) cartelelor autorizate, citite anterior pe monitorul serial
  {
    Serial.println("Acces autorizat! Bine ati venit!");
    Serial.println();
    delay(500);
    digitalWrite(LED_V, HIGH);
    tone(BUZZER, 350);
    delay(300);
    noTone(BUZZER);
    bariera.write(120);
    delay(5000);
    bariera.write(0);
    digitalWrite(LED_V, LOW);

  }

 else   {
    Serial.println(" Access interzis! La revedere!");
    digitalWrite(LED_R, HIGH);
    tone(BUZZER, 300);
    delay(1000);
    digitalWrite(LED_R, LOW);
    noTone(BUZZER);
  }
} 

因此,如果 RFID CARD/TAG 为“A0 B9 8D 7C”,LED_V 灯亮,蜂鸣器短音,伺服(此处称为 bariera)转到 120 度。

如果 RFID CARD/TAG 不是“A0 B9 8D 7C”,LED_R 会亮起,蜂鸣器长音且 serv 不执行任何操作。

我还做了一个铝箔开关(两张用纸板隔开的铝片,按下时((digitalRead(IESIRE)== 0)应该:LED_V灯,蜂鸣器短音,伺服(这里命名为bariera)转到120度。

这是包含开关的整个代码(#define IESIRE 6):

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

#define SS_PIN 10 // SLAVE SELECT la DIGITAL 10
#define RST_PIN 9 // PIN RESET la DIGITAL 9
#define LED_V 5 //LED_Verde la D5
#define LED_R 4 //LED_Rosu la D4
#define BUZZER 2 //BUZZER la D2
#define IESIRE 6 // IESIRE la D6
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Creaza instanta MFRC522.
Servo bariera; //defineste nume Servo

void setup() 
{
  Serial.begin(9600);   // Incepe comunicatia seriala cu PC-ul
  SPI.begin();      // Initializeaza bus-ul SPI
  mfrc522.PCD_Init();   // Initializeaza MFRC522
  bariera.attach(3); //servo pin
  bariera.write(0); //servo pozitie start
  pinMode(LED_V, OUTPUT);
  pinMode(LED_R, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  pinMode(IESIRE, INPUT);
  digitalWrite(IESIRE, HIGH);
  noTone(BUZZER);
  Serial.println("Apropie cartela...[x][][]");
  delay(2500);
  Serial.println("Apropie cartela...[x][x][]");
  delay(3500);
  Serial.println("Apropie cartela...[x][x][x]");
  delay(4500);
  Serial.println("Astept raspuns utilzator!");
  Serial.println();
}
void loop() 
{
  // Cauta cartele noi
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }
  // Selecteaza una dintre cartele
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  {
    return;
  }
  //Arata UID pe monitorul serial
  Serial.print("ID Tag/Cartela: ");
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
     Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
     Serial.print(mfrc522.uid.uidByte[i], HEX);
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
     content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  Serial.println();
  Serial.print("Mesaj : ");
  content.toUpperCase();
  if (content.substring(1) == "A0 B9 8D 7C") //aici schimbam ID-ul (UID-ul) cartelelor autorizate, citite anterior pe monitorul serial
  {
    Serial.println("Acces autorizat! Bine ati venit!");
    Serial.println();
    delay(500);
    digitalWrite(LED_V, HIGH);
    tone(BUZZER, 350);
    delay(300);
    noTone(BUZZER);
    bariera.write(120);
    delay(5000);
    bariera.write(0);
    digitalWrite(LED_V, LOW);

  }

 else if (content.substring(1) != "A0 B9 8D 7C")    {
    Serial.println(" Access interzis! La revedere!");
    digitalWrite(LED_R, HIGH);
    tone(BUZZER, 300);
    delay(1000);
    digitalWrite(LED_R, LOW);
    noTone(BUZZER);

 }

  else if ((content.substring(1) != "A0 B9 8D 7C") && (digitalRead(IESIRE)==0))     {
    Serial.println("Drum bun!");
    digitalWrite(LED_V, HIGH);
    tone(BUZZER, 350);
    delay(300);
    bariera.write(120);
    delay(5000);
    bariera.write(0);
    digitalWrite(LED_V, LOW);

  }
}

请忽略 else if 语句和其他东西,我对编码还很陌生,我正在尽力而为。因此,如果按下开关(这转换为digitalRead(IESIRE)==0))伺服需要转到 120 度,无论其他语句如何。

CARD/RFID TAG present > recognised > servo to 120 + led, buzzer
                present > not recognised > led, buzzer
 IF SWITCH is pressed > servo to 120 + led, buzzer REGARDLESS of the CARD stuff.

我希望这是有道理的,而且更明确。

4

1 回答 1

4

很难说出“最后一部分”是什么意思,但假设您在这里:

else if (content.substring(1) != "A0 B9 8D 7C")    {
    /* stuff */
 }
 else if ((content.substring(1) != "A0 B9 8D 7C") && (digitalRead(IESIRE)==0))     {
    /* other stuff */
  }

让我们简化一下:

else if (A)    {
    /* stuff */
 }
 else if (A && B)     {
    /* other stuff */
  }

你现在能看到吗?如果满足条件 A,则第一位完成,因此忽略 else if。

如果第 2 位应始终完成,请删除“else if”,以便始终检查它。如果是其中一种情况,则将更具体的部分(A && B)放在一般情况之前。

另外:为了性能和我敢说清楚,不要调用substr两次 - 存储substr(...) != "..."在一个变量中并只使用该变量。如果你给它一个合理的名字,就像它的!= "A0 B9 8D 7C"实际含义一样,你的代码就会变得更加清晰!如果值发生变化等,您还可以避免在 2 个地方更改字符串的麻烦。

编辑:所以从评论中:ANYTIME digitalRead(IESIRE)==0 我希望这发生:Serial.println("Drum bun!"); 数字写入(LED_V,高);音调(蜂鸣器,350);延迟(300);bariera.write(120); ... (ETC)

你应该做这个:

else if (content.substring(1) != "A0 B9 8D 7C")    {
    /* stuff */
 }

if (digitalRead(IESIRE)==0)     {
    /* other stuff */
  }

请注意,它不是一个else if,我们已经删除了您不关心的冗余检查。

另一个编辑:

我认为这可以做到。这是为什么 DRY(不要重复自己)很重要的一个很好的例子。你有大约 10 行中的一大块,在 2 个条件下重复 - 这使得更难看到正在发生的事情。将您的原始代码与您的代码的简化版本进行比较。

if (content.substring(1) == "A0 B9 8D 7C")  { //aici schimbam ID-ul (UID-ul) cartelelor autorizate, citite anterior pe monitorul serial
    doA();
  } 
 else if (content.substring(1) != "A0 B9 8D 7C")    {
    do(B);
 }
  else if ((content.substring(1) != "A0 B9 8D 7C") && (digitalRead(IESIRE)==0))     {
    doA();  
  }


 I think this is what you want:


 bool isRightCard = (content.substring(1) == "A0 B9 8D 7C");
 bool buttonPressed = digitalRead(IESIRE)==0;
 if (isRightCard || buttonPressed) //aici schimbam ID-ul (UID-ul) cartelelor autorizate, citite anterior pe monitorul serial
  {
    if (buttonPressed)
    {
        Serial.println("Drum bun!");
    }
    else
    {
        Serial.println("Acces autorizat! Bine ati venit!");
    }
    Serial.println();
    delay(500);
    digitalWrite(LED_V, HIGH);
    tone(BUZZER, 350);
    delay(300);
    noTone(BUZZER);
    bariera.write(120);
    delay(5000);
    bariera.write(0);
    digitalWrite(LED_V, LOW);

  }
 else {
    Serial.println(" Access interzis! La revedere!");
    digitalWrite(LED_R, HIGH);
    tone(BUZZER, 300);
    delay(1000);
    digitalWrite(LED_R, LOW);
    noTone(BUZZER);

 }
于 2017-06-05T03:44:25.000 回答