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);
}
}
Ну что ж, всем спасибо за внимание)))
В коде обнаружил существенные ошибки, влияющие на удаление прочитанных СМС. Скорее всего в этом и была проблема.