TCP loop problem

Hello,

My aim is to send data every so often to a server using TCP, with the 3G shield.
I’m having a problem with my TCP connection:
I can send the data once, then the program stalls.

I’ve printed the output
the first time round it prints

AT+NETOPEN="TCP",8081
CONT=1,"IP","gprs.swisscom.ch"OKAT+NETOPEN="TCP",8081Network opened

but the second time it just blocks after the netopen:

AT+NETOPEN="TCP",8081
xuV0RKRks2eXJ1az0g"},"body":AT+CGSOCKCONT=1,"IP","gprs.swisscom.ch"OKAT+CGSOCKCONT=1,"IP","gprs.swisscom.ch"OK....

Or sometimes, instead of the "AT+CGSOCKCONT=1,“IP”,“gprs.swisscom.ch"OK” I get other prints like:
AT+NETCLOKatingAT+CGSOCKCONT=1,“IP”,"gprs.swisscom.ch"Manufacturer: SIMCOM INCORPORATEDModel: SIMCOM_SIM5218ERevision: SIM5218E_V2.4IMEI: 355843030369544+GCAP: +CGSM,+FCLASS,+DSERRORAT+NETCLOKatingAT+CGSOCKCONT=1,“IP”,"gprs.swisscom.ch"Manufacturer: SIMCOM INCORPORATEDModel: SIMCOM_SIM5218ERevision: SIM5218E_V2.4IMEI: 355843030369544+GCAP: +CGSM

then it’s like if the program restarts again and bugs at
AT+NETOPEN=“TCP”,8081
But it never receives the Network opened.

I’ve made a library out of this: http://www.cooking-hacks.com/index.php/documentation/tutorials/arduino-3g-gprs-gsm-gps#step14
In my loop function I create the object and I call a function to send the info to the server (it’s the same code as is the link)

Could you please enlighten me on how I could send data at regular intervals, and why I’m not getting the “Network opened” response?

Thanks a lot!

I've made a library out of this:

Then show that library and the code you're doing your tests with. We don't like guessing what you may have done.

Ok,

Here is the library

So this is the header:

public:
		TCP_3G();
		void begin(int led, int onModulePin);
		void sendInfo(int bottleN, float waterHeight, float derivative);
		
	private:
		void switchModule();
		int _led;
		int _onModulePin;
		String COSM_API_KEY;
		String COSM_FEED;
		char data[1024];
		int x;
		char name[20];

and the code in the cpp file:

TCP_3G::TCP_3G(){
	
}

void TCP_3G::begin(int led, int onModulePin){
	_led = led;
	_onModulePin = onModulePin;
	
	COSM_API_KEY = "**********";
	COSM_FEED = "*****";
	x = 0;
	
	Serial.println(".................START..................");
    delay(2000);
    pinMode(_led, OUTPUT);
    pinMode(_onModulePin, OUTPUT);
    
}

void TCP_3G::switchModule(){
    digitalWrite(_onModulePin,HIGH);
    delay(2000);
    digitalWrite(_onModulePin,LOW);
}

