GSM устройство управления котлами Webasto и не только

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Вот замерил - подключил ДВА последовательно прибора (китай UNI-T и Fluke true rms) - оба показывают одинаково - прошивка из первого поста - потребляемый ток спустя несколько секунд стабилизируется на показаниях = 37мА. Разрываю питания модуля сим800 - потребление 32мА.

uu5jhu
Offline
Зарегистрирован: 21.11.2017
/*   arduino       SIM800L
       D2           RING
       D4            TX
       D5            RX
       D6           DTR     */

#include "SIM900.h"
#include <SoftwareSerial.h>
#include "sms.h"
#include "call.h"
#include <avr/sleep.h>
#include <avr/power.h>
 
int pin = 2; // подключается к ring пину gsm модуля
int relay = 9; // реле
byte stat=0;

SMSGSM sms;
CallGSM call;

void setup(){
set_sleep_mode(SLEEP_MODE_STANDBY); //Определяем режим сна
pinMode(pin, INPUT);
digitalWrite(pin,HIGH);

     pinMode(6, OUTPUT); // к DTR пину GSM модуля
     digitalWrite(6,LOW); // пробуждаем GSM модуль
     
     pinMode(relay, OUTPUT);
     digitalWrite(relay,HIGH);

     Serial.begin(115200);
     Serial.println("GSM test.");
      
     if (gsm.begin(2400)) {
          Serial.println("\nstatus=READY");
          
     } else Serial.println("\nstatus=IDLE");
     
     delay(300);

     gsm.SimpleWrite(F("AT+CSCLK=1"));
     gsm.SimpleWriteln("");

}

void loop(){

stat=call.CallStatus();
      
    if(stat==CALL_INCOM_VOICE) {
 //     Serial.println("CALL!!!");
    //  sms.SendSMS("+79371662772", "Vipolneno!");
      digitalWrite(relay,LOW);
      delay(2000);
      digitalWrite(relay,HIGH);
      call.HangUp(); // Кладем трубку
    }

  digitalWrite(6,HIGH); // вырубаем GSM модуль
  EnterSleep(); //Пора спать
    
}

void wakeUp()
{
  Serial.println("WakeUp"); //Проснулись
  detachInterrupt(0); //Отключаем прерывания 
  digitalWrite(6,LOW); // пробуждаем GSM модуль
  delay(500);
}

void EnterSleep()
{
  attachInterrupt(0, wakeUp, LOW); //Если на 0-вом прерываниии - ноль, то просыпаемся.
  delay(100);
 
  sleep_enable(); //Разрешаем спящий режим
  sleep_mode(); //Спим (Прерывания продолжают работать.) Программа останавливается.
  sleep_disable(); //Запрещаем спящий режим
}

 

 

Прошу прощения за "плагиат" - вот нашёл на просторах ютуба - товарищ отправляет в сон и сим800 и дуню. Может можно прикрутить и к Вашему скетчу!?

MaksVV
Offline
Зарегистрирован: 06.08.2015

дак толку отправлять в сон Sim 800 если он ест 3..5мА. И дуня даже врядли ест 30мА. Нужно вытащить дуню и замрить сколько она ест с этим скетчем. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

видимо основные обжоры это DC-DC 12 to 4 и DC78L05. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

не представляю алгоритм работы моего устройства, если МК будет спать. Если делать чисто GSM включалку то, да, можно дуню усыплять. 

uu5jhu
Offline
Зарегистрирован: 21.11.2017

MaksVV пишет:

дак толку отправлять в сон Sim 800 если он ест 3..5мА. И дуня даже врядли ест 30мА. Нужно вытащить дуню и замрить сколько она ест с этим скетчем. 

Подключил дуню (со скетчем V2.1) напрямую к БП 13,6В (Vin & GND) - потребление составило = 18мА

MaksVV
Offline
Зарегистрирован: 06.08.2015

нет, надо к 5В без использования стабилизатора дуни. Мда 18 многовато

MaksVV
Offline
Зарегистрирован: 06.08.2015

короче, походу, нужно: 

- оставлять только DC-DC 12to4.2v , запитывая дуню не 5В , а 4.2; 78L05 при этом не нужен

- применять про мини (там нет uart-usb, который тоже кушает),

- отпаять штатный стабилизатор дуни; 

- отпаять светодиоды  (ну это лишнее конечно, они совсем мало едят)

MaksVV
Offline
Зарегистрирован: 06.08.2015

а это опять всю плату полностью перерисовывать , полная попа. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

думаю, что при этом можно добиться суммарного потребления надеюсь до 20мА -  столько работы нужно провести, а толку будет не много, проще АКБ хороший и машину на неделю не бросать, а если бросать, то запускать раз в 5 дней. 

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Мой DC-DC при подключении 13,6В без нагрузки кушает 12мА (настроен на 4,1В на выход) при подключении дуни нано со скетчем к напряжению 4,1В на вход дуни 5В ток увеличивается до 16мА

MaksVV
Offline
Зарегистрирован: 06.08.2015

ну вот, прибавить ещё 3...4 мА от SIM800 и будет 20мА, уже жить можно. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

только мне непонятно, почему SIM800 так и не уснул. Нужно посмотреть отвечает ли он ОК на команду AT+CSCLK=1

uu5jhu
Offline
Зарегистрирован: 21.11.2017

MaksVV пишет:

ну вот, прибавить ещё 3...4 мА от SIM800 и будет 20мА, уже жить можно. 

 

"Изувечил" дуню - выдернув пин 5В (чтобы не кромсать плату) - подключил 13,6В к DC-DC, вставил сим800 и запитал дуню от 4,1В - в общем дуню и сим800 посадил на одно питание от DC-DC 13.6В - 4.1В 

барабанная дробь......... 21-22 мА...... Осталось только проверить работает ли всё при этом полноценно (тест на коленке на скорую руку только ради замеров потребления)

MaksVV
Offline
Зарегистрирован: 06.08.2015

если оторвать встроенный стабилизатор дуни, ещё меньше будет

uu5jhu
Offline
Зарегистрирован: 21.11.2017

MaksVV пишет:

если оторвать встроенный стабилизатор дуни, ещё меньше будет

Почему так считаете? Вроде как там установлен стабилизатор на 5В и автоматически переключается на тот источник, напряжение которого выше. Получается если запитывать непосредственно дуню на вход +5В (пин после А7) то внутренний стабилизатор не будет использован. Или я ошибаюсь? 

MaksVV
Offline
Зарегистрирован: 06.08.2015

тут на форуме вроде слышал, что он всё равно потребляет. Также потребляет ch340 (usb-uart переходник). Поэтому идеальный вариант испоьзовать про мини 8мгц, 3,3В. Но можно ли её 4,1 запитать, это хз. Думаю можно, опять же, если стаб вытащить.  

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Ну дальше курочить дуню не очень хочется. Завтра попробую всё собрать в кучу, провести тесты "коробочки" и ещё раз проведу замеры потребления и дуни и сим800 от DC-DC. Отпишусь здесь.

22мА уже интереснее чем 37мА. Но идеально конечно же это новый АКБ да ещё и AGM.....

MaksVV
Offline
Зарегистрирован: 06.08.2015

AGM не стоит своих денег. Они умирают почти также как и обычные. Поэтому проще обычный АКБ менять почаще. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

uu5jhu пишет:

Ну дальше курочить дуню не очень хочется. Завтра попробую всё собрать в кучу, провести тесты "коробочки" и ещё раз проведу замеры потребления и дуни и сим800 от DC-DC. Отпишусь здесь.

22мА уже интереснее чем 37мА. Но идеально конечно же это новый АКБ да ещё и AGM.....

я так понимаю, в этой схеме убран внешний стабилизатор 78L05, что и составило экономию ? 

uu5jhu
Offline
Зарегистрирован: 21.11.2017

[/quote]

я так понимаю, в этой схеме убран внешний стабилизатор 78L05, что и составило экономию ? 

 

Да совершенно верно. Сегодня собрал всё в кучу, выпаял внешний стабилизатор 7805, регулировка DC-DC достаточно острая, получилось поймать 4.16В. Потребляемый ток спустя несколько секунд (после выпаивания 7805) составил = 18.2 - 19.2 мА (периодами прыгает до 20.3мА) прошивка v2.1. ОУ нет и стоит только 2 оптопары которые в режиме "St-By" не кушают.  Проверил функционал - отправка/получение смс - запуск потенциалом +12В это работает как и с питанием дуни от +5В. Осталось провести ходовые испытания на авто особенно в минус за бортом.

Если будет возможность хочу ещё поставить временно шунт по питанию и посмотреть осциллограммы на нём, есть предположения что мультимеры "врут" усредняя значения потребляемого тока.

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Теперь предположения по поводу сна сим800. Сейчас залит скетч v2.1 напряжение на пине DTR составляет 2.8В...... Вчера пробовал Ваш скетч v2.4  - спустя примерно 5 минут замерил потенциал на DTR и на А6.....там были примерно эти же уровни. То есть я так понимаю в режиме сна на А6 должно присутствовать постоянно +5В далее делитель напряжения...... Может я ошибаюсь.

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Сейчас залил скетч v2.4 (синал на DTR не заводил) - через 5 минут проверил напряжение - на А6 = 2.2В на DTR 2.8В. Но потребляемый ток с этим скетчем упал до 15мА в среднем.... почему так не знаю - напряжения питание все так же проверил - одинаковые остались.

MaksVV
Offline
Зарегистрирован: 06.08.2015

uu5jhu пишет:

Сейчас залил скетч v2.4 (синал на DTR не заводил) - через 5 минут проверил напряжение - на А6 = 2.2В на DTR 2.8В. Но потребляемый ток с этим скетчем упал до 15мА в среднем.... почему так не знаю - напряжения питание все так же проверил - одинаковые остались.


Видимо все же уснул сим 800. По идее без подключенного DTR он не должен проснуться и смс ки уже дуня не сможет слать, проверьте.

MaksVV
Offline
Зарегистрирован: 06.08.2015

uu5jhu пишет:
То есть я так понимаю в режиме сна на А6 должно присутствовать постоянно +5В далее делитель напряжения...... Может я ошибаюсь.

да, всё верно. Когда GSM вгоняется в сон,  на пине А6 ардуино должно быть 5В. На пине DTR GSM - 3В (это 5В после делителя) 

но этому не бывать, вычитал что A6 и А7 не могут использоваться как цифровые выходы, только аналоговый вход. Поэтому переделываем на А5. В скетче v2.4.1  (см. ниже) это уже поправлено

MaksVV
Offline
Зарегистрирован: 06.08.2015

Провел наконецто и я свои измерения. Тестер у меня более менее точный, микроАмперы им ловлю даже, когда измеряб потребение тока брелоком сигнализации из батарейки. Mastech 8211D.

ток измерялся на линии +12В, между источником питания 12В и нижеследующим: скетч 2.3.1

1. Чистый 78L05 с кондерами:                                              2,85мА

2. Arduino Nano питание на VCC 5В от 78L05:                        20,0мА

