gsm.begin very slow and inhibit Arduino to keep reading inputs

Hi,
I tried a lot in the forums and on google but I can not find a solution to my problem. I want to implement a simple counting that periodically sends the data to a web server via HTTP GET.
Now the problem is that the code that handles the sending is very slow in its execution (even 30 seconds if the first attempt fails) as a result my arduino can not count the objects that pass as long as is sending the data.
Any suggestion is well accepted
Renato

Can't you use an interrupt to do the counting? With each interrupt you increase a variable that holds the counter value and you are able to transmit you read the value.

Should work.

Any suggestion is well accepted

Post your current program would be my first suggestion.

It would also help to define what you are counting.

I did not know of the existence of interrupts and I will make an attempt as suggested by Simon . You mean I have to put the piece of code that I use to count the pieces in an outer part and let into the loop the part that is used to send data to my web server ?
In every case i post the original sketch:

/*
  Web client
 
 This sketch connects to a website through a GSM shield.
 
 Circuit:
 * GSM shield attached to an Arduino
 * SIM card with a data plan
  */

// libraries
#include <GSM.h>

// PIN Number
#define PINNUMBER ""

// APN data
#define GPRS_APN       "tre.it" 
#define GPRS_LOGIN     ""    
#define GPRS_PASSWORD  "" 

// initialize the library instance
GSMClient client;
GPRS gprs;
GSM gsmAccess(true);

//initialize the costant
const int sensorPin=A0;
const int  buttonPin = 4;

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

// URL, path & port (for example: arduino.cc)
char server[] = "";
char path[] = "/InserisciTemperatura.aspx";
int port = 80; // port 80 is the default for HTTP

void setup()
{
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);  
  // initialize serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

}

void loop()
{
   Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);
  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
    } 
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off"); 
    }
  }
  // save the current state as the last state, 
  //for next time through the loop
  lastButtonState = buttonState;

  Serial.println("Starting Arduino web client.");
  // connection state
  boolean notConnected = true;

  // After starting the modem with GSM.begin()
  // attach the shield to the GPRS network with the APN, login and password
  while(notConnected)
    {
      int ok = 0;
      Serial.println("Entered to while connection cicle");
      gsmAccess.ready();
      ok = gsmAccess.getStatus();
      Serial.println(ok);
    if((gsmAccess.begin(PINNUMBER)==GSM_READY) &
      (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY))
    {  
          
      notConnected = false;
    }
    else
    {
      Serial.println("Not connected");
      delay(1000);
    }
  }

  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, port))
  {
    Serial.println("connected");
    
      } 
  else
  {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
  //Retrive the value
  int sensorVal=analogRead(sensorPin);
  Serial.print("Sensor value:");
  Serial.print(sensorVal);
  
  //convert to temperature
  float voltage=(sensorVal/1024.0)*5.0;
  Serial.print(" Volts:");
  Serial.print(voltage);
  Serial.print(", degrees C: ");
  int temperature=(voltage - 0.5)*100;
  Serial.println(temperature);
  
  // Make a HTTP request:
    client.print("GET ");
    client.print(path);
    client.print("?Temperatura=");
    client.print(temperature);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();
    Serial.println("HTTP Request sent");
   client.stop();
   gsmAccess.shutdown();
  // if the server's disconnected, stop the client:
  if (!client.available() && !client.connected())
  {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
    }
                 
}

this is an example , of course if I can achieve the result will replace the temperature measurement with that of my pieces are numbered
Thanks

I admit that I know nothing about the subject, but do you need to keep starting and stopping the connection ?

I have to count some pieces on a production line. The pieces are moving not very fast so i think that is ok if i can read input every 0.5s.
My idea was to count and send cumulative data every 5 minutes so for this reason i make the connection and disconnection. in any way i can try to maintain the connection

My idea was to count and send cumulative data every 5 minutes

But that is NOT what the code you posted is doing. That code is making a connection on EVERY pass through loop(), even when the count is the same.