void TCP_3G::sendInfo(int bottleN, float waterHeight, float derivative){
	
	// Wake up module
	switchModule();                    // switches the module ON
    for (int i=0;i< 5;i++){
        delay(5000);
    }
	// the server and the port
	char _server[] = "api.cosm.com";
	char _port[] = "8081";
	
	//Doing this for the size
	char sbottle[6];
    itoa(bottleN,sbottle, 10);
    char scm[6];
    sprintf(scm,"%.0f",waterHeight);
    char sderiv[6];
    sprintf(sderiv,"%.0f",derivative);
	
    char feedStr[] = "{\"method\":\"put\",\"resource\":\"/feeds/87672\",\"params\":{},\"headers\":{\"X-PachubeApiKey\":\"JuGragDnlf4No0_C6_OLrVGg8biSAKxuV0RKRks2eXJ1az0g\"},\"body\":{\"datastreams\":[{\"id\":\"0\",\"current_value\":\"\"},{\"id\":\"1\",\"current_value\":\"\"},{\"id\":\"2\",\"current_value\":\"\"}]},\"token\":\"0x12345\"}";

	// Set PDP parameters
    Serial.println("AT+CGSOCKCONT=1,\"IP\",\"gprs.swisscom.ch\"");
    Serial.flush();
	Serial.print(Serial.read());
    while(Serial.available()==0 || Serial.read()!='K');
    
    // Set connection parameters
    Serial.print("AT+NETOPEN=\"TCP\","); Serial.println(_port);
    Serial.flush();
    x=0;
    do {
        while(Serial.available()==0);
        data[x]=Serial.read();
		if((data[x]!='\n') && (data[x]!='\r')) Serial.print(char(data[x]));
        x++;  
    } while(!(data[x-1]=='d'&&data[x-2]=='e'));       //waits for response "Network opened"

    while(Serial.available()==0 || Serial.read()!='K');

	
    // Connect to server
    Serial.print("AT+TCPCONNECT=\""); Serial.print(_server); Serial.print("\","); Serial.println(_port);
    Serial.flush();
    while(Serial.available()==0 || Serial.read()!='K');
    
    Serial.print("AT+TCPWRITE="); Serial.println(sizeof(sbottle) + sizeof(scm) + sizeof(sderiv) + sizeof(feedStr));//
    Serial.flush();
    while(Serial.available()==0 || Serial.read()!='>');
	
    Serial.print("{\"method\":\"put\",\"resource\":\"/feeds/");
    Serial.print(COSM_FEED); 
    Serial.print("\",\"params\":{},\"headers\":{\"X-PachubeApiKey\":\"");
    Serial.print(COSM_API_KEY);
    Serial.print("\"},\"body\":{\"datastreams\":[{\"id\":\"0\",\"current_value\":\"");
    Serial.print(bottleN);  
    Serial.print("\"},{\"id\":\"1\",\"current_value\":\"");
    Serial.print(waterHeight);
    Serial.print("\"},{\"id\":\"2\",\"current_value\":\"");
    Serial.print(derivative);
    Serial.println("\"}]},\"token\":\"0x12345\"}");
	
    Serial.println("AT+NETCLOSE"); //Opens the socket with the type of protocol and the port 
    Serial.flush();
    while(Serial.available()==0 || Serial.read()!='K');
	memset(data, 0, 255);
    
    switchModule();

}

And here is the code I’m doing my tests with:

 #include <TCP_3G.h>
  
  TCP_3G info;
  
  // Time
  unsigned int dtLoop = 10000;            // [ms]

  float cm = 0.0f;
    
  // Sampler
  unsigned char curBottle = 1;           // The current bottle waiting to be filled.
  
  void setup()
  {
    // initialize serial communication.
    Serial.begin(115200);
    
    info.begin(13,2);

  }
  
  void loop()
  {

    float cmDerivative = 62;
    
    
    //info.sendInfo(curBottle, cm, cmDerivative);
    info.sendInfo(8,-1.2, 4.2);
    
    Serial.println("info sent"); 
   
    delay(dtLoop);
  }
    Serial.println("info sent");

You’re sending debugging info to your 3G shield?

Again here it seems:

	Serial.println(".................START..................");

It's just so it prints in the terminal, should I do it in another way?

But it's also sent to the 3G shield and the shield may get rather confused by it, don't you think so?

You're right, however, how am I supposed to debug and know where the program blocks without disturbing the arduino and the 3G shield?

I've taken out these prints and run tests again, but it still blocks at: AT+NETOPEN="TCP",8081

So I'm not sure if it really disturbs to put in some prints when no argument/command is expected.

I’ve found a work around!

in the sendInfo method, I only have this left:

char sbottle[6];
    itoa(bottleN,sbottle, 10);
    char scm[6];
    sprintf(scm,"%.0f",waterHeight);
    char sderiv[6];
    sprintf(sderiv,"%.0f",derivative);
	
    char feedStr[] = "{\"method\":\"put\",\"resource\":\"/feeds/12345\",\"params\":{},\"headers\":{\"X-PachubeApiKey\":\"KuGtesAnlf8No0_C9_pLrVGt8biSAKxuViRKFks2eXJ1ez0g\"},\"body\":{\"datastreams\":[{\"id\":\"0\",\"current_value\":\"\"},{\"id\":\"1\",\"current_value\":\"\"},{\"id\":\"2\",\"current_value\":\"\"}]},\"token\":\"0x12345\"}";

