Автоматические ворота с управлением по звонку
- Войдите на сайт для отправки комментариев
Втр, 13/11/2018 - 01:52
Здравствуйте! Ищу программиста который сможет написать программу для ардуино для открывания автоматических ворот при помощи звонка и/или смс.
Есть Ардуино НАНО, sim800L.
Основные функции:
1. Возможность удобного просмотра разрешенных номеров
2. Добавление/удаление разрешенных номеров по смс
3. Ведение логов открывания/закрывания с указанием даты\времени
4. Запрос баланса и получение смс на номер администратора.
5. Запрос количества циклов открывания\закрывания за 24 часа\ месяц.
Для опытных думаю дело 30 минут. Спасибо всем кто откликнется!
От 8000 рублей
Andycat2013@yandex.ru
PS студент? С такими запросами не найдёте дёшево и качественно.
Для опытных думаю дело 30 минут. Спасибо всем кто откликнется!
30? Много что-то. Не более десяти.
Это для садоводцеского товарищества. Хотим сделать пропучкной режим для членов снт. Пешком можно будет ходить без ключа, а вот на машине заехать смогут только те кто не имеент долгов по взносам. По этому будет порядка 100 номеров в белом списке, остальные пешком или заплатят долги.
Реально сделать дешевле? И оставить только самую важную функцию: добавление\удаление разрешенного номера по смс.
И действительно, может быть у когото есть готовый вариант что бы только поправить?
На ютубе есть несколько роликов по этой теме, но там не совсем то что нужно.
Например есть такой код. Но там с использованием дисплея. Он нам не нужен. И отсутствует функция добавления новых номеров.
https://yadi.sk/d/f0el4pHEp2jMT
https://www.youtube.com/watch?v=78TJRGNDf-w
100 номеров....
100 номеров....
Эти 100 номеров будут сразу добавлены в коде. Потом только добавлять\удалять.
Или памяти может не хватить ? Пишут что надо использовать EEPROM
И действительно, может быть у когото есть готовый вариант что бы только поправить?
есть, но тоже не бесплатно, озвучьте свою цену - всем проще будет. Да и хотелки уменьшите, и конечно 100 номеров и логи входов/выходов....это вам явно хранить как минимум где нибудь в облаке надо.
Есть готовый такой вариант (4990 рублей):
- прием команд по СМС по разрешенному списку (в скетче задается)
- отправка подтверждений/команд по СМС
- прием команд/данных по UART от внешнего устройства, в реальном устройстве это роутер с измененной прошивкой, который принимает команды от сервера, и контролирует работоспособность устройств (видеокамера, GPS и еще там что-то) в служебном авто.
- отправка HTTP запроса/ссылка на сервер - ведение лога состояний внешних устройств
- выполнение команд по звонку (DTMF)
Архитектура достаточно гибкая - можно нарисовать много чего.
И действительно, может быть у когото есть готовый вариант что бы только поправить?
есть, но тоже не бесплатно, озвучьте свою цену - всем проще будет. Да и хотелки уменьшите, и конечно 100 номеров и логи входов/выходов....это вам явно хранить как минимум где нибудь в облаке надо.
Есть готовый такой вариант (4990 рублей):
- прием команд по СМС по разрешенному списку (в скетче задается)
- отправка подтверждений/команд по СМС
- прием команд/данных по UART от внешнего устройства, в реальном устройстве это роутер с измененной прошивкой, который принимает команды от сервера, и контролирует работоспособность устройств (видеокамера, GPS и еще там что-то) в служебном авто.
- отправка HTTP запроса/ссылка на сервер - ведение лога состояний внешних устройств
- выполнение команд по звонку (DTMF)
Архитектура достаточно гибкая - можно нарисовать много чего.
Ок. Можно начать с самого простого.
1. Что бы просто при звонке из белого списка открывались ворота, при повторном закрывались.
2. Добавление/удаление номеров по смс (с телефона администратора)
Логи и прочее пока не нужно. Хотел бы увидеть цену в районе 1000р, а последующие доработки обсудеть отдельно.
mrgreen - мой вам совет, не делайте по звонку. это дико неудобно. Купите вот таких вот брелков (на Али от 100 рублей) и раздайте членам СНТ.
На каждый брелок зашейте свой код - так вы сможете регулировать, кому открывать, кому нет. И код будет проще
Со ста номерами, воможностью их удобного просмотра, логами и прочим от 7999 рублей. Простите, но это не 30 минут. Это дня два придется убить на код и отладку...
Хотел бы увидеть цену в районе 1000р, а последующие доработки обсудеть отдельно.
я пас...
1. Тут уже неоднократно обсуждали - по самому минимальному день работы - 2000 рублей и то не МСК, то что вы перечислили вместе с тестированием минимум пару дней.
2. Последующие доработки сложно реализовывать, т.к. в программу сразу необходимо закладывать нужную функциональность, иначе это будет костыли.
Хотел бы увидеть цену в районе 1000р, а последующие доработки обсудеть отдельно.
нереально, в таком случае ищите готовое в инете и сами дорабатывайте, готовых скетчей "включение чего-либо по звонку/СМС" - в инете сотни
mrgreen - мой вам совет, не делайте по звонку. это дико неудобно. Купите вот таких вот брелков (на Али от 100 рублей) и раздайте членам СНТ.
На каждый брелок зашейте свой код - так вы сможете регулировать, кому открывать, кому нет. И код будет проще
Изначально с этого и начинал. Но:
1. Представьте что хозяин участка с пультом далеко от ворот, а к нему приехали гости. Очень не удобно ехать к воротам - открывать дверь.
2. Например специальные службы приедут, скорая или пожарная. Нужно будет простить когото подойти к воротам и открыть их с пульта. А так, на воротах мой телефон, и в случае чего, я сам позвоню на ворота и открою.
3. Да и пенсионеров много, они запутаются в кнопках на пульте. Куда проще позвонить на номер ворот и все)
Хотел бы увидеть цену в районе 1000р, а последующие доработки обсудеть отдельно.
нереально, в таком случае ищите готовое в инете и сами дорабатывайте, готовых скетчей "включение чего-либо по звонку/СМС" - в инете сотни
Вот есть такой примерно. https://www.youtube.com/watch?v=qh7dqAzKq0Y
Но там нет функции добавление номеров по смс.
Может быть кто то доработает ?
3. Да и пенсионеров много, они запутаются в кнопках на пульте. Куда проще позвонить на номер ворот и все)
это вам так кажется. На самом деле пульт в разы проще телефона - делаете ВСЕ 4 кнопки на открытие ворот - запутаться невозможно.
3. Да и пенсионеров много, они запутаются в кнопках на пульте. Куда проще позвонить на номер ворот и все)
это вам так кажется. На самом деле пульт в разы проще телефона - делаете ВСЕ 4 кнопки на открытие ворот - запутаться невозможно.
Если не найду человека кто поправит код, придется с брелками делать. Но все же уверен, с телефона удобнее, и нет дополнительных брелков на ключах. телефон у всех есть, и на брелки тратиться не нужно.
Если не найду человека кто поправит код, придется с брелками делать.
с брелками тоже придется код писать....
RTU5015
RTU5024
RTU5025
а че бы садоводческому хозяйству не скинуться рубле по....и сделать нормально и через СМС и по интернету и по звонку и по брелкам
а че бы садоводческому хозяйству не скинуться рубле по....и сделать нормально и через СМС и по интернету и по звонку и по брелкам
судя по тому. что хотят "не пускать неплательщиков", там наверно половина членов не готова вкладывать ни рубля... Знаю я такие "коллективы" - не только сами ни копейки не дадут - еще и писать будут во все инстанции. что их незаконно лишили проезда к своему участку.
Так что ТС-у посоветую не расслаблятся - таким методом это не вы неплательщиков на участок не пустите - скорее это они заставят вас шлагбаум убрать.
И действительно, может быть у когото есть готовый вариант что бы только поправить?
есть, но тоже не бесплатно, озвучьте свою цену - всем проще будет. Да и хотелки уменьшите, и конечно 100 номеров и логи входов/выходов....это вам явно хранить как минимум где нибудь в облаке надо.
Есть готовый такой вариант (4990 рублей):
- прием команд по СМС по разрешенному списку (в скетче задается)
- отправка подтверждений/команд по СМС
- прием команд/данных по UART от внешнего устройства, в реальном устройстве это роутер с измененной прошивкой, который принимает команды от сервера, и контролирует работоспособность устройств (видеокамера, GPS и еще там что-то) в служебном авто.
- отправка HTTP запроса/ссылка на сервер - ведение лога состояний внешних устройств
- выполнение команд по звонку (DTMF)
Архитектура достаточно гибкая - можно нарисовать много чего.
Ок. Можно начать с самого простого.
1. Что бы просто при звонке из белого списка открывались ворота, при повторном закрывались.
2. Добавление/удаление номеров по смс (с телефона администратора)
Логи и прочее пока не нужно. Хотел бы увидеть цену в районе 1000р, а последующие доработки обсудеть отдельно.
За эти 2 хотелки 1500.
а че бы садоводческому хозяйству не скинуться рубле по....и сделать нормально и через СМС и по интернету и по звонку и по брелкам
судя по тому. что хотят "не пускать неплательщиков", там наверно половина членов не готова вкладывать ни рубля... Знаю я такие "коллективы" - не только сами ни копейки не дадут - еще и писать будут во все инстанции. что их незаконно лишили проезда к своему участку.
Так что ТС-у посоветую не расслаблятся - таким методом это не вы неплательщиков на участок не пустите - скорее это они заставят вас шлагбаум убрать.
Да, часть нелательщиков есть, но их не много, 15% от общего числа.. "Вы сначала сделайте, потом мы деньги заплатим". А на что делать если денег нет?
С этого года стало проще, доступ мы им не закрываем, пешком проходите пожалуйста,доступ к участку не ограничиваем. А на машине только те кто не имеет долгов, есть решение общего собрания. Так что будут писать, будем судиться.
Скажите Ваши контакты, обсудим.
А на машине только те кто не имеет долгов, есть решение общего собрания.
это незаконно. Никакое "общее собрание" не может лишить собственника права доступа к его собственности, а доступ предполагает не только проход. но и возможность что-то подвезти или вывезти. Суд наверняка проиграете.
Обычно в таких случаях давят на неплательщиков угрозами, но в общем-то, если попадется грамотный - вы ему даже брелок будете обязаны выдать за счет СНТ.
Вообще, конечно, если "отказников" всего 15% - непонятно. в чем проблема. Соберите деньги с оставшихся 85% и сделайте. Или они тоже согласны только на словах? :)
А на машине только те кто не имеет долгов, есть решение общего собрания.
это незаконно. Никакое "общее собрание" не может лишить собственника права доступа к его собственности, а доступ предполагает не только проход. но и возможность что-то подвезти или вывезти. Суд наверняка проиграете.
Обычно в таких случаях давят на неплательщиков угрозами, но в общем-то, если попадется грамотный - вы ему даже брелок будете обязаны выдать за счет СНТ.
Пусть юрист занимается, так или иначе это его работа. А вот неплательщику отбиваться сложнее, чем просто заплатить. Более того, в суд если подаст, то и долги его обяжут выплатить.
Пусть юрист занимается, так или иначе это его работа. А вот неплательщику отбиваться сложнее, чем просто заплатить. Более того, в суд если подаст, то и долги его обяжут выплатить.
проезд отдельно, долги отдельно. Причем незаконное ограничение доступа куда более простое дело (не в вашу пользу), чем взыскание долгов, которые должник еще и оспорить может.
Ну да ладно, это уже оффтоп.
RTU5015
RTU5024
RTU5025
Спасибо, подходящий вариант.
phoenixoid@yandex.ru
Плюсую!
0
Минусую!
0
р е а л и з у е м о - maslachenko767@mail.ru
Но все же уверен, с телефона удобнее, и нет дополнительных брелков на ключах. телефон у всех есть, и на брелки тратиться не нужно.
вы просто не представляете себе сложность и стоимость ведения учёта, запись и удаление номеров (100 штук) в белом списке с помощью смс.
запись и удаление номеров
что там сложного? кроме как уместить 100 номеров в eeprom просто невозможно :)
вот древний но рабочий код который прекрасно и читает и выводит и сохраняет номера по СМС
#include <avr/wdt.h> #include <EEPROM.h> // address 0 = count control users phone // address 1.... control users phones, first char - A - active D - deleted, last char = 0 #include "a6modem.h" #include <OneWire.h> #include <DallasTemperature.h> #include <RCSwitch.h> #define max_time_read_sms 120000UL // 2min #define max_time_read_command 10000UL // 10sec #define startEEPROMmessages 128 // 0 position = byte - current save posifion from 0 #define endEEPROMmessages 383 #define max_count_users_phone 6 #define max_len_sms 252 #define keypad_pin A0 #define min_time_period_key_press 1000 #define alarm_pin A1 #define rc_reciv_pin 2 #define ds18b20_pin 3 #define period_get_internal_temp 317947 // ~ 5 min #define pos_eeprom_relay1_mode 456 // 0 or FF - off 12 -on #define pos_eeprom_relay2_mode 458 // 0 or FF - off 21 -on #define pos_eeprom_count_reset_timeout 454 OneWire oneWire(ds18b20_pin); DallasTemperature sensors(&oneWire); RCSwitch mySwitch = RCSwitch(); unsigned long time_read_sms; unsigned long time_read_command; unsigned long time_unpress_key; byte gsmmode, submode; char OPSname[] = "Russia00"; char OPSbalance[] = "*99999#"; char* UnitCommands[] = {"addphone", "delphone", "getuptime", "getbalance", "gettemp", "resetmodem", "relay1on", "relay1off", "relay2on", "relay2off", "getrelay", "resetdevice"}; char sender[24]; char smsmsg[max_len_sms]; char begstr[] = "~NEWsSMS~"; char endstr[] = "~SUCCSMS~"; boolean sw_lcd_light; unsigned long time_sw_lcd_light; boolean req_temp; byte internal_temp; byte external_temp; unsigned long time_get_internal_temp; unsigned long time_req_internal_temp; word mas_str_temp[10]; byte med_str_pos = 0; byte med_str_cnt = 0; boolean minus_str_temp = false; void setup() { // put your setup code here, to run once: firststart(); } void loop() { // put your main code here, to run repeatedly: wdt_reset(); unsigned long current_millis = millis(); // lcd backlight control if (!sw_lcd_light) { word palm = analogRead(alarm_pin); if (palm < 500) { time_sw_lcd_light = current_millis; sw_lcd_light = true; digitalWrite(10, HIGH); } } else { if ((current_millis - time_sw_lcd_light) >= 30000) { // 30 sec - lcd light on sw_lcd_light = false; digitalWrite(10, LOW); } } // end lcd backlight control // get ext temp if (mySwitch.available()) { unsigned long receivedCode = mySwitch.getReceivedValue(); mySwitch.resetAvailable(); if ((receivedCode >= 11500UL) && (receivedCode <= 14750UL)) { receivedCode -= 11500; if (((receivedCode >= 2000UL) && (receivedCode <= 2600UL)) || ((receivedCode >= 0UL) && (receivedCode <= 400UL))) { if ((receivedCode <= 400UL)) { receivedCode = 2000UL - receivedCode; } // correct temp if (receivedCode <= 1900UL) { receivedCode -= 12UL; // 1.2 degree } else { if (receivedCode <= 1950UL) { receivedCode -= 8UL; // 0.8 degree } else { if (receivedCode <= 1999UL) { receivedCode -= 5UL; // 0.5 degree } } } // -- mas_str_temp[med_str_pos] = (word)(receivedCode); if ((++med_str_pos) >= 10) { med_str_pos = 0; } if ((++med_str_cnt) >= 10) { med_str_cnt = 10; } word sum_temp = 0; for (int i = 0; i < med_str_cnt; ++i) { sum_temp += mas_str_temp[i]; } sum_temp /= med_str_cnt; if (sum_temp < 2000) { minus_str_temp = true; sum_temp = 2000 - sum_temp; } else { minus_str_temp = false; sum_temp -= 2000; } sum_temp /= 10; external_temp = (byte)(sum_temp); } } } // end get ext temp byte result = a6work(); if ((result == 1) || (result == 2)) { if (result == 1) { domainmode(); } else { //timeout byte br = EEPROM.read(pos_eeprom_count_reset_timeout); if (br == 0xFF) br = 0; ++br; EEPROM.write(pos_eeprom_count_reset_timeout, br); wdt_disable(); a6resetmodem(); unsigned long delp = millis(); while ((millis() - delp) <= 20000); // boot modem firststart(); } } else { // other action // read sms mode if ((current_millis - time_read_sms) >= max_time_read_sms) { if (gsmmode == 1) { if (a6sendcmd("AT+CMGL=4", "OK", "", "", true) == 1) { // read SMS, =0 unread, =4 all gsmmode = 2; submode = 0; // mode read sms time_read_sms = current_millis; // after sucess send command read sms } } } // end read sms mode // read sms from eeprom for execute comand if ((current_millis - time_read_command) >= max_time_read_command) { if (gsmmode == 1) { time_read_command = current_millis; readSMSforCommand(); } } // end read command // read key pad if (gsmmode == 1) { if ((current_millis - time_unpress_key) >= min_time_period_key_press) { word kp = analogRead(keypad_pin); byte key_mode; if ((kp > 600) && (kp < 700)) { key_mode = 0; } else { if ((kp > 370) && (kp < 450)) { key_mode = 1; } else { if ((kp > 80) && (kp < 120)) { key_mode = 2; } else { if ((kp > 216) && (kp < 296)) { key_mode = 3; } else { if (kp < 20) { key_mode = 4; } else { key_mode = 5; // not press } } } } } if (key_mode < 5) { time_unpress_key = current_millis; switch (key_mode) { case 0: { char strtemp[4]; SendStrToLCD("Int="); strtemp[0] = '0' + internal_temp / 10; strtemp[1] = '0' + internal_temp % 10; strtemp[2] = 0; SendStrToLCD(strtemp); SendStrToLCD(" Ext="); if (minus_str_temp) strtemp[0] = '-'; else strtemp[0] = '+'; strtemp[1] = '0' + external_temp / 10; strtemp[2] = '0' + external_temp % 10; strtemp[3] = 0; SendStrToLCD(strtemp); SendStrToLCD(" "); break; } case 1: { if (a6sendcmd("AT+CREG?", "OK", "", "", true) == 1) { gsmmode = 3; submode = 1; } break; } case 2: { byte i = 0; while ((smsmsg[i] = OPSname[i]) != 0 ) ++i; smsmsg[i] = ' '; ++i; i = addTextUptime(i); smsmsg[i] = 0; SendStrToLCD(smsmsg); break; } case 3: { gsmmode = 100; // show phones from eeprom byte pc = EEPROM.read(0); if (pc == 0xFF) pc = 0; for (byte i = 0; ((i < pc) && (i < max_count_users_phone)); ++i) { byte possend = 0; boolean fle = true; word startpos = 1 + i * 14; if (EEPROM.read(startpos) == 'A') sender[possend] = 'A'; else sender[possend] = 'D'; ++possend; sender[possend] = ' '; ++possend; byte j = 0; while (EEPROM.read(startpos + j + 1) != 0) { sender[possend] = EEPROM.read(startpos + j + 1); ++j; ++possend; } sender[possend] = ' '; ++possend; sender[possend] = 0; SendStrToLCD(sender); unsigned long delp = millis(); while ((millis() - delp) <= 2000); wdt_reset(); } // end show phones resetModeAndClearRespBuf(); break; } case 4: { if (a6sendcmd("AT+CSQ", "OK", "", "", true) == 1) { gsmmode = 3; submode = 1; } break; } default: { } } } } } // end key pad // req temp if ((current_millis - time_req_internal_temp) >= period_get_internal_temp) { if ((gsmmode == 1) && (!req_temp)) { time_req_internal_temp = current_millis; sensors.requestTemperatures(); req_temp = true; time_get_internal_temp = current_millis; } } // end req temp -> get temp if ((current_millis - time_get_internal_temp) >= 1200) { if ((gsmmode == 1) && (req_temp)) { internal_temp = sensors.getTempCByIndex(0); req_temp = false; } } // end get internal temp } } void domainmode() { switch (gsmmode) { case 0: { // init modem switch (submode) { case 0: { // wait reponse first command AT if (a6sendcmd("ATE0", "OK", "", "", true) == 1) submode = 1; // no echo break; } case 1: { // wait reponse command ATE0 if (a6sendcmd("ATV1", "OK", "", "", true) == 1) submode = 2; // get text for error break; } case 2: { // wait reponse command ATV1 if (a6sendcmd("AT+CMEE=2", "OK", "", "", true) == 1) submode = 3; // get full text error break; } case 3: { // wait reponse command cmee if (a6sendcmd("AT+CLIP=1", "OK", "", "", true) == 1) submode = 4; // on aon break; } case 4: { // wait reponse command clip if (a6sendcmd("ATS0=3", "OK", "", "", true) == 1) submode = 5; // 3 ring break; } case 5: { // wait reponse command ats unsigned long delp = millis(); while ((millis() - delp) <= 30000); //delay for registration if (a6sendcmd("AT+CREG?", "+CREG: 1,1", "OK", "", true) == 1) submode = 6; // true registration //if (a6sendcmd("AT+CREG?", "OK", "", "", true) == 1) submode = 6; // registration break; } case 6: { // wait registration if (a6sendcmd("AT+CMGF=0", "OK", "", "", true) == 1) submode = 7; // mode SMS = PDU break; } case 7: { // wait mode sms if (a6sendcmd("AT+CMGD=1,4", "OK", "", "", true) == 1) submode = 8; // delete all sms break; } case 8: { // wait del sms if (a6sendcmd("AT+COPS?", "+COPS:", "OK", "", true) == 1) submode = 9; // load operator data break; } case 9: { // decode operator data a6getopsname(OPSname, OPSbalance); resetModeAndClearRespBuf(); // init ok digitalWrite(LED_BUILTIN, HIGH); SendByteToLCD(32, true); SendByteToLCD(223, false); SendByteToLCD(32, true); SendByteToLCD(226, false); SendByteToLCD(32, true); SendByteToLCD(241, false); SendByteToLCD(229, false); SendByteToLCD(242, false); SendByteToLCD(232, false); SendByteToLCD(32, true); SendByteToLCD('!', true); SendByteToLCD(32, true); wdt_enable(WDTO_8S); break; } } break; } case 1: { // main loop break; } case 2: { // mode read sms switch (submode) { case 0: { byte countsms = a6getcountsms(); if (countsms > 0) { while (countsms > 0) { // loop by sms a6readsms(countsms, sender, smsmsg); if ((getAllowCommandPhone(sender) == 1) || (getAllowCommandPhone(sender) == 2)) { // save sms to eeprom saveSMStoEEPROM(sender, smsmsg); } // - end loop sms --countsms; } // delete all sms if (a6sendcmd("AT+CMGD=1,4", "OK", "", "", true) == 1) submode = 1; } else { resetModeAndClearRespBuf(); // no sms } break; } default: { resetModeAndClearRespBuf(); } } break; } case 3: { // mode send sms and mode test commands switch (submode) { case 0: { if (a6sendcmd(smsmsg, "+CMGS:", "OK", "", false) == 1) submode = 1; break; } default: { resetModeAndClearRespBuf(); } } break; } case 4: { // mode get balance switch (submode) { case 0: { // decode USSD // send SMS text from USSD resetModeAndClearRespBuf(); // temp text, need submode = 1 break; } default: { resetModeAndClearRespBuf(); } } break; } default: { a6clearrespbuf(); } } } void firststart() { pinMode(A0, INPUT_PULLUP); pinMode(A1, INPUT_PULLUP); pinMode(10, OUTPUT); pinMode(rc_reciv_pin, INPUT); digitalWrite(10, LOW); // LCD backlight control sensors.begin(); time_req_internal_temp = 0; req_temp = false; sw_lcd_light = false; gsmmode = 0; submode = 0; // start time_read_sms = 0UL; time_read_command = 0UL; mySwitch.enableReceive(0); pinMode(A2, OUTPUT); // relay 1 pinMode(A3, OUTPUT); // relay 2 // on off relay if (EEPROM.read(pos_eeprom_relay1_mode) == 12) digitalWrite(A2, LOW); else digitalWrite(A2, HIGH); if (EEPROM.read(pos_eeprom_relay2_mode) == 21) digitalWrite(A3, LOW); else digitalWrite(A3, HIGH); // end on off relay pinMode(A4, OUTPUT); digitalWrite(A4, LOW); pinMode(A5, OUTPUT); digitalWrite(A5, LOW); a6initmodem(9600); // work - hard uart } void SerialPrintWin1251(char* textsms) { byte i = 0; while (textsms[i] != 0) { byte wb = textsms[i]; if (wb <= 128) { Serial.write(wb); } else { switch (wb) { case 168: { Serial.write(208); Serial.write(101); break; } case 184: { Serial.write(209); Serial.write(145); break; } default: { if (wb < 192) { Serial.write(wb); } else { if (wb < 240) { Serial.write(208); Serial.write(wb - 48); } else { Serial.write(209); Serial.write(wb - 112); } } } } } ++i; } } byte getAllowCommandPhone(char* sender) { if (strPos(sender, ADMIN_PHONE) >= 0) return 2; word rb = FindPhomeFromUsersList(sender); if ((rb > 1000) && (rb < 2000)) { return 1; } else { return 0; } } void saveSMStoEEPROM(char* sender, char* textsms) { byte l1 = strlen(sender); byte l2 = strlen(textsms); word lastpos = EEPROM.read(startEEPROMmessages); if ((lastpos == 0xFF) || ((lastpos + l1 + l2 + 12) >= (endEEPROMmessages - startEEPROMmessages))) lastpos = 0; lastpos += (startEEPROMmessages + 1); byte i = 0; while (begstr[i] != 0) { EEPROM.write(lastpos + i, begstr[i]); ++i; } EEPROM.write(lastpos + i, 0); lastpos += (i + 1); i = 0; while (sender[i] != 0) { EEPROM.write(lastpos + i, sender[i]); ++i; } EEPROM.write(lastpos + i, 0); lastpos += (i + 1); i = 0; while (textsms[i] != 0) { EEPROM.write(lastpos + i, textsms[i]); ++i; } EEPROM.write(lastpos + i, 0); lastpos += (i + 1); EEPROM.write(startEEPROMmessages, (lastpos - startEEPROMmessages - 1)); } void readSMSforCommand() { word lastpos = startEEPROMmessages + 1; word i, j, k; m3: i = 0; j = 0; k = 0; m1: byte eb = EEPROM.read(lastpos + i); if ((eb == begstr[i]) || (eb == endstr[i])) { if (eb == begstr[i]) ++j; if (eb == endstr[i]) ++k; if ((++i) >= 9) goto m2; goto m1; } else { return; } m2: if (k == 9) { // skip -> new sms lastpos += (k + 1); // find 0 and 0 i = 0; while (EEPROM.read(lastpos + i) != 0) ++i; lastpos += (i + 1); if (lastpos >= endEEPROMmessages) return; i = 0; while (EEPROM.read(lastpos + i) != 0) ++i; lastpos += (i + 1); if (lastpos >= endEEPROMmessages) return; goto m3; } if (j == 9) { // save to eeprom ~SUCCSMS~ i = 0; while ((endstr[i]) != 0) { EEPROM.write((lastpos + i), endstr[i]); ++i; } // new command lastpos += (j + 1); i = 0; while ((sender[i] = EEPROM.read(lastpos + i)) != 0) ++i; sender[i] = 0; lastpos += (i + 1); i = 0; while ((smsmsg[i] = EEPROM.read(lastpos + i)) != 0) ++i; smsmsg[i] = 0; lastpos += (i + 1); // find command j = 0; // num found command for (i = 0; i < 12; ++i) { // 12 commands if (strPos(smsmsg, UnitCommands[i]) >= 0) { j = i + 1; break; } } switch (j) { case 1: { if (getAllowCommandPhone(sender) != 2) return; // command for admin only if (CutPhoneFromText(smsmsg) != 1) return; // save phone to eeprom AddPhoneToUsersList(smsmsg); break; } case 2: { if (getAllowCommandPhone(sender) != 2) return; // command for admin only if (CutPhoneFromText(smsmsg) != 1) return; // delete phone from eeprom DelPhoneToUsersList(smsmsg); break; } case 3: { if (getAllowCommandPhone(sender) == 0) return; // command for any user // prepare send text i = 0; while ((smsmsg[i] = OPSname[i]) != 0 ) ++i; smsmsg[i] = ' '; ++i; i = addTextUptime(i); smsmsg[i] = 0; sendSMS(); break; } case 4: { if (getAllowCommandPhone(sender) == 0) return; // command for any user char strcmd[] = "AT+CUSD=1,"; i = 0; while ((sender[i] = strcmd[i]) != 0) ++i; j = 0; while ((sender[i] = OPSbalance[j]) != 0) { ++i; ++j; } sender[i] = ','; ++i; sender[i] = '1'; ++i; sender[i] = '5'; ++i; sender[i] = 0; a6sendcmd(sender, "OK", "+CUSD: 2,", ",72", true); gsmmode = 4; submode = 0; break; } case 5: { if (getAllowCommandPhone(sender) == 0) return; // command for any user // prepare send text char strtemp[] = "Int="; i = 0; while ((smsmsg[i] = strtemp[i]) != 0 ) ++i; strtemp[0] = '0' + internal_temp / 10; strtemp[1] = '0' + internal_temp % 10; strtemp[2] = 0; j = 0; while ((smsmsg[i] = strtemp[j]) != 0 ) { ++i; ++j; } smsmsg[i] = ','; ++i; strtemp[0] = 'E'; strtemp[1] = 'x'; strtemp[2] = 't'; strtemp[3] = '='; strtemp[4] = 0; j = 0; while ((smsmsg[i] = strtemp[j]) != 0 ) { ++i; ++j; } if (minus_str_temp) strtemp[0] = '-'; else strtemp[0] = '+'; strtemp[1] = '0' + external_temp / 10; strtemp[2] = '0' + external_temp % 10; strtemp[3] = 0; j = 0; while ((smsmsg[i] = strtemp[j]) != 0 ) { ++i; ++j; } smsmsg[i] = ','; ++i; i = addTextUptime(i); smsmsg[i] = 0; sendSMS(); break; } case 6: { if (getAllowCommandPhone(sender) == 0) return; // command for any user byte br = EEPROM.read(pos_eeprom_count_reset_timeout); if (br == 0xFF) br = 0; ++br; EEPROM.write(pos_eeprom_count_reset_timeout, br); wdt_disable(); a6resetmodem(); unsigned long delp = millis(); while ((millis() - delp) <= 20000); // boot modem firststart(); break; } case 7: { if (getAllowCommandPhone(sender) == 0) return; // command for any user // relay 1 ON EEPROM.write(pos_eeprom_relay1_mode, 12); digitalWrite(A2, LOW); unsigned long delp = millis(); while ((millis() - delp) <= 1000); // relay 2 ON EEPROM.write(pos_eeprom_relay2_mode, 21); digitalWrite(A3, LOW); break; } case 8: { if (getAllowCommandPhone(sender) == 0) return; // command for any user // relay 1 OFF EEPROM.write(pos_eeprom_relay1_mode, 00); digitalWrite(A2, HIGH); unsigned long delp = millis(); while ((millis() - delp) <= 1000); // relay 2 OFF EEPROM.write(pos_eeprom_relay2_mode, 00); digitalWrite(A3, HIGH); break; } case 9: { if (getAllowCommandPhone(sender) == 0) return; // command for any user // relay 2 ON EEPROM.write(pos_eeprom_relay2_mode, 21); digitalWrite(A3, LOW); unsigned long delp = millis(); while ((millis() - delp) <= 1000); // relay 1 ON EEPROM.write(pos_eeprom_relay1_mode, 12); digitalWrite(A2, LOW); break; } case 10: { if (getAllowCommandPhone(sender) == 0) return; // command for any user // relay 2 OFF EEPROM.write(pos_eeprom_relay2_mode, 00); digitalWrite(A3, HIGH); unsigned long delp = millis(); while ((millis() - delp) <= 1000); // relay 1 OFF EEPROM.write(pos_eeprom_relay1_mode, 00); digitalWrite(A2, HIGH); break; } case 11: { if (getAllowCommandPhone(sender) == 0) return; // command for any user // prepare send text char strtemp[] = "Rl1"; i = 0; while ((smsmsg[i] = strtemp[i]) != 0 ) ++i; if (EEPROM.read(pos_eeprom_relay1_mode) == 12) { strtemp[0] = 'o'; strtemp[1] = 'n'; strtemp[2] = 0; } else { strtemp[0] = 'o'; strtemp[1] = 'f'; strtemp[2] = 'f'; strtemp[3] = 0; } j = 0; while ((smsmsg[i] = strtemp[j]) != 0 ) { ++i; ++j; } smsmsg[i] = ','; ++i; strtemp[0] = 'R'; strtemp[1] = 'l'; strtemp[2] = '2'; strtemp[3] = 0; j = 0; while ((smsmsg[i] = strtemp[j]) != 0 ) { ++i; ++j; } if (EEPROM.read(pos_eeprom_relay2_mode) == 21) { strtemp[0] = 'o'; strtemp[1] = 'n'; strtemp[2] = 0; } else { strtemp[0] = 'o'; strtemp[1] = 'f'; strtemp[2] = 'f'; strtemp[3] = 0; } j = 0; while ((smsmsg[i] = strtemp[j]) != 0 ) { ++i; ++j; } smsmsg[i] = ','; ++i; i = addTextUptime(i); smsmsg[i] = 0; sendSMS(); break; } case 12: { if (getAllowCommandPhone(sender) != 2) return; // command for admin only // test WDT unsigned long delp = millis(); while ((millis() - delp) <= 20000); // reboot device after 8 sec break; } default: { } } } else { return; } } byte CutPhoneFromText(char* smstxt) { int pp = strPos(smstxt, "+79"); if (pp > 0) { byte cb = 0; for (byte i = 0; i < 12; ++i) { // +7 and 10 digit smstxt[cb] = smstxt[pp + cb]; ++cb; } smstxt[cb] = 0; if (cb == 12) return 1; } return 0; } void AddPhoneToUsersList(char* phoneNumber) { word rb = FindPhomeFromUsersList(phoneNumber); if (rb > 2000) { // set active number EEPROM.write((rb - 2000), 'A'); return; } if (rb > 1000) { return; } // add new number byte pc = EEPROM.read(0); if (pc == 0xFF) pc = 0; if (pc >= max_count_users_phone) pc = 5; // last number; word startpos = 1 + (pc * 14); byte i = 0; EEPROM.write(startpos, 'A'); while (phoneNumber[i] != 0) { EEPROM.write((startpos + 1 + i), phoneNumber[i]); ++i; } EEPROM.write((startpos + 1 + i), 0); ++pc; EEPROM.write(0, pc); } void DelPhoneToUsersList(char* phoneNumber) { word rb = FindPhomeFromUsersList(phoneNumber); if (rb > 1000) { // set delete number EEPROM.write((rb - 1000), 'D'); return; } } word FindPhomeFromUsersList(char* phoneNumber) { byte pc = EEPROM.read(0); if (pc == 0xFF) pc = 0; if (pc == 0) { return 0; } byte i; boolean fla = false; for (i = 0; ((i < pc) && (i < max_count_users_phone)); ++i) { boolean fle = true; word startpos = 1 + i * 14; if (EEPROM.read(startpos) == 'A') fla = true; else fla = false; byte j = 0; while (phoneNumber[j] != 0) { if (phoneNumber[j] != EEPROM.read(startpos + j + 1)) { fle = false; break; } ++j; } if (fle) { if (fla) { return (1000 + startpos); } else { return (2000 + startpos); } } } return 0; } byte addTextUptime(byte firstpos) { unsigned long cml = millis() / 1000UL; byte days = cml / 86400; byte hours = (cml % 86400) / 3600; byte mins = ((cml % 86400) % 3600) / 60; if (days > 9) { smsmsg[firstpos] = (days / 10) + '0'; ++firstpos; } smsmsg[firstpos] = (days % 10) + '0'; ++firstpos; smsmsg[firstpos] = 228; ++firstpos; smsmsg[firstpos] = 237; ++firstpos; smsmsg[firstpos] = '.'; ++firstpos; if (hours > 9) { smsmsg[firstpos] = (hours / 10) + '0'; ++firstpos; } smsmsg[firstpos] = (hours % 10) + '0'; ++firstpos; smsmsg[firstpos] = 247; ++firstpos; smsmsg[firstpos] = 224; ++firstpos; smsmsg[firstpos] = 241; ++firstpos; smsmsg[firstpos] = '.'; ++firstpos; if (mins > 9) { smsmsg[firstpos] = (mins / 10) + '0'; ++firstpos; } smsmsg[firstpos] = (mins % 10) + '0'; ++firstpos; smsmsg[firstpos] = 236; ++firstpos; smsmsg[firstpos] = 232; ++firstpos; smsmsg[firstpos] = 237; ++firstpos; smsmsg[firstpos] = '.'; ++firstpos; // add count timeout reset smsmsg[firstpos] = 'R'; ++firstpos; byte br = EEPROM.read(pos_eeprom_count_reset_timeout); smsmsg[firstpos] = '0' + (br / 100); ++firstpos; smsmsg[firstpos] = '0' + ((br % 100) / 10); ++firstpos; smsmsg[firstpos] = '0' + ((br % 100) % 10); ++firstpos; smsmsg[firstpos] = '.'; ++firstpos; return firstpos; } void sendSMS() { // convert msg to pdu format byte lenTextByChar = strlen(smsmsg); // move text to end buf byte i, j; for (i = 0; i < lenTextByChar; ++i) { smsmsg[max_len_sms - lenTextByChar + i] = smsmsg[i]; } byte curr_pos_pdu = 0; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; // SCA field smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '1'; ++curr_pos_pdu; // PDU type smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; // MR byte lenSenderPhone = strlen(sender); if (lenSenderPhone != 12) return; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = 'B'; ++curr_pos_pdu; // DA-PL smsmsg[curr_pos_pdu] = '9'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '1'; ++curr_pos_pdu; // DA-PT // convert sender number for (i = 0; i < lenSenderPhone; ++i) { sender[i] = sender[i + 1]; } sender[lenSenderPhone - 1] = 'F'; sender[lenSenderPhone] = 0; for (i = 0; i < lenSenderPhone; i += 2) { j = sender[i + 1]; sender[i + 1] = sender[i]; sender[i] = j; } for (i = 0; i < lenSenderPhone; ++i) { // DA-RP smsmsg[curr_pos_pdu] = sender[i]; ++curr_pos_pdu; } smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; // PID field smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '8'; ++curr_pos_pdu; // DCS field lenTextByChar *= 2; // UDL byte bb = lenTextByChar / 16; if (bb < 10) { smsmsg[curr_pos_pdu] = (bb + '0'); ++curr_pos_pdu; } else { smsmsg[curr_pos_pdu] = (bb + '0' + 7); ++curr_pos_pdu; } bb = lenTextByChar % 16; if (bb < 10) { smsmsg[curr_pos_pdu] = (bb + '0'); ++curr_pos_pdu; } else { smsmsg[curr_pos_pdu] = (bb + '0' + 7); ++curr_pos_pdu; } // UD - text by UCS2 for (i = 0; i < (lenTextByChar / 2); ++i) { bb = smsmsg[max_len_sms - (lenTextByChar / 2) + i]; if (bb < 0x7F) { smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; // convert to hex j = bb / 16; if (j < 10) { smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu; } else { smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu; } j = bb % 16; if (j < 10) { smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu; } else { smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu; } } else { switch (bb) { case 168: { smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '4'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '1'; ++curr_pos_pdu; break; } case 184: { smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '4'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '5'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '1'; ++curr_pos_pdu; break; } default: { if (bb < 192) { smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; // convert to hex j = bb / 16; if (j < 10) { smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu; } else { smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu; } j = bb % 16; if (j < 10) { smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu; } else { smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu; } } else { smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '4'; ++curr_pos_pdu; // convert to hex j = (bb - 176) / 16; if (j < 10) { smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu; } else { smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu; } j = (bb - 176) % 16; if (j < 10) { smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu; } else { smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu; } } } } } } // - smsmsg[curr_pos_pdu] = 26; smsmsg[curr_pos_pdu + 1] = 0; char strcmd[] = "AT+CMGS="; i = 0; while ((sender[i] = strcmd[i]) != 0) ++i; sender[i] = ((curr_pos_pdu / 2 - 1) / 10) + '0'; ++i; sender[i] = ((curr_pos_pdu / 2 - 1) % 10) + '0'; ++i; sender[i] = 0; a6sendcmd(sender, ">", "", "", false); gsmmode = 3; submode = 0; } void resetMode() { gsmmode = 1; submode = 0; // main loop } void resetModeAndClearRespBuf() { resetMode(); a6clearrespbuf(); }это вы к чему ?
что программа простецкая или дешёвая))))
Возможно я что-то упускаю, но коды мобильных операторов начинаются на 9, т.е. +79 можно не хранить. Тогда максимально возможное число (для номера +7(999)999-99-99) будет 999999999 или 3B 9A C9 FF - это 4 байта. Итого 4 х 100 = 400 байт. Я нигде не ошибся?
Возможно я что-то упускаю, но коды мобильных операторов начинаются на 9, т.е. +79 можно не хранить. Тогда максимально возможное число (для номера +7(999)999-99-99) будет 999999999 или 3B 9A C9 FF - это 4 байта. Итого 4 х 100 = 400 байт. Я нигде не ошибся?
ну да, усложнив логику обработки, согласен - возможно.
беда в другом - что делать когда их будет например 300 :)
Update: да вы расслабьтесь :) с ТС я уже общался, он реально понял что проще готовое устройство купить чем заказывать.
Приклеить еще одну обдурину сверху.
Взять ардуину с мегой 2560, там больше тыщи номеров влезет :) или прицепить внешнюю EEPROM.
А потрындеть :) Нам же это тоже интересно :)