Arduino Uno + SIM900

Dear partners,

I'm new in Arduino development (just 1 week).

I need help with following simple issue:

Arduino Uno paired with GSM shield SIM900 (last one is "wear" on Arduino). RX/TX jumpers set to SW position. After starting devices, they setting up GPRS connection and send GET request to server. As a reply it's getting text values (1 or 0) and depending on them I need to switch on/off led lamp. Connection process is successful (I see it on web-server's logs). I need procedure for reading console and assigning to "ledcmd" received after AT+HTTPREAD reply. In manual mode after AT+HTTPREAD I see following:
+HTTPREAD:1
1
OK

My basic code is below.

#include "SIM900.h"
#include <SoftwareSerial.h>

int ledpin = 11;
char ledcmd;

void setup()
{
    pinMode(ledpin, OUTPUT);
    
    Serial.begin(9600);
    Serial.println("GSM Shield testing.");
    if (gsm.begin(9600)) Serial.println("\nstatus=READY");
    else Serial.println("\nstatus=IDLE");
    Serial.println("Setting up GPRS");
    gsm.SimpleRead();
    gsm.SimpleWriteln(("AT+SAPBR=3,1,\"Contype\",\"GPRS\""));
    delay(100);
    gsm.SimpleWriteln(("AT+SAPBR=3,1,\"APN\",\"internet.beeline.am\""));
    delay(100);
    gsm.SimpleWriteln(("AT+SAPBR =1,1"));
    delay(100);
    gsm.SimpleWriteln(("AT+HTTPINIT"));
    delay(100);
    gsm.SimpleWriteln(("AT+HTTPPARA=\"CID\",1"));
    delay(100);
    gsm.SimpleWriteln(("AT+HTTPPARA=\"URL\",\"http://www.mydomain.com/request.php\""));
    delay(100);
    gsm.SimpleWriteln(("AT+HTTPACTION=0"));
    delay(100);
    gsm.SimpleWriteln(("AT+HTTPREAD"));
};


void loop()
{
    if (ledcmd=="1")
    {
    digitalWrite(ledpin, HIGH);
    }
    else
    {
    digitalWrite(ledpin, LOW);
    }
    delay (2000);
}

There are too many similar tasks and replies in internet. Unfortunately I have tried most of them in last days and haven't reached any result.

Thanks for any advice or reply.

I need procedure for reading console and assigning to "ledcmd" received after AT+HTTPREAD reply.

First step is to get the GSM modem off of the hardware serial pins. The Arduino is NOT reading the response from the modem. That response is being sent directly to the Serial Monitor application by the modem, because the modem is on the hardware serial pins.

PaulS:
First step is to get the GSM modem off of the hardware serial pins. The Arduino is NOT reading the response from the modem. That response is being sent directly to the Serial Monitor application by the modem, because the modem is on the hardware serial pins.

Thanks a lot for reply. What I need to do for that? Something physically or on code level? Could you please explain?

Something physically or on code level?

Yes. Both.

RX/TX jumpers set to SW position.

This tells us nothing, as we have no idea which shield you have. You should be able to set the jumpers to use two pins other than the hardware serial pins, and use an instance of the SoftwareSerial class to send data to, AND get data from, the shield.

PaulS:
Yes. Both.
This tells us nothing, as we have no idea which shield you have. You should be able to set the jumpers to use two pins other than the hardware serial pins, and use an instance of the SoftwareSerial class to send data to, AND get data from, the shield.

Unfortunately there are no more information about GSM shield. Just SIM900 and SimCom, and as I know it just main module's vendor. There are too many shields vendors based on SIM900. I only can share shield's photo. There are pins for select RX and TX mode between hardware and software. They are on SW position (visible on photo). So, I think my shield is "ready" to use other (software selected) pins for send/get data. As I understand, I need do something in my code. Besides this, as I told, communication with modem is established. I can send AT commands. For it I'm using SIM900.h library, which calling GSM.h/GSM.cpp and there is #define GSM_TXPIN 2 and #define GSM_RXPIN 3 lines. As I understand, on software level pins assigned to 2 and 3. Am I right?

There are some code eamples here that may be of assistance?

Plus there is the article in my signature that may also be of use.

dannable:
There are some code eamples here that may be of assistance?

Plus there is the article in my signature that may also be of use.

Thanks a lot for reply. Depend on your examples and manuals here updated code:

#include <SoftwareSerial.h>