Serial.print("AT+TCPWRITE="); Serial.println(sizeof(sbottle) + sizeof(scm) + sizeof(sderiv) + sizeof(feedStr));//
    Serial.flush();
    while(Serial.available()==0 || Serial.read()!='>');
	
    Serial.print("{\"method\":\"put\",\"resource\":\"/feeds/");//87672\",\"params\":{},\"headers\":{\"X-PachubeApiKey\":\"");//JuGragDnlf4No0_C6_OLrVGg8biSAKxuV0RKRks2eXJ1az0g\"},\"body\":{\"datastreams\":[{\"id\":\"0\",\"current_value\":\"1\"},{\"id\":\"1\",\"current_value\":\"20.9\"},{\"id\":\"2\",\"current_value\":\"-4.9\"}]},\"token\":\"0x12345\"}");
    Serial.print(COSM_FEED); // 87672
    Serial.print("\",\"params\":{},\"headers\":{\"X-PachubeApiKey\":\"");
    Serial.print(COSM_API_KEY);
    Serial.print("\"},\"body\":{\"datastreams\":[{\"id\":\"0\",\"current_value\":\"");
    Serial.print(bottleN);  
    Serial.print("\"},{\"id\":\"1\",\"current_value\":\"");
    Serial.print(waterHeight);
    Serial.print("\"},{\"id\":\"2\",\"current_value\":\"");
    Serial.print(derivative);
    Serial.println("\"}]},\"token\":\"0x12345\"}");
	
    Serial.println("AT+NETCLOSE"); //should I not close it?
    Serial.flush();
    while(Serial.available()==0 || Serial.read()!='K');

And the rest, I moved to the begin method. So the connection is always kept and I can
send data periodicaly!

Thanks for your help!

Hi SeanHotRice,

I faced same problem for a month now and as you know there is not much support by cookinghack. could you please share the library. I'm so frustrated and disappointed by this company.

waiting for your response, thank you

Hi,

I’ve changed the code, I kept this same version I posted before.

Anyway, I ran straight into another problem described here:
http://arduino.cc/forum/index.php/topic,152368.0.html

Please tell me if it worked out for you. I’m sending data to the site every minute. Then after working a while the program blocks…

The header file:

#ifndef TCP_3G_h
#define TCP_3G_h

#include "Arduino.h"

class TCP_3G
{
	public:
		TCP_3G();
		void begin(int led, int onModulePin);
		void sendInfo(int bottleN, float waterHeight, float derivative);
		
	private:
		void switchModule();
		int _led;
		int _onModulePin;
		char data[1024];
		int x;
};

#endif

And here is the cpp:

#include "Arduino.h"
#include "TCP_3G.h"

TCP_3G::TCP_3G(){
	
}

void TCP_3G::begin(int led, int onModulePin){
	_led = led;
	_onModulePin = onModulePin;
	
	x = 0;
	
    delay(2000);
    pinMode(_led, OUTPUT);
    pinMode(_onModulePin, OUTPUT);
    
    switchModule();                    // switches the module ON
    for (int i=0;i< 5;i++){
        delay(5000);
    }
	
	char _server[] = "api.cosm.com";
	char _port[] = "8081";

							
    Serial.println(F("AT+CGSOCKCONT=1,\"IP\",\"gprs.swisscom.ch\""));
	Serial.flush();

	x=0;
    do{
        while(Serial.available()==0);
        data[x]=Serial.read();
		x++;                        
    }while(!(data[x-1]=='K'&&data[x-2]=='O'));
    
    
    // Set connection parameters
    Serial.print(F("AT+NETOPEN=\"TCP\",")); Serial.println(_port);
    Serial.flush();
    x=0;
    do {
        while(Serial.available()==0);
        data[x]=Serial.read();
		if((data[x-1]=='R') && (data[x-2]=='O') && (data[x-3]=='R') && (data[x-4]=='R')) {
			//delay(5000);
			Serial.print(F("AT+NETOPEN=\"TCP\",")); Serial.println(_port);
			Serial.flush();
		}
		//if((data[x]!='\n') && (data[x]!='\r')) Serial.print(char(data[x]));
        x++;  
    } while(!(data[x-1]=='d'&&data[x-2]=='e'));       //waits for response "Network opened"

    while(Serial.available()==0 || Serial.read()!='K');

	
    // Connect to server
    Serial.print(F("AT+TCPCONNECT=\"")); Serial.print(_server); Serial.print(F("\",")); Serial.println(_port);
    Serial.flush();
    x=0;
    do{
        while(Serial.available()==0);
        data[x]=Serial.read();
		x++;                        
    }while(!(data[x-1]=='K'&&data[x-2]=='O'));
}