3. Arduino Nano (откусил PowerLED) на VCC 5В от 78L05:      17,2мА

4. Arduino Nano питание от встроенного стаба (12В на Vin):  17,5мА

5. Плата устройства без SIM800 и без Arduino (78L05, DC-DC, LM393):  15,4 мА

6. Плата устройства с SIM800 без Arduino (78L05, DC-DC, LM393):        20мА

7. Вся конструкция устройства:                                                              41мА                                                              

8.                                                          

Исходя из этого получается потребеление

SIM800L  4.6...5.0 мА

светодиод питания Arduinо 2,85 мА

откусил диод питания дуни: 

Вся конструкция устройства, но на Arduino откушен PowerLED :          38мА   

 загрузил скетч 2.4 с энергосбережением sim800

Вся конструкция устройства, но на Arduino откушен PowerLED+энергосбереж:        33,3 мА    

Здесь получается, что SIM800 вообще почти перестаёт потреблять, т.к. ток упал как раз на величину  потребления SIM800, которую мы выше замерили. 

Так что работает энергосбережение , хех. 

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

в скетче v2.4 обнаружил неточность. Реле ресета SIM800 было всегда активно, исправил. Также управление энергосбережением переделано на пин А5, т.к. А6 как цифровой выход использовать нельзя.

Исправленный скетч v2.4.1

#include <EEPROM.h>
#include <Button.h>

Button test;

// для GSM модуля *********************
#include <SoftwareSerial.h>
SoftwareSerial mySerial(14, 15); //Rx, Tx
//#define mySerial Serial 
String currStr = "";

String TelNumber1 = "000000000000";

String TelNumber2 = "000000000000";

String BufferNumber = "000000000000";

bool SaveNumber2 = 0;  // флаг когда необходима запись номера#2, он true

int isStringMessage = 0; 
int KTOzapros = 0;
int KTOreport = 1;
//************************


int Protocol = 1; // протокол, по которому будет происходить выход на запуск котла: 1 - импульсный минусовой выход (на впайку в таймер вебасто например)
                  // 2 - по протоколу W-BUS ( котлы TermoTOP EVO)
                  // 3 - по подаче потенциала 12В, т.е. пока висит +12В - котел включен (котлы по аналогу - TermoTOP C,E)

                  
//_______Все для цикла void voltmetr()*************
float vout = 0.0;      // Напряжение на входе аналового входа
float Vpit = 0.0;      // Измеряемое напряжение на выходе ИБП
  int volt = 0;        // Напряжение на входе АЦП

// входы выходы на соостветствующие пины **************
#define DopOn 4      // сюда доп канал от сигналки на включение вебасто
#define DopOff  5    // сюда доп канал от сигналки на выключение вебасто
#define VyhodWebasto  12     // это импульсный минусовой выход вкл/выкл вебасто к таймеру. 
#define VyhodWebastoAnalog  3  // это потенциальный плюсовой выход вкл/выкл вебасто (напрямую к котлу без таймера). 
#define Sost  9      // Сюда состояние вебасто (+12В когда работает)

#define Ohrana  6      // Сюда состояние охраны сигналки
#define Trevoga  7      // Сюда состояние тревоги
#define StartEng 8   // это импульсный минусовой выход вкл/выкл ДВС. подключать на вход событий сиги.
#define IGN 10       // Сюда состояние зажигания
#define Eng 11       // Сюда состояние работы ДВС
#define ResetGSM 16       // пин ресета GSM (A2) подключен к реле, разрывающее питание модуля. 
#define StartButton 0       // программный номер тактовой кнопки вкл/выкл котла 
#define StatusWebastoLED 13  // пин индикация включенности котла
#define DTR 19  // пин (А5), управляющий энергосберегающим режимом GSM модуля





// для шины 1-wire и датчиков DS18B20****************

#include <OneWire.h> // библиотека для DS18B20
OneWire ds(2); // датчики DS18B20 на 2 пин

byte VyhlopC[8] ={0x28, 0xFF, 0xE6, 0x14, 0x90, 0x15, 0x04, 0x62}; 
byte EngineC[8] ={0x28, 0xFF, 0x06, 0x15, 0x90, 0x15, 0x04, 0x37}; 
byte UlicaC[8] ={0x28, 0xFF, 0x43, 0x42, 0xA8, 0x15, 0x03, 0x2A};  
byte SalonC[8] ={0x28, 0xFF, 0xE0, 0x19, 0xA8, 0x15, 0x01, 0xA7};  
volatile int  TempVyhlopC = 20;
volatile int  TempEngineC = 20;
volatile int  TempUlicaC = 20;
volatile int  TempSalonC = 20;

// для организации W-BUS и различные таймеры********************
byte Zapusk20[5] = {0xF4,0x03, 0x20, 0x3B, 0xEC} ;
byte Zapusk21[5] = {0xF4,0x03, 0x21, 0x3B, 0xED} ;
byte Stop[4] = {0xF4,0x02, 0x10, 0xE6} ;

bool flagStartPresent = 1;               //флаг что отправляем в момент периодического поддержания связи W-Bus status или start
int StartMessageRepeat = 0;              //количество отправленных сообщений на старт котла
int StopMessageRepeat = 0;               //количество отправленных сообщений на остановку котла

unsigned long TimeWebasto = 1800000;   //время работы котла, 1800000 = 30мин
unsigned long EndReportMillis = 0;     //переменная для таймера отправки отчета об успешности запуска котла
unsigned long EndReportEngine = 0;     //переменная для таймера отправки отчета об успешности запуска ДВС
unsigned long Prev_PeriodW_BusMessage = 0;     //переменная для таймера периодической отправки сообщений состояния котла в шину W-Bus 
unsigned long Prev_PeriodW_BusStartStop = 0;       //переменная для таймера периодической отправки сообщений старта/стопа котла в шину W-Bus 
unsigned long prevdelSMS = 0;       //переменная для таймера периодического удаления СМС 

//для таймера  - активация котла - импульс массы 0,8 сек на провод, впаянный в таймер вебасто)
unsigned long time, timer=0;
bool timerenabled=false;
#define TIMEREXPIRED (time-timer)>800


//для таймера  - старт двигателя - импульс +5В на оптопару, в итоге минусовой импульс 1.5 сек на вход событий сигналки для запуска ДВС)
unsigned long  timerStartEng=0; bool timerenabledStartEng=false;
#define TIMEREXPIRED_StartEng (millis()-timerStartEng)>1500


//для таймера  - старт котла по W-BUS )
unsigned long timerStart_W_BUS=0; bool timerenabledStart_W_BUS=false;
#define TIMEREXPIRED_Start_W_BUS (millis()-timerStart_W_BUS)> TimeWebasto 



//ниже всё для организации ресета GSM модуля, если с ним отсутствует свзяь

unsigned long  prevReset=0;      // для таймера периодичности проверки (командой "АТ")
int intervalReset = 30;          // каждые столько мин  будет ресет
unsigned long  timerWaitOK=0;    // для таймера ожидания ответа после посылки команды "АТ"
bool timerenabledWaitOK=false;   // для таймера ожидания ответа после посылки команды "АТ"
int errors=0;                    // количество неответов  от GSM модуля
bool gsmOK = 1;                  // флаг есть свяpь с GSM модулем или нет
bool resettimer = 0;             // для таймера удерживания реле в режиме сброс питания
unsigned long  resetTimer=0;     // для таймера удерживания реле в режиме сброс питания
int ResetNumber = 0;             //количество ресетов GSM модуля для статистики (хранится в еепром)

//**************************


//Основные переменные  
bool webasto = 0;            // состояние команды на работу Webasto. 0 - котел выключен, 1 - котел включен
bool startWebasto_OK = 0;    // состояние успешного запуска котла
bool report = false;      // состояние нужности отправки отчета false - не нужно отправлять, true - нужно отправлять
bool reportEngine = false;// состояние нужности отправки отчета false - не нужно отправлять, true - нужно отправлять

bool engine =0;    //флаг работает ли ДВС или нет
bool ignition=0;   //флаг включено ли зажигание или нет
bool ohrana=0;     //флаг включена ли охрана или нет
bool trevoga=0;    //флаг включена ли тревога или нет
bool alarmSMS = 0; //флаг отправлена ли смс о тревоге или нет





// СТАРТОВЫЙ ЦИКЛ
void setup() 
{
 delay (2500);

test.NO(); 
test.pullUp();
test.duration_bounce       (  50);
test.duration_click_Db     ( 250);
test.duration_inactivity_Up(5000);
test.duration_inactivity_Dn(1000);
test.duration_press        ( 500);
test.button(17); //пин 17 (А3) тактовой кнопки вкл/выкл котла (программный номер у неё будет 0)
 
  WDTCSR=(1<<WDCE)|(1<<WDE); //для датчиков DS18B20
 
  WDTCSR=(1<<WDIE)| (1<<WDP3)|(1<<WDP0); // для датчиков DS18B20 (разрешение прерывания + выдержка 8 секунд)
  pinMode (DopOn,  INPUT);   digitalWrite (DopOn,  HIGH);
  pinMode (DopOff, INPUT);   digitalWrite (DopOff, HIGH);
  pinMode (Sost,   INPUT);   digitalWrite (Sost,   HIGH);
  pinMode (VyhodWebasto,  OUTPUT);  digitalWrite (VyhodWebasto,  HIGH);
  pinMode (VyhodWebastoAnalog,  OUTPUT);  digitalWrite (VyhodWebastoAnalog,  LOW);
  pinMode (StartEng,  OUTPUT);  digitalWrite (StartEng,  LOW);
  pinMode (StatusWebastoLED,     OUTPUT);  digitalWrite (StatusWebastoLED,     LOW);
  pinMode (ResetGSM,     OUTPUT);  digitalWrite (ResetGSM,    HIGH);
  pinMode (DTR,     OUTPUT);  digitalWrite (DTR, LOW);  // низкий уровень - для пробуждения GSM из "спячки"

  pinMode (Ohrana, INPUT);  digitalWrite (Ohrana,  HIGH);
  pinMode (Trevoga, INPUT);  digitalWrite (Trevoga,  HIGH);
  pinMode (IGN, INPUT);  digitalWrite (IGN,  HIGH);
  pinMode (Eng, INPUT);  digitalWrite (Eng,  HIGH);
  
  
Serial.begin (2400, SERIAL_8E1);   // сериал соединение протокол W-Bus

mySerial.begin(19200);           // сериал соединение для gsm модуля


    delay(2000);

  NastroykaGSM ();

TimeWebasto = EEPROM.read(1)*60000UL;
Protocol = EEPROM.read(2);
ResetNumber = EEPROM.read(0);
for (int i=0; i<12; i++) TelNumber1[i] = EEPROM.read (i+10);
for (int i=0; i<12; i++) TelNumber2[i] = EEPROM.read (i+30);

}


