Все о SIM800L и все что с ним связано.

Alex_Mn
Offline
Зарегистрирован: 07.05.2021
		if(strstr(buf, "RING") != NULL) // ЕСЛИ ЭТО ЗВОНОК
		{

			if(strstr(buf, "+CLIP:") != NULL) // если телефон определяется

				memset(phone, 0, 12);
				uint8_t phoneindex = strcspn(buf, "+"); // точка вхождения +CLIP
				phoneindex += 8; // прибавляем 8 находим точку вхождения телефона.

					for (i = 0; i < 12; ++i)  //копируем телефон в масив phone.
					{
						phone[i] = buf[phoneindex];
						++phoneindex;
					}

					if(strstr(White_List, phone) != NULL) // если звонит нужный номер
					{
						// что-то делаем

					}
					else
					{
						 // что-то делаем
	
					}

			}

			else
			{
				disable_connection(); // сброс соединения

			}
		}

вот мой вариант (с использованием библиотек) с выдергиванием телефона в массив

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Спасибо

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Irinka пишет:

Спасибо

Ирина, что вы такое изобретаете?

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Изучаю)
Char мне даётся трудно, тренируюсь.)

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Irinka пишет:
Char мне даётся трудно, тренируюсь.)

Постоянно с «женскими чарами» мысли путаются?))

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Да не.
Вот эта звездочка *в заблуждение вводит XD
Учусь.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Друзья, может я не прав, но позвольте немного критики:
Если б у вас размер буфера приходящих данных от модема был пару тройку килобайт, то ваш поиск в буфер работал бы норм, но когда например приходит пакет данных gprs, за ним сразу смс +ussd реклама, в буфер все это не влазит, и получается что устройство не отработает команду.
На stm32 с кучей ресурсов это взлетает, на atmega328p только online логика обработки данных спасает.

Alex_Mn
Offline
Зарегистрирован: 07.05.2021

andycat пишет:
... На stm32 с кучей ресурсов... VS ... на atmega328p только...

да победит сильнейший, в жизни всегда так.

olegue
Offline
Зарегистрирован: 23.09.2020

хочу гудки входящего звонка посчитать. Нашел пока только

ATS0=<n>
<n> — количество гудков до автоматического ответа при входящем вызове:

0 — автоответ отключен
1...255 — количество гудков, после которых модуль автоматически ответит на входящий вызов.
xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

olegue пишет:

хочу гудки входящего звонка посчитать.

считай, кто тебе не дает, на SIM800L есть выход RING.

olegue
Offline
Зарегистрирован: 23.09.2020

Спасибо. Именно то что нужно.

Nesco
Offline
Зарегистрирован: 22.08.2022

Sim800L с али работает только на скорости 115200. Это нормально или брак?

В связке с Arduino UNO заметил глюки, пока не понял программные или аппаратные. Мусор в порту. Может UNO всё таки подожжёный, а может и программные косяки.

Если Sim800L воткнуть через USB-UART в компьютер, то на скорости 115200 мусора нет. AT команды выполняет, на RING реагирует, на мониторе порта всё нормально.  На остальных скоростях он не работает нормально.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Nesco пишет:

Sim800L с али работает только на скорости 115200. Это нормально или брак?

В связке с Arduino UNO заметил глюки, пока не понял программные или аппаратные. Мусор в порту. Может UNO всё таки подожжёный, а может и программные косяки.

Если Sim800L воткнуть через USB-UART в компьютер, то на скорости 115200 мусора нет. AT команды выполняет, на RING реагирует, на мониторе порта всё нормально.  На остальных скоростях он не работает нормально.

это нормально. И зачем больше? GPRS Там медленный, а если используете software serial - то нормальной работы в принципе не получите.

Upper
Offline
Зарегистрирован: 23.06.2020

Nesco пишет:

Sim800L с али работает только на скорости 115200. Это нормально или брак?

Какой ответ приходит на команду "AT+IPR?"

Nesco
Offline
Зарегистрирован: 22.08.2022

Через USB UART на AT+IPR? получаю:

+IPR: 115200

 

Upper
Offline
Зарегистрирован: 23.06.2020

