Problem sending message via arduino trigger

Hi guys. I am currently making a project of a remote sensor that has a transmitter that sends characters of various lengths to signify different conditions and I'm using those character lengths (buflen) to tell the arduino to trigger the relay and send an sms. The trigger part was easy but once I added the syntax for sending message to the if statements, my code got stuck, I think, since the serial monitor stopped showing the next strings of data. Below is my code and I commented the area where I think the problem lies. Up to now I'm still trying a lot of stuff but as a beginner I would like to ask you guys for help. Thanks in advance. Sorry for my bad english

#include <VirtualWire.h>
#include <SoftwareSerial.h>
SoftwareSerial SIM900(7, 8);
const byte rxpin = 19; //Data pin
const byte rxenable = 52; //DIO pin 7 for Rx Enable
const byte ledpin = 13;
unsigned int spattern = 0x6810; //BR_Range2
unsigned int lpattern = 0x2FD8; // bit check limit for 4500-5100 bps
byte bitctr = 14;
void setup()
{
  SIM900.begin(19200);
  delay(20000);
  pinMode(rxenable, OUTPUT); // EGRF-433A1 DIO for ENable pin
  ATA3741(); // setup Rx module ATA3741 chip
  // UART is used for this demo to allow visual display
  // of Rxed data via Arduino IDE Tools>Serial Monitor
  // Otherwise, it is freely available for other purpose
  Serial.begin(9600);
  // Apply VitualWire settings
  vw_setup(4800); // Bits per sec
  vw_set_rx_pin(rxpin);
  vw_rx_start(); // Start the receiver PLL running
  pinMode(ledpin, OUTPUT); // LED

}
  void sendSMS()
  {
    SIM900.print("AT+CMGF=1\r");                                // AT command to SMS mode to text
    delay(100);
    SIM900.println("AT + CMGS = \"+6************\"");            // my number
    delay(100);
    SIM900.println("warning!.");        // Message to send
    delay(100);
    SIM900.println((char)26);                                   // End AT command with a ^Z, ASCII code 26
    delay(100);
    SIM900.println();
    delay(5000);                                                // give module time to send SMS
  }

void loop()
{
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  int i;

  if (vw_get_message(buf, &buflen))
  {


    for (i = 0; i < buflen; i++)
    {
      Serial.print((char)buf[i]);
    }

    Serial.println("");
    digitalWrite(rxenable, LOW); // Reset EGRF-433A1-R
    digitalWrite(13, LOW); // Flash OFF LED indicator
    digitalWrite(rxenable, HIGH); //Re enable to receive next data packet

    if (buflen == 6)
    {
      digitalWrite (40, HIGH);                                              
      sendSMS();                          //This and below                                  
      do {} while (1);                       //is the instruction for sending sms. I think this is where the problem is but I can't solve it atm. I can't find another syntax for this
   
    }
    else
    {
      digitalWrite (40, LOW);
    }

    if (buflen == 5)
    {
      digitalWrite (42, HIGH);
      sendSMS();                     //This and below                            
      do {} while (1);                  //is the code for sending sms. I think this is where the problem is but I can't solve it atm
    }
    else
    {
      digitalWrite (42, LOW);
    }

    if (buflen == 4)
    {
      digitalWrite (44, HIGH);
      sendSMS();                                             
      do {} while (1);      


    }
    else
    {
      digitalWrite (44, LOW);
    }

    if (buflen == 3)
    {
      digitalWrite (41, HIGH);

    }
    else
    {
      digitalWrite (41, LOW);
    }

    if (buflen == 2)
    {
      digitalWrite (43, HIGH);
      

    }
    else
    {
      digitalWrite (43, LOW);
    }

    if (buflen == 1)
    {
      digitalWrite (45, HIGH);
      do {} while (1);
    }
    else
    {
      digitalWrite (45, LOW);
    }


  }
}
void ATA3741(void)
{
  digitalWrite(rxenable, HIGH);

  // forcing DATA pin low for 15ms
  pinMode(rxpin, OUTPUT); // Change DATA pin direction to OUTPUT
  digitalWrite(rxpin, LOW);
  delayMicroseconds(15000);
  digitalWrite(rxpin, HIGH);
  pinMode(rxpin, INPUT);
  digitalWrite(rxpin, LOW);
  // wait for t2
  bitctr = 14;
  // send 14 bits ini
  while (bitctr > 0) {
    while (digitalRead(rxpin) == HIGH);
    if ((spattern & 0x8000) == 0)
      ATA3741_LO();
    else
      ATA3741_HI();
    bitctr--;
    spattern = spattern << 1;
  }
  delayMicroseconds(15000);
  pinMode(rxpin, OUTPUT);
  digitalWrite(rxpin, LOW);
  delayMicroseconds(1000);
  digitalWrite(rxpin, HIGH);
  pinMode(rxpin, INPUT);
  digitalWrite(rxpin, LOW);
  // Enter 14-bit bit check limits pattern
  bitctr = 14;
  while (bitctr > 0) {
    while (digitalRead(rxpin) == HIGH);
    if ((lpattern & 0x8000) == 0)
      ATA3741_LO();
    else
      ATA3741_HI();
    bitctr--;
    lpattern = lpattern << 1;
  }
}
// Output a logic low
void ATA3741_LO(void) {
  // wait until rxpin goes hi
  while (digitalRead(rxpin) == LOW);
  delayMicroseconds(131);
  pinMode(rxpin, OUTPUT); // output a low
  delayMicroseconds(150); // for 150uS
  pinMode(rxpin, INPUT);
  delayMicroseconds(50);
}
// Output a logic high
void ATA3741_HI(void) {
  // Since rxpin should be normally at logic high
  // just wait if necessary until rxpin goes high
  while (digitalRead(rxpin) == LOW);
}
do {} while (1);