void loop() {
test.read();
digitalWrite (StatusWebastoLED, webasto);
//если нажали тактовую кнопку меняем состояние котла на противоположное 
if (test.event_click_Dn (StartButton)) {
  if (!webasto) {StartWebasto(); report = false;}
  else StopWebasto();
    }

if (Protocol!=2) {if (TempVyhlopC - TempUlicaC > 40) startWebasto_OK = 1;
                  else startWebasto_OK = 0;}

if (Protocol==1) webasto = !digitalRead (Sost);

if (Protocol==2) W_Bus();

//ниже для таймера старта котла по W-BUS и аналогу 
 
  if (timerenabledStart_W_BUS && TIMEREXPIRED_Start_W_BUS) StopWebasto();

//ниже для таймера создания импульса на старт ДВС 

if (timerenabledStartEng && TIMEREXPIRED_StartEng) {digitalWrite (StartEng, LOW); timerenabledStartEng=false;}
    
 engine =  !digitalRead (Eng);
 ignition= !digitalRead (IGN); 
 ohrana=   !digitalRead (Ohrana);  
 trevoga=  !digitalRead (Trevoga);
  
if (webasto && report) timerReport ();
if (reportEngine) timerReportEngine ();
if (trevoga && !alarmSMS) AlarmSMS ();
if (!ohrana) alarmSMS = false;

if (gsmOK)readSMS();
Reset_gsm();
voltmetr();
WebastoOprosImpulse ();
delSMS();


}

void voltmetr()  //____________Цикл "Вольтметр"__измерение напряжения на выходе ИБП

{
   volt = analogRead(A7);                       // А7 аналоговый вход вольтметра
   vout = (volt * 4.92) / 1024;             
   Vpit = vout / (9950.0/(98930.0+9950.0));  // По формуле Vpit = vout / (R2/(R1+R2)) 
   if (Vpit<0.09)  Vpit=0.0;                  // Округление до нуля 
}






// Вектор прерывания для Dallas DS18B20
ISR (WDT_vect){ //вектор прерывания WD
static boolean n=0; // флаг работы: запрос температуры или её чтение
n=!n;
if (n) {ds.reset();  // сброс шины
        ds.write(0xCC);//обращение ко всем датчикам
        ds.write(0x44);// начать преобразование (без паразитного питания)  
       }
else   {ds.reset();
        ds.select(VyhlopC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempVyhlopC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта       
        TempVyhlopC = TempVyhlopC / 16;
        // получение с 2-го датчика
        ds.reset();
        ds.select(EngineC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempEngineC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта  
        TempEngineC = TempEngineC/16;
        ds.reset();
        ds.select(UlicaC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempUlicaC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта       
        TempUlicaC = TempUlicaC / 16;
        // получение с 2-го датчика
        ds.reset();
        ds.select(SalonC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempSalonC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта  
        TempSalonC = TempSalonC/16 ;
}}




                    


void StartWebasto()
{
 if (Protocol==1){ digitalWrite (VyhodWebasto, LOW); 
  timer=time; 
  timerenabled=true;}

 else if (Protocol==2||Protocol==3){
  StartMessageRepeat = 0;
  webasto = 1; digitalWrite (VyhodWebastoAnalog, HIGH);
  timerStart_W_BUS=millis();
  timerenabledStart_W_BUS = true;}

  report = true; EndReportMillis = millis();
}

void StopWebasto()
{
 if (Protocol==1){ digitalWrite (VyhodWebasto, LOW); 
  timer=time; 
  timerenabled=true;}

 else if (Protocol==2||Protocol==3){
  StopMessageRepeat = 0;
  webasto = 0; digitalWrite (VyhodWebastoAnalog, LOW);
  timerenabledStart_W_BUS = false;}
   report = false;
}




void WebastoOprosImpulse (){

// опрос допканалов от сигнализации включения/ выключение котла и таймер импульса старт/стоп котла 
  time = millis();
  if (timerenabled) {if (TIMEREXPIRED) {digitalWrite (VyhodWebasto, HIGH); timerenabled=false;}}
  else  {if (!digitalRead (DopOn)  && !webasto) {StartWebasto(); KTOreport = 1;}
         if (!digitalRead (DopOff) && webasto) StopWebasto();
         }}


// цикл таймера отправки отчета об успешности запуска котла (отчёт через 6 мин после старта)
void timerReport () {
   if(millis() - EndReportMillis > 360000UL) 
   {EndReportMillis = millis(); report = false; SMSzapros();  }} 

// цикл таймера отправки отчета об успешности запуска ДВС  (отчёт через 30сек после старта)                       
void timerReportEngine () {
   if(millis() - EndReportEngine > 30000) 
   {EndReportEngine = millis(); reportEngine = false; SMSzapros();}} 





   void NastroykaGSM () {
  digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
    delay (150);
  mySerial.print(F("AT+CMGF=1\r"));         //устанавливает текстовый режим смс-сообщения
    delay(200);
  mySerial.print(F("+IFC=1, 1\r"));       //устанавливает программный контроль потоком передачи данных
    delay(200);
  mySerial.print(F("AT+CPBS=\"SM\"\r"));    //открывает доступ к данным телефонной книги SIM-карты
    delay(200);
  mySerial.print(F("AT+GSMBUSY=1\r"));   //запрет всех входящих звонков
    delay(300);
  mySerial.print(F("AT+CNMI=1,2,2,1,0\r")); //включает оповещение о новых сообщениях
    delay(300);
  mySerial.print(F("AT+CMGDA=\"DEL ALL\"\r")); // удаляем все смс, ки
   delay(2000);
  mySerial.println(F("AT+CSCLK=1")); //включает энергосберегающий режим 
  delay(150);
  digitalWrite (DTR, HIGH); // вводим в спячку GSM модуль высоким уровнем на пине DTR
  delay(150);
  
}

void startNumber1SMS() //__________________Цикл подготовки модуля к отправке СМС-сообщений по первому номеру
{
     digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
         delay (150);
     mySerial.print(F("AT+CMGF=1\r"));
         delay(200);
     mySerial.print(F("AT+CMGS=\"")); mySerial.print(TelNumber1); mySerial.println("\""); 
         delay(400);
}

void startNumber2SMS() //__________________Цикл подготовки модуля к отправке СМС-сообщений по второму  номеру
{
      digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
         delay (150);
      mySerial.print(F("AT+CMGF=1\r"));
         delay(200);
      mySerial.print(F("AT+CMGS=\"")); mySerial.print(TelNumber2); mySerial.println(F("\"")); 
         delay(400);
}

void startBufferNumberSMS() //__________________Цикл подготовки модуля к отправке СМС-сообщений по второму  номеру
{
      digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
         delay (150);
      mySerial.print(F("AT+CMGF=1\r"));
         delay(200);
      mySerial.print(F("AT+CMGS=\"")); mySerial.print(BufferNumber); mySerial.println(F("\"")); 
         delay(400);
}

void EndSMS ()
{
   mySerial.println((char)26);                       // Команда отправки СМС
   delay(2000);
   digitalWrite (DTR, HIGH); // вводим в спячку GSM модуль 
   delay (150);
}

void delSMS ()
{
if (millis() - prevdelSMS > 7200000ul){  //раз в 2 часа 
 digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
    delay (150);
 mySerial.print(F("AT+CMGDA=\"DEL ALL\"\r")); // удаляем все смс, ки
   delay(2000);
 digitalWrite (DTR, HIGH); // вводим в спячку GSM модуль 
   delay (150);

  prevdelSMS = millis();}
}


void readSMS() //_____Цикл чтения входящих СМС-сообщений______________     
{
    if (!mySerial.available()) return;
    char currSymb = mySerial.read();
//  Serial.print (currSymb);
    if ('\r' == currSymb)
       {
         if (isStringMessage!=0&&isStringMessage!=10) //если текущая строка - SMS-сообщение, отреагируем на него соответствующим образом
                {
if (!currStr.compareTo("ZAPROS"))   { SMSzapros();}               // Передача параметров по СМС
else if (!currStr.compareTo("ZAPROSTEL"))   { SMSzaprosTEL();}               // Передача номеров телефонов пользователей по СМС



else if (!currStr.compareTo("Webasto-ON"))  { if (!webasto)  {StartWebasto ();  // если получили команду на включение и вебаста в настоящий момент выключена - включаем
                                                                              if (isStringMessage == 1) {startNumber1SMS(); KTOreport = 1;}
                                                                         else if (isStringMessage == 2) {startNumber2SMS();  KTOreport = 2;}
                                                                         mySerial.println(F("Webasto Vkluchena")); EndSMS();}
                                                                       
                                                   else                     {if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else if (isStringMessage == 2) startNumber2SMS(); 
                                                                        mySerial.println(F("Webasto uzhe vkluchena")); EndSMS();}}

                                                            
               else if (!currStr.compareTo("Webasto-OFF"))   {if (webasto){StopWebasto ();  // если получили команду на выключение и вебаста в настоящий момент включена - выключаем
                                                                              if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else  if (isStringMessage == 2) startNumber2SMS();
                                                                        mySerial.println(F("Webasto Otkluchena")); EndSMS();}


                                                     else                    {if (isStringMessage == 1) startNumber1SMS(); 
                                                                         else if (isStringMessage == 2) startNumber2SMS(); 
                                                                         mySerial.println(F("Webasto uzhe otkluchena")); EndSMS();}}          


                else if (!currStr.compareTo("Engine-ON"))  {if (!engine)  { digitalWrite (StartEng, HIGH);  timerStartEng=millis(); timerenabledStartEng=true; reportEngine = true; EndReportEngine = timerStartEng; // если получили команду на включение ДВС и он в настоящий момент выключен - включаем
                                                                              if (isStringMessage == 1) {startNumber1SMS();  KTOreport = 1;}
                                                                         else if (isStringMessage == 2) {startNumber2SMS();  KTOreport = 2;}
                                                                         mySerial.println(F("Engine Start")); EndSMS();}
                                                                       
                                                   else                     {if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else if (isStringMessage == 2) startNumber2SMS();
                                                                        mySerial.println(F("Dvigatel uzhe rabotaet")); EndSMS();}}
                                                                                 
               else if (!currStr.compareTo("Engine-OFF"))   {if (engine){ digitalWrite (StartEng, HIGH);  timerStartEng=millis(); timerenabledStartEng=true; reportEngine = false; // если получили команду на выключение ДВС и он в настоящий момент работает - выключаем
                                                                              if (isStringMessage == 1) startNumber1SMS();
                                                                        else  if (isStringMessage == 2) startNumber2SMS();
                                                                        mySerial.println(F("Dvigatel ostanovlen")); EndSMS();}


                                                     else                    {if (isStringMessage == 1) startNumber1SMS(); 
                                                                         else if (isStringMessage == 2) startNumber2SMS();
                                                                         mySerial.println(F("dvigatel uzhe ostanovlen")); EndSMS(); }}          
                                                    

               else if (!currStr.compareTo("Impulse"))   {if (!webasto) {Protocol = 1;  EEPROM.write(2,Protocol);     if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("zapusk GND_impulse")); EndSMS();}
                                                                        else  if (isStringMessage == 2) {startNumber2SMS(); mySerial.println(F("zapusk GND_impulse")); EndSMS();}}}                                                               

               else if (!currStr.compareTo("W-BUS"))   {if (!webasto) {Protocol = 2; EEPROM.write(2,Protocol);  webasto = 0;  if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("zapusk W-BUS")); EndSMS();}
                                                                        else  if (isStringMessage == 2) {startNumber2SMS(); mySerial.println(F("zapusk W_BUS")); EndSMS();}}}

               else if (!currStr.compareTo("Potenzial"))   {if (!webasto) {Protocol = 3; EEPROM.write(2,Protocol);   if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("zapusk +12V Potencial")); EndSMS();}
                                                                        else  if (isStringMessage == 2) {startNumber2SMS(); mySerial.println(F("zapusk +12V Potencial")); EndSMS();}}}

               
                else if (currStr.endsWith("min"))   {if (!webasto) {TimeWebasto = currStr.toInt()*60000UL; // для задания время цикла работы отправить сообщение вида "25 min", где 25 время работы в мин
               if (TimeWebasto>3540000UL) TimeWebasto = 3540000UL;
               if (TimeWebasto<=600000UL) TimeWebasto = 600000UL;
               EEPROM.write(1,TimeWebasto/60000UL);
                     if (isStringMessage == 1)startNumber1SMS(); 
               else  if (isStringMessage == 2) startNumber2SMS(); 
               mySerial.print(F("Webasto time: ")); mySerial.print(TimeWebasto/60000UL); mySerial.print(F("min")); EndSMS();}}
               

               else if (!currStr.compareTo("ResetNumbers"))   {if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("Phone numbers are erased")); EndSMS(); 
                                                                     
             TelNumber1 = "000000000000"; TelNumber2 = "000000000000"; for (int i=0; i<12; i++) {EEPROM.write (i+10,  TelNumber1[i]); EEPROM.write (i+30,  TelNumber2[i]); }}}

              else if (!currStr.compareTo("WriteNumber2")&& isStringMessage == 1)   { 
                SaveNumber2 = 1; startNumber1SMS(); mySerial.println(F("Otpravte lyuboye SMS s nomera2 dlya sochraneniya nomera")); EndSMS();} 

                                                                        

                                                     
               else if (!currStr.compareTo("Balance"))    SMSbalance();
            isStringMessage = 0;
                }
              else if (isStringMessage==10){ if (!currStr.compareTo("WriteNumber1"))   { TelNumber1 = BufferNumber; for (int i=0; i<12; i++) {EEPROM.write (i+10, BufferNumber[i]);}
              startNumber1SMS(); mySerial.println(F("Tel Number#1 is saving in memory"));  mySerial.print("Tel#1: ");  mySerial.println (TelNumber1); EndSMS();
              } 
                                             else if (!currStr.compareTo("ZAPROS"))   { SMSzapros();}   
                                             else if (!currStr.compareTo("ZAPROSTEL"))   { SMSzaprosTEL();}               // Передача номеров телефонов пользователей по СМС            
               isStringMessage = 0;
              
              }           



                
         else if (isStringMessage==0) {  if (TelNumber1!="000000000000" && !SaveNumber2 && TelNumber1!="яяяяяяяяяяяя"){
         
                     if (currStr.startsWith("+CMT: \""+TelNumber1)) { isStringMessage = 1; KTOzapros = 1; }   
                else if (currStr.startsWith("+CMT: \""+TelNumber2)) { isStringMessage = 2; KTOzapros = 2; }   
                else if (currStr.startsWith("+CUSD: 0,"))  //если текущая строка начинается с "+CUSD",то следующая строка является запросом баланса
                  {
                       if (KTOzapros == 1) startNumber1SMS();
                  else if (KTOzapros == 2) startNumber2SMS();
                  mySerial.print (currStr);
                  EndSMS();
                  }    
                                                }

                else if    (currStr.startsWith("+CMT:") && !SaveNumber2) { isStringMessage = 10; for (int i =0; i<12; i++) {BufferNumber[i]=currStr[i+7];}}
                else if    (currStr.startsWith("+CMT:") && SaveNumber2) { for (int i =0; i<12; i++) {BufferNumber[i]=currStr[i+7];} TelNumber2 = BufferNumber; for (int i=0; i<12; i++) {EEPROM.write (i+30, BufferNumber[i]);}
              startNumber2SMS(); mySerial.println(F("Vash nomer sochranyon kak Number#2 v pamyati!")); 
              mySerial.print(F("Tel#1: ")); mySerial.println(TelNumber1); mySerial.print(F("Tel#2: "));  mySerial.println (TelNumber2); EndSMS(); SaveNumber2 = 0; } 
              
              } 
               
        currStr = "";
      } 
 
    else if ('\n' != currSymb) { currStr += String(currSymb);}
}


