problem facing in GSM900A Module with Arduino UNO

I had tried to make a simple project with using GSM Module and arduino uno.

GSM Module will send an sms to desired phone number according to switch position.

below mentioned program was copied from google.But problem is that when i power ON the arduino GSM not sending sms.SMS is sending after changing the switch position

If i switched off the arduino power supply at the time of Input switch turned “on” position. GSM will resend the sms when i again power on the arduino.

please advice what are the changes i have to do in existing program for achieving desired results.

#include <SoftwareSerial.h>

SoftwareSerial GPRS(10, 11);
boolean state, lastState;

void setup()
{
  pinMode(2, INPUT_PULLUP);
  state = digitalRead(2);
  lastState = state;
  
  GPRS.begin(9600);
  Serial.begin(9600);
  
  GPRS.println("AT+CMGF=1");
  
  delay(100);
}

void loop()
{
  while(GPRS.available()) {
    Serial.write(GPRS.read());
  }

  lastState = state;
  state = digitalRead(2);
  
  if ( state != lastState ) {
    sendSMS();
  }
  
  delay(100);
}

void sendSMS() {
  Serial.print("Switch was turned ");
  Serial.println(state ? "off" : "on");
  
  GPRS.println("AT+CMGS=\"+917987553768\"");
  
  delay(500);
  
  GPRS.print("Switch was turned ");
  GPRS.println(state ? "off" : "on");
  GPRS.write( 0x1a ); // ctrl+Z character
  
  delay(500);
}

when you power up the Arduino, state and lastState are both 0 (false). In setup(), you read the digital pint and store that same value in both state and laststate, so they are equal.

Inside loop(), you read the digital pin again. If you haven't changed anything, state == lastState so you don't send the SMS.

You need to rethink your logic if you only want to send a message when the digital pin is HIGH/LOW (On/Off)

blh64:
You need to rethink your logic if you only want to send a message when the digital pin is HIGH/LOW (On/Off)

I using toggle switch for input,So i make the program with "if "statement i,e if switch is in HIGH,sms will send.But problem is that GSM sending msg continuously in place of one msg.At last I has stop the sms by changing the toggle switch position.

But problem is that when i power ON the arduino GSM not sending sms.SMS is sending after changing the switch position

This is not a "problem" , it is how the program is designed. It seems like a reasonable architecture if you have a two position toggle switch, and you want to sent a message when the switch is changed from one position to the other.

What switch are you actually using?

If i switched off the arduino power supply at the time of Input switch turned "on" position. GSM will resend the sms when i again power on the arduino.

There is no "on" position.

This behavior is very strange given that in setup() you do this

pinMode(2, INPUT_PULLUP);
  state = digitalRead(2);
  lastState = state;

and in loop () this

lastState = state;
  state = digitalRead(2);

Try adding some Serial prints of the value of state and last state to your code to understand how this is true if the switch position has not been changed.

if ( state != lastState ) {
    sendSMS();
  }

i using small pcb mounted on/off switch

cattledog:
.

What switch are you actually using?

There is no "on" position.

ihave make some changes in my program.Now after power ON arduino GSM send the sms if switch in ON position.But msg sending continuously i have to change the switch position for stopping sms.
i need only one sms according to toggle switch position.

please help

#include <SoftwareSerial.h>

SoftwareSerial GPRS(10, 11);
/*boolean state, lastState;*/
const uint8_t switchPin     = 2;
const bool switchOn  = false;     // using INPUT_PULLUP
const bool switchOff = true;
bool lastState   = switchOff;
bool newState    = switchOff;
int joystick[1];
void setup()
{
   pinMode ( switchPin, INPUT_PULLUP );
   GPRS.begin(9600);
   Serial.begin(9600);
   GPRS.println("AT+CMGF=1");
   delay(500);
}

void loop()
{
  while(GPRS.available()) {
    Serial.write(GPRS.read());
  }
    joystick[0] = digitalRead(switchPin);
    newState = joystick[0]; 
  if( lastState != newState ) // state changed
  { newState=lastState;
    sendSMS();
   }
   }
  void sendSMS() {
  GPRS.println("AT+CMGS=\"+917987553768\"");
  delay(500);
  GPRS.println ("Switch was turned ON ");
  GPRS.write( 0x1a ); // ctrl+Z character
  delay(500);
}

You have this assignment backwards.

if( lastState != newState ) // state changed
  {// newState=lastState;
     lastState = newState;
    sendSMS();
   }

In your code, lastState is always == true (because of the initialization)and doesn’t change.
Anytime you have logical constructions like this, and you see unexpected behavior, you should use Serial print debugging to determine the value of your variables.

