Código para realizar una llamada desde un gprs

Buenas a todos, estoy tratando de realizar un proyecto el cual requiero hacer una llamada desde un gprs, esto se hace después que se oprime un pulsador marca a un numero determinado… en lo que me gustaría que me ayudaran es poder cortar la llamada con e mismo pulsador cuando este en la llamada.

#include <SoftwareSerial.h>
SoftwareSerial SIM900(7, 8);

int pulsador = 12; 
int val=0;

void setup(){

pinMode(pulsador, INPUT_PULLUP);  //entrada con pull-up --> conectar pulsador N/A a GND en este pin.
digitalWrite(9, HIGH); // Descomentar para activar la alimentación de la tarjeta por Software
delay(1000); 
digitalWrite(9, LOW);
delay (5000);  //Nos damos un tiempo para encender el GPRS y la alimentación de la tarjeta
SIM900.begin(19200);  //Configura velocidad del puerto serie para el SIM900
Serial.begin(19200);  //Configura velocidad del puerto serie del Arduino
Serial.println("OK");
delay (1000);


}

void loop() 
 {
while(1){
val = digitalRead(pulsador);//leer continuamente el pulsador. Siempre esta an HIGH (por la pull-up) y pasa a LOW al presionarlo.
if(val==LOW){llamar();}      //al presionar el boton, llamar a un numero.
        }
 }

void llamar()
  {
    Serial.println("Realizando llamada...");
    SIM900.println("ATD31xxxxxxxx;");  //Comando AT para realizar una llamada
    delay(120000);  // Espera 30 segundos mientras realiza la llamada
    SIM900.println("ATH");  // Cuelga la llamada
    delay(1000);
    Serial.println("Llamada finalizada");
  }

Hola tecnico_dos, primero mira el mensaje privado y edita tu post usando la etiqueta que corresponde.

Luego hay un detalle de mas en esto

void loop() 
  {
 while(1){
 val = digitalRead(pulsador);//leer continuamente el pulsador. Siempre esta an HIGH (por la pull-up) y pasa a LOW al presionarlo.
 if(val==LOW){llamar();}      //al presionar el boton, llamar a un numero.
         }
  }

loop en realidad es un while(1) asi que no hace falta poner otro while(1).
Con esto suficiente

void loop() 
{

 val = digitalRead(pulsador);//leer continuamente el pulsador. Siempre esta an HIGH (por la pull-up) y pasa a LOW al presionarlo.
 if (val==LOW){
     llamar();
 }      //al presionar el boton, llamar a un numero.
         }
  }

Ahora lo que quieres es que el mismo botón haga las dos cosas
Entonces crea una variable bool tal que cada pulsación del boton cambie el estado de la variable y entonces una pulsación llama y otra corta y la siguiente repite y asi.

#include <SoftwareSerial.h>
SoftwareSerial SIM900(7, 8);

int pulsador = 12; 
bool val = false, valAnt = false;
bool estado = false;

void setup(){
  pinMode(pulsador, INPUT_PULLUP);  //entrada con pull-up --> conectar pulsador N/A a GND en este pin.
  digitalWrite(9, HIGH); // Descomentar para activar la alimentación de la tarjeta por Software
  delay(1000); 
  digitalWrite(9, LOW);
  delay (5000);  //Nos damos un tiempo para encender el GPRS y la alimentación de la tarjeta
  SIM900.begin(19200);  //Configura velocidad del puerto serie para el SIM900
  Serial.begin(19200);  //Configura velocidad del puerto serie del Arduino
  Serial.println("OK");
  delay (1000);
}

void loop() 
{
  val = digitalRead(pulsador);//leer continuamente el pulsador. Siempre esta an HIGH (por la pull-up) y pasa a LOW al presionarlo.
  if (val==LOW && valAnt == HIGH) {
       estado = !estado;
  }
  valAnt = val;

  if (estado)    
      llamar();      //al presionar el boton, llamar a un numero.
  else 
      colgar();

}

void llamar()    {
  Serial.println("Realizando llamada...");
  SIM900.println("ATD31xxxxxxxx;");  //Comando AT para realizar una llamada
  delay(120000);  // Espera 30 segundos mientras realiza la llamada
}

void colgar() {
  // implementa colgar
  SIM900.println("ATH");  // Cuelga la llamada
  delay(1000);
  Serial.println("Llamada finalizada");
}

Buenas tardes, surbaty muchas gracias por responder, he aplicado los cambios que me has indicado pero cada vez que corre la funcion en el arduino y se verifica por el monitor serial se observa que este lo que hace es finalizar la llamada de inmediato.

Si la llamada finaliza de inmediato entoces tu rutina llamar() esta mal. Yo no hice mas que tomar tu rutina llamar y colgar.

cuando presionas, cambias el estado, y será o una cosa o la otra. Llamar dice

void llamar()    {
  Serial.println("Realizando llamada...");
  SIM900.println("ATD31xxxxxxxx;");  //Comando AT para realizar una llamada
  delay(120000);  // Espera 30 segundos mientras realiza la llamada
}

No tiene error aparente.

Si el pulsador esta bien no debería cambiar nada ademas no puede devolver el control hasta que se supere ese tremendo delay(120000)

Asi que el problema debe estar en otro sitio.

Cuando accionas el monitor serie? Si lo haces una vez iniciada la llamada es lógico que te apague todo. Porque resetea el arduino. Asi que prueba todo desde el arranque con monitor serie activo.

Buenas noches; la función de llamar no tiene problema ya que esta con el código inicial realiza perfectamente la llamada y el delay de 120000 que le coloque es para que me diera tiempo determinado la llamada, el tema es que al realizar el código como me siguieres siempre se salta de una a la opción de colgar sin nunca iniciar la función llamar.

Creo, surbyte, que debes meter el "if (estado)" dentro del "if (val==LOW && valAnt == HIGH)", para que sólo se produzca la llamada a la función si hay pulsación.