void SMSzapros()
{   if (isStringMessage == 10){
 startBufferNumberSMS();

 mySerial.println (F("Tel.number#1 has been no save in memory!"));
 mySerial.println (F("For save Tel#1 send SMS command \"WriteNumber1\""));
  mySerial.print(F("Tel#1: ")); mySerial.println(TelNumber1);
  mySerial.print(F("Tel#2: ")); mySerial.println(TelNumber2); 
  }
  
  
  
  else {
  
  if (isStringMessage == 1) { startNumber1SMS();}
  else if (isStringMessage == 2) { startNumber2SMS();}
  else if (isStringMessage == 0) {if  (KTOreport == 1) startNumber1SMS();
                             else if  (KTOreport == 2) startNumber2SMS();}
        if (webasto) { mySerial.println (F("Webasto ON"));
           if (startWebasto_OK) mySerial.println (F("StartWebasto OK"));
           else mySerial.println (F("StartWebasto FAIL"));}
     else mySerial.println (F("Webasto OFF"));  

     if (engine)  mySerial.println (F("Engine ON"));
     else mySerial.println (F("Engine OFF"));  

     if (ignition)  mySerial.println (F("IGN ON"));
     else mySerial.println (F("IGN OFF"));  

     if (ohrana)  mySerial.println (F("OHRANA ON"));
     else mySerial.println (F("OHRANA OFF"));  

     if (trevoga)  mySerial.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
     
  mySerial.print(F("Battery: ")); mySerial.print (Vpit); mySerial.println(F("V"));
  mySerial.print(F("Engine: ")); mySerial.print (TempEngineC); mySerial.println(F("*C"));
  mySerial.print(F("Vyhlop: ")); mySerial.print (TempVyhlopC); mySerial.println(F("*C"));
  mySerial.print(F("Ulica: ")); mySerial.print (TempUlicaC); mySerial.println(F("*C"));
  mySerial.print(F("Salon: ")); mySerial.print (TempSalonC); mySerial.println(F("*C"));  
  mySerial.print(F("Protocol: "));
       if (Protocol==1) mySerial.println(F("GND Impulse"));
  else if (Protocol==2) mySerial.println(F("W-BUS"));
  else if (Protocol==3) mySerial.println(F("+12V Potencial"));
  if (Protocol!=1) {mySerial.print(F("Webasto Time: ")); mySerial.print (TimeWebasto/60000UL); mySerial.println(F("min"));}
  mySerial.print(F("GSM Resets: ")); mySerial.println (ResetNumber); 
 
  }  
   EndSMS();                                 
}

void SMSzaprosTEL(){
  if (isStringMessage == 1) { startNumber1SMS();}
  else if (isStringMessage == 2) { startNumber2SMS();}
  else if (isStringMessage == 10) { startBufferNumberSMS();}
  
  
  mySerial.print(F("Tel#1: ")); mySerial.println(TelNumber1);
  mySerial.print(F("Tel#2: ")); mySerial.println(TelNumber2); 
  if (TelNumber1!="000000000000" && TelNumber1!="яяяяяяяяяяяя"){
  mySerial.print(F("Protocol: "));
  if (Protocol==1) mySerial.println(F("GND Impulse"));
  else if (Protocol==2) mySerial.println(F("W-BUS"));
  else if (Protocol==3) mySerial.println(F("+12V Potencial"));
  mySerial.print(F("Webasto Time: ")); mySerial.print (TimeWebasto/60000UL); mySerial.println(F("min"));
  mySerial.print(F("Resets: ")); mySerial.println (ResetNumber); 
  }
  EndSMS();                                 
  }


void SMSbalance() {
digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
      delay (150);
mySerial.print(F("AT+CMGF=1\r"));
      delay(200);
mySerial.println (F("AT+CUSD=1,\"#100#\""));    // команда на замену на транслит *111*6*2# у МТС 
      delay(2000);  
digitalWrite (DTR, HIGH); // вводим в спячку GSM модуль 
      delay (150);  
                             
     
}


void AlarmSMS() {
 
 startNumber1SMS();
mySerial.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
 EndSMS();      
 startNumber2SMS();
mySerial.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
 EndSMS();      
 alarmSMS = true;
}

void W_Bus (){
if (webasto) {
    if (StartMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800)){

 for (int i = 0; i<5; i++) Serial.write (Zapusk21[i]); 
  StartMessageRepeat++; 
  Prev_PeriodW_BusStartStop = millis();
  
    }
  if (StartMessageRepeat>=4){ if (millis()-Prev_PeriodW_BusMessage>5000)  {
    //делаем периодическое поддержание связи W-BUS
    // наверное сканает отправка сообщения о состоянии котла
    // т.е. ,например, отправляем периодически запрос на показания датчиков
    // состоянием работы котла будет наличие или отсутствие пламени
if (flagStartPresent) {for (int i = 0; i<5; i++) Serial.write (Zapusk21[i]); }
//else {for (int i = 0; i<5; i++) Serial.write (StateMessage[i]);}
flagStartPresent = !flagStartPresent;
StopMessageRepeat = 0;
    
    Prev_PeriodW_BusMessage = millis();
    }}}





else if (StopMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800)){
  for (int i = 0; i<4; i++) Serial.write (Stop[i]); 
StopMessageRepeat++; 
StartMessageRepeat = 0;
   Prev_PeriodW_BusStartStop = millis();
  
  
  }

}



void Reset_gsm (){
  if (millis()-prevReset>(unsigned long)intervalReset*60000UL){
  digitalWrite (DTR, LOW); delay (130);
  mySerial.println (F("AT")); 
  timerenabledWaitOK = 1; timerWaitOK = millis();
  gsmOK= false;
  prevReset = millis(); }

if (timerenabledWaitOK && millis()-timerWaitOK>6000) {
    timerenabledWaitOK = 0;
    if (!gsmOK) {
      mySerial.println (F("AT")); timerenabledWaitOK = 1; timerWaitOK = millis();
      errors++; if (errors>5) errors = 5; 
      
      }
}

  
 if (!gsmOK)  { 
  if (mySerial.available()>0){                                   
    char currSymb = mySerial.read();                           
    if ('\r' == currSymb) {                                      
                                  
       if (!currStr.compareTo("OK")) {   gsmOK = true;  timerenabledWaitOK = 0; errors=0; digitalWrite (DTR, HIGH);}
       currStr = "";                                           
    }
    
    else if ('\n' != currSymb) {currStr += String(currSymb);}}}
    
    
    if (errors>=5) Reset();
    
    }

 void Reset(){
     
      if (!resettimer) {digitalWrite (ResetGSM, 0); resettimer = 1; resetTimer = millis();} 
else if (millis()- resetTimer>6000 ) {
digitalWrite (ResetGSM, 1); 
resettimer = 0; 
errors=0; 
ResetNumber++; 
EEPROM.write (0, ResetNumber);
delay (3000); NastroykaGSM ();}
           
      
      
      }