The code above will send an SMS when the switch position changes either way. On >Off or Off>On.
To only send on a state change to ON, or if you power up in the ON position, you want this

  if(newState == switchOn and lastState == switchOff) //switched changed from off to on
  { 
    sendSMS();
   }
  lastState = newState; //update lastState outside of conditional
#include <SoftwareSerial.h>

SoftwareSerial GPRS(10, 11);
/*boolean state, lastState;*/
const uint8_t switchPin     = 2;
const bool switchOn  = false;     // using INPUT_PULLUP
const bool switchOff = true;
bool lastState   = switchOff;
bool newState    = switchOff;
int joystick[1];
void setup()
{
  pinMode ( switchPin, INPUT_PULLUP );
  GPRS.begin(9600);
  Serial.begin(9600);
  GPRS.println("AT+CMGF=1");
  delay(500);
}

void loop()
{
  while (GPRS.available()) {
    Serial.write(GPRS.read());
  }
  joystick[0] = digitalRead(switchPin);
  newState = joystick[0];
  //if( lastState != newState ) // state changed
  if (newState == switchOn and lastState == switchOff)
  { //newState=lastState;
    sendSMS();
  }
  lastState = newState;
}
void sendSMS() {
  GPRS.println("AT+CMGS=\"+917987553768\"");
  delay(500);
  GPRS.println ("Switch was turned ON ");
  GPRS.write( 0x1a ); // ctrl+Z character
  delay(500);
}

cattledog:
You have this assignment backwards.

In your code, lastState is always == true (because of the initialization)and doesn’t change.
Anytime you have logical constructions like this, and you see unexpected behavior, you should use Serial print debugging to determine the value of your variables.

first of all i give big thanks to u sir,

i made some correction and make new program, as per this program sms will send on switch’s both position either ON or OFF.

#problem is that

When i switch on the UNO power supply GSM has sending the msg if switch in ON position .switch in OFF position GSM not sending sms at the time UNO power supply ON.

#include <SoftwareSerial.h>

SoftwareSerial GPRS(10, 11);

const uint8_t switchPin     = 2;
const bool switchOn  = false;     // using INPUT_PULLUP
const bool switchOff = true;
bool lastState = switchOff;
bool newState;
int joystick[1];
void setup()  
{
  pinMode ( switchPin, INPUT_PULLUP );
  GPRS.begin(9600);
  Serial.begin(9600);
  GPRS.println("AT+CMGF=1");
  delay(500);
}

void loop()
{
  while (GPRS.available()) {
    Serial.write(GPRS.read());
  }
  joystick[0] = digitalRead(switchPin);
  newState = joystick[0];
  delay(500);
  if (newState == switchOn and lastState == switchOff)
  { 
    sendSMS();
  }
  else if (newState == switchOff and lastState == switchOn)
  { 
    sendSMS1();
  }
  lastState = newState;
delay(500);
}

void sendSMS() {
  Serial.println("Switch was turned ON ");
  GPRS.println("AT+CMGS=\"+917987553768\"");
  delay(500);
  GPRS.println ("Switch was turned ON ");
  GPRS.write( 0x1a ); // ctrl+Z character*/
  delay(500);
}
void sendSMS1() {
  Serial.println("Switch was turned off ");
  GPRS.println("AT+CMGS=\"+917987553768\"");
  delay(500);
  GPRS.println ("Switch was turned off ");
  GPRS.write( 0x1a ); // ctrl+Z character*/
  delay(500);
}

When i switch on the UNO power supply GSM has sending the msg if switch in ON position .switch in OFF position GSM not sending sms at the time UNO power supply ON.

You can’t have both ways working at power on with fixed initialization of the states.

If you add the following line at the end of setup() you will make lastState the opposite of the power on switch position and send either SMS or SMS1 as appropriate.

lastState = !digitalRead(switchPin);

cattledog:
You can’t have both ways working at power on with fixed initialization of the states.

If you add the following line at the end of setup() you will make lastState the opposite of the power on switch position and send either SMS or SMS1 as appropriate.

lastState = !digitalRead(switchPin);

Now its perfectly working .thank u very much.

sir now i want to operate the relay through GSM.When i get the msg from GSM “switch turned ON”, I will send the msg to GSM Turn on the relay.How its possible.

I have prepare the programe:-

#include <SoftwareSerial.h>