Чтобы узнать поддерживаемые скорости

AT+IPR=?

Если хотите автоматический выбор скорости дайте команду

AT+IPR=0

Nesco
Offline
Зарегистрирован: 22.08.2022

Спасибо !!!

С AT+IPR=0 всё получилось. Сохранил через AT&W0. Оключил от питания, проверил. Всё сохранилось. Автовыбор стоит. Классно!

А яуже успел новый модуль купить. Буду дальше разбираться.

Nesco
Offline
Зарегистрирован: 22.08.2022

andycat

У меня другой модем работал на 9600, с ним вроде мусора в порту не было. И покупал его не на али, а здесь в магазине в несколько раз дороже. Но я его спалил.

Мне не нужен GPRS. GSM хватит, я хочу его использовать только в качестве голосового телефона.

А для реализации голосового телефона кроме software serial можете что-то ещё посоветовать?

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Тем более, для команд 9600 более чем достаточно.
Совет один, скетч тестируем через software serial, потом в итоговом устройстве просто через 0 и 1 пины ардуины работаем через hw uart

Nesco
Offline
Зарегистрирован: 22.08.2022

Ну вот и разобрался с глюками.

В программе использую как и раньше SIM800L.begin(9600);

В модеме сохранено автоопределение скорости.

И никакого мусора в порте.

Т.е. с программой всё нормально, прикол был в настройках скорости модема.

Благодарю форумчан за помощь !

olegue
Offline
Зарегистрирован: 23.09.2020

подскажите , плиз код как проверить что установлено gprs соединение. Оператор рвет каждые 12 часов.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Это нормально, обычно через сутки нахождения модема в зоне одной базовой станции оператор наглухо рвёт связь, необходима или повторная регистрация или радио часть модема переключать
https://arduino.ru/forum/programmirovanie/snova-mqtt-1?page=1#comment-56...

olegue
Offline
Зарегистрирован: 23.09.2020

посмотрел проект, мудрено очень, с наскоку не освоить. Но если не сильно заморачиваться можно ж периодически резетить  модем и МК?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Да, легко.
Только при перезагрузке модема через reset он пытается восстановить cip сессию, поэтому можно при старте cip shutdown. Но вообще это все костыль, пока не начнёте анализировать ответы модема, толком нормальной железки не получиться.
По ссылке выше список команд инициализации, которые я практически всегда использую, можете банально при каждом старте прогонять весь список с задержкой секунд 5 после каждой команды, или хотя бы ожидания ответа OK

olegue
Offline
Зарегистрирован: 23.09.2020

оператор и в 00.00 тоже рвет сессию.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

olegue пишет:

оператор и в 00.00 тоже рвет сессию.

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

olegue
Offline
Зарегистрирован: 23.09.2020

не хотелось бы , конечно, себя костылями обкладывать уже в самом начале пути. Понимаю, что без этого не обойдется.  Мой случай пока чисто академический, закидываю температуру с ds18b20 на thingSpeak и одновременно на свой Php server. В перспективе, данные планирую закидывать в базу mysql с анализом в google chart и с него же хочу сделать управление нагрузками. 

что если мне распарсить At+cipstatus перед отправкой данных и при необходимости опять запускать настройку gprs соединения?

olegue
Offline
Зарегистрирован: 23.09.2020

Ну это по прежнему останется костылем, но он будет менее костыльный. Как думаете?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

olegue пишет:

что если мне распарсить At+cipstatus перед отправкой данных и при необходимости опять запускать настройку gprs соединения?

это лучше чем ничего, если не CONNECTED - перезагрузка, но в идеале надо все ответы модема смотреть без исключения.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

очередное наблюдение из жизни питания SIM800L:
модем SIM800L подцепил к RP2040 на монтажную панельку штырьками, питание от аккумулятора 18650.
третий день не мог понять почему SIM карта то регистрируется в сети то нет, перебрал кучу СИМок/операторов, ничего не помогало.
подцепил аккумулятор напрямую к модему, без панели, и о чудо - проблема исчезла.
пришлось паять маленькую испытательную платку, с намертво припаянным питанием.

 

olegue
Offline
Зарегистрирован: 23.09.2020