This will loop forever and therefore stop the program at this point.

Did you copy the program from somewhere with these statements in it?

Yes, most of it. The do {} while (1); is included in the datasheet sample program:
Here it is:

#include <SoftwareSerial.h>
SoftwareSerial SIM900(7, 8);
 
void setup()
{
  SIM900.begin(19200);
  delay(20000);    // give time to manually power ON the GSM Shield and connect to the network
}
  
void sendSMS()
{
  SIM900.print("AT+CMGF=1\r");                                // AT command to SMS mode to text
  delay(100);
  SIM900.println("AT + CMGS = \"+6*********\"");            // Change this to your desired recipient mobile number. (international format)
  delay(100);
  SIM900.println("Hello! World. Success! This is a text message from an Arduino Uno.");        // Message to send
  delay(100);
  SIM900.println((char)26);                                   // End AT command with a ^Z, ASCII code 26
  delay(100); 
  SIM900.println();
  delay(5000);                                                // give module time to send SMS
}

void loop()
{
  sendSMS();                                                  // Call this function to start sending the message
  do {} while (1);
}

So I copied the functions in the setup and void loop to my main program which I posted above. I tried deleting the do while loop too but it didn't fix the problem unfortunately

Ok, they wrote it that way so that the test program would only send one SMS message and then stop. The loop() function repeats forever, so would otherwise send a constant stream of messages :).

(They could have done the same thing by putting sendSMS() at the end of setup() function and leaving loop() empty, because setup() is run once when the program starts).

In your program, start by removing all the do {} while (1); statements and see what happens.

Oh I see. Thanks for the info.
You said:
"(They could have done the same thing by putting sendSMS() at the end of setup() function and leaving loop() empty, because setup() is run once when the program starts)."

How do I write it? I can't write sendSMS() inside the sendSMS() function. Is that correct?

I removed all and I'm receiving some stream of sms. How can I send an SMS once per trigger without getting stuck? Thanks for your patience.

I removed all and I'm receiving some stream of sms.

So you know the sendSMS() function works OK, and the problem is in when it is being called.

For testing, try replacing each call to sendSMS() with Serial.println("Send SMS");.