void TCP_3G::switchModule(){
    digitalWrite(_onModulePin,HIGH);
    digitalWrite(_onModulePin,LOW);
    delay(2000);
}

void TCP_3G::sendInfo(int bottleN, float waterHeight, float derivative){
	
	char COSM_API_KEY[] = "MqWjogDnlf4No0_C5_OLrVGg8biSAKxuPCMALks2eXJ1az0g";
	
	char COSM_FEED[] = "12345";
	
	//Doing this for the size
	char sbottle[6];
    itoa(bottleN,sbottle, 10);
    char scm[6];
    sprintf(scm,"%.0f",waterHeight);
    char sderiv[6];
    sprintf(sderiv,"%.0f",derivative);
	
    char feedStr[] = "{\"method\":\"put\",\"resource\":\"/feeds/119610\",\"params\":{},\"headers\":{\"X-PachubeApiKey\":\"MqWjogDnlf4No0_C5_OLrVGg8biSAKxuPCMALks2eXJ1az0g\"},\"body\":{\"datastreams\":[{\"id\":\"0\",\"current_value\":\"\"},{\"id\":\"1\",\"current_value\":\"\"},{\"id\":\"2\",\"current_value\":\"\"}]},\"token\":\"0x12345\"}";

    Serial.print(F("AT+TCPWRITE=")); Serial.println(sizeof(sbottle) + sizeof(scm) + sizeof(sderiv) + sizeof(feedStr));//
    Serial.flush();
	
    while(Serial.available()==0 || Serial.read()!='>');
	/*{
		if(Serial.read() == 'R'){
			Serial.println(F("There was an error: try again"));
			delay(5000);
			Serial.print(F("AT+TCPWRITE=")); Serial.println(sizeof(sbottle) + sizeof(scm) + sizeof(sderiv) + sizeof(feedStr));//
		}
	}//*/
	
    Serial.print(F("{\"method\":\"put\",\"resource\":\"/feeds/"));//12345\",\"params\":{},\"headers\":{\"X-PachubeApiKey\":\"");
    Serial.print(COSM_FEED); // 12345 COSM_FEED --> gets altered, because of String? --> Use char[]
    Serial.print(F("\",\"params\":{},\"headers\":{\"X-PachubeApiKey\":\""));
    Serial.print(COSM_API_KEY);
    Serial.print(F("\"},\"body\":{\"datastreams\":[{\"id\":\"0\",\"current_value\":\""));
    Serial.print(bottleN);  
    Serial.print(F("\"},{\"id\":\"1\",\"current_value\":\""));
    Serial.print(waterHeight);
    Serial.print(F("\"},{\"id\":\"2\",\"current_value\":\""));
    Serial.print(derivative);
    Serial.println(F("\"}]},\"token\":\"0x12345\"}"));
	
    Serial.println(F("AT+NETCLOSE"));
    Serial.flush();
    while(Serial.available()==0 || Serial.read()!='K');

}
while(Serial.available()==0 || Serial.read()!='K');

What if the module is not sending "OK" back to you? At least include a timeout, better do an error handling.

I've already tried to do an error handling, it messes up even more... I try resending if I get ERROR but that doesn't seem to work. in this other thread, I've tried to make a timeout, even though I'm still having problems http://arduino.cc/forum/index.php/topic,155123.0.html