Hi all, I'm trying to connect SIM900 module to the my Arduino Uno. All is OK, but I'm strongly need to use software or hardware flow control. In SIM900 manual I read that it supporting XON/XOFF symbols, but I don't know how I can to use them.
For example, I have one loop(), which contain all operations including serial port reading. But execution of reading segment delayed by another segments and often I'm losing data which was sent by SIM900. And I want to allow incoming data from module only on activity of reading segment in loop(). What I need to do?
My sketch with trys to get software flow control worked, if somebody needs:
#include <SoftwareSerial.h>
#define txPin 8
#define rxPin 7
SoftwareSerial phoneSerial(rxPin, txPin);
#define pirPin 4
#define relayPin 12
String currStr = "";
unsigned long updateTime = 0;
unsigned long timeOfNextCall = 0;
unsigned char state = 0; //0 - inactive
//1 - active
//2 - alarm
unsigned char ringFlag = 0;
unsigned char smsFlag = 0;
unsigned char flagCalled = 0;
unsigned char needActive = 0;
unsigned char needInactive = 0;
void relayOn(void) {
digitalWrite(relayPin, LOW);
Serial.println("Relay turned on.");
}
void relayOff(void) {
digitalWrite(relayPin, HIGH);
Serial.println("Relay turned off.");
}
void callOwner(void) {
phoneSerial.print(char(17));
phoneSerial.println("ATD+7XXXXXXXXXX;");
phoneSerial.print(char(19));
}
void sendSMS(String string) {
/*
phoneSerial.print(char(17));
phoneSerial.print("AT+CMGF=1\r"); //text mode
delay(100);
phoneSerial.println("AT + CMGS = \"+7XXXXXXXXXX\"");
delay(100);
phoneSerial.println(string);
delay(100);
phoneSerial.println((char)26); //Ctrl+Z
phoneSerial.print(char(19));*/
Serial.print("Outgoing SMS: ");
Serial.println(string);
}
void touch() {
if (millis() >= updateTime) {
phoneSerial.print(char(17)); //XON
phoneSerial.println("AT");
if (updateTime >= 4294965000) { //near the end of unsigned long
updateTime = 4294967295;
} else {
updateTime += 5000;
}
phoneSerial.print(char(19)); //XOFF
}
}
void setup(void) {
pinMode(pirPin, INPUT);
pinMode(relayPin, OUTPUT);
relayOff();
delay(2000); //time to init phone
Serial.begin(4800);
phoneSerial.begin(4800);
phoneSerial.print("AT+CMGF=1\r\n"); //text format instead PDU
delay(300);
phoneSerial.print("AT+IFC=1, 1\r\n"); //this and all next for syncronized input of incoming SMS
delay(300);
phoneSerial.print("AT+CPBS=\"SM\"\r\n");
delay(300);
phoneSerial.print("AT+CNMI=1,2,2,1,0\r\n");
delay(500);
phoneSerial.print("AT+IPR=1,1\r\n"); //enabling software flow control
delay(300);
phoneSerial.print(char(19)); //XOFF
}
void loop(void) {
switch (state) {
case 0: { //inactive
if (needActive == 1) {
state = 1;
needActive = 0;
Serial.println("Changing state to active...");
delay(60000);
Serial.println("State is active from inactive.");
sendSMS("State is active.");
}
break;
}
case 1: { //active
if (digitalRead(pirPin) == HIGH) {
state = 2;
Serial.println("State is alarm from active.");
}
if (needInactive == 1) {
state = 0;
needInactive = 0;
Serial.println("State is inactive from active.");
sendSMS("State is inactive.");
}
break;
}
case 2: { //alarm
if (flagCalled == 1 && timeOfNextCall <= millis()) {
flagCalled = 0;
}
if (flagCalled == 0) {
callOwner();
if (timeOfNextCall >= 4294800000) {
timeOfNextCall = 4294967295;
} else {
timeOfNextCall += 300000;
}
flagCalled = 1;
}
if (needInactive == 1) {
state = 0;
needInactive = 0;
flagCalled = 0;
Serial.println("State is inactive from alarm.");
sendSMS("State is inactive, alarm stopped.");
}
break;
}
}
if (!phoneSerial.available()) return;
phoneSerial.print(char(17));
char currSymb = phoneSerial.read();
if ('\r' == currSymb) {
if (smsFlag) {
Serial.println(currStr);
if (!currStr.compareTo("1")) { //set active state
needActive = 1;
}
else if (!currStr.compareTo("2")) { //set inactive state
needInactive = 1;
}
else if (!currStr.compareTo("3")) { //set relay on
relayOn();
sendSMS("Relay open.");
}
else if (!currStr.compareTo("4")) { //set relay off
relayOff();
sendSMS("Relay close.");
}
smsFlag = 0;
}
else {
if (!currStr.compareTo("RING")) { //incoming call
ringFlag = 1;
phoneSerial.println("AT+CHUP"); //hup call
Serial.println("Recieved a RING signal.");
}
else if (currStr.startsWith("+CMT:")) { //incoming SMS
smsFlag = 1;
phoneSerial.println("AT+CMGD=1,4"); //deleting it from SIM
Serial.print("Recieved a SMS: ");
}
}
currStr = "";
} else if (currSymb != '\n') currStr += String(currSymb);
touch();
phoneSerial.print(char(19));
}