http://lazysmart.ru/ - кто пробовал и какие аналоги есть в интернет*
- Войдите на сайт для отправки комментариев
Пт, 01/06/2018 - 20:22
http://lazysmart.ru/ ктонибудь пробовал сервис и скетч оттуда?
#include <OneWire.h> //Подключаем библиотеку для обмена с датчиком температуры #include <avr/wdt.h> //Подключаем библиотеку для использования сторожевого таймера //----------------------------------Флаги ----------------------------------------- bool GPRS_connect=false; //Флаг "Есть подключение к GPRS" bool CSt_send_success=true; //Флаг "Текущая команда реле передана успешно" bool BT_send_success=true; //Флаг "Значение текущей температуры передано успешно" bool change_request = false; //Флаг "Запрос на сервер изменён". Устанавливается в момент когда необходимо отправить на сервер новые данные bool blink_led; //Флаг "Светодиод "В работе" горит" //---------------------------------------------------------------------------------- //-------------------------------------- int Command; //Содержит команду для реле, полученную от сервера int Command_o=-1; //Предыдущая команда для реле. Служит для фиксации факта изменения комады. Проинициализирована заведомо ложным значением -1 int term; //Содержит последнее измеренное значение температуры int term_o; //Содержит предпоследнее измеренное значение температуры. Служит для фиксации факта изменения температуры. int GET_step, GET_step_o; //Текущий и предыдущий шаги посылки запроса серверу int SRead_step, SRead_step_o; //Текущий и предыдущий шаги получения ответа от сервера unsigned long Startup_time_s; //Время с момента включения в секундах unsigned long Last_succsess_time; //Время, последнего успешного обмена с сервером unsigned long Last_blink_time; //Время, последнего моргания светодиодом "В работе" int DO=38; //Номер пина, который управляет выходным реле long int LOG=1234; //Логин устройства. Его можно посмотреть в настройках устройства на сервисе LS Cloud long int PAS=1111; //Пароль устройства. Его можно посмотреть в настройках устройства на сервисе LS Cloud OneWire ds(42); // Линия 1-Wire для опроса датчика температуры будет на пине 42 byte data[2]; // Массив для обмена с датчиком температуры unsigned char Step; //Номер шага, на котором находится основной цикл программы ("Отправка запроса на сервер", "Получение ответа от сервера", "Анализ системы") String responce_status; //Хранит статус обмена с модемом на текущем шаге String Request; //Хранит строку запроса на сервер String Responce; //Хранит строку ответа от сервера String SIM_Data; //Строка содержит символы, полученные от модема при "общении" с ним void setup() { /* ----------------------Включаем сторожевой таймер на 8 секунд.---------------- */ /* Сторожевой таймер служит для защиты контроллера от зависания. */ /* Программа выполняется циклично и в каждом цикле производится сброс таймера. */ /* Если контроллер зависнет, таймер не будет сброшен программно и через 8 секунд */ /* контроллер автоматически перезагрузится. */ wdt_enable(WDTO_8S); /*Формируем первичный запрос к серверу. */ /*Добавляем в параметры логин и пароль для авторизации устройства на сервере*/ Request = "http://t.lazysmart.ru/device_status.php?LOG="; Request+=String(LOG); Request+="&PAS="; Request+=String(PAS); /*Инициализируем COM-порты*/ Serial.begin(57600); // скорость обмена с отладочным портом Serial1.begin(19200); // скорость обмена с модемом Serial1.setTimeout(1000); // 1000 мс ждать данных от модема до генерации таймаута /*Инициализируем порт, который управляет реле перезагрузки модема*/ pinMode(48,OUTPUT); //Для вкл./выкл. модема /*Инициализируем порты, к которым подлючены сигнальные светодиоды*/ pinMode(49,OUTPUT); //Для индикации "В работе". Моргает не чаще раза в секунду, если контроллер работает (т.е. не завис) pinMode(50,OUTPUT); //Для индикации нового запроса. Загорается при каждом запросе и гаснет после получения ответа pinMode(52,OUTPUT); //Для индикации подключения к GPRS /*Инициализируем порт, который управляет выходным реле*/ pinMode(DO,OUTPUT); //Дискретные выход digitalWrite(48,HIGH); //Подаём питание на модем digitalWrite(49,HIGH); //Начальное состояние светодиода "В работе": "горит" /*Запускаем модем*/ powerUp(); //Запускаем GPRS-модем //---------------------------!ИНИЦИАЛИЗАЦИЯ ЗАВЕРШЕНА----------------------------------------------------------------------------- //---------------------------ПОДКЛЮЧЕНИЕ К GPRS----------------------------------------------------------------------------------- GPRS_Init(); } //--------------------------!ПОДКЛЮЧЕНИЕ К GPRS----------------------------------------------------------------------------------- //--------------------------------------ОСНОВНОЙ ЦИКЛ----------------------------------------------------------------------------- void loop() { //Моргаем сетодиодом "В работе" не чаще раза в секунду if(blink_led && Last_blink_time - (millis()/1000) > 1){ Last_blink_time = (millis()/1000); //Время с момента последнего моргания digitalWrite(49,LOW); //Переключаем светодиод "В работе" blink_led = false; } else if(Last_blink_time - (millis()/1000) > 1){ Last_blink_time = (millis()/1000); //Время с момента последнего моргания digitalWrite(49,HIGH); //Переключаем светодиод "В работе" blink_led = true; } /*Главный цикл программы выполняется пошагово*/ if(Step != ' '){ switch(Step){ /* На первом шаге отправляем запрос серверу */ case '1': { digitalWrite(50,HIGH); //Зажигаем светодиод при отправке запроса int SendStatus = SendGETRequest(); // Определяем статус отправки запроса if(SendStatus==1){ Step = '2'; //Запрос успешно отправлен - переходим к следующему шагу } else if(SendStatus==-1){ SIM900_Reload(); //При отправке возникла критическая ошибка - нужно перезагрузить модем } } break; /* На втором шаге ожидаем ответ сервера */ case '2': switch(WaitForResponce()){ case 0: { break; //еще анализируем ответ от сервера } case 1: { //Ответ получен успешно PrintlnToSerial(Responce); //Посылаем текст ответа на отладочный порт digitalWrite(50,LOW); //Гасим светодиод при успешном ответе String S = AnalizeResponce("COMMAND"); //По кодовому слову "вычленяем" полезные данные из ответа if(S != "NOT_STR"){ //Если ответ валиден и в нём найдены полезнае данные (команда устройству от сервера) - // то выполняем полученные команду, если она отлична от предыдущей PerformCommands(S); } Step = '3'; //Переходим на следующий шаг break; } case -1:{ Step = '1'; //Возникла ошибка, вернул -1. Возвращаемся на предыдущий шаг для отправки нового запроса } } break; /* На третьем шаге производится обмен с датчиком температуры (для получения её актуального значения), выполняются полученные от сервера команды и формируется новый запрос */ case '3': { AnalizeSystem(); Step = '1'; //Возвращаемся на первый шаг } } } //Сбрасываем сторожевой таймер на каждом цикле программы wdt_reset(); //-------------------------------------------Алгоритм "выживания" ----------------------------------------------------------------- /* Алгоритм выживания используется для предотвращения непредвиденных ситуаций в обмене с модемом. */ /* Сбои программной логике модема, "мусор" полученный от сети и другие ситуации - могут привести к зависанию модема или его неадекватной работе */ /* Применяем простейший алгоритм "выживания" в таких ситуациях: если в течение 3-х минут от сервера не получено никаких полезных данных - */ /* - перезагружаем модем */ if(((millis()/1000) - Last_succsess_time) >180){ //Если в течение 3-х минут ни разу не получили полезные данные - перегружаем мождем PrintlnToSerial("Last_succsess_responce_time > 180 s. Reload modem..."); //Отправляем сообщение о перезагрузке в отладочный порт SIM900_Reload(); //Перегружаем модем } } //--------------------------------------!КОНЕЦ ОСНОВНОГО ЦИКЛА-------------------------------------------------------------------- /*------------------------------------------------------------------------------------------------------------------*/ /* Описание: Функция ConnectToGPRS() */ /* Производит подключение модема к GPRS и открывает HTTP-сеанс */ /* Входы: ----- */ /* Выходы: Возвращает true в случае успешного подключения и false - в противном случае */ /*------------------------------------------------------------------------------------------------------------------*/ bool ConnectToGPRS() { Startup_time_s = (millis()/1000); //Время с момента включения в секундах. //Последовательно выполняем команды для подключения модема к GPRS и открытия HTTP-сеанса //После каждой команды ожидаем ответа в цикле while. //Для избежания зависания на каждом цикле выполняем функцию SIM900_answ_test() Serial1.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\""); while(!ShowSerialData("OK","ERROR")){if(!SIM900_answ_test()) return false;} if(responce_status == "OK") { Serial1.println("AT+SAPBR=3,1,\"APN\",\"internet\""); while(!ShowSerialData("OK","ERROR")){if(!SIM900_answ_test()) return false;} if(responce_status == "OK") { while(1){ delay(1000); Serial1.println("AT+SAPBR=1,1"); //модем может вернуть ERROR //но это не ошибка, если продолжать запросы в конце концов может подключиться и вернуть ОК //поэтому если получаем ERROR - продолжаем посылать такие запросы while(!ShowSerialData("OK","ERROR")){if(!SIM900_answ_test()) return false;} if(responce_status == "OK") { Serial1.println("AT+HTTPINIT"); while(!ShowSerialData("OK","ERROR")){if(!SIM900_answ_test()) return false;} if(responce_status == "OK") { Serial1.println("AT+HTTPPARA=\"CID\",1"); while(!ShowSerialData("OK","ERROR")){if(!SIM900_answ_test()) return false;} if(responce_status == "OK") { return true; //Сеанс обмена успешно открыт } } } } } } return false; } /*------------------------------------------------------------------------------------------------------------------*/ /* Описание: Функция ShowSerialData(String OK, String ERR) */ /* Читает ответ от модема контроллеру по последовательному порту */ /* Когда ответ получен, функция записывает его в переменную responce_status */ /* Входы: Принимает строку успешного ответа на команду и строку ответа-ошибки */ /* Выходы: Возвращает true если ответ получен(успешный или ошибка), false - ответ от модема еще анализируется */ /*------------------------------------------------------------------------------------------------------------------*/ boolean ShowSerialData(String OK, String ERR) { responce_status = "!"; //Инициализируем заведомо ложным значением if(Serial1.available()) //Если в порт уже пришли новые данные от модема { Startup_time_s = (millis()/1000); //Время с момента включения в секундах. while(Serial1.available()) //Пока не прочитаем то, что уже пришло { SIM_Data = Serial1.readStringUntil(char(13)); // читаем ответ до символа перевода на след. строку '\r' PrintlnToSerial(SIM_Data); //Посылаем в отладочный порт полученные данные //Сравниваем полученные данные с кодом успешного ответа и ответа-ошибки if (SIM_Data.substring(SIM_Data.length()- OK.length()) == OK) { responce_status = OK; Serial1.flush(); //Ждём пока данные перестанут лететь и освобождаем буфер return true; } else if (SIM_Data.substring(SIM_Data.length()- ERR.length()) == ERR) { responce_status = ERR; Serial1.flush(); //Ждём пока данные перестанут лететь и освобождаем буфер return true; } //Если каким-то немыслимым образом тут зависли (данные из порта продолжают приходить), //выходом из цикла while будет подпрограмма защиты от зависания if(!SIM900_answ_test()) return false; } } else return false; } /*-------------------------------------------------------------------------------------------------------------------*/ /* Описание: Функция WaitReadyToRead(String OK) */ /* Ждёт от модема приглашения прочитать данные, полученные от сервера. */ /* Когда приглашение получено, функция анализирует код ответа сервера (следует в той же строке после ","). */ /* Если код ответа 200 - данные успешно получены. responce_status = "GOOD RESPONCE" */ /* Если код ответа отличен от 200 - сервер ответил ошибкой. responce_status = "BAD RESPONCE" */ /* Входы: Принимает строку-приглашение от модема. */ /* Выходы: Возвращает true если ответ получен, false - ответ от модема еще ожидается */ /*-------------------------------------------------------------------------------------------------------------------*/ boolean WaitReadyToRead(String OK) { responce_status = "!"; //Инициализируем заведомо ложным значением if(Serial1.available()) { Startup_time_s = (millis()/1000); //Время с момента включения в секундах. while(Serial1.available()) //Пока не прочитаем то, что уже пришло { SIM_Data = Serial1.readStringUntil(char(13)); // читаем ответ до символа перевода на след. строку '\r' PrintlnToSerial(SIM_Data); // Посылаем в отладочный порт полученные данные if (OK.equals(SIM_Data.substring(1,OK.length()+1))){ //Если строка-приглашение получена, смотрим что идёт дальше // - это код ошибки. if (SIM_Data.substring(OK.length()+1,OK.length()+4) == "200"){ //Если код ошибки 200 - обмен прошёл успешно responce_status = "GOOD RESPONCE"; Serial1.flush(); //Ждём пока данные перестанут лететь и освобождаем буфер return true; } else{ //Если код ошибки не 200 - сервер ответил ошибкой responce_status = "BAD RESPONCE"; Serial1.flush(); //Ждём пока данные перестанут лететь и освобождаем буфер return true; } } //Если каким-то немыслимым образом тут зависли (данные из порта продолжают приходить), //выходом из цикла while будет подпрограмма защиты от зависания if(!SIM900_answ_test()) return false; } } else return false; } /*-------------------------------------------------------------------------------------------------------------------*/ /* Описание: Функция ReadServerResponce() */ /* Читает данные полученные от сервера. */ /* Признаком конца сообщение служит строка "ОК" */ /* Входы: */ /* Выходы: Возвращает true если ответ получен, false - ещё читаем */ /*-------------------------------------------------------------------------------------------------------------------*/ boolean ReadServerResponce(){ responce_status = "!"; //Инициализируем заведомо ложным значением if(Serial1.available()) { Startup_time_s = (millis()/1000); //Время с момента включения в секундах. while(Serial1.available()){ Responce=Serial1.readString(); if(Responce.substring(Responce.length()-4,Responce.length()-2) == "OK"){ // Ждём "ОК" в конце сообщения responce_status = "OK"; return true; } if(!SIM900_answ_test()) return false; //Если каким-то непостижимым образом тут повисли } } return false; } /*-------------------------------------------------------------------------------------------------------------------*/ /* Описание: Функция SendGETRequest() */ /* Посылает GET-запрос на сервер. */ /* Устанавливает responce_status = "ОК", при успешной передаче команды модему. */ /* Устанавливает responce_status = "ERROR", если модем в процессе обмена ответил ошибкой. */ /* Входы: */ /* Выходы: Возвращает 1 если запрос передан, -1 - если в процессе передачи запроса модем ответил ошибкой, 0 - если */ /* процесс передачи запроса на сервер ещё продолжается. */ /*-------------------------------------------------------------------------------------------------------------------*/ int SendGETRequest() { responce_status = "!"; //Инициализируем заведомо ложным значением switch(GET_step) { case 1: //Передаём модему новый запрос для сервера Serial1.println("AT+HTTPPARA=\"URL\",\""+Request+"\""); // GET_step++; break; case 2: //Читаем ответ модема на предыдущую команду if(ShowSerialData("OK","ERROR")) { if(responce_status == "OK") GET_step++; else if(responce_status == "ERROR") {GET_step=1; return -1;} } break; case 3: //Командуем модему передать запрос на сервер Serial1.println("AT+HTTPACTION=0"); GET_step++; break; case 4: //Читаем ответ модема на предыдущую команду if(ShowSerialData("OK","ERROR")) { if(responce_status == "OK"){GET_step=3; return 1;} else if(responce_status == "ERROR") {GET_step=1; return -1;} } } return 0; } /*-------------------------------------------------------------------------------------------------------------------*/ /* Описание: Функция AnalizeResponce() */ /* Вычленяет из ответа сервера команду для выходного реле. */ /* Команда следует в ответе за кодовым словом. */ /* Входы: Принимает кодовое слово */ /* Выходы: Возвращает строку, содержащую команду для выходного реле */ /*-------------------------------------------------------------------------------------------------------------------*/ String AnalizeResponce(String Code_Str) { String OutStr; for(int i=Responce.length()-1; i > 0; i--) { if(Responce[i] == Code_Str[0]) //Ищем в полученном от сервера ответе кодовое слово COMMAND начиная с конца. { //Если нашли первую букву кодового слова - проверяем дальше, //действительно ли это кодовое слово for(int j = i+1, k=1; k < Code_Str.length(); j++, k++) { if(Responce[j] != Code_Str[k]) //Если следующий символ не совпал { k = Code_Str.length(); // выходим из перебора - это не то слово } else { //Все символы совпали if(k == Code_Str.length()-1) //значит это действительно кодовое слово - дальше идут полезнае данные { for(int f=j+2; f<Responce.length() && Responce[f]!=(char)32; f++) //копируем строку с полезными данными { OutStr += (char)Responce[f]; } Last_succsess_time = (millis()/1000); //Время с момента последнего успешного обмена с сервером //Удаляем из запроса все передаваемые параметры CSt_send_success=true; BT_send_success=true; return OutStr; } } } } } return "NOT_STR"; } /*-------------------------------------------------------------------------------------------------------------------*/ /* Описание: Функция WaitForResponce() */ /* Управляет процессом получения ответа от сервера. */ /* Входы: */ /* Выходы: Возвращает 1 - если получен успешный ответ, -1 - сервер ответил ошибкой, 0 - ответ еще не получен. */ /*-------------------------------------------------------------------------------------------------------------------*/ int WaitForResponce() { responce_status = "!"; //Инициализируем заведомо ложным значением switch(SRead_step){ case 1: if(WaitReadyToRead("+HTTPACTION:0,")){ //Ждём приглашения от SIM900 вида +HTTPACTION:0,<...>, //Приглашение означает, что сервер ответил //После приглашения <...> - идет код ответа (200 - успешный ответ) if(responce_status == "GOOD RESPONCE"){ SRead_step++; //Если получен "хороший" ответ - двигаемся на шаг чтения данных } else if(responce_status == "BAD RESPONCE"){ SRead_step = 1; return -1; //Если получен "плохой" ответ - выходим из функции } } break; case 2: Serial1.println("AT+HTTPREAD"); //Команда модему SIM900 на выдачу ответа, полученного от сервера SRead_step++; break; case 3: if(ReadServerResponce()){ //Читаем ответ сервера SRead_step = 1; return 1; } } return 0; } /*-------------------------------------------------------------------------------------------------------------------*/ /* Описание: PerformCommands(String S) */ /* Меняет состояние выходного реле в соответствии с командой, полученной от сервера. */ /* Входы: Принимает строку, содержащую команду для выходного реле. */ /* Выходы: */ /*-------------------------------------------------------------------------------------------------------------------*/ void PerformCommands(String S) { Command = S.toInt(); if(Command == 1){ digitalWrite(DO,HIGH); } else{ digitalWrite(DO,LOW); } } /*-------------------------------------------------------------------------------------------------------------------*/ /* Описание: AnalizeSystem() */ /* Анализирует текущее состояние системы(температура, сотояние реле) и формирует новый запрос на сервер. */ /* Входы: */ /* Выходы: */ /*-------------------------------------------------------------------------------------------------------------------*/ void AnalizeSystem(){ BoardTermRead(); //Получаем от датчика текущую температуру int delta = term - term_o; //Вычисляем разницу между текущим и предыдущим значением температуры //Формируем очередной запрос //Удаляем все предыдущие передаваемые параметры из запроса Request = "http://t.lazysmart.ru/device_status.php?LOG="; Request+=String(LOG); Request+="&PAS="; Request+=String(PAS); change_request = false; //Добавляем к запросу параметры, которые поменялись или не были успешно переданы //Если состояние выходного реле изменилось, добавляем этот параметр в запрос - даст серверу понять, //что устройство приняло и выполнило команду if(Command != Command_o || !CSt_send_success){ Request+="&CSt="+String(Command); CSt_send_success = false; //сбрасываем флаг успешной передачи параметра change_request=true; //устанавливаем флаг "Запрос на сервер изменён" } //Если температура изменилась больше чем на 0.5 градуса, добавляем этот параметр в запрос if(abs(delta) > 5 || !BT_send_success){ Request+="&BT="+String(term); term_o = term; //приравниваем предыдущую температуру текущей BT_send_success = false; //сбрасываем флаг успешной передачи параметра change_request=true; //устанавливаем флаг "Запрос на сервер изменён" } if(change_request){ GET_step=1; //Если запрос поменялся } Command_o = Command; //Приравниваем предыдущую команду текущей } /*-------------------------------------------------------------------------------------------------------------------*/ /* Описание: BoardTermRead() */ /* Реализует обмен с датчиком температуры. */ /* Входы: */ /* Выходы: */ /*-------------------------------------------------------------------------------------------------------------------*/ void BoardTermRead(){ ds.reset(); //сбрасываем линию ds.skip(); //команда SKIP_ROM, т.к. на линии только один датчик ds.write(0x44,1); // запускаем конвертацию delay(1000); ds.reset(); //сбрасываем линию ds.skip(); //команда SKIP_ROM, т.к. на линии только один датчик ds.write(0xBE); // считываем ОЗУ датчика for (int i = 0; i < 2; i++) { // читаем переданные датчиком 2 первых байта, содержащих информацию о температуре data[i] = ds.read(); } unsigned char znak = (data[1]&0xF8); //раскодируем знак температуры if(znak == 0xF8) { data[0] = ~data[0]; //побитово инвертируем полезные байты, если занк отрицательный data[1] = ~data[1]; } unsigned char digit=data[0]>>4; //вычисляем целую часть digit|=(data[1]&0x7)<<4; unsigned char decimal=(data[0]&0xf)>>2; //вычисляем дробную часть if(decimal==0x00) term = 0; if(decimal==0x01) term =3; if(decimal==0x02) term =5; if(decimal==0x03) term =8; //Сохраняем температуру в глобальную переменную term = 10*digit+term; //объединяем целую и дробную части - получаем текущую температуру if(znak == 0xF8) term = -term; //Добавляем знак "-", если нужно Serial.print("Temperature="); //Выводим в отладочный порт значение температуры Serial.println(term); } /*-------------------------------------------------------------------------------------------------------------------*/ /* Описание: PrintlnToSerial(String S) */ /* Выводит строку в отладочный порт. */ /* Входы: Принимает строку для вывода. */ /* Выходы: */ /*-------------------------------------------------------------------------------------------------------------------*/ void PrintlnToSerial(String S) { Serial.println(S); } /*-------------------------------------------------------------------------------------------------------------------*/ /* Описание: PrintlnToSerial(String S) */ /* Перезагружает модем SIM900. */ /* Входы: */ /* Выходы: */ /*-------------------------------------------------------------------------------------------------------------------*/ void SIM900_Reload() { CSt_send_success=true; //Сбрасываем флаги успешной передачи параметров BT_send_success=true; digitalWrite(50,LOW); //Выключаем светодиод индикации запросов PrintlnToSerial("RELOAD..."); //Передаём сообщение о перезагрузке модема на отладочный порт digitalWrite(48,LOW); //Снимаем питание с модема delay(1000); //Выдерживаем паузу 1 с. digitalWrite(48,HIGH); //Подаём питание на модем wdt_reset(); //Сбрасываем сторожевой таймер powerUp(); //Подаём команду на включение модема GPRS_Init(); //Инициализируем GPRS модема } /*-------------------------------------------------------------------------------------------------------------------*/ /* Описание: GPRS_Init() */ /* Ожидает готовности модема к работе. Управляет подключением модема к GPRS. */ /* Входы: */ /* Выходы: */ /*-------------------------------------------------------------------------------------------------------------------*/ void GPRS_Init() { Startup_time_s = (millis()/1000); //Инициализируем время с момента включения в секундах. Last_blink_time = (millis()/1000); //Инициализируем время крайнего моргания лампочки "Я жив" GPRS_connect=false; //Сбрасываем флаг "Есть подключение к GPRS" digitalWrite(52,LOW); //GPRS не подключен - светодиод не горит while(!ShowSerialData("Call Ready","ERROR")) //ждём пока модем ответит, что готов принимать АТ-команды { if(!SIM900_answ_test()) SIM900_Reload(); //Если не отвечает - перезагружаем } delay(3000); //Если ответил, что готов - делаем задержку на всякий пожарный while(!GPRS_connect) { GPRS_connect = ConnectToGPRS(); //Состояние флага "Есть подключение к GPRS" соответствует статусу подключения if(GPRS_connect==true) { digitalWrite(52,HIGH); //GPRS подключен - зажигаем светодиод GET_step=1, GET_step_o=1, SRead_step=1, SRead_step_o=1; //Начинаем сначала все этапы обмена PrintlnToSerial("Connected to GPRS"); //Сообщение в отладочный порт Step='1'; //Начинаем основной цикл сначала Last_succsess_time = (millis()/1000); //Инициализируем время последнего успешного обмена с сервером } else { //Не смог подключиться к GPRS PrintlnToSerial("Cannot connect to GPRS. Reload modem..."); //Сообщение в отладочный порт SIM900_Reload(); //Перезагружаем модем } } } /*-------------------------------------------------------------------------------------------------------------------*/ /* Описание: SIM900_answ_test() */ /* Функция используется в локальных циклах при обмене с модемом, когда время прохождения основного */ /* цикла увеличивается. */ /* В таких случаях сторожевой таймер может быть не сброшен программно за необходимое время и контроллер */ /* перезагрузится аппаратно. */ /* Функция вместо глобального цикла продолжает моргать светодиодом "В работе" и сбрасывать */ /* сторожевой таймер. */ /* Если функция вызывается дольше 25 секунд - считаем что время обмена с модемом превышено, он */ /* завис и не отвечает (необходима перезагрузка). */ /* Входы: */ /* Выходы: Возвращает false, если время ожидания превышено и true - в противном случае. */ /*-------------------------------------------------------------------------------------------------------------------*/ boolean SIM900_answ_test(){ //Моргаем сетодиодом "В работе" не чаще раза в секунду if(blink_led && Last_blink_time - (millis()/1000) > 1){ Last_blink_time = (millis()/1000); //Время с момента последнего моргания digitalWrite(49,LOW); //Переключаем светодиод "В работе" blink_led = false; } else if(Last_blink_time - (millis()/1000) > 1){ Last_blink_time = (millis()/1000); //Время с момента последнего моргания digitalWrite(49,HIGH); //Переключаем светодиод "В работе" blink_led = true; } //Сбрасываем сторожевой таймер wdt_reset(); if((millis()/1000 - Startup_time_s)>25){ //Если функция вызывается дольше 25 секунд - считаем что время //обмена с модемом превышено, он завис и не отвечает. PrintlnToSerial("Sim900 not answer. Reload modem..."); //Сообщение в отладочный порт return false; } return true; } /*-------------------------------------------------------------------------------------------------------------------*/ /* Описание: powerUp() */ /* Подаёт последовательность импульсов на вход PWRKEY модема для его включения. */ /* Входы: */ /* Выходы: */ /*-------------------------------------------------------------------------------------------------------------------*/ void powerUp() { PrintlnToSerial("Turn modem on"); //Сообщение в отладочный порт //Последовательность импульсов на вход PWRKEY модема SIM900 pinMode(9, OUTPUT); digitalWrite(9,LOW); delay(1000); digitalWrite(9,HIGH); delay(2000); digitalWrite(9,LOW); delay(3000); PrintlnToSerial("Modem power on"); //Сообщение в отладочный порт }
Short Circuit, а при чем тут раздел "Проекты"?
это готовый проект. можете по ссылсе сходить и посмотреть.
мне интересна модификация, и кто пользовался тем сервером.
http://lazysmart.ru/nabor-konstruktor-dlya-interneta-veshhej-iot-ls-moni... - могу выложить переделаный скетч под уно.
IoT со String? Really?
это готовый проект. можете по ссылсе сходить и посмотреть.
мне интересна модификация, и кто пользовался тем сервером.
http://lazysmart.ru/nabor-konstruktor-dlya-interneta-veshhej-iot-ls-moni... - могу выложить переделаный скетч под уно.
Чтоб вы поняли масштаб кривизны кода, приведу пример: вот уже недели три занимаемся отладкой кода и железки с заказчиком, добиваемся почти абсолютной надёжности и круглосуточной работы, в связи с кучей хотелок заказчика уменьшил код с 70 % до 40, иначе ничего не влезет....я к тому что если вы думаете что данный код со String будет долго и хорошо работать то вы сильно ошибаетесь, мало строк инициализации, в случае оперативной замены работать не будет, никаких delay в принципе не должно быть иначе никуда уже саму логику программы не впихнете.
код выше - для меги.
Есть примеры скетчей "правильного" кода без String?
любопытно посмотреть.
код выше - для меги.
Есть примеры скетчей "правильного" кода без String?
любопытно посмотреть.
Да пожалуйста, не жалко, не претендую на совсем правильность, но работает, ещё добавил работу с gprs и dtmf, засунул все строки в progmem и ещё кучу улучшений, но извините это код заказчика и он за него заплатил, выложить окончательный вариант не могу
http://arduino.ru/forum/proekty/ocherednaya-temperaturnaya-signalizatsiy...
Short Circuit, код полное Г. и вряд ли стоит "пробовать" этот проект. В коде, кроме String - невероятное количество делеев, так что при попытке подгрузить эти процедуры в собственный проект вы огребете кучу проблем. Процедура измерения температуры со "знаменитой" задержкой в секунду - так писать просто стыдно.
Ребята, судя по всему, просто набрали куски кода в инете, не особо разбираясь, как они работают.
Есть примеры скетчей "правильного" кода без String?
вы сомневаетесь, что это можно было написать на char array ? - зря.
Код будет точно меньше и несравненно эффективнее.
я не сомневаюсь, я точно знаю, что еще мало знаю..
Поэтому спросил - покажите реальные примеры кода. Я войду в курс дела, изучу, сделаю как мне нужно и буду использовать.
ЗЫ: String я успешно использую, ничего не зависает(оптимизировал как умел)
в итоге скетчи под 1000 строк занимает к примеру до 31кб флеш, и до 35-40% ! памяти.
Там не все идеально конечно, но хотелось бы научится всячески парсить уже принятые char строки - не используя String, буду признателен за такие примеры.
Э....берете пример выше, там тупо процедура поиска постройки и парсите на здоровье
ааа... понял куда смотреть.. спасибо.