You already have code in the program to print the message received over virtual wire. Add some more print statements to it like this:

  if (vw_get_message(buf, &buflen))
  {
    Serial.print("Buffer: ");
    for (i = 0; i < buflen; i++)
    {
      Serial.print((char)buf[i]);
    }
    Serial.println("");
    Serial.print("Buffer length: ");
    Serial.println(buflen);

What do you see on serial monitor when you run the program? You could copy and paste some of the output into a post so we can see it.

And please post your updated program.

here's the code with serial print and I attached the screen shot of the serial monitor.
It's working fine with Serial.println.

#include <VirtualWire.h>
#include <SoftwareSerial.h>
SoftwareSerial SIM900(7, 8);
const byte rxpin = 19; // DIO pin 2 for Rx
const byte rxenable = 52; //DIO pin 7 for Rx Enable
const byte ledpin = 13; // Built in LED
unsigned int spattern = 0x6810; //BR_Range2
unsigned int lpattern = 0x2FD8; // bit check limit for 4500-5100 bps
byte bitctr = 14;
void setup()
{
  SIM900.begin(19200);
  pinMode(rxenable, OUTPUT); // EGRF-433A1 DIO for ENable pin
  ATA3741(); // setup Rx module ATA3741 chip
  // UART is used for this demo to allow visual display
  // of Rxed data via Arduino IDE Tools>Serial Monitor
  // Otherwise, it is freely available for other purpose
  Serial.begin(9600);
  // Apply VitualWire settings
  vw_setup(4800); // Bits per sec
  vw_set_rx_pin(rxpin);
  vw_rx_start(); // Start the receiver PLL running
  pinMode(ledpin, OUTPUT); // LED

}
  void sendSMS()
  {
    SIM900.print("AT+CMGF=1\r");                                // AT command to SMS mode to text
    delay(100);
    SIM900.println("AT + CMGS = \"+639486316820\"");            // Change this to your desired recipient mobile number. (international format)
    delay(100);
    SIM900.println("Hello! World. Success! This is a text message from an Arduino Uno.");        // Message to send
    delay(100);
    SIM900.println((char)26);                                   // End AT command with a ^Z, ASCII code 26
    delay(100);
    SIM900.println();
    delay(5000);                                                // give module time to send SMS
  }

void loop()
{
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  int i;

  if (vw_get_message(buf, &buflen))
  {


    for (i = 0; i < buflen; i++)
    {
      Serial.print((char)buf[i]);
    }

    Serial.println("");
    digitalWrite(rxenable, LOW); // Reset EGRF-433A1-R
    digitalWrite(13, LOW); // Flash OFF LED indicator
    digitalWrite(rxenable, HIGH); //Re enable to receive next data packet

    if (buflen == 6)
    {
      digitalWrite (40, HIGH);                                              
        Serial.println("Send SMS");                                 
      
   
    }
    else
    {
      digitalWrite (40, LOW);
    }

    if (buflen == 5)
    {
      digitalWrite (42, HIGH);
      Serial.println("Send SMS1");                           
    
    }
    else
    {
      digitalWrite (42, LOW);
    }

    if (buflen == 4)
    {
      digitalWrite (44, HIGH);
   
    


    }
    else
    {
      digitalWrite (44, LOW);
    }

    if (buflen == 3)
    {
      digitalWrite (41, HIGH);

    }
    else
    {
      digitalWrite (41, LOW);
    }

    if (buflen == 2)
    {
      digitalWrite (43, HIGH);
      

    }
    else
    {
      digitalWrite (43, LOW);
    }

    if (buflen == 1)
    {
      digitalWrite (45, HIGH);
      do {} while (1);
    }
    else
    {
      digitalWrite (45, LOW);
    }


  }
}
void ATA3741(void)
{
  digitalWrite(rxenable, HIGH);

  // forcing DATA pin low for 15ms
  pinMode(rxpin, OUTPUT); // Change DATA pin direction to OUTPUT
  digitalWrite(rxpin, LOW);
  delayMicroseconds(15000);
  digitalWrite(rxpin, HIGH);
  pinMode(rxpin, INPUT);
  digitalWrite(rxpin, LOW);
  // wait for t2
  bitctr = 14;
  // send 14 bits ini
  while (bitctr > 0) {
    while (digitalRead(rxpin) == HIGH);
    if ((spattern & 0x8000) == 0)
      ATA3741_LO();
    else
      ATA3741_HI();
    bitctr--;
    spattern = spattern << 1;
  }
  delayMicroseconds(15000);
  pinMode(rxpin, OUTPUT);
  digitalWrite(rxpin, LOW);
  delayMicroseconds(1000);
  digitalWrite(rxpin, HIGH);
  pinMode(rxpin, INPUT);
  digitalWrite(rxpin, LOW);
  // Enter 14-bit bit check limits pattern
  bitctr = 14;
  while (bitctr > 0) {
    while (digitalRead(rxpin) == HIGH);
    if ((lpattern & 0x8000) == 0)
      ATA3741_LO();
    else
      ATA3741_HI();
    bitctr--;
    lpattern = lpattern << 1;
  }
}
// Output a logic low
void ATA3741_LO(void) {
  // wait until rxpin goes hi
  while (digitalRead(rxpin) == LOW);
  delayMicroseconds(131);
  pinMode(rxpin, OUTPUT); // output a low
  delayMicroseconds(150); // for 150uS
  pinMode(rxpin, INPUT);
  delayMicroseconds(50);
}
// Output a logic high
void ATA3741_HI(void) {
  // Since rxpin should be normally at logic high
  // just wait if necessary until rxpin goes high
  while (digitalRead(rxpin) == LOW);
}

Can you give me a tip on how to send the message once every trigger? Thanks a lot. I've learned so much from this

Where you have each "send SMS" print statement, put back in sendSMS().

This should send one SMS each time you get the trigger.

For example:

if (buflen == 6)
{
    digitalWrite (40, HIGH);                                              
    Serial.println("Before call to sendSMS");                                 
    sendSMS();  // This function has delays built in, so will take a few seconds to complete
    Serial.println("After call to sendSMS");
}
else
{
     digitalWrite (40, LOW);
}

Thanks for the tip! Is it ok if I put a long delay, like (10000)? Will the program bypass the delay if another 'if' statement is met?

thecoffeetoy:
Thanks for the tip! Is it ok if I put a long delay, like (10000)? Will the program bypass the delay if another 'if' statement is met?

If you put a delay statement in each of the if statements, they will only happen if that specific if statement is executed. So long as the if statements are each looking for a different buffer length, then you will get maximum of one delay before you go back round loop() and check for the next virtual wire message.

Remember, while each of these delays is happening (the ones in sendSMS and any you add), nothing else will happen in the program. I have not used the virtual wire library, but there might be an issue if lots of trigger messages are being sent to the Arduino.

Oh I see. I've got more information to work with now. Thanks a lot!