Using c == "x" or char c;

I am semi new to programming, but courtesy of some books I have purchased, and this website, I am getting there.

I have a GSM shield and have found some code to turn a light on and off via txt message (sms). It all works well, when I send the number “1”, the light turns on; “2” the light turns off.

What I want to be able to send is “light on” as a txt to turn the light on, and “light off” to turn it back off. The code that acknowledges the txt message relies on if ("c == “1”…

So how can I make it: if (c == “light on”…?

To hold a whole string you need something larger than a char variable. You need a whole array of them, at least one character larger than the string you want to hold. Then, you use strcmp to compare the string you get to the string literal you want to test against.

See also @Robin2 Serial Input Basics thread.

Thank you for pointing me in the right direction. :slight_smile:

Here's a post with a sketch that is similar. Like Delta_G suggested, it uses character arrays and strcmp functions. In that sketch, it uses the strcmp_P variant to save some RAM by using the F macro.

Okay, I have read through the string and array and character differences and for some reason it all makes no sense to me :/. Here is what I have in the sketch, it is almost there, but I just can’t figure out how to make the if statement compare the message text against the given string properly.

#include <GSM.h>

#define PINNUMBER ""


GSM gsmAccess;
GSM_SMS sms;

char remoteNumber[20];  // Holds the emitting number

int RELAY1 = 11;
int LED1ON = 8;
int LED1OFF = 9;


void setup() 
{
 Serial.begin(9600);
 Serial.println("SMS Messages Receiver");
 boolean notConnected = true;

 while(notConnected)
 {
   if(gsmAccess.begin(PINNUMBER)==GSM_READY)
     notConnected = false;
     else
       {
         Serial.println("Not connected");
         delay(1000);
       }
       Serial.println("GSM initialized");
 Serial.println("Waiting for messages");


 }

pinMode(RELAY1, OUTPUT);  
pinMode(LED1ON, OUTPUT);
pinMode(LED1OFF, OUTPUT);



}

void loop() 
{
 char c;
 const char string_2[] = "off";
 const char string_3[] = "on";
 int strcmp ( const char * string_2, const char * string_3 );

 if (sms.available())
{  Serial.println("Message received from:");

   sms.remoteNumber(remoteNumber, 20);
   Serial.println(remoteNumber);

   if(sms.peek()=='#')
   {
     Serial.println("Discarded SMS");
     sms.flush();
   }

   // Read message bytes and print them
   while(c = sms.read()){
    if(strcmp(string_2,c)){
            digitalWrite(RELAY1, HIGH);   // turn the relay off
            digitalWrite(LED1ON, HIGH);
            digitalWrite(LED1OFF, LOW);
            Serial.print(string_2);
            delay(4000);
          }
          else if(strcmp(string_3,c)){
                digitalWrite(RELAY1, LOW);   // turn the relay on
                digitalWrite(LED1OFF, HIGH);
                digitalWrite(LED1ON, LOW);
                Serial.print(string_3);
                delay(4000);
          

          }
    Serial.println("\nEND OF MESSAGE");
   }

   // delete message from modem memory
   sms.flush();
   Serial.println("MESSAGE DELETED");
 }

 delay(1000);

}
  while(c = sms.read()){
     if(strcmp(string_2,c)){

What did the compiler say about that?
Robin2's has a very useful tutorial thread on serial input basics

Please remember to use code tags when posting code.

AWOL:

  while(c = sms.read()){

if(strcmp(string_2,c)){


What did the compiler say about that?
Robin2's has a very useful tutorial thread on serial input basics

Please remember to use code tags when posting code.

Yes, it was late in the day, since put the code tags in. The compiler accepted the if() statement, but from putting theory into practice, upon the first sms message, it turns the relay off, but the message text is not received as a word in the serial, rather each letter of the string is received as its own "message." Therefore it won't work as far as the next else if() where I want it to read the "on" word to differentiate commands.

I have read the Serial input tutorial a couple of times now, but my mind isn't letting me swap serial input for sms input, although they are essentially the same concept through different means.

Given char c;, and if(strcmp(string_2,c)){, it doesn't seem very likely to me that

The compiler accepted the if() statement

I have no idea why it accepts it, but it doesn’t function in a working way either.

I have tried changing it around a bit

void loop() 
{
  char c;
  char sms_text;
  
  if (sms.available())
 {  Serial.println("Message received from:");

    sms.remoteNumber(remoteNumber, 20);
    Serial.println(remoteNumber);

    if(sms.peek()=='#')
    {
      Serial.println("Discarded SMS");
      sms.flush();
    }


    // Read message bytes and print them
    while (sms_text = sms.read()){
     if(strcmp(sms_text, "Off") == 0){
             digitalWrite(RELAY1, HIGH);   // turn the relay off
             digitalWrite(LED1ON, HIGH);
             digitalWrite(LED1OFF, LOW);
             Serial.print("\nRelay off");
             delay(4000);
           }
      else if(strcmp(sms_text, "On") == 0){
                 digitalWrite(RELAY1, LOW);   // turn the relay on
                 digitalWrite(LED1OFF, HIGH);
                 digitalWrite(LED1ON, LOW);
                 Serial.print("\nRelay on");
                 delay(4000);

As you hinted at earlier, and after rereading the serial thread a third time I realised that, like excel, a comparison function will need an output of =,<,> 0 or 1. Still can’t seem to make it work, every sms in this case will turn it on, but never off.

Basically I think I need to know how to turn the data in the message into a character array properly, that compares 1 to 1 with the quoted “On” and “Off.” In the serial thread that people have directed me to, I see that they use a function like if I were to be able to type sms.read(sms_txt) to dictate what the character array of the sms.read function is seeing.

Or I have just lost the plot, and my compiler is messing with me.

     if(strcmp(sms_text, "Off") == 0){

If the ONE character you just read equals the string "Off", do something. Well, there isn't a hope in hell of that ever happening.

FORGET about trying to use the data ONE CHARACTER AT A TIME.

Re-read Robin2's post as many times as you need to, until you get that you MUST collect the data in an array.

One of the problems with helping you is that you post just snippets of code. So, here's a snippet of an answer:

You need to ... It's really that simple.

PaulS:

     if(strcmp(sms_text, "Off") == 0){

If the ONE character you just read equals the string “Off”, do something. Well, there isn’t a hope in hell of that ever happening.

FORGET about trying to use the data ONE CHARACTER AT A TIME.

Re-read Robin2’s post as many times as you need to, until you get that you MUST collect the data in an array.

One of the problems with helping you is that you post just snippets of code. So, here’s a snippet of an answer:

You need to … It’s really that simple.

#include <GSM.h>


#define PINNUMBER ""


GSM gsmAccess;
GSM_SMS sms;

char remoteNumber[20];  // Holds the emitting number

int RELAY1 = 11;
int LED1ON = 8;
int LED1OFF = 9;


void setup() 
{
  Serial.begin(9600);
  Serial.println("SMS Messages Receiver");
  boolean notConnected = true;

  while(notConnected)
  {
    if(gsmAccess.begin(PINNUMBER)==GSM_READY)
      notConnected = false;
      else
        {
          Serial.println("Not connected");
          delay(1000);
        }
        Serial.println("GSM initialized");
  Serial.println("Waiting for messages");
 

  }

 pinMode(RELAY1, OUTPUT);  
 pinMode(LED1ON, OUTPUT);
 pinMode(LED1OFF, OUTPUT);


}

void loop() 
{
  char c;
  char sms_text[];
  
  if (sms.available())
 {  Serial.println("Message received from:");

    sms.remoteNumber(remoteNumber, 20);
    Serial.println(remoteNumber);

    if(sms.peek()=='#')
    {
      Serial.println("Discarded SMS");
      sms.flush();
    }

    // Read message bytes and print them
    while (sms_text = sms.read()){
     if(strcmp(sms_text, "Off") == 0){
             digitalWrite(RELAY1, HIGH);   // turn the relay off
             digitalWrite(LED1ON, HIGH);
             digitalWrite(LED1OFF, LOW);
             Serial.print("\nRelay off");
             delay(4000);
           }
      else if(strcmp(sms_text, "On") == 0){
                 digitalWrite(RELAY1, LOW);   // turn the relay on
                 digitalWrite(LED1OFF, HIGH);
                 digitalWrite(LED1ON, LOW);
                 Serial.print("\nRelay on");
                 delay(4000);
           
 
           }
     Serial.println("\nEND OF MESSAGE");
    }

    // delete message from modem memory
    sms.flush();
    Serial.println("MESSAGE DELETED");
  }

  delay(1000);

}

Sorry, I didn’t know the whole sketch needed to be reposted for every change in the void loop. See the newbie next to my name, it means I am new and learning. I have read up on character arrays, but until I do something that works, I find it quite hard to understand how it works.

Here is the latest revision, and this time the compiler says

exit status 1
incompatible types in assignment of ‘int’ to ‘char [25]’
[\quote]

See the newbie next to my name, it means I am new and learning

No, it means you haven't posted much here.

    while (sms_text = sms.read()){

Wishful thinking is getting you nowhere. sms.read() returns one character in an int variable. You can't assign an int to an array.

   char array[80];
   byte index = 0;

   while(sms.available() > 0)
   {
      array[index++] = sms.read();
      array[index] = '\0';
   }

   if(strcmp(sms_text, "Off") == 0)
   {
      // Do whatever off means

Thank you for the post PaulS, through that I have learned a bit more about arrays and the index[i/++] function, and how it works.

What I don't understand is how the array or index bind to the character sms_text? I have tried a couple of ways, which REALLY didn't work, jamming my serial monitor.

You have also answered the function of sms.read() and why it sent as three messages in the serial monitor for the phrase "off."