SoftwareSerial GPRS(10, 11);
String textMessage;
const int relay = 12;
const uint8_t switchPin     = 2;
const bool switchOn  = false;     // using INPUT_PULLUP
const bool switchOff = true;
bool lastState = switchOff;
bool newState;
int joystick[1];
void setup()  
{
 pinMode(relay, OUTPUT);
  digitalWrite(relay, HIGH);
  pinMode ( switchPin, INPUT_PULLUP );
  GPRS.begin(9600);
  Serial.begin(9600);
  GPRS.println("AT+CMGF=1");
  delay(500);
  GPRS.print("AT+CNMI=2,2,0,0,0\r");
  delay(100);
}

void loop()
{
  while (GPRS.available()) {
    Serial.write(GPRS.read());
  }
  joystick[0] = digitalRead(switchPin);
  newState = joystick[0];
  delay(500);
  if (newState == switchOn and lastState == switchOff)
  { 
    sendSMS();
  }
  
  lastState = newState;
  delay(500);
  if(GPRS.available()>0){
    textMessage = GPRS.readString();
    Serial.print(textMessage);    
    recvSMS();
    delay(10);
  
  }}
void recvSMS() {
  if(textMessage.indexOf("ON")>=0){
    // Turn on relay and save current state
    digitalWrite(relay, LOW);
    Serial.println("Relay set to ON");  
    textMessage = "";   
  }
  if(textMessage.indexOf("OFF")>=0){
    // Turn off relay and save current state
    digitalWrite(relay, HIGH);
     Serial.println("Relay set to OFF");
    textMessage = ""; 
  }
}


void sendSMS() {
  Serial.println("Switch was turned ON ");
  GPRS.println("AT+CMGS=\"+917987553768\"");
  delay(500);
  GPRS.println ("Switch was turned ON ");
  GPRS.write( 0x1a ); // ctrl+Z character*/
  delay(500);
}

Problem is that when switch get ON ,RELAY state also changed automatically.
please let me know where i did wrong.

Problem is that when switch get ON,RELAY state also changed automatically.

I don't understand. Please explain more. I do not understand the arrangement of your system. How many Arduinos/GSM modules do you have?

Do you have two units. One unit with a switch which sends the switch position message to the other unit. The unit with the relay then operates the relay based on the state of the switch, and then sends a confirmation message back?

Do you have one unit which is sending a message to itself and then operating the relay? What is the point of that?

Sir,
Brief explanation of my project:-
One GSM900A module,One arduino UNO,One switch and One 5V relay.

First function:-

When switch turned" ON " GSM will send sms on my mobile number (which was mentioned in program).

Second Function:-
When i send text sms "ON" from my mobile number to GSM . Relay has to be get ON .
Same as if i send text sms "OFF" from my mobile number to GSM , Relay to be OFF.

But as per my program switch get ON , relay change the state automatically without any command.

Thank you for the explanation of your project. I now understand better what you are trying to do.

Is the relay active LOW or active HIGH?

With just the relay on pin 12, how does it respond to digitalWrite(12,HIGH) and digitalWrite(12,LOW)?

I know what the program says, but have you confirmed it.

Relay have the both options .But I choose the option.When Pin12 will become "LOW" relay gets ON

Relay have the both options .But I choose the option.When Pin12 will become “LOW” relay gets ON

I know that’s what you think you have, but have you confirmed it. If so, how have you done this. Multimeter? Lamp? What is connected to the relay?

The only way I can think that the relay turns on without a command is that something is not as expected, and the setup code actually turns the relay on

pinMode(relay, OUTPUT);
 digitalWrite(relay, HIGH);

cattledog:
I know that’s what you think you have, but have you confirmed it. If so, how have you done this. Multimeter? Lamp? What is connected to the relay?

The only way I can think that the relay turns on without a command is that something is not as expected, and the setup code actually turns the relay on

pinMode(relay, OUTPUT);

digitalWrite(relay, HIGH);

Actualy i am connected LED in place of relay.

changed some parametrs

  1. Set up code-relay-HIGH- deleted.
    2)HIGH for Relay ON
    3)LOW for Relay OFF

But no Improvement Relay gets ON, while operating switch.

#include <SoftwareSerial.h>

SoftwareSerial GPRS(10, 11);
String textMessage;
const int relay = 12;
const uint8_t switchPin     = 2;
const bool switchOn  = false;     // using INPUT_PULLUP
const bool switchOff = true;
bool lastState = switchOff;
bool newState;
int joystick[1];
void setup()  
{
 pinMode(relay, OUTPUT);
  /*digitalWrite(relay, HIGH);*/
  pinMode ( switchPin, INPUT_PULLUP );
  GPRS.begin(9600);
  Serial.begin(9600);
  GPRS.println("AT+CMGF=1");
  delay(500);
  GPRS.print("AT+CNMI=2,2,0,0,0\r");
  delay(100);
}