You seem to be confusing getting hardware ready to make a connection and making the connection. Some of what you are doing is getting hardware ready. That belongs in setup(), so it is done ONCE. That would be the whole while(notConnected) block.

You should NOT be shutting the hardware down on every pass through loop(). (That is what gsmAccess.shutdown(); is doing). You should actually never do this.

If you are doing it to save power, you really are using the wrong hardware.

In my original code i had a delay of 30 s (that will be changed on 30 minutes whe i moved to production)that i intentionally removed previuos posting into the forum.

Now, as you suggested, I tried to move the creation of the connection in the setup leaving only the reading of inputs and sending the HTTP GET in the loop.

In serial monitor i see the HTTP GET but on my server i receive only the first one because i find only one record on my database. Why?

Now, as you suggested, I tried to move the creation of the connection in the setup leaving only the reading of inputs and sending the HTTP GET in the loop.

In serial monitor i see the HTTP GET but on my server i receive only the first one because i find only one record on my database. Why?

I changed my code. I'm not going to show you the changes. It doesn't work the way it is written. Why not?

You don't really want us to guess, do you? If you do, I'll guess that you've done something wrong in the code.

Thanks for the support.
This is the version of my code without the disconnection on every loop cycle.
In my web server i found only one record that is insert with the first HTTP GET

/*
  Web client
 
 This sketch connects to a website through a GSM shield.
 
 Circuit:
 * GSM shield attached to an Arduino
 * SIM card with a data plan
  */

// libraries
#include <GSM.h>

// PIN Number
#define PINNUMBER ""

// APN data
#define GPRS_APN       "tre.it" 
#define GPRS_LOGIN     ""    
#define GPRS_PASSWORD  "" 

// initialize the library instance
GSMClient client;
GPRS gprs;
GSM gsmAccess(true);

//initialize the costant
const int sensorPin=A0;
const int  buttonPin = 4;

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

// URL, path & port (for example: arduino.cc)
char server[] = "www.recointernet.com";
char path[] = "/InserisciTemperatura.aspx";
int port = 80; // port 80 is the default for HTTP

void setup()
{
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);  
  // initialize serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
Serial.println("Starting Arduino web client.");
  // connection state
  boolean notConnected = true;

  // After starting the modem with GSM.begin()
  // attach the shield to the GPRS network with the APN, login and password
  while(notConnected)
    {
      int ok = 0;
      Serial.println("Entered to while connection cicle");
      gsmAccess.ready();
      ok = gsmAccess.getStatus();
      Serial.println(ok);
    if((gsmAccess.begin(PINNUMBER)==GSM_READY) &
      (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY))
    {  
          
      notConnected = false;
    }
    else
    {
      Serial.println("Not connected");
      delay(1000);
    }
  }

  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, port))
  {
    Serial.println("connected");
    
      } 
  else
  {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
  
}

void loop()
{
   Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);
  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
    } 
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off"); 
    }
  }
  // save the current state as the last state, 
  //for next time through the loop
  lastButtonState = buttonState;

  //Retrive the value
  int sensorVal=analogRead(sensorPin);
  Serial.print("Sensor value:");
  Serial.print(sensorVal);
  
  //convert to temperature
  float voltage=(sensorVal/1024.0)*5.0;
  Serial.print(" Volts:");
  Serial.print(voltage);
  Serial.print(", degrees C: ");
  int temperature=(voltage - 0.5)*100;
  Serial.println(temperature);
  
  // Make a HTTP request:
    client.print("GET ");
    client.print(path);
    client.print("?Temperatura=");
    client.print(temperature);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();
    Serial.println("HTTP Request sent");
    delay(500);
   // if the server's disconnected, stop the client:
  if (!client.available() && !client.connected())
  {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
    }
                 
}
   // if the server's disconnected, stop the client:
  if (!client.available() && !client.connected())
  {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
    }

And if there is a client connected and/or there is data to read, just ignore it. How's that working for you?

Never mind, I already know that answer.

When you connect to the server, you MUST read the entire response from the server, or the connection is not closed, and you can not connect again.

