• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Запрос примеров для Sming

JustACat

Moderator
Команда форума
чтобы таймером самому себе не наступать на пятки
Можно еще запускать таймер разово, то есть вызывать:
[inline]procTimer.initializeMs(100, process).startOnce();[/inline]
Каждый раз в конце самой этой вашей процедуры void process() после всех обработок. Тогда таймер вторично не вызовется точно.
Правда это не избавит вас от вызова других прерываний (если они есть - тут уже к @anakod'у) во время выполнения вашего кода. Тогда, если критично, то да, надо как-то запрещать прерывания на время выполнения критичного кода.
 

Okadzaki

New member
Прошу добавить, или указать на существующий пример планировщика. Например на веб-странице указать время, оно запишется в файл, и по достижению этого время, будет выдана 1 или 0 на соответствующей ноге. Время берётся по NTP.
В итоге, чтобы при выключении питания, программа опять открывала файл, брало ближайшее событие (время), и по его достижению - меняло состояние на ноге.
Предпологаю, что числа нужно хранить в файле как массив JSON в формате time_t (UnixTime), но как-то реализовать не получилось.
 

anakod

Moderator
Команда форума
Okadzaki, приведите код, подскажем. А вообще хороший пример чтения\записи данных в файл есть в примере HttpServer_ConfigNetwork. Для работы с массивами: json.createNestedArray("...")
 

Okadzaki

New member
Okadzaki, приведите код, подскажем. А вообще хороший пример чтения\записи данных в файл есть в примере HttpServer_ConfigNetwork. Для работы с массивами: json.createNestedArray("...")
Есть например следующий обработчик страницы:
Код:
void onSchedule(HttpRequest &request, HttpResponse &response)
{
    if (request.getRequestMethod() == RequestMethod::POST){
        uint8_t min = request.getPostParameter("minutes").toInt();
        uint8_t hour = request.getPostParameter("hour").toInt();
        uint8_t sec = request.getPostParameter("Seconds").toInt();

        uint16_t year = request.getPostParameter("year").toInt();
        uint8_t month = request.getPostParameter("month").toInt();
        uint8_t day = request.getPostParameter("day").toInt();
         
    bool state = request.getPostParameter("state").toInt();
     time_t time = convertToUnixTime(sec,min,hour,day,month,year);
     scheduleFile.save(time,state);
    }
    TemplateFileStream *tmpl = new TemplateFileStream("schedule.html");
    auto &vars = tmpl->variables();
    response.sendTemplate(tmpl);
}
Структура JSON, что будет хранится в файле - ориентировачно такая:
JavaScript:
{
  "times":[
  {
  "time": 111111111,
  "state": true
  },
  {
  "time": 111111111,
  "state": true
  }
  ]
}
А вот как сделать так, чтобы при записи в файл, оно дополняло массив ( а если файл с конфигурацией вообще пуст - создать массив, добавить в него первый объект) - не знаю.

Плюс, при старте модуля, считать из файла ближайшее события и состояние которое нужно выставить на ноге релюхи, например.

А раз в секунду, проверять, совпадает ли текущее время с тем ближайшем событием из файла. Как-то так:
Код:
void checkEvent(){
time_t now = SystemClock.now(true);
if (now == eventTime){
    digitalWrite(RELAY_PIN,event_state);
    scheduleFile.deleteEvent();
}
}

void connectOK(){
    Serial.print("OK");
    WifiAccessPoint.enable(false);
    ntp.setAutoQueryInterval(30);
    ntp.setAutoQuery(true);
    /*if (!AppSettings.rtc_sync){
        ntp.requestTime();
    }*/
    schedulePlan.initializeMs(1000,checkEvent);

}

Сама же структура scheduleFile включает в себя функции по записи в файл, чтения ближайшего события, и удаление последнего события.
 

alexhi

Member
Подскажите как в SMING настроить ногу RXD как цифровой вход , пробывал так pinMode(3,INPUT); не получается.
 

JustACat

Moderator
Команда форума
alexhi, а вывод дебага отключали?
[inline]Serial.systemDebugOutput(false);[/inline]
Хотя это же на TXD должно влиять, ну может еще что-то нужно...
Если только может еще не делать в начале:
[inline]Serial.begin();[/inline]
Т.к. в нем же как раз происходит настройка UART и запуск его прерываний.
 

alexhi

Member
JustCat,спасибо. Так работает:

Serial.systemDebugOutput(false);
[HASHTAG]#define[/HASHTAG] PIN_RXD 3
pinMode(PIN_RXD,INPUT);
while (1)
{
WDT.alive();
delay(1000);
Serial.println(digitalRead(PIN_RXD));
}
 

anakod

Moderator
Команда форума
Okadzaki, в целом все правильно. Хороший пример открытия и загрузки файла:
https://github.com/anakod/Sming/blob/master/HttpServer_ConfigNetwork/include/AppSettings.h

Если файла нет - инициализируете структуру, добавляете пустой массив (как создаются объекты в методе save). Далее по необходимости добавляете и удаляете узлы.
Посмотрите документацию на исходную библиотеку: https://github.com/bblanchon/ArduinoJson там есть примеры и информация по методам.

А вот пример создания массива и добавления элементов:
https://github.com/anakod/Sming/blob/master/HttpServer_ConfigNetwork/app/application.cpp#L84
 

Okadzaki

New member
А каким образом я смогу тогда просто дописать в файл элемент массива?
 
Последнее редактирование модератором:

anakod

Moderator
Команда форума
Загружаете текущее состояние из файла, получаете нужный узел по имени (собственно Ваш массив), а затем так же добавляете в него новый элемент.
 

anakod

Moderator
Команда форума
Okadzaki, если приложите полный код (архивом), то возможно что-нибудь еще смогу подсказать.
Обратное тоже верно: когда доделаете, буду очень рад принять pull-request в основной репозиторий, мне кажется пример планирования задач по времени - действительно интересная вещь для пользователей.
 

Okadzaki

New member
Возникла проблема с сохранением в файл JSON.
Есть следующая структура, в которой хранятся данные об файле с расписанием.
Код:
#define TIMERS_FILE ".timers.conf"
struct ScheduleFile{

   void save(time_t time, bool state){
     DynamicJsonBuffer jsonBuffer;
     if (!exist()){
       JsonObject& root = jsonBuffer.createObject();
       root["count"] = 1;
       JsonArray& timesArray = root.createNestedArray("times");
       JsonObject &item = timesArray.createNestedObject();
       item.add("time",time);
       item.add("state",state);
       fileSetContent(TIMERS_FILE,root.toJsonString());
     }else{
       int size = fileGetSize(TIMERS_FILE);
       char* jsonString = new char[size + 1];
       fileGetContent(TIMERS_FILE, jsonString, size + 1);
       JsonObject& root = jsonBuffer.parseObject(jsonString);
       uint8 count = root["count"];
       root["count"] = count + 1;
       JsonArray& timesArray = root["times"];
       JsonObject &item = timesArray.createNestedObject();
       item.add("time",time);
       item.add("state",state);
       delete[] jsonString;
       fileSetContent(TIMERS_FILE,root.toJsonString());
     }
   }



   bool exist() { return fileExist(TIMERS_FILE); }

};
На вход поступает bool и time_t (UNIX time число).
Проблема заключается именно при записи в файл, если он уже существует. Вариации файла .timers.conf представлены ниже:
Произошла первая запись в файл(файл до этого момента не существовал):
JavaScript:
{
  "count": 1,
  "times": [
  {
  "time": 1449832271,
  "state": true
  }
  ]
}
Вторая:
JavaScript:
{
  "count": 2,
  "times": [
    {
      "time": 1449832271,
      "state": true
    },
    {
      "time": 1452600732,
      "state": true
    }
  ]
}
Третья:
JavaScript:
{
  "s.conf": 3,
  "": [
    {
      " 3,\r\n  \"\": [\r\n    {\r\n      \" 3,\\r\\n  \\\"\\\": [\\r\\n    {\\r\\n      \\\" 3,\\\\r\\\\n  \\\\\\\"\\\\\\\": [\\\\r\\\\n    {\\\\r\\\\n      \\\\\\\" 3": 1449832271,
      "\" 3,\\r\\n  \\\"\\\": [\\r\\n    {\\r\\n      \\\" 3,\\\\r\\\\n  \\\\\\\"\\\\\\\": [\\\\r\\\\n    {\\\\r\\\\n      \\\\\\\" 3": true
    },
    {
      "\\\" 3,\\\\r\\\\n  \\\\\\\"\\\\\\\": [\\\\r\\\\n    {\\\\r\\\\n      \\\\\\\" 3": 1452600732,
      "\\\\n    {\\\\r\\\\n      \\\\\\\" 3": true
    },
    {
      "time": 1454288461,
      "state": false
    }
  ]
}
Четвертая:
JavaScript:
{
  "": 3,
  "": [
    {
      "я?h": 1449832271,
      "\" 3,\\r\\n  \\\"\\\": [\\r\\n    {\\r\\n      \\\" 3,\\\\r\\\\n  \\\\n  \\\\\\\\n  \\\\\\\\\\\\\\\\n  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\set-3\">\n \\\\Ђlя?Ш": true
    },
    {
      "t-3\">\n \\\\Ђnя?Ш": 1452600732,
      "\\\\n    {\\\\r\\\\n      \\\\\\\" 3": true
    },
    {
      "time": 1454288461,
      "state": false
    }
  ],
  "count": 1,
  "times":
}

После пятой записи, файл тупо становится размером в 2 байта, и ничего в себе не хранит.7
Подскажите, в чем ошибка?
 

anakod

Moderator
Команда форума
Ошибка из-за того что delete[] jsonString; делается до того как файл записан. Соответственно данные могут быть потеряны (т.к. ArduinoJson не копирует память а использует исходную).
 

Okadzaki

New member
Ошибка из-за того что delete[] jsonString; делается до того как файл записан. Соответственно данные могут быть потеряны (т.к. ArduinoJson не копирует память а использует исходную).
Да, действительно проблема была в этом. Спасибо
 

Данило

New member
Здравствуйте.
Не подбросите пример для Mqtt. Почему то не публикует сообщение без таймера, если просто вызвать метод.
 

anakod

Moderator
Команда форума
Пример есть в стандартных.
Возможно проблема в том что Вы пробуете опубликовать сообщение до того как соединение с сервером установлено?
 

VelAndr

New member
Здравствуйте!
Начинаю изучать Ваш sming - все очень красиво выглядит. В процессе написания первой тестовой прошивки (на основе примера ConfigNetwork) у меня не получилось сформировать файл с файловой системой spiffs с веб-контентом (чтобы не загружать страницы по FTP). Я пробовал использовать find | mkespfsimage > spiff_rom.bin , но ничего не получилось - в файловой системе остался все тот же index.html.
Как правильно это делать, и можно ли вообще это сделать?
Спасибо!
 
Сверху Снизу