SoftwareSerial gsmserial(2,3);
int ledpin = 11;
char responce[100];
int count=0;

 
void setup()
{
     pinMode(ledpin, OUTPUT);
     
     gsmserial.begin(9600);
     Serial.begin(9600);
     
     Serial.println("Setting up GPRS");
     
     gsmserial.println(("AT+SAPBR=3,1,\"Contype\",\"GPRS\""));
     delay(1000);
     serialread();
     clearbuffer();
     
     gsmserial.println(("AT+SAPBR=3,1,\"APN\",\"internet.beeline.am\""));
     delay(1000);
     serialread();
     clearbuffer();
     
     gsmserial.println(("AT+SAPBR =1,1"));
     delay(1000);
     serialread();
     clearbuffer();
     
     gsmserial.println(("AT+HTTPINIT"));
     delay(1000);
     serialread();
     clearbuffer();
     
     gsmserial.println(("AT+HTTPPARA=\"CID\",1"));
     delay(1000);
     serialread();
     clearbuffer();
     
     gsmserial.println(("AT+HTTPPARA=\"URL\",\"http://www.55tele.com/arduino.php?name=ALARM\""));
     delay(1000);
     serialread();
     clearbuffer();
     
     gsmserial.println(("AT+HTTPACTION=0"));
     delay(1000);
     serialread();
     clearbuffer();
     
     Serial.println("GPRS ready");
     
     gsmserial.println(("AT+HTTPREAD"));
     delay(1000);
     serialread();
};

void serialread()
{
     while(gsmserial.available())
     {
            responce[count++]=gsmserial.read();
            if(count == 100) break;
     }
     count = 0;
};

void clearbuffer()
{
    for (int i=0; i<100; i++)
    {
      responce[i]=(char)0;
    }
}

void loop()
{
     if (responce[0]=='1')
     {
     digitalWrite(ledpin, HIGH);
     }
     else
     {
     digitalWrite(ledpin, LOW);
     }
     
     Serial.println("Current buffer is:");
     Serial.println(responce);
     delay (2000);
}

In serialread() I'm reading my software serial ports.

In clearbuffer() I'm clearing buffer after each AT command except last one.

In loop beside of checking I'm showing mu buffer. It must contain only output for AT+HTTPREAD but in console I see something mixed with previous outputs and no anything from last one:

Current buffer is:
AT+HTTPREAD

OK

+HTTPACTION:0,200,1
rduino.php?name=ALARM

Please help me find where is my mistake.

void serialread()
{
     while(gsmserial.available())
     {
            responce[count++]=gsmserial.read(); 
            if(count == 100) break;
     }
     count = 0;
};

when do you null terminate the responce[] string?

BulldogLowell:
when do you null terminate the responce[] string?

There was mistake. I have corrected it.

void clearbuffer()
{
    for (int i=0; i<100; i++)
    {
      responce[i]=(char)0;
    }
}

Situation not seriously changed.
Current buffer is:
AT+HTTPREAD
OK
+HTTPACTION:0,200,1

So your approach is a bit flawed.

Here is an example that you can look at that seems to work:

#include <SoftwareSerial.h>
#define MAX_MESSAGE_LENGTH 100

SoftwareSerial gsmserial(2,3);
const byte ledpin = 11;

//HardwareSerial& gsmserial = Serial;  // for debug
 
void setup()
{
     pinMode(ledpin, OUTPUT);
     gsmserial.begin(9600);
     Serial.begin(9600);
     Serial.println("Setting up GPRS");

     gsmserial.println(("AT+SAPBR=3,1,\"Contype\",\"GPRS\""));
     while (!waitAndPrintResponse()); // EDIT
     
     gsmserial.println(("AT+SAPBR=3,1,\"APN\",\"internet.beeline.am\""));
     while (!waitAndPrintResponse()); // EDIT
     
     gsmserial.println(("AT+SAPBR =1,1"));
     while (!waitAndPrintResponse());
     
     gsmserial.println(("AT+HTTPINIT"));
     while (!waitAndPrintResponse());
     
     gsmserial.println(("AT+HTTPPARA=\"CID\",1"));
     while (!waitAndPrintResponse());
     
     gsmserial.println(("AT+HTTPPARA=\"URL\",\"http://www.55tele.com/arduino.php?name=ALARM\""));
     while (!waitAndPrintResponse());
     
     gsmserial.println(("AT+HTTPACTION=0"));
     while (!waitAndPrintResponse());
     
     Serial.println("GPRS ready");
     
     gsmserial.println(("AT+HTTPREAD"));

};

void loop()
{

}

bool waitAndPrintResponse()
{
  if(const char* response = checkForNewMessage(gsmserial, '\n'))
  {
    Serial.print(F("New Response:\t"));
    Serial.println(response);
    return true;
  }
  return false;
}

const char* checkForNewMessage(Stream& stream, const char endMarker)
{
  static char incomingMessage[MAX_MESSAGE_LENGTH] = "";
  static byte idx = 0;
  if(stream.available())
  {
    incomingMessage[idx] = stream.read();
    if(incomingMessage[idx] == endMarker)
    {
      incomingMessage[idx] = '\0';
      idx = 0;
      return incomingMessage;
    }
    else
    {
      idx++;
      if(idx > MAX_MESSAGE_LENGTH - 1)
      {
        //stream.print(F("{\"error\":\"message too long\"}\n"));  //you can send an error to sender here
        idx = 0;
        incomingMessage[idx] = '\0';
      }
    }
  }
  return nullptr;
}

EDIT: I corrected two function calls...

BulldogLowell:
So your approach is a bit flawed.

Here is an example that you can look at that seems to work:

Thanks for code. But it isn't work for me. It isn't parse a nothing from serial.