Если оператор оборвет связь достаточно ли будет дать команду

AT+SAPBR=1,1

 

что бы восстановить ее?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

olegue пишет:

Если оператор оборвет связь достаточно ли будет дать команду

AT+SAPBR=1,1

 

что бы восстановить ее?

нет

ЗЫ. Хотя не уверен, попробуйте :) нам расскажете

olegue
Offline
Зарегистрирован: 23.09.2020

обязательно, завтра буду знать как это сработало. А может и сегодня , спрячу модуль в железную коробку, ну типа эмуляция - нет сети и посмотрю что из этого будет. Сумеет ли он восстановить связь.

SAB
Offline
Зарегистрирован: 27.12.2016

в железной коробке (сейфе) сеть будет. Проверено сотик в сейфе звонит.

olegue
Offline
Зарегистрирован: 23.09.2020

да, в фольгу обернул - gprs никак не отреагировал

olegue
Offline
Зарегистрирован: 23.09.2020

AT+SAPBR=1,1

 

с этой командой перед отправкой легко прошел 00.00, но что бы все точно выяснить нужно повторить эксперимент.

olegue
Offline
Зарегистрирован: 23.09.2020

я так понял , что ThingSpeak это бесплатная балалайка , которая показывает лишь 60 значений. 

nik182
Offline
Зарегистрирован: 04.05.2015

Ну так накати какое-нибудь mojordomo на маленькую малинку и будет тебе куда больше 60 и всё в руках.    

olegue
Offline
Зарегистрирован: 23.09.2020

в 3.30 thingSpeak прекратил прием данных по неизвестной причине, думал, что проблема gprs. Но мой php сервер продолжил как нив чем. Отлично! Про 60 я ошибочную инфу дал выше.

kontulavittu
Offline
Зарегистрирован: 06.12.2018

Привет!  800L ,насколько я понял, работает макс. в 2G-сетях. У нас их начали отключать. Посмотрел модули 3G, какие-то космические цены, дешевле б/у телефон купить. Кто как решает проблему коммуникации Ардуино с 3G -мобильными сетями? Или есть чудо-тема соединения/управления смартфоном через блютузку? Заранее благодарю за ответы.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Да, цены на 3g4g модемы simcom космические, вариантов нет. У них есть NB-IoT модемы, я с таким работал, хорошая вещь, относительно недорогая, но сети эти не везде, тарифы в массе своей только для юр лиц, просто так sim ку не купить (во всяком случае я не смог в своём регионе), да и тарифы я б не сказал что дешёвые.

Nesco
Offline
Зарегистрирован: 22.08.2022

andycat пишет:
Тем более, для команд 9600 более чем достаточно. Совет один, скетч тестируем через software serial, потом в итоговом устройстве просто через 0 и 1 пины ардуины работаем через hw uart

Дошёл до этого момента. Попробовал на аппаратном UART, всё работает. Понял, что пока у меня всё таки ещё есть глюки, пришлось вернуться на программный UART, иначе не изменишь программу.

Хочется сделать на процессоре, UNO уже ни к чему. Конечно надо плату разрабатывать, процесс идёт.

Решил сразу заложить возможность правки программы, вывести интерфейс SPI. На процессоре это выводы 17,18,19 и 1. У меня из них оказался занят один 18,  перенесу его на другой свободный.

А вообще освобождение выводов SPI обязательно или нет?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Крайне рекомендовано.

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Здравствуйте.

Не хочет модуль сеть ловить при такой трассировке на плате.

Земля общая.

Антенна накручена вот такая

Эта же антенна через переходник сеть ловит (IPX ANT)

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Очередная реинкарнация логики работы с модемом, без использования какого либо буфера.
Минимальный код инициализации модема:

/*
 Name:		S800wTFT.ino
 Created:	13.01.2023 15:49:09
 Author:	Andrey
*/

#include <avr/wdt.h>

#define SHOW_REPORT_LOG // закомментировать, если не требуется ничего выводить в HW UART монитор порта

