mySerial.println("AT+CSCS=\"GSM\""); // кодировка текста - GSM
21
delay(300);
22
Serial.println("SMS to terminal:");
23
mySerial.println("AT+CNMI=2,2,0,0,0"); // вывод смс в консоль
24
delay(300);
25
26
}
27
28
voidloop()
29
{
30
if(mySerial.available()) //если модуль что-то послал
31
{
32
charch = ' ';
33
String val = "";
34
35
while(mySerial.available())
36
{
37
ch = mySerial.read();
38
val += char(ch); //собираем принятые символы в строку
39
delay(3);
40
}
41
42
Serial.print("Sim send> ");
43
Serial.println(val);
44
45
if(val.indexOf("+CMT") > -1) //если есть входящее sms
46
{
47
if(val.indexOf("On") > -1) // смотрим, что за команда
48
{
49
Serial.println("On D13");
50
digitalWrite(led, HIGH); //включаем светодиод
51
}
52
53
if(val.indexOf("Off") > -1) // смотрим, что за команда
54
{
55
digitalWrite(led, LOW); //выключаем
56
Serial.println("Off D13");
57
}
58
}
59
}
60
}
Попробовал сейчас не меняя схемы(нет ни датчиков Темп ни ОС по Напр...) залить найденный и немного изенённый скетч (тот что выше) - при получении смс (ON or OFF) светодиод переключается......
В программирование пока что нуб поэтому появилось предположение, что, возможно, нужо собрать всю схему до конца.....
Таже пробовал ещё один (так же с просторов тырнета) скетч для отправки смс с "СИМкарты webasto" - смс отправляет мне на номер с текстом.... (правда с небольшой грамматической ошибкой непонятно почему-то получаю смс)
Осталось две фичи реализовать - энергосбережение и контроль зависания и перезагрузки GSM. Всем спасибо, так активно помогаете.
У меня sim900.
Контроль делал так:
1. Раз в минуту посылаю AT. Если модуль ответил OK - хорошо, cчётчик=0. Иначе +1 к счётчику попыток.
2. Если счётчик >= 5, сбрасываю счётчик и "нажимаю" кнопку питания.
Всё работает более года.
Одно такое событие за год произошло.
В продолжении попытки получения положительного результата обнаружил что общаясь с модулем через переходник UNO с использованием PuTTY обнаружил что на команду:
AT+ICF?
Приходит сообщение об ошибки.... при этом при попытке отправить смс, оно приходит на телефон...
boolSaveNumber2 = 0; // флаг когда необходима запись номера#2, он true
014
015
intisStringMessage = 0;
016
intKTOzapros = 0;
017
intKTOreport = 1;
018
//************************
019
020
021
intProtocol = 1; // протокол, по которому будет происходить выход на запуск котла: 1 - импульсный минусовой выход (на впайку в таймер вебасто например)
022
// 2 - по протоколу W-BUS ( котлы TermoTOP EVO)
023
// 3 - по подаче потенциала 12В, т.е. пока висит +12В - котел включен (котлы по аналогу - TermoTOP C,E)
024
025
026
//_______Все для цикла void voltmetr()*************
027
floatvout = 0.0; // Напряжение на входе аналового входа
028
floatVpit = 0.0; // Измеряемое напряжение на выходе ИБП
029
intvolt = 0; // Напряжение на входе АЦП
030
031
// входы выходы на соостветствующие пины **************
032
#define DopOn 4 // сюда доп канал от сигналки на включение вебасто
033
#define DopOff 5 // сюда доп канал от сигналки на выключение вебасто
034
#define VyhodWebasto 12 // это импульсный минусовой выход вкл/выкл вебасто к таймеру.
035
#define VyhodWebastoAnalog 3 // это потенциальный плюсовой выход вкл/выкл вебасто (напрямую к котлу без таймера).
036
#define Sost 9 // Сюда состояние вебасто (+12В когда работает)
037
038
#define Ohrana 6 // Сюда состояние охраны сигналки
039
#define Trevoga 7 // Сюда состояние тревоги
040
#define StartEng 8 // это импульсный минусовой выход вкл/выкл ДВС. подключать на вход событий сиги.
041
#define IGN 10 // Сюда состояние зажигания
042
#define Eng 11 // Сюда состояние работы ДВС
043
044
045
046
047
// для шины 1-wire и датчиков DS18B20****************
if(isStringMessage!=0&&isStringMessage!=10) //если текущая строка - SMS-сообщение, отреагируем на него соответствующим образом
360
{
361
if(!currStr.compareTo("ZAPROS")) { SMSzapros();} // Передача параметров по СМС
362
elseif(!currStr.compareTo("ZAPROSTEL")) { SMSzaprosTEL();} // Передача номеров телефонов пользователей по СМС
363
364
365
366
elseif(!currStr.compareTo("Webasto-ON")) { if(!webasto) {StartWebasto (); report = true; EndReportMillis = millis(); // если получили команду на включение и вебаста в настоящий момент выключена - включаем
elseif(!currStr.compareTo("Webasto-OFF")) {if(webasto){StopWebasto (); report = false; // если получили команду на выключение и вебаста в настоящий момент включена - выключаем
elseif(!currStr.compareTo("Engine-ON")) {if(!engine) { digitalWrite (StartEng, HIGH); timerStartEng=TimeStartEng; timerenabledStartEng=true; reportEngine = true; EndReportEngine = millis(); // если получили команду на включение ДВС и он в настоящий момент выключен - включаем
elseif(!currStr.compareTo("Engine-OFF")) {if(engine){ digitalWrite (StartEng, HIGH); timerStartEng=TimeStartEng; timerenabledStartEng=true; reportEngine = false; // если получили команду на выключение ДВС и он в настоящий момент работает - выключаем
elseif(currStr.endsWith("min")) {TimeWebasto = currStr.toInt()*60000UL; // для задания время цикла работы отправить сообщение вида "25 min", где 25 время работы в мин
Когда EEprom был у вас ещё не тронутый (во всех ячейках FF),то заработало бы, если бы вы скетч заливали сразу после копипаста (без сохранения скетча на компе). При сохранении скетча на компе сбивается кодировка символов соответсвующих байту FF (который в еепроме был изначально), т.е. символа "я" и все косяки из-за этого, а потом я вам немного неправильно почистить еепром предложил, поэтому тоже не работало. Исправил в начале темы как еепром чистить до заливки скетча.
это у вас НЕ получилось, а нули написались в этом случае, потому что вы распечатку в терминал поставили до считываения тел.номера из еепром, а изначально, при старте программы, в переменную тел.номера нули записываются и вы их сразу и распечатали.
PS удалите простыню из сообщения #71, мешает . Кстати когда вставляете скетч, там вверху вкладка правая, можно галочку ставить "свернуть", чтобы под катом было.
Приветствую. Спасибо Вам огромное за проделанную работу, всё теперь получилось (пошёл покупать недостающие детали и буду собирать до конца – смс ки отправляю – в ответ приходят подтверждения и инфо о состоянии – попробовал пока только с напряжением питания) - давно занялся поиском чего-то подобного для запуска котла по смс. Об arduino узнал недавно и пока что всё в процессе начинания и изучения. Изначально была идея запускать по шине CAN (точнее сказать в моей машине по периферийной шине i-bus через приборную панель) и по CAN отслеживать и отправлять сообщение о состоянии котла, температуре ОЖ и бортовом напряжении. Но для этого, как понимаю, нужно знать протокол обмена… Но с выносными датчиками, кому не лень, тоже всё хорошо.
Готов нарисовать и выложить нарисованную схему, для тех «ленивых» кто спрашивает её, но пока не пойму как прикрепить рисунок.
По ходу макетирования появилось несколько вопросов.
1. sms на запрос баланса приходят в HEX unicode =( /лечится заменой оператора или можно программой?/
2. не знаю как на версиях Webasto которые устанавливают как доп, но на "старых" например, моделях БМВ есть несколько условий при которых котёл не будет запущен - (с завода котёл кстати, работал только как "догревайка", но перекодировка творит чудеса и теперь работает ещё и как "автономное отопление" без колхозинга) - одно из них пониженное напряжение питания (недавно у товарища попытались запустить котёл при разряженной АКБ U=11.6V) - сигнал на запуск пришел, а вот котёл не запустился пока не зарядили АКБ. И это считаю правильная задумка - зачем тёплый двигатель, если стартер не крутится. Не увидел организованно ли это в Вашей программе уважаемый автор, но возможно, это будет своим образом аварийная защита, для котлов которые будут рады усадить АКБ в ноль (если такие существуют, конечно)
Изначально была идея запускать по шине CAN (точнее сказать в моей машине по периферийной шине i-bus через приборную панель) и по CAN отслеживать и отправлять сообщение о состоянии котла, температуре ОЖ и бортовом напряжении. Но для этого, как понимаю, нужно знать протокол обмена… Но с выносными датчиками, кому не лень, тоже всё хорошо.
Я так понимаю котел у вас штатный, да к тому же по CAN управляется . Вы уверены в возможности запуска его по аналогу? Вообще чтобы по CAN запускать конечно нужно знать протокол обмена. Но исследование CAN шины тоже дело интересное, хотя и не лёгкое. Если будет интересно, могу выложить проект CAN хакера на ардуино (там собственно сама ардуино и китайский модуль кана на MCP2515), который как раз и позволяет выявить из CAN шины нужные сообщения.
Короче в будущем конечно неплохо было бы дополнить данное устройство CAN шиной, но работы с этим не мало будет, особенно в программной части - протоколы разных авто.
Я хочу допилить хотябы W-BUS, т.к. если сказать по чесноку, в данный момент организовано только включение выключение котла без опроса его реального состояния. Просто у меня нет Webasto Evo чтобы протокол W-BUS помучить.
А вы если только аналог будете использовать вам можно не ставить микруху LM393 и всю её обвязку
По ходу макетирования появилось несколько вопросов.
1. sms на запрос баланса приходят в HEX unicode =( /лечится заменой оператора или можно программой?/
2. не знаю как на версиях Webasto которые устанавливают как доп, но на "старых" например, моделях БМВ есть несколько условий при которых котёл не будет запущен - (с завода котёл кстати, работал только как "догревайка", но перекодировка творит чудеса и теперь работает ещё и как "автономное отопление" без колхозинга) - одно из них пониженное напряжение питания (недавно у товарища попытались запустить котёл при разряженной АКБ U=11.6V) - сигнал на запуск пришел, а вот котёл не запустился пока не зарядили АКБ. И это считаю правильная задумка - зачем тёплый двигатель, если стартер не крутится. Не увидел организованно ли это в Вашей программе уважаемый автор, но возможно, это будет своим образом аварийная защита, для котлов которые будут рады усадить АКБ в ноль (если такие существуют, конечно)
1. Намного проще через оператора решить. (Ну всмысле не заменой его, а подбором правильной команды запроса баланса, либо есть такая функция у некоторых перевода на транслит.) Парсить этот юникод и PDU полный песец.
2. По напряжению АКБ по идее во всех котлах есть выключение. Я не стал делать выключение по напряжению. Но это не сложно - пару строк добавить.
boolSaveNumber2 = 0; // флаг когда необходима запись номера#2, он true
018
019
intisStringMessage = 0;
020
intKTOzapros = 0;
021
intKTOreport = 1;
022
//************************
023
024
025
intProtocol = 1; // протокол, по которому будет происходить выход на запуск котла: 1 - импульсный минусовой выход (на впайку в таймер вебасто например)
026
// 2 - по протоколу W-BUS ( котлы TermoTOP EVO)
027
// 3 - по подаче потенциала 12В, т.е. пока висит +12В - котел включен (котлы по аналогу - TermoTOP C,E)
028
029
030
//_______Все для цикла void voltmetr()*************
031
floatvout = 0.0; // Напряжение на входе аналового входа
032
floatVpit = 0.0; // Измеряемое напряжение на выходе ИБП
033
intvolt = 0; // Напряжение на входе АЦП
034
035
// входы выходы на соостветствующие пины **************
036
#define DopOn 4 // сюда доп канал от сигналки на включение вебасто
037
#define DopOff 5 // сюда доп канал от сигналки на выключение вебасто
038
#define VyhodWebasto 12 // это импульсный минусовой выход вкл/выкл вебасто к таймеру.
039
#define VyhodWebastoAnalog 3 // это потенциальный плюсовой выход вкл/выкл вебасто (напрямую к котлу без таймера).
040
#define Sost 9 // Сюда состояние вебасто (+12В когда работает)
041
042
#define Ohrana 6 // Сюда состояние охраны сигналки
043
#define Trevoga 7 // Сюда состояние тревоги
044
#define StartEng 8 // это импульсный минусовой выход вкл/выкл ДВС. подключать на вход событий сиги.
045
#define IGN 10 // Сюда состояние зажигания
046
#define Eng 11 // Сюда состояние работы ДВС
047
#define ResetGSM 16 // пин ресета GSM (A2) подключен к реле, разрывающее питание модуля.
048
#define StartButton 17 // пин тактовой кнопки (А3) вкл/выкл котла
049
#define StatusWebastoLED 13 // пин индикация включенности котла
050
051
052
053
054
055
// для шины 1-wire и датчиков DS18B20****************
if(isStringMessage!=0&&isStringMessage!=10) //если текущая строка - SMS-сообщение, отреагируем на него соответствующим образом
387
{
388
if(!currStr.compareTo("ZAPROS")) { SMSzapros();} // Передача параметров по СМС
389
elseif(!currStr.compareTo("ZAPROSTEL")) { SMSzaprosTEL();} // Передача номеров телефонов пользователей по СМС
390
391
392
393
elseif(!currStr.compareTo("Webasto-ON")) { if(!webasto) {StartWebasto (); // если получили команду на включение и вебаста в настоящий момент выключена - включаем
elseif(!currStr.compareTo("Webasto-OFF")) {if(webasto){StopWebasto (); // если получили команду на выключение и вебаста в настоящий момент включена - выключаем
elseif(!currStr.compareTo("Engine-ON")) {if(!engine) { digitalWrite (StartEng, HIGH); timerStartEng=millis(); timerenabledStartEng=true; reportEngine = true; EndReportEngine = timerStartEng; // если получили команду на включение ДВС и он в настоящий момент выключен - включаем
elseif(!currStr.compareTo("Engine-OFF")) {if(engine){ digitalWrite (StartEng, HIGH); timerStartEng=millis(); timerenabledStartEng=true; reportEngine = false; // если получили команду на выключение ДВС и он в настоящий момент работает - выключаем
elseif(currStr.endsWith("min")) {TimeWebasto = currStr.toInt()*60000UL; // для задания время цикла работы отправить сообщение вида "25 min", где 25 время работы в мин
Да, совершенно верно, котёл штатный. Вопрос конечно этот самому интересен будет ли он по +12V запускаться....но скачав документацию (описание + схемы соединений) предполагаю что работать должно. В любом случае скоро узнаем и напишу здесь. Главное чтобы конфликта не было по CAN.
А по поводу использовать MCP2515 - я уже получил из Китая его именно для этих целей, так что выкладывайте прошивку CAN хакера если найду время с удовольствием посижу с ним.
Хочу собрать полную схему (с LM393) так как машины меняются а сегодня новые котлы так понимаю уже все работают по W-Bus....возможно пригодится.
на портале carhelp.info много полезного найдете на этот счет - как запускать штатные котлы. Вам нужно узнать, есть ли у вашего котла шина W-Bus, если есть, то нужно попробовать запустить диагноситку котла по этой шине оригинальной вебастовской программой WTT при помощи обычного к-лайн адаптера. Если диагностика получится, всё упрощается.
ДА, пару лет назад использовал эту программу (WTT) для ремонта своего котла - не пропаяно было хорошо одно сопротивление. На каком-то форуме писал об этом с фото.
Значит можно попробовать подключиться к шине используя Вашу схему!?
Сейчас уже схему не вспомню но кажется именно по этой шине котёл соединён с приборной панелью и имеет название i-bus а уже приборная панель с CAN шиной. То есть через диагностический разъём авто к котлу с помощью WTT не подключиться, собирал всё дома на столе и подключал.
Значит можно попробовать подключиться к шине используя Вашу схему!?
Собираете два адаптера из сообщения #84 или легче покупаете, Один для подключения WTT к котлу, второй - чтобы посниффить обмен данными. Когда узнаете какие байты там летают, можно будет запускать котёл по i-bus (полагаю тот же W-bus)
Спасибо за схему и скетч. Один адаптер есть им собственно и ковыряюсь в авто (прошивка / кодировка блоков) второго нет, попробую купить.... Китай совсем обленил увы, да и часто получается что проще и Дешевле купить готовое устройство чем собирать в одном экземпляре. Исключение составляет - хобби.
Почти закончил собирать плату. Пока провожу эксперименты на столе, надеюсь скоро начнуться полевые испытания!
Если позволите ещё один момент замечен при проверке.
Всё прекрасно работает (смс команды) пока не отключить питание. После повторного включения питания и спустя даже 10 минут устройство никак не реагирует на смс команды пока не нажать кнопку Reset на Nano. После этого снова начинает всё работать.
И ещё подскажите в какую строку и что добавить чтобы в мониторе порта увидеть напряжение АКБ (исключительно для настройки) ? Понижающий DC-DC отличается от Вашего и шунтирует входным сопротивлением делитель напряжения. Вместо 13,70 приходит в смс 12,65. Хочу подобрать подстроичником, но каждый раз отправлять смс.......
вот здесь 4,92 это напряжение питания на ардуино, реальное измеренное вольтметром , 9950 это реальное измеренное сопротивление плеча 10К делителя напряжения, 98930 - это реальное измеренное сопротивление плеча 100К делителя напряжения. Измерьте и подставьте свои данные, должно быть ближе к правде. Если после этого отличается от реального напряжения, корректируйте ещё значение сопротивлений.
Скетч для настройки вольтаметра с выводом в терминал.
Всё прекрасно работает (смс команды) пока не отключить питание. После повторного включения питания и спустя даже 10 минут устройство никак не реагирует на смс команды пока не нажать кнопку Reset на Nano. После этого снова начинает всё работать.
вот тут хз, у меня тоже так было на одной ардуино (от robotdyn ), на другой все норм. надо пробовать на другом МК. попробуйте в Setup строка 115 задержку на 6...7 секунд повысить
Приветствую. Спасибо за скетч - подобрал в программе величинами сопротивлений значение напряжения. Про делитель напряжения как бы всё понятно, но как ранее заметил что DC-DC шунтирует этот делитель и показывает "погоду" вместо напряжения. (Если запитать DC-DC от отдельного источника то проблем нет). В общем сейчас всё хорошо (значения в программе кстати получились далеки от истины).
Появилось время и добрался до авто. Идёт с фишки от котла три провода - один на насос, второй на i-BUS (CAN) и третий на таймер (точнее сказать на связку Telestart + timer) которого нет но можно дооснастить. На схеме этот провод идёт на квадратную фишку таймера на контакт "OUT". Отсюда появился вопрос - по какому протоколу работает связка таймер-котёл? Если W-Bus то можно попробовать подключить выход с Вашей конструкции на этот провод!?
А Подозреваю что на проводе OUT должен быть просто потенциал 12в при включении. Но если даже там цифра, мой вариант может и подойдет. По крайней мере так включали некоторые штатные котлы. Машина то какая?
MaksVV,
1. Получилось сделать контроль зависаний? Я писал выше #63
2. все возможности по энергосбережению в микроконтроллере AVR описаны тут https://www.gammon.com.au/power
спасибо по ссылке почитаю. Контроль зависаний попытался сделать. Добавил в скетч (сообщение #82). Нарисовал новую плату с реле. Т.е. питание GSM сидит на нормально-замкнутых контактах реле. При рестарте подается питание на реле и оно размыкает питание GSM. Но это только пробная версия, ещё ничего не проверял. Т.к. нет времени и детали ещё не дошли.
реле между контактами gsm модуля. Если gsm модуль на панельки устанавливать, то он высоко сидит, туда это реле по идее влезть должно, судя по его размерам.
01
#include <SoftwareSerial.h>
02
SoftwareSerial mySerial(14, 15);
03
04
byte
led = 13;
05
06
void
setup
() {
07
delay(2000);
08
pinMode(led, OUTPUT);
09
digitalWrite(led, LOW);
10
Serial
.begin(9600);
11
mySerial.begin(9600);
12
Serial
.println();
13
Serial
.println(
"Turn on AOH:"
);
14
mySerial.println(
"AT+CLIP=1"
);
//включить АОН
15
delay(300);
16
Serial
.println(
"Text format sms:"
);
17
mySerial.println(
"AT+CMGF=1"
);
// текстовый формат SMS
18
delay(300);
19
Serial
.println(
"Mode GSM:"
);
20
mySerial.println(
"AT+CSCS=\"GSM\""
);
// кодировка текста - GSM
21
delay(300);
22
Serial
.println(
"SMS to terminal:"
);
23
mySerial.println(
"AT+CNMI=2,2,0,0,0"
);
// вывод смс в консоль
24
delay(300);
25
26
}
27
28
void
loop
()
29
{
30
if
(mySerial.available())
//если модуль что-то послал
31
{
32
char
ch =
' '
;
33
String val =
""
;
34
35
while
(mySerial.available())
36
{
37
ch = mySerial.read();
38
val +=
char
(ch);
//собираем принятые символы в строку
39
delay(3);
40
}
41
42
Serial
.print(
"Sim send> "
);
43
Serial
.println(val);
44
45
if
(val.indexOf(
"+CMT"
) > -1)
//если есть входящее sms
46
{
47
if
(val.indexOf(
"On"
) > -1)
// смотрим, что за команда
48
{
49
Serial
.println(
"On D13"
);
50
digitalWrite(led, HIGH);
//включаем светодиод
51
}
52
53
if
(val.indexOf(
"Off"
) > -1)
// смотрим, что за команда
54
{
55
digitalWrite(led, LOW);
//выключаем
56
Serial
.println(
"Off D13"
);
57
}
58
}
59
}
60
}
Попробовал сейчас не меняя схемы(нет ни датчиков Темп ни ОС по Напр...) залить найденный и немного изенённый скетч (тот что выше) - при получении смс (ON or OFF) светодиод переключается......
В программирование пока что нуб поэтому появилось предположение, что, возможно, нужо собрать всю схему до конца.....
такой скетч попробуйте, если не работает, проблема в аппартаной части. СМС нужно слать с текстом ON или OFF , управляем встроенным светодиодом.
01
#include <SoftwareSerial.h>
02
03
SoftwareSerial gprsSerial(14, 15);
04
05
//для зелёного светодиода будем использовать второй цифровой вход,
06
//а для жёлтого - третий
07
08
09
void
setup
()
10
{
11
gprsSerial.begin(19200);
12
pinMode(13, OUTPUT);
13
digitalWrite (13, 0);
14
15
16
// Настраиваем приём сообщений с других устройств
17
// Между командами даём время на их обработку
18
gprsSerial.print(
"AT+CMGF=1\r"
);
19
delay(300);
20
gprsSerial.print(
"AT+IFC=1, 1\r"
);
21
delay(300);
22
gprsSerial.print(
"AT+CPBS=\"SM\"\r"
);
23
delay(300);
24
gprsSerial.print(
"AT+CNMI=1,2,2,1,0\r"
);
25
delay(500);
26
}
27
28
String currStr =
""
;
29
// Переменная принимает значение True, если текущая строка является сообщением
30
boolean isStringMessage =
false
;
31
32
void
loop
()
33
{
34
if
(!gprsSerial.available())
35
return
;
36
37
char
currSymb = gprsSerial.read();
38
if
(
'\r'
== currSymb) {
39
if
(isStringMessage) {
40
//если текущая строка - SMS-сообщение,
41
//отреагируем на него соответствующим образом
42
if
(!currStr.compareTo(
"ON"
)) {
43
digitalWrite(13, HIGH);
44
}
else
if
(!currStr.compareTo(
"OFF"
)) {
45
digitalWrite(13, LOW);
46
}
47
48
isStringMessage =
false
;
49
}
else
{
50
if
(currStr.startsWith(
"+CMT"
)) {
51
//если текущая строка начинается с "+CMT",
52
//то следующая строка является сообщением
53
isStringMessage =
true
;
54
}
55
}
56
currStr =
""
;
57
}
else
if
(
'\n'
!= currSymb) {
58
currStr += String(currSymb);
59
}
60
}
эмм, не успел ответить ))
Этот Ваш скетч крайний попробовал - РАБОТАЕТ тоже! =))
ну то есть ON включает и OFF выключает светодиод!
Таже пробовал ещё один (так же с просторов тырнета) скетч для отправки смс с "СИМкарты webasto" - смс отправляет мне на номер с текстом.... (правда с небольшой грамматической ошибкой непонятно почему-то получаю смс)
попробуйте почистить еепром сначала вот этим
01
/*
02
* EEPROM Clear
03
*
04
* Sets all of the bytes of the EEPROM to 0.
05
* Please see eeprom_iteration for a more in depth
06
* look at how to traverse the EEPROM.
07
*
08
* This example code is in the public domain.
09
*/
10
11
#include <EEPROM.h>
12
13
void
setup
() {
14
// initialize the LED pin as an output.
15
pinMode(13, OUTPUT);
16
Serial
.begin (9600);
17
/***
18
Iterate through each byte of the EEPROM storage.
19
20
Larger AVR processors have larger EEPROM sizes, E.g:
21
- Arduno Duemilanove: 512b EEPROM storage.
22
- Arduino Uno: 1kb EEPROM storage.
23
- Arduino Mega: 4kb EEPROM storage.
24
25
Rather than hard-coding the length, you should use the pre-provided length function.
26
This will make your code portable to all AVR processors.
27
***/
28
29
for
(
int
i = 0 ; i < EEPROM.length() ; i++) {
30
EEPROM.write(i, 0);
31
}
32
33
// turn the LED on when we're done
34
35
36
for
(
int
i = 0 ; i < EEPROM.length() ; i++) {
37
Serial
.print (EEPROM.read(i));
Serial
.print (
" "
);
38
}
39
40
digitalWrite(13, HIGH);
41
}
42
43
void
loop
() {
44
/** Empty loop. **/
45
}
в сериал мониторе должно появиться много нулей
Подтверждаю - спустя пару сек побежали нули
залил снова после чистки v2.1 - ничего увы не поменялось.....ответное смс на WriteNumber1 не получаю
недавно собрал пару модулей, всё работало, соберу ещё один, найду косяк, отпишусь
Может проблема из-за нестыковки уровней Rx Tx или скорости !? Но со светодиодом работает. А вот смс с СИМ получаю hello @ord вместо hello world.....
ОК. Будет интересно. Хочу пристроить модуль к своему котлу - Thermo Top С...... запускать думаю сигналом +12В на 30 минут.
Осталось две фичи реализовать - энергосбережение и контроль зависания и перезагрузки GSM. Всем спасибо, так активно помогаете.
У меня sim900.
Контроль делал так:
1. Раз в минуту посылаю AT. Если модуль ответил OK - хорошо, cчётчик=0. Иначе +1 к счётчику попыток.
2. Если счётчик >= 5, сбрасываю счётчик и "нажимаю" кнопку питания.
Всё работает более года.
Одно такое событие за год произошло.
В продолжении попытки получения положительного результата обнаружил что общаясь с модулем через переходник UNO с использованием PuTTY обнаружил что на команду:
AT+ICF?
Приходит сообщение об ошибки.... при этом при попытке отправить смс, оно приходит на телефон...
Чтобы посмотреть что происходит на Rх GSM модуля нужно раскоментировать строку 356 скетча 2.1. а строку 137 поменять на
1
Serial
.begin (19200);
Соответственно смотреть в сериал мониторе на скорости 19200
Чтобы посмотреть что происходит на Rх GSM модуля нужно раскоментировать строку 356 скетча 2.1. а строку 137 поменять на
1
Serial
.begin (19200);
Соответственно смотреть в сериал мониторе на скорости 19200
Приветствую. Поменял скетч. В мониторе вижу что пришла смс WriteNumber1
Но в ответ так же тишина
01
AT+CMGF=1
02
03
OK
04
+IFC=1, 1
05
AT+CPBS=
"SM"
06
07
OK
08
AT+GSMBUSY=1
09
10
OK
11
+CMT:
"+7978xxxxxxx"
,
""
,
"17/11/22,18:30:46+12"
12
WriteNumber1
А вот продолжение - отправляю смс с телефона, в мониторе порта вижу, что получает модуль, а в ответ - тишина =(
01
AT+CMGF=1
02
03
OK
04
+IFC=1, 1
05
AT+CPBS=
"SM"
06
07
OK
08
AT+GSMBUSY=1
09
10
OK
11
+CMT:
"+7978xxxxxxx"
,
""
,
"17/11/22,18:30:46+12"
12
WriteNumber1
13
14
+CMT:
"+7978xxxxxxx"
,
""
,
"17/11/22,18:34:40+12"
15
ZAPROS
16
17
+CMT:
"+7978xxxxxxx"
,
""
,
"17/11/22,18:35:26+12"
18
ZAPROSTEL
в строку 147 добавьте это, чтобы узнать изначально какой номер из еепрома в переменную считался
1
Serial
.println (
""
);
Serial
.println (TelNumber1);
должны нули по идее быть
Добавил....ничего нового в терменале увы не появилось
то что в строке 140
NastroykaGSM ();
переместить после строки 147 (после Serial.println (""); Serial.println (TelNumber1); )
в сериал порту должен напечататься первым делом номер телефона, вот нужно и посмотреть какой там номер, должны быть все нули
001
#include <EEPROM.h>
002
// для GSM модуля *********************
003
#include <SoftwareSerial.h>
004
SoftwareSerial mySerial(14, 15);
//Rx, Tx
005
String currStr =
""
;
006
007
String TelNumber1 =
"000000000000"
;
008
009
String TelNumber2 =
"000000000000"
;
010
011
String BufferNumber =
"000000000000"
;
012
013
bool
SaveNumber2 = 0;
// флаг когда необходима запись номера#2, он true
014
015
int
isStringMessage = 0;
016
int
KTOzapros = 0;
017
int
KTOreport = 1;
018
//************************
019
020
021
int
Protocol = 1;
// протокол, по которому будет происходить выход на запуск котла: 1 - импульсный минусовой выход (на впайку в таймер вебасто например)
022
// 2 - по протоколу W-BUS ( котлы TermoTOP EVO)
023
// 3 - по подаче потенциала 12В, т.е. пока висит +12В - котел включен (котлы по аналогу - TermoTOP C,E)
024
025
026
//_______Все для цикла void voltmetr()*************
027
float
vout = 0.0;
// Напряжение на входе аналового входа
028
float
Vpit = 0.0;
// Измеряемое напряжение на выходе ИБП
029
int
volt = 0;
// Напряжение на входе АЦП
030
031
// входы выходы на соостветствующие пины **************
032
#define DopOn 4 // сюда доп канал от сигналки на включение вебасто
033
#define DopOff 5 // сюда доп канал от сигналки на выключение вебасто
034
#define VyhodWebasto 12 // это импульсный минусовой выход вкл/выкл вебасто к таймеру.
035
#define VyhodWebastoAnalog 3 // это потенциальный плюсовой выход вкл/выкл вебасто (напрямую к котлу без таймера).
036
#define Sost 9 // Сюда состояние вебасто (+12В когда работает)
037
038
#define Ohrana 6 // Сюда состояние охраны сигналки
039
#define Trevoga 7 // Сюда состояние тревоги
040
#define StartEng 8 // это импульсный минусовой выход вкл/выкл ДВС. подключать на вход событий сиги.
041
#define IGN 10 // Сюда состояние зажигания
042
#define Eng 11 // Сюда состояние работы ДВС
043
044
045
046
047
// для шины 1-wire и датчиков DS18B20****************
048
049
#include <OneWire.h> // библиотека для DS18B20
050
OneWire ds(2);
// датчики DS18B20 на 2 пин
051
052
byte
VyhlopC[8] ={0x28, 0xFF, 0xE6, 0x14, 0x90, 0x15, 0x04, 0x62};
053
byte
EngineC[8] ={0x28, 0xFF, 0x06, 0x15, 0x90, 0x15, 0x04, 0x37};
054
byte
UlicaC[8] ={0x28, 0xFF, 0x43, 0x42, 0xA8, 0x15, 0x03, 0x2A};
055
byte
SalonC[8] ={0x28, 0xFF, 0xE0, 0x19, 0xA8, 0x15, 0x01, 0xA7};
056
volatile
int
TempVyhlopC = 20;
057
volatile
int
TempEngineC = 20;
058
volatile
int
TempUlicaC = 20;
059
volatile
int
TempSalonC = 20;
060
061
// для организации W-BUS и различные таймеры********************
062
byte
Zapusk20[5] = {0xF4,0x03, 0x20, 0x3B, 0xEC} ;
063
byte
Zapusk21[5] = {0xF4,0x03, 0x21, 0x3B, 0xED} ;
064
byte
Stop[4] = {0xF4,0x02, 0x10, 0xE6} ;
065
066
bool
flagStartPresent = 1;
//флаг что отправляем в момент периодического поддержания связи W-Bus status или start
067
int
StartMessageRepeat = 0;
//количество отправленных сообщений на старт котла
068
int
StopMessageRepeat = 0;
//количество отправленных сообщений на остановку котла
069
070
unsigned
long
TimeWebasto = 1800000;
//время работы котла, 1800000 = 30мин
071
unsigned
long
EndReportMillis = 0;
//переменная для таймера отправки отчета об успешности запуска котла
072
unsigned
long
EndReportEngine = 0;
//переменная для таймера отправки отчета об успешности запуска ДВС
073
unsigned
long
Prev_PeriodW_BusMessage = 0;
//переменная для таймера периодической отправки сообщений состояния котла в шину W-Bus
074
unsigned
long
Prev_PeriodW_BusStartStop = 0;
//переменная для таймера периодической отправки сообщений старта/стопа котла в шину W-Bus
075
076
//для таймера - активация котла - импульс массы 0,8 сек на провод, впаянный в таймер вебасто)
077
unsigned
long
time, timer=0;
078
bool
timerenabled=
false
;
079
#define TIMEREXPIRED (time-timer)>800
080
081
082
//для таймера - старт двигателя - импульс +5В на оптопару, в итоге минусовой импульс 1 сек на вход событий сигналки для запуска ДВС)
083
unsigned
long
TimeStartEng, timerStartEng=0;
084
bool
timerenabledStartEng=
false
;
085
#define TIMEREXPIRED_StartEng (TimeStartEng-timerStartEng)>2000
086
087
088
//для таймера - старт котла по W-BUS )
089
unsigned
long
TimeStart_W_BUS, timerStart_W_BUS=0;
090
bool
timerenabledStart_W_BUS=
false
;
091
#define TIMEREXPIRED_Start_W_BUS (TimeStart_W_BUS-timerStart_W_BUS)> TimeWebasto
092
093
//**************************
094
095
096
//Основные переменные
097
bool
webasto = 0;
// состояние команды на работу Webasto. 0 - котел выключен, 1 - котел включен
098
bool
startWebasto_OK = 0;
// состояние успешного запуска котла
099
bool
report =
false
;
// состояние нужности отправки отчета false - не нужно отправлять, true - нужно отправлять
100
bool
reportEngine =
false
;
// состояние нужности отправки отчета false - не нужно отправлять, true - нужно отправлять
101
102
bool
engine =0;
//флаг работает ли ДВС или нет
103
bool
ignition=0;
//флаг включено ли зажигание или нет
104
bool
ohrana=0;
//флаг включена ли охрана или нет
105
bool
trevoga=0;
//флаг включена ли тревога или нет
106
bool
alarmSMS = 0;
//флаг отправлена ли смс о тревоге или нет
107
108
109
110
111
112
// СТАРТОВЫЙ ЦИКЛ
113
void
setup
()
114
{
115
delay (2500);
116
WDTCSR=(1<<WDCE)|(1<<WDE);
//для датчиков DS18B20
117
// WDTCSR=(1<<WDIE)| (1<<WDP2)|(1<<WDP1); // для датчиков DS18B20 (разрешение прерывания + выдержка 1 секунда)
118
WDTCSR=(1<<WDIE)| (1<<WDP3)|(1<<WDP0);
// для датчиков DS18B20 (разрешение прерывания + выдержка 8 секунд)
119
pinMode (DopOn, INPUT); digitalWrite (DopOn, HIGH);
120
pinMode (DopOff, INPUT); digitalWrite (DopOff, HIGH);
121
pinMode (Sost, INPUT); digitalWrite (Sost, HIGH);
122
pinMode (VyhodWebasto, OUTPUT); digitalWrite (VyhodWebasto, HIGH);
123
pinMode (VyhodWebastoAnalog, OUTPUT); digitalWrite (VyhodWebastoAnalog, LOW);
124
pinMode (StartEng, OUTPUT); digitalWrite (StartEng, LOW);
125
pinMode (13, OUTPUT); digitalWrite (13, LOW);
126
127
pinMode (Ohrana, INPUT); digitalWrite (Ohrana, HIGH);
128
pinMode (Trevoga, INPUT); digitalWrite (Trevoga, HIGH);
129
pinMode (IGN, INPUT); digitalWrite (IGN, HIGH);
130
pinMode (Eng, INPUT); digitalWrite (Eng, HIGH);
131
132
133
134
135
136
137
Serial
.begin (19200);
// сериал соединение протокол W-Bus
138
mySerial.begin(19200);
// сериал соединение для gsm модуля
139
delay(2000);
140
141
TimeWebasto = EEPROM.read(1)*60000UL;
142
Protocol = EEPROM.read(2);
143
144
for
(
int
i=0; i<12; i++) TelNumber1[i] = EEPROM.read (i+10);
145
for
(
int
i=0; i<12; i++) TelNumber2[i] = EEPROM.read (i+30);
146
Serial
.println (
""
);
Serial
.println (TelNumber1);
147
NastroykaGSM ();
148
}
149
150
151
152
153
154
155
156
157
void
loop
() {
158
159
if
(Protocol==1||Protocol==3) {webasto = !digitalRead (Sost);
160
if
(TempVyhlopC - TempUlicaC > 20) startWebasto_OK = 1;
161
else
startWebasto_OK = 0;}
162
163
164
if
(Protocol==2)W_Bus();
165
//ниже для таймера старта котла по W-BUS и аналогу
166
TimeStart_W_BUS = millis();
167
if
(timerenabledStart_W_BUS){
168
if
(TIMEREXPIRED_Start_W_BUS) {
169
digitalWrite (VyhodWebastoAnalog,LOW); webasto=0; timerenabledStart_W_BUS =
false
;}}
170
171
//ниже для таймера создания импульса на старт ДВС
172
TimeStartEng = millis();
173
if
(timerenabledStartEng) {
174
if
(TIMEREXPIRED_StartEng) {digitalWrite (StartEng, LOW); timerenabledStartEng=
false
;}}
175
176
engine = !digitalRead (Eng);
177
ignition= !digitalRead (IGN);
178
ohrana= !digitalRead (Ohrana);
179
trevoga= !digitalRead (Trevoga);
180
181
if
(webasto && report) timerReport ();
182
if
(reportEngine) timerReportEngine ();
183
if
(trevoga && !alarmSMS) AlarmSMS ();
184
if
(!ohrana) alarmSMS =
false
;
185
186
readSMS();
187
voltmetr();
188
WebastoOprosImpulse ();
189
190
191
}
192
193
void
voltmetr()
//____________Цикл "Вольтметр"__измерение напряжения на выходе ИБП
194
// Взято с <a href="<a href="<a href="<a href="<a href="http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html" rel="nofollow">http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html</a>" rel="nofollow"><a href="http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html" rel="nofollow">http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html</a></a>" rel="nofollow"><a href="<a href="http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html" rel="nofollow">http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html</a>" rel="nofollow"><a href="http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html" rel="nofollow">http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html</a></a></a>" rel="nofollow"><a href="<a href="<a href="http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html" rel="nofollow">http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html</a>" rel="nofollow"><a href="http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html" rel="nofollow">http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html</a></a>" rel="nofollow"><a href="<a href="http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html" rel="nofollow">http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html</a>" rel="nofollow"><a href="http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html" rel="nofollow">http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html</a></a></a></a>" rel="nofollow"><a href="<a href="<a href="<a href="http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html" rel="nofollow">http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html</a>" rel="nofollow"><a href="http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html" rel="nofollow">http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html</a></a>" rel="nofollow"><a href="<a href="http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html" rel="nofollow">http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html</a>" rel="nofollow"><a href="http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html" rel="nofollow">http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html</a></a></a>" rel="nofollow"><a href="<a href="<a href="http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html" rel="nofollow">http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html</a>" rel="nofollow"><a href="http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html" rel="nofollow">http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html</a></a>" rel="nofollow"><a href="<a href="http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html" rel="nofollow">http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html</a>" rel="nofollow"><a href="http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html" rel="nofollow">http://digitrode.ru/computing-devices/mcu_cpu/87-voltmetr-na-arduino.html</a></a></a></a></a>
195
{
196
volt = analogRead(A7);
// А7 аналоговый вход вольтметра
197
vout = (volt * 4.92) / 1024;
198
Vpit = vout / (9950.0/(98930.0+9950.0));
// По формуле Vpit = vout / (R2/(R1+R2))
199
if
(Vpit<0.09) Vpit=0.0;
// Округление до нуля
200
}
201
202
203
204
205
206
207
// Вектор прерывания для Dallas DS18B20
208
ISR (WDT_vect){
//вектор прерывания WD
209
static
boolean n=0;
// флаг работы: запрос температуры или её чтение
210
n=!n;
211
if
(n) {ds.reset();
// сброс шины
212
ds.write(0xCC);
//обращение ко всем датчикам
213
ds.write(0x44);
// начать преобразование (без паразитного питания)
214
}
215
else
{ds.reset();
216
ds.select(VyhlopC);
217
ds.write(0xBE);
// Read Scratchpad (чтение регистров)
218
TempVyhlopC = ds.read() | (ds.read()<<8);
//прочитаны 2 байта
219
TempVyhlopC = TempVyhlopC / 16;
220
// получение с 2-го датчика
221
ds.reset();
222
ds.select(EngineC);
223
ds.write(0xBE);
// Read Scratchpad (чтение регистров)
224
TempEngineC = ds.read() | (ds.read()<<8);
//прочитаны 2 байта
225
TempEngineC = TempEngineC/16;
226
ds.reset();
227
ds.select(UlicaC);
228
ds.write(0xBE);
// Read Scratchpad (чтение регистров)
229
TempUlicaC = ds.read() | (ds.read()<<8);
//прочитаны 2 байта
230
TempUlicaC = TempUlicaC / 16;
231
// получение с 2-го датчика
232
ds.reset();
233
ds.select(SalonC);
234
ds.write(0xBE);
// Read Scratchpad (чтение регистров)
235
TempSalonC = ds.read() | (ds.read()<<8);
//прочитаны 2 байта
236
TempSalonC = TempSalonC/16 ;
237
}}
238
239
240
241
242
243
244
245
void
StartWebasto()
246
{
247
if
(Protocol==1){ digitalWrite (VyhodWebasto, LOW);
248
timer=time;
249
timerenabled=
true
;}
250
251
else
if
(Protocol==2||Protocol==3){
252
StartMessageRepeat = 0;
253
webasto = 1; digitalWrite (VyhodWebastoAnalog, HIGH);
254
timerStart_W_BUS=TimeStart_W_BUS;
255
timerenabledStart_W_BUS =
true
;}
256
}
257
258
void
StopWebasto()
259
{
260
if
(Protocol==1){ digitalWrite (VyhodWebasto, LOW);
261
timer=time;
262
timerenabled=
true
;}
263
264
else
if
(Protocol==2||Protocol==3){
265
StopMessageRepeat = 0;
266
webasto = 0; digitalWrite (VyhodWebastoAnalog, LOW);
267
timerenabledStart_W_BUS =
false
;}
268
}
269
270
271
272
273
void
WebastoOprosImpulse (){
274
275
// опрос допканалов от сигнализации включения/ выключение котла и таймер импульса старт/стоп котла
276
time = millis();
277
if
(timerenabled) {
if
(TIMEREXPIRED) {digitalWrite (VyhodWebasto, HIGH); timerenabled=
false
;}}
278
else
{
if
(!digitalRead (DopOn) && !webasto) {StartWebasto(); report =
true
; EndReportMillis = millis(); KTOreport = 1;}
279
if
(!digitalRead (DopOff) && webasto) {StopWebasto(); report =
false
;}}}
280
281
282
// цикл таймера отправки отчета об успешности запуска котла (отчёт через 6 мин после старта)
283
void
timerReport () {
284
if
(millis() - EndReportMillis > 360000UL)
285
{EndReportMillis = millis(); report =
false
; SMSzapros(); }}
286
287
// цикл таймера отправки отчета об успешности запуска ДВС (отчёт через 30сек после старта)
288
void
timerReportEngine () {
289
if
(millis() - EndReportEngine > 30000)
290
{EndReportEngine = millis(); reportEngine =
false
; SMSzapros();}}
291
292
293
294
295
296
void
NastroykaGSM () {
297
mySerial.print(F(
"AT+CMGF=1\r"
));
//устанавливает текстовый режим смс-сообщения
298
delay(200);
299
mySerial.print(F(
"+IFC=1, 1\r"
));
//устанавливает программный контроль потоком передачи данных
300
delay(200);
301
mySerial.print(F(
"AT+CPBS=\"SM\"\r"
));
//открывает доступ к данным телефонной книги SIM-карты
302
delay(200);
303
mySerial.print(F(
"AT+GSMBUSY=1\r"
));
//запрет всех входящих звонков
304
delay(300);
305
mySerial.print(F(
"AT+CNMI=1,2,2,1,0\r"
));
//включает оповещение о новых сообщениях
306
delay(300);
307
mySerial.print(F(
"AT+CMGDA=\"DEL ALL\"\r"
));
// удаляем все смс, ки
308
delay(2000);
309
}
310
311
void
startNumber1SMS()
//__________________Цикл подготовки модуля к отправке СМС-сообщений по первому номеру
312
{
313
mySerial.print(F(
"AT+CMGF=1\r"
));
314
delay(200);
315
mySerial.print(F(
"AT+CMGS=\""
)); mySerial.print(TelNumber1); mySerial.println(
"\""
);
316
delay(400);
317
}
318
319
void
startNumber2SMS()
//__________________Цикл подготовки модуля к отправке СМС-сообщений по второму номеру
320
{
321
mySerial.print(F(
"AT+CMGF=1\r"
));
322
delay(200);
323
mySerial.print(F(
"AT+CMGS=\""
)); mySerial.print(TelNumber2); mySerial.println(F(
"\""
));
324
delay(400);
325
}
326
327
void
startBufferNumberSMS()
//__________________Цикл подготовки модуля к отправке СМС-сообщений по второму номеру
328
{
329
mySerial.print(F(
"AT+CMGF=1\r"
));
330
delay(200);
331
mySerial.print(F(
"AT+CMGS=\""
)); mySerial.print(BufferNumber); mySerial.println(F(
"\""
));
332
delay(400);
333
}
334
335
void
WriteNubmer1() {
336
337
338
339
340
}
341
342
343
void
EndSMS ()
344
{
345
mySerial.println((
char
)26);
// Команда отправки СМС
346
delay(3000);
347
mySerial.print(F(
"AT+CMGDA=\"DEL ALL\"\r"
));
// удаляем все смс, ки
348
delay(1500);
349
}
350
351
352
void
readSMS()
//_____Цикл чтения входящих СМС-сообщений______________
353
{
354
if
(!mySerial.available())
return
;
355
char
currSymb = mySerial.read();
356
Serial
.print (currSymb);
357
if
(
'\r'
== currSymb)
358
{
359
if
(isStringMessage!=0&&isStringMessage!=10)
//если текущая строка - SMS-сообщение, отреагируем на него соответствующим образом
360
{
361
if
(!currStr.compareTo(
"ZAPROS"
)) { SMSzapros();}
// Передача параметров по СМС
362
else
if
(!currStr.compareTo(
"ZAPROSTEL"
)) { SMSzaprosTEL();}
// Передача номеров телефонов пользователей по СМС
363
364
365
366
else
if
(!currStr.compareTo(
"Webasto-ON"
)) {
if
(!webasto) {StartWebasto (); report =
true
; EndReportMillis = millis();
// если получили команду на включение и вебаста в настоящий момент выключена - включаем
367
if
(isStringMessage == 1) {startNumber1SMS(); KTOreport = 1;}
368
else
if
(isStringMessage == 2) {startNumber2SMS(); KTOreport = 2;}
369
mySerial.println(F(
"Webasto Vkluchena"
)); EndSMS();}
370
371
else
{
if
(isStringMessage == 1) startNumber1SMS();
372
else
if
(isStringMessage == 2) startNumber2SMS();
373
mySerial.println(F(
"Webasto uzhe vkluchena"
)); EndSMS();}}
374
375
376
else
if
(!currStr.compareTo(
"Webasto-OFF"
)) {
if
(webasto){StopWebasto (); report =
false
;
// если получили команду на выключение и вебаста в настоящий момент включена - выключаем
377
if
(isStringMessage == 1) startNumber1SMS();
378
else
if
(isStringMessage == 2) startNumber2SMS();
379
mySerial.println(F(
"Webasto Otkluchena"
)); EndSMS();}
380
381
382
else
{
if
(isStringMessage == 1) startNumber1SMS();
383
else
if
(isStringMessage == 2) startNumber2SMS();
384
mySerial.println(F(
"Webasto uzhe otkluchena"
)); EndSMS();}}
385
386
387
else
if
(!currStr.compareTo(
"Engine-ON"
)) {
if
(!engine) { digitalWrite (StartEng, HIGH); timerStartEng=TimeStartEng; timerenabledStartEng=
true
; reportEngine =
true
; EndReportEngine = millis();
// если получили команду на включение ДВС и он в настоящий момент выключен - включаем
388
if
(isStringMessage == 1) {startNumber1SMS(); KTOreport = 1;}
389
else
if
(isStringMessage == 2) {startNumber2SMS(); KTOreport = 2;}
390
mySerial.println(F(
"Engine Start"
)); EndSMS();}
391
392
else
{
if
(isStringMessage == 1) startNumber1SMS();
393
else
if
(isStringMessage == 2) startNumber2SMS();
394
mySerial.println(F(
"Dvigatel uzhe rabotaet"
)); EndSMS();}}
395
396
else
if
(!currStr.compareTo(
"Engine-OFF"
)) {
if
(engine){ digitalWrite (StartEng, HIGH); timerStartEng=TimeStartEng; timerenabledStartEng=
true
; reportEngine =
false
;
// если получили команду на выключение ДВС и он в настоящий момент работает - выключаем
397
if
(isStringMessage == 1) startNumber1SMS();
398
else
if
(isStringMessage == 2) startNumber2SMS();
399
mySerial.println(F(
"Dvigatel ostanovlen"
)); EndSMS();}
400
401
402
else
{
if
(isStringMessage == 1) startNumber1SMS();
403
else
if
(isStringMessage == 2) startNumber2SMS();
404
mySerial.println(F(
"dvigatel uzhe ostanovlen"
)); EndSMS(); }}
405
406
407
else
if
(!currStr.compareTo(
"Impulse"
)) {Protocol = 1; EEPROM.write(2,Protocol);
if
(isStringMessage == 1) {startNumber1SMS(); mySerial.println(F(
"zapusk GND_impulse"
)); EndSMS();}
408
else
if
(isStringMessage == 2) {startNumber2SMS(); mySerial.println(F(
"zapusk GND_impulse"
)); EndSMS();}}
409
410
else
if
(!currStr.compareTo(
"W-BUS"
)) {Protocol = 2; EEPROM.write(2,Protocol); webasto = 0;
if
(isStringMessage == 1) {startNumber1SMS(); mySerial.println(F(
"zapusk W-BUS"
)); EndSMS();}
411
else
if
(isStringMessage == 2) {startNumber2SMS(); mySerial.println(F(
"zapusk W_BUS"
)); EndSMS();}}
412
413
else
if
(!currStr.compareTo(
"Potenzial"
)) {Protocol = 3; EEPROM.write(2,Protocol);
if
(isStringMessage == 1) {startNumber1SMS(); mySerial.println(F(
"zapusk +12V Potencial"
)); EndSMS();}
414
else
if
(isStringMessage == 2) {startNumber2SMS(); mySerial.println(F(
"zapusk +12V Potencial"
)); EndSMS();}}
415
416
417
else
if
(currStr.endsWith(
"min"
)) {TimeWebasto = currStr.toInt()*60000UL;
// для задания время цикла работы отправить сообщение вида "25 min", где 25 время работы в мин
418
if
(TimeWebasto>3540000UL) TimeWebasto = 3540000UL;
419
if
(TimeWebasto<=600000UL) TimeWebasto = 600000UL;
420
EEPROM.write(1,TimeWebasto/60000UL);
421
if
(isStringMessage == 1)startNumber1SMS();
422
else
if
(isStringMessage == 2) startNumber2SMS();
423
mySerial.print(F(
"Webasto time: "
)); mySerial.print(TimeWebasto/60000UL); mySerial.print(F(
"min"
)); EndSMS();}
424
425
426
else
if
(!currStr.compareTo(
"ResetNumbers"
)) {
if
(isStringMessage == 1) {startNumber1SMS(); mySerial.println(F(
"Phone numbers are erased"
)); EndSMS();
427
428
TelNumber1 =
"000000000000"
; TelNumber2 =
"000000000000"
;
for
(
int
i=0; i<12; i++) {EEPROM.write (i+10, TelNumber1[i]); EEPROM.write (i+30, TelNumber2[i]); }}}
429
430
else
if
(!currStr.compareTo(
"WriteNumber2"
)&& isStringMessage == 1) {
431
SaveNumber2 = 1; startNumber1SMS(); mySerial.println(F(
"Otpravte lyuboye SMS s nomera2 dlya sochraneniya nomera"
)); EndSMS();}
432
433
434
435
436
else
if
(!currStr.compareTo(
"Balance"
)) SMSbalance();
437
isStringMessage = 0;
438
}
439
else
if
(isStringMessage==10){
if
(!currStr.compareTo(
"WriteNumber1"
)) { TelNumber1 = BufferNumber;
for
(
int
i=0; i<12; i++) {EEPROM.write (i+10, BufferNumber[i]);}
440
startNumber1SMS(); mySerial.println(F(
"Tel Number#1 is saving in memory"
)); mySerial.print(
"Tel#1: "
); mySerial.println (TelNumber1); EndSMS();
441
}
442
else
if
(!currStr.compareTo(
"ZAPROS"
)) { SMSzapros();}
443
else
if
(!currStr.compareTo(
"ZAPROSTEL"
)) { SMSzaprosTEL();}
// Передача номеров телефонов пользователей по СМС
444
isStringMessage = 0;
445
446
}
447
448
449
450
451
else
if
(isStringMessage==0) {
if
(TelNumber1!=
"000000000000"
&& !SaveNumber2 && TelNumber1!=
"яяяяяяяяяяяя"
){
452
453
if
(currStr.startsWith(
"+CMT: \""
+TelNumber1)) { isStringMessage = 1; KTOzapros = 1; }
454
else
if
(currStr.startsWith(
"+CMT: \""
+TelNumber2)) { isStringMessage = 2; KTOzapros = 2; }
455
else
if
(currStr.startsWith(
"+CUSD: 0,"
))
//если текущая строка начинается с "+CUSD",то следующая строка является запросом баланса
456
{
457
if
(KTOzapros == 1) startNumber1SMS();
458
else
if
(KTOzapros == 2) startNumber2SMS();
459
mySerial.print (currStr);
460
EndSMS();
461
}
462
}
463
464
else
if
(currStr.startsWith(
"+CMT:"
) && !SaveNumber2) { isStringMessage = 10;
for
(
int
i =0; i<12; i++) {BufferNumber[i]=currStr[i+7];}}
465
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]);}
466
startNumber2SMS(); mySerial.println(F(
"Vash nomer sochranyon kak Number#2 v pamyati!"
));
467
mySerial.print(F(
"Tel1: "
)); mySerial.println(TelNumber1); mySerial.print(F(
"Tel#2: "
)); mySerial.println (TelNumber2); EndSMS(); SaveNumber2 = 0; }
468
469
}
470
471
currStr =
""
;
472
}
473
474
else
if
(
'\n'
!= currSymb) { currStr += String(currSymb);}
475
}
476
477
478
void
SMSzapros()
479
{
if
(isStringMessage == 10){
480
startBufferNumberSMS();
481
482
mySerial.println (F(
"Tel.number#1 is not has been saving in memory!"
));
483
mySerial.println (F(
"For save Tel1 send SMS command \"WriteNumber1\""
));
484
mySerial.print(F(
"Tel1: "
)); mySerial.println(TelNumber1);
485
mySerial.print(F(
"Tel2: "
)); mySerial.println(TelNumber2);
486
}
487
488
489
490
else
{
491
492
if
(isStringMessage == 1) { startNumber1SMS();}
493
else
if
(isStringMessage == 2) { startNumber2SMS();}
494
else
if
(isStringMessage == 0) {
if
(KTOreport == 1) startNumber1SMS();
495
else
if
(KTOreport == 2) startNumber2SMS();}
496
if
(webasto) { mySerial.println (F(
"Webasto ON"
));
497
if
(startWebasto_OK) mySerial.println (F(
"StartWebasto OK"
));
498
else
mySerial.println (F(
"StartWebasto FAIL"
));}
499
else
mySerial.println (F(
"Webasto OFF"
));
500
501
if
(engine) mySerial.println (F(
"Engine ON"
));
502
else
mySerial.println (F(
"Engine OFF"
));
503
504
if
(ignition) mySerial.println (F(
"IGN ON"
));
505
else
mySerial.println (F(
"IGN OFF"
));
506
507
if
(ohrana) mySerial.println (F(
"OHRANA ON"
));
508
else
mySerial.println (F(
"OHRANA OFF"
));
509
510
if
(trevoga) mySerial.println (F(
"Vnimanie!!! Trevoga!!! Sirena Vkl!"
));
511
512
mySerial.print(F(
"Battery: "
)); mySerial.print (Vpit); mySerial.println(F(
"V"
));
513
mySerial.print(F(
"Engine: "
)); mySerial.print (TempEngineC); mySerial.println(F(
"*C"
));
514
mySerial.print(F(
"Vyhlop: "
)); mySerial.print (TempVyhlopC); mySerial.println(F(
"*C"
));
515
mySerial.print(F(
"Ulica: "
)); mySerial.print (TempUlicaC); mySerial.println(F(
"*C"
));
516
mySerial.print(F(
"Salon: "
)); mySerial.print (TempSalonC); mySerial.println(F(
"*C"
));
517
mySerial.print(F(
"Protocol: "
));
518
if
(Protocol==1) mySerial.println(F(
"GND Impulse"
));
519
else
if
(Protocol==2) mySerial.println(F(
"W-BUS"
));
520
else
if
(Protocol==3) mySerial.println(F(
"+12V Potencial"
));
521
mySerial.print(F(
"Webasto Time: "
)); mySerial.print (TimeWebasto/60000UL); mySerial.println(F(
"min"
));
522
523
}
524
EndSMS();
525
}
526
527
void
SMSzaprosTEL(){
528
if
(isStringMessage == 1) { startNumber1SMS();}
529
else
if
(isStringMessage == 2) { startNumber2SMS();}
530
else
if
(isStringMessage == 10) { startBufferNumberSMS();}
531
532
533
mySerial.print(F(
"Tel1: "
)); mySerial.println(TelNumber1);
534
mySerial.print(F(
"Tel2: "
)); mySerial.println(TelNumber2);
535
if
(TelNumber1!=
"000000000000"
&& TelNumber1!=
"яяяяяяяяяяяя"
){
536
mySerial.print(F(
"Protocol: "
));
537
if
(Protocol==1) mySerial.println(F(
"GND Impulse"
));
538
else
if
(Protocol==2) mySerial.println(F(
"W-BUS"
));
539
else
if
(Protocol==3) mySerial.println(F(
"+12V Potencial"
));
540
mySerial.print(F(
"Webasto Time: "
)); mySerial.print (TimeWebasto/60000UL); mySerial.println(F(
"min"
));}
541
EndSMS();
542
}
543
544
545
void
SMSbalance() {
546
mySerial.print(F(
"AT+CMGF=1\r"
));
547
delay(200);
548
549
mySerial.println (F(
"AT+CUSD=1,\"#100#\""
));
550
551
//mySerial.println("AT+CMGS=\"#100#\"");
552
// mySerial.println("ATD#100#");
553
//mySerial.println("AT + CMGS = \"111\""); //
554
delay(2000);
// команда на замену на транслит *111*6*2#
555
//mySerial.println ("11");
556
//EndSMS();
557
}
558
559
560
void
AlarmSMS() {
561
startNumber1SMS();
562
mySerial.println (F(
"Vnimanie!!! Trevoga!!! Sirena Vkl!"
));
563
EndSMS();
564
startNumber2SMS();
565
mySerial.println (F(
"Vnimanie!!! Trevoga!!! Sirena Vkl!"
));
566
EndSMS();
567
alarmSMS =
true
;
568
569
}
void
W_Bus (){
570
if
(webasto) {
571
if
(StartMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800)){
572
573
for
(
int
i = 0; i<5; i++)
Serial
.write (Zapusk21[i]);
574
StartMessageRepeat++;
575
Prev_PeriodW_BusStartStop = millis();
576
577
}
578
if
(StartMessageRepeat>=4){
if
(millis()-Prev_PeriodW_BusMessage>5000) {
579
//делаем периодическое поддержание связи W-BUS
580
// наверное сканает отправка сообщения о состоянии котла
581
// т.е. ,например, отправляем периодически запрос на показания датчиков
582
// состоянием работы котла будет наличие или отсутствие пламени
583
if
(flagStartPresent) {
for
(
int
i = 0; i<5; i++)
Serial
.write (Zapusk21[i]); }
584
//else {for (int i = 0; i<5; i++) Serial.write (StateMessage[i]);}
585
flagStartPresent = !flagStartPresent;
586
StopMessageRepeat = 0;
587
588
Prev_PeriodW_BusMessage = millis();
589
}}}
590
591
592
593
594
595
else
if
(StopMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800)){
596
for
(
int
i = 0; i<4; i++)
Serial
.write (Stop[i]);
597
StopMessageRepeat++;
598
StartMessageRepeat = 0;
599
Prev_PeriodW_BusStartStop = millis();
600
601
602
}
603
604
}
605
606
607
608
609
Получился вот такой скетч если правильно Вас понял. Но в терминале ничего нового. Наверное я не правильно Вас понял.
01
AT+CMGF=1
02
03
OK
04
+IFC=1, 1
05
AT+CPBS=
"SM"
06
07
OK
08
AT+GSMBUSY=1
09
10
OK
Ага разобрался перекинул часть программы за "строку 147" - - - - да первые нули
1
000000000000
потом
01
AT+CMGF=1
02
03
OK
04
+IFC=1, 1
05
AT+CPBS=
"SM"
06
07
OK
08
AT+GSMBUSY=1
09
10
OK
Получилось вот так:
01
pinMode (IGN, INPUT); digitalWrite (IGN, HIGH);
02
pinMode (Eng, INPUT); digitalWrite (Eng, HIGH);
03
04
05
06
07
08
09
Serial
.begin (19200);
// сериал соединение протокол W-Bus
10
mySerial.begin(19200);
// сериал соединение для gsm модуля
11
delay(2000);
12
13
14
15
Serial
.println (
""
);
Serial
.println (TelNumber1);
16
17
NastroykaGSM ();
18
19
TimeWebasto = EEPROM.read(1)*60000UL;
20
Protocol = EEPROM.read(2);
21
22
for
(
int
i=0; i<12; i++) TelNumber1[i] = EEPROM.read (i+10);
23
for
(
int
i=0; i<12; i++) TelNumber2[i] = EEPROM.read (i+30);
24
}
25
26
27
28
29
30
31
32
33
void
loop
() {
почистите еепром таким скетчем и заливайте 2.1 без измнений, должно всё заработать по идее
01
#include <EEPROM.h>
02
03
void
setup
() {
04
05
pinMode(13, OUTPUT);
06
digitalWrite(13, 0);
07
08
09
10
for
(
int
i = 0 ; i < EEPROM.length() ; i++) EEPROM.write(i,
'0'
);
11
12
digitalWrite(13, HIGH);
13
}
14
15
void
loop
() {}
Когда EEprom был у вас ещё не тронутый (во всех ячейках FF),то заработало бы, если бы вы скетч заливали сразу после копипаста (без сохранения скетча на компе). При сохранении скетча на компе сбивается кодировка символов соответсвующих байту FF (который в еепроме был изначально), т.е. символа "я" и все косяки из-за этого, а потом я вам немного неправильно почистить еепром предложил, поэтому тоже не работало. Исправил в начале темы как еепром чистить до заливки скетча.
это у вас НЕ получилось, а нули написались в этом случае, потому что вы распечатку в терминал поставили до считываения тел.номера из еепром, а изначально, при старте программы, в переменную тел.номера нули записываются и вы их сразу и распечатали.
PS удалите простыню из сообщения #71, мешает . Кстати когда вставляете скетч, там вверху вкладка правая, можно галочку ставить "свернуть", чтобы под катом было.
почистите еепром таким скетчем и заливайте 2.1 без измнений, должно всё заработать по идее
01
#include <EEPROM.h>
02
03
void
setup
() {
04
05
pinMode(13, OUTPUT);
06
digitalWrite(13, 0);
07
08
09
10
for
(
int
i = 0 ; i < EEPROM.length() ; i++) EEPROM.write(i,
'0'
);
11
12
digitalWrite(13, HIGH);
13
}
14
15
void
loop
() {}
Приветствую. Спасибо Вам огромное за проделанную работу, всё теперь получилось (пошёл покупать недостающие детали и буду собирать до конца – смс ки отправляю – в ответ приходят подтверждения и инфо о состоянии – попробовал пока только с напряжением питания) - давно занялся поиском чего-то подобного для запуска котла по смс. Об arduino узнал недавно и пока что всё в процессе начинания и изучения. Изначально была идея запускать по шине CAN (точнее сказать в моей машине по периферийной шине i-bus через приборную панель) и по CAN отслеживать и отправлять сообщение о состоянии котла, температуре ОЖ и бортовом напряжении. Но для этого, как понимаю, нужно знать протокол обмена… Но с выносными датчиками, кому не лень, тоже всё хорошо.
Готов нарисовать и выложить нарисованную схему, для тех «ленивых» кто спрашивает её, но пока не пойму как прикрепить рисунок.
По ходу макетирования появилось несколько вопросов.
1. sms на запрос баланса приходят в HEX unicode =( /лечится заменой оператора или можно программой?/
2. не знаю как на версиях Webasto которые устанавливают как доп, но на "старых" например, моделях БМВ есть несколько условий при которых котёл не будет запущен - (с завода котёл кстати, работал только как "догревайка", но перекодировка творит чудеса и теперь работает ещё и как "автономное отопление" без колхозинга) - одно из них пониженное напряжение питания (недавно у товарища попытались запустить котёл при разряженной АКБ U=11.6V) - сигнал на запуск пришел, а вот котёл не запустился пока не зарядили АКБ. И это считаю правильная задумка - зачем тёплый двигатель, если стартер не крутится. Не увидел организованно ли это в Вашей программе уважаемый автор, но возможно, это будет своим образом аварийная защита, для котлов которые будут рады усадить АКБ в ноль (если такие существуют, конечно)
Я так понимаю котел у вас штатный, да к тому же по CAN управляется . Вы уверены в возможности запуска его по аналогу? Вообще чтобы по CAN запускать конечно нужно знать протокол обмена. Но исследование CAN шины тоже дело интересное, хотя и не лёгкое. Если будет интересно, могу выложить проект CAN хакера на ардуино (там собственно сама ардуино и китайский модуль кана на MCP2515), который как раз и позволяет выявить из CAN шины нужные сообщения.
Короче в будущем конечно неплохо было бы дополнить данное устройство CAN шиной, но работы с этим не мало будет, особенно в программной части - протоколы разных авто.
Я хочу допилить хотябы W-BUS, т.к. если сказать по чесноку, в данный момент организовано только включение выключение котла без опроса его реального состояния. Просто у меня нет Webasto Evo чтобы протокол W-BUS помучить.
А вы если только аналог будете использовать вам можно не ставить микруху LM393 и всю её обвязку
По ходу макетирования появилось несколько вопросов.
1. sms на запрос баланса приходят в HEX unicode =( /лечится заменой оператора или можно программой?/
2. не знаю как на версиях Webasto которые устанавливают как доп, но на "старых" например, моделях БМВ есть несколько условий при которых котёл не будет запущен - (с завода котёл кстати, работал только как "догревайка", но перекодировка творит чудеса и теперь работает ещё и как "автономное отопление" без колхозинга) - одно из них пониженное напряжение питания (недавно у товарища попытались запустить котёл при разряженной АКБ U=11.6V) - сигнал на запуск пришел, а вот котёл не запустился пока не зарядили АКБ. И это считаю правильная задумка - зачем тёплый двигатель, если стартер не крутится. Не увидел организованно ли это в Вашей программе уважаемый автор, но возможно, это будет своим образом аварийная защита, для котлов которые будут рады усадить АКБ в ноль (если такие существуют, конечно)
1. Намного проще через оператора решить. (Ну всмысле не заменой его, а подбором правильной команды запроса баланса, либо есть такая функция у некоторых перевода на транслит.) Парсить этот юникод и PDU полный песец.
2. По напряжению АКБ по идее во всех котлах есть выключение. Я не стал делать выключение по напряжению. Но это не сложно - пару строк добавить.
на скорую руку состряпал скетч v2.2 и переделал плату. Добавлено:
- тактовая кнопка вкл/выкл с индикацией состояния команды на работу котла;
- рестарт GSM модуля в случае если он не отвечает ("завис") при помощи кратковременного оключения питания средствами реле;
- запись в еепром количество рестартов;
Но это вообще ничего не проверено, т.к. деталей нет и проверить пока некогда
001
#include <EEPROM.h>
002
#include <Button.h>
003
004
Button test;
005
006
// для GSM модуля *********************
007
#include <SoftwareSerial.h>
008
SoftwareSerial mySerial(14, 15);
//Rx, Tx
009
String currStr =
""
;
010
011
String TelNumber1 =
"000000000000"
;
012
013
String TelNumber2 =
"000000000000"
;
014
015
String BufferNumber =
"000000000000"
;
016
017
bool
SaveNumber2 = 0;
// флаг когда необходима запись номера#2, он true
018
019
int
isStringMessage = 0;
020
int
KTOzapros = 0;
021
int
KTOreport = 1;
022
//************************
023
024
025
int
Protocol = 1;
// протокол, по которому будет происходить выход на запуск котла: 1 - импульсный минусовой выход (на впайку в таймер вебасто например)
026
// 2 - по протоколу W-BUS ( котлы TermoTOP EVO)
027
// 3 - по подаче потенциала 12В, т.е. пока висит +12В - котел включен (котлы по аналогу - TermoTOP C,E)
028
029
030
//_______Все для цикла void voltmetr()*************
031
float
vout = 0.0;
// Напряжение на входе аналового входа
032
float
Vpit = 0.0;
// Измеряемое напряжение на выходе ИБП
033
int
volt = 0;
// Напряжение на входе АЦП
034
035
// входы выходы на соостветствующие пины **************
036
#define DopOn 4 // сюда доп канал от сигналки на включение вебасто
037
#define DopOff 5 // сюда доп канал от сигналки на выключение вебасто
038
#define VyhodWebasto 12 // это импульсный минусовой выход вкл/выкл вебасто к таймеру.
039
#define VyhodWebastoAnalog 3 // это потенциальный плюсовой выход вкл/выкл вебасто (напрямую к котлу без таймера).
040
#define Sost 9 // Сюда состояние вебасто (+12В когда работает)
041
042
#define Ohrana 6 // Сюда состояние охраны сигналки
043
#define Trevoga 7 // Сюда состояние тревоги
044
#define StartEng 8 // это импульсный минусовой выход вкл/выкл ДВС. подключать на вход событий сиги.
045
#define IGN 10 // Сюда состояние зажигания
046
#define Eng 11 // Сюда состояние работы ДВС
047
#define ResetGSM 16 // пин ресета GSM (A2) подключен к реле, разрывающее питание модуля.
048
#define StartButton 17 // пин тактовой кнопки (А3) вкл/выкл котла
049
#define StatusWebastoLED 13 // пин индикация включенности котла
050
051
052
053
054
055
// для шины 1-wire и датчиков DS18B20****************
056
057
#include <OneWire.h> // библиотека для DS18B20
058
OneWire ds(2);
// датчики DS18B20 на 2 пин
059
060
byte
VyhlopC[8] ={0x28, 0xFF, 0xE6, 0x14, 0x90, 0x15, 0x04, 0x62};
061
byte
EngineC[8] ={0x28, 0xFF, 0x06, 0x15, 0x90, 0x15, 0x04, 0x37};
062
byte
UlicaC[8] ={0x28, 0xFF, 0x43, 0x42, 0xA8, 0x15, 0x03, 0x2A};
063
byte
SalonC[8] ={0x28, 0xFF, 0xE0, 0x19, 0xA8, 0x15, 0x01, 0xA7};
064
volatile
int
TempVyhlopC = 20;
065
volatile
int
TempEngineC = 20;
066
volatile
int
TempUlicaC = 20;
067
volatile
int
TempSalonC = 20;
068
069
// для организации W-BUS и различные таймеры********************
070
byte
Zapusk20[5] = {0xF4,0x03, 0x20, 0x3B, 0xEC} ;
071
byte
Zapusk21[5] = {0xF4,0x03, 0x21, 0x3B, 0xED} ;
072
byte
Stop[4] = {0xF4,0x02, 0x10, 0xE6} ;
073
074
bool
flagStartPresent = 1;
//флаг что отправляем в момент периодического поддержания связи W-Bus status или start
075
int
StartMessageRepeat = 0;
//количество отправленных сообщений на старт котла
076
int
StopMessageRepeat = 0;
//количество отправленных сообщений на остановку котла
077
078
unsigned
long
TimeWebasto = 1800000;
//время работы котла, 1800000 = 30мин
079
unsigned
long
EndReportMillis = 0;
//переменная для таймера отправки отчета об успешности запуска котла
080
unsigned
long
EndReportEngine = 0;
//переменная для таймера отправки отчета об успешности запуска ДВС
081
unsigned
long
Prev_PeriodW_BusMessage = 0;
//переменная для таймера периодической отправки сообщений состояния котла в шину W-Bus
082
unsigned
long
Prev_PeriodW_BusStartStop = 0;
//переменная для таймера периодической отправки сообщений старта/стопа котла в шину W-Bus
083
084
//для таймера - активация котла - импульс массы 0,8 сек на провод, впаянный в таймер вебасто)
085
unsigned
long
time, timer=0;
086
bool
timerenabled=
false
;
087
#define TIMEREXPIRED (time-timer)>800
088
089
090
//для таймера - старт двигателя - импульс +5В на оптопару, в итоге минусовой импульс 1.5 сек на вход событий сигналки для запуска ДВС)
091
unsigned
long
timerStartEng=0;
bool
timerenabledStartEng=
false
;
092
#define TIMEREXPIRED_StartEng (millis()-timerStartEng)>1500
093
094
095
//для таймера - старт котла по W-BUS )
096
unsigned
long
timerStart_W_BUS=0;
bool
timerenabledStart_W_BUS=
false
;
097
#define TIMEREXPIRED_Start_W_BUS (millis()-timerStart_W_BUS)> TimeWebasto
098
099
100
//ниже всё для организации ресета GSM модуля, если с ним отсутствует свзяь
101
102
unsigned
long
prevCheckConnect=0;
// для таймера периодичности проверки (командой "АТ")
103
int
intervalCheck = 10;
// каждые столько мин будет проверка свзи с GSM (командой "АТ")
104
unsigned
long
timerWaitOK=0;
// для таймера ожидания ответа после посылки команды "АТ"
105
bool
timerenabledWaitOK=
false
;
// для таймера ожидания ответа после посылки команды "АТ"
106
int
errors=0;
// количество неответов от GSM модуля
107
bool
gsmOK = 1;
// флаг есть свзяь с GSM модулем или нет
108
bool
resettimer = 0;
// для таймера удерживания реле в режиме сброс питания
109
unsigned
long
resetTimer=0;
// для таймера удерживания реле в режиме сброс питания
110
int
ResetNumber = 0;
//количество ресетов GSM модуля для статистики (хранится в еепром)
111
112
//**************************
113
114
115
//Основные переменные
116
bool
webasto = 0;
// состояние команды на работу Webasto. 0 - котел выключен, 1 - котел включен
117
bool
startWebasto_OK = 0;
// состояние успешного запуска котла
118
bool
report =
false
;
// состояние нужности отправки отчета false - не нужно отправлять, true - нужно отправлять
119
bool
reportEngine =
false
;
// состояние нужности отправки отчета false - не нужно отправлять, true - нужно отправлять
120
121
bool
engine =0;
//флаг работает ли ДВС или нет
122
bool
ignition=0;
//флаг включено ли зажигание или нет
123
bool
ohrana=0;
//флаг включена ли охрана или нет
124
bool
trevoga=0;
//флаг включена ли тревога или нет
125
bool
alarmSMS = 0;
//флаг отправлена ли смс о тревоге или нет
126
127
128
129
130
131
// СТАРТОВЫЙ ЦИКЛ
132
void
setup
()
133
{
134
delay (2500);
135
136
test.NO();
137
test.pullUp();
138
test.duration_bounce ( 50);
139
test.duration_click_Db ( 250);
140
test.duration_inactivity_Up(5000);
141
test.duration_inactivity_Dn(1000);
142
test.duration_press ( 500);
143
test.button(StartButton);
// arduino pins connected to button
144
145
WDTCSR=(1<<WDCE)|(1<<WDE);
//для датчиков DS18B20
146
147
WDTCSR=(1<<WDIE)| (1<<WDP3)|(1<<WDP0);
// для датчиков DS18B20 (разрешение прерывания + выдержка 8 секунд)
148
pinMode (DopOn, INPUT); digitalWrite (DopOn, HIGH);
149
pinMode (DopOff, INPUT); digitalWrite (DopOff, HIGH);
150
pinMode (Sost, INPUT); digitalWrite (Sost, HIGH);
151
pinMode (VyhodWebasto, OUTPUT); digitalWrite (VyhodWebasto, HIGH);
152
pinMode (VyhodWebastoAnalog, OUTPUT); digitalWrite (VyhodWebastoAnalog, LOW);
153
pinMode (StartEng, OUTPUT); digitalWrite (StartEng, LOW);
154
pinMode (StatusWebastoLED, OUTPUT); digitalWrite (StatusWebastoLED, LOW);
155
pinMode (ResetGSM, OUTPUT); digitalWrite (ResetGSM, LOW);
156
157
pinMode (Ohrana, INPUT); digitalWrite (Ohrana, HIGH);
158
pinMode (Trevoga, INPUT); digitalWrite (Trevoga, HIGH);
159
pinMode (IGN, INPUT); digitalWrite (IGN, HIGH);
160
pinMode (Eng, INPUT); digitalWrite (Eng, HIGH);
161
162
163
164
165
166
167
168
Serial
.begin (2400, SERIAL_8E1);
// сериал соединение протокол W-Bus
169
mySerial.begin(19200);
// сериал соединение для gsm модуля
170
delay(2000);
171
NastroykaGSM ();
172
173
TimeWebasto = EEPROM.read(1)*60000UL;
174
Protocol = EEPROM.read(2);
175
ResetNumber = EEPROM.read(0);
176
for
(
int
i=0; i<12; i++) TelNumber1[i] = EEPROM.read (i+10);
177
for
(
int
i=0; i<12; i++) TelNumber2[i] = EEPROM.read (i+30);
178
179
}
180
181
182
void
loop
() {
183
test.read();
184
digitalWrite (StatusWebastoLED, webasto);
185
//если нажали тактовую кнопку меняем состояние котла на противоположное
186
if
(test.event_click_Dn (StartButton)) {
187
if
(!webasto) {StartWebasto(); report =
false
;}
188
else
StopWebasto();
189
}
190
191
if
(Protocol!=2) {
if
(TempVyhlopC - TempUlicaC > 20) startWebasto_OK = 1;
192
else
startWebasto_OK = 0;}
193
194
if
(Protocol==1) webasto = !digitalRead (Sost);
195
196
if
(Protocol==2) W_Bus();
197
198
//ниже для таймера старта котла по W-BUS и аналогу
199
200
if
(timerenabledStart_W_BUS && TIMEREXPIRED_Start_W_BUS) StopWebasto();
201
202
//ниже для таймера создания импульса на старт ДВС
203
204
if
(timerenabledStartEng && TIMEREXPIRED_StartEng) {digitalWrite (StartEng, LOW); timerenabledStartEng=
false
;}
205
206
engine = !digitalRead (Eng);
207
ignition= !digitalRead (IGN);
208
ohrana= !digitalRead (Ohrana);
209
trevoga= !digitalRead (Trevoga);
210
211
if
(webasto && report) timerReport ();
212
if
(reportEngine) timerReportEngine ();
213
if
(trevoga && !alarmSMS) AlarmSMS ();
214
if
(!ohrana) alarmSMS =
false
;
215
216
if
(gsmOK)readSMS();
217
CheckConnect_GSM();
218
voltmetr();
219
WebastoOprosImpulse ();
220
221
222
}
223
224
void
voltmetr()
//____________Цикл "Вольтметр"__измерение напряжения на выходе ИБП
225
226
{
227
volt = analogRead(A7);
// А7 аналоговый вход вольтметра
228
vout = (volt * 4.92) / 1024;
229
Vpit = vout / (9950.0/(98930.0+9950.0));
// По формуле Vpit = vout / (R2/(R1+R2))
230
if
(Vpit<0.09) Vpit=0.0;
// Округление до нуля
231
}
232
233
234
235
236
237
238
// Вектор прерывания для Dallas DS18B20
239
ISR (WDT_vect){
//вектор прерывания WD
240
static
boolean n=0;
// флаг работы: запрос температуры или её чтение
241
n=!n;
242
if
(n) {ds.reset();
// сброс шины
243
ds.write(0xCC);
//обращение ко всем датчикам
244
ds.write(0x44);
// начать преобразование (без паразитного питания)
245
}
246
else
{ds.reset();
247
ds.select(VyhlopC);
248
ds.write(0xBE);
// Read Scratchpad (чтение регистров)
249
TempVyhlopC = ds.read() | (ds.read()<<8);
//прочитаны 2 байта
250
TempVyhlopC = TempVyhlopC / 16;
251
// получение с 2-го датчика
252
ds.reset();
253
ds.select(EngineC);
254
ds.write(0xBE);
// Read Scratchpad (чтение регистров)
255
TempEngineC = ds.read() | (ds.read()<<8);
//прочитаны 2 байта
256
TempEngineC = TempEngineC/16;
257
ds.reset();
258
ds.select(UlicaC);
259
ds.write(0xBE);
// Read Scratchpad (чтение регистров)
260
TempUlicaC = ds.read() | (ds.read()<<8);
//прочитаны 2 байта
261
TempUlicaC = TempUlicaC / 16;
262
// получение с 2-го датчика
263
ds.reset();
264
ds.select(SalonC);
265
ds.write(0xBE);
// Read Scratchpad (чтение регистров)
266
TempSalonC = ds.read() | (ds.read()<<8);
//прочитаны 2 байта
267
TempSalonC = TempSalonC/16 ;
268
}}
269
270
271
272
273
274
275
276
void
StartWebasto()
277
{
278
if
(Protocol==1){ digitalWrite (VyhodWebasto, LOW);
279
timer=time;
280
timerenabled=
true
;}
281
282
else
if
(Protocol==2||Protocol==3){
283
StartMessageRepeat = 0;
284
webasto = 1; digitalWrite (VyhodWebastoAnalog, HIGH);
285
timerStart_W_BUS=millis();
286
timerenabledStart_W_BUS =
true
;}
287
288
report =
true
; EndReportMillis = millis();
289
}
290
291
void
StopWebasto()
292
{
293
if
(Protocol==1){ digitalWrite (VyhodWebasto, LOW);
294
timer=time;
295
timerenabled=
true
;}
296
297
else
if
(Protocol==2||Protocol==3){
298
StopMessageRepeat = 0;
299
webasto = 0; digitalWrite (VyhodWebastoAnalog, LOW);
300
timerenabledStart_W_BUS =
false
;}
301
report =
false
;
302
}
303
304
305
306
307
void
WebastoOprosImpulse (){
308
309
// опрос допканалов от сигнализации включения/ выключение котла и таймер импульса старт/стоп котла
310
time = millis();
311
if
(timerenabled) {
if
(TIMEREXPIRED) {digitalWrite (VyhodWebasto, HIGH); timerenabled=
false
;}}
312
else
{
if
(!digitalRead (DopOn) && !webasto) {StartWebasto(); KTOreport = 1;}
313
if
(!digitalRead (DopOff) && webasto) StopWebasto();
314
}}
315
316
317
// цикл таймера отправки отчета об успешности запуска котла (отчёт через 6 мин после старта)
318
void
timerReport () {
319
if
(millis() - EndReportMillis > 360000UL)
320
{EndReportMillis = millis(); report =
false
; SMSzapros(); }}
321
322
// цикл таймера отправки отчета об успешности запуска ДВС (отчёт через 30сек после старта)
323
void
timerReportEngine () {
324
if
(millis() - EndReportEngine > 30000)
325
{EndReportEngine = millis(); reportEngine =
false
; SMSzapros();}}
326
327
328
329
330
331
void
NastroykaGSM () {
332
mySerial.print(F(
"AT+CMGF=1\r"
));
//устанавливает текстовый режим смс-сообщения
333
delay(200);
334
mySerial.print(F(
"+IFC=1, 1\r"
));
//устанавливает программный контроль потоком передачи данных
335
delay(200);
336
mySerial.print(F(
"AT+CPBS=\"SM\"\r"
));
//открывает доступ к данным телефонной книги SIM-карты
337
delay(200);
338
mySerial.print(F(
"AT+GSMBUSY=1\r"
));
//запрет всех входящих звонков
339
delay(300);
340
mySerial.print(F(
"AT+CNMI=1,2,2,1,0\r"
));
//включает оповещение о новых сообщениях
341
delay(300);
342
mySerial.print(F(
"AT+CMGDA=\"DEL ALL\"\r"
));
// удаляем все смс, ки
343
delay(2000);
344
}
345
346
void
startNumber1SMS()
//__________________Цикл подготовки модуля к отправке СМС-сообщений по первому номеру
347
{
348
mySerial.print(F(
"AT+CMGF=1\r"
));
349
delay(200);
350
mySerial.print(F(
"AT+CMGS=\""
)); mySerial.print(TelNumber1); mySerial.println(
"\""
);
351
delay(400);
352
}
353
354
void
startNumber2SMS()
//__________________Цикл подготовки модуля к отправке СМС-сообщений по второму номеру
355
{
356
mySerial.print(F(
"AT+CMGF=1\r"
));
357
delay(200);
358
mySerial.print(F(
"AT+CMGS=\""
)); mySerial.print(TelNumber2); mySerial.println(F(
"\""
));
359
delay(400);
360
}
361
362
void
startBufferNumberSMS()
//__________________Цикл подготовки модуля к отправке СМС-сообщений по второму номеру
363
{
364
mySerial.print(F(
"AT+CMGF=1\r"
));
365
delay(200);
366
mySerial.print(F(
"AT+CMGS=\""
)); mySerial.print(BufferNumber); mySerial.println(F(
"\""
));
367
delay(400);
368
}
369
370
void
EndSMS ()
371
{
372
mySerial.println((
char
)26);
// Команда отправки СМС
373
delay(3000);
374
mySerial.print(F(
"AT+CMGDA=\"DEL ALL\"\r"
));
// удаляем все смс, ки
375
delay(1500);
376
}
377
378
379
void
readSMS()
//_____Цикл чтения входящих СМС-сообщений______________
380
{
381
if
(!mySerial.available())
return
;
382
char
currSymb = mySerial.read();
383
// Serial.print (currSymb);
384
if
(
'\r'
== currSymb)
385
{
386
if
(isStringMessage!=0&&isStringMessage!=10)
//если текущая строка - SMS-сообщение, отреагируем на него соответствующим образом
387
{
388
if
(!currStr.compareTo(
"ZAPROS"
)) { SMSzapros();}
// Передача параметров по СМС
389
else
if
(!currStr.compareTo(
"ZAPROSTEL"
)) { SMSzaprosTEL();}
// Передача номеров телефонов пользователей по СМС
390
391
392
393
else
if
(!currStr.compareTo(
"Webasto-ON"
)) {
if
(!webasto) {StartWebasto ();
// если получили команду на включение и вебаста в настоящий момент выключена - включаем
394
if
(isStringMessage == 1) {startNumber1SMS(); KTOreport = 1;}
395
else
if
(isStringMessage == 2) {startNumber2SMS(); KTOreport = 2;}
396
mySerial.println(F(
"Webasto Vkluchena"
)); EndSMS();}
397
398
else
{
if
(isStringMessage == 1) startNumber1SMS();
399
else
if
(isStringMessage == 2) startNumber2SMS();
400
mySerial.println(F(
"Webasto uzhe vkluchena"
)); EndSMS();}}
401
402
403
else
if
(!currStr.compareTo(
"Webasto-OFF"
)) {
if
(webasto){StopWebasto ();
// если получили команду на выключение и вебаста в настоящий момент включена - выключаем
404
if
(isStringMessage == 1) startNumber1SMS();
405
else
if
(isStringMessage == 2) startNumber2SMS();
406
mySerial.println(F(
"Webasto Otkluchena"
)); EndSMS();}
407
408
409
else
{
if
(isStringMessage == 1) startNumber1SMS();
410
else
if
(isStringMessage == 2) startNumber2SMS();
411
mySerial.println(F(
"Webasto uzhe otkluchena"
)); EndSMS();}}
412
413
414
else
if
(!currStr.compareTo(
"Engine-ON"
)) {
if
(!engine) { digitalWrite (StartEng, HIGH); timerStartEng=millis(); timerenabledStartEng=
true
; reportEngine =
true
; EndReportEngine = timerStartEng;
// если получили команду на включение ДВС и он в настоящий момент выключен - включаем
415
if
(isStringMessage == 1) {startNumber1SMS(); KTOreport = 1;}
416
else
if
(isStringMessage == 2) {startNumber2SMS(); KTOreport = 2;}
417
mySerial.println(F(
"Engine Start"
)); EndSMS();}
418
419
else
{
if
(isStringMessage == 1) startNumber1SMS();
420
else
if
(isStringMessage == 2) startNumber2SMS();
421
mySerial.println(F(
"Dvigatel uzhe rabotaet"
)); EndSMS();}}
422
423
else
if
(!currStr.compareTo(
"Engine-OFF"
)) {
if
(engine){ digitalWrite (StartEng, HIGH); timerStartEng=millis(); timerenabledStartEng=
true
; reportEngine =
false
;
// если получили команду на выключение ДВС и он в настоящий момент работает - выключаем
424
if
(isStringMessage == 1) startNumber1SMS();
425
else
if
(isStringMessage == 2) startNumber2SMS();
426
mySerial.println(F(
"Dvigatel ostanovlen"
)); EndSMS();}
427
428
429
else
{
if
(isStringMessage == 1) startNumber1SMS();
430
else
if
(isStringMessage == 2) startNumber2SMS();
431
mySerial.println(F(
"dvigatel uzhe ostanovlen"
)); EndSMS(); }}
432
433
434
else
if
(!currStr.compareTo(
"Impulse"
)) {Protocol = 1; EEPROM.write(2,Protocol);
if
(isStringMessage == 1) {startNumber1SMS(); mySerial.println(F(
"zapusk GND_impulse"
)); EndSMS();}
435
else
if
(isStringMessage == 2) {startNumber2SMS(); mySerial.println(F(
"zapusk GND_impulse"
)); EndSMS();}}
436
437
else
if
(!currStr.compareTo(
"W-BUS"
)) {Protocol = 2; EEPROM.write(2,Protocol); webasto = 0;
if
(isStringMessage == 1) {startNumber1SMS(); mySerial.println(F(
"zapusk W-BUS"
)); EndSMS();}
438
else
if
(isStringMessage == 2) {startNumber2SMS(); mySerial.println(F(
"zapusk W_BUS"
)); EndSMS();}}
439
440
else
if
(!currStr.compareTo(
"Potenzial"
)) {Protocol = 3; EEPROM.write(2,Protocol);
if
(isStringMessage == 1) {startNumber1SMS(); mySerial.println(F(
"zapusk +12V Potencial"
)); EndSMS();}
441
else
if
(isStringMessage == 2) {startNumber2SMS(); mySerial.println(F(
"zapusk +12V Potencial"
)); EndSMS();}}
442
443
444
else
if
(currStr.endsWith(
"min"
)) {TimeWebasto = currStr.toInt()*60000UL;
// для задания время цикла работы отправить сообщение вида "25 min", где 25 время работы в мин
445
if
(TimeWebasto>3540000UL) TimeWebasto = 3540000UL;
446
if
(TimeWebasto<=600000UL) TimeWebasto = 600000UL;
447
EEPROM.write(1,TimeWebasto/60000UL);
448
if
(isStringMessage == 1)startNumber1SMS();
449
else
if
(isStringMessage == 2) startNumber2SMS();
450
mySerial.print(F(
"Webasto time: "
)); mySerial.print(TimeWebasto/60000UL); mySerial.print(F(
"min"
)); EndSMS();}
451
452
453
else
if
(!currStr.compareTo(
"ResetNumbers"
)) {
if
(isStringMessage == 1) {startNumber1SMS(); mySerial.println(F(
"Phone numbers are erased"
)); EndSMS();
454
455
TelNumber1 =
"000000000000"
; TelNumber2 =
"000000000000"
;
for
(
int
i=0; i<12; i++) {EEPROM.write (i+10, TelNumber1[i]); EEPROM.write (i+30, TelNumber2[i]); }}}
456
457
else
if
(!currStr.compareTo(
"WriteNumber2"
)&& isStringMessage == 1) {
458
SaveNumber2 = 1; startNumber1SMS(); mySerial.println(F(
"Otpravte lyuboye SMS s nomera2 dlya sochraneniya nomera"
)); EndSMS();}
459
460
461
462
463
else
if
(!currStr.compareTo(
"Balance"
)) SMSbalance();
464
isStringMessage = 0;
465
}
466
else
if
(isStringMessage==10){
if
(!currStr.compareTo(
"WriteNumber1"
)) { TelNumber1 = BufferNumber;
for
(
int
i=0; i<12; i++) {EEPROM.write (i+10, BufferNumber[i]);}
467
startNumber1SMS(); mySerial.println(F(
"Tel Number#1 is saving in memory"
)); mySerial.print(
"Tel#1: "
); mySerial.println (TelNumber1); EndSMS();
468
}
469
else
if
(!currStr.compareTo(
"ZAPROS"
)) { SMSzapros();}
470
else
if
(!currStr.compareTo(
"ZAPROSTEL"
)) { SMSzaprosTEL();}
// Передача номеров телефонов пользователей по СМС
471
isStringMessage = 0;
472
473
}
474
475
476
477
478
else
if
(isStringMessage==0) {
if
(TelNumber1!=
"000000000000"
&& !SaveNumber2 && TelNumber1!=
"яяяяяяяяяяяя"
){
479
480
if
(currStr.startsWith(
"+CMT: \""
+TelNumber1)) { isStringMessage = 1; KTOzapros = 1; }
481
else
if
(currStr.startsWith(
"+CMT: \""
+TelNumber2)) { isStringMessage = 2; KTOzapros = 2; }
482
else
if
(currStr.startsWith(
"+CUSD: 0,"
))
//если текущая строка начинается с "+CUSD",то следующая строка является запросом баланса
483
{
484
if
(KTOzapros == 1) startNumber1SMS();
485
else
if
(KTOzapros == 2) startNumber2SMS();
486
mySerial.print (currStr);
487
EndSMS();
488
}
489
}
490
491
else
if
(currStr.startsWith(
"+CMT:"
) && !SaveNumber2) { isStringMessage = 10;
for
(
int
i =0; i<12; i++) {BufferNumber[i]=currStr[i+7];}}
492
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]);}
493
startNumber2SMS(); mySerial.println(F(
"Vash nomer sochranyon kak Number#2 v pamyati!"
));
494
mySerial.print(F(
"Tel1: "
)); mySerial.println(TelNumber1); mySerial.print(F(
"Tel#2: "
)); mySerial.println (TelNumber2); EndSMS(); SaveNumber2 = 0; }
495
496
}
497
498
currStr =
""
;
499
}
500
501
else
if
(
'\n'
!= currSymb) { currStr += String(currSymb);}
502
}
503
504
505
void
SMSzapros()
506
{
if
(isStringMessage == 10){
507
startBufferNumberSMS();
508
509
mySerial.println (F(
"Tel.number#1 has been no save in memory!"
));
510
mySerial.println (F(
"For save Tel#1 send SMS command \"WriteNumber1\""
));
511
mySerial.print(F(
"Tel#1: "
)); mySerial.println(TelNumber1);
512
mySerial.print(F(
"Tel#2: "
)); mySerial.println(TelNumber2);
513
}
514
515
516
517
else
{
518
519
if
(isStringMessage == 1) { startNumber1SMS();}
520
else
if
(isStringMessage == 2) { startNumber2SMS();}
521
else
if
(isStringMessage == 0) {
if
(KTOreport == 1) startNumber1SMS();
522
else
if
(KTOreport == 2) startNumber2SMS();}
523
if
(webasto) { mySerial.println (F(
"Webasto ON"
));
524
if
(startWebasto_OK) mySerial.println (F(
"StartWebasto OK"
));
525
else
mySerial.println (F(
"StartWebasto FAIL"
));}
526
else
mySerial.println (F(
"Webasto OFF"
));
527
528
if
(engine) mySerial.println (F(
"Engine ON"
));
529
else
mySerial.println (F(
"Engine OFF"
));
530
531
if
(ignition) mySerial.println (F(
"IGN ON"
));
532
else
mySerial.println (F(
"IGN OFF"
));
533
534
if
(ohrana) mySerial.println (F(
"OHRANA ON"
));
535
else
mySerial.println (F(
"OHRANA OFF"
));
536
537
if
(trevoga) mySerial.println (F(
"Vnimanie!!! Trevoga!!! Sirena Vkl!"
));
538
539
mySerial.print(F(
"Battery: "
)); mySerial.print (Vpit); mySerial.println(F(
"V"
));
540
mySerial.print(F(
"Engine: "
)); mySerial.print (TempEngineC); mySerial.println(F(
"*C"
));
541
mySerial.print(F(
"Vyhlop: "
)); mySerial.print (TempVyhlopC); mySerial.println(F(
"*C"
));
542
mySerial.print(F(
"Ulica: "
)); mySerial.print (TempUlicaC); mySerial.println(F(
"*C"
));
543
mySerial.print(F(
"Salon: "
)); mySerial.print (TempSalonC); mySerial.println(F(
"*C"
));
544
mySerial.print(F(
"Protocol: "
));
545
if
(Protocol==1) mySerial.println(F(
"GND Impulse"
));
546
else
if
(Protocol==2) mySerial.println(F(
"W-BUS"
));
547
else
if
(Protocol==3) mySerial.println(F(
"+12V Potencial"
));
548
mySerial.print(F(
"Webasto Time: "
)); mySerial.print (TimeWebasto/60000UL); mySerial.println(F(
"min"
));
549
mySerial.print(F(
"Resets: "
)); mySerial.println (ResetNumber);
550
551
}
552
EndSMS();
553
}
554
555
void
SMSzaprosTEL(){
556
if
(isStringMessage == 1) { startNumber1SMS();}
557
else
if
(isStringMessage == 2) { startNumber2SMS();}
558
else
if
(isStringMessage == 10) { startBufferNumberSMS();}
559
560
561
mySerial.print(F(
"Tel#1: "
)); mySerial.println(TelNumber1);
562
mySerial.print(F(
"Tel#2: "
)); mySerial.println(TelNumber2);
563
if
(TelNumber1!=
"000000000000"
&& TelNumber1!=
"яяяяяяяяяяяя"
){
564
mySerial.print(F(
"Protocol: "
));
565
if
(Protocol==1) mySerial.println(F(
"GND Impulse"
));
566
else
if
(Protocol==2) mySerial.println(F(
"W-BUS"
));
567
else
if
(Protocol==3) mySerial.println(F(
"+12V Potencial"
));
568
mySerial.print(F(
"Webasto Time: "
)); mySerial.print (TimeWebasto/60000UL); mySerial.println(F(
"min"
));
569
mySerial.print(F(
"Resets: "
)); mySerial.println (ResetNumber);
570
}
571
EndSMS();
572
}
573
574
575
void
SMSbalance() {
576
mySerial.print(F(
"AT+CMGF=1\r"
));
577
delay(200);
578
579
mySerial.println (F(
"AT+CUSD=1,\"#100#\""
));
580
581
//mySerial.println("AT+CMGS=\"#100#\"");
582
// mySerial.println("ATD#100#");
583
//mySerial.println("AT + CMGS = \"111\""); //
584
delay(2000);
// команда на замену на транслит *111*6*2#
585
//mySerial.println ("11");
586
//EndSMS();
587
}
588
589
590
void
AlarmSMS() {
591
startNumber1SMS();
592
mySerial.println (F(
"Vnimanie!!! Trevoga!!! Sirena Vkl!"
));
593
EndSMS();
594
startNumber2SMS();
595
mySerial.println (F(
"Vnimanie!!! Trevoga!!! Sirena Vkl!"
));
596
EndSMS();
597
alarmSMS =
true
;
598
}
599
600
void
W_Bus (){
601
if
(webasto) {
602
if
(StartMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800)){
603
604
for
(
int
i = 0; i<5; i++)
Serial
.write (Zapusk21[i]);
605
StartMessageRepeat++;
606
Prev_PeriodW_BusStartStop = millis();
607
608
}
609
if
(StartMessageRepeat>=4){
if
(millis()-Prev_PeriodW_BusMessage>5000) {
610
//делаем периодическое поддержание связи W-BUS
611
// наверное сканает отправка сообщения о состоянии котла
612
// т.е. ,например, отправляем периодически запрос на показания датчиков
613
// состоянием работы котла будет наличие или отсутствие пламени
614
if
(flagStartPresent) {
for
(
int
i = 0; i<5; i++)
Serial
.write (Zapusk21[i]); }
615
//else {for (int i = 0; i<5; i++) Serial.write (StateMessage[i]);}
616
flagStartPresent = !flagStartPresent;
617
StopMessageRepeat = 0;
618
619
Prev_PeriodW_BusMessage = millis();
620
}}}
621
622
623
624
625
626
else
if
(StopMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800)){
627
for
(
int
i = 0; i<4; i++)
Serial
.write (Stop[i]);
628
StopMessageRepeat++;
629
StartMessageRepeat = 0;
630
Prev_PeriodW_BusStartStop = millis();
631
632
633
}
634
635
}
636
637
638
639
void
CheckConnect_GSM (){
640
if
(millis()-prevCheckConnect>(unsigned
long
)intervalCheck*60000UL){
//тут периодически раз в интервал шлем "АТ" для проверки связи
641
mySerial.println (F(
"AT"
));
642
timerenabledWaitOK = 1; timerWaitOK = millis();
643
gsmOK =
false
;
644
prevCheckConnect = millis(); }
645
646
if
(timerenabledWaitOK && millis()-timerWaitOK>6000) {
//если таймер после отправки "AT" включен и истекло время таймера 6 сек
647
timerenabledWaitOK = 0;
//обнуляем таймер
648
if
(!gsmOK) {
// и если GSM так и не ответил, опять отправляем "AT" и включаем таймер
649
mySerial.println (F(
"AT"
));
650
timerenabledWaitOK = 1; timerWaitOK = millis();
651
errors++;
if
(errors>5) errors = 5;
// +1 к ошибкам связи
652
653
}
654
}
655
656
657
// если GSM ещё не ответил, проверяем буфер уарт
658
if
(!gsmOK && !resettimer) {
659
if
(mySerial.available()>0){
660
char
currSymb = mySerial.read();
661
if
(
'\r'
== currSymb) {
662
663
if
(!currStr.compareTo(
"OK"
)) {gsmOK =
true
; errors=0;}
//если GSM отвеитил ОК, то связь есть, ошибки на ноль
664
currStr =
""
;
665
}
666
667
else
if
(
'\n'
!= currSymb) {currStr += String(currSymb);}}}
668
669
670
if
(errors>=5) Restart();
// если количество ошибок связи больше или равно 5, делаем рестарт
671
672
}
673
674
void
Restart(){
675
676
if
(!resettimer) {digitalWrite (ResetGSM, 1); resettimer = 1; resetTimer = millis();}
//разрываем питание GSM, включаем таймер
677
else
if
(millis()- resetTimer>3000 ) {
// если таймер в 3 сек кончился, восстанавливаем питание GSM, в еепром +1 к количеству рестартов
678
digitalWrite (ResetGSM, 0);
679
resettimer = 0;
680
errors=0;
681
ResetNumber++;
682
gsmOK =
true
;
683
EEPROM.write (0, ResetNumber);
684
delay (3000); NastroykaGSM ();}
685
686
687
688
}
плата
Да, совершенно верно, котёл штатный. Вопрос конечно этот самому интересен будет ли он по +12V запускаться....но скачав документацию (описание + схемы соединений) предполагаю что работать должно. В любом случае скоро узнаем и напишу здесь. Главное чтобы конфликта не было по CAN.
А по поводу использовать MCP2515 - я уже получил из Китая его именно для этих целей, так что выкладывайте прошивку CAN хакера если найду время с удовольствием посижу с ним.
Хочу собрать полную схему (с LM393) так как машины меняются а сегодня новые котлы так понимаю уже все работают по W-Bus....возможно пригодится.
на портале carhelp.info много полезного найдете на этот счет - как запускать штатные котлы. Вам нужно узнать, есть ли у вашего котла шина W-Bus, если есть, то нужно попробовать запустить диагноситку котла по этой шине оригинальной вебастовской программой WTT при помощи обычного к-лайн адаптера. Если диагностика получится, всё упрощается.
схема к-лайн
программа Webasto Termo Test
ДА, пару лет назад использовал эту программу (WTT) для ремонта своего котла - не пропаяно было хорошо одно сопротивление. На каком-то форуме писал об этом с фото.
Значит можно попробовать подключиться к шине используя Вашу схему!?
Сейчас уже схему не вспомню но кажется именно по этой шине котёл соединён с приборной панелью и имеет название i-bus а уже приборная панель с CAN шиной. То есть через диагностический разъём авто к котлу с помощью WTT не подключиться, собирал всё дома на столе и подключал.
Скетч Can Hacker
01
#include <can.h>
02
#include <mcp2515.h>
03
04
#include <CanHacker.h>
05
#include <CanHackerLineReader.h>
06
#include <lib.h>
07
08
#include <SPI.h>
09
#include <SoftwareSerial.h>
10
11
const
int
SPI_CS_PIN = 10;
12
const
int
INT_PIN = 2;
13
14
const
int
SS_RX_PIN = 3;
15
const
int
SS_TX_PIN = 4;
16
17
CanHackerLineReader *lineReader = NULL;
18
CanHacker *canHacker = NULL;
19
20
SoftwareSerial softwareSerial(SS_RX_PIN, SS_TX_PIN);
21
22
void
setup
() {
23
Serial
.begin(115200);
24
while
(!
Serial
);
25
SPI.begin();
26
softwareSerial.begin(115200);
27
28
Stream *interfaceStream = &
Serial
;
29
Stream *debugStream = &softwareSerial;
30
31
32
canHacker =
new
CanHacker(interfaceStream, debugStream, SPI_CS_PIN);
33
//canHacker->enableLoopback(); // uncomment this for loopback
34
lineReader =
new
CanHackerLineReader(canHacker);
35
36
pinMode(INT_PIN, INPUT);
37
}
38
39
void
loop
() {
40
CanHacker::ERROR error;
41
42
if
(digitalRead(INT_PIN) == LOW) {
43
error = canHacker->processInterrupt();
44
handleError(error);
45
}
46
47
error = lineReader->process();
48
handleError(error);
49
}
50
51
void
handleError(
const
CanHacker::ERROR error) {
52
53
switch
(error) {
54
case
CanHacker::ERROR_OK:
55
case
CanHacker::ERROR_UNKNOWN_COMMAND:
56
case
CanHacker::ERROR_NOT_CONNECTED:
57
case
CanHacker::ERROR_MCP2515_ERRIF:
58
case
CanHacker::ERROR_INVALID_COMMAND:
59
return
;
60
61
default
:
62
break
;
63
}
64
65
softwareSerial.print(
"Failure (code "
);
66
softwareSerial.print((
int
)error);
67
softwareSerial.println(
")"
);
68
69
digitalWrite(SPI_CS_PIN, HIGH);
70
pinMode(LED_BUILTIN, OUTPUT);
71
72
while
(1) {
73
int
c = (
int
)error;
74
for
(
int
i=0; i<c; i++) {
75
digitalWrite(LED_BUILTIN, HIGH);
76
delay(500);
77
digitalWrite(LED_BUILTIN, LOW);
78
delay(500);
79
}
80
81
delay(2000);
82
} ;
83
}
библиотеки для скетча CanHacker (уже настроены на кварц 8 Мгц CAN-модуля)
программа CanHacker
Скорость ком порта в программе CanHacker в настройках делаем 115200
схема подключения
Собираете два адаптера из сообщения #84 или легче покупаете, Один для подключения WTT к котлу, второй - чтобы посниффить обмен данными. Когда узнаете какие байты там летают, можно будет запускать котёл по i-bus (полагаю тот же W-bus)
Спасибо за схему и скетч. Один адаптер есть им собственно и ковыряюсь в авто (прошивка / кодировка блоков) второго нет, попробую купить.... Китай совсем обленил увы, да и часто получается что проще и Дешевле купить готовое устройство чем собирать в одном экземпляре. Исключение составляет - хобби.
Почти закончил собирать плату. Пока провожу эксперименты на столе, надеюсь скоро начнуться полевые испытания!
Если позволите ещё один момент замечен при проверке.
Всё прекрасно работает (смс команды) пока не отключить питание. После повторного включения питания и спустя даже 10 минут устройство никак не реагирует на смс команды пока не нажать кнопку Reset на Nano. После этого снова начинает всё работать.
И ещё подскажите в какую строку и что добавить чтобы в мониторе порта увидеть напряжение АКБ (исключительно для настройки) ? Понижающий DC-DC отличается от Вашего и шунтирует входным сопротивлением делитель напряжения. Вместо 13,70 приходит в смс 12,65. Хочу подобрать подстроичником, но каждый раз отправлять смс.......
193
void
voltmetr()
//____________Цикл "Вольтметр"__измерение напряжения на выходе ИБП
194
195
{
196
volt = analogRead(A7);
// А7 аналоговый вход вольтметра
197
vout = (volt * 4.92) / 1024;
198
Vpit = vout / (9950.0/(98930.0+9950.0));
// По формуле Vpit = vout / (R2/(R1+R2))
199
if
(Vpit<0.09) Vpit=0.0;
// Округление до нуля
200
}
вот здесь 4,92 это напряжение питания на ардуино, реальное измеренное вольтметром , 9950 это реальное измеренное сопротивление плеча 10К делителя напряжения, 98930 - это реальное измеренное сопротивление плеча 100К делителя напряжения. Измерьте и подставьте свои данные, должно быть ближе к правде. Если после этого отличается от реального напряжения, корректируйте ещё значение сопротивлений.
Скетч для настройки вольтаметра с выводом в терминал.
01
#define analogInput A7
02
float
vout = 0.0;
03
float
vin = 0.0;
04
float
R1 = 100000.0;
// сопротивление R1 (100K)
05
float
R2 = 10000.0;
// сопротивление R2 (10K)
06
int
value = 0;
07
void
setup
(){
08
pinMode(analogInput, INPUT);
09
Serial
.begin (9600);
10
}
11
void
loop
(){
12
// считывание аналогового значения
13
value = analogRead(analogInput);
14
vout = (value * 5.0) / 1024.0;
15
vin = vout / (R2/(R1+R2));
16
if
(vin<0.09) vin=0.0;
// обнуляем нежелательное значение
17
Serial
.print(
"INPUT V= "
);
18
Serial
.println(vin);
19
delay(500);
20
}
вот тут хз, у меня тоже так было на одной ардуино (от robotdyn ), на другой все норм. надо пробовать на другом МК. попробуйте в Setup строка 115 задержку на 6...7 секунд повысить
Приветствую. Спасибо за скетч - подобрал в программе величинами сопротивлений значение напряжения. Про делитель напряжения как бы всё понятно, но как ранее заметил что DC-DC шунтирует этот делитель и показывает "погоду" вместо напряжения. (Если запитать DC-DC от отдельного источника то проблем нет). В общем сейчас всё хорошо (значения в программе кстати получились далеки от истины).
Появилось время и добрался до авто. Идёт с фишки от котла три провода - один на насос, второй на i-BUS (CAN) и третий на таймер (точнее сказать на связку Telestart + timer) которого нет но можно дооснастить. На схеме этот провод идёт на квадратную фишку таймера на контакт "OUT". Отсюда появился вопрос - по какому протоколу работает связка таймер-котёл? Если W-Bus то можно попробовать подключить выход с Вашей конструкции на этот провод!?
А Подозреваю что на проводе OUT должен быть просто потенциал 12в при включении. Но если даже там цифра, мой вариант может и подойдет. По крайней мере так включали некоторые штатные котлы. Машина то какая?
Можно просто подать 12в попробовать. По идее на w-bus шине такие уровни сигналов.
MaksVV,
1. Получилось сделать контроль зависаний? Я писал выше #63
2. все возможности по энергосбережению в микроконтроллере AVR описаны тут https://www.gammon.com.au/power
спасибо по ссылке почитаю. Контроль зависаний попытался сделать. Добавил в скетч (сообщение #82). Нарисовал новую плату с реле. Т.е. питание GSM сидит на нормально-замкнутых контактах реле. При рестарте подается питание на реле и оно размыкает питание GSM. Но это только пробная версия, ещё ничего не проверял. Т.к. нет времени и детали ещё не дошли.
реле применил миниатюное, такое
не вижу на плате реле, ткните носом пожалуйста
нет ли в планах нарисовать схему, что бы проще было разбираться откуда куда и зачем?
реле между контактами gsm модуля. Если gsm модуль на панельки устанавливать, то он высоко сидит, туда это реле по идее влезть должно, судя по его размерам.
время жалко, а что вам кроме реле не понятно?
схема надеюсь нигде не накосячил.