Доброго дня всем! Соорудил из gsm модуля и ардуинки сигнализацию в авто. Все работает. Но через пару недель вдруг подвис GSM модуль и перестал слать оповещения. Сама дуина отрабатывала при этом на ура - ставила/снимала с охраны, работал светодиод-индикатор. Вот я и задумался - как реализовать периодический контроль работоспособности GMS модуля? и в случае зависания - хотя бы оповещать меня. Ну или перезагружать модуль? Подскажите как это сделать красиво? ))
Можно посылать ему АТ каждые 5 минут к примеру и если он не ответит ОК релюхой подключенной к ардуине вырубать его и снова включать через минуту.Это первое что пришло на ум хотя все сложнее у меня например на старлайне ГСМ модуль после перезагрузки и чистки ластиком контактов СИМ рпботает пару дней а потом опять глючит.Тут надо причину искать.И хорошо если дело в Сети а если в модуле?Тут только выкинуть и заменить.
Да, я тоже так думаю. Это первое, что приходит на ум. Единственное, я затрудняюсь реализовать код. Еще пока на Вы с программированием. Не знаю, как правильно сделать так, чтобы дуина поняла, что он не ответил на команду.
Мы в своих устройствах принудительно раз в сутки делаем рестарт GSM-модуля, но у нас не охранная система. Для охранной системы действительно нужно периодически опрашивать модуль и в случае отсутствия ответа делать ему RESET.
Да, чем проще, тем лучше. Пожалуй, сделаю принудительную перезагрузку раз в сутки. 10-15 секунд перезагрузки погоды не сделают. Только кто подскажет, может ли SIM900 зависнуть так, что не будет реагировать на сигналы включения/выключения? Дело в том, что тупо рубить питание ему не получится - устройство собрано. Вмешиваться можно только в код. Во второй версии устройства я предусмотрю такую функцию.
Ну вот если проверять работоспособность модуля, то я родил вот такую функцию, которую нужно вызывать периодически. Код (C++): void TestGsm(){ gprsSerial.println("AT"); //отправляем модулю команду АТ bool out = true; // переменная для выхода из цикла static unsigned long previousMillis=0; // предыдущее время в миллисекундах previousMillis=millis(); while(out){ //начинаем цикл ожидания ответа if(millis()-previousMillis>=3000){ // если ответа нет 3 секунды // РЕСТАРТИМ GSM МОДУЛЬ out = false; //выходим из цикла while } if (gprsSerial.available()){ // если в буфере есть что-то while (gprsSerial.available()){ // начинаем считывать в цикле, пока что-то есть в буфере char currSymb = gprsSerial.read(); if ('\r' == currSymb) { // когда получен символ окончания строки, парсим строку: if (!currStr.compareTo("OK")){ // если модуль ответил "ОК", просто выходим из цикла проверки out = false; //выходим из цикла while } currStr = ""; // обнуляем полученную строку }else if ('\n' != currSymb) { // Пока не получим символ окончания строки, собираем строку currStr += String(currSymb); // переменная currStr уже объявлена в начале программы } } } } } Поправьте, может ошибся где?
Правильно ли я его прикрутил? Код (C++): #include <SoftwareSerial.h> SoftwareSerial gprsSerial(7, 8); int nasos1Pin = 2; int nasos2Pin = 3; int power = 9 ; void setup() { gprsSerial.begin(19200); pinMode(nasos1Pin, OUTPUT); pinMode(nasos2Pin, OUTPUT); pinMode(power, OUTPUT); digitalWrite(power,HIGH); //подали питание delay(3000); //на 3 сек digitalWrite(power,LOW); //сняли питание // Настраиваем приём сообщений с других устройств // Между командами даём время на их обработку gprsSerial.print("AT+CMGF=1\r"); delay(300); gprsSerial.print("AT+IFC=1, 1\r"); delay(300); gprsSerial.print("AT+CPBS=\"SM\"\r"); delay(300); gprsSerial.print("AT+CNMI=1,2,2,1,0\r"); delay(500); } String currStr = ""; // Переменная принимает значение True, если текущая строка является сообщением boolean isStringMessage = false; void TestGsm(){ gprsSerial.println("AT"); //отправляем модулю команду АТ bool out = true; // переменная для выхода из цикла static unsigned long previousMillis=0; // предыдущее время в миллисекундах previousMillis=millis(); while(out){ //начинаем цикл ожидания ответа if(millis()-previousMillis>=3000){ // если ответа нет 3 секунды // РЕСТАРТИМ GSM МОДУЛЬ out = false; //выходим из цикла while } if (gprsSerial.available()){ // если в буфере есть что-то while (gprsSerial.available()){ // начинаем считывать в цикле, пока что-то есть в буфере char currSymb = gprsSerial.read(); if ('\r' == currSymb) { // когда получен символ окончания строки, парсим строку: if (!currStr.compareTo("OK")){ // если модуль ответил "ОК", просто выходим из цикла проверки out = false; //выходим из цикла while } currStr = ""; // обнуляем полученную строку }else if ('\n' != currSymb) { // Пока не получим символ окончания строки, собираем строку currStr += String(currSymb); // переменная currStr уже объявлена в начале программы } } } } } void loop() { if (!gprsSerial.available()) return; char currSymb = gprsSerial.read(); if ('\r' == currSymb) { if (isStringMessage) { //если текущая строка - SMS-сообщение, //отреагируем на него соответствующим образом if (!currStr.compareTo("Nasos1 on")) { digitalWrite(nasos1Pin, HIGH); } else if (!currStr.compareTo("Nasos1 off")) { digitalWrite(nasos1Pin, LOW); } else if (!currStr.compareTo("Nasos2 on")) { digitalWrite(nasos2Pin, HIGH); } else if (!currStr.compareTo("Nasos2 off")) { digitalWrite(nasos2Pin, LOW); } isStringMessage = false; } else { if (currStr.startsWith("+CMT")) { //если текущая строка начинается с "+CMT", //то следующая строка является сообщением isStringMessage = true; } } currStr = ""; } else if ('\n' != currSymb) { currStr += String(currSymb); } }