Несколько операторов 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[].
Попробуйте сделать все вышеперечисленное и свяжитесь со мной, если возникнут какие-либо проблемы.
Прошу прощения за поздний ответ и благодарю за то, что уделили время ответу на мой вопрос. Я проверю код на оборудовании и сообщу вам. Ещё раз спасибо за помощь, я очень ценю это., @Awais Saifi
sketch_oct16a.ino: В функции 'void loop()': sketch_oct16a:81: ошибка: «сообщения» не были объявлены в этой области sketch_oct16a:114: ошибка: «messsage» не был объявлен в этой области Что это значит? Я проверил, и возникла эта ошибка., @Awais Saifi
Я ошибся, это просто опечатки. Я отредактировал код в своём ответе., @Chris
Да, я так и думал. Теперь всё в порядке, проверено. Ура!, @Awais Saifi
Две вещи:
elseбудет зависеть только от последнегоif, остальная частьifоператоров полностью отделена и не может повлиять наelseникаким образом. Чтобы сцепить их, вам нужноif (...) { blah blah } else if (...) { blah blah }и т. д.- Вы не можете сравнивать символы и строки таким образом (и на самом деле это даже не строки, а множество символов, сжатых в один символ с помощью использования неправильных кавычек).
Так что, по сути, нет, вся ваша программа совершенно неверна и не будет делать то, что вы ожидаете, и вам нужно полностью переосмыслить, как она работает.
Несколько советов:
- Используйте
strcmp()для сравнения строк. - Если считывать строки из последовательного порта, то сохранять их в массивах символов, а не в отдельных символах.
Вам может быть полезно:
- http://hacking.majenko.co.uk/reading-serial-on-the-arduino
- http://hacking.majenko.co.uk/the-evils-of-arduino-strings
Итак, вы говорите, что мне нужно создать массив строк, а затем использовать функцию strcmp() для их сравнения. Как тогда назначить каждой строке отдельную функцию?, @Awais Saifi
Нет, я говорю, что *каждая* строка должна быть массивом *символов*. Погуглите руководства по «строкам C»., @Majenko
тогда мне придется определять каждый массив, как в начале, и просто ссылаться на него в условном выражении?, @Awais Saifi
Попросите Google показать вам. Он справится с этим лучше, чем я, пытаясь научить вас основам в комментариях. Существует буквально миллиард примеров и обучающих программ. Зайдите и прочтите их., @Majenko
Я перешёл по этой ссылке, и она оказалась весьма полезной. Спасибо., @Awais Saifi
Если вы хотите, чтобы каждый оператор if выполнялся независимо от того, выполнялись ли предыдущие операторы, то да, они не требуют предложений else.
Если вы хотите проверить каждое условие, пока не найдете то, которое является истинным, и выполнить его и только его, то второй и последующие if должны быть else if. Последний может быть просто else, если вам нужно предложение catch-all; или else if, если возможно, что ни одно из предложений не нужно будет выполнять.
Обновление: чтобы выполнить максимум одно предложение, вам нужно использовать if, несколько else if и, возможно, финальный else.
Если вы пытаетесь сопоставить строки, вы можете использовать массив строк или использовать литеральные строки, как вы пытались сделать. Однако строки должны быть заключены в двойные кавычки ("), а не в одинарные, которые вы использовали. А переменная char c;, которую вы пытались использовать для хранения SMS-сообщения, на самом деле состоит только из одного символа. Вам нужно будет сделать ее массивом символов, например char c[140+1];, размером самого длинного SMS-сообщения + еще один для нулевого символа-терминатора строки. C напрямую не сравнивает строки как простые переменные, поэтому == и != здесь не сработают. Вам нужно будет сравнить их с помощью strcmp().
из всех условий только одно должно быть истинным. поэтому при совпадении строки следует выполнить только это условие и ждать прибытия следующего сообщения., @Awais Saifi
- Проблема с получением 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