Несколько операторов If

Я использую следующий код для своего проекта Arduino, в котором мне нужно управлять двигателем постоянного тока с помощью Arduino Uno с помощью текстовых сообщений. Мой вопрос заключается в том, что я использовал несколько операторов «If» и только один оператор else в конце. Я скомпилировал этот код и не получил никаких ошибок. Можно ли использовать несколько операторов If один за другим, не используя else после каждого if?

#include <LiquidCrystal595.h>
#include <GSM.h>

GSM gsmAccess;
GSM_SMS sms;
char sendernumber[20];  
int Enable_m=11;
int Control_2=12;
int Control_7=10;
LiquidCrystal595 lcd(7,8,9);
void setup() 
{
   Serial.begin(9600);
   pinMode(Enable_m,OUTPUT);
   pinMode(Control_2,OUTPUT);
   pinMode(Control_7,OUTPUT);

   digitalWrite(Enable_m,LOW);
   digitalWrite(Control_2,LOW);
   digitalWrite(Control_7,LOW);

   lcd.begin(16,2);
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("Hello");
   lcd.setCursor(0,1);
   lcd.print("Everyone");
   delay(2000);

   while (!Serial) 
      Serial.println("SMS Messages Receiver");
   boolean notConnected = true;
   while(notConnected)
   {
      if(gsmAccess.begin("0000")==GSM_READY)
         notConnected = false;
      else
      {
         Serial.println("Not connected");
         delay(1000);
      }
   }  
   Serial.println("GSM initialized");
   Serial.println("Waiting for messages");
}

void loop() {
   // put your main code here, to run repeatedly:
   char c;
   int val=0;
   val=digitalRead(Enable_m);
   if (val==LOW){
      digitalWrite(Enable_m,HIGH);
   }
   if (sms.available())
   {
      Serial.println("Message received from:");
      sms.remoteNumber(sendernumber, 20);
      Serial.println(sendernumber);

      if(sms.peek()=='#')
      {
         Serial.println("Discarded SMS");
         sms.flush();
      }
      while(c=sms.read())
         if(c=='motoroff'){
            analogWrite(Enable_m, 0);
            digitalWrite(Control_2,LOW);
            digitalWrite(Control_7,LOW);

         }
      if(c=='motoronclockwise'){
         analogWrite(Enable_m, 255);
         digitalWrite(Control_2,LOW);
         digitalWrite(Control_7,HIGH);
      }
      if(c=='motoronanticlockwise'){
         analogWrite(Enable_m, 255);
         digitalWrite(Control_2,HIGH);
         digitalWrite(Control_7,LOW);
      }
      if(c=='speedhalf'){
         analogWrite(Enable_m, 128);
         digitalWrite(Control_2,LOW);
         digitalWrite(Control_7,HIGH);
      }
      if(c=='speedquarter'){
         analogWrite(Enable_m, 65);
         digitalWrite(Control_2,LOW);
         digitalWrite(Control_7,HIGH);
      }
      if(c=='speed75'){
         analogWrite(Enable_m, 192);
         digitalWrite(Control_2,LOW);
         digitalWrite(Control_7,HIGH);
      }
      else{
         digitalWrite(Enable_m,HIGH);
         Serial.print(c);
      }
      Serial.println("\nEND OF MESSAGE");
      sms.flush();
      Serial.println("MESSAGE DELETED");
   }

}

, 👍1

Обсуждение