uint8_t mcusr_mirror __attribute__((section(".noinit")));
void get_mcusr(void) \
__attribute__((naked)) \
__attribute__((used)) \
__attribute__((section(".init3")));
void get_mcusr(void)
{
	mcusr_mirror = MCUSR;
	MCUSR = 0;
	wdt_disable();
}

static constexpr unsigned char pin_SIM800L_TX = 2; // пин TX на модуле подключаем к указаному пину на Ардуино RX
static constexpr unsigned char pin_SIM800L_RX = 3; // пин RX на модуле подключаем к указаному пину на Ардуино TX
static constexpr unsigned char pin_SIM800L_RST = 4; // пин сброс модема

#include <SoftwareSerial.h> // библиотека softaware UART, через нее идет обмен данными с модемом
// в реальном устройстве крайне рекомендуется не использовать
// после окончательного тестирования, полностью убрать из скетча
// перевести работу с модемом на аппаратный UART RX0 TX1
// или использовать МК с двумя и более Serial
SoftwareSerial gsm(pin_SIM800L_TX, pin_SIM800L_RX); // установка контактов GSM_TX->RX и GSM_RX->TX для программного порта

static constexpr unsigned long period_wait_OK_init_cmd = 2000; // время ожидания ответа модема на начальные команды инициализации
// значение в даташите не прописано, двух секунд обычно достаточно, в случае отсутствия ответа -> перезагрузка модема и все сначала
static constexpr unsigned long period_wait_start_modem = 10000; // время проснуться модему после включения
static constexpr unsigned long period_wait_reg_modem = 60000; // время регистрации в сети

unsigned char modemReady; // флаг, что модем успешно инициализировался и вышел на связь с базовой станцией

const char at0cmdATZ[] PROGMEM = "ATZ\r"; // проверка связи // сброс настроек модема
const char at1cmdDDET[] PROGMEM = "AT+DDET=1\r"; // включаем режим распознавания DTMF
const char at2cmdATE0[] PROGMEM = "ATE0\r"; // отключаем возврат команд от модема
const char at3cmdCLIP1[] PROGMEM = "AT+CLIP=1\r"; // включаем АОН
const char at4cmdATS0[] PROGMEM = "ATS0=0\r"; // вручную поднимать трубку при входящем звонке
const char at5cmdATV1[] PROGMEM = "ATV1\r"; // развернутый символьный ответ от модема
const char at6cmdATCMEE2[] PROGMEM = "AT+CMEE=2\r"; // подробный вывод ошибок
const char at7cmdATCMGF1[] PROGMEM = "AT+CMGF=1\r"; // не PDU режим приема и отправки SMS
const char at8cmdCSCLK1[] PROGMEM = "AT+CSCLK=0\r"; // отключаем режим ухода в сон с помощью пина DTR на модеме
const char at9cmdNULL[] PROGMEM = ""; // последняя команда пустая

const char* const at_list_cmd_init[] PROGMEM = { // команды начальной инициализации модема
  at0cmdATZ, at2cmdATE0, at5cmdATV1, at6cmdATCMEE2, at3cmdCLIP1, at1cmdDDET, at4cmdATS0, at7cmdATCMGF1, at8cmdCSCLK1, // initATmodem
  at9cmdNULL // в конце обязательно пустая команда
};

void resetModem() { // функция сброс модема
	pinMode(pin_SIM800L_RST, OUTPUT);
	delay(115);
	pinMode(pin_SIM800L_RST, INPUT);
	modemReady = 0; // после сброса модем еще не настроен
#ifdef SHOW_REPORT_LOG
	Serial.println("Reset!");
#endif
}

// the setup function runs once when you press reset or power the board
void setup() { // начало работы
	MCUSR = 0; wdt_disable(); // отключение Watch Dog Timer
#ifdef SHOW_REPORT_LOG
	Serial.begin(115200); // HW UART для отладки
#endif
	gsm.begin(9600); // SW UART для модема
	pinMode(LED_BUILTIN, OUTPUT); // пин встроенного светодиода
	digitalWrite(LED_BUILTIN, LOW); // гасим встроенный светодиод
	pinMode(pin_SIM800L_RST, INPUT); // пин сброса модема в режим входа
	digitalWrite(pin_SIM800L_RST, LOW); // ногу сброса отключаем - рабочий режим
	modemReady = 0; // начало работы, модем еще не настроен
#ifdef SHOW_REPORT_LOG
	Serial.println("Start!");
#endif
	wdt_enable(WDTO_8S); // запуск WDT
}

