1

I'm using SIM900 module + arduino uno + gsmlib.org library.

I'd like to send a string to endpoint on my API , and it worked correctly for the first time when I using inet.httpPOST function in setup(), but... in loop(), when I call that function again, it doesn't work. On serial monitor I get:

ATT: ERROR
RIC: 
ERROR    
DB:STARTING NEW CONNECTION
ATT: SHUT OK
RIC: 
SHUT OK    
DB:SHUTTED OK
ATT: OK
RIC: 
OK    
DB:APN OK
ATT: OK
RIC: 
OK    
DB:CONNECTION OK
ATT: ERROR
RIC: 
xxx.xxx.xxx.xxx

DB:ASSIGNED AN IP
status=ATTACHED

http://api.com.br/mystring

ATT: OK
RIC: 
OK    
DB:RECVD CMD
ATT: CONNECT OK
RIC: 
OK    
ATT: OK
RIC: 
CONNECT OK    
DB:OK TCP
ATT: >
RIC: 
> 
DB:>
ATT: SEND OK
RIC: 
SEND OK

DB:SENT

http://api.com.br/mystring

ATT: OK
RIC: 
xxx.xxx.xxx.xxx
ERROR    
ALREADY CONNECT    
DB:NOT CONN
ATT: OK
RIC: 
ERROR

ALREADY CONNECT    
DB:NOT CONN
ATT: OK
RIC: 
ERROR

ALREADY CONNECT    
DB:NOT CONN

How can I send data to my API continuously on loop() Could someone help me?

Following is my code (SOLVED):

#include <SoftwareSerial.h>
#include <TinyGPS++.h>
#include <inetGSM.h>

InetGSM inet;
TinyGPSPlus gps;
SoftwareSerial serialGps(11, 10);

/**
    setup
*/
void setup() {
  // Serial connection.
  Serial.begin(19200);
  Serial.println(F("Starting App Arduino"));

  // Turn on GPRS
  powerUpGprs();

  // Start configuration of shield SIM900 with baudrate and  connect to internet.
  if (gsm.begin(9600)) {
    Serial.println(F("\nstatus=READY"));

  // Start configuration of shield GPS NEO-6M with baudrate.
  serialGps.begin(9600);

  // Mensure and show memory usage
  Serial.println(F("\nMemory usage"));
  Serial.print(freeRam());
}

/**
   loop
*/
 void loop() {
  serialGps.listen();
  while (serialGps.available() > 0)  {
    if (gps.encode(serialGps.read())) {
      // Get GPS position and send To API 
      gsm.listen();
      // if sim900 started, connect to internet
      Serial.print(F("\r\n"));        
      Serial.print(F(" CONNECT TO INTERNET \r\n"));

      // GPRS attach, put in order APN, username and password.
      if (inet.attachGPRS("zap.com.br", "zap", "zap"))
        Serial.println("status=ATTACHED");
      else Serial.println("status=ERROR");
      delay(1000);
      // Read IP address.
      gsm.SimpleWriteln("AT+CIFSR");

      Serial.print(F("\r\n\r\n"));
      Serial.print(F(" GET GEOLOCATION & SEND TO API \r\n"));
      // get geolocation
      String geo;
      geo.concat("lat=" + String(gps.location.lat(), 6));
      geo.concat("&lng=" + String(gps.location.lng(), 6));
      geo.concat("&spd=" + String(gps.speed.kmph()));
      geo.concat("&gps.uuid=1");
      // send2Api
      Serial.println(geo.c_str());
      Serial.print(F("\n"));
      gsm.SimpleWriteln("AT+CIFSR");
      inet.httpPOST("api.com.br", 80, "/geolocations", geo.c_str(), "", 100);
    }
  }
}    

/**
   mensure memory usage
*/
int freeRam() {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

/**
   Power up
*/
void powerUpGprs() {
  pinMode(9, OUTPUT);
  delay(100);
  digitalWrite(9, HIGH);
  Serial.println(F("\nPower Up SIM900!"));
}    

Thank You!!!

Robson Fagundes
  • 35
  • 1
  • 3
  • 11

2 Answers2

1

Like I told you before, you have 2 instances of SoftwareSerial active, but you're allowed to listen to only one at a time (implementation rules). So you have to alternate between calling listen() on each instance; any data arriving at any port while its not the active port will be discarded. inet.httpPOST() worked in setup() because you called the function before begin()ing serialGps. Calling serialGps.begin() immediately made serialGps the active port, severing communication with the modem.

  • Add this line to SIM900.h in the library, under the public methods:

    void listen();
    
  • Add this method to SIM900.cpp:

    void SIMCOM900::listen(){
       _cell.listen();
    }
    
  • Save the files and add gsm.listen() right before gsm.SimpleWriteln("AT+CIFSR"); in loop().

  • Re-initialize GPRS, like you did in setup() with attachGprs(), right after gsm.listen() in loop().

  • Make serialGps.listen() the last statement in loop() immediately after the inet.httpPOST() call. Use braces to enclose the body of the while loop.

Hopefully this should solve your problem.

SoreDakeNoKoto
  • 2,422
  • 2
  • 14
  • 23
-1

I had similar problem. I have added gsm.begin() method at the end of the loop, and it has solved my problem!!

Seems like you can't send multiple http requests with single gsm session. Relevant parts of setup() and loop() methods are shown below:

void setup() 
{

Serial.begin(9600);
Serial.println("GSM Shield testing.");

if (gsm.begin(2400)){
  Serial.println("\nstatus=READY");
  started=true;  
}
else Serial.println("\nstatus=IDLE");

}

void loop()

{
   if(started){
      if(inet.attachGPRS("internet.wind","",""))
        Serial.println("status=ATTACHED");
      else
        Serial.println("status=ERROR");

      if(inet.httpPOST(server,port, path,parameters,msg, 50)){
          Serial.println("Data sent to server succesfully!");
      }
      else{
        Serial.println("Failed to send data to the server");
      }
 } 

 if (gsm.begin(2400)){
  Serial.println("\nstatus=READY");
  started=true;  
}
else Serial.println("\nstatus=IDLE");

};
Nick Gammon
  • 38,901
  • 13
  • 69
  • 125