Принципиальную схему и плату устройства в сообщении #142 исправил. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

щас проверил скетч v2.4.1 Sim800 засыпает как положено. При отправке АТ команд арудиной SIM800 просыпается, всё гуд. СМС ки принимаются и отправляются. Энергосбережение SIM800 работает! Вместо 5мА модуль потребляет менее 1мА (это всё по линии 12В). 

MaksVV
Offline
Зарегистрирован: 06.08.2015

интересно также, что для делителя напряжения  (с пина А5 на DTR) нужно брать на один порядок больше номиналы плеч. А то с пина A5 через делитель ток аж 1,5 мА понапрасну течет. 

Берем плечи 10К и 20К тогда делитель ничего потреблять не будет! 

MaksVV
Offline
Зарегистрирован: 06.08.2015

uu5jhu пишет:
Мой DC-DC при подключении 13,6В без нагрузки кушает 12мА (настроен на 4,1В на выход)

Сейчас замерил потребление с такого DC-DC без нагрузки (ничего к нему не подллючено).  Он почти ничего не потребляет (0,5мА). Как у вас могло 12мА получится? (правда может потому что DC-DC отличается). 

Настроил DC-DC на 3.3В подключил на контакт VCC  Arduino PRO Mini 8MHz 3.3v правда Atmega 168 (328 нет у меня) , загрузил пустой скетч. Потребление составило 3.9мА!!! и это я ещё стаб не откусывал. 

Настроил на DC-DC 4.1В и, рискнув, подал на VCC, всё гуд - ардуина робит (номинал у неё 3.3V но МК то до 5В рачитан), стаб встроенный не греется, хотя с чего бы ему греться. Потребление при 4.1V составило 7.1мА - хороший показатель, однако. Короче всю конструкцию можно при этом в 8...9мА уложить (добавиться потребление Sim800 пусть 1мА, всякие оптопары, делители напряжения, и K-line).

Нужно попробовать ещё Powerled убрать и стаб, тогда вообще шикарно будет: 

C откушенным PowerLed DC-DC 4,1V на VCC Pro Mini 8Mhz :  6,2мА

Откусил PowerLed и встроенный стаб DC-DC 4,1V на VCC Pro Mini 8Mhz :  3,8мА 

и попробовал на номанальном питании дуни:

Откусил PowerLed и встроенный стаб DC-DC 3,3V на VCC Pro Mini 8Mhz :  2,2мА!!!! 

 

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Да результаты измерений Ваших приятно радуют - хорошее дополнение к хорошей конструкции. На днях помучаю ещё свой вариант.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Нарисовал плату под Arduino Pro Mini. Только смотрите - они немного разные бывают по расположению некоорых пинов (которые А4, А5 и т.д.). Плата сделана вот под такую про мини

Размеры платы изменил для такого корпуса

Для уменьшения энергопотребления на про мини отрываем PowerLED и встроенный стабилизатор питания (Vin мы не используем).

Про мини в принципе можно использовать как 8 Mhz 3.3V так и 16Mhz 5V. Питать будем 4.1V поэтому и та и та будет работать. По идее 8Mhz в плане тока поэкономичнее должна быть. Но чип обязательно 328, на 168 не влезет скетч. 

Плата v6 для Pro Mini

Скетч v3.0

#include <EEPROM.h>
#include <Button.h>

Button test;

// для GSM модуля *********************
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); //Rx, Tx
//#define mySerial Serial 
String currStr = "";

String TelNumber1 = "000000000000";

String TelNumber2 = "000000000000";

String BufferNumber = "000000000000";

bool SaveNumber2 = 0;  // флаг когда необходима запись номера#2, он true

int isStringMessage = 0; 
int KTOzapros = 0;
int KTOreport = 1;
//************************


int Protocol = 1; // протокол, по которому будет происходить выход на запуск котла: 1 - импульсный минусовой выход (на впайку в таймер вебасто например)
                  // 2 - по протоколу W-BUS ( котлы TermoTOP EVO)
                  // 3 - по подаче потенциала 12В, т.е. пока висит +12В - котел включен (котлы по аналогу - TermoTOP C,E)

                  
//_______Все для цикла void voltmetr()*************
float vout = 0.0;      // Напряжение на входе аналового входа
float Vpit = 0.0;      // Измеряемое напряжение на выходе ИБП
  int volt = 0;        // Напряжение на входе АЦП

// входы выходы на соостветствующие пины **************
#define DopOn 4      // сюда доп канал от сигналки на включение вебасто
#define DopOff  5    // сюда доп канал от сигналки на выключение вебасто
#define VyhodWebasto  19     // (A5) это импульсный минусовой выход вкл/выкл вебасто к таймеру. 
#define VyhodWebastoAnalog  3  // это потенциальный плюсовой выход вкл/выкл вебасто (напрямую к котлу без таймера). 
#define Sost  9      // Сюда состояние вебасто (+12В когда работает)

#define Ohrana  6      // Сюда состояние охраны сигналки
#define Trevoga  7      // Сюда состояние тревоги
#define StartEng 18   // (A4) это импульсный минусовой выход вкл/выкл ДВС. подключать на вход событий сиги.
#define IGN 8       // Сюда состояние зажигания
#define Eng 14       // (А0) Сюда состояние работы ДВС
#define ResetGSM 12       // пин ресета GSM подключен к реле, разрывающее питание модуля. 
#define StartButton 0       // программный номер тактовой кнопки вкл/выкл котла 
#define StatusWebastoLED 15  //(А1) пин LED  индикация включенности котла
#define DTR 17  // пин (А3), управляющий энергосберегающим режимом GSM модуля





// для шины 1-wire и датчиков DS18B20****************

#include <OneWire.h> // библиотека для DS18B20
OneWire ds(2); // датчики DS18B20 на 2 пин

byte VyhlopC[8] ={0x28, 0xFF, 0xE6, 0x14, 0x90, 0x15, 0x04, 0x62}; 
byte EngineC[8] ={0x28, 0xFF, 0x06, 0x15, 0x90, 0x15, 0x04, 0x37}; 
byte UlicaC[8] ={0x28, 0xFF, 0x43, 0x42, 0xA8, 0x15, 0x03, 0x2A};  
byte SalonC[8] ={0x28, 0xFF, 0xE0, 0x19, 0xA8, 0x15, 0x01, 0xA7};  
volatile int  TempVyhlopC = 20;
volatile int  TempEngineC = 20;
volatile int  TempUlicaC = 20;
volatile int  TempSalonC = 20;

// для организации W-BUS и различные таймеры********************
byte Zapusk20[5] = {0xF4,0x03, 0x20, 0x3B, 0xEC} ;
byte Zapusk21[5] = {0xF4,0x03, 0x21, 0x3B, 0xED} ;
byte Stop[4] = {0xF4,0x02, 0x10, 0xE6} ;

bool flagStartPresent = 1;               //флаг что отправляем в момент периодического поддержания связи W-Bus status или start
int StartMessageRepeat = 0;              //количество отправленных сообщений на старт котла
int StopMessageRepeat = 0;               //количество отправленных сообщений на остановку котла

unsigned long TimeWebasto = 1800000;   //время работы котла, 1800000 = 30мин
unsigned long EndReportMillis = 0;     //переменная для таймера отправки отчета об успешности запуска котла
unsigned long EndReportEngine = 0;     //переменная для таймера отправки отчета об успешности запуска ДВС
unsigned long Prev_PeriodW_BusMessage = 0;     //переменная для таймера периодической отправки сообщений состояния котла в шину W-Bus 
unsigned long Prev_PeriodW_BusStartStop = 0;       //переменная для таймера периодической отправки сообщений старта/стопа котла в шину W-Bus 
unsigned long prevdelSMS = 0;       //переменная для таймера периодического удаления СМС 
unsigned long prevVpit = 0;       //переменная для таймера периодического измерения напряжения АКБ

//для таймера  - активация котла - импульс массы 0,8 сек на провод, впаянный в таймер вебасто)
unsigned long time, timer=0;
bool timerenabled=false;
#define TIMEREXPIRED (time-timer)>800


//для таймера  - старт двигателя - импульс +5В на оптопару, в итоге минусовой импульс 1.5 сек на вход событий сигналки для запуска ДВС)
unsigned long  timerStartEng=0; bool timerenabledStartEng=false;
#define TIMEREXPIRED_StartEng (millis()-timerStartEng)>1500


//для таймера  - старт котла по W-BUS )
unsigned long timerStart_W_BUS=0; bool timerenabledStart_W_BUS=false;
#define TIMEREXPIRED_Start_W_BUS (millis()-timerStart_W_BUS)> TimeWebasto 



//ниже всё для организации ресета GSM модуля, если с ним отсутствует свзяь

unsigned long  prevReset=0;      // для таймера периодичности проверки (командой "АТ")
int intervalReset = 30;          // каждые столько мин  будет ресет
unsigned long  timerWaitOK=0;    // для таймера ожидания ответа после посылки команды "АТ"
bool timerenabledWaitOK=false;   // для таймера ожидания ответа после посылки команды "АТ"
int errors=0;                    // количество неответов  от GSM модуля
bool gsmOK = 1;                  // флаг есть свяpь с GSM модулем или нет
bool resettimer = 0;             // для таймера удерживания реле в режиме сброс питания
unsigned long  resetTimer=0;     // для таймера удерживания реле в режиме сброс питания
int ResetNumber = 0;             //количество ресетов GSM модуля для статистики (хранится в еепром)

//**************************


//Основные переменные  
bool webasto = 0;            // состояние команды на работу Webasto. 0 - котел выключен, 1 - котел включен
bool startWebasto_OK = 0;    // состояние успешного запуска котла
bool report = false;      // состояние нужности отправки отчета false - не нужно отправлять, true - нужно отправлять
bool reportEngine = false;// состояние нужности отправки отчета false - не нужно отправлять, true - нужно отправлять

bool engine =0;    //флаг работает ли ДВС или нет
bool ignition=0;   //флаг включено ли зажигание или нет
bool ohrana=0;     //флаг включена ли охрана или нет
bool trevoga=0;    //флаг включена ли тревога или нет
bool alarmSMS = 0; //флаг отправлена ли смс о тревоге или нет