unsigned char readByteFromModem() { // функция чтения байта из UART модема
	if (gsm.available()) return gsm.read(); // если есть что считывать - читаем байт
	else return 0; // иначе выдаем ноль
}

unsigned char findOKRNfromModem(const unsigned char inByte /*входной байт из модема*/) { // Поиск во входящих из модема данных OK
	const unsigned char strOK[] = "OK\r\n"; // строка поиска
	static constexpr unsigned char lenOK = 4; // длина строки поиска // можно strlen использовать, но константой быстрее
	static unsigned char foundPosOK = 0; // число найденных символов в строке OK\r\n
	if (strOK[foundPosOK] == inByte) { // нашелся символ
		if ((++foundPosOK) == lenOK) { // увеличиваем счетчик найденых символов и заодно сдвигаем позицию поиска // нашлась вся строка
			foundPosOK = 0; // обнуляем поиск
			return 1; // успешно выходим
		}
	}
	else { // не совпадает
		foundPosOK = 0; // обнуляем поиск
	}
	return 0;
}

unsigned char initModem(const unsigned char inByte /*входной байт из модема*/) { // функция начальной инициализации модема
	static unsigned char initMode = 0; // 0 - инициализация 1 - регистрация в сети 2 - удаление всех СМС
	static unsigned char initStep = 0; // текущий шаг работы внутри режима
	static unsigned char initCmd; // текущая команда внутри режима
	static unsigned long initTimer; // рабочий таймер
	static unsigned long regTimer; // таймер регистрации модема в сети
	if (!initMode) { // инициализация
		switch (initStep) { // режимы/шаги инициализации
		case 1: { // модем просыпается, ждем окончания таймера
			if ((millis() - initTimer) >= period_wait_start_modem) ++initStep; // время вышло // переходим на след шаг
			break;
		}
		case 2: { // начнем по очереди слать команды модему и ожидать от них ответа
			initCmd = 0; // начнем с нулевой команды
			++initStep; // переходим на след шаг
			break;
		}
		case 3: { // отправка команды модему
			char cmd_buf[14]; // буфер команд
			cmd_buf[0] = '\0'; // очиcтка строки
			const char* addrStroki = pgm_read_word_near((int)(at_list_cmd_init + initCmd)); // адрес команды в eeprom
			strcpy_P(cmd_buf, addrStroki); // достать команду
			if (cmd_buf[0] == '\0') { // пустая команда
				initMode = 1; // переходим в режим регистрации SIM в сети
				initStep = 0; // начальный шаг
			}
			else { // успешно вытащили команду из PROGMEM
				gsm.print(cmd_buf); // отправляем команду в модем
#ifdef SHOW_REPORT_LOG
				Serial.print(cmd_buf); // выводим/дублируем в лог
#endif
				initTimer = millis(); // обновили таймер
				++initStep; // переходим на след шаг
			}
			break;
		}
		case 4: { // ожидание ОК от модема
			if ((millis() - initTimer) >= period_wait_OK_init_cmd) goto initLabelReset; // ответ не пришел
			if (inByte) { // что то вразумительное прилетело из модема
				if (findOKRNfromModem(inByte)) { // нашлось ОК
					++initCmd; // будем отправлять следующую команду
					initStep = 3; // переходим в режим отправки команды
				}
			}
			break;
		}
		default: { // 0 - запуск таймера ожидания модема при включении
			initTimer = millis(); // обновили таймер
			++initStep; // переходим на след шаг
		}
		}
	}
	else if (initMode == 1) { // регистрация в сети
		static unsigned char flagReg; // флаг успешной регистрации
		static unsigned char regStep; // шаги парсинга регистрации
		const unsigned char strREG[] = "+CREG: "; // строка поиска
		static constexpr unsigned char lenREG = 7; // длина строки поиска // можно strlen использовать, но константой быстрее
		static unsigned char foundPosREG; // число найденных символов в строке
		switch (initStep) { // режимы/шаги регистрации в сети
		case 1: { // отправка команды
			if ((millis() - regTimer) >= period_wait_reg_modem) goto initLabelReset; // не смогли зарегестрироваться
			gsm.print(F("AT+CREG?\r")); // запрос статуса регистрации
#ifdef SHOW_REPORT_LOG
			Serial.println(F("AT+CREG?")); // дублируем команду в консоль
#endif
			initTimer = millis(); // обновили таймер
			++initStep; // переходим на след шаг
			flagReg = 0; // сбросим флаг регистрации
			regStep = 0; // начинается парсинг с начала
			foundPosREG = 0; // ничего пока не нашли
			break;
		}
		case 2: { // парсинг ответа на команду и ожидание ОК
			if ((millis() - initTimer) >= period_wait_OK_init_cmd) ++initStep; // переходим на след шаг // ответ не пришел
			if (inByte) { // что то вразумительное прилетело из модема
				// парсим ответ модема
				switch (regStep) {
				case 100: { // ждем цифру
					if (isdigit((char)inByte)) ++regStep; else regStep = 0; // если да - переходим на другой шаг
					break;
				}
				case 101: { // ждем запятую
					if (inByte == ',') ++regStep; else regStep = 0; // если да - переходим на другой шаг
					break;
				}
				case 102: { // ждем цифру регистрации в домашней сети или в роуминге
					if ((inByte == '1') || (inByte == '5')) {
						regStep = 0; flagReg = 1; // если да - ставим флаг
					}
					else {
						regStep = 0;
					}
					break;
				}
				default: { // 0 - ищем строку +CREG:
					if (strREG[foundPosREG] == inByte) { // нашелся символ
						if ((++foundPosREG) == lenREG) { // увеличиваем счетчик найденых символов и заодно сдвигаем позицию поиска // нашлась вся строка
							foundPosREG = 0; // обнуляем поиск
							regStep = 100; // переходим на след шаг поиска
						}
					}
					else { // не совпадает
						foundPosREG = 0; // обнуляем поиск
					}
				}
				}
				// окончание парсинга
				if (findOKRNfromModem(inByte)) { // нашлось ОК
					if (flagReg) { // успешно зарегестрировались
						// если на этом необходимо закончить начальную инициализацию
						//return 1; // успешно выходим
						// если необходимо удалить все SMS на модеме
						initMode = 2; // переходим в режим удаления всех СМС
						initStep = 0; // начнем с начала
					}
					else { // не прошла регистрация
						++initStep; // переходим на след шаг
					}
				}
			}
			break;
		}
		case 3: { // начнем отсчитывать время до следующей отправки команды запроса регистрации
			initTimer = millis(); // обновили таймер
			++initStep; // переходим на след шаг
			break;
		}
		case 4: { // ждем окончания таймера для повтора команды
			if ((millis() - initTimer) >= 5000UL) initStep = 1; // переходим на шаг отправки команды
			break;
		}
		default: { // 0 - начало
			regTimer = millis(); // обнулили таймер регистрации
			++initStep; // переходим на след шаг
		}
		}
	}
	else { // удаление всех СМС
		switch (initStep) { // режимы/шаги
		case 1: { // ждем ответ
			if ((millis() - initTimer) >= 25000UL) return 1; // ответ не пришел - все равно успешно выходим
			if (inByte) { // что то вразумительное прилетело из модема
				if (findOKRNfromModem(inByte)) return 1; // нашлось ОК - успешно выходим
			}
			break;
		}
		default: { // 0 - отправляем команду
			gsm.print(F("AT+CMGDA=\"DEL ALL\"\r")); // удалить все SMS с SIM карты
#ifdef SHOW_REPORT_LOG
			Serial.println(F("AT+CMGDA=\"DEL ALL\"")); // дублируем команду в консоль
#endif
			initTimer = millis(); // обновили таймер
			++initStep; // переходим на след шаг
		}
		}
	}
	return 0;
initLabelReset: // все плохо, модем нормально не отвечает
	initMode = 0; // все обнуляем
	initStep = 0; // все обнуляем
	resetModem(); // сбрасываем модем
	return 0;
}

