Несколько операторов 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");
}
}
@Awais Saifi, 👍1
Обсуждение3 ответа
Лучший ответ:
#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[]
.
Попробуйте сделать все вышеперечисленное и свяжитесь со мной, если возникнут какие-либо проблемы.
Две вещи:
else
будет зависеть только от последнегоif
, остальная частьif
операторов полностью отделена и не может повлиять наelse
никаким образом. Чтобы сцепить их, вам нужноif (...) { blah blah } else if (...) { blah blah }
и т. д.- Вы не можете сравнивать символы и строки таким образом (и на самом деле это даже не строки, а множество символов, сжатых в один символ с помощью использования неправильных кавычек).
Так что, по сути, нет, вся ваша программа совершенно неверна и не будет делать то, что вы ожидаете, и вам нужно полностью переосмыслить, как она работает.
Несколько советов:
- Используйте
strcmp()
для сравнения строк. - Если считывать строки из последовательного порта, то сохранять их в массивах символов, а не в отдельных символах.
Вам может быть полезно:
Если вы хотите, чтобы каждый оператор if
выполнялся независимо от того, выполнялись ли предыдущие операторы, то да, они не требуют предложений else
.
Если вы хотите проверить каждое условие, пока не найдете то, которое является истинным, и выполнить его и только его, то второй и последующие if
должны быть else if
. Последний может быть просто else
, если вам нужно предложение catch-all; или else if
, если возможно, что ни одно из предложений не нужно будет выполнять.
Обновление: чтобы выполнить максимум одно предложение, вам нужно использовать if
, несколько else if
и, возможно, финальный else
.
Если вы пытаетесь сопоставить строки, вы можете использовать массив строк или использовать литеральные строки, как вы пытались сделать. Однако строки должны быть заключены в двойные кавычки ("
), а не в одинарные, которые вы использовали. А переменная char c;
, которую вы пытались использовать для хранения SMS-сообщения, на самом деле состоит только из одного символа. Вам нужно будет сделать ее массивом символов, например char c[140+1];
, размером самого длинного SMS-сообщения + еще один для нулевого символа-терминатора строки. C напрямую не сравнивает строки как простые переменные, поэтому ==
и !=
здесь не сработают. Вам нужно будет сравнить их с помощью strcmp().
- Проблема с получением SMS - GSM-модуль Arduino Uno и SIM900A
- Мини-модем SIM900a, IMEI 0, помощь с контактами TX RX
- Как получить данные из базы данных моего сервера в переменную в моем Arduino?
- Как отправить команду AT на sim800l с помощью SoftwareSerial
- SIM800L не регистрируется в сети
- Как проверить, работает ли GSM-модуль?
- Как отправлять сообщения на несколько номеров с помощью модуля Arduino uno и SIM800?
- Клиент MQTT на Arduino + SIM900
Список' операторов
if
должен быть реализован как операторswitch/case
; он используется, когда у одной переменной много возможностей, и допускает случайdefault', который делает то, что *вы думаете*, что делает ваш последний оператор
else`. Однако, как говорит Маженко, вы не можете напрямую сравнивать строки, как вы это делаете., @CharlieHanson@CharlieHanson, то есть я могу заменить if-ы на метки и установить значение переменной, равное входящему сообщению?, @Awais Saifi