// СТАРТОВЫЙ ЦИКЛ
void setup() 
{
 delay (2500);

test.NO(); 
test.pullUp();
test.duration_bounce       (  50);
test.duration_click_Db     ( 250);
test.duration_inactivity_Up(5000);
test.duration_inactivity_Dn(1000);
test.duration_press        ( 500);
test.button(16); //пин 16 (А2) тактовой кнопки вкл/выкл котла (программный номер у неё будет 0)
 
  WDTCSR=(1<<WDCE)|(1<<WDE); //для датчиков DS18B20
 
  WDTCSR=(1<<WDIE)| (1<<WDP3)|(1<<WDP0); // для датчиков DS18B20 (разрешение прерывания + выдержка 8 секунд)
  pinMode (DopOn,  INPUT);   digitalWrite (DopOn,  HIGH);
  pinMode (DopOff, INPUT);   digitalWrite (DopOff, HIGH);
  pinMode (Sost,   INPUT);   digitalWrite (Sost,   HIGH);
  pinMode (VyhodWebasto,  OUTPUT);  digitalWrite (VyhodWebasto,  HIGH);
  pinMode (VyhodWebastoAnalog,  OUTPUT);  digitalWrite (VyhodWebastoAnalog,  LOW);
  pinMode (StartEng,  OUTPUT);  digitalWrite (StartEng,  LOW);
  pinMode (13,     OUTPUT);  digitalWrite (13,     LOW);
  pinMode (StatusWebastoLED,     OUTPUT);  digitalWrite (StatusWebastoLED,     LOW);
  pinMode (ResetGSM,     OUTPUT);  digitalWrite (ResetGSM,    HIGH);
  pinMode (DTR,     OUTPUT);  digitalWrite (DTR, HIGH);  // низкий уровень - для пробуждения GSM из "спячки"

  pinMode (Ohrana, INPUT);  digitalWrite (Ohrana,  HIGH);
  pinMode (Trevoga, INPUT);  digitalWrite (Trevoga,  HIGH);
  pinMode (IGN, INPUT);  digitalWrite (IGN,  HIGH);
  pinMode (Eng, INPUT);  digitalWrite (Eng,  HIGH);
  
  
Serial.begin (2400, SERIAL_8E1);  // сериал соединение протокол W-Bus

mySerial.begin(19200);           // сериал соединение для gsm модуля


    delay(2000);

  NastroykaGSM ();

TimeWebasto = EEPROM.read(1)*60000UL;
Protocol = EEPROM.read(2);
ResetNumber = EEPROM.read(0);
for (int i=0; i<12; i++) TelNumber1[i] = EEPROM.read (i+10);
for (int i=0; i<12; i++) TelNumber2[i] = EEPROM.read (i+30);

}


void loop() {
test.read();
digitalWrite (StatusWebastoLED, webasto);
//если нажали тактовую кнопку меняем состояние котла на противоположное 
if (test.event_click_Dn (StartButton)) {
  if (!webasto) {StartWebasto(); report = false;}
  else StopWebasto();
    }

if (Protocol!=2) {if (TempVyhlopC - TempUlicaC > 40) startWebasto_OK = 1;
                  else startWebasto_OK = 0;}

if (Protocol==1) webasto = !digitalRead (Sost);

if (Protocol==2) W_Bus();

//ниже для таймера старта котла по W-BUS и аналогу 
 
  if (timerenabledStart_W_BUS && TIMEREXPIRED_Start_W_BUS) StopWebasto();

//ниже для таймера создания импульса на старт ДВС 

if (timerenabledStartEng && TIMEREXPIRED_StartEng) {digitalWrite (StartEng, LOW); timerenabledStartEng=false;}
    
 engine =  !digitalRead (Eng);
 ignition= !digitalRead (IGN); 
 ohrana=   !digitalRead (Ohrana);  
 trevoga=  !digitalRead (Trevoga);
  
if (webasto && report) timerReport ();
if (reportEngine) timerReportEngine ();
if (trevoga && !alarmSMS) AlarmSMS ();
if (!ohrana) alarmSMS = false;

if (gsmOK)readSMS();
Reset_gsm();
voltmetr();
WebastoOprosImpulse ();
delSMS();


}

void voltmetr()  //____________Цикл "Вольтметр"__измерение напряжения на выходе ИБП

{if (millis()-prevVpit>10000){
   volt = analogRead(A7);                       // А7 аналоговый вход вольтметра
   vout = (volt * 4.92) / 1024;             
   Vpit = vout / (9700.0/(98930.0+9700.0));  // По формуле Vpit = vout / (R2/(R1+R2)) 
   if (Vpit<0.09)  Vpit=0.0;                  // Округление до нуля 
   prevVpit=millis();
}}