void loop()
{
  while (GPRS.available()) {
    Serial.write(GPRS.read());
  }
  joystick[0] = digitalRead(switchPin);
  newState = joystick[0];
  delay(500);
  if (newState == switchOn and lastState == switchOff)
  { 
    sendSMS();
  }
  
  lastState = newState;
  delay(500);
  if(GPRS.available()>0){
    textMessage = GPRS.readString();
    Serial.print(textMessage);    
    recvSMS();
    delay(10);
  
  }}
void recvSMS() {
  if(textMessage.indexOf("ON")>=0){
    // Turn on relay and save current state
    digitalWrite(relay, HIGH);
    Serial.println("Relay set to ON");  
    textMessage = "";   
  }
  if(textMessage.indexOf("OFF")>=0){
    // Turn off relay and save current state
    digitalWrite(relay, LOW);
     Serial.println("Relay set to OFF");
    textMessage = ""; 
  }
}


void sendSMS() {
  Serial.println("Switch was turned ON ");
  GPRS.println("AT+CMGS=\"+917987553768\"");
  delay(500);
  GPRS.println ("Switch was turned ON ");
  GPRS.write( 0x1a ); // ctrl+Z character*/
  delay(500);
}

Please help me on this matter... project is held up due to this fix

I don’t understand what is going on, but here is some trouble shooting ideas.

1). Remove the receive code at the start of loop(). It should not be required. It is not saving any message and can remove a message that you want to see.

  1. Try the code with and with out the outgoing message when the switch is turned On.

3). If the relay turns on with the switch and there is no outgoing message, and no printed incoming message, there must be some sort of hardware issue.

  1. Try moving the relay output do a different pin.
#include <SoftwareSerial.h>

SoftwareSerial GPRS(10, 11);
String textMessage;
const int relay = 12;
const uint8_t switchPin = 2;
const bool switchOn  = false;     // using INPUT_PULLUP
const bool switchOff = true;
bool lastState = switchOff;
bool newState;
int joystick[1];
void setup()
{
  pinMode(relay, OUTPUT);
  /*digitalWrite(relay, HIGH);*/
  pinMode ( switchPin, INPUT_PULLUP );
  GPRS.begin(9600);
  Serial.begin(9600);
  GPRS.println("AT+CMGF=1");
  delay(500);
  GPRS.print("AT+CNMI=2,2,0,0,0\r");
  delay(100);
}

void loop()
{
  //while (GPRS.available()) {
  //  Serial.write(GPRS.read());
  // }
  joystick[0] = digitalRead(switchPin);
  newState = joystick[0];
  delay(500);
  if (newState == switchOn and lastState == switchOff)
  {
    Serial.println("Switch was turned ON ");
    //sendSMS(); //try with and without an outgoing message
  }

  lastState = newState;
  delay(500);
  if (GPRS.available() > 0) {
    textMessage = GPRS.readString();
    Serial.print(textMessage);
    recvSMS();
    delay(10);
  }
}
void recvSMS() {
  if (textMessage.indexOf("ON") >= 0) {
    // Turn on relay and save current state
    digitalWrite(relay, HIGH);
    Serial.println("Relay set to ON");
    textMessage = "";
  }
  if (textMessage.indexOf("OFF") >= 0) {
    // Turn off relay and save current state
    digitalWrite(relay, LOW);
    Serial.println("Relay set to OFF");
    textMessage = "";
  }
}

void sendSMS() {
  Serial.println("Switch was turned ON ");
  GPRS.println("AT+CMGS=\"+917987553768\"");
  delay(500);
  GPRS.println ("Switch was turned ON ");
  GPRS.write( 0x1a ); // ctrl+Z character*/
  delay(500);
}

cattledog:
I don't understand what is going on, but here is some trouble shooting ideas.

1). Remove the receive code at the start of loop(). It should not be required. It is not saving any message and can remove a message that you want to see.

  1. Try the code with and with out the outgoing message when the switch is turned On.

3). If the relay turns on with the switch and there is no outgoing message, and no printed incoming message, there must be some sort of hardware issue.

  1. Try moving the relay output do a different pin.

without SendSMS() Switch ON has not interuping relay state.

But with SendSMS() Switch ON make interuption on relay state same as before. :frowning:

I think that for some reason, which I don't understand, the outgoing message is being received as well as sent.

Do you see "Switch was turned ON " as a received message with this piece of your code?

textMessage = GPRS.readString();
 Serial.print(textMessage);

Is your phone echoing anything back when it receives the sent message?

If the issue is the phone echo, that can be modified.

If the issue is some sort of self receipt of the outgoing message, I think there is a work around if you change the message in sendSMS().

Try changing ON to on (no caps.) or try changing ON to O_N_