Do you mean that i have to put this after the HTTP Request Post:

while (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

Do you mean that i have to put this after the HTTP Request Post:

Something like that, yes. You need a compound while statement that considers client.connected() and client.available().

I summarize the test carried out.
With this

client.print("GET ");
    client.print(path);
    client.print("?Temperatura=");
    client.print(temperature);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();
    Serial.println("HTTP Request sent");
   while (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

I could not then create a new connection to the fact that the previous connection was left pending because I did not have time to wait and read all the server's response.
This is demonstrated by the fact that adding a delay before the while ( client.avaiable () ) of at least 800 ms now can read the server's response , can properly close the connection and reopen a new one to the next round of the loop.
To speed things up I saw that it is also possible to skip the reading of the response from the server immediately making a client.stop () after the HTTP request . But this belief is not stylistically correct in that a good sketch should always check if the server responded correctly to the request made.
Now i want to try rearrange all the sketch to let loop count the pieces and call the sending data piece of code with the use of millis().
Tomorrow i will update. Goodnight

What super-duper, lightning fast connection mechanism are you using to talk to the server? What super-duper, lightning fast server are you talking to?

You are expecting a response from the server within nano-seconds after sending the request. Get real.

You need a nested while:

while(client.connected())
{
    while(client.available())
   {
       // Read the response
   }
}

This will wait for the server to disconnect, which it will do only after sending the complete response, and will wait for the entire response to arrive.

I want to share with all of you my final solution.
I want to specify that:
-The time between the control of an input and the next is in average 100 ms
-The time for the connection to send the data is in average 7 seconds (this could be a good compromise for my actual project)
-the code don't read the answer of the server to reduce the delay of reading input (it isn't an elegant solution but for now it's ok for me)
Thanks for your help

/*
  Web client 
 This sketch connects to a website through a GSM shield.
 The time between the control of an input and the next is in average 100 ms
 The time for the connection to send the data is in average 7 seconds
 IMPORTANT!!!
 You must not use the data sent from Arduino for inventories or to declare the production in to the ERP
  */
// libraries
#include <GSM.h>
// PIN Number
#define PINNUMBER ""
// APN data
#define GPRS_APN       "tre.it" 
#define GPRS_LOGIN     ""    
#define GPRS_PASSWORD  "" 
// initialize the library instance
GSMClient client;
GPRS gprs;
GSM gsmAccess(true);
//GSM gsmAccess(true);   //Use this if you want to enable debug for the connection
//initialize the costant
const int InputMod1=4;
const int InputMod2=5;
const int InputMod3 = 6;
const int InputMod4=8;
// Variables will change:
int InputMod1Counter = 0;   // counter for the number of pieces Input1
int InputMod2Counter = 0;
int InputMod3Counter = 0;
int InputMod4Counter = 0;
int InputStateMod1 = 0;         // current state of the Input
int InputStateMod2 = 0;
int InputStateMod3 = 0;
int InputStateMod4 = 0;
int lastInputStateMod1 = 0;     // previous state of the Input
int lastInputStateMod2 = 0;
int lastInputStateMod3 = 0;
int lastInputStateMod4 = 0;
unsigned long currentMillis ;
long previousMillis = 0;
long interval=30000;
// URL, path & port (for example: arduino.cc)
char server[] = "";
char path[] = "/";
int port = 80; // port 80 is the default for HTTP

void setup()
{
  // initialize pin as a input:
  pinMode(InputMod1, INPUT);
  pinMode(InputMod2, INPUT);
  pinMode(InputMod3, INPUT);
  pinMode(InputMod4, INPUT);
  // initialize serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  
Serial.println("Starting Arduino web client.");
  // connection state
  boolean notConnected = true;

  // After starting the modem with GSM.begin()
  // attach the shield to the GPRS network with the APN, login and password
  while(notConnected)
    {      if((gsmAccess.begin(PINNUMBER)==GSM_READY) &
      (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY))
    {    
      Serial.println("GSM_READY and GPRS_READY");
      notConnected = false;
    }
    else
    {
      Serial.println("Not connected");
      delay(1000);
    }
  }
}

void loop()
{
  Serial.print("Millis time:");
  Serial.println(millis());
  Serial.print("number of Pieces Mod1:  ");
   Serial.println(InputMod1Counter);
   Serial.print("number of Pieces Mod2:  ");
   Serial.println(InputMod2Counter);
   Serial.print("number of Pieces Mod3:  ");
   Serial.println(InputMod3Counter);
   Serial.print("number of Pieces Mod4:  ");
   Serial.println(InputMod4Counter);
  // read the input pin:
  InputStateMod1 = digitalRead(InputMod1);
  InputStateMod2 = digitalRead(InputMod2);
  InputStateMod3 = digitalRead(InputMod3);
  InputStateMod4 = digitalRead(InputMod4);
    // compare the InputState to its previous state
  if (InputStateMod1 != lastInputStateMod1) {
    // if the state has changed, increment the counter
    if (InputStateMod1 == HIGH) {
      // if the current state is HIGH then the input
      // wend from off to on:
      InputMod1Counter++;
      Serial.println("on");
      Serial.print("number of pieces:  ");
      Serial.println(InputMod1Counter);
    } 
    else {
      // if the current state is LOW then the input
      // wend from on to off:
      Serial.println("off"); 
    }
  }
    // compare the InputState to its previous state
  if (InputStateMod2 != lastInputStateMod2) {
    // if the state has changed, increment the counter
    if (InputStateMod2 == HIGH) {
      // if the current state is HIGH then the input
      // wend from off to on:
      InputMod2Counter++;
      Serial.println("on");
      Serial.print("number of pieces:  ");
      Serial.println(InputMod2Counter);
    } 
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off"); 
    }
  }
    // compare the InputState to its previous state
  if (InputStateMod3 != lastInputStateMod3) {
    // if the state has changed, increment the counter
    if (InputStateMod3 == HIGH) {
      // if the current state is HIGH then the input
      // wend from off to on:
      InputMod3Counter++;
      Serial.println("on");
      Serial.print("number of pieces:  ");
      Serial.println(InputMod3Counter);
    } 
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off"); 
    }
  }
    // compare the InputState to its previous state
  if (InputStateMod4 != lastInputStateMod4) {
    // if the state has changed, increment the counter
    if (InputStateMod4 == HIGH) {
      // if the current state is HIGH then the input
      // wend from off to on:
      InputMod4Counter++;
      Serial.println("on");
      Serial.print("number of pieces:  ");
      Serial.println(InputMod4Counter);
    } 
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off"); 
    }
  }
  // save the current state as the last state, 
  //for next time through the loop
  lastInputStateMod1 = InputStateMod1;
  lastInputStateMod2 = InputStateMod2;
  lastInputStateMod3 = InputStateMod3;
  lastInputStateMod4 = InputStateMod4;
  
 currentMillis = millis();
 if(currentMillis - previousMillis > interval)
 {
   previousMillis = currentMillis;
   Serial.print("Time begin connection:");
   Serial.println(millis());
 Serial.print("Status of connection");
 Serial.println(client.connected());
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, port))
  {
    Serial.println("connected");
  } 
  else
  {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
 
  
  // Make a HTTP request:
    client.print("GET ");
    client.print(path);
    client.print("?Modulo1=");
    client.print(InputMod1Counter);
    client.print("&Modulo2=");
    client.print(InputMod2Counter);
    client.print("&Modulo3=");
    client.print(InputMod3Counter);
    client.print("&Modulo4=");
    client.print(InputMod4Counter);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();
    Serial.println("HTTP Request sent");
   Serial.println("Start waiting for data");
   client.stop();
   Serial.println("Stop waiting for data");
    while (client.available()) {
    char c = client.read();
    Serial.print(c);
  }
  
    // if the server's disconnected, stop the client:
  
  if (!client.available() && !client.connected())
  {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
    }
    Serial.print("Time end of connection:");
    Serial.println(millis());
}    
}