// Вектор прерывания для Dallas DS18B20
ISR (WDT_vect){ //вектор прерывания WD
static boolean n=0; // флаг работы: запрос температуры или её чтение
n=!n;
if (n) {ds.reset();  // сброс шины
        ds.write(0xCC);//обращение ко всем датчикам
        ds.write(0x44);// начать преобразование (без паразитного питания)  
       }
else   {ds.reset();
        ds.select(VyhlopC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempVyhlopC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта       
        TempVyhlopC = TempVyhlopC / 16;
        // получение с 2-го датчика
        ds.reset();
        ds.select(EngineC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempEngineC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта  
        TempEngineC = TempEngineC/16;
        ds.reset();
        ds.select(UlicaC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempUlicaC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта       
        TempUlicaC = TempUlicaC / 16;
        // получение с 2-го датчика
        ds.reset();
        ds.select(SalonC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempSalonC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта  
        TempSalonC = TempSalonC/16 ;
}}




                    


void StartWebasto()
{
 if (Protocol==1){ digitalWrite (VyhodWebasto, LOW); 
  timer=time; 
  timerenabled=true;}

 else if (Protocol==2||Protocol==3){
  StartMessageRepeat = 0;
  webasto = 1; digitalWrite (VyhodWebastoAnalog, HIGH);
  timerStart_W_BUS=millis();
  timerenabledStart_W_BUS = true;}

  report = true; EndReportMillis = millis();
}

void StopWebasto()
{
 if (Protocol==1){ digitalWrite (VyhodWebasto, LOW); 
  timer=time; 
  timerenabled=true;}

 else if (Protocol==2||Protocol==3){
  StopMessageRepeat = 0;
  webasto = 0; digitalWrite (VyhodWebastoAnalog, LOW);
  timerenabledStart_W_BUS = false;}
   report = false;
}




void WebastoOprosImpulse (){

// опрос допканалов от сигнализации включения/ выключение котла и таймер импульса старт/стоп котла 
  time = millis();
  if (timerenabled) {if (TIMEREXPIRED) {digitalWrite (VyhodWebasto, HIGH); timerenabled=false;}}
  else  {if (!digitalRead (DopOn)  && !webasto) {StartWebasto(); KTOreport = 1;}
         if (!digitalRead (DopOff) && webasto) StopWebasto();
         }}


// цикл таймера отправки отчета об успешности запуска котла (отчёт через 6 мин после старта)
void timerReport () {
   if(millis() - EndReportMillis > 360000UL) 
   {EndReportMillis = millis(); report = false; SMSzapros();  }} 

// цикл таймера отправки отчета об успешности запуска ДВС  (отчёт через 30сек после старта)                       
void timerReportEngine () {
   if(millis() - EndReportEngine > 30000) 
   {EndReportEngine = millis(); reportEngine = false; SMSzapros();}} 





   void NastroykaGSM () {
  mySerial.println(F("AT+CSCLK=1")); //включает энергосберегающий режим 
    delay(200);
  digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
    delay (200);
  mySerial.print(F("AT+CMGF=1\r"));         //устанавливает текстовый режим смс-сообщения
    delay(200);
  mySerial.print(F("+IFC=1, 1\r"));       //устанавливает программный контроль потоком передачи данных
    delay(200);
  mySerial.print(F("AT+CPBS=\"SM\"\r"));    //открывает доступ к данным телефонной книги SIM-карты
    delay(200);
  mySerial.print(F("AT+GSMBUSY=1\r"));   //запрет всех входящих звонков
    delay(300);
  mySerial.print(F("AT+CNMI=1,2,2,1,0\r")); //включает оповещение о новых сообщениях
    delay(300);
  mySerial.print(F("AT+CMGDA=\"DEL ALL\"\r")); // удаляем все смс, ки
   delay(2000);
   digitalWrite (DTR, HIGH); // вводим в спячку GSM модуль высоким уровнем на пине DTR
  delay(150);
  
}

void startNumber1SMS() //__________________Цикл подготовки модуля к отправке СМС-сообщений по первому номеру
{
     digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
         delay (150);
     mySerial.print(F("AT+CMGF=1\r"));
         delay(200);
     mySerial.print(F("AT+CMGS=\"")); mySerial.print(TelNumber1); mySerial.println("\""); 
         delay(400);
}

void startNumber2SMS() //__________________Цикл подготовки модуля к отправке СМС-сообщений по второму  номеру
{
      digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
         delay (150);
      mySerial.print(F("AT+CMGF=1\r"));
         delay(200);
      mySerial.print(F("AT+CMGS=\"")); mySerial.print(TelNumber2); mySerial.println(F("\"")); 
         delay(400);
}

void startBufferNumberSMS() //__________________Цикл подготовки модуля к отправке СМС-сообщений по второму  номеру
{
      digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
         delay (150);
      mySerial.print(F("AT+CMGF=1\r"));
         delay(200);
      mySerial.print(F("AT+CMGS=\"")); mySerial.print(BufferNumber); mySerial.println(F("\"")); 
         delay(400);
}

void EndSMS ()
{
   mySerial.println((char)26);                       // Команда отправки СМС
   delay(2000);
   digitalWrite (DTR, HIGH); // вводим в спячку GSM модуль 
   delay (150);
}

void delSMS ()
{
if (millis() - prevdelSMS > 7200000ul){  //раз в 2 часа 
 digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
    delay (150);
 mySerial.print(F("AT+CMGDA=\"DEL ALL\"\r")); // удаляем все смс, ки
   delay(2000);
 digitalWrite (DTR, HIGH); // вводим в спячку GSM модуль 
   delay (150);

  prevdelSMS = millis();}
}


void readSMS() //_____Цикл чтения входящих СМС-сообщений______________     
{
    if (!mySerial.available()) return;
    char currSymb = mySerial.read();
//  Serial.print (currSymb);
    if ('\r' == currSymb)
       {
         if (isStringMessage!=0&&isStringMessage!=10) //если текущая строка - SMS-сообщение, отреагируем на него соответствующим образом
                {
if (!currStr.compareTo("ZAPROS"))   { SMSzapros();}               // Передача параметров по СМС
else if (!currStr.compareTo("ZAPROSTEL"))   { SMSzaprosTEL();}               // Передача номеров телефонов пользователей по СМС



else if (!currStr.compareTo("Webasto-ON"))  { if (!webasto)  {StartWebasto ();  // если получили команду на включение и вебаста в настоящий момент выключена - включаем
                                                                              if (isStringMessage == 1) {startNumber1SMS(); KTOreport = 1;}
                                                                         else if (isStringMessage == 2) {startNumber2SMS();  KTOreport = 2;}
                                                                         mySerial.println(F("Webasto Vkluchena")); EndSMS();}
                                                                       
                                                   else                     {if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else if (isStringMessage == 2) startNumber2SMS(); 
                                                                        mySerial.println(F("Webasto uzhe vkluchena")); EndSMS();}}

                                                            
               else if (!currStr.compareTo("Webasto-OFF"))   {if (webasto){StopWebasto ();  // если получили команду на выключение и вебаста в настоящий момент включена - выключаем
                                                                              if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else  if (isStringMessage == 2) startNumber2SMS();
                                                                        mySerial.println(F("Webasto Otkluchena")); EndSMS();}


                                                     else                    {if (isStringMessage == 1) startNumber1SMS(); 
                                                                         else if (isStringMessage == 2) startNumber2SMS(); 
                                                                         mySerial.println(F("Webasto uzhe otkluchena")); EndSMS();}}          


                else if (!currStr.compareTo("Engine-ON"))  {if (!engine)  { digitalWrite (StartEng, HIGH);  timerStartEng=millis(); timerenabledStartEng=true; reportEngine = true; EndReportEngine = timerStartEng; // если получили команду на включение ДВС и он в настоящий момент выключен - включаем
                                                                              if (isStringMessage == 1) {startNumber1SMS();  KTOreport = 1;}
                                                                         else if (isStringMessage == 2) {startNumber2SMS();  KTOreport = 2;}
                                                                         mySerial.println(F("Engine Start")); EndSMS();}
                                                                       
                                                   else                     {if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else if (isStringMessage == 2) startNumber2SMS();
                                                                        mySerial.println(F("Dvigatel uzhe rabotaet")); EndSMS();}}
                                                                                 
               else if (!currStr.compareTo("Engine-OFF"))   {if (engine){ digitalWrite (StartEng, HIGH);  timerStartEng=millis(); timerenabledStartEng=true; reportEngine = false; // если получили команду на выключение ДВС и он в настоящий момент работает - выключаем
                                                                              if (isStringMessage == 1) startNumber1SMS();
                                                                        else  if (isStringMessage == 2) startNumber2SMS();
                                                                        mySerial.println(F("Dvigatel ostanovlen")); EndSMS();}


                                                     else                    {if (isStringMessage == 1) startNumber1SMS(); 
                                                                         else if (isStringMessage == 2) startNumber2SMS();
                                                                         mySerial.println(F("dvigatel uzhe ostanovlen")); EndSMS(); }}          
                                                    

               else if (!currStr.compareTo("Impulse"))   {if (!webasto) {Protocol = 1;  EEPROM.write(2,Protocol);     if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("zapusk GND_impulse")); EndSMS();}
                                                                        else  if (isStringMessage == 2) {startNumber2SMS(); mySerial.println(F("zapusk GND_impulse")); EndSMS();}}}                                                               

               else if (!currStr.compareTo("W-BUS"))   {if (!webasto) {Protocol = 2; EEPROM.write(2,Protocol);  webasto = 0;  if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("zapusk W-BUS")); EndSMS();}
                                                                        else  if (isStringMessage == 2) {startNumber2SMS(); mySerial.println(F("zapusk W_BUS")); EndSMS();}}}

               else if (!currStr.compareTo("Potenzial"))   {if (!webasto) {Protocol = 3; EEPROM.write(2,Protocol);   if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("zapusk +12V Potencial")); EndSMS();}
                                                                        else  if (isStringMessage == 2) {startNumber2SMS(); mySerial.println(F("zapusk +12V Potencial")); EndSMS();}}}

               
                else if (currStr.endsWith("min"))   {if (!webasto) {TimeWebasto = currStr.toInt()*60000UL; // для задания время цикла работы отправить сообщение вида "25 min", где 25 время работы в мин
               if (TimeWebasto>3540000UL) TimeWebasto = 3540000UL;
               if (TimeWebasto<=600000UL) TimeWebasto = 600000UL;
               EEPROM.write(1,TimeWebasto/60000UL);
                     if (isStringMessage == 1)startNumber1SMS(); 
               else  if (isStringMessage == 2) startNumber2SMS(); 
               mySerial.print(F("Webasto time: ")); mySerial.print(TimeWebasto/60000UL); mySerial.print(F("min")); EndSMS();}}
               

               else if (!currStr.compareTo("ResetNumbers"))   {if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("Phone numbers are erased")); EndSMS(); 
                                                                     
             TelNumber1 = "000000000000"; TelNumber2 = "000000000000"; for (int i=0; i<12; i++) {EEPROM.write (i+10,  TelNumber1[i]); EEPROM.write (i+30,  TelNumber2[i]); }}}

              else if (!currStr.compareTo("WriteNumber2")&& isStringMessage == 1)   { 
                SaveNumber2 = 1; startNumber1SMS(); mySerial.println(F("Otpravte lyuboye SMS s nomera2 dlya sochraneniya nomera")); EndSMS();} 

                                                                        

                                                     
               else if (!currStr.compareTo("Balance"))    SMSbalance();
            isStringMessage = 0;
                }
              else if (isStringMessage==10){ if (!currStr.compareTo("WriteNumber1"))   { TelNumber1 = BufferNumber; for (int i=0; i<12; i++) {EEPROM.write (i+10, BufferNumber[i]);}
              startNumber1SMS(); mySerial.println(F("Tel Number#1 is saving in memory"));  mySerial.print("Tel#1: ");  mySerial.println (TelNumber1); EndSMS();
              } 
                                             else if (!currStr.compareTo("ZAPROS"))   { SMSzapros();}   
                                             else if (!currStr.compareTo("ZAPROSTEL"))   { SMSzaprosTEL();}               // Передача номеров телефонов пользователей по СМС            
               isStringMessage = 0;
              
              }           



                
         else if (isStringMessage==0) {  if (TelNumber1!="000000000000" && !SaveNumber2 && TelNumber1!="яяяяяяяяяяяя"){
         
                     if (currStr.startsWith("+CMT: \""+TelNumber1)) { isStringMessage = 1; KTOzapros = 1; }   
                else if (currStr.startsWith("+CMT: \""+TelNumber2)) { isStringMessage = 2; KTOzapros = 2; }   
                else if (currStr.startsWith("+CUSD: 0,"))  //если текущая строка начинается с "+CUSD",то следующая строка является запросом баланса
                  {
                       if (KTOzapros == 1) startNumber1SMS();
                  else if (KTOzapros == 2) startNumber2SMS();
                  mySerial.print (currStr);
                  EndSMS();
                  }    
                                                }

                else if    (currStr.startsWith("+CMT:") && !SaveNumber2) { isStringMessage = 10; for (int i =0; i<12; i++) {BufferNumber[i]=currStr[i+7];}}
                else if    (currStr.startsWith("+CMT:") && SaveNumber2) { for (int i =0; i<12; i++) {BufferNumber[i]=currStr[i+7];} TelNumber2 = BufferNumber; for (int i=0; i<12; i++) {EEPROM.write (i+30, BufferNumber[i]);}
              startNumber2SMS(); mySerial.println(F("Vash nomer sochranyon kak Number#2 v pamyati!")); 
              mySerial.print(F("Tel#1: ")); mySerial.println(TelNumber1); mySerial.print(F("Tel#2: "));  mySerial.println (TelNumber2); EndSMS(); SaveNumber2 = 0; } 
              
              } 
               
        currStr = "";
      } 
 
    else if ('\n' != currSymb) { currStr += String(currSymb);}
}


void SMSzapros()
{   if (isStringMessage == 10){
 startBufferNumberSMS();

 mySerial.println (F("Tel.number#1 has been no save in memory!"));
 mySerial.println (F("For save Tel#1 send SMS command \"WriteNumber1\""));
  mySerial.print(F("Tel#1: ")); mySerial.println(TelNumber1);
  mySerial.print(F("Tel#2: ")); mySerial.println(TelNumber2); 
  }
  
  
  
  else {
  
  if (isStringMessage == 1) { startNumber1SMS();}
  else if (isStringMessage == 2) { startNumber2SMS();}
  else if (isStringMessage == 0) {if  (KTOreport == 1) startNumber1SMS();
                             else if  (KTOreport == 2) startNumber2SMS();}
        if (webasto) { mySerial.println (F("Webasto ON"));
           if (startWebasto_OK) mySerial.println (F("StartWebasto OK"));
           else mySerial.println (F("StartWebasto FAIL"));}
     else mySerial.println (F("Webasto OFF"));  

     if (engine)  mySerial.println (F("Engine ON"));
     else mySerial.println (F("Engine OFF"));  

     if (ignition)  mySerial.println (F("IGN ON"));
     else mySerial.println (F("IGN OFF"));  

     if (ohrana)  mySerial.println (F("OHRANA ON"));
     else mySerial.println (F("OHRANA OFF"));  

     if (trevoga)  mySerial.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
     
  mySerial.print(F("Battery: ")); mySerial.print (Vpit); mySerial.println(F("V"));
  mySerial.print(F("Engine: ")); mySerial.print (TempEngineC); mySerial.println(F("*C"));
  mySerial.print(F("Vyhlop: ")); mySerial.print (TempVyhlopC); mySerial.println(F("*C"));
  mySerial.print(F("Ulica: ")); mySerial.print (TempUlicaC); mySerial.println(F("*C"));
  mySerial.print(F("Salon: ")); mySerial.print (TempSalonC); mySerial.println(F("*C"));  
  mySerial.print(F("Protocol: "));
       if (Protocol==1) mySerial.println(F("GND Impulse"));
  else if (Protocol==2) mySerial.println(F("W-BUS"));
  else if (Protocol==3) mySerial.println(F("+12V Potencial"));
  if (Protocol!=1) {mySerial.print(F("Webasto Time: ")); mySerial.print (TimeWebasto/60000UL); mySerial.println(F("min"));}
  mySerial.print(F("GSM Resets: ")); mySerial.println (ResetNumber); 
 
  }  
   EndSMS();                                 
}

void SMSzaprosTEL(){
  if (isStringMessage == 1) { startNumber1SMS();}
  else if (isStringMessage == 2) { startNumber2SMS();}
  else if (isStringMessage == 10) { startBufferNumberSMS();}
  
  
  mySerial.print(F("Tel#1: ")); mySerial.println(TelNumber1);
  mySerial.print(F("Tel#2: ")); mySerial.println(TelNumber2); 
  if (TelNumber1!="000000000000" && TelNumber1!="яяяяяяяяяяяя"){
  mySerial.print(F("Protocol: "));
  if (Protocol==1) mySerial.println(F("GND Impulse"));
  else if (Protocol==2) mySerial.println(F("W-BUS"));
  else if (Protocol==3) mySerial.println(F("+12V Potencial"));
  mySerial.print(F("Webasto Time: ")); mySerial.print (TimeWebasto/60000UL); mySerial.println(F("min"));
  mySerial.print(F("Resets: ")); mySerial.println (ResetNumber); 
  }
  EndSMS();                                 
  }


