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);
}
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.
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);
}
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.