помогите избавится от "string"
- Войдите на сайт для отправки комментариев
Пнд, 29/01/2018 - 14:43
Здравствуйте, не знаю пока нужен скетч или нет, нужен выложу, но он более 2500 строк... проблемма такая, программа работает хорошо, но хочу оптимизацию и дополнительное место для будущей можернизации устройства... и для этого хочу отказатся от стрингов :) жмут заразы. скетч без них занимает 1060 динамической памяти а с ними 1526...
что делаю с этими строками:
1) забиваю строку с модема m590e
2) проверяю совпадают ли строки
3) отправляю смс
понимаю надо использховать массивы char[] но каким образом пока не могу понять
#include <EEPROM.h> #include <SoftwareSerial.h> SoftwareSerial myGSM(3, 4); // RX3, TX4 #define MY_GSM Serial //#define MY_GSM myGSM #define OPEN "open" #define SIGNAL "signal" #define SIRENA_ON "sirena" #define RUCHNAYA "ruchnaya" #define AVTOMAT "avtomat" #define CLOSED "closed" #define TRUNK "trunk" #define SETUP "setup" #define HARD_RESET "reset" #define SBROS_NASTROEK "sbros" #define WRITE1 "write1" #define WRITE2 "write2" #define WRITE3 "write3" #define START_ON "start" #define START_OFF "stop" #define SRABOTKA_DVERI 1500 //время сработки активаторов дверей #define ENGINE_START_MAX_TIME 4 //В секундах масимальное время работы стартера типично 3 -10 сек #define ENGINE_WARM_TIME 1200000 //В миллисекундах время работы мотора после запуска 1200000 миллисекунд = 20 минут #define ZADERZHKA_LOG_NETRAL 600000 //задержка логической нейтрали #define DELTA 500 //задаем ffвремя для расброса времени посылаемого сигнала #define DELTA1 3400 //задаем время для расброса времени посылаемого сигнала #define RXD 2 #define PASSWORD "password" #define KOD_BRELKA1 111111 #define KOD_BRELKA 111111111 // код брелка #define KOD_KNOPKI_OPEN 13 #define KOD_KNOPKI_CLOSED 14 #define KOD_KNOPKI_CHANEL 11 #define KOD_KNOPKI_ZAPUSK 7 #define HAND_BRAKE_IN A3 // геркон на КПП "-" #define SHARGING_IN A2 //генератор #define KONCEVIKI A5// концевики дверей #define SHOCK_SENSOR_LOW A4 #define SHOCK_SENSOR_HIGH A4 #define PIN_ZAZHIGANIYA A1 #define ENGINE_OUT 9 //d9 adruino зажигание #define STARTER_OUT 14 //A0 adruino реле стартера #define POVOROT_OUT 6 // d6 поворотники #define SECPOWER_OUT 11 //d11 цепи вторичного питания печка, фары итд #define DOOR_CLOSE 8// d8 реле закрытия дверей #define SIRENA 7 #define DOOR_OPEN 12// d12реле открытия дверей #define STATUS_OUT 13 //d13 светодиод статуса системы горит = система готова к работе(включена, ручник стоит). одно мигание запущен с первой попытки 2 со второй 3 с третьей #define BAGAZHNIK_OUT 10// d9 багажник #define DOP_RELEY 5// дополнительное реле на выход boolean rucnik_OFF = 1; boolean actual_mode = 0; boolean allow_start = 0; boolean chanel_button = 0; boolean close_button = 0; boolean dveri_otkrili = 0; boolean flag_blink = 1; boolean flag_securiti = 0; boolean flag_securiti_1 = 0; boolean flag_security_konceviki = 1; boolean flag_set_status_led = 1; boolean flag_sirena_high = 0; boolean flag_sirena_millis = 0; boolean GO = 0; boolean hand_brake_else_plus = 1; // "1" - Когда стоит на скорости то замыкается на массу, "0" - Кода стоит на скорости то нет замыкания на массу boolean hand_brake_if_plus = 1; // "1" - Когда стоит на скорости то замыкается на массу, "0" - Кода стоит на скорости то нет замыкания на массу boolean log_netral_gotov = 0; boolean ne_zapusk = 0; boolean obnulenie = 1; boolean open_button = 0; boolean ot_sms = 0; boolean otmetka_skorosty = 0; boolean otmetka2 = 0; boolean otmetka3 = 0; boolean otschet_poshel = 0; boolean proverka_reset = 0; boolean proverka_skorosty1 = 0; boolean razriv = 0; boolean rezreshil_proverku = 1; boolean ruchnaya_kpp = 0; boolean sbros_miganiya = 0; boolean securiti = 0; boolean sharnging_else_plus = 1; // "1" - Если на генераторе при заведенном двигателе +12В , "0" - Если на генераторе при заведенном двигателе 0В boolean sharnging_if_plus = 1; // "1" - Если на генераторе при заведенном двигателе +12В , "0" - Если на генераторе при заведенном двигателе 0В boolean sirena_program = 0; boolean srabotka_koncevikov = 0; boolean vikluchil = 0; boolean warring_security = 0; byte zapis1 = 0; boolean zapusk_button = 0; boolean zapusk_off = 0; byte Button_code; byte dlya_ruchnika = 0; byte flag_zakrit = 0; byte flash_count = 0; byte i = 0; byte l = 0; byte left_start_try = 0; byte otmena_povtora = 10; byte otmena_svecheniya = 0; byte otmetka1 = 0; byte proverka_pered_otpravkoi_1 = 0; byte rcvd_err = 0; //флаг наличия ошибки приема byte received = 0; //флаг наличия принятой инфы char ch = 0; char data = 0; char flag_dva = 3; char flag_dva_sirena = 3; const int buflen = 200; int c = 0; int gena = 0; int gena1 = 0; int generator_konec = 0; int generator_nashalo = 0; int generator_seredina = 0; int HAND_BRAKE_ON = 0; // значение входа ручника int ne_zapusk1 = 5; int ruchik_konec = 0; int ruchik_nachalo = 0; int ruchik_seredina = 0; int SHARGING_ON = 0; // значение входа генератора static unsigned long big_interval = 0; static unsigned long flash_interval = 0; String val = ""; String MASTER_status = ""; String phone1 = ""; String phone2 = ""; String phone3 = ""; uint32_t code = 0UL; // собственно принятая инфа uint32_t RC_code; unsigned int h = 0; unsigned int time, oldtime; //переменные для времени unsigned long delay_millis_sirena_high = 0; unsigned long dlya_miganiya = 0; unsigned long dlya_sekund_dveri = 0; // для хранения секнд сработки дверей unsigned long flag_raz = 0; unsigned long flag_raz_sirena = 0; unsigned long last_start_time = 0; //время в тысячных секунды когда был запущен движок unsigned long millis_dor_close = 0; unsigned long otschet_neitrali = 0; unsigned long reset_modem_millis = 0; unsigned long sekunda_skoroty = 0; unsigned long sekunda_skoroty_sirena = 0; unsigned long set_time_call = 0; char buf[buflen]; void setup() { pinMode(POVOROT_OUT, OUTPUT); // enable output POVOROT_OUT_HIGH(); pinMode(SIRENA, OUTPUT); // enable output pinMode(STARTER_OUT, OUTPUT); // enable output pinMode(ENGINE_OUT, OUTPUT); // enable output pinMode(SECPOWER_OUT, OUTPUT); // enable output pinMode(STATUS_OUT, OUTPUT); // enable output pinMode(BAGAZHNIK_OUT, OUTPUT); // enable output pinMode(DOOR_OPEN, OUTPUT); // enable output pinMode(DOOR_CLOSE, OUTPUT); // enable output pinMode(DOP_RELEY, OUTPUT); nastroyki(); readi_modem(); } void sms_zapusk_nevozmozhen() { sms("ustanovki ne sohraneni, zapusk nevozmozhen", MASTER_status); } void sms_esli_stoit_na_skorosti() { sms("stoit na skorosti", MASTER_status); } void sms_esli_popytki_zapuska_konchilis() { sms("popytki zapyska konchilis'", MASTER_status); } void sms_esli_uhe_zavedena() { sms("uzhe zavedena", MASTER_status); } void sms_esli_zavedena_uspeshno() { sms("zavedena uspeshno", MASTER_status); } void sms_esli_zaglushen_uspeshno() { sms("zaglushen uspeshno", MASTER_status); } void loop() { if (MY_GSM.available() ) { //есть данные от GSM модуля i = 0; while (i < 131) { buf[i] = '\0'; i++; } val = ""; i = 0; while (MY_GSM.available()) { ch = MY_GSM.read(); delay(10); buf[i] = ch; val += ch; i++; } Serial.println(val); buf[i] = '\0'; delay(100); } sms_start_stop(); if (securiti == 1) { proverka_securiti(); flag_securiti = 1; if (sirena_program == 1) { sirena_prerivanie(); } } else if (securiti == 0 && flag_securiti == 1 && flag_securiti_1 == 1) { flag_securiti_1 = 0; flag_securiti = 0; POVOROT_OUT_LOW(); SIRENA_LOW(); rucnik_OFF = 0; do_shutdown(); left_start_try = 0; last_start_time = 0; } if (ne_zapusk == 1) { zvonok_zapuska(); } if (actual_mode != 0 ) { check_for_shutdown(); } set_status_led(); if (rezreshil_proverku == 1 && actual_mode == 0) { proverka_skoroti(); } drevi_off(); button(); if (flag_raz >= 1) { Miganie(); } kakaya_knopka(); migaem_raz(); obnulenie_millis(); if (warring_security == 1) { if (millis() >= (set_time_call + 20000)) { sbros(); delay(500); zvonok(); delay(200); set_time_call = millis(); } if (hand_brake_if_plus == 1) { if (analogRead(HAND_BRAKE_IN) > HAND_BRAKE_ON) { hand_brake_funkcion(); } } else if (hand_brake_if_plus == 0) { if (analogRead(HAND_BRAKE_IN) <= HAND_BRAKE_ON) { hand_brake_funkcion(); } } } reset_modem(); if ((ruchnaya_kpp == 1) && (log_netral_gotov == 0) && (actual_mode == 0)) { log_netral(); } if (val != "") { // Serial.println(val); val = ""; } } void hand_brake_funkcion() { dlya_ruchnika++; if (dlya_ruchnika == 25) { POVOROT_OUT_LOW(); rucnik_OFF = 0; do_shutdown(); left_start_try = 0; // и больше не заводим actual_mode = 0; dlya_ruchnika = 0; } } void obnulenie_millis() { if (millis() > 11000) { obnulenie = 0; } if (millis() > 0 && millis() < 10000 && obnulenie == 0) { obnulenie = 1; proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms("BPEM9 O6HyJIuJIoCb", MASTER_status); proverka_modema(); } if (millis() < big_interval) { big_interval = 0; } if (millis() < flash_interval) { flash_interval = 0; } if (millis() < last_start_time) { last_start_time = 0; } if (millis() < sekunda_skoroty) { sekunda_skoroty = 0; } if (millis() < set_time_call) { set_time_call = 0; } if (millis() < dlya_sekund_dveri) { dlya_sekund_dveri = 0; } if (millis() < dlya_miganiya) { dlya_miganiya = 0; } if (millis() < delay_millis_sirena_high) { delay_millis_sirena_high = 0; } if (millis() < millis_dor_close) { millis_dor_close = 0; } } } void proverka_modema() { c++; delay(1000); int p = 0; if (val.indexOf("OK") > -1) { c = 4; } else { for (; p < 11;) { delay(200); if (MY_GSM.available() ) { //есть данные от GSM модуля i = 0; while (i < 131) { buf[i] = '\0'; i++; val = ""; } i = 0; while (MY_GSM.available()) { ch = MY_GSM.read(); delay(10); buf[i] = ch; val += ch; i++; } buf[i] = '\0'; Serial.println(val); } p++; if (val.indexOf("OK") > -1) { c = 4; return; } else if ((p == 10) || (val.indexOf("ERROR") > -1)) { return; } } } } void nezapusk_plus() { delay(200); sbros(); delay(500); zvonok(); delay(200); set_time_call = millis(); ne_zapusk1++; } void zvonok_zapuska() { if (ne_zapusk1 < 5) { if (val.indexOf("+CLIP") > -1) { ne_zapusk1++; delay(200); sbros(); } else if ((val.indexOf("CONNECT") > -1) ) { delay(200); sbros(); ne_zapusk = 0; set_time_call = millis(); } else if (val.indexOf("NO CARRIER") > -1) { nezapusk_plus(); } else if (val.indexOf("NO ANSWER") > -1) { nezapusk_plus(); } else if (val.indexOf("BUSY") > -1) { nezapusk_plus(); } else if (millis() >= (set_time_call + 20000)) { nezapusk_plus(); } } else { ne_zapusk1 = 5; ne_zapusk = 0; proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms("mashina zavedena, dozvon neudalsya", MASTER_status); proverka_modema(); } } } void had_brake_proverka() { rucnik_OFF = 0; do_shutdown(); actual_mode = 1; // заканчиваем попытки запустить движок left_start_try = 0; //без ручника другие попытки бесполезны if (razriv == 0) { proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms_esli_stoit_na_skorosti(); proverka_modema(); } razriv = 1; } } void sharnging_proverka() { ENGINE_OUT_HIGH();//включаем зажигание POVOROT_OUT_HIGH(); delay(1500); POVOROT_OUT_LOW(); delay(1500); // останавливаем код на 3 секунды чтобы бензонасос набрал давление, все датчики включились do_start(); if (left_start_try == 0 ) { delay(200); if (razriv == 0) { proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms_esli_popytki_zapuska_konchilis(); proverka_modema(); } razriv = 1; } delay(200); POVOROT_OUT_LOW(); SIRENA_LOW(); rucnik_OFF = 0; do_shutdown(); left_start_try = 0; actual_mode = 0; // движок выключили запомним это last_start_time = 0; // ну и забудем о том что он был включен } } void sharnging_else_proverka() { actual_mode = 1; // движок выключили запомним это last_start_time = 0; // ну и забудем о том что он был включен delay(200); if (razriv == 0) { proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms_esli_uhe_zavedena(); proverka_modema(); } razriv = 1; } delay(200); } void check_start() { zapusk_off = 1; gena = 0; gena1 = 0; if ( left_start_try > 0) { if (hand_brake_if_plus == 1) { if ((analogRead(HAND_BRAKE_IN) > HAND_BRAKE_ON ) && (ruchnaya_kpp == 0) ) //без ручника не делаем запуск { had_brake_proverka(); return; } else if ( (ruchnaya_kpp == 1) && (log_netral_gotov == 0)) //без ручника не делаем запуск { had_brake_proverka(); return; } } else if (hand_brake_if_plus == 0) { if ((analogRead(HAND_BRAKE_IN) <= HAND_BRAKE_ON ) && (ruchnaya_kpp == 0)) //без ручника не делаем запуск { had_brake_proverka(); return; } else if ( (ruchnaya_kpp == 1) && (log_netral_gotov == 0)) //без ручника не делаем запуск { had_brake_proverka(); return; } } if (sharnging_else_plus == 1) { proverka_geni(); if (gena <= SHARGING_ON ) // проверяем что генератор не работает { sharnging_proverka(); } else { sharnging_else_proverka(); } } else if (sharnging_else_plus == 0) { proverka_geni(); if (gena > SHARGING_ON ) // проверяем что генератор не работает { sharnging_proverka(); } else { sharnging_else_proverka(); } } } } void do_start() { gena = 0; gena1 = 0; SECPOWER_OUT_LOW(); //выключаем печку фары итд left_start_try-- ; STARTER_OUT_HIGH(); //включаем стартер for (int secs = 0; secs <= (ENGINE_START_MAX_TIME * 5) ; secs++) // { delay(200); // и продолжаем его держать включенным 1 секунду if (sharnging_if_plus == 1) { proverka_geni(); if (gena > SHARGING_ON) //если зарядка пошла то { break; // прерываем цикл } } else if (sharnging_if_plus == 0) { proverka_geni(); if (gena <= SHARGING_ON) //если зарядка пошла то { break; // прерываем цикл } } } STARTER_OUT_LOW(); //отключаем стартер if (sharnging_if_plus == 1) { proverka_geni(); if (gena >= SHARGING_ON) //еще раз смотрим что зарядка пошла { actual_mode = 1; //Запоминаем что движок запущен razriv = 0; last_start_time = millis(); // запоминаем время запуска движка flash_count = 4 - left_start_try; } else { ENGINE_OUT_LOW(); //выключаем зажигание чтбы разблокировать реле стартера SECPOWER_OUT_LOW(); //выключаем печку фары итд delay(2000); if ( left_start_try > 0) { check_start(); } } } else if (sharnging_if_plus == 0) { proverka_geni(); if (gena <= SHARGING_ON) //еще раз смотрим что зарядка пошла { actual_mode = 1; //Запоминаем что движок запущен razriv = 0; last_start_time = millis(); // запоминаем время запуска движка flash_count = 4 - left_start_try; } else { ENGINE_OUT_LOW(); //выключаем зажигание чтбы разблокировать реле стартера SECPOWER_OUT_LOW(); //выключаем печку фары итд delay(2000); if ( left_start_try > 0) { check_start(); } } } } void check_for_shutdown() { gena = 0; gena1 = 0; if (sharnging_else_plus == 1) { proverka_geni(); if (gena <= SHARGING_ON ) { rucnik_OFF = 0; do_shutdown(); delay(2000); check_start(); } else { SECPOWER_OUT_HIGH(); if (millis() > last_start_time + 3000) { if ((razriv == 0) && (ot_sms == 0) ) { ne_zapusk1 = 0; zvonok(); delay(200); razriv = 1; ne_zapusk = 1; set_time_call = millis(); } else if ( (razriv == 0) && (ot_sms == 1)) { proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms_esli_zavedena_uspeshno(); proverka_modema(); } razriv = 1; } } } } else if (sharnging_else_plus == 0) { proverka_geni(); if (gena > SHARGING_ON ) { rucnik_OFF = 0; do_shutdown(); delay(2000); check_start(); } else { SECPOWER_OUT_HIGH(); if (millis() > last_start_time + 3000) { if ((razriv == 0) && (ot_sms == 0) ) { ne_zapusk1 = 0; zvonok(); delay(200); razriv = 1; ne_zapusk = 1; set_time_call = millis(); } else if ( (razriv == 0) && (ot_sms == 1)) { proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms_esli_zavedena_uspeshno(); proverka_modema(); } razriv = 1; } } } } if (hand_brake_if_plus == 1) { if (analogRead(HAND_BRAKE_IN) > HAND_BRAKE_ON) { hand_brake_funkcion(); } } else if (hand_brake_if_plus == 0) { if (analogRead(HAND_BRAKE_IN) <= HAND_BRAKE_ON) { hand_brake_funkcion(); } } if (actual_mode != 0 ) { if (millis() < last_start_time) { last_start_time = 0; } if (millis() > last_start_time + ENGINE_WARM_TIME) { POVOROT_OUT_LOW(); SIRENA_LOW(); rucnik_OFF = 0; do_shutdown(); left_start_try = 0; proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms("progrev okonchen", MASTER_status); proverka_modema(); } } } } void do_shutdown() { SECPOWER_OUT_LOW(); //выключаем печку фары итд ENGINE_OUT_LOW(); //вырубаем зажигание actual_mode = 0; // движок выключили запомним это zapusk_off = 0; last_start_time = 0; // ну и забудем о том что он был включен if (rucnik_OFF == 0) { POVOROT_OUT_LOW(); rucnik_OFF = 1; } } void set_status_led() { if (hand_brake_else_plus == 1) { if (analogRead(HAND_BRAKE_IN) <= HAND_BRAKE_ON ) //Если ручник не стоит то выкл светодиод нечего ему в пути мигать попусту { STATUS_OUT_HIGH(); } else { STATUS_OUT_LOW(); // постоянное свечение - показываем что готов к следующему запуску } } else if (hand_brake_else_plus == 0) { if (analogRead(HAND_BRAKE_IN) > HAND_BRAKE_ON ) //Если ручник не стоит то выкл светодиод нечего ему в пути мигать попусту { STATUS_OUT_HIGH(); } else { STATUS_OUT_LOW(); // постоянное свечение - показываем что готов к следующему запуску } } if (actual_mode == 1) { //Движок запущен status_led_flash(); // показываем с какой попытки был прошлый запуск flag_set_status_led = 1; } if (actual_mode != 1 && flag_set_status_led == 1) { POVOROT_OUT_LOW(); STATUS_OUT_LOW(); flag_set_status_led = 0; } } void status_led_flash() { if (millis() > big_interval + 6000) { otmena_svecheniya = flash_count + 1; } if ((millis() > flash_interval + 500) && (otmena_svecheniya >= 1) && (vikluchil == 0)) { vikluchil = 1; otmena_svecheniya--; POVOROT_OUT_HIGH(); STATUS_OUT_HIGH(); big_interval = millis(); flash_interval = millis(); } else if ((millis() > flash_interval + 500) && (otmena_svecheniya >= 0) && ( vikluchil == 1)) { if ( otmena_svecheniya == 1) { otmena_svecheniya--; } vikluchil = 0; POVOROT_OUT_LOW(); STATUS_OUT_LOW(); big_interval = millis(); flash_interval = millis(); } } void sms_start_stop() { if (val.indexOf("+CMT") > -1) { delay(200); if (((val.substring(1, 25)).indexOf(phone1.substring(1)) > -1) || ((val.substring(1, 25)).indexOf(phone2.substring(1)) > -1) || ((val.substring(1, 25)).indexOf(phone3.substring(1)) > -1) || (val.indexOf(PASSWORD) > -1)) { delay(200); if (val.indexOf(phone1.substring(1)) > -1) { delay(200); MASTER_status = phone1; } else if (val.indexOf(phone2.substring(1)) > -1) { delay(200); MASTER_status = phone2; } else if (val.indexOf(phone3.substring(1)) > -1) { delay(200); MASTER_status = phone3; } if ((val.indexOf(START_ON) > -1) && (actual_mode == 0 ) && (allow_start == 1)) { delay(200); left_start_try = 4; ot_sms = 1; razriv = 0; check_start(); } else if ((val.indexOf(START_ON) > -1) && (actual_mode == 0 ) && (allow_start == 0)) { proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms_zapusk_nevozmozhen(); proverka_modema(); } } else if ((val.indexOf(START_OFF) > -1) && (actual_mode != 0 ) && (allow_start == 1)) { rucnik_OFF = 0; do_shutdown(); left_start_try = 0; last_start_time = 0; proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms_esli_zaglushen_uspeshno(); proverka_modema(); } } else if (val.indexOf(OPEN) > -1) { delay(200); open_button = 1; } else if (val.indexOf(CLOSED) > -1) { delay(200); close_button = 1; } else if (val.indexOf(TRUNK) > -1) { chanel_button = 1; Button_code = 0; otmena_povtora = 0; } else if (val.indexOf(SETUP) > -1) { prisvoenie_znacheniy(); } else if (val.indexOf(RUCHNAYA) > -1) { ruchnaya_kpp = 1; EEPROM.update(46, ruchnaya_kpp); proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms("ustanovlena ruchaya KPP", MASTER_status); proverka_modema(); } } else if (val.indexOf(AVTOMAT) > -1) { ruchnaya_kpp = 0; EEPROM.update(46, ruchnaya_kpp); proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms("ustanovlena avtomaticheskaya KPP", MASTER_status); proverka_modema(); } } else if (val.indexOf(SIGNAL) > -1) { sirena_program = 1; EEPROM.update(47, sirena_program); proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms("ustanovlen signal", MASTER_status); proverka_modema(); } } else if (val.indexOf(SIRENA_ON) > -1) { sirena_program = 0; EEPROM.update(47, sirena_program); proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms("ustanovlena sirena", MASTER_status); proverka_modema(); } } if (val.indexOf(WRITE1) > -1) { zapis1 = 1; } else if (val.indexOf(WRITE2) > -1) { zapis1 = 2; } else if (val.indexOf(WRITE3) > -1) { zapis1 = 3; } if (val.indexOf(HARD_RESET) > -1) { hard_reset(); } else if (val.indexOf(SBROS_NASTROEK) > -1) { minimal_reset(); } } MY_GSM.println("AT+CMGD=1,4"); delay(200); } else if (val.indexOf("+CLIP") > -1) { delay(200); sbros(); if (((val.substring(1, 40)).indexOf(phone1.substring(1)) > -1) || ((val.substring(1, 40)).indexOf(phone2.substring(1)) > -1) || ((val.substring(1, 40)).indexOf(phone3.substring(1)) > -1)) { delay(200); if (val.indexOf(phone1.substring(1)) > -1) { delay(200); MASTER_status = phone1; } else if (val.indexOf(phone2.substring(1)) > -1) { delay(200); MASTER_status = phone2; } else if (val.indexOf(phone3.substring(1)) > -1) { delay(200); MASTER_status = phone3; } if ((actual_mode == 0 ) && (allow_start == 1)) { delay(200); left_start_try = 4; delay(200); ot_sms = 0; razriv = 0; check_start(); delay(200); } else if ((actual_mode == 0 ) && (allow_start == 0)) { proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms_zapusk_nevozmozhen(); proverka_modema(); } } else if ((actual_mode == 1 ) && (allow_start == 1)) { sbros(); //разрываем связь rucnik_OFF = 0; do_shutdown(); left_start_try = 0; // и больше не заводим last_start_time = 0; delay(200); proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms_esli_zaglushen_uspeshno(); proverka_modema(); } delay(200); } } } if (zapis1 == 1) { phone1 = ""; i = 4; while (((buf[i]) != '+') && i < 50) { delay(20); i++ ; l = 0; GO = 1; } while ((GO == 1) && (l < 12)) { EEPROM.update(l, (buf[i])); delay(20); phone1 += buf[i]; l++; i++; } GO = 0; zapis1 = 0; i = 0; delay(200); proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms("nomer " + phone1 + " zapisan uspeshno", phone1); proverka_modema(); } while (i < 131) { buf[i] = '\0'; i++; } i = 0; } if (zapis1 == 2) { phone2 = ""; i = 4; while (((buf[i]) != '+') && i < 50) { i++ ; l = 13; GO = 1; } while ((GO == 1) && (l < 25)) { EEPROM.update(l, (buf[i])); delay(20); phone2 += buf[i]; l++; i++; } i = 0; GO = 0; zapis1 = 0; delay(200); proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms("nomer " + phone2 + " zapisan uspeshno", phone2); proverka_modema(); } while (i < 131) { buf[i] = '\0'; i++; } i = 0; } if (zapis1 == 3) { phone3 = ""; i = 4; while (((buf[i]) != '+') && i < 50) { i++ ; l = 26; GO = 1; } while ((GO == 1) && (l < 38)) { EEPROM.update(l, (buf[i])); delay(20); phone3 += buf[i]; l++; i++; } i = 0; GO = 0; zapis1 = 0; delay(200); proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms("nomer " + phone3 + " zapisan uspeshno", phone3); proverka_modema(); } while (i < 131) { buf[i] = '\0'; i++; } i = 0; } if ((val.indexOf("+CPAS: 1") > -1) || (val.indexOf("+CPAS: 2") > -1) || (val.indexOf("+CPAS: 5") > -1)) { AT_CFUN_15(); delay(200); } if (val.indexOf("+PBREADY") > -1) { readi_modem(); } } void drevi_off() { if (millis() >= dlya_sekund_dveri + SRABOTKA_DVERI) { DOOR_CLOSE_LOW(); DOOR_OPEN_LOW(); } } void migaem_raz() { if (flag_zakrit > 0) { if ((millis() >= dlya_miganiya + 500) && (flag_blink == 1)) { POVOROT_OUT_LOW(); //SIRENA_LOW(); dlya_miganiya = millis(); flag_blink = 0; flag_zakrit--; rezreshil_proverku = 1; } else if ((millis() >= dlya_miganiya + 500) && (flag_blink == 0)) { POVOROT_OUT_HIGH(); //vSIRENA_HIGH(); dlya_miganiya = millis(); flag_blink = 1; rezreshil_proverku = 0; } } } void sms(String text, String phone) //процедура отправки СМС { MY_GSM.println("AT+CMGS=\"" + phone + "\""); delay(300); MY_GSM.print(text); delay(300); MY_GSM.println((char)26); delay(400); //delay(2500); } void pinint() { static uint32_t oldtime = micros(); static uint8_t metka2 = 0; static byte metka = 0; if (digitalRead(RXD) == LOW) //значит приняли ноль { oldtime = micros(); //записали время } else { time = micros() - oldtime; //нходим время в котором был 0 или 1 // Serial.println(time); if (constrain(time, 13400 - DELTA1, 13400 + DELTA1) == time)// если попадает 0 или еденица в интервал от 10000 до 16800 значит пришел стартовы бит и начнем считать саму посылку { metka = 1; //выставилм метки что бы понять что посылка кода пошла metka2 = 0; //выставилм метки что бы понять что посылка кода пошла code = 0; rcvd_err = 0; //сброс флага ошибки received = 0; //сброс флага приема } if (metka == 1 && metka2 <= 24 ) //значит метки совпадают начинаем читать сигналы { metka2++; //выставим что бы метка отсчитала 24 посылки "1" и "0", после 24 приходит мусор code <<= 1; //заполняем, как обойму в АК, проталкивая старое влево. Последние принятые разряды окажуться младшими if (constrain(time, 1300 - DELTA, 1300 + DELTA) == time) //если пришла 1 запишем ее в функцию, там она напечатается в монитор { code |= 1UL; } else if (constrain(time, 51, 799) == time) //если пришел 0 запишем его в функцию, там он напечатается в монитор { code &= ~1UL; } else if (constrain(time, 0, 50) == time) // если поймапли какой то мусор, сразу обрубаем чтение порта { metka = 0; metka2 = 25; rcvd_err = 1; } if ( metka2 == 25) //ну это для образовательных целей что бы видеть разрыв между посылками { received = 1; } } } } void kakaya_knopka() { if (received) { if (! rcvd_err) //если нет ошибки напечатаем отдельно код брелока и кнопки. { RC_code = code >> 4; Button_code = code & 0xf; //Serial.println(RC_code); //Serial.println(Button_code); } received = 0; // обработав, снимаем флаг if ((RC_code == KOD_BRELKA) || (RC_code == KOD_BRELKA1)) { RC_code = 0; if (Button_code == KOD_KNOPKI_CLOSED) { close_button = 1; Button_code = 0; } else if (Button_code == KOD_KNOPKI_OPEN) { open_button = 1; Button_code = 0; } else if (Button_code == KOD_KNOPKI_CHANEL) { chanel_button = 1; Button_code = 0; otmena_povtora = 0; } else if (Button_code == KOD_KNOPKI_ZAPUSK) { Button_code = 0; zapusk_button = 1; } } } Button_code = 0; RC_code = 0; } void button() { if (close_button == 1) { DOP_RELEY_LOW(); DOOR_CLOSE_HIGH(); DOOR_OPEN_LOW(); dlya_sekund_dveri = millis(); close_button = 0; open_button = 0; chanel_button = 0; dlya_miganiya = millis(); if (analogRead(KONCEVIKI) > 300) { flag_security_konceviki = 0; securiti = 1; } else if (analogRead(KONCEVIKI) <= 300) { proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms("WARRING!!! dveri libo kapot otrity", MASTER_status); proverka_modema(); } delay(200); SIRENA_HIGH(); POVOROT_OUT_HIGH(); delay(200); SIRENA_LOW(); delay(300); POVOROT_OUT_LOW(); delay(500); SIRENA_HIGH(); POVOROT_OUT_HIGH(); delay(200); SIRENA_LOW(); delay(300); POVOROT_OUT_LOW(); delay(500); SIRENA_HIGH(); POVOROT_OUT_HIGH(); delay(200); SIRENA_LOW(); delay(300); POVOROT_OUT_LOW(); delay(500); } POVOROT_OUT_HIGH(); SIRENA_HIGH(); delay(100); SIRENA_LOW(); delay(200); SIRENA_HIGH(); delay(100); SIRENA_LOW(); flag_zakrit = 2; flag_blink = 1; rezreshil_proverku = 0; millis_dor_close = millis(); } else if (open_button == 1) { DOP_RELEY_HIGH(); log_netral_gotov = 0; DOOR_OPEN_HIGH(); dlya_sekund_dveri = millis(); DOOR_CLOSE_LOW(); close_button = 0; open_button = 0; chanel_button = 0; dlya_miganiya = millis(); POVOROT_OUT_HIGH(); SIRENA_HIGH(); delay(100); SIRENA_LOW(); delay(200); rezreshil_proverku = 0; flag_zakrit = 1; flag_blink = 1; securiti = 0; flag_security_konceviki = 1; warring_security = 0; flag_raz_sirena = 0; //SIRENA_LOW(); flag_sirena_high = 0; flag_dva_sirena = 3; sbros(); delay(500); } else if (chanel_button == 1 || otmena_povtora < 1) { BAGAZHNIK_OUT_HIGH(); delay(100); BAGAZHNIK_OUT_LOW(); delay(50); otmena_povtora ++; close_button = 0; open_button = 0; chanel_button = 0; } else if (zapusk_button == 1) { zapusk_button = 0; if ((actual_mode == 0 ) && (allow_start == 1)) { delay(200); left_start_try = 4; delay(200); ot_sms = 0; razriv = 0; check_start(); delay(200); } else if ((actual_mode == 0 ) && (allow_start == 0)) { proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms_zapusk_nevozmozhen(); proverka_modema(); } } } } void proverka_skoroti() { if (ruchnaya_kpp == 0) { gena = 0; gena1 = 0; if (sharnging_if_plus == 1) { proverka_geni(); if (gena > SHARGING_ON) { proverka_skorosty1 = 1; } } else if (sharnging_if_plus == 0) { proverka_geni(); if (gena <= SHARGING_ON) { proverka_skorosty1 = 1; } } if (hand_brake_if_plus == 1 && (proverka_skorosty1 == 1)) { if (sharnging_else_plus == 1) { proverka_geni(); if ( (gena <= SHARGING_ON) && (analogRead(HAND_BRAKE_IN) > HAND_BRAKE_ON )) { otmetka_skorosty = 1; proverka_skorosty1 = 0; } } else if (sharnging_else_plus == 0) { proverka_geni(); if (gena > SHARGING_ON && (analogRead(HAND_BRAKE_IN) > HAND_BRAKE_ON )) { otmetka_skorosty = 1; proverka_skorosty1 = 0; } } } else if (hand_brake_if_plus == 0 && (proverka_skorosty1 == 1)) { if (sharnging_else_plus == 1) { proverka_geni(); if ( gena <= SHARGING_ON && (analogRead(HAND_BRAKE_IN) <= HAND_BRAKE_ON )) { otmetka_skorosty = 1; proverka_skorosty1 = 0; } } else if (sharnging_else_plus == 0) { proverka_geni(); if ( gena > SHARGING_ON && (analogRead(HAND_BRAKE_IN) <= HAND_BRAKE_ON )) { otmetka_skorosty = 1; proverka_skorosty1 = 0; } } } if ( otmetka_skorosty == 1) { flag_raz = 1; proverka_skorosty1 = 0; otmetka_skorosty = 0; sekunda_skoroty = millis(); flag_dva = 0; } if ((actual_mode == 0) && (flag_dva < 3)) { // 1"); if (hand_brake_else_plus == 1) { if (sharnging_if_plus == 1) { proverka_geni(); if (millis() >= sekunda_skoroty + 10000 || analogRead(HAND_BRAKE_IN) <= HAND_BRAKE_ON || gena > SHARGING_ON ) { POVOROT_OUT_LOW(); otmetka_skorosty = 0; flag_raz = 0; flag_dva = 3; } } else if (sharnging_if_plus == 0) { proverka_geni(); if (millis() >= sekunda_skoroty + 10000 || analogRead(HAND_BRAKE_IN) <= HAND_BRAKE_ON || gena <= SHARGING_ON ) { POVOROT_OUT_LOW(); otmetka_skorosty = 0; flag_raz = 0; flag_dva = 3; } } } else if (hand_brake_else_plus == 0) { if (sharnging_if_plus == 1) { proverka_geni(); if (millis() >= sekunda_skoroty + 10000 || analogRead(HAND_BRAKE_IN) > HAND_BRAKE_ON || gena > SHARGING_ON ) { POVOROT_OUT_LOW(); otmetka_skorosty = 0; flag_raz = 0; flag_dva = 3; } } else if (sharnging_if_plus == 0) { proverka_geni(); if (millis() >= sekunda_skoroty + 10000 || analogRead(HAND_BRAKE_IN) > HAND_BRAKE_ON || gena <= SHARGING_ON ) { POVOROT_OUT_LOW(); // 2"); otmetka_skorosty = 0; flag_raz = 0; flag_dva = 3; } } } } } } void Miganie() { if (flag_dva == 0 && millis() >= sekunda_skoroty + (300 * flag_raz)) { POVOROT_OUT_HIGH(); flag_raz++; flag_dva = 1; } else if (flag_dva == 1 && millis() >= sekunda_skoroty + (300 * flag_raz)) { POVOROT_OUT_LOW(); flag_raz++; flag_dva = 0; } if (flag_dva == 3 && sbros_miganiya == 1) { flag_raz = 0; sbros_miganiya = 0; POVOROT_OUT_LOW(); } } //функция чтения настроек из ЕЕПРОМ void eprom_read() { i = 0; phone1 = ""; while (i < 12) { data = EEPROM.read(i); delay(20); phone1 += data; i++; } if (phone1.indexOf("+7") > -1) { phone1 = phone1; } else { phone1 = ("+71111111111"); } phone2 = ""; i = 13; while (i < 25) { data = EEPROM.read(i); delay(20); phone2 += data; i++; } if (phone2.indexOf("+7") > -1) { phone2 = phone2; } else { phone2 = ("+71111111111"); } i = 26; phone3 = ""; while (i < 38) { data = EEPROM.read(i); delay(20); phone3 += data; i++; } if (phone3.indexOf("+7") > -1) { phone3 = phone3; } else { phone3 = ("+71111111111"); } EEPROM.get(50, SHARGING_ON); delay(20); EEPROM.get(70, HAND_BRAKE_ON); delay(20); sharnging_if_plus = EEPROM.read(40); delay(5); sharnging_else_plus = EEPROM.read(41); delay(5); hand_brake_if_plus = EEPROM.read(42); delay(5); hand_brake_else_plus = EEPROM.read(43); delay(5); allow_start = EEPROM.read(44); delay(5); ruchnaya_kpp = EEPROM.read(46); delay(5); sirena_program = EEPROM.read(47); delay(5); } void prisvoenie_znacheniy() { gena1 = 0; gena = 0; ENGINE_OUT_HIGH();//включаем зажигание delay(500); proverka_geni(); generator_nashalo = gena; //если значение генератора правельные, записываем их в переменную как начальные ruchik_nachalo = analogRead(HAND_BRAKE_IN); //и считываем начальные значения положения рычага КПП(ручника) proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms("snimite skorost', potom zavedite avto", MASTER_status); //отсылаем смс с дальнейшими действиями proverka_modema(); } delay(200); h = 0; while ( h <= 12000) { proverka_geni(); generator_seredina = gena; //если значение генератора правельные, записываем их в переменную для вычеслений из начального в средние ruchik_seredina = analogRead(HAND_BRAKE_IN); //то же с ручником или рычагом КПП h++; if (((generator_nashalo + 50) <= generator_seredina) || ((generator_nashalo - 50) >= generator_seredina))// посмотрели машина завилась { delay(2000); proverka_geni(); generator_seredina = gena; //записываем уже конечные значения ruchik_seredina = analogRead(HAND_BRAKE_IN); //записываем уже конечные значения otmetka1 = 2; break; } } if ((h <= 11999) && (otmetka1 == 2)) { generator_konec = ((generator_nashalo + generator_seredina) / 2); //находим среднее значение между заглушенный и заведенной машиной delay(20); ruchik_konec = ((ruchik_nachalo + ruchik_seredina) / 2);//находим среднее значение между заглушенный и заведенной машиной delay(20); SHARGING_ON = generator_konec; HAND_BRAKE_ON = ruchik_konec; EEPROM.put(50, SHARGING_ON); //записываем их в EEPROM delay(5); EEPROM.put(70, HAND_BRAKE_ON);//записываем их в EEPROM delay(5); otmetka1 = 1; // дальше смотрим что бы у нас выполнялись правильные куски программы // потому что переменная генератора может и увеличиться с запуском двигателя // так и уменьшиться, мы как раз здесь это и смотрим // и записываем все в ЕЕПРОМ if (generator_nashalo < generator_seredina) { sharnging_if_plus = 1; sharnging_else_plus = 1; EEPROM.update(40, sharnging_if_plus); delay(5); EEPROM.update(41, sharnging_else_plus); delay(5); otmetka2 = 1; } else if (generator_nashalo > generator_seredina) { sharnging_if_plus = 0; sharnging_else_plus = 0; EEPROM.update(40, sharnging_if_plus); delay(5); EEPROM.update(41, sharnging_else_plus); delay(5); otmetka2 = 1; } // то же самое и с ручником if (ruchik_nachalo < ruchik_seredina) { hand_brake_if_plus = 0; hand_brake_else_plus = 0; EEPROM.update(42, hand_brake_if_plus); delay(5); EEPROM.update(43, hand_brake_else_plus); delay(5); otmetka3 = 1; } else if (ruchik_nachalo > ruchik_seredina) { hand_brake_if_plus = 1; hand_brake_else_plus = 1; EEPROM.update(42, hand_brake_if_plus); delay(5); EEPROM.update(43, hand_brake_else_plus); delay(5); otmetka3 = 1; } //если мы прошли все отметки с успехом, то отправляем смс с такой командой if (otmetka1 == 1 && otmetka2 == 1 && otmetka3 == 1) { proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms("ustanovki sohraneni uspeshno", MASTER_status); proverka_modema(); } ENGINE_OUT_LOW(); otmetka1 = 0; otmetka2 = 0; otmetka2 = 0; allow_start = 1; EEPROM.update(44, allow_start); } } // если закончилось время и мы не завели авто то шлем смс с ошибкой else if (h > 11999) { allow_start = 0; EEPROM.update(44, allow_start); ENGINE_OUT_LOW(); } //или если какую то отметку не прошли тоже смс с ошибкой else if (otmetka1 == 0 || otmetka2 == 0 || otmetka3 == 0) { allow_start = 0; EEPROM.update(44, allow_start); otmetka1 = 0; otmetka2 = 0; otmetka2 = 0; ENGINE_OUT_LOW(); } } void proverka_securiti() { if ((analogRead(KONCEVIKI) <= 300) && flag_security_konceviki == 0) { flag_security_konceviki = 1; delay(200); proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms("srabotala signalizaciya", MASTER_status); proverka_modema(); } delay(200); zvonok(); delay(200); flag_securiti_1 = 1; warring_security = 1; set_time_call = millis(); left_start_try = 4; ot_sms = 1; razriv = 0; check_start(); if (sirena_program == 0) { SIRENA_HIGH(); } else if (sirena_program == 1) { flag_raz_sirena = 1; sekunda_skoroty_sirena = millis(); flag_dva_sirena = 0; srabotka_koncevikov = 1; } } if ((zapusk_off == 0) && (digitalRead(DOOR_CLOSE) == 0)) { if (millis > millis_dor_close + 3000) { if ((analogRead(SHOCK_SENSOR_HIGH) <= 300) && (flag_sirena_high == 0)) { if (sirena_program == 0) { SIRENA_HIGH(); flag_sirena_high = 1; delay_millis_sirena_high = millis(); flag_sirena_millis = 0; } else if (sirena_program == 1) { flag_raz_sirena = 1; sekunda_skoroty_sirena = millis(); delay_millis_sirena_high = millis(); flag_dva_sirena = 0; srabotka_koncevikov = 0; flag_sirena_millis = 0; } proverka_pered_otpravkoi(); c = 0; while (c <= 3) { sms("mashinu udarili", MASTER_status); proverka_modema(); } } if (analogRead(SHOCK_SENSOR_LOW) <= 300) { SIRENA_HIGH(); delay (400); SIRENA_LOW(); delay (700); SIRENA_HIGH(); delay (400); SIRENA_LOW(); delay (700); SIRENA_HIGH(); delay (400); SIRENA_LOW(); } if (flag_sirena_millis == 0) { if (millis() > (delay_millis_sirena_high + 120000)) { SIRENA_LOW(); flag_sirena_high = 0; flag_sirena_millis = 1; } } } } } void sirena_prerivanie() { if (flag_dva_sirena == 0 && millis() >= sekunda_skoroty_sirena + (800 * flag_raz_sirena)) { SIRENA_HIGH(); flag_raz_sirena++; flag_dva_sirena = 1; } else if (flag_dva_sirena == 1 && millis() >= sekunda_skoroty_sirena + (800 * flag_raz_sirena)) { SIRENA_LOW(); flag_raz_sirena++; flag_dva_sirena = 0; } if (srabotka_koncevikov == 0) { if (flag_dva_sirena == 3 || (millis() > (delay_millis_sirena_high + 120000))) { flag_raz_sirena = 0; SIRENA_LOW(); flag_sirena_high = 0; flag_dva_sirena = 3; } } } void proverka_geni() { gena = analogRead(SHARGING_IN); delay(5); gena1 = analogRead(SHARGING_IN); for (; gena1 != gena;) { gena = analogRead(SHARGING_IN); delay(5); gena1 = analogRead(SHARGING_IN); } } void reset_modem() { if (reset_modem_millis > millis()) { reset_modem_millis = 0; } if (millis() > reset_modem_millis + 120000) { reset_modem_millis = millis(); proverka_reset = 1; } if ( proverka_reset == 1) { reset_proverki_modema(); modem_v_gsm(); MY_GSM.println("AT+CPAS"); proverka_reset = 0; } } void hard_reset() { for (int i = 0 ; i < EEPROM.length() ; i++) { EEPROM.write(i, 0); } minimal_reset(); } void minimal_reset() { flag_sirena_high = 0; SHARGING_ON = 0; HAND_BRAKE_ON = 0; h = 0; ne_zapusk1 = 5; flag_set_status_led = 1; sharnging_if_plus = 1; sharnging_else_plus = 1; hand_brake_if_plus = 1; hand_brake_else_plus = 1; gena = 0; gena1 = 0; otmetka1 = 0; otmetka2 = 0; otmetka3 = 0; zapusk_button = 0; rucnik_OFF = 1; GO = 0; proverka_skorosty1 = 0; zapis1 = 0; otmetka_skorosty = 0; razriv = 0; chanel_button = 0; open_button = 0; close_button = 0; securiti = 0; flag_security_konceviki = 1; flag_securiti = 0; actual_mode = 0; // 2 engine started allow_start = 0; ot_sms = 0; warring_security = 0; flag_securiti_1 = 0; flag_blink = 1; proverka_reset = 0; flag_zakrit = 0; c = 0; flash_count = 0; dlya_ruchnika = 0; left_start_try = 0; // переменная для хранения остатка числа попыток запуска ch = 0; // otmena_povtora = 10; flag_raz = 0; ne_zapusk = 0; generator_nashalo = 0; generator_seredina = 0; generator_konec = 0; ruchik_nachalo = 0; ruchik_seredina = 0; ruchik_konec = 0; MASTER_status = ""; big_interval = 0; flash_interval = 0; last_start_time = 0; //время в тысячных секунды когда был запущен движок sekunda_skoroty = 0; set_time_call = 0; dlya_sekund_dveri = 0; // для хранения секнд сработки дверей dlya_miganiya = 0; reset_modem_millis = 0; flag_dva = 3; rcvd_err = 0; //флаг наличия ошибки приема obnulenie = 1; data = 0; millis_dor_close = 0; phone1 = "+71111111111"; phone2 = "+71111111111"; phone3 = "+71111111111"; otmena_svecheniya = 0; vikluchil = 0; delay_millis_sirena_high = 0; zapusk_off = 0; nastroyki(); } void nastroyki() { SIRENA_LOW(); STARTER_OUT_LOW(); ENGINE_OUT_LOW(); SECPOWER_OUT_LOW(); STATUS_OUT_LOW(); BAGAZHNIK_OUT_LOW(); DOOR_OPEN_LOW(); DOOR_CLOSE_LOW(); digitalWrite(14, HIGH); digitalWrite(15, HIGH); digitalWrite(16, HIGH); digitalWrite(17, HIGH); digitalWrite(18, HIGH); digitalWrite(19, HIGH); DOP_RELEY_HIGH(); pinMode(RXD, INPUT); attachInterrupt(digitalPinToInterrupt(RXD), pinint, CHANGE); delay(100); Serial.begin(460800); MY_GSM.begin(460800); AT_IPR_9600(); delay(200); Serial.begin(230400); MY_GSM.begin(230400); AT_IPR_9600(); delay(200); Serial.begin(115200); MY_GSM.begin(115200); AT_IPR_9600(); delay(200); Serial.begin(57600); MY_GSM.begin(57600); AT_IPR_9600(); delay(200); Serial.begin(38400); MY_GSM.begin(38400); AT_IPR_9600(); delay(200); Serial.begin(28800); MY_GSM.begin(28800); AT_IPR_9600(); Serial.begin(19200); MY_GSM.begin(19200); AT_IPR_9600(); delay(200); Serial.begin(14400); MY_GSM.begin(14400); AT_IPR_9600(); delay(200); Serial.begin(4800); MY_GSM.begin(4800); AT_IPR_9600(); delay(200); Serial.begin(2400); MY_GSM.begin(2400); AT_IPR_9600(); delay(200); Serial.begin(9600); MY_GSM.begin(9600); delay(100); eprom_read(); MASTER_status = phone1; POVOROT_OUT_LOW(); // Serial.println(ruchnaya_kpp); } void log_netral() { if (hand_brake_if_plus == 1) { if ((analogRead(HAND_BRAKE_IN) < HAND_BRAKE_ON) && (otschet_poshel == 0)) { if (sharnging_if_plus == 1) { proverka_geni(); if (gena > SHARGING_ON) { SIRENA_HIGH(); delay(200); SIRENA_LOW(); otschet_poshel = 1; otschet_neitrali = millis(); ENGINE_OUT_HIGH(); sekunda_skoroty = millis(); flag_raz = 1; flag_dva = 0; sbros_miganiya = 1; } } else if (sharnging_if_plus == 0) { proverka_geni(); if (gena < SHARGING_ON) { SIRENA_HIGH(); delay(200); SIRENA_LOW(); otschet_poshel = 1; otschet_neitrali = millis(); ENGINE_OUT_HIGH(); sekunda_skoroty = millis(); flag_raz = 1; flag_dva = 0; sbros_miganiya = 1; } } } else if (analogRead(HAND_BRAKE_IN) > HAND_BRAKE_ON) { otschet_neitrali = millis(); flag_dva = 3; otschet_poshel = 0; ENGINE_OUT_LOW(); log_netral_gotov = 0; } } if (hand_brake_if_plus == 0) { if ((analogRead(HAND_BRAKE_IN) > HAND_BRAKE_ON) && (otschet_poshel == 0)) { if (sharnging_if_plus == 1) { proverka_geni(); if (gena > SHARGING_ON) { SIRENA_HIGH(); delay(200); SIRENA_LOW(); otschet_poshel = 1; otschet_neitrali = millis(); ENGINE_OUT_HIGH(); sekunda_skoroty = millis(); flag_raz = 1; flag_dva = 0; sbros_miganiya = 1; } } else if (sharnging_if_plus == 0) { proverka_geni(); if (gena < SHARGING_ON) { SIRENA_HIGH(); delay(200); SIRENA_LOW(); otschet_poshel = 1; otschet_neitrali = millis(); ENGINE_OUT_HIGH(); sekunda_skoroty = millis(); flag_raz = 1; flag_dva = 0; sbros_miganiya = 1; } } } else if (analogRead(HAND_BRAKE_IN) < HAND_BRAKE_ON) { otschet_neitrali = millis(); flag_dva = 3; otschet_poshel = 0; ENGINE_OUT_LOW(); log_netral_gotov = 0; } } if ((otschet_poshel == 1) && (millis() < (otschet_neitrali + ZADERZHKA_LOG_NETRAL))) { if (analogRead(KONCEVIKI) < 500) { dveri_otkrili = 1; } if ((dveri_otkrili == 1) && (securiti == 1) && (analogRead(KONCEVIKI) > 500)) { log_netral_gotov = 1; flag_dva = 3; ENGINE_OUT_LOW(); } } if ((otschet_poshel == 0) || (millis() > (otschet_neitrali + ZADERZHKA_LOG_NETRAL))) { flag_dva = 3; ENGINE_OUT_LOW(); } if ((otschet_poshel == 0) || (millis() > (otschet_neitrali + 2000))) { flag_dva = 3; } } void zvonok() { MY_GSM.println("ATD" + MASTER_status + ";"); } void sbros() { MY_GSM.println("ATH0"); } void POVOROT_OUT_LOW() { digitalWrite(POVOROT_OUT, LOW); } void STATUS_OUT_LOW() { digitalWrite(STATUS_OUT, LOW); } void SIRENA_LOW() { digitalWrite(SIRENA, LOW); } void STARTER_OUT_LOW() { digitalWrite(STARTER_OUT, LOW); } void ENGINE_OUT_LOW() { digitalWrite(ENGINE_OUT, LOW); } void SECPOWER_OUT_LOW() { digitalWrite(SECPOWER_OUT, LOW); } void BAGAZHNIK_OUT_LOW() { digitalWrite(BAGAZHNIK_OUT, LOW); } void DOOR_OPEN_LOW() { digitalWrite(DOOR_OPEN, LOW); } void DOOR_CLOSE_LOW() { digitalWrite(DOOR_CLOSE, LOW); } void ENGINE_OUT_HIGH() { digitalWrite(ENGINE_OUT, HIGH); } void STARTER_OUT_HIGH() { digitalWrite(STARTER_OUT, HIGH); } void SECPOWER_OUT_HIGH() { digitalWrite(SECPOWER_OUT, HIGH); } void STATUS_OUT_HIGH() { digitalWrite(STATUS_OUT, HIGH); } void POVOROT_OUT_HIGH() { digitalWrite(POVOROT_OUT, HIGH); } void DOOR_CLOSE_HIGH() { digitalWrite(DOOR_CLOSE, HIGH); } void SIRENA_HIGH() { digitalWrite(SIRENA, HIGH); } void DOOR_OPEN_HIGH() { digitalWrite(DOOR_OPEN, HIGH); } void BAGAZHNIK_OUT_HIGH() { digitalWrite(BAGAZHNIK_OUT, HIGH); } void DOP_RELEY_HIGH() { digitalWrite(DOP_RELEY, HIGH); } void DOP_RELEY_LOW() { digitalWrite(DOP_RELEY, LOW); } void AT_IPR_9600() { MY_GSM.println("AT+IPR=9600"); } void AT_CFUN_15() { MY_GSM.println("AT+CFUN=15"); } void readi_modem() { delay(100); MY_GSM.println("AT+CLIP=1"); //включаем АОН delay(100); MY_GSM.println("AT+CMGF=1"); //режим кодировки СМС - обычный (для англ.) delay(100); MY_GSM.println("AT+CSCS=\"GSM\""); //режим кодировки текста delay(100); MY_GSM.println("AT+CNMI=2,2"); //отображение смс в терминале сразу после приема (без этого сообщения молча падают в память) delay(100); MY_GSM.println("ATE1"); } void proverka_pered_otpravkoi() { if (proverka_pered_otpravkoi_1 < 20) { MY_GSM.println("AT+CSQ"); delay(200); val = ""; while (MY_GSM.available()) { ch = MY_GSM.read(); delay(10); val += ch; } Serial.println(val); if (val.indexOf("99") > -1) { delay(500); proverka_pered_otpravkoi_1++; val = ""; proverka_pered_otpravkoi(); } } val = ""; proverka_pered_otpravkoi_1 = 0; } void reset_proverki_modema() { val = ""; MY_GSM.println("AT"); delay(400); if (MY_GSM.available() ) { //есть данные от GSM модуля i = 0; while (i < 131) { buf[i] = '\0'; i++; } i = 0; while (MY_GSM.available()) { ch = MY_GSM.read(); delay(10); buf[i] = ch; val += ch; i++; } buf[i] = '\0'; Serial.println(val); } if (val.indexOf("OK") > -1) { return; } else { AT_CFUN_15(); delay(200); } } void modem_v_gsm() { val = ""; MY_GSM.println("AT+CSCS=?"); delay(400); if (MY_GSM.available() ) { //есть данные от GSM модуля i = 0; while (i < 131) { buf[i] = '\0'; i++; } i = 0; while (MY_GSM.available()) { ch = MY_GSM.read(); delay(10); buf[i] = ch; val += ch; i++; } buf[i] = '\0'; Serial.println(val); } if (val.indexOf("GSM") > -1) { return; } else { readi_modem(); delay(200); } }У Вас полно статичных строк может сначала от них избавиться с помощью F или прогмем, а там видно будет
не понимаю о чем вы сможете ссылку привести где можно почитать об "F"
понял на счет F, супер, ноо большой ущерб памяти флеш... у меня и так флеша 76% на 328p-au
не понимаю о чем вы сможете ссылку привести где можно почитать об "F"
http://atmel.ucoz.ru/publ/progmem/1-1-0-64
понял на счет F, супер, ноо большой ущерб памяти флеш... у меня и так флеша 76% на 328p-au
флеш можно использовать хоть на 100% - лишь бы хватило. А вот оперативку нежелательно забивать более 60-70% - иначе могут начаться глюки.
на счет F просто супер))) все работает!! спасибо большое! и теперь освободил с 74% до 42% отлично вообще!
да, все таки полезно скетч выкладывать... думал будет бесполезный
может еще элементарные способы оптимизации подскажите? на ваш взгляд
жесть... уже до 38% снизил... вот это я косяяяяяяяяяяк
наверное я такой криворукий, но у меня весь скетч на char[] и тоже занимает более 80 % динамической памяти,
250 байт входящий буфер от модема, 250 байт исходящий буфер для отправки SMS в PDU формате,
и даже учитывая что я максимально многократно стараюсь использовать одни и те же переменные,
и без этих двух буферов все равно много памяти съедается :(
не знаю как на УНО умудряются мегапроекты строить....
наверное я такой криворукий, но у меня весь скетч на char[] и тоже занимает более 80 % динамической памяти,
250 байт входящий буфер от модема, 250 байт исходящий буфер для отправки SMS в PDU формате,
и даже учитывая что я максимально многократно стараюсь использовать одни и те же переменные,
и без этих двух буферов все равно много памяти съедается :(
не знаю как на УНО умудряются мегапроекты строить....
80% это на каком чипе?
328 чип
328 чип
а можешь скинуть скетч? посмотрим почему так много
я себе сократил на 700байт
у меня щас этот скетч занимает:
да пожалуйста,
но мне не надо ничего сокращать :) - меня все устраивает,
потому не тратьте свое время на ковыряние чужого кода.
#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 250 #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 450 // 0 or FF - off 12 -on #define pos_eeprom_relay2_mode 452 // 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"}; 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); } // 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, HIGH); else digitalWrite(A2, LOW); if (EEPROM.read(pos_eeprom_relay2_mode) == 21) digitalWrite(A3, HIGH); else digitalWrite(A3, LOW); // 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 < 11; ++i) { // 11 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 EEPROM.write(pos_eeprom_relay1_mode, 12); digitalWrite(A2, HIGH); break; } case 8: { if (getAllowCommandPhone(sender) == 0) return; // command for any user EEPROM.write(pos_eeprom_relay1_mode, 00); digitalWrite(A2, LOW); break; } case 9: { if (getAllowCommandPhone(sender) == 0) return; // command for any user EEPROM.write(pos_eeprom_relay2_mode, 21); digitalWrite(A3, HIGH); break; } case 10: { if (getAllowCommandPhone(sender) == 0) return; // command for any user EEPROM.write(pos_eeprom_relay2_mode, 00); digitalWrite(A3, LOW); 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; } 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(); }// functions for a6 gsm modem #include "a6modem.h" #include "Arduino.h" #include <LiquidCrystal_1602_RUS.h> char _rsp_buf[RESPONSE_BUF_SIZE]; word _rsp_pos; char _resp_detect1[RESPONSE_DETECT_SIZE]; char _resp_detect2[RESPONSE_DETECT_SIZE]; char _resp_detect3[RESPONSE_DETECT_SIZE]; unsigned long cmd_started_time; boolean wait_response; char* OPSlist[] = {"TELE2RUS", "*105#", "25020", "Beeline", "*100#", "25099", "MegaFon", "*100#", "25002", "MTS", "*100#", "25001"}; char OPScode[] = "250000"; byte IdxLCD = 0; // 0..31 - char on LCD LiquidCrystal_1602_RUS LCD(8, 9, 4, 5, 6, 7 );//For LCD Keypad Shield // a6 init modem // p1 - modem speed // p2 - 1=use Software Serial UART // p3 - Serial0 speed, use as console, =0 if dont use or modem use Serial0; void a6initmodem(word a6uartspeed) { // init LCD LCD.begin(16, 2); LCD.clear(); LCD.setCursor(0, 0); IdxLCD = 0; SendByteToLCD(209, false); SendByteToLCD(242, false); SendByteToLCD(224, false); SendByteToLCD(240, false); SendByteToLCD(242, false); SendByteToLCD(32, true); SendStrToLCD("Start "); LCD.cursor(); LCD.blink(); // init modem pinMode(_a6_reset_pin, OUTPUT); pinMode(_a6_power_pin, OUTPUT); pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); digitalWrite(_a6_reset_pin, LOW); digitalWrite(_a6_power_pin, HIGH); // power on unsigned long delp = millis(); while ((millis() - delp) <= 10000); Serial.begin(a6uartspeed); // adaptive speed a6 module unsigned long curr_millis = millis(); while ((millis() - curr_millis) <= 4000UL) Serial.println("AT"); curr_millis = millis(); while ((millis() - curr_millis) <= 5000UL) if (Serial.available()) while (Serial.available()) Serial.read(); // - wait_response = false; a6sendcmd("AT", "OK", "", "", true); // begin work } void a6resetmodem() { // reset modem digitalWrite(_a6_reset_pin, HIGH); unsigned long delp = millis(); while ((millis() - delp) <= 500); digitalWrite(_a6_reset_pin, LOW); } byte a6sendcmd(char* txtcmd, char* resp1, char* resp2, char* resp3, boolean show_cmd) { if (wait_response) return 0; Serial.println(txtcmd); if (show_cmd) SendStrToLCD(txtcmd); cmd_started_time = millis(); a6clearrespbuf(); byte pp = 0; if (resp1[0] == 0) { wait_response = false; _resp_detect1[0] = 0; return 1; } else { wait_response = true; pp = 0; while ((resp1[pp] != 0) && (pp < (RESPONSE_DETECT_SIZE - 1))) { _resp_detect1[pp] = resp1[pp]; ++pp; } _resp_detect1[pp] = 0; } pp = 0; while ((resp2[pp] != 0) && (pp < (RESPONSE_DETECT_SIZE - 1))) { _resp_detect2[pp] = resp2[pp]; ++pp; } _resp_detect2[pp] = 0; pp = 0; while ((resp3[pp] != 0) && (pp < (RESPONSE_DETECT_SIZE - 1))) { _resp_detect3[pp] = resp3[pp]; ++pp; } _resp_detect3[pp] = 0; return 1; } byte a6work() { boolean getdata = false; if (Serial.available()) while (Serial.available()) if (_rsp_pos < (RESPONSE_BUF_SIZE - 1)) { _rsp_buf[_rsp_pos] = Serial.read(); ++_rsp_pos; getdata = true; } if (getdata) { _rsp_buf[_rsp_pos] = 0; if (_rsp_pos > 0) { if (_rsp_pos <= 32) SendStrToLCD(_rsp_buf); } } // wait response for sent at command if (wait_response) { if ((millis() - cmd_started_time) >= RESPONSE_MAX_TIME) { wait_response = false; return 2; // timeout } else { if (a6detectresp(_resp_detect1, _resp_detect2, _resp_detect3)) { wait_response = false; return 1; // OK } } } return 0; } void a6clearrespbuf() { _rsp_pos = 0; _rsp_buf[_rsp_pos] = 0; } byte a6detectresp(char* resp1, char* resp2, char* resp3) { if (_rsp_pos > 0) { if (resp1[0] != 0) { if (strPos(_rsp_buf, resp1) >= 0) { if (resp2[0] == 0) { return 1; } else { if (strPos(_rsp_buf, resp2) >= 0) { if (resp3[0] == 0) { return 1; } else { if (strPos(_rsp_buf, resp3) >= 0) { return 1; } else { return 0; } } } else { return 0; } } } else { return 0; } } else { return 0; } } else { return 0; } } char* LastPos(char *str1, char *str2) { int L1 = strlen(str1); int L2 = strlen(str2); for (int i = L1 - L2; i >= 0; i--) { int j = 0; for (; j < L2; j++) if (str1[i + j] != str2[j]) break; if (j == L2) return str1 + i; } return 0; } int strPos(char *str11, char *str22) { char*p = LastPos(str11, str22); int n = p - str11; return n; } byte a6getcountsms() { char findstr[] = "+CMGL:"; if (a6detectresp(findstr, "", "") == 0) return 0; byte result = 0; int L1 = strlen(_rsp_buf); int L2 = strlen(findstr); for (int i = L1 - L2; i >= 0; i--) { int j = 0; for (j = 0; j < L2; j++) if (_rsp_buf[i + j] != findstr[j]) break; if (j == L2) { ++result; } } return result; } byte a6readsms(byte indexsms, char* phonenumber, char* textsms) { phonenumber[0] = 0; textsms[0] = 0; byte numfirstchar; if (indexsms < 10) { char findstr[] = "+CMGL: 1"; findstr[7] = '0' + indexsms; numfirstchar = strPos(_rsp_buf, findstr); numfirstchar += (strlen(findstr) + 4); // first posifion = count byte of pdu message } else { char findstr[] = "+CMGL: 1 "; findstr[8] = '0' + (indexsms % 10); numfirstchar = strPos(_rsp_buf, findstr); numfirstchar += (strlen(findstr) + 4); // first posifion = count byte of pdu message } // get lenght pdu byte i = 0; byte countbytepdu = 0; while (isdigit(_rsp_buf[numfirstchar + i])) { if (i > 0) { countbytepdu = (countbytepdu * 10) + (_rsp_buf[numfirstchar + i] - '0'); } else { countbytepdu = _rsp_buf[numfirstchar + i] - '0'; } ++i; } numfirstchar += i; if ((_rsp_buf[numfirstchar] == '\r') && (_rsp_buf[numfirstchar + 1] == '\n')) { // find first CR LF numfirstchar += 2; } else { return; } i = 0; while (!((_rsp_buf[numfirstchar + i] == '\r') && (_rsp_buf[numfirstchar + 1 + i] == '\n') && (_rsp_buf[numfirstchar + i] != 0))) { // find last CR LF ++i; } byte numlastchar = numfirstchar + i - 1; a6decodepdusms(numfirstchar, countbytepdu, numlastchar, phonenumber, textsms); } void a6decodepdusms(byte firstcharpdu, byte counttextpdu, byte lastcharpdu, char* senderphone, char* textsms) { // firstcharpdu - pos TP-SCA + 1 byte size byte nf = strHexTobyte(_rsp_buf[firstcharpdu], _rsp_buf[firstcharpdu + 1]) + 1; // new pos = TP-MTI & Co ++nf; // new pos = TP-OA byte lf = strHexTobyte(_rsp_buf[firstcharpdu + (nf * 2)], _rsp_buf[firstcharpdu + (nf * 2) + 1]); // lenght sender phone number // check format number ++nf; if ((_rsp_buf[firstcharpdu + (nf * 2)] != '9') || (_rsp_buf[firstcharpdu + (nf * 2) + 1] != '1')) return; // not digit format ++nf; senderphone[0] = '+'; for (byte i = 0; i < lf; ++i) { senderphone[i + 1] = _rsp_buf[firstcharpdu + (nf * 2) + i + 1]; senderphone[i + 2] = _rsp_buf[firstcharpdu + (nf * 2) + i]; ++i; } nf *= 2; nf += lf; if (senderphone[lf] == 'F') senderphone[lf] = 0; else senderphone[lf + 1] = 0; ++nf; // next char - pos TP-PID nf += 2; // pos TP-DCS boolean flUCS2; if ((_rsp_buf[firstcharpdu + nf] == '0') && (_rsp_buf[firstcharpdu + nf + 1] == '0')) flUCS2 = false; else flUCS2 = true; nf += 2; // pos TP-SCTS nf += 14; // pos TP-UDL byte lenpdutext = strHexTobyte(_rsp_buf[firstcharpdu + nf], _rsp_buf[firstcharpdu + nf + 1]); nf += 2; // pos TP-UD if (flUCS2) { a6decodetextpduUCS2(lenpdutext, (firstcharpdu + nf), textsms); } else { a6decodetextpdu7bit(lenpdutext, (firstcharpdu + nf), textsms); } } byte strHexTobyte(char p1, char p2) { p1 -= '0'; if (p1 > 10) (p1 -= 7); p1 = p1 << 4; p2 -= '0'; if (p2 > 10) (p2 -= 7); return (p1 | p2); } void a6decodetextpdu7bit(byte charcount, byte firstpos, char* textsms) { for (byte i = 0; i < charcount; ++i) { byte begin7bytepart = i / 8; byte resultbyte = 0; byte numbyte = i % 8; byte b1 = firstpos + (begin7bytepart * 2 * 8) + (numbyte * 2) - (2 * (begin7bytepart + 1)); byte b2 = strHexTobyte(_rsp_buf[b1 + 2], _rsp_buf[b1 + 3]); b1 = strHexTobyte(_rsp_buf[b1], _rsp_buf[b1 + 1]); byte lowb; if (numbyte == 0) { lowb = b2; } else { if (numbyte < 7) (lowb = b2 << numbyte); else (lowb = 0); } byte hib; if (numbyte > 0) (hib = b1 >> (8 - numbyte)); else (hib = 0); resultbyte = hib | lowb; textsms[i] = resultbyte & 0x7F; } textsms[charcount] = 0; } void a6decodetextpduUCS2(byte bytecount, byte firstpos, char* textsms) { for (byte i = 0; i < bytecount; i += 2) { byte b1 = firstpos + (i * 2); byte b2 = strHexTobyte(_rsp_buf[b1 + 2], _rsp_buf[b1 + 3]); b1 = strHexTobyte(_rsp_buf[b1], _rsp_buf[b1 + 1]); if (b1 == 0) { textsms[i / 2] = b2; } else { byte rb; if (b1 == 0x04) { switch (b2) { case 0x01: { rb = 168; break; } case 0x51: { rb = 184; break; } default: { if ((b2 >= 0x10) && (b2 <= 0x4F)) { rb = b2 + 176; } else { rb = b2; } } } } else { rb = b2; } textsms[i / 2] = rb; } } textsms[bytecount / 2] = 0; } void a6getopsname(char* opsname, char* opsbalance) { boolean fl = false; byte i; for (i = 0; i < 12; ++i) { if (strPos(_rsp_buf, OPSlist[i]) >= 0) { fl = true; break; } } if (fl) { byte j = 0; while ((OPScode[j] = OPSlist[i][j]) != 0) ++j; OPScode[j] = 0; j = 0; while ((opsname[j] = OPSlist[i - 2][j]) != 0) ++j; opsname[j] = 0; j = 0; while ((opsbalance[j] = OPSlist[i - 1][j]) != 0) ++j; opsbalance[j] = 0; } } // send win1251 byte to LCD void SendByteToLCD(byte inByte, boolean ET) { if (inByte == 13) { LCD.print(" "); } else { if (inByte < 0x20) return; if ((ET == true) && (inByte >= 0x7F)) return; if (ET == false) { if ((inByte == 168) || (inByte == 184) || ((inByte >= 192) && (inByte <= 255))) { LCD.print(LCD.asciiutf8(inByte)); } else { LCD.print(char(inByte)); } } else { LCD.print(char(inByte)); } } switch (IdxLCD) { case 15: { LCD.setCursor(0, 1); ++IdxLCD; break; } case 31: { LCD.setCursor(0, 0); IdxLCD = 0; break; } default : { ++IdxLCD; } } } void SendStrToLCD(char* latinStr) { byte i = 0; while (latinStr[i] != 0) { SendByteToLCD(latinStr[i], false); ++i; } }наверное я такой криворукий, но у меня весь скетч на char[] и тоже занимает более 80 % динамической памяти,
250 байт входящий буфер от модема, 250 байт исходящий буфер для отправки SMS в PDU формате,
А нельзя использовать один буфер и для приема и для отправки? по-моему они не нужны одновременно...
наверное я такой криворукий, но у меня весь скетч на char[] и тоже занимает более 80 % динамической памяти,
250 байт входящий буфер от модема, 250 байт исходящий буфер для отправки SMS в PDU формате,
А нельзя использовать один буфер и для приема и для отправки? по-моему они не нужны одновременно...
Можно, но сразу сходу не получилось, так как отправка смс идёт двумя AT командами, а скетч универсальный под любые команды и передача смс самой идёт сразу после ответа на первую команду, т е в памяти желательно все держать и отправку и приём.
Как вариант использовать различную размер массивов и динамическое выделение памяти, но тогда теряется универсальность библиотеки которую я для А6 модема написал.
Короче все реально, нужно просто сесть и сделать, а на работе я иногда и работу работаю....лень доделывать - работает стабильно и хорошо.
понял на счет F, супер, ноо большой ущерб памяти флеш... у меня и так флеша 76% на 328p-au
Не будет никакого ущерба. От слова совсем.
Если у Вас используются константные строки, то, когда МК выключен, они должны где-то храниться? Кроме как во flash, больше негде. Вопрос только в том, будут ли они перед применением копироваться в оперативную память или нет. А места занимают ровно столько же.
Не будет никакого ущерба. От слова совсем.
Если у Вас используются константные строки, то, когда МК выключен, они должны где-то храниться? Кроме как во flash, больше негде. Вопрос только в том, будут ли они перед применением копироваться в оперативную память или нет. А места занимают ровно столько же.
Вы ошибаетесь и весьма сильно. Макрос F() вообще ОЧЕНЬ НЕЭФФЕКТИВНО тратит флеш - он тратит флеша куда больше, чем экономит ОЗУ. Особенно это касается повторяющихся строк.
например, код
Serial.print("Bla-bla-bla!"); Serial.print("Bla-bla-bla!"); Serial.print("Bla-bla-bla!"); Serial.print("Bla-bla-bla!"); Serial.print("Bla-bla-bla!");сохранит в ОЗУ только одну копию строки и потратит на это всего 12 байт, а такой же код с макросом F(), сэкономив 12 байт - положит во флеш пять одинаковых строк по 12 байт, не считая накладных расходов.
Можете легко убедится, компилируя коды в Ардуино ИДЕ.
b707, Вы это серьезно?
Да, действительно, способ размещения констант в оперативной памяти и во флеш различается. Именно способ. Из этого следует, что в каких-то случаях оптимальнее окажется одно, в каких-то - другое. Вашь пример явно искусственный, поэтому ориентироваться на него как на правило, вряд ли следует.
В среднем при нормальном коде разницы практически нет. В частности, разница может быть как в плюс, так и в минус.
Но можно придумать частный случай, в котором разница окажется существенной.
В любом случае, ничто не отменаяет того положения, что любая уникальная строка, которая должна появиться в ОЗУ после включения питания, занимает место во flash памяти.
b707, Вы это серьезно?
В среднем при нормальном коде разницы практически нет. В частности, разница может быть как в плюс, так и в минус. Вашь пример явно искусственный, поэтому ориентироваться на него как на правило, вряд ли следует.
В любом случае, ничто не отменаяет того положения, что любая уникальная строка, которая должна появиться в ОЗУ после включения питания, занимает место во flash памяти.
Что, интересно, в этом коде искусственного? То, что строки повторяются?
Вы бы, вместо того, чтобы лозунгами писать - взяли бы и сначала убедились на практике. Возьмем максимально простой пример -одна уникальная строка.
void setup() { // put your setup code here, to run once: } void loop() { // put your main code here, to run repeatedly: Serial.print("s"); } Код - 1342 байта ОЗУ - 186Далее меняем только строчку, поэтому буду указывать только оператор вывода и цифры:
Serial.print("sss"); Код - 1344 байта ОЗУ - 188Пока все логично - дополнительные 2 символа заняли 2 лишних байта и в ОЗУ и в во флеш
Добавляем F()
Serial.print(F("sss")); } Код - 1366 байта ОЗУ - 184Ну что, вы все еще считаете, что "разницы практически нет"? Чтобы освободить 4 байта ОЗУ, макрос F() потратил аж 22 байта флеш.
Хотите дальше? - извольте! добавим еще одну строку, опять уникальную:
Serial.print(F("sss")); Serial.print(F("ght")); Код - 1414 байт, ОЗУ - 184чтобы сравнение было корректным, тот же код без F()
Serial.print("sss"); Serial.print("ght"); Код - 1364 байт, ОЗУ - 192Опять "разницы нет", правда? Тут уже экономия 8 байт обошлась аж в 50 байт флеша...
Можно продолжать и дальше. При каждом использовании F() потери флеша будут разными. Но они всегда больше , чем экономия оперативки. Иногда разница в разы, как в примере выше - иногда почти то на то - но всегда НЕ МЕНЬШЕ.
Ну что, скажете, пример опять неудачен?
Приведите свой.
Ну что, скажете, пример опять неудачен? Приведите свой.
При выключении и включении питания строки без F() продолжают выводиться, значит они сохранены в флеш-памяти. Вопрос в том: почему с F() увеличивается расход флеша?
Вопрос в том: почему с F() увеличивается расход флеша?
нуу... порой исходники макроса F() - видимо они и занимают место на флеше.
При выключении и включении питания строки без F() продолжают выводиться, значит они сохранены в флеш-памяти. Вопрос в том: почему с F() увеличивается расход флеша?
вопрос скорее надо ставить так - если это жестко кодированая строковая константа, зачем она вообще занимает место в оперативке?
А ответ на вопрос, почему макрос F() расходует столько флеша - это как раз просто. Этот макрос не является специализированным именно для констант, это "обертка" для типа FlashStringHelper. который работает не только с контантами, но и с переменными. Поэтому конструкция F("SSS") трактует "SSS" как переменную, которую надо перенести во флеш, оставив на месте ее вызова код, извлекающий строку из флеш-памяти. Поэтому F() не только занимает 4 байта во флеш под строку, но и добавляет в код программы инструкции обратного извлечения этих байт в ОЗУ.
И, снова про повторяющиеся строки - если макросу встречается пять одинаковых строк - он положит во флеш каждую отдельно, не анализируя. что такая строка уже там есть. Это, как я понимаю, тоже следствие того, что F() считает строки переменными.