// the loop function runs over and over again until power down or reset
void loop() { // бесконечный цикл
	wdt_reset(); // сброс WDT
	unsigned char readedByte = readByteFromModem(); // прочитали байт из модема
#ifdef SHOW_REPORT_LOG
	if (readedByte) Serial.write(readedByte); // вывели прочитанный байт в консоль
#endif
	if (!modemReady) { // если связь модема еще не установилась
		if (initModem(readedByte)) { // успешно проинициализировались
			modemReady = 1; // ставим флаг успешности
			// тут можно что то сделать сразу после успешного запуска модема
#ifdef SHOW_REPORT_LOG
			Serial.println("Ready!");
#endif
		}
	}
	else { // GSM связь успешно наладилась
		// тут работаем с модемом, выполняем какие то свои действия с приемом/передачей данных
		// для работы своего функционала можно например использовать список текущих режимов
		// т е отправка или чтение СМС или обработка DTMF сигналов
		// или делать постоянный запуск своей функции и если на выходе ее единичка,
		// значит функция свое отработала и можно запускать каскадно другие обработчики
	}
	// делаем что то свое в цикле, не рекомендуется использовать delay и любые другие сильно тормознутые конструкции
	// окончание своей работы в цикле
}

/*Program size: 4 732 bytes (used 15% of a 30 720 byte maximum) (11,02 secs)
Minimum Memory Usage: 351 bytes (17% of a 2048 byte maximum)*/

 

