1

I am using following code for my arduino project in which i have to control a dc motor using arduino uno via text messages. my question is that i have used multiple number of 'If' statements and only one else statement at the last, i compiled this code and gives no error, is it ok to use multiple If statements one after another without using else after each 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");
   }

}
2
  • A 'list' of if statements should be implemented as a switch/case statement; this is used where a single variable has many possibilities, and allows a 'default' case which does what you think your final else statement does. However, as Majenko says, you can't directly compare strings as your are doing. Oct 9 '15 at 16:33
  • @CharlieHanson so i can replace the if's with labels and set the value of the variable equal to the incoming message? Oct 9 '15 at 18:46
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");
   }

}

So I've made some edits to your code. For example this code 'motoronanticlockwise' isn't correct. Single quotes are used for char data types and double quotes are used for string literals. You should use double quotes since there are multiple characters "motoronanticlockwise". Also as Majenko said you would have to use strcmp() in order to compare c-strings c-strings are char arrays that have a null terminator '\0'. Also strcmp() returns 0 if the two strings are equal.

Your last else statement will only executed if the previous if statement is false. It seems like you only want it to execute if all of the previous if statement are false. To do this you make the first if statement and then make a chain of if else statements followed by a single else statement. You can have a single if statement with no else or if else statements however, if you want else or if else statements then you need to have an if statement. I've made the necessarily edits to your code already.

Lastly, this part of the program is the biggest problem while(c=sms.read()) This is because sms.read() returns a char so you can only read the sms message one character at a time. To do this properly you should make a character array and store the values returned by sms.read() in it. This can be done like this

char message [160]; // I chose 160 since that is max size for sms
memset( message, '\0', sizeof(char)*160 ); // this fills message with null characters
// this will add the characters to messages[]
for(int i = 0; message[i] = sms.read(); i++){}

I am using a for loop to iterate through message[].

Try the above and get back to me if there are any problems with it.

4
  • I apologize for late reply, and thank you for your time to answer the question. I'll check the code on hardware and let you know. Again thanks for you help, I really appreciate that. Oct 15 '15 at 21:43
  • sketch_oct16a.ino: In function 'void loop()': sketch_oct16a:81: error: 'messages' was not declared in this scope sketch_oct16a:114: error: 'messsage' was not declared in this scope what does this mean? i verified and this error came up Oct 15 '15 at 22:03
  • I screwed up, those are just typos. I edited the code in my answer.
    – Chris
    Oct 16 '15 at 2:18
  • Yeah i thought so, its OK now verified. cheers Oct 16 '15 at 11:19
1

Two things:

  1. The else will only be subject to the last if being false, the rest of the if statements are completely separate and can affect the else in no way whatsoever. To chain them you need if (...) { blah blah } else if (...) { blah blah } etc.
  2. You cannot compare characters and strings like that (and in fact they're not even strings, they're lots of characters squeezed into a single character through the use of the wrong kind of quotes).

So basically no, your whole program there is completely wrong and won't do what you think it will and you need to completely re-thing how it works.

Some tips:

  • Use strcmp() to compare strings.
  • If reading strings from serial store them in character arrays not a single character.

You might find this useful:

5
  • So you are saying that i should create an array of strings and then using 'strcmp()' to compare them. Then how would i assign each string a seperate function? Oct 9 '15 at 18:42
  • No, I am saying each string should be an array of characters. Google for tutorials on "C strings".
    – Majenko
    Oct 9 '15 at 18:44
  • then i have to define each array like i have at the beginning and just refer to it in the conditional statement? Oct 9 '15 at 18:48
  • Ask google to show you. It's better at it than me trying to teach you the basics in comments. There's literally a bazillion examples and tutorials out there. Go and read them.
    – Majenko
    Oct 9 '15 at 18:50
  • i was going through that link it and its quite useful. thanks. Oct 9 '15 at 18:56
0

If you intend each if statement to be executed, regardless of the whether the prior one(s) did, then yes, they do not require else clauses.

If you mean to try each condition until you find one that is true, and execute that one and only that one, then the second and subsequent ifs need to be else ifs. The final one may be just an else, if you want a catch-all clause; or an else if if it is possible that none of the clauses might need to be run.

Update: To execute at most one clause, you need to use if, some else ifs, and maybe a final else.

If you're trying to match strings, you can use an array of strings or use literal strings as you've tried to do. Strings have to be enclosed in double-quotes (") however, not the single quotes you've used. And the variable char c; you tried to use to hold the SMS message is really only one character. You'll need to make it an array of characters such as char c[140+1];, the size of the longest SMS message + one more for a zero-character string-terminator. C doesn't directly compare strings as simple variables so == and != won't work here. You'll need to compare them with strcmp().

1
  • from all the conditions only one has to be true. so when the string is matched it should execute only that condition and wait for the next message to arrive. Oct 9 '15 at 18:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.