Список' операторов if должен быть реализован как оператор switch/case; он используется, когда у одной переменной много возможностей, и допускает случай default', который делает то, что *вы думаете*, что делает ваш последний оператор else`. Однако, как говорит Маженко, вы не можете напрямую сравнивать строки, как вы это делаете., @CharlieHanson

@CharlieHanson, то есть я могу заменить if-ы на метки и установить значение переменной, равное входящему сообщению?, @Awais Saifi


3 ответа


Лучший ответ:

1
#include <LiquidCrystal.h>
#include <GSM.h>

GSM gsmAccess;
GSM_SMS sms;
char sendernumber[20]; 
int Enable_m=11;
int Control_2=12;
int Control_7=10;
LiquidCrystal lcd(7,8,9,8,1,2,3,4,5,6);

void setup() 
{
   Serial.begin(9600);
   pinMode(Enable_m,OUTPUT);
   pinMode(Control_2,OUTPUT);
   pinMode(Control_7,OUTPUT);

   digitalWrite(Enable_m,LOW);
   digitalWrite(Control_2,LOW);
   digitalWrite(Control_7,LOW);

   lcd.begin(16,2);
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("Hello");
   lcd.setCursor(0,1);
   lcd.print("Everyone");
   delay(2000);

   while (!Serial) 
      Serial.println("SMS Messages Receiver");
   boolean notConnected = true;
   while(notConnected)
   {
      if(gsmAccess.begin("0000")==GSM_READY)
         notConnected = false;
      else
      {
         Serial.println("Not connected");
         delay(1000);
      }
   }  
   Serial.println("GSM initialized");
   Serial.println("Waiting for messages");
}

void loop() {
   // put your main code here, to run repeatedly:

   // I chose 160 since that is max size for sms
   char message [160]; 
   // this fills message with null characters
   memset( message, '\0', sizeof(char)*160 ); 

   int val=0;
   val=digitalRead(Enable_m);
   if (val==LOW){
      digitalWrite(Enable_m,HIGH);
   }
   if (sms.available())
   {
      Serial.println("Message received from:");
      sms.remoteNumber(sendernumber, 20);
      Serial.println(sendernumber);

      // you used single qoutes properly here
      // single qoutes denote a char which is a single character
      if(sms.peek()=='#')
      {
         Serial.println("Discarded SMS");
         sms.flush();
      }


      // this will add the characters to messages[]
      for(int i = 0; message[i] = sms.read(); i++){}

      // I changed this to double qoutes since you need double
      // qoutes to denote a string literal
      if(strcmp(message, "motoroff") == 0){
         analogWrite(Enable_m, 0);
         digitalWrite(Control_2,LOW);
         digitalWrite(Control_7,LOW);
      }
      else if(strcmp(message, "motoronclockwise") == 0){
         analogWrite(Enable_m, 255);
         digitalWrite(Control_2,LOW);
         digitalWrite(Control_7,HIGH);
      }
      else if(strcmp(message, "motoronanticlockwise") == 0){
         analogWrite(Enable_m, 255);
         digitalWrite(Control_2,HIGH);
         digitalWrite(Control_7,LOW);
      }
      else if(strcmp(message, "speedhalf") == 0){
         analogWrite(Enable_m, 128);
         digitalWrite(Control_2,LOW);
         digitalWrite(Control_7,HIGH);
      }
      else if(strcmp(message, "speedquarter") == 0){
         analogWrite(Enable_m, 65);
         digitalWrite(Control_2,LOW);
         digitalWrite(Control_7,HIGH);
      }
      else if(strcmp(message, "speed75") == 0){
         analogWrite(Enable_m, 192);
         digitalWrite(Control_2,LOW);
         digitalWrite(Control_7,HIGH);
      }
      // This else will only be executed if the previous if and else if statements are false
      else{
         digitalWrite(Enable_m,HIGH);
         Serial.print(message);
      }
      Serial.println("\nEND OF MESSAGE");
      sms.flush();
      Serial.println("MESSAGE DELETED");
   }

}

Итак, я внес некоторые изменения в ваш код. Например, этот код 'motoronanticlock' неверен. Одинарные кавычки используются для типов данных char, а двойные кавычки используются для строковых литералов. Вам следует использовать двойные кавычки, поскольку есть несколько символов "motoronanticlock". Также, как сказал Маженко, вам придется использовать strcmp() для сравнения c-строок c-строки — это массивы char, которые имеют нулевой терминатор '\0'. Также strcmp() возвращает 0, если две строки равны.

Ваш последний оператор else будет выполнен только в том случае, если предыдущий оператор if будет false. Похоже, вы хотите, чтобы он выполнялся только в том случае, если все предыдущие операторы if будут ложными. Для этого вы создаете первый оператор if, а затем создаете цепочку операторов if else, за которыми следует один оператор else. Вы можете иметь один оператор if без операторов else или if else, однако, если вы хотите операторы else или if else, вам нужно иметь оператор if. Я уже внес необходимые изменения в ваш код.

Наконец, эта часть программы является самой большой проблемой while(c=sms.read()) Это потому, что sms.read() возвращает char, поэтому вы можете читать sms-сообщение только по одному символу за раз. Чтобы сделать это правильно, вам следует создать массив символов и сохранить в нем значения, возвращаемые sms.read(). Это можно сделать так

char message [160]; // Я выбрал 160, так как это максимальный размер для смс
memset( message, '\0', sizeof(char)*160 ); // это заполняет сообщение нулевыми символами
// это добавит символы в messages[]
for(int i = 0; message[i] = sms.read(); i++){}

Я использую цикл for для перебора message[].

Попробуйте сделать все вышеперечисленное и свяжитесь со мной, если возникнут какие-либо проблемы.

,

1

Две вещи:

  1. else будет зависеть только от последнего if, остальная часть if операторов полностью отделена и не может повлиять на else никаким образом. Чтобы сцепить их, вам нужно if (...) { blah blah } else if (...) { blah blah } и т. д.
  2. Вы не можете сравнивать символы и строки таким образом (и на самом деле это даже не строки, а множество символов, сжатых в один символ с помощью использования неправильных кавычек).

Так что, по сути, нет, вся ваша программа совершенно неверна и не будет делать то, что вы ожидаете, и вам нужно полностью переосмыслить, как она работает.

Несколько советов:

  • Используйте strcmp() для сравнения строк.
  • Если считывать строки из последовательного порта, то сохранять их в массивах символов, а не в отдельных символах.

Вам может быть полезно:

,

0

Если вы хотите, чтобы каждый оператор if выполнялся независимо от того, выполнялись ли предыдущие операторы, то да, они не требуют предложений else.

Если вы хотите проверить каждое условие, пока не найдете то, которое является истинным, и выполнить его и только его, то второй и последующие if должны быть else if. Последний может быть просто else, если вам нужно предложение catch-all; или else if, если возможно, что ни одно из предложений не нужно будет выполнять.

Обновление: чтобы выполнить максимум одно предложение, вам нужно использовать if, несколько else if и, возможно, финальный else.

Если вы пытаетесь сопоставить строки, вы можете использовать массив строк или использовать литеральные строки, как вы пытались сделать. Однако строки должны быть заключены в двойные кавычки ("), а не в одинарные, которые вы использовали. А переменная char c;, которую вы пытались использовать для хранения SMS-сообщения, на самом деле состоит только из одного символа. Вам нужно будет сделать ее массивом символов, например char c[140+1];, размером самого длинного SMS-сообщения + еще один для нулевого символа-терминатора строки. C напрямую не сравнивает строки как простые переменные, поэтому == и != здесь не сработают. Вам нужно будет сравнить их с помощью strcmp().

,