Alex_Mn
Offline
Зарегистрирован: 07.05.2021

я не сильно гуру в программировании, пяток устройств с использовании модемов SIM800L, в устройствах используется Передача и прием СМС + передача звука. за пару лет эксплуатации (эксплуатация постоянная) ниразу ниче не зависло.

Oleg.L.
Offline
Зарегистрирован: 19.08.2014

Здравствуйте. Модуль SIM800L в паре с Ардуино Мега после включения питания, прекрасно работает в гаражной сигнализации, принимает СМС-команды, исправно исполняет, отчитывается об исполнении СМС-ответами, но спустя примерно месяц или чуть больше, перестает реагировать на входящие СМС-команды от пользователя, при этом работа сигнализации не нарушается, приходят и СМС оповещения и дозвоны пользователю, снимается и ставится на охрану с помощью брелока (как задумано), из чего следует, что контроллер не зависает, модуль SIM800L тоже в деле. Но вот СМСки модуль перестает принимать именно спустя несколько дней после включения питания. Если предположить, что память модуля забивается СМС-спамом, так я прописал в модуль команду принимать звонки и СМС только от конкретного номера. В скетче предусмотрена АТ-команда очистка всех СМС при каждом получении команды от пользователя. В setup тоже есть такая АТ команда. СМС от пользователя в течение того же времени отправлялись раза два. А может спам все-таки проходит от оператора (Билайн) и забивает память модуля? Может кто сталкивался с такой проблемкой?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Oleg.L. пишет:

 Может кто сталкивался с такой проблемкой?

писать код программы так, что бы не подавилось длинными рекламными СМС.

 

Oleg.L.
Offline
Зарегистрирован: 19.08.2014

Возможно, теперь прописал раз в 5 дней (по таймеру) очистку всех СМС, и все равно, спустя 5-7 дней перестает принимать команды, точно сколько проходит дней не знаю, заметил еще, что команды от брелока, снятия и постановки на охрану спустя те же несколько дней, тоже выполняются не сразу, на 5й, а то и на 8й раз нажатия на кнопку, чего не замечалось после перезагрузки. Может контроллер без перезагрузки, спустя некоторое время, начинает "тормозить" из-за большого программного кода?  Хочу попробовать прописать раз в сутки программную перезагрузку перехода на начало кода. Как думаете, есть смысл?

Alex_Mn
Offline
Зарегистрирован: 07.05.2021

код должен быть таким чтоб при приеме длинного СМС (рекламное) не происходил затык. проверяется легко. запустил код послал команду она исполнилась. послал длинное СМС (очень длинное), и после этого проверка, послал команду если теперь она не принимается явные причины беспокойства на длинные СМС.