void SMSbalance() {
digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
      delay (150);
mySerial.print(F("AT+CMGF=1\r"));
      delay(200);
mySerial.println (F("AT+CUSD=1,\"#100#\""));    // команда на замену на транслит *111*6*2# у МТС 
      delay(2000);  
digitalWrite (DTR, HIGH); // вводим в спячку GSM модуль 
      delay (150);  
                             
     
}


void AlarmSMS() {
 
 startNumber1SMS();
mySerial.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
 EndSMS();      
 startNumber2SMS();
mySerial.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
 EndSMS();      
 alarmSMS = true;
}

void W_Bus (){
if (webasto) {
    if (StartMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800)){

 for (int i = 0; i<5; i++) Serial.write (Zapusk21[i]); 
  StartMessageRepeat++; 
  Prev_PeriodW_BusStartStop = millis();
  
    }
  if (StartMessageRepeat>=4){ if (millis()-Prev_PeriodW_BusMessage>5000)  {
    //делаем периодическое поддержание связи W-BUS
    // наверное сканает отправка сообщения о состоянии котла
    // т.е. ,например, отправляем периодически запрос на показания датчиков
    // состоянием работы котла будет наличие или отсутствие пламени
if (flagStartPresent) {for (int i = 0; i<5; i++) Serial.write (Zapusk21[i]); }
//else {for (int i = 0; i<5; i++) Serial.write (StateMessage[i]);}
flagStartPresent = !flagStartPresent;
StopMessageRepeat = 0;
    
    Prev_PeriodW_BusMessage = millis();
    }}}





else if (StopMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800)){
  for (int i = 0; i<4; i++) Serial.write (Stop[i]); 
StopMessageRepeat++; 
StartMessageRepeat = 0;
   Prev_PeriodW_BusStartStop = millis();
  
  
  }

}



void Reset_gsm (){
  if (millis()-prevReset>(unsigned long)intervalReset*60000UL){
  digitalWrite (DTR, LOW); delay (130);
  mySerial.println (F("AT")); 
  timerenabledWaitOK = 1; timerWaitOK = millis();
  gsmOK= false;
  prevReset = millis(); }

if (timerenabledWaitOK && millis()-timerWaitOK>6000) {
    timerenabledWaitOK = 0;
    if (!gsmOK) {
      mySerial.println (F("AT")); timerenabledWaitOK = 1; timerWaitOK = millis();
      errors++; if (errors>5) errors = 5; 
      
      }
}

  
 if (!gsmOK)  { 
  if (mySerial.available()>0){                                   
    char currSymb = mySerial.read();                           
    if ('\r' == currSymb) {                                      
                                  
       if (!currStr.compareTo("OK")) {   gsmOK = true;  timerenabledWaitOK = 0; errors=0; digitalWrite (DTR, HIGH);}
       currStr = "";                                           
    }
    
    else if ('\n' != currSymb) {currStr += String(currSymb);}}}
    
    
    if (errors>=5) Reset();
    
    }

 void Reset(){
     
      if (!resettimer) {digitalWrite (ResetGSM, 0); resettimer = 1; resetTimer = millis();} 
else if (millis()- resetTimer>6000 ) {
digitalWrite (ResetGSM, 1); 
resettimer = 0; 
errors=0; 
ResetNumber++; 
EEPROM.write (0, ResetNumber);
delay (3000); NastroykaGSM ();}
           
      
      
      }

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

вопрос к общественности, кто привык собирать какие-нибудь поделки до конца - корпус там, все дела. Планирую собрать 5...10 таких устройств друзьям и родственникам. Вопрос какие разъёмы лучше применить. Тут нужен минимум 20 pin. 

Какой лучше применить? DB-25 (от старого ком-порта) больно громоздкий. Да и выпиливать в корпусе фигурное отверстие это не моё. Тем более 10 раз. Может лучше сделать круглую дырку (сверлом то проще) и провести сквозь неё кабель, а разъём папа-мама уже на весу сделать? DB25 на весу тоже не маленкий. Покомпактнее бы. Что посоветуете, чтобы в ходу было (или на али) и не очень дорого? или такого не бывает. DVI от монитора чтоли применить, но , блин, такого кабеля с пинами-мамами вроде не бывает. 

uu5jhu
Offline
Зарегистрирован: 21.11.2017
https://ru.aliexpress.com/item/10-pcs-Mini-360-DC-DC-Buck-Converter-Step-Down-Module-Ultra-Small-Power-Supply-Module/32413014083.html?spm=a2g0v.10010108.1000013.2.76617622mzSIbA&traffic_analysisId=recommend_2088_1_-1_iswistore&scm=1007.13339.90158.0&pvid=3d583623-3b50-4b4c-9fba-913ab48b1bbe&tpp=1

Я использую вот такой DC-DC. У меня их 2 шт - поробовал подцепил второй - потребляемый ток на хх = 17мА. Странно что Ваш не потребляет  совсем.

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Попробовал скетч v2.4.1 - модуль переходит в сон - потребление теперь сосотавляет около 17мА. Но появилась проблема - отправляю смс - в ответ тишина.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Как линию DTR подключили? Нужно от А5 ардуино через делитель 10к-20к к DTR.
Внимательно читаем сообщение #175

MaksVV
Offline
Зарегистрирован: 06.08.2015

uu5jhu пишет:
поробовал подцепил второй - потребляемый ток на хх = 17мА. Странно что Ваш не потребляет  совсем.

я использую такой DC-DC

uu5jhu
Offline
Зарегистрирован: 21.11.2017

DTR подключаю через делитель 1к / 2к (я думаю пока что это не принципиально) пробовал и с делителем и без него (висит в воздухе) но с последнем скетчем смс от модуля не получаю. С первым скетчем всё ок. Может у меня что-то с модулем сим800... Дуни две - пробовал обе. По схеме так понял ничего не изменилось кроме А5 / А6 - но и оставляя эти контакты в воздухе смс не получаю почему-то. А сколько у Вас напряжение на выходе DTR - если он висит в воздухе?

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Посмотрел datasheet на микросхемы применяемые в DC-DC. Тот что используется в Вашем DC-DC конечно же предпочтительнее так как работает на повышенной частоте что не может не сказываться на общем электропотреблении.

MaksVV
Offline
Зарегистрирован: 06.08.2015

MaksVV пишет:

uu5jhu пишет:
поробовал подцепил второй - потребляемый ток на хх = 17мА. Странно что Ваш не потребляет  совсем.

я использую такой DC-DC


Притяните вручную DTR сим800 на землю на время проверки. Смс должны начать отправляться.

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Притянул через 27 Ом к земле DTR (Правда не совсем в моём случае это понятно) - напряжение на DTR 0.3В.

1. Заливаю скетч v2.1 - отправляю смс - WriteNumber1 - приходит смс с подтверждением, что номер записан.

2. Вытаскиваю дуню - заливаю скетч для чистки еепром, жду, светодиод загорелся, заливаю скетч v2.4.1 - устанавливаю в плату (сим800 более не трогаю ни в первый ни во второй ни в третий раз) - отправляю тоже самое смс - в ответ тихо! Звоню - абонент занят.......

3. Вытаскиваю дуню, очистка еепром, заливаю скетч v2.3.1 - устанавливаю дуню в плату, отправляю смс - получаю подтверждение...

4. Сижу думаю.....

uu5jhu
Offline
Зарегистрирован: 21.11.2017

По поводу разъёмов. Я в этой конструкции применил "папу" как на дуне - ответная часть (чтобы ничего не колхозить и не крамсать) с завода в машине, штекер "мама" идеально стыкуются. Ранее для других конструкций применял небольшие сборки с одной стороны под пайку (устанавливается на плату) с другой - терминал с болтиком. Сейчас быстро марку не скажу - покупал в местном радиомагазине, размеры есть разные.

uu5jhu
Offline
Зарегистрирован: 21.11.2017
MaksVV
Offline
Зарегистрирован: 06.08.2015

Не надо каждый раз чистить еепром. Один раз номер записали и все, можно разные скетчи заливать, номер не трогается при этом. Это так, к слову.

MaksVV
Offline
Зарегистрирован: 06.08.2015

uu5jhu пишет:
отправляю тоже самое смс - в ответ тихо! Звоню - абонент занят.......

... Сижу думаю.....

строку 168 скетча 2.4.1. замените на 

Serial.begin (19200);

Строку 414 раскоментируйте и смотрите в мониторе порта , как идет общение с SIM800

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Сделал. Вот что в мониторе получил на отправку смс - ZAPROS:

 
+CMT: "",25
07919781340300F0040B919787502795F500008110121235742106DA20540
 
На смс - WriteNumber:
 
+CMT: "",30
07919781340300F0040B919787502795F50000811012125594210C57799A62

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

ещё раз попробовал загрузить скетч 2.4.1. У меня всё работает. Судя по данным в мониторе как будто SIM800 не настраивается функцикей NastroykaGSM(). DTR точно к массе притянули? Можно напрямую без резистора. Только обязательно отключите от А5 ардуины, а то сгорит выход дуни!!!!  Может не тот пин подтягиваете? проверьте ещё раз.

Попробуйте также задержки увеличить до 300 в строках 338, 340, 342, 344, 352, 354

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Да уж. Просмотрел. Спасибо. Не обратил внимание что вывод RING на модуле не подписан. Сейчас посадил DTR на землю через 20к и подтянул к А5 10к - напряжение на свободном DTR было 2,3В стало 0,6В, при подаче с А5 4,2В становится 2,7В.

В моём случае ещё нужно будет увеличить задержку на инициализацию - так как снова появилась проблема, что при первой подачи питания и отправки смс модуль никак не реагирует пока не нажму на дуни Reset.

Заказал DC-DC по вашей ссылке, получу буду эксперементировать дальше.

Подскажите по новому скетчу - на смс ЗАПРОС появилась новая строчка в получаемом смс: - GSM Reset: 109 Это что он считает и как на это реагировать?

MaksVV
Offline
Зарегистрирован: 06.08.2015

uu5jhu пишет:

Подскажите по новому скетчу - на смс ЗАПРОС появилась новая строчка в получаемом смс: - GSM Reset: 109 Это что он считает и как на это реагировать?

это количество ресетов GSM модуля, если он не отвечал на команду AT , данное число записывается в еепром. Я исправил в посте #1 чистку еепром, чтобы изначально число было 0. почистите ещё раз еепром и запишите заново номер телефона. Это число станет 0 и потом будет показывать количество перезагрузок SIM800L. Сброс этого числа можно сделать от длительного нажатия на тактовую кнопку включения, например. Но я ещё этого не сделал.  

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Да всё получилось. Число стало 0. Так понял Вы убрали в смс информацию о времени работы котла?

Интересно - прямо на плате распаян один DS18D20 (аля - температура салона) - в корпусе TO-92, врёт нагло на несколько градусов....может какой-то глючный датчик.