#include "flprogUtilites.h"
#include <SoftwareSerial.h>
#define Module_Start "Call Ready"
SoftwareSerial Serial_S(11 , 10);
bool GSM_Outgoing_Call;
bool GSM_Take_Call;
bool GSM_Connect;
#define GSM_INCLUSION_CALLS
bool GSM_In_sms;
String GSM_Phone;
String GSM_text;
bool GSM_Reject_call;
bool GSM_start;
bool GSM_Net;
int GSM_dBm;
bool GSM_Received_SMS;
String GSM_Text_sms;
String GSM_T_Nomer;
bool GSM_Sent_SMS;
bool GSM_Call;
int GSM_Number_calls;
int GSM_Error_Code;
bool GSM_start_N; //Модем прислал сообщение о том, что он стартовал
bool GSM_final; // закончена обработка запроса
bool GSM_wait; // идет ожидание ответа на команду
bool GSM_past_SMS;
bool GSM_command_SMS;
bool GSM_past_Reject_call;
bool GSM_command_Reject_call;
//bool GSM_Call_P1;
char GSM_ch;
//символ пришетший в ком порт
byte GSM_errorCounter; // счетчик ошибок
byte GSM_numberRepeats;
//byte GSM_Dial_response_code;
byte GSM_team_room; //номер текущей функции
byte GSM_count; // счетчик последовальности команд
unsigned long GSM_time; //Время посылки команды
unsigned long GSM_T_millis; //Время посылки команды
unsigned long GSM_time_n; //Время последнего опроса связи с сетью.
String GSM_line; // сообщение от модуля
String GSM_reply; //Ответ модуля на команду
String GSM_Phone_T=""; //Телефон во время подачи команд на звонок или отправку смс
int GSM_DTMF;
#define GSM_INCLUSION_DTMF
int _gtv1;
bool _gtv2;
bool _gtv3;
bool _trgt2 = 0;
bool _trgt2I = 0;
bool _trgrt4 = 0;
bool _trgrt4I = 0;
bool _trgrt2 = 0;
bool _trgrt2I = 0;
bool _tim2I = 0;
bool _tim2O = 0;
unsigned long _tim2P = 0UL;
bool _trgrt1 = 0;
bool _trgrt1I = 0;
bool _tim3I = 0;
bool _tim3O = 0;
unsigned long _tim3P = 0UL;
bool _bounseInputD6S = 0;
bool _bounseInputD6O = 0;
unsigned long _bounseInputD6P = 0UL;
bool _tim4I = 0;
bool _tim4O = 0;
unsigned long _tim4P = 0UL;
void setup()
{
pinMode(6, INPUT_PULLUP);
pinMode(2, OUTPUT);
digitalWrite(2, 0);
pinMode(3, OUTPUT);
digitalWrite(3, 0);
pinMode(13, OUTPUT);
digitalWrite(13, 0);
pinMode(7, OUTPUT);
digitalWrite(7, 0);
_bounseInputD6O = digitalRead(6);
Serial_S.begin(9600);
}
void loop()
{
bool _bounceInputTmpD6 = (digitalRead (6));
if (_bounseInputD6S)
{
if (millis() >= (_bounseInputD6P + 40))
{
_bounseInputD6O= _bounceInputTmpD6;
_bounseInputD6S=0;
}
}
else
{
if (_bounceInputTmpD6 != _bounseInputD6O)
{
_bounseInputD6S=1;
_bounseInputD6P = millis();
}
}
//Плата:1
_gtv1 = GSM_DTMF;
if (_gtv3)
{
if (_trgrt4I)
{
_trgrt4 = 0;
}
else
{
_trgrt4 = 1;
_trgrt4I = 1;
}
}
else
{
_trgrt4 = 0;
_trgrt4I = 0;
}
;
GSM_In_sms = 0;
GSM_Phone = String("");
GSM_text = String("");
GSM_Reject_call = _trgrt4;
GSM_Received_SMS =0; //Сброс статутса СМС Принята
GSM_Sent_SMS =0; //Сброс статуса СМС Отправлена
if (1)
{
if (GSM_team_room==3)
{
GSM_Number_calls =0;
GSM_Text_sms="";
GSM_T_Nomer ="";
}
}
GSM_T_millis =millis();
while(Serial_S.available()) //Получаем данные с модема
{
GSM_ch = Serial_S.read();
if(GSM_ch == '\r') continue;
if(GSM_ch == '\n')
{
GSM_GotLineFromNeoway();
GSM_line ="";
}
else GSM_line += GSM_ch;
}
if (GSM_wait) //ожиание ответа на команду
{
if(GSM_line.length()>0)
{
if(GSM_line==F("> "))
{
GSM_count++;
GSM_wait=0;
GSM_line ="";
}
}
if(GSM_T_millis>GSM_time)
{
GSM_err (2,0);
}
}
if (GSM_Call&&(GSM_team_room!=1))
{
GSM_team_room=1;
GSM_Number_calls=1; //сброс числа гудков
// GSM_resetExpectations() ;
}
if (GSM_start_N)
{
if (!GSM_wait)
{
if (GSM_setup_comand())
{
GSM_start_N=0;
GSM_start =1;
}
}
}
// Инициализация
if (GSM_start) //Не работать пока не старт
{
//______Проверка статуса сети
if ((30000 >0)&&(GSM_team_room==0)) //проверять ли статутс сети
{
if((GSM_T_millis-GSM_time_n) > 30000)
{
GSM_team_room=3;
}
}
//______Конец Проверка статуса сети
//______Отправка СМС
if (GSM_In_sms && !GSM_past_SMS)
{
if (GSM_number_search())GSM_command_SMS =1;
}
// поступление команды на отправу СМС. Проверка корректности номера
GSM_past_SMS= GSM_In_sms;
if (GSM_command_SMS && (GSM_team_room==0))
{
GSM_team_room=2;
GSM_command_SMS =0;
}
// начинать отправу СМС
//______Конец Отправка СМС
//______Команда сброс вызова или разрыв разговора
if (GSM_Reject_call && !GSM_past_Reject_call)
{
GSM_command_Reject_call =1;
}
GSM_past_Reject_call=GSM_Reject_call;
//______Конец Команда сброс вызова или разрыв разговора
#ifdef GSM_INCLUSION_USSD // Обработка вызова USSD запросов
GSM_causeProcessingUSSD();
#endif
#ifdef GSM_INCLUSION_DATA_TIME //Обработка времени, даты, оператора
GSM_causeProcessingDataTime();
#endif
#ifdef GSM_INCLUSION_CALLS // исходящий вызов
if (GSM_causeProcessingCall())
{
if(GSM_number_search())
{
GSM_wait=1; // ожитать
GSM_time =millis() + 20000; // время ожидания
Serial_S.println("ATD"+ GSM_Phone_T+";");
GSM_team_room=5;
#ifdef GSM_DEBUG // отладка
Serial.println("Command: ATD"+ GSM_Phone_T+";");
#endif
}
}
#endif
//________ Обработка разных процессов
switch (GSM_team_room)
{
case 0:
break;
case 1: //Обработка входящих вызовов
if (!GSM_wait)
{
if (GSM_command_Reject_call)
{
if (GSM_singleCommand(F("ATH0"), 10))
{
GSM_command_Reject_call=0;
GSM_Call=0;
GSM_count=0;
}
}
#ifdef GSM_INCLUSION_CALLS
#ifndef GSM_TYPE_M590
if (GSM_causeProcessingTake())
{
GSM_Connect=1;
GSM_team_room=5;
}
#endif
#endif
}
if (!GSM_Call)
{
GSM_final =1;
GSM_T_Nomer ="";
}
break;
case 2:
if (!GSM_wait)
{
GSM_final=GSM_sms_sent();
}
// отправка сообщения
break;
case 3:
if (!GSM_wait)
{
GSM_final=GSM_net_status();
}
// проверка связи с сетью
break;
case 4: //приход смс
//if (!GSM_wait){ GSM_final=1; GSM_count=0; GSM_Error_Code =0; GSM_team_room =0; }//
break;
#ifdef GSM_INCLUSION_CALLS
case 5: //разговор
if (!GSM_wait)
{
if (GSM_command_Reject_call)
{
if (GSM_singleCommand(F("ATH0"), 10))
{
GSM_command_Reject_call=0;
GSM_Call=0;
GSM_count=0;
GSM_Connect=0;
}
}
}
break;
#endif
#ifdef GSM_INCLUSION_DATA_TIME
case 6: // дата время
if (!GSM_wait)
{
if (GSM_DataTime())
{
GSM_final =1;
}
}
// запрос баланса
break;
#endif
#ifdef GSM_INCLUSION_USSD
case 7: // USSD
if (!GSM_wait)
{
GSM_final=GSM_USSD();
}
// запрос баланса
break;
#endif
}
//________ Конец Обработка разных процессов
if (GSM_final)
{
GSM_team_room=0;
GSM_final=0;
}
//должно быть последним
}
GSM_Outgoing_Call = 0;
GSM_Take_Call = ((GSM_T_Nomer).equalsIgnoreCase(String("+79876057564")));
//Плата:2
_gtv3 = ((!((_gtv1) == (1))) || (0));
_gtv2 = ((!((_gtv1) == (1))) || (0));
bool _tmp2 = ((!(_bounseInputD6O)) || (!((_gtv1) == (1))));
if (_tmp2)
{
if (! _trgt2I) _trgt2 = ! _trgt2;
}
_trgt2I = _tmp2;
digitalWrite(13, _trgt2);
if (_trgt2)
{
if (_tim2I)
{
if (flprog::isTimer(_tim2P, 4000))
{
_tim2O = 1;
}
}
else
{
_tim2I =1;
_tim2P = millis();
}
}
else
{
_tim2O = 0;
_tim2I = 0;
}
if (_tim2O)
{
if (_trgrt1I)
{
_trgrt1 = 0;
}
else
{
_trgrt1 = 1;
_trgrt1I = 1;
}
}
else
{
_trgrt1 = 0;
_trgrt1I = 0;
}
;
if(_trgrt1)
{
_tim3O = 1;
_tim3I = 1;
}
else
{
if(_tim3I)
{
_tim3I = 0;
_tim3P = millis();
}
else
{
if (_tim3O)
{
if (flprog::isTimer(_tim3P, 2000)) _tim3O = 0;
}
}
}
digitalWrite(3, !(_tim3O));
digitalWrite(2, !(_trgt2));
//Плата:3
if (1)
{
if (_tim4I)
{
if (flprog::isTimer(_tim4P, 100))
{
_tim4O = 1;
}
}
else
{
_tim4I =1;
_tim4P = millis();
}
}
else
{
_tim4O = 0;
_tim4I = 0;
}
if (_tim4O)
{
if (_trgrt2I)
{
_trgrt2 = 0;
}
else
{
_trgrt2 = 1;
_trgrt2I = 1;
}
}
else
{
_trgrt2 = 0;
_trgrt2I = 0;
}
;
digitalWrite(7, !(_trgrt2));
}
bool GSM_setup_comand()
{
switch (GSM_count)
{
case 0:
GSM_count ++;
break;
case 1:
GSM_Command(F("ATE0") ,2) ; //отключение эхо ответа
break;
case 2:
GSM_AT_Command(F("CPAS"),4);
// проверка готовности модуля к работе
break;
case 3:
GSM_analysisResponse(F("+CPAS: 0"));
break;
case 4:
GSM_AT_Command(F("CREG?"),10);
//Проверка регистрации в сети
break;
case 5:
if (GSM_analysisResponse(F("+CREG")))
{
if((GSM_reply.endsWith("1")) || (GSM_reply.endsWith("5")))
{
GSM_Net =1;
}
// 1-В домашней сети, 5- в роуминге
else
{
GSM_err(0,1);
GSM_count--;
}
}
break;
case 6:
GSM_AT_Command(F("CSCB=1") ,2);
// Отключение приема широковещательных сообщений
break;
case 7:
GSM_AT_Command(F("CLIP=1") ,2);
// настройки автоматического определения номера
break;
case 8:
GSM_AT_Command(F("CMGF=1") ,2) ; //настройки формата SMS сообщений, текстовый
break;
case 9:
GSM_AT_Command(F("CSCS=\"GSM\"") ,2);
// выбора кодировки текста, кодировка ASCII
break;
case 10:
GSM_AT_Command(F("CNMI=2,2,0,0,0") ,2) ; //выдовать смс в терминал и не сохранять в память
break;
case 11:
#ifdef GSM_INCLUSION_DTMF // Если добвален блок DTMF
GSM_AT_Command(F("DDET=1") ,5) // Включение работы с DTMF
#else
GSM_count ++;
#endif
break;
#ifdef TELEFONNAYA_BOOK // Если использовать телефонну книгу
case 12:
GSM_AT_Command(F("CPBS?"),2);
break;
case 13:
GSM_analysisResponse(F("+CPBS: \"SM\""));
break;
case 14:
GSM_AT_Command(F("CPBF=\""), GSM_Name_Contact , 2) ;
GSM_index_array =0;
break;
case 15:
#else //Если не использовать телефонную книгу
case 12:
#endif //Окнчание выбора по телефонной книге
GSM_count=0;
GSM_Error_Code =0; //Сброc ошибки
return 1;
break;
}
return 0;
}
bool GSM_causeProcessingCall()
{
static bool past_Outgoing_Call=0;
static bool command_Outgoing_Call=0;
if (GSM_Outgoing_Call && !past_Outgoing_Call) command_Outgoing_Call =1;
past_Outgoing_Call = GSM_Outgoing_Call ;
if (command_Outgoing_Call && (GSM_team_room==0))
{
command_Outgoing_Call =0;
return 1;
}
// начинать запрос времени
return 0;
}
bool GSM_causeProcessingTake()
{
static bool past_Take_Call;
static bool command_Take_Call;
if (GSM_Take_Call && !past_Take_Call)
{
command_Take_Call=1;
}
past_Take_Call = GSM_Take_Call;
if (command_Take_Call)
{
switch (GSM_count)
{
case 0:
GSM_count++;
break;
case 1:
GSM_Command(F("ATA"), 5);
// Поднять трубку
#ifdef GSM_DEBUG // отладка
Serial.println("Command: ATA");
#endif
break;
case 2:
GSM_count=0;
command_Take_Call =0;
return 1;
break;
}
}
return 0;
}
void GSM_GotLineFromNeoway()
{
bool flag_=0; //Анализ телефонной книги
static bool isStringMessage;
#ifdef GSM_DEBUG
Serial.print("Message module: "); //Тест
Serial.println(GSM_line); //Тест
Serial.print("GSM_team_room: "); //Тест
Serial.println(GSM_team_room); //Тест
#endif
if (GSM_line.length()>0)
{
//Обработка входящих СМС
if (isStringMessage)
{
GSM_Text_sms = GSM_line ; //выводим текст сообщения
GSM_Received_SMS =true; // Импульс приход сообщения
isStringMessage=0;
return;
}
if (GSM_line.startsWith("+CMT")) // пришло СМС
{
flag_=1;
GSM_resetExpectations();
isStringMessage=1;
}
//Конец Обработка входящих СМС
// Обработка входящих вызовов
if (GSM_Call)
{
if (GSM_line.startsWith(F("+CLIP")))
{
flag_=1;
GSM_reply="";
}
else if (GSM_line == F("NO CARRIER"))
{
GSM_Call=0;
}
}
if (GSM_line == F("RING"))
{
//Входящий звонок
if(!GSM_Call)GSM_resetExpectations();
GSM_Call=1;
GSM_Number_calls ++;
}
#ifdef GSM_INCLUSION_CALLS //Если добавлен блок работы со звонками
#ifdef GSM_INCLUSION_DTMF // Если добвален блок DTMF
if (GSM_Connect)
{
if (GSM_line.startsWith(F("+DTMF")))
{
GSM_ID_DTMF(GSM_line);
}
}
#endif
if (GSM_team_room==5)
{
if (GSM_line == F("CONNECT"))GSM_Connect=1;
else if (GSM_line == F("BUSY")) GSM_err (505,2);
else if (GSM_line == F("NO ANSWER")) GSM_err (506,2);
else if (GSM_line == F("NO CARRIER"))
{
if (GSM_Connect)GSM_Connect=0;
else GSM_err (507,2);
}
}
#endif
// Конец Обработка входящих вызовов
if(GSM_line == F("ERROR")) GSM_err (1, 0);
else if(GSM_line == F("OK"))
{
GSM_wait=0;
GSM_count++;
GSM_errorCounter=0;
}
else
{
GSM_reply+=GSM_line;
}
if (GSM_reply.length()> 160)
{
GSM_reply="";
GSM_err(10100,2);
}
//Защита от переполнения строки
if (GSM_line == Module_Start)
{
GSM_start_N=1;
GSM_start=0;
GSM_err(0 , 2);
}
//Сообщение от модуля о том, закончил загрузку
if (flag_) //Получение номер телефона отправителя/звонящего
{
GSM_T_Nomer = GSM_substring_commas(GSM_line, 4);
if(GSM_T_Nomer.indexOf("+")==-1) GSM_T_Nomer=(String("+"))+ GSM_T_Nomer;
#ifdef TELEFONNAYA_BOOK // если используется телефооная книга
int GSM_ind_arr= GSM_StringArray(GSM_Telefon, GSM_T_Nomer);
if (GSM_ind_arr>-1) GSM_T_Nomer = GSM_Contact [ GSM_ind_arr ];
#endif
flag_=0;
}
#ifdef TELEFONNAYA_BOOK // если используется телефооная книга
if (!GSM_start)
{
if (GSM_line.startsWith("+CPBF")) // пришла запись телефонной книги
{
if(GSM_index_array< GSM_Number_Contacts)
{
GSM_Telefon[ GSM_index_array ] = GSM_substring_commas(GSM_line, 5);
GSM_Contact[ GSM_index_array ]= GSM_substring_commas(GSM_line, (GSM_line.lastIndexOf(","))) ;
GSM_index_array ++;
}
}
}
#endif
}
// Получили строку ответа от Neoway. Любые ответы приходят в виде
// либо одной, либо нескольких строк, так что единица, которой мы должны
// оперировать - именно строка
// F("") -Хранить строку в Флеш памяти
}
void GSM_AT_Command(const __FlashStringHelper* str, String str2, byte _numRep)
{
GSM_numberRepeats=_numRep;
GSM_reply=""; //Сброс содержимого прошлого ответа модуля
GSM_wait=1; // ожитать
GSM_time =millis() + 20000; // время ожидания
Serial_S.write("AT+");
Serial_S.print(str);
Serial_S.print(str2);
Serial_S.write("\"\r\n");
#ifdef GSM_DEBUG // отладка
Serial.write("Command: AT+");
Serial.print(str);
Serial.print(str2);
Serial.write("\"\r\n");
#endif
}
bool GSM_net_status()
{
switch (GSM_count)
{
case 0:
GSM_count ++;
break;
case 1:
GSM_AT_Command(F("CREG?") , 5);
//Проверка регистрации в сети
break;
case 2:
if (GSM_analysisResponse(F("+CREG")))
{
if((GSM_reply.endsWith("1")) || (GSM_reply.endsWith("5")))
{
GSM_Net =1;
}
// 1-В домашней сети, 5- в роуминге
else
{
GSM_Net =0;
}
}
break;
case 3: // Проверка уровня сигнала
GSM_AT_Command(F("CSQ") , 5);
break;
case 4:
if (GSM_analysisResponse(F("+CSQ")))
{
//
int t1= GSM_reply.indexOf(": ");
if(t1>-1) GSM_dBm =((((GSM_reply.substring(t1+2,t1+4)).toInt())*(2))-(113));
if(GSM_dBm >0) GSM_dBm =-120; //нет сети
}
break;
case 5:
GSM_count=0;
GSM_time_n=millis(); // время последнего опроса
GSM_Error_Code =0; //Сброc ошибки
return 1;
break;
}
return 0;
}
bool GSM_sms_sent()
{
switch (GSM_count)
{
case 0:
GSM_count ++;
break;
case 1:
GSM_AT_Command(F("CMGF=1"),1);
// Перевод сообщенй в текстовый режим
break;
case 2:
GSM_AT_Command(F("CMGS=\""), GSM_Phone_T ,1); // Отправка команды на начальный этап отправки СМС
break;
case 3: // передача текста СМС и отправка сообщения
if (GSM_errorCounter)
{
GSM_err((200+ GSM_count) , 2);
break;
}
// выход из посылки команд если достигнуто придельное колличество ошибок
Serial_S.println(GSM_text +String((char)26));
GSM_wait=1; // ожитать
GSM_time =millis() + 20000; // время ожидания
#ifdef GSM_DEBUG // отладка
Serial.println(GSM_text +String((char)26));
#endif
break;
case 4:
GSM_count=0;
GSM_Sent_SMS =1;
GSM_Error_Code =0; //Сброc ошибки
return 1;
break;
}
return 0;
}
String GSM_substring_commas(String text_analyze, int position)
{
int t1=text_analyze.indexOf("\"", position);
int t2=text_analyze.indexOf("\"",(t1+1));
if(t1>-1)
{
if(t2>-1) return text_analyze.substring(t1+1,t2);
else return text_analyze.substring(t1+1);
}
return "";
}
bool GSM_number_search()
{
if (GSM_Phone.length() <4)
{
GSM_Error_Code =10005;
return 0;
}
GSM_Phone_T = GSM_Phone ;
#ifdef TELEFONNAYA_BOOK
int ind_arr;
ind_arr= GSM_StringArray(GSM_Contact , GSM_Phone);
if (ind_arr>-1) GSM_Phone_T = GSM_Telefon [ ind_arr ];
else if(GSM_White_list)
{
GSM_Error_Code =10006;
return 0;
}
#endif
return 1;
}
void GSM_resetExpectations()
{
//сброс текущей операции
GSM_wait=0; //сброс ожидания ответа
GSM_count=0; //Сброс состояний обработки других функций
GSM_time_n=GSM_T_millis; //отсрочка проверки статуса сети
GSM_team_room=0;
}
void GSM_err(int error, byte _ret)
{
GSM_errorCounter++ ;
GSM_reply=""; //Сброс содержимого прошлого ответа модуля
GSM_wait =0;
if (_ret==0)
{
if (GSM_errorCounter >GSM_numberRepeats)
{
error = GSM_team_room*100+ GSM_count;
_ret=2;
}
else return;
}
if (_ret==1) GSM_count--;
else if (_ret==2)
{
GSM_errorCounter=0;
GSM_Error_Code =error;
if (GSM_team_room==3)
{
GSM_Net =0;
GSM_dBm =-120;
}
GSM_resetExpectations();
}
}
void GSM_AT_Command(const __FlashStringHelper* str, byte _numRep)
{
#ifdef GSM_DEBUG // отладка
Serial.write("AT+ _ ");
#endif
Serial_S.write("AT+");
GSM_Command(str,_numRep) ;
}
bool GSM_analysisResponse(const __FlashStringHelper* response)
{
#ifdef GSM_DEBUG
Serial.print("Expected Answer: "); //Тест
Serial.println(response); //Тест
Serial.print("Real Answer: "); //Тест
Serial.println(GSM_reply); //Тест
#endif
if (GSM_reply.startsWith(response))
{
GSM_count++;
return 1;
}
GSM_err(0,1);
return 0;
}
bool GSM_singleCommand(const __FlashStringHelper* str, byte _numRep)
{
switch (GSM_count)
{
case 0:
GSM_Command(str, _numRep) ;
break;
case 1:
GSM_count=0;
GSM_Error_Code =0; //Сброc ошибки
return 1;
break;
}
return 0;
}
void GSM_Command(const __FlashStringHelper* str, byte _numRep)
{
GSM_reply=""; //Сброс содержимого прошлого ответа модуля
GSM_numberRepeats=_numRep;
GSM_wait=1; // ожитать
GSM_time =millis() + 20000; // время ожидания
Serial_S.println(str);
#ifdef GSM_DEBUG // отладка
Serial.write("Command: ");
Serial.println(str);
#endif
}
void GSM_ID_DTMF(String st)
{
int www=(int(st.charAt(7)));
switch (www)
{
case 35:
GSM_DTMF =14;
break;
case 42:
GSM_DTMF =15;
break;
case 65:
GSM_DTMF =10;
break;
case 66:
GSM_DTMF =11;
break;
case 67:
GSM_DTMF =12;
break;
case 68:
GSM_DTMF =13;
break;
default:
if (www>47 && www<58) GSM_DTMF =www-48;
}
Arduino: 1.8.19 (Windows 7), Плата:“Arduino Uno”
C:\Users\э\AppData\Local\Temp\flprog\pr11\pr11.ino: In function ‘bool GSM_setup_comand()’:
pr11:540:10: error: expected ‘;’ before ‘break’
exit status 1
expected ‘;’ before ‘break’
Этот отчёт будет иметь больше информации с
включенной опцией Файл → Настройки →
“Показать подробный вывод во время компиляции”