Modulo GSM y sensor magnético para puertas SMS

Hola a todos agradecería que me pudieran ayudar con el siguiente proyecto: consiste en enviar un sms automaticamente cuando una puerta se abra y cuando se cierre, hasta el momento lo logré mas o menos, el problema que tengo es que necesito que se envie solo un sms unicamente, hasta ahora se envian varios mientras la puerta permanezca abierta, agraceria bastante su ayuda.

Adjunto el código, gracias.

include <SoftwareSerial.h>
SoftwareSerial SIM900(10, 11); // Configura el puerto serial para el SIM900

char incoming_char = 0; //Variable que guarda los caracteres que envia el SIM900
int salir = 0;
const int switchPin = 2; //Pin de el sensor magnético
const int ledPin = 8;    //Pin para encender led

void setup() {

  SIM900.begin(19200); //Configura velocidad serial para el SIM900
  delay(5000);  //Retardo para que encuentra a una RED
  Serial.begin(19200); //Configura velocidad serial para el Arduino
  Serial.println("OK"); //Mensaje OK en el arduino, para saber que todo va bien.

  pinMode (switchPin, INPUT); //Se establece el pin del sensor como entrada

  pinMode (ledPin, OUTPUT); //Se establece el pin de led como salida.

  digitalWrite (switchPin, HIGH);// Se establece el pin digital en alto el pin del sensor

}

void loop() {   //Cliclo repetitivo


  if (digitalRead(switchPin) == LOW ) { // Condición si el sensor se encuentra cerrado(LOW) se ejecuta accion
    digitalWrite (ledPin, LOW); // Led permanece apagado


  } else { //Condición si el sensor se encuentra abierto(HIGH)
    digitalWrite (ledPin, LOW); // Led se enciende
    mensaje_sms();
  }

}



void llamar()
// Función que permite llamar a un celular local
{
  // SIM900.println("ATD 10725275;"); //Numero
  SIM900.println("ATD 78305229;"); //Celular
  //delay(100);
  SIM900.println();
  delay(5000); // Espera 30 segundos.
  SIM900.println("ATH"); // Cuelga el telefono
  //delay(1000);
}


void mensaje_sms()
//Funcion para mandar mensaje de texto
{

  SIM900.print("AT+CMGF=1\r"); // Comando AT para enviar mensaje
  delay(100);
  SIM900.println("AT + CMGS = \"51109746\""); // Numero al que se le va enviar SMS
  delay(100);
  SIM900.println("ALERTA: Ingreso a Sitio:Ch1  ID:2014"); // Mensaje que vamos a enviar
  delay(100);
  SIM900.println((char)26); // Comando AT para finalizar con ^Z, ASCII code 26 //Comando de finalizacion
  delay(100);
  SIM900.println();
  delay(1000); // Tiempo para que se envie el mensaje
  Serial.println("SMS enviado satisfactoriamente");


}

proyecto_final.ino (2.04 KB)

Hola @steven10mb, bienvenido al foro Arduino en Español.
Te invito a que leas las normas del foro, (1er hilo de cualquier sección) y edites tu post inicial para que el código se visualice no como texto simple (copiar y pegar) sino con la etiqueta de código que se explica en las normas.

Cuando veamos el código, será mas fácil que la comunidad te ayude.

Gracias.

Excelente muchas gracias, ya lo edité agradecería su ayuda.

Tu código sólo tiene un problema y es que siempre estas enviando, cuando la puerta esté abierta.

Necesitas una variable de control que te indique si está enviado a no. Y aunque la puerta esté abierta no lo vuelva a enviar.

bool enviado = false;

void loop() {   //Cliclo repetitivo

  // Si al leer el sensor esté está a LOW (puerta cerrada) ponemos enviado 
  // a false. tampien ponemos el pin del led apagado.
  if (digitalRead(switchPin) == LOW ) { 
    digitalWrite (ledPin, LOW); 
    enviado=false;
  } 
  else { 
    // Se ha abierto la puerta. Encendemos el led.
    digitalWrite (ledPin, LOW); // Led se enciende
    // Si enviado es falso, significa que tenemos que mandar el mensaje
    // así que lo enviamos y lo ponemos a cierto.
    if ( enviado==false ) {
      mensaje_sms();
      enviado=true; 
      // A partir de aquí aunque la puerta siga abierta ya ha sido enviado
      // por lo que hasta que no se cierre y vuelva a abrir no se volverá
      // a enviar.
  }
}

Aún así te recomiendo que uses alguna rutina de "debounce" para el interruptor ya que esté en el proceso de apertura o cierre, rebotará con lo que te enviará algún mensaje más.

NOTA: has hecho doble posteo, con lo que posiblemente el moderador te va a cerrar algún hilo. Supongo el de la sección de hardware.

Tu problema esta en esta parte del código

  if (digitalRead(switchPin) == LOW ) { // Condición si el sensor se encuentra cerrado(LOW) se ejecuta accion
      digitalWrite (ledPin, LOW); // Led permanece apagado
  } else { //Condición si el sensor se encuentra abierto(HIGH)
     digitalWrite (ledPin, LOW); // Led se enciende
      mensaje_sms();
  }

Tu cada vez que ves el switchPin en 1 envias mensaje, y lo que debes hacer es mirar el flanco, cuando pasa de 0 a 1.
Define antes esto

bool estado, estadoAnt = false;

en el loop reemplaza lo anterior por:

   estado = digitalRead(switchPin);
   if ( estado && !estadoAnt) { // Si pasamos de 0 a 1
       digitalWrite (ledPin, HIGH); // Led se enciende
       mensaje_sms();
       // solo ocurrirá una vez
  }
   if ( !estado && estadoAnt) { // Si pasamos de 1 a 0
        digitalWrite (ledPin, LOW); // Led permanece apagado
   }
   estadoAnt = estado;

Acabo de darme cuenta que había dos hilos con el mismo tema. Por favor lee las normas y no doble postees, es solo una perdida de tiempo para los miembros de la comunidad.
He juntado ambos hilos en 1, asi que se cruzan las respuestas de algunos que obviamente serán similares.