SIM800l vs SIM800l v2.
- Войдите на сайт для отправки комментариев
Вечер добрый! Помогите кто чем может)
Есть, вернее было вполне работоспособное устройство - блок автозапуска автомобиля. Управлялось по СМС, контролировало напряжение и температуру. 3-года трудилось, но заболело и умерло( здох вначале SIM800 v2(я помог, случайно), потом и ардуинка шиться перестала. Есть в загашнике новая Ардуино нано и SIM800l, первой версии.
Так вот проблема в том, что новая парочка работает как попало: то принимает СМС, то нет. То отправляет их в ответ, то нет. Питание в порядке - 4В на Sim, 5В на Ардуино.
Может кто подскажет в чём может быть засада? Скетч один и тот же.
На скетч прошу сильно не ругаться - я не программер, от слова, совсем) Но писал сам, вернее склеивал из разных скетчей один и допиливал...
//Замер температуры, напряжения, старт-стоп по СМС, с отчётами. С реле закрытия двери. //подключаем библиотеки #include <OneWire.h> // Подключаем библиотеку для работы с шиной OneWire OneWire oneWire(4); // Термометр будет подключен на Pin4 #include <DallasTemperature.h> //Подключаем библиотеку для работы с термометром DallasTemperature sensors(&oneWire);//Создаем объект sensors, подключенный по OneWire //Создаем переменные для работы с термометром DeviceAddress tempDeviceAddress; //переменная для хранения адреса датчика #include "SIM900.h" #include <SoftwareSerial.h> #include "sms.h" SMSGSM sms; //Переменные Вольтметра int analogInput = 0; //Вход измерения U float vout = 0.0; float vin = 0.0; //float R1 = 100000.0; // сопротивление R1 (100K) //float R2 = 10000.0; // сопротивление R2 (10K) int value = 0; //назначаем переменные //Объявим переменные для задания задержки long previousMillis1 = 0; long interval1 = 10000; // интервал опроса датчиков температуры и U //стандартный набор из примера int numdata; boolean started=false; char smsbuffer[160]; char n[20]; //новые переменные String input_string = ""; String smsContent = ""; char pos; //номер последней смс char sendsms[160];//содержание СМС //флаги, для однократности действия команд int flag=0; int flagT=1; int flagV=0; int flagV1=0; int Start=0; int Stop=0; int flag_Start=0; int flag_Stop=0; char n1[] = "+79206601085"; //разрешённый номер для СМС //переменные измерения температуры float temp; //переменная для текущего значения температуры int LowTmp= -10; // переменная для низкой температуры int HiTmp= 110; // переменная для высокой температуры int ErrorTmp= -127; // переменная для высокой температуры //Настройки unsigned long ENGINE_WARM_TIME = 900000; //В миллисекундах время работы мотора после запуска 1200000 миллисекунд = 20 минут int ENGINE_START_MAX_TIME = 5; //В секундах масимальное время работы стартера типично 3 -10 сек // select pins for input const int hand_brake_in = 11; //d11 adruino Контакт стояночного тормоза "-", МКПП. const int sharging_in = 5; //d5 adruino - лампа заряд const int sharging_on = 1; // 0 когда во время работы генератора или от датчика давления масла на этом входе низкое состояние , 1 когда на лампе генератора при работе генератора высокое состояние const int hand_brake_on = 0; // 0 поднятый датчик ручника замыкает на массу тормоз активен (жигули), 1 датчик ручника в поднятом состоянии выдает высокий уровень напряжения // select pins for output const int starter_out = 6; //d6 adruino реле стартера const int engine_out = 8; //d7 adruino зажигание const int secpower_out = 7; //d8 цепи вторичного питания печка, фары итд const int status_out = 9; //d9 светодиод статуса системы моргает равномерно = система готова к работе(включена, ручник стоит). одно мигание запущен с первой попытки 2 со второй 3 с третьей //светодиод подключать с этого пина на массу const int door_out = 10; //имитация открытия вод. двери, для выключения головного света const int door_lock = 12; //закрытие дверей после остановки двигателя // variable for actual mode int actual_mode = 0; // 2 engine started int left_start_try = 0; // переменная для хранения остатка числа попыток запуска unsigned long last_start_time = 0; //время в тысячных секунды когда был запущен движок int ledState = LOW; // этой переменной устанавливаем состояние светодиода long previousMillis_led = 0; // храним время последнего переключения светодиода long interval_led = 1000; void setup() { //Инициализируем термодатчик sensors.begin(); // init input pinMode(analogInput, INPUT); pinMode(hand_brake_in, INPUT); // enable input pinMode(sharging_in, INPUT); // enable input // init outputs pinMode(starter_out, OUTPUT); // enable output digitalWrite(starter_out, LOW); //set digital 0 pinMode(engine_out, OUTPUT); // enable output digitalWrite(engine_out, LOW); //set digital 0 pinMode(secpower_out, OUTPUT); // enable output digitalWrite(secpower_out, LOW); //set digital 0 pinMode(status_out, OUTPUT); // enable output digitalWrite(status_out, LOW); //set digital 0 pinMode(door_out, OUTPUT); // enable output digitalWrite(door_out, LOW); //set digital 0 pinMode(door_lock, OUTPUT); // enable output digitalWrite(door_lock, LOW); //set digital 0 //Скорости портов и текст сообщение в сериал порт Serial.begin(9600); if (gsm.begin(2400)) { Serial.println("\nstatus=READY"); started=true; } else Serial.println("\nstatus=IDLE"); for (int i=0; i <= 20; i++) { sms.DeleteSMS(i); } } void loop() { //Модуль опроса датчиков и получения сведений о температуре и напряжении //Вызывается 1 раз в 10 секунд unsigned long currentMillis1 = millis(); if(currentMillis1 - previousMillis1 > interval1) { previousMillis1 = currentMillis1; gettemperature(); voltage(); // Вывод текущего значения температуры в порт Serial.println("temp: "+String(temp)); Serial.println("Voltage: "+String(vin)); } pos = sms.IsSMSPresent(SMS_UNREAD); // смотрим непрочитанные СМС delay(1000); if (pos) { // Если непрочитанные СМС есть, то... getsms(); // получаем непрочитанную СМС } delay(1000); //Начальные условия автозапуска if (actual_mode < 2 ) //если двигатель не запущен check_start(); //Управляем режимом запуска //код условия обязательно включать в фигурные скобки если должно быть выполнено несколько инструкций, в данном случае одна, поэтому скобки опущены else // иначе { check_for_shutdown(); //Управляем режимом ожидания окончания прогрева } //но хорошая привычка фигурные скобки ставить всегда set_status_led(); //независимо от режима Управляем светодиодом статуса //------------------конец основного кода ----------------- } void getsms() { sms.GetSMS(pos,n,20,smsbuffer,160); Serial.println(n); Serial.println(smsbuffer); input_string =String(smsbuffer); //Если номер входящей СМС соответствует заданному (char n1[] = "+79XXXXXXXXX";) if(strstr(n, n1) != NULL) { if (input_string=="1")//запуск авто { Start=1; check_start(); memset(n,0,20); } else if (input_string=="2")//останов { Stop=1; memset(n,0,20); } else if (input_string=="3")//Temp_Start OFF { flagT=1; sms.SendSMS(n1, "Temp_Start OFF"); memset(n,0,20); } else if (input_string=="4")//запрос температуры { flagT=0; sms.SendSMS(n1, "Temp_Start ON"); memset(n,0,20); } else if (input_string=="5")//Запрос напряжения и температуры { //отправляем СМС при входящей СМС "5" smsContent=("Voltage: "+String(vin)+"Temp: "+String(temp)); smsContent.toCharArray(sendsms,160); sms.SendSMS(n1, sendsms); memset(n,0,20); } } EndSMS(); } void EndSMS() //__________________Чистим СМС_______________________ { for (int i=0; i <= 21; i++) { sms.DeleteSMS(i); } } //Считывание значения температуры void gettemperature() { { //Запуск процедуры измерения температуры sensors.setWaitForConversion(false); sensors.requestTemperatures(); sensors.setWaitForConversion(true); delay(750);// задержка для обработки информации внутри термометра, //в данном случае можно не задавать sensors.getAddress(tempDeviceAddress, 4); temp = sensors.getTempC(tempDeviceAddress); } if (temp>ErrorTmp&&temp<=LowTmp && flag==0) { sms.SendSMS(n1, "t < -25C, Nizkaya temperatura");//оповещение о низкой температуре двигателя delay(1000); flag = 1 ; if (temp>ErrorTmp && temp<LowTmp && flagT==0 && Start==0) { Start = 1 ; flagT = 1 ;//запуск двигателя по СМС "Temp_Start ON " } } if (temp>HiTmp && flag==0) { sms.SendSMS(n1, "t > 110C, Peregrev");//оповещение о высокой температуре двигателя delay(1000); flag = 1 ; } if (temp<=100&&temp>=0) { flag = 0 ; } } // считывание напряжения void voltage() { // считывание аналогового значения value = analogRead(analogInput); vout = (value * 0.005078125); //vout = (value * 5.20) / 1024.0; vin = (vout / 0.090744266); //vin = vout / (R2/(R1+R2)); //if (vin<0.09) //{ //vin=0.0;// обнуляем нежелательное значение //} if (vin<11.5 && flagV==1 && flagV1==1) //Второе измерение - отправляем СМС { sms.SendSMS(n1, "Voltage < 11.5V");flagV=0;//оповещение о разряде АКБ и сбрасываем один флаг } if (vin<11.5 && flagV==0 && flagV1==0) //Первое измерение напряжения - поднимаем флаги { flagV=1;flagV1=1;//оповещение о разряде АКБ } if (vin>12.5) { flagV=0;flagV1=0; //Напряжение поднялось выше порога - сброс флагов } } void check_start() { if (Start != 0 && left_start_try == 0) // 1 is command for start - 1 значит импульс старта пришел с дистанционного управления <--- тут определяется полярность импульса запуска { left_start_try = 3;// указываем что нужно попытаться трижды запустить движок delay(1000); Start = 0 ; } if ( left_start_try > 0 ) { digitalWrite(engine_out, HIGH); //включаем зажигание delay(3000); // останавливаем код на 3 секунды чтобы бензонасос набрал давление, все датчики включились if (digitalRead(hand_brake_in) != hand_brake_on) //без ручника не делаем запуск { actual_mode = 2; // заканчиваем попытки запустить движок left_start_try = 0; //без ручника другие попытки бесполезны //Start = 0 ; return; } if (digitalRead(sharging_in) != sharging_on ) // проверяем что генератор не работает { do_start(); // пытаемся запустить движок left_start_try = left_start_try - 1 ; //уменьшаем число попыток if (left_start_try == 0 ) actual_mode = 2; // заканчиваем попытки запустить движок } // конец проверки что ручник стоит а генератор не работает } } // конец процедуры старта void do_start() { //тут будет запуск движка //----------------------------------------------------------------------------------- цикл стартера digitalWrite(starter_out, HIGH); //включаем стартер for (int secs=0; secs <= ENGINE_START_MAX_TIME ; secs++) // { delay(1000); // и продолжаем его держать включенным 1 секунду if (digitalRead(sharging_in) == sharging_on) //если зарядка пошла то break; // прерываем цикл } //----------------------------------------------------------------------------------- digitalWrite(starter_out, LOW); //отключаем стартер if (digitalRead(sharging_in) == sharging_on) //еще раз смотрим что зарядка пошла { actual_mode = 2; //Запоминаем что движок запущен last_start_time = millis(); // запоминаем время запуска движка //sms.SendSMS(n1, "Start OK"); } else { digitalWrite(engine_out, LOW); //выключаем зажигание что бы разблокировать реле стартера delay(3000); // останавливаем код на 3 секунды чтобы бензонасос набрал давление } } void check_for_shutdown() { //сюда мы попадаем когда контроллер считает что движок работает if (digitalRead(sharging_in) != sharging_on ) //проверяем что движок случайно не заглох { do_shutdown(); } else { digitalWrite(secpower_out, HIGH); //включаем печку фары итд if (flag_Start==0) //однократность СМС { sms.SendSMS(n1, "Start OK"); } flag_Start=1;//однократность СМС flag_Stop=0; } if (digitalRead(hand_brake_in) != hand_brake_on ) //проверяем что если злодеи сняли с ручника то глушим мотор { do_shutdown(); left_start_try =0; // и больше не заводим if ((digitalRead(hand_brake_in) != hand_brake_on ) && (digitalRead(sharging_in) != sharging_on ))//если мотор заглох - отправляем СМС { sms.SendSMS(n1, "Alarm STOP"); } } if (Stop != 0 ) // СМС на выключение { do_shutdown(); left_start_try =0; // и больше не заводим } //тут будем контролировать чтоб если забыли машинку заведенной она не молотила до скончания бензобака а выключалась через какоето время if (actual_mode != 0 ) //значит не выключили заглохший двигатель только что { // милисекунды в ардуино обнуляются каждые 49 суток // для того чтобы в случае если запуск произошел в течении последних 20 минут до обнуления мотор не молотил еще 49 суток // нужно обнулить и время старта, при этом мотор максимум будет прогреваться вдвое больше обычного if (millis() < last_start_time) { last_start_time = 0; } if (millis() > last_start_time+ENGINE_WARM_TIME) // если текущее время больше чем время старта + время прогрева { do_shutdown(); left_start_try =0; // и больше не заводим } } } void do_shutdown() { digitalWrite(secpower_out, LOW); //выключаем печку фары итд digitalWrite(engine_out, LOW); //вырубаем зажигание actual_mode = 0; // движок выключили запомним это last_start_time = 0; // ну и забудем о том что он был включен Stop = 0; //Разблокируем следующий запуск flag_Start=0;//и отправку СМС delay(1000); digitalWrite(door_out, HIGH); //хлопнули дверью - свет погас delay(1000); digitalWrite(door_out, LOW); if ((digitalRead(sharging_in) != sharging_on ) && (flag_Stop==0))//проверяем что двигатель заглох и отправляем СМС { sms.SendSMS(n1, "Stop OK"); flag_Stop=1; } digitalWrite(door_lock, HIGH); //закрыли двери delay(1000); digitalWrite(door_lock, LOW); } void set_status_led() { if (digitalRead(hand_brake_in) != hand_brake_on ) //Если ручник не стоит то выкл светодиод нечего ему в пути мигать попусту { digitalWrite(status_out, LOW); return; //прерываем выполнение функции } if (actual_mode == 2) //Движок запущен status_led_flash(); // показываем с какой попытки был прошлый запуск else status_led_flash1(); // показываем с какой попытки был прошлый запуск // постоянное свечение - показываем что готов к следующему запуску } void status_led_flash() { static unsigned long big_interval = 0; static unsigned long flash_interval = 0; unsigned long flash_count = 0; flash_count = 3 - left_start_try; //сколько раз мигать //1 секндный интервал if (millis() > flash_interval + 1000L) flash_interval = millis() ; //задаем счетчие от 0 до 1 секунды //задаем 6 секунд if (millis() > big_interval + 6000L) { big_interval = millis() ; //задаем счетчие от 0 до 10секунд flash_interval = big_interval; } if (millis() < big_interval + flash_count * 1000L) // делим 6 секндный интервал на два периода, в первый мигаем количество раз соответствующее числу израсходованных попыток { //мигает if (millis() > flash_interval + 500L) digitalWrite(status_out, HIGH); else digitalWrite(status_out, LOW); } else { // негорит digitalWrite(status_out, LOW); //set digital 0 } } void status_led_flash1() { //const int status_out = 13; // номер выхода, подключенного к светодиоду // Variables will change: //int ledState = LOW; // этой переменной устанавливаем состояние светодиода //long previousMillis = 0; // храним время последнего переключения светодиода //long interval = 1000; // интервал между включение/выключением светодиода (1 секунда) // здесь будет код, который будет работать постоянно // и который не должен останавливаться на время между переключениями свето unsigned long currentMillis_led = millis(); //проверяем не прошел ли нужный интервал, если прошел то if(currentMillis_led - previousMillis_led > interval_led) { // сохраняем время последнего переключения previousMillis_led = currentMillis_led; // если светодиод не горит, то зажигаем, и наоборот if (ledState == LOW) ledState = HIGH; else ledState = LOW; // устанавливаем состояния выхода, чтобы включить или выключить светодиод digitalWrite(status_out, ledState); } }
Ну что ж, всем спасибо за внимание)))
В коде обнаружил существенные ошибки, влияющие на удаление прочитанных СМС. Скорее всего в этом и была проблема.