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, буду признателен за такие примеры.
Э....берете пример выше, там тупо процедура поиска постройки и парсите на здоровье
ааа... понял куда смотреть.. спасибо.