2560 зависает с LoRa

b707
Offline
Зарегистрирован: 26.05.2017

sadman41 пишет:
Вот если честно - Вы ожидаете, что кто-то будет эти сотни строк у себя в голове прокручивать, чтобы понять, где стек пропарывает кучу?

я подозреваю, что когда String инициируется строкой с нечетным числом кавычек, в памяти начинается бардак. а твое мнение?

alexbel620017
Offline
Зарегистрирован: 26.03.2017

b707 пишет:

alexbel620017 пишет:

Вот так на самом деле стоит (часть строк скопировал)

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

client.println(F("<body background=<a href="https://wmpics.pics/di-TW62.jpg" rel="nofollow">https://wmpics.pics/di-TW62.jpg</a>><font color=\"WHITE\">")); // из мурманска в Питер

и тут просто дофига не прикрытых кавычек.

Нужно абсолютно все кавычки внутри строки оформить так, как записано "WHITE":

client.println(F("<font color=\"WHITE\">")); // из мурманска в Питер

 

Именно так и сделано. Я не знаю почему при переносе кода на форум эти кавычки "портятся".

С не прикрытыми кавычками компилятор ошибки выдаёт.

sadman41
Offline
Зарегистрирован: 19.10.2016

b707 пишет:

sadman41 пишет:
Вот если честно - Вы ожидаете, что кто-то будет эти сотни строк у себя в голове прокручивать, чтобы понять, где стек пропарывает кучу?

я подозреваю, что когда String инициируется строкой с нечетным числом кавычек, в памяти начинается бардак. а твое мнение?


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

И при нечетном числе кавычек, равно как и скобок, компилятор вывалится в ошибку.

b707
Offline
Зарегистрирован: 26.05.2017

alexbel620017 пишет:

Именно так и сделано. Я не знаю почему при переносе кода на форум эти кавычки "портятся".

С не прикрытыми кавычками компилятор ошибки выдаёт.

ОК, тогда начните с того, что добавьте макррос F() во все строчки длиной более 5-7 символов и посмотрите,насколько станет больше свободной памяти.

В остальном я согласен с Садман41 - к сожалению, вы себя так зарекомендовали, что я категорически не доверяю вашим спсобностям программировать, поэтому ошибка (и далеко не одна) может быть где угодно, вообще на ровном месте

alexbel620017
Offline
Зарегистрирован: 26.03.2017

sadman41 пишет:
b707 пишет:

sadman41 пишет:
Вот если честно - Вы ожидаете, что кто-то будет эти сотни строк у себя в голове прокручивать, чтобы понять, где стек пропарывает кучу?

я подозреваю, что когда String инициируется строкой с нечетным числом кавычек, в памяти начинается бардак. а твое мнение?

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

Все (!) соединения на пайке, каждый модуль шунтирован электролитом и керамикой, БП трансформаторный с линейным стабилизатором (не импульсный преобразователь). Осциллограф показывает идеальную форму питания, равно как и форму импульсов на SPI. Уровни импульсов тоже 5 и 3,2 вольта.

alexbel620017
Offline
Зарегистрирован: 26.03.2017

b707 пишет:

alexbel620017 пишет:

Именно так и сделано. Я не знаю почему при переносе кода на форум эти кавычки "портятся".

С не прикрытыми кавычками компилятор ошибки выдаёт.

ОК, тогда начните с того, что добавьте макррос F() во все строчки длиной более 5-7 символов и посмотрите,насколько станет больше свободной памяти.

В остальном я согласен с Садман41 - к сожалению, вы себя так зарекомендовали, что я категорически не доверяю вашим спсобностям программировать, поэтому ошибка (и далеко не одна) может быть где угодно, вообще на ровном месте

Я код и так сократил - повырезал всё не участвующее. Остались только части связанные с этими тремя модулями.

С макросами так и сделал уже.

b707
Offline
Зарегистрирован: 26.05.2017

alexbel620017 пишет:

С макросами так и сделал уже.

насколько прибавилось памяти?

alexbel620017
Offline
Зарегистрирован: 26.03.2017

Прибавилось прилично - было свободно 1607 байт, сейчас 3287

Добил остальные принты - свободно стало 4174

sadman41
Offline
Зарегистрирован: 19.10.2016

Лично я бы в такой ситуации, при наличии подозрений на железо, сделал бы скетч, в котором работа со всей периферией была активной, но простой - типа постоянного чтения\установки статусов. Если проблема действительно в сочетании комплектующих - новый скетч повиснет так же быстро.

b707
Offline
Зарегистрирован: 26.05.2017

 точно огромный HTML с картинками надо бы выкинуть.

alexbel620017
Offline
Зарегистрирован: 26.03.2017

Да, так и сделаю, но это уже завтра, спасибо.

alexbel620017
Offline
Зарегистрирован: 26.03.2017

b707 пишет:

 точно огромный HTML с картинками надо бы выкинуть.

Выкидывал! - та же хрень...

alexbel620017
Offline
Зарегистрирован: 26.03.2017

Сейчас с освободившимся ОЗУ ещё раз убрал HTML (печатает одну надпись на странице без картинок) - посмотрю как будет

 

Нет, виснет. Заметил - если в скетче есть Serial.print то работает дольше, если скетч маслает без задержек, то "конец" наступает гораздо быстрее......

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

alexbel620017 пишет:

Я код и так сократил - повырезал всё не участвующее. Остались только части связанные с этими тремя модулями.

С макросами так и сделал уже.

И где он? Новый код?

alexbel620017
Offline
Зарегистрирован: 26.03.2017

#include <SD.h>

// при окончательной установке убрать коммент. "аварию отоления"  562 стр.

#include <RH_RF95.h>
#include <Adafruit_SHT31.h>
#include <EEPROM.h>
#include <TinyGPS.h>
#include <Ethernet2.h>
#include <Nextion.h>
#include <OneWire.h>
#include <DS1307RTC.h>
#include <DS3231.h>
#include <Time.h>
#include <SPI.h>
#include <iarduino_Pressure_BMP.h>

// ------------------------- сеть ---------------------------------
byte mac[] = {0x2C, 0xF7, 0xF1, 0x08, 0x00, 0x9A};
IPAddress ip(192, 168, 1, 6);
EthernetServer server(756);

// ------------------------- LoRa ---------------------------------
RH_RF95 rf95(48, 2);                       // (SS, interrupt) внимательно с выводом прерывания на Ардуине!
uint32_t data[5];                                 // Создаём массив для приёма данных - 32 разряда, тк передатчик DUE

// ------------------------- часы ---------------------------------
DS3231 Clock;
TinyGPS gps;

// ------------------------- давление -----------------------------
iarduino_Pressure_BMP sensor;

// ------------------------- влажность ----------------------------
Adafruit_SHT31 sht31 = Adafruit_SHT31();

// ------------------------- температура --------------------------
OneWire sensDs1(7);                        // датчик температуры подключен к выводу 7 дом
byte bufData1[9];                          // буфер данных температуры в доме
byte addr1[8];                             // массив адреса датчика темп. в доме
OneWire sensDs2(6);                        // датчик температуры подключен к выводу 6 вход
byte bufData2[9];                          // буфер данных
byte addr2[8];                             // массив адреса датчика
bool frchtd = false;                       // флаг разрешения чтения с дисплея "сброса"
bool newdata = false;
bool Century = false;
bool h12;
bool PM;
bool td = false;                           // флаг разрешения обработки данных датчика температуры в доме
bool fwdt = true;                          // флаг WDT
bool fsd = true;                           // флаг однократности вывода "данные устарели"
byte m, s, h, d, M;                        // переменные даты и времени
int Y = 2000;
bool fscht;                                // флаг разрешения суммирования при чтении с дисплея
bool BanTM = false;                        // флаг наличия данных из бани
bool Zu = false;                           // флаг печати значка SD-карты на дисплей
bool fp = false;                           // флаг разрешения сброса раз в сутки
bool fa = true;                            // флаг для однократности сработывания аварии
int celsius1, celsius2, celsius3;          // температура в доме
float celsgis = 100;                       // промежуточная темп. для прохождения гистерезиса
int toutside = 0;                          // температура на улице с датчика влажности
int tPred;                                 // переменная для проверки перехода с одного разряда на два и обратно при печати ул. температуры на дисплей
int p;                                     // давление
int hum;                                   // влажность на улице
int ch;                                    // переменная для вычитывания буфера Nextion
int val;                                   // строка из дисплея
int i;
float tuprm;                               // считанное значение уличной температуры
float huprm;                               // считанное значение уличной влажности
float dvl;                                 // считанное значение атм. давления
bool gisalarm;
float toutsidegis = 100;                   // переменная для гистерезиса
unsigned long mln = 300000;                // период синхронизации с GPS (сначала ч/з 5 минут (считывание альманаха при перв вкл, потом раз в 7 сут. (604800000)
unsigned long sinhr;                       // переменная в мсек задающ. период синхронизации
unsigned long za;                          // переменная в мсек задающ. задержку на сработывание аварии (2 мин, искл. ложных срабатываний)
unsigned long zadavar;                     // переменная в мсек задающ. период синхронизации
unsigned long start;                       // переменная в мсек задающ. цикл считывания данных gps
unsigned long registr;                     // переменная в мсек для таймера регистратора
unsigned long dvt = 3000;                  // период измерения давл. вл. и температуры (нач. 5 сек, потом раз в минуту)
unsigned long dvtperiod;                   // переменная в мсек для таймера измерен. давл.вл и у.темп.
unsigned long loraperiod;                  // переменная таймера проверки приёма LoRa
unsigned long swi = millis();              // перенная для смены фона на сайте ТМ данных
unsigned long treg = 290000;               // период записи регистратора 5 мин (переменная на 10 сек меньше - догоняет остаток от деления =0)
unsigned long tperiod;                     // переменная в мсек для таймера обработки измерен. темп. в доме
unsigned long nadisplei;                   // переменная в мсек для таймера вывода на дисплей
unsigned long disp = 50;                   // период таймера вывода на дисплей, нач. 1 сек, потом 10 сек.
unsigned long olddata;                     // переменная
unsigned long pwdt;                        // переменная для WDT
unsigned long time, date;                  // переменные для считыв. даты и времени для вычисления "пустой" даты
float gis = 0.2;                           // гистерезис температуры и влажности
float pgis, hgis;                          // вспомогательная переменная для гистерезиса влажн. и давления
String pch;                                // переменная для вывода на дисплей
String SMSOUT;                             // текстовая переменная "номер для смс"

int db1;                                   // темпеатура парной
int db2;                                   // темпеатура комната бани
int db3;                                   // темпеатура т. пола бани
int db4;                                   // нагрев (0 - нет, 1 - нагрев)
int db5;                                   // CRC с LoRa

int d1;                                    // темпеатура выход котла К-->
int d2;                                    // темпеатура вход котла (обратка) K<--
int d5;                                    // темпеатура выход на ТП
int d6;                                    // темпеатура вход с ТП (обратка)
int d7;                                    // темпеатура бойлера
int d8;                                  // давление системы водоснабжения
int d9;                                  // давление системы отопления
int d81, d82, d91, d92;                    // промеж. параметры для отобр. гидро давления в СМС
int d10;                                   // темпеатура в котельной
int d11;                                   // темпеатура в гараже
int d12;                                   // темпеатура скважины
int d13;                                   // расход фильтра Мех.
int d14;                                   // расход фильтра Ca Mg.
int d15;                                    // расход фильтра Fe.
int d3, d4;                                // резерв
String(s1), (s2), (s3), (s4), (s5), (s6), (s7), (s8), (s9), (s10), (s11), (s12), (s13), (s14), (s15), (s16);
String(s151), (s152), (s161), (s162);
String(ss1), (ss2), (ss3), (ss4), (ss5), (ss6), (ss7);

int ttt;

// ------------------------------------------------------ setup --------------------------------------------------------------

void setup() {

  Serial.begin(9600);
  Serial1.begin(9600);                      // порт GPS
  Serial2.begin(9600);                      // порт Nextion
  Serial3.begin(9600);                      // порт SIM800

  pinMode(48, OUTPUT);                      // CS LoRa
  pinMode(49, OUTPUT);                      // CS W5500
  pinMode(47, OUTPUT);                      // CS SD
  pinMode(53, OUTPUT);                      // штатный CS не используется
  pinMode(33, OUTPUT);                      // выход на WDT
  digitalWrite(47, HIGH);
  digitalWrite(48, HIGH);
  digitalWrite(49, HIGH);
  digitalWrite(53, HIGH);
  digitalWrite(33, LOW);

  setSyncProvider(RTC.get);                 // библиотечная команда извлечения данных из модуля часов

  za = millis();                            // переменная в мсек задающ. задержку на сработывание аварии (2 мин, искл. ложных срабатываний)
  sinhr = millis();                         // переменная в мсек для синхронизации по GPS
  zadavar = millis();                       // переменная задержки сработки АВАРИИ по давлению отопл. или t котла (на минуту после вкл. или сброса аварии)
  registr = millis();                       // переменная в мсек для таймера регистратора
  dvtperiod = millis();
  loraperiod = millis();
  tperiod = millis();                       // переменная в мсек для таймера изм. температуры
  nadisplei = millis();                     // переменная в мсек для таймера вывода на дисплей
  olddata = millis();                       // переменная для проверки новизны данных с котельной
  pwdt = millis();

  SendDataP("q0.picc", 11);                 // очистка уличной температуры
  SendDataP("pio0", 0);                     // выключили сирену в Nextion

  if (EEPROM.read(10) == 1) {
    SendDataP("tm5.en", 1);                 // запустили тревогу на дисплее
    frchtd = true;                          // разрешили чтение с дисплея "сброса"
  }
  else {
    SendDataP("page0.tm5.en", 0);           // остановили таймеры мигания "АВАРИИ" на дисплее
    SendDataP("page0.tm6.en", 0);
    SendDataP("page0.p0.pic", 10);          // опять нарисовали "БАНЬКУ"
    frchtd = false;                         // запретили чтение с дисплея "сброса"
  }

  SPI.begin;
  SPI.setClockDivider(SPI_CLOCK_DIV4);

  Ethernet.begin(mac, ip);
  server.begin();
  sensor.begin();                           // инициализация датчика давления
  sht31.begin(0x44);                        // инициализация датчика влажности
  SD.begin(47);                             // инициализация модуля SD карты
  rf95.init();                              // инициализация SX1278
  //rf95.setTxPower(5, false);                // мощность 5 - 23, максимальная мощность (при 23) 100мВт (шаги с 5 по 23 не подряд! смотреть в библиотеке)
  //void clearRxBuf();

  sensDs1.search(addr1);                    // поиск и запись адреса датчика температуры
  sensDs1.write(0x4E);                      // разрешение записи 3-х байт в DS18B20 (предустановка)
  sensDs1.write(0x7F);                      // TH
  sensDs1.write(0xFF);                      // TL
  sensDs1.write(0x20);                      // регистр конфигурации (разрешение: 0х00-0.5  0х20-0.25   0х40-0.125  0х60-0.0625)

  sensDs2.search(addr2);                    // поиск и запись адреса датчика температуры
  sensDs2.write(0x4E);                      // разрешение записи 3-х байт в DS18B20 (предустановка)
  sensDs2.write(0x7F);                      // TH
  sensDs2.write(0xFF);                      // TL
  sensDs2.write(0x20);                      // регистр конфигурации (разрешение: 0х00-0.5  0х20-0.25   0х40-0.125  0х60-0.0625)

  Serial3.println("AT+IPR=9600");           // скорость модема
  delay(200);
  //Serial3.println("AT+CSQ");              // уровень сигнала                   // ПРИ УРОВНЕ СИГНАЛА
  //delay(500);
  Serial3.println("AT+CLIP=1");             // включить АОН
  delay(200);
  Serial3.println("AT+CMGF=1");             // текстовый формат SMS
  delay(200);
  Serial3.println("AT+CSCS=\"GSM\"");       // кодировка текста - GSM
  delay(200);
  Serial3.println("AT+CMGD=1,4");           // удалить все смс
  delay(200);
  Serial3.println("AT+CNMI=2,2,0,0,0");     // вывод смс в консоль
  delay(200);
  Serial3.println("AT&W");                  // запомнить настройки
  delay(200);

  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

// ==========================================================================================================================
// ============================================================ L O O P =====================================================

void loop() {
  //Serial.println("1");
  //Serial.println(millis());
  ttt++;
  if (ttt == 1000) {
    Serial.println(millis());
    ttt = 0;
  }
/*
  // --------------------------------------- суточный брос ------------------------------------------------------------------

  if (h == 10 && m == 6 && fp == true) {              // RESET в 10 часов 06 минут каждый день
    goto M3;                                          // для сут. сброса нет стробов WDT
  }
  if (m == 8) {
    fp = true;
  }

  // --------------------------------------------------- WDT ----------------------------------------------------------------

  if (millis() - pwdt > 500) {
    if (fwdt) {
      //digitalWrite(33, HIGH);
      fwdt = false;
      pwdt = millis();
    }

    else {
      //digitalWrite(33, LOW);
      fwdt = true;
      pwdt = millis();
    }
  }
M3:
*/
  // -------------------------------------------- LoRa ------------------------------------------------------------

  //Serial.println("1");
  if (rf95.available()) {
    delay(10);
    rf95.recv((uint8_t*)data, sizeof(data));
    if (data[0] + data[1] + data[2] + data[3] == data[4] && data[0] + data[1] + data[2] + data[3] != 0) {       // проверка на отсутствие 0 приёма и на соответствие CRC
      db1 = data[0];
      db2 = data[1];
      db3 = data[2];
      db4 = data[3];
      db5 = data[4];
      olddata = millis();
      fsd = true;
      BanTM = true;                         // есть данные из бани
    }
  }
  if (millis() - olddata > 60000 && fsd == true) {
    BanTM = false;                         // нет данных из бани
    fsd = false;
  }

  // -------------------------------------------------- SD карта ------------------------------------------------------------------------------


  //Serial.println("2");
  SDcard();

  // -------------------------------------------------- Сеть ------------------------------------------------------------------

  //Serial.println("3");
  d9 = 16;                 // для отработки
  d8 = 38;
  html();
  //Serial.println("4");
/*
  // -------------------------------------------------- ОСНОВНОЙ ЦИКЛ ------------------------------------------------
  // --------------------------------------- влажность и температура с датчика влажности -----------------------------
  //Serial.println("5");

  if (millis() - dvtperiod > dvt) {               // таймер для измерения температуры, давл. и влажности, dvt 5c\60c
    tuprm = sht31.readTemperature();              //снятые с датчика значения вл и темп для работы с ними  (float)
    huprm = sht31.readHumidity();

    if ((huprm - hgis > gis) || (hgis - huprm > gis)) {                    // проверка на гистерезис для влажности
      hum = huprm;
      if (huprm - hum >= 0.5) {
        hum = hum + 1;
      }
      hgis = huprm;
    }

    if ((toutsidegis - tuprm > gis) || (tuprm - toutsidegis > gis) || (toutsidegis - tuprm < -gis) || (tuprm - toutsidegis < -gis)) {    // проверка на гистерезис для температуры
      toutside = tuprm;
      if (tuprm - toutside >= 0.5) {
        toutside = toutside + 1;
      }
      if (tuprm - toutside <= -0.5) {
        toutside = toutside - 1;
      }
      toutsidegis = tuprm;
    }

    // --------------------------------------- давление -----------------------------------------------------------
    sensor.read(1);
    dvl = sensor.pressure;
    if ((pgis - dvl > gis) || (dvl - pgis > gis)) {
      p = dvl;
      if (dvl - p >= 0.5) {
        p = p + 1;
      }
      pgis = dvl;
    }
    //Serial.println("6");
    // ------------------------------------- температура DS18B20 (дом) ---------------------------------------------
    sensDs1.reset();
    sensDs1.select(addr1);
    sensDs1.write(0x44, 0);                   // инициализация измерения с первого датчика
    sensDs2.reset();
    sensDs2.select(addr2);
    sensDs2.write(0x44, 0);                   // инициализация измерения с второго датчика
    delay(100);
    sensDs1.reset();
    sensDs1.select(addr1);
    sensDs1.write(0xBE, 0);                                             // команда чтения памяти датчика
    sensDs1.read_bytes(bufData1, 9);                                    // чтение памяти датчика, 9 байтов
    if ( OneWire::crc8(bufData1, 8) == bufData1[8] ) {
      float cels1 = (float)((int)bufData1[0] | (((int)bufData1[1]) << 8)) * 0.0625;
      celsius1 = cels1;                                                 // температура в доме
      if ((cels1 - celsius1) >= 0.5) {
        celsius1 = celsius1 + 1;
      }
    }
    sensDs2.reset();
    sensDs2.select(addr2);
    sensDs2.write(0xBE, 0);                                             // команда чтения памяти датчика
    sensDs2.read_bytes(bufData2, 9);                                    // чтение памяти датчика, 9 байтов
    if ( OneWire::crc8(bufData2, 8) == bufData2[8] ) {
      float cels2 = (float)((int)bufData2[0] | (((int)bufData2[1]) << 8)) * 0.0625;
      celsius2 = cels2;                                                 // температура входа
      if ((cels2 - celsius2) >= 0.5) {
        celsius2 = celsius2 + 1;
      }
    }
    dvtperiod = millis();
    dvt = 5000;                              // установка таймера изм. темп, давления и влажности в 1 мин.

  }// ----------------------------------------- конец ОСНОВНОГО цикла температуры, влажности ---------------------------------------


  // ------------------------------------------------- SIM800 ---------------------------------------------------------------
  //Serial.println("3");
  //Serial3.println("AT+CSQ");                                               // ПРИ УРОВНЕ СИГНАЛА
  if (Serial3.available()) {
    delay(20);
    char ch = ' ';
    String val = "";
    while (Serial3.available())
    {
      ch = Serial3.read();
      val += char(ch);                                                       // собираем принятые символы в строку
      delay(2);
    }
    //Serial.println(val);                                                   // ПРИ УРОВНЕ СИГНАЛА
    if (val.indexOf("RING") > -1) {                                          // если есть входящий вызов
      if (val.indexOf("9122234744") > -1) {
        SMSOUT = "+79122230000";                                             // мой номер
      }
      else {
        if (val.indexOf("79121111111") > -1) {
          SMSOUT = "+79122857000";                                           // другой номер
        }
        else {
          if (val.indexOf("79121111111") > -1) {
            SMSOUT = "+79122459000";                                         // другой номер
          }
          else {
            Serial3.println("ATH");        // разрываем связь в случае "левого" звонка
            goto M1;
          }
        }
      }
      Serial3.println("ATH");              // разрываем связь в случае одного из трёх звонков
      delay(1000);
      balans();                            // запрос баланса
      s1 = String(toutside);               // строковая переменная с уличной температурой
      s2 = String(hum);                    // строковая переменная с уличной влажностью
      s3 = String(p);                      // строковая переменная с давлением
      s4 = String(celsius1);               // строковая переменная с температурой в доме
      s5 = String(d11);                    // строковая переменная с температурой в гараже
      s6 = String(d10);                    // строковая переменная с температурой в котельной
      s7 = String(d12);                    // строковая переменная с температурой скважины
      s8 = String(d1);                     // строковая переменная с температурой выхода из котла
      s9 = String(d2);                     // строковая переменная с температурой входа в котёл (обратка)
      s10 = String(d5);                    // строковая переменная с температурой выход на ТП
      s11 = String(d6);                    // строковая переменная с температурой ТП обратка
      s14 = String(d7);                    // строковая переменная с температурой бойлера
      d81 = (d8 / 10);                     // формирование дробных переменных для давл. в.с.
      d82 = (d8 - (d8 / 10) * 10);         // формирование дробных переменных для давл. в.с.
      d91 = (d9 / 10);                     // формирование дробных переменных для давл. отопл.
      d92 = (d9 - (d9 / 10) * 10);         // формирование дробных переменных для давл. отопл.
      s151 = String(d81);                  // строковая переменная с давлением водоснабжения
      s152 = String(d82);                  // строковая переменная с давлением водоснабжения
      s161 = String(d91);                  // строковая переменная с давлением отопления
      s162 = String(d92);                  // строковая переменная с давлением отопления

      sms(String("Balans sim: " + ss1 + ss2 + ss3 + ss4 + ss5 + ss6 + ss7 + '\n' + '\n'
                 + "Temp. ulica: " + s1 + '\n'
                 + "Vlagnost ulica: " + s2 + "%" + '\n'
                 + "Davlenie atm: " + s3 + "mm" + '\n' + '\n'
                 + "Temp. dom: " + s4 + '\n'
                 + "Temp. garag: " + s5 + '\n'
                 + "Temp. kotelnay: " + s6 + '\n'
                 + "Temp. skvagina: " + s7 + '\n' + '\n'
                 + "Temp. kotel podacha: " + s8 + '\n'
                 + "Temp. kotel vozvrat: " + s9 + '\n'
                 + "Temp. TP podacha: " + s10 + '\n'
                 + "Temp. TP vozvrat: " + s11 + '\n'
                 + "Temp. boyler: " + s14 + '\n' + '\n'
                 + "Davl. vodosn: " + s151 + "," + s152 + '\n'
                 + "Davl. otopl: " + s161 + "," + s162), String(SMSOUT));   // номер на кот пойдет смс
    }

    if (val.indexOf("+CMT") > -1) {                                         // если есть входящее смс
      if (val.indexOf("9122230000") > -1) {
        if (val.indexOf("Reset") > -1) {
          EEPROM.write(10, 0);                 // сбросили тревогу
          delay(5);
          SendDataP("page0.tm5.en", 0);           // остановили таймеры мигания "АВАРИИ" на дисплее
          SendDataP("page0.tm6.en", 0);
          SendDataP("page0.p0.pic", 10);          // опять нарисовали "БАНЬКУ"
          fa = true;                           // разрешили вновь сработку тревоги  tm1.en=0
          digitalWrite(62, HIGH);              // аппаратный RESET
          delay(500);
        }
        if (val.indexOf("S") > -1) {           // смотрим время последней синхронизации с GPS, отправл. СМС
          sms(String("Poslednyy sinhr: " + String(EEPROM.read(13)) + "." + String(EEPROM.read(12))
                     + "." + String(EEPROM.read(11)) + "  " + String(EEPROM.read(14))
                     + ":" + String(EEPROM.read(15))), "+79122230000");
        }
      }
    }
  }
M1:

  //----------------------------------------------- работа  GPS  модуля ----------------------------------------------------------------------
  //Serial.println("8");
  if (millis() - sinhr > mln) {
    newdata = false;
    start = millis();
    while (millis() - start < 2000)
    {
      if (Serial1.available())
      {
        char c = Serial1.read();    // чтение массива, переданного NEO-6M
        //Serial.print(c);          // вывести на печать массив из NEO-6M
        if (gps.encode(c))          // проверка данных на правильность
        {
          newdata = true;
          break;                    // остановить цикл при нормальной декодировке
        }
      }
    }
    if (newdata)
    {
      getgps(gps);                  // при нормальной декодеровке уходим на выполнение getgps(TinyGPS &gps)
    }
  }

  //d8 = 26;                                  //
  //d9 = 20;                                  // отопл.

  // --------------------------------- вывод на Nextion уличной температуры ------------------------------------------------
  //Serial.println("9");
  if ((millis() - nadisplei) > disp) {

    if ((abs(tPred) == 10 && abs(toutside) == 9) || (tPred < 0 && toutside >= 0) || (toutside < 0 && tPred >= 0)) {  // переход с двух разрядов температуры на один - очистка знакомест
      SendDataP("q0.picc", 11);                  // очистка всей температуры
    }
    if (toutside < 0 && toutside > -10) {              // ----  два разряда температуры    (  -5  )
      SendDataP("n29.picc", 11);                  // печать минуса
      SendDataP("n32.val", abs(toutside));
      SendDataP("t43.picc", 11);                  // печать градуса двух разрядов
    }
    if (toutside < 10 && toutside >= 0) {              // ------------  один разряд температуры   (  8  )
      SendDataP("n30.val", toutside);
      SendDataP("t42.picc", 11);                  // печать градуса одного разряда
    }
    if (toutside <= -10) {                             // ------------  три разряда температуры   (  -23   )
      SendDataP("n0.val", abs(toutside));         // печать температуры
      SendDataP("n31.picc", 11);                  // печать минуса
      SendDataP("t0.picc", 11);                   // печать градуса одного разряда
    }
    if (toutside >= 10) {                              // ------------  три разряда температуры   (  40   )
      SendDataP("n28.val", toutside);             // печать температуры
      SendDataP("t41.picc", 11);                  // печать градуса одного разряда
    }
    tPred = toutside;

    // ---------------- печать ТМ параметров ------------------
    //Serial.println("10");
    SendDataP("n3.val", hum);                                 // печать влажности
    SendDataP("n4.val", p);                                   // печать давления
    SendDataP("n12.val", celsius1);                           // печать температуры в доме
    SendDataP("page0.n14.val", d11);                          // печать температуры в гараже
    SendDataP("page0.n15.val", d10);                          // печать температуры в котельной
    SendDataP("page0.n16.val", d12);                          // печать температуры скважины
    SendDataP("page0.n7.val", d1);                            // печать температуры котёл подача
    SendDataP("page0.n8.val", d2);                            // печать температуры котёл обратка
    SendDataP("page0.n21.val", d1 - d2);                      // печать дэльты температуры котла
    SendDataP("page0.n9.val", d5);                            // печать температуры ТП подача
    SendDataP("page0.n10.val", d6);                           // печать температуры ТП обратка
    SendDataP("page0.n22.val", d5 - d6);                      // печать дэльты температуры ТП
    SendDataP("page0.n11.val", d7);                           // печать температуры бойлера
    SendDataP("page0.n23.val", d1 - d7);                      // печать дэльты температуры бойлера
    SendDataP("page0.n17.val", d9 / 10);                      // печать целого давления отопления
    SendDataP("page0.n19.val", d9 - (d9 / 10) * 10);          // печать десяток давления отопления
    SendDataP("page0.n18.val", d8 / 10);                      // печать целого давления водоснабжения
    SendDataP("page0.n20.val", d8 - (d8 / 10) * 10);          // печать десяток давления водоснабжения
    SendDataP("page0.n13.val", celsius2);                     // печать температуры входа
    if (BanTM) {                                              // есть инфа с бани
      SendDataP("page1.n7.val", db1);                         // печать температуры парной в бане
      SendDataP("page1.n9.val", db2);                         // печать температуры комнаты в бане
      SendDataP("page1.n8.val", db3);                         // печать температуры т.пола в бане
      SendDataP("page1.t2.picc", 11);                         // рисуем надписи и градусы
      SendDataP("page1.t1.picc", 11);                         // рисуем надписи и градусы
      SendDataP("page1.t5.picc", 11);                         // рисуем надписи и градусы
      SendDataP("page1.t34.picc", 11);                        // рисуем надписи и градусы
      SendDataP("page1.t7.picc", 11);                         // рисуем надписи и градусы
      SendDataP("page1.t8.picc", 11);                         // рисуем надписи и градусы
      if (db4 == 1) {                                         // нагрев включен
        SendDataP("page1.tm3.en", 1);
      }
      else {                                                  // нагрев выключен
        SendDataP("page1.tm3.en", 0);                         // останавливаем таймеры "костра"
        SendDataP("page1.tm4.en", 0);
        SendDataP("page1.tm5.en", 0);
        SendDataP("page1.tm6.en", 0);
        SendDataP("page1.p3.pic", 12);                        // рисуем картинку "нагрев выключен"
      }
    }
    else {                                                    //  нет инфы с бани
      SendDataP("page1.tm3.en", 0);                           // останавливаем таймеры "костра"
      SendDataP("page1.tm4.en", 0);
      SendDataP("page1.tm5.en", 0);
      SendDataP("page1.tm6.en", 0);
      SendDataP("page1.t9.picc", 11);                         // закрасили верх от "нагрев выключен"
      SendDataP("page1.p4.pic", 16);                          // написали "нет данных" от бани
    }

    // ------------------------------------------------------ часы -------------------------------------------------------

    Y = Clock.getYear();                      // получение года из модуля часов DS3231
    M = Clock.getMonth(Century);              // получение месяца из модуля часов DS3231
    d = Clock.getDate();                      // получение дня из модуля часов DS3231
    h = Clock.getHour(h12, PM);               // получение часов из модуля часов DS3231
    m = Clock.getMinute();                    // получение минут из модуля часов DS3231
    s = Clock.getSecond();                    // получение секунд из модуля часов DS3231

    // ---------------------------------- синхронизация часов  и календаря с Nextion ------------------------------------
    SendDataP("rtc0", 2000 + Y);
    SendDataP("rtc1", M);
    SendDataP("rtc2", d);
    SendDataP("rtc3", h);
    SendDataP("rtc4", m);
    SendDataP("rtc5", s);
    //Serial.println("11");
    // ------------------------------------ печать значка SD-карты на дисплей -----------------------------------------
    if (Zu) {
      SendDataP("page0.p1.pic", 3);                                        // ЗЕЛЁНЫЙ значёк
    }
    else {
      SendDataP("page0.p1.pic", 4);                                        // КРАСНЫЙ значёк
    }

    disp = 10000;                                         // установка периода вывода на дисплей основной информации (10 сек)
    nadisplei = millis();
  } // -------------------------------------- конец печати на Nextion ----------------------------------------------------


  // ---------------------------------------------------------------- авария ----------------------------------------------------------

  d9 = 7;
  d1 = 31;
  if ((d9 < 6 || d1 < 30) && fa == true) {                                     // условия аварии: давл отопл <0,6 Атм или темп выхода котла <30 градусов / флаг однократности сработки "Аварии"
  }
  else {
    za = millis();
  }
  // при наступлении аварийного условия ждём минуту устоявшегося события (типа защита от "дребезга")
  if ((millis() - za) > 10000) {
    sms(String("AVARIY OTOPLENIY!"), String("+79122230000"));
    EEPROM.write(10, 1);                                                       // записали аварию в память
    delay(5);
    SendDataP("page0.tm5.en", 1);                                              // запустили таймеры "АВАРИИ" на Nextion
    frchtd = true;                                                             // флаг разрешения чтения с дисплея "сброс аварии"
    fa = false;                                                                // флаг однократности сработки "Аварии"
  }
  //Serial.println("12");
  // ---------------------------------------- сброс тревоги и смена страницы (принимаем с Nextion) ----------------------------

  if (Serial2.available()) {
    delay (20);
    i = 1;
    val = 0;
    while (Serial2.available()) {
      ch = Serial2.read();
      delay (2);
      if (ch == 101) {
        fscht = true;                         // разрешили счёт считываемых байт если передача началась со 101
      }
      if (i < 5 && fscht) {
        val += ch;                            //собираем принятые символы в строку (4 байта всего): 173 - сброс аварии
        i++;
      }
    }
    //Serial.println(val);
    if (val == 196 || val == 148) {
      disp = 0;                              // разовый период вывода на дисплей
      delay(100);                            // таймер пиканья на Nextion не даёт очистить знакоместо - ждём пока пикнет Nextion
      nadisplei = millis();
      SendDataP("q0.picc", 11);               // очистка места температуры при переключении страницы
    }
    fscht = false;                              // закончили и опять разрешили счёт четырёх первых байт с дисплея
    if (frchtd) {                               // разрешение сброса тревоги с дисплея
      if ((val == 196 || val == 148) && EEPROM.read(10) == 1) {               // приняли с дисплея "сброс аварии"
        EEPROM.write(10, 0);                    // сбросили тревогу в ЕЕПРОМе
        delay(5);
        //Serial.println("сброс");
        SendDataP("page0.tm5.en", 0);           // остановили таймеры мигания "АВАРИИ" на дисплее
        SendDataP("page0.tm6.en", 0);
        SendDataP("page0.p0.pic", 10);          // опять нарисовали "БАНЬКУ"
        SendDataP("pio5", 0);                   // заткнули пищалку
        fa = true;                              // разрешили вновь сработку тревоги
        za = millis();
        frchtd = false;                         // запретили читать "сброс" с дисплея, но чтение перекл страницы возможно
      }
    }
  }
*/
}                      // -------------------------- конец LOOP ------------------------------
// --------------------------------------------------------------------

//================================================================================================================================
//================================================================================================================================

// ----------------- подпрограмма вывода данных из gps и синхронизации модуля часов ---------------------
/*
void getgps(TinyGPS & gps)
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  // вынимание данных из массива, полученного из модуля gps
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths);
  hour = hour + 5;                                        // переделка час. пояса
  if (hour > 23)                                          // избежание 25, 26 часов на дисплее
  {
    hour = hour - 24;
  }
  if (hour > 0 && hour < 5) {                             // коррекция даты в зависимости от времени и час. пояса
    day = day + 1;                                        // от 0 до 5 утра синхронизируется ещё старая дата (по Гринвичу)
  }
  gps.get_datetime(&date, &time);
  if (date == 0) {                                        // проверка на "нулевую дату" (бывает такой косяк при синхр.)
    mln = 60000;                                          // при косячной дате период синхр. GPS  - 1 минута
    //Serial.println("Косячная дата! - нет синхронизации");
  }
  else {
    setTime(hour, minute, second, day, month, year);      // устанавливаем: часы, минуты, секунды, день, месяц, год)
    RTC.set(now());                                       // применяем значение
    // запись времени и даты последней синхронизации с GPS, можно вытащить смской "S"
    EEPROM.write(11, 2000 + Y);     // год
    delay(5);
    EEPROM.write(12, M);            // месяц
    delay(5);
    EEPROM.write(13, d);            // день
    delay(5);
    EEPROM.write(14, h);            // часы
    delay(5);
    EEPROM.write(15, m);            // минуты
    delay(5);
    //Serial.println("Дата норма!");
    mln = 90000000;                                      // при норм. дате период синхр. GPS - до след. перезагрузки устройства, для запаса 25 часов. (90000000)
  }
  sinhr = millis();
}

//=========================================== Подпрограмма посылки SMS ====================================

void sms(String text, String phone)
{
  //Serial3.println("AT+CMGS=\"" + phone + "\"");
  delay(1000);
  Serial3.println(text);
  delay(300);
  Serial3.println((char)26);
  delay(300);
  Serial3.println(F("AT+CMGD=1,4"));
  delay(500);
}
*/
// ============================= Подпрограмма отправки на Nextion =========================================

void SendDataP(String dev, int dataP)           // для вывода картинок и чисел
{
  Serial2.print(dev);   // Отправляем данные dev(номер экрана, название переменной) на Nextion
  Serial2.print("=");   // Отправляем данные =(знак равно, далее передаем сами данные) на Nextion
  Serial2.print(dataP); // Отправляем данные data(данные) на Nextion
  Serial2.write(0xff);  // Отправляем данные 0xff(значение показывающее Nextion конец передачи) на Nextion
  Serial2.write(0xff);  // Отправляем данные 0xff(значение показывающее Nextion конец передачи) на Nextion
  Serial2.write(0xff);  // Отправляем данные 0xff(значение показывающее Nextion конец передачи) на Nextion
  dev = "";             // Очищаем переменную
}
/*
// ============================= Подпрограмма получения баланса GSM =========================================

void balans()                                // получение баланса
{
  Serial3.println(F("AT+CUSD=1,\"#100#\""));    // запрос баланса
  while (Serial3.available())                // очистка буфера
  {
    Serial3.read();
    delay(2);
  }
  delay(7000);
  if (Serial3.available()) {                 // задержка спец. не нужна - 7 сек. хватает
    char ch = ' ';
    String val = "";
    while (Serial3.available())
    {
      ch = Serial3.read();
      val += char(ch);                       //собираем принятые символы в строку
      delay(3);
    }
    if (val.indexOf("+CUSD") > -1) {
      char result1 = val.charAt(21);         // для МТС\SIM800 21
      char result2 = val.charAt(22);
      char result3 = val.charAt(23);
      char result4 = val.charAt(24);
      char result5 = val.charAt(25);
      char result6 = val.charAt(26);
      char result7 = val.charAt(27);
      ss1 = String(result1);
      ss2 = String(result2);
      ss3 = String(result3);
      ss4 = String(result4);
      ss5 = String(result5);
      ss6 = String(result6);
      ss7 = String(result7);
    }
  }
}
*/
//=================================== Пишем страницу html ============================================

void html()
{
  EthernetClient client = server.available();
  if (client) {
    float d8p = d8;                                     // промежуточная переменная для индикации давления
    d8p = d8p / 10;
    float d9p = d9;                                     // промежуточная переменная для индикации давления
    d9p = d9p / 10;
    client.println(F("HTTP/1.1 200 OK"));
    client.println(F("Content-Type: text/html"));
    client.println(F("Connection: close"));                // the connection will be closed after completion of the response
    client.println(F("Refresh: 15"));                      // обновление страницы через 60 сек
    client.println();
    client.println(F("<!DOCTYPE HTML>"));
    client.println("<html>");  //------------------------------------- Пишем страницу ------------------------------------
    client.println("<head>");
    client.println(F("<meta charset=\"UTF-8\">"));         // Установка кодировки
    client.println(F("<title>п.Залесье, ул.Осенняя, д.00</title>"));
    client.println("</head>");
/*
    if (millis() - swi < 60000) {         //1800000 3600000 5400000 7200000 9000000 10800000 12600000 14400000
      client.println(F("<body background=https://wmpics.pics/di-TW62.jpg><font color=\"WHITE\">")); // из мурманска в Питер
    }

    if (millis() - swi > 60000 && millis() - swi < 120000) {
      client.println(F("<body background=https://wmpics.pics/di-EAI35.jpg><font color=\"WHITE\">")); // разлив Ишима
    }
    if (millis() - swi > 120000 && millis() - swi < 180000) {
      client.println(F("<body background=https://wmpics.pics/di-M3D9.jpg><font color=\"WHITE\">")); // полуостров ночью
    }
    if (millis() - swi > 180000 && millis() - swi < 240000) {
      client.println(F("<body background=https://wmpics.pics/di-7QFR2.jpg><font color=\"WHITE\">")); // Санрайз 2
    }
    if (millis() - swi > 240000 && millis() - swi < 300000) {
      client.println(F("<body background=https://wmpics.pics/di-5QQV.jpg><font color=\"WHITE\">")); // Санрайз
    }
    if (millis() - swi > 300000 && millis() - swi < 360000) {
      client.println(F("<body background=https://wmpics.pics/di-T3D0.jpg><font color=\"WHITE\">")); // в открытом море
    }
    if (millis() - swi > 360000 && millis() - swi < 420000) {
      client.println(F("<body background=https://wmpics.pics/di-9GCF.jpg><font color=\"WHITE\">")); // колокольня в Калязине
    }
    if (millis() - swi > 420000 && millis() - swi < 480000) {
      client.println(F("<body background=https://wmpics.pics/di-I4U1.jpg>"));         // ромашковое поле
    }
    if (millis() - swi > 480000) {
      swi = millis();
    }

    client.println(F("<div style=\"position: absolute; top: 42px; left: 90px\">"));   // блок Котельная
    client.println(F("<h1>Котельная:</h1>"));
    client.println(F("<h2>Котёл подача:  "));    client.println(d1);    client.println("&deg;");    client.println("<br />");
    client.println(F("Котёл возврат: "));    client.println(d2);    client.println("&deg;");    client.println("<br />");
    client.println(F("Тёплый пол подача:"));    client.println(d5);    client.println("<br />");
    client.println(F("Тёплый пол возврат:"));    client.println(d6);    client.println("&deg;");    client.println("<br />");
    client.println(F("Бойлер:"));    client.println(d7);    client.println("&deg;");    client.println("<br />");
    client.println(F("Давление отопления:"));    client.println(d9p);    client.println("Bar.");    client.println("<br />");
*/
    client.println(F("Давление водоснабж.:"));    client.println(d8p);    client.println("Bar.");    client.println("<br />");
/*
    client.println("</h2></div>");

    client.println(F("<div style=\"position: absolute; top: 42px; left: 500px\">"));   // блок Температурные параметры
    client.println(F("<h1>Температурные параметры:</h1>"));
    client.println(F("<h2>Температура на улице:  ")); client.println(toutside); client.println("&deg;"); client.println("<br />");
    client.println(F("Влажность: ")); client.println(hum); client.println("&#37;"); client.println("<br />");
    client.println(F("Атмосф. давление:")); client.println(p); client.println(F("мм.рт.ст.")); client.println("<br /><br />");
    client.println(F("Дом:")); client.println(celsius1); client.println("&deg;"); client.println("<br />");
    client.println(F("Вход:")); client.println(celsius2); client.println("&deg;"); client.println("<br />");
    client.println(F("Гараж:")); client.println(d11); client.println("&deg;"); client.println("<br />");
    client.println(F("Котельная:")); client.println(d10); client.println("&deg;"); client.println("<br />");
    client.println(F("Скважина:")); client.println(d12); client.println("&deg;"); client.println("</div>");

    client.println(F("<div style=\"position: absolute; top: 42px; left: 980px\">"));   // блок Баня
    client.println(F("<h1>Баня:</h1>"));
    if (BanTM) {
      client.println(F("<h2>Парная:  ")); client.println(db1); client.println("&deg;"); client.println("<br />");
      client.println(F("Комната: ")); client.println(db2); client.println("&deg;"); client.println("<br />");
      client.println(F("Тёплый пол:")); client.println(db3); client.println("&deg;"); client.println("<br />");
      if (db4 != 0) {
        client.println(F("<p><font color=\"red\">Нагрев включен</font></p>"));
      }
      else {
        client.println(F("<br />Нагрев выключен"));
      }
    }
    else {
      client.println(F("<h2>Нет данных</h2>"));
    }
    client.println("</div>");

    client.println(F("<div style=\"position: absolute; top: 42px; left: 1230px\">"));   // блок Расход фильтров
    client.println(F("<h1>Фильтры:</h1>"));
    client.println(F("<h2>Мех.:  ")); client.println(F("&nbsp;&nbsp;&nbsp;&nbsp;")); client.println(d12); client.println("&#37;"); client.println("<br />");
    client.println(F("Ca Mg: ")); client.println("&nbsp;"); client.println(d14); client.println("&#37;"); client.println("<br />");
    client.println(F("Fe:")); client.println(F("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;")); client.println(d15); client.println("&#37;"); client.println("<br />");
    client.println("</div>");
    if (frchtd) {
      client.println(F("<div style=\"position: absolute; top: 420px; left: 400px\">"));   // Авария
      client.println(F("<h1><p><blink><font color=\"red\">АВАРИЯ! АВАРИЯ! АВАРИЯ! АВАРИЯ! АВАРИЯ!</font></blink></p></h1>")); client.println("</div>");
    }
*/
    client.println("</html>"); //------------------------- Закончили страницу -------------------------------
    delay(50);

    client.stop();
    Serial.println(millis());
  }
}
// -------------------------------------------------- SD карта ------------------------------------------------------------------------------

void SDcard()
{
  //delay(10);
  //if ((millis() - registr) > treg && m % 5 == 0) {                      // таймер для записи регистратора на 5 мин и кратно 5 мин.

  if ((millis() - registr) > 10000) {                      // таймер для записи регистратора на 5 мин и кратно 5 мин.
    String logStringData = "";                                          // формирование строки с данными
    String Bm;                                                          // переменная для минут меньше 10, чтобы минуты на дисплее были с нулём
    if (m < 10) {
      Bm = "0" + String(m);
    }
    else {
      Bm = String(m);
    }
    String Bh;                                                          // переменная для часов меньше 10, чтобы часы на дисплее были с нулём
    if (h < 10) {
      Bh = "0" + String(h);
    }
    else {
      Bh = String(h);
    }
    // формируем строку с данными
    logStringData = Bh + ":" + Bm + " > " + "Котёл " + d1 + "/" + d2 + "; ТП " + d5 + "/" + d6 + "; Бойл " + d7 + "; Давл.вс " + d8 / 10 + ","
                    + (d8 - (d8 / 10) * 10) + "; Давл.от " + d9 / 10 + "," + (d9 - (d9 / 10) * 10) + ";" + "\n" + "        Темп ул. " + toutside + "; Вл. "
                    + hum + "; Давл. " + p + "; Темп. дом " + celsius1 + "; Темп. вход " + celsius2 + "; Темп. гараж " + d11 + "; Темп. кот. " + d10 + "; Темп. скв. " + d12 + ";";
    //Serial.println(logStringData);
    String DirectName = "20" + String(Y) + "/" + String(M);                // Создаём имя папки из месяца и года
    String logStringName = DirectName + "/" + String(d) + ".txt";          // формируем текстовый файл на один день максимум 12 знаков в названии файла
    //Serial.println (logStringName);
    //if (SD.begin(47)) {
    if (SD.mkdir(DirectName)) {                                            // создаём на SD указанную территорию, может включать в себя вложенные папки, разделенные прямым слешем "/"
      // Открываем файл, Если файла с таким именем не будет, ардуино создаст его.
      File dataFile = SD.open(logStringName, FILE_WRITE);
      // Если все хорошо, то записываем строку:
      if (dataFile) {
        dataFile.println(logStringData);                                     // в файл записываем строку данных с переводом строки
        dataFile.close();                                                    // закрываем файл
        SendDataP("page0.p1.pic", 3);                                        // ЗЕЛЁНЫЙ значёк
        Serial.println(F("Запись прошла на SD"));
        Zu = true;                                                           // флаг для печати нужного значка в цикле печати
      }
      else {
        SendDataP("page0.p1.pic", 4);                                        // КРАСНЫЙ значёк
        Serial.println(F("Ошибка записи на SD!"));
        Zu = false;                                                          // флаг для печати нужного значка в цикле печати
      }
      registr = millis();
    }
    //}
  }
}

 

Вот...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А что написано в строках №№ 116-118?

И где определены используемые там переменные?

alexbel620017
Offline
Зарегистрирован: 26.03.2017

В блоке "SIM800" для отправки смс с телеметрией.

Евгений, убегаю на работу, буду ближе к вечеру.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Не понял ответа, в каком блоке, у него номера строк есть? И первая часть вопроса осталась без ответа - что там вообще написано?

b707
Offline
Зарегистрирован: 26.05.2017

Евгений, автор все равно не знает ответа. Давайте я за него.

Мне кажется что строки 116-118 написана по аналогии со строкой 115. То есть, собственно это и есть определение переменных типа String.  А что, разве тут ошибка? Скобки, конечно, лишние, а больше никаких проблем не вижу.

Используются эти переменные в строках 397 - 408... в блоке отправки СМС, ныне закомментированном

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b707 пишет:
Давайте я за него.
Напрасно. Вопрос-то был на самом деле такой: "стоит ли напрягаться и пытаться тебе помогать - или тебе только готовый скетч поможет?". Я надеялся получить ясный ответ от ТС :-(

b707
Offline
Зарегистрирован: 26.05.2017

ЕвгенийП пишет:

Вопрос-то был на самом деле такой: "стоит ли напрягаться и пытаться тебе помогать - или тебе только готовый скетч поможет?"

о том, что ТС полный дуп и "программирование не его" - я ему в ветке уже раза три написал. Я уже скорее не ему помогаю, мне просто любопытно, сколько же еще невообразимых ляпов он насажал в этом, нехитром вообще-то, коде...

alexbel620017
Offline
Зарегистрирован: 26.03.2017

ЕвгенийП пишет:

Не понял ответа, в каком блоке, у него номера строк есть? И первая часть вопроса осталась без ответа - что там вообще написано?

Используются в строках 397-416, 418

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Понятно, значит вопрос о том, "что именно там написано" Вы проигнорировали уже во второй раз. Ладно, хозяин - барин.

alexbel620017
Offline
Зарегистрирован: 26.03.2017

Присвоение идёт в этих же строках - 397-416

Вы про то что при объявлении не указано что в них?

String s1 = "", s2 = "", s3 = "", s4 = "", s5 = "", s6 = "", s7 = "", s8 = "", s9 = "", s10 = "", s11 = "", s12 = "", s13 = "", s14 = "", s15 = "", s16 = "";

Так правильно?

alexbel620017
Offline
Зарегистрирован: 26.03.2017

Вот этот скетч с участием модулей SD и W5500 проработал всю ночь. При подключении модуля LoRa виснет. Сам модуль на SX1278 у меня старый, состояние его не известно - откопал с каких-то прежних пректов. RA-01 я благополучно спалил (их было два у меня - один стоит в банном модуле на DUE, у другого случилась коза по питанию). Сейчас из Китая жду новые, скоро должны быть. Может модуль этот старый больной?....

#include <SD.h>
#include <RH_RF95.h>
#include <Ethernet2.h>
#include <SPI.h>

// ------------------------- сеть ---------------------------------
byte mac[] = {0x2C, 0xF7, 0xF1, 0x08, 0x00, 0x9A};
IPAddress ip(192, 168, 1, 6);
EthernetServer server(756);

// ------------------------- LoRa ---------------------------------
RH_RF95 rf95(48, 2);                       // (SS, interrupt) внимательно с выводом прерывания на Ардуине!
uint32_t data[5];                                 // Создаём массив для приёма данных - 32 разряда, тк передатчик DUE

//------------------------- температура --------------------------

bool frchtd = false;                       // флаг разрешения чтения с дисплея "сброса"
bool newdata = false;
bool Century = false;
bool h12;
bool PM;
bool td = false;                           // флаг разрешения обработки данных датчика температуры в доме
bool fwdt = true;                          // флаг WDT
bool fsd = true;                           // флаг однократности вывода "данные устарели"
byte m, s, h, d, M;                        // переменные даты и времени
int Y = 2000;
bool fscht;                                // флаг разрешения суммирования при чтении с дисплея
bool BanTM = false;                        // флаг наличия данных из бани
bool Zu = false;                           // флаг печати значка SD-карты на дисплей
bool fp = false;                           // флаг разрешения сброса раз в сутки
bool fa = true;                            // флаг для однократности сработывания аварии
int celsius1, celsius2, celsius3;          // температура в доме
float celsgis = 100;                       // промежуточная темп. для прохождения гистерезиса
int toutside = 0;                          // температура на улице с датчика влажности
int tPred;                                 // переменная для проверки перехода с одного разряда на два и обратно при печати ул. температуры на дисплей
int p;                                     // давление
int hum;                                   // влажность на улице
int ch;                                    // переменная для вычитывания буфера Nextion
int val;                                   // строка из дисплея
int i;
float tuprm;                               // считанное значение уличной температуры
float huprm;                               // считанное значение уличной влажности
float dvl;                                 // считанное значение атм. давления
bool gisalarm;
float toutsidegis = 100;                   // переменная для гистерезиса
unsigned long mln = 300000;                // период синхронизации с GPS (сначала ч/з 5 минут (считывание альманаха при перв вкл, потом раз в 7 сут. (604800000)
unsigned long sinhr;                       // переменная в мсек задающ. период синхронизации
unsigned long za;                          // переменная в мсек задающ. задержку на сработывание аварии (2 мин, искл. ложных срабатываний)
unsigned long zadavar;                     // переменная в мсек задающ. период синхронизации
unsigned long start;                       // переменная в мсек задающ. цикл считывания данных gps
unsigned long registr;                     // переменная в мсек для таймера регистратора
unsigned long dvt = 3000;                  // период измерения давл. вл. и температуры (нач. 5 сек, потом раз в минуту)
unsigned long dvtperiod;                   // переменная в мсек для таймера измерен. давл.вл и у.темп.
unsigned long loraperiod;                  // переменная таймера проверки приёма LoRa
unsigned long swi = millis();              // перенная для смены фона на сайте ТМ данных
unsigned long treg = 290000;               // период записи регистратора 5 мин (переменная на 10 сек меньше - догоняет остаток от деления =0)
unsigned long tperiod;                     // переменная в мсек для таймера обработки измерен. темп. в доме
unsigned long nadisplei;                   // переменная в мсек для таймера вывода на дисплей
unsigned long disp = 50;                   // период таймера вывода на дисплей, нач. 1 сек, потом 10 сек.
unsigned long olddata;                     // переменная
unsigned long pwdt;                        // переменная для WDT
unsigned long time, date;                  // переменные для считыв. даты и времени для вычисления "пустой" даты
float gis = 0.2;                           // гистерезис температуры и влажности
float pgis, hgis;                          // вспомогательная переменная для гистерезиса влажн. и давления
String pch = "";                           // переменная для вывода на дисплей
String SMSOUT = "";                        // текстовая переменная "номер для смс"

int db1;                                   // темпеатура парной
int db2;                                   // темпеатура комната бани
int db3;                                   // темпеатура т. пола бани
int db4;                                   // нагрев (0 - нет, 1 - нагрев)
int db5;                                   // CRC с LoRa

int d1;                                    // темпеатура выход котла К-->
int d2;                                    // темпеатура вход котла (обратка) K<--
int d5;                                    // темпеатура выход на ТП
int d6;                                    // темпеатура вход с ТП (обратка)
int d7;                                    // темпеатура бойлера
int d8;                                  // давление системы водоснабжения
int d9;                                  // давление системы отопления
int d81, d82, d91, d92;                    // промеж. параметры для отобр. гидро давления в СМС
int d10;                                   // темпеатура в котельной
int d11;                                   // темпеатура в гараже
int d12;                                   // темпеатура скважины
int d13;                                   // расход фильтра Мех.
int d14;                                   // расход фильтра Ca Mg.
int d15;                                    // расход фильтра Fe.

int ttt;
//File myFile;

// ------------------------------------------------------ setup --------------------------------------------------------------

void setup() {

  Serial.begin(9600);
  Serial1.begin(9600);                      // порт GPS
  Serial2.begin(9600);                      // порт Nextion
  Serial3.begin(9600);                      // порт SIM800

  pinMode(48, OUTPUT);                      // CS LoRa
  pinMode(49, OUTPUT);                      // CS W5500
  pinMode(47, OUTPUT);                      // CS SD
  pinMode(53, OUTPUT);                      // штатный CS не используется
  //pinMode(33, OUTPUT);                      // выход на WDT
  digitalWrite(47, HIGH);
  digitalWrite(48, HIGH);
  digitalWrite(49, HIGH);
  digitalWrite(53, HIGH);
  //digitalWrite(33, LOW);

  SPI.begin;
  //SPI.setClockDivider(SPI_CLOCK_DIV16);

  Ethernet.begin(mac, ip);
  server.begin();
  SD.begin(47);                             // инициализация модуля SD карты
  rf95.init();                              // инициализация SX1278
  rf95.setTxPower(5, false);                // мощность 5 - 23, максимальная мощность (при 23) 100мВт (шаги с 5 по 23 не подряд! смотреть в библиотеке)
  //void clearRxBuf();

  Serial.print(F("server is at "));
  Serial.println(Ethernet.localIP());
}

// ==========================================================================================================================
// ============================================================ L O O P =====================================================

void loop() {
  ttt++;
  if (ttt > 1000) {
    Serial.println(millis());
    ttt = 0;
  }
  // -------------------------------------------- LoRa ------------------------------------------------------------
/*
  if (rf95.available()) {
    rf95.recv((uint8_t*)data, sizeof(data));
  }
  */
  // -------------------------------------------------- SD карта ------------------------------------------------------------------------------

  SDcard();

  // -------------------------------------------------- Сеть ------------------------------------------------------------------

  html();
}                      // -------------------------- конец LOOP ------------------------------
// --------------------------------------------------------------------

//================================================================================================================================
//================================================================================================================================

//=================================== Пишем страницу html ============================================

void html()
{
  EthernetClient client = server.available();
  if (client) {
    client.println(F("HTTP/1.1 200 OK"));
    client.println(F("Content-Type: text/html"));
    client.println(F("Connection: close"));                // the connection will be closed after completion of the response
    client.println(F("Refresh: 15"));                      // обновление страницы через 60 сек
    client.println();
    client.println(F("<!DOCTYPE HTML>"));
    client.println("<html>");  //------------------------------------- Пишем страницу ------------------------------------
    client.println("<head>");
    client.println(F("<meta charset=\"UTF-8\">"));         // Установка кодировки
    client.println(F("<title>п.Залесье, ул.Осенняя, д.00</title>"));
    client.println("</head>");

    if (millis() - swi < 60000) {         //1800000 3600000 5400000 7200000 9000000 10800000 12600000 14400000
      client.println(F("<body background=https://wmpics.pics/di-TW62.jpg><font color=\"WHITE\">")); // из мурманска в Питер
    }

    if (millis() - swi > 60000 && millis() - swi < 120000) {
      client.println(F("<body background=https://wmpics.pics/di-EAI35.jpg><font color=\"WHITE\">")); // разлив Ишима
    }
    if (millis() - swi > 120000 && millis() - swi < 180000) {
      client.println(F("<body background=https://wmpics.pics/di-M3D9.jpg><font color=\"WHITE\">")); // полуостров ночью
    }
    if (millis() - swi > 180000 && millis() - swi < 240000) {
      client.println(F("<body background=https://wmpics.pics/di-7QFR2.jpg><font color=\"WHITE\">")); // Санрайз 2
    }
    if (millis() - swi > 240000 && millis() - swi < 300000) {
      client.println(F("<body background=https://wmpics.pics/di-5QQV.jpg><font color=\"WHITE\">")); // Санрайз
    }
    if (millis() - swi > 300000 && millis() - swi < 360000) {
      client.println(F("<body background=https://wmpics.pics/di-T3D0.jpg><font color=\"WHITE\">")); // в открытом море
    }
    if (millis() - swi > 360000 && millis() - swi < 420000) {
      client.println(F("<body background=https://wmpics.pics/di-9GCF.jpg><font color=\"WHITE\">")); // колокольня в Калязине
    }
    if (millis() - swi > 420000 && millis() - swi < 480000) {
      client.println(F("<body background=https://wmpics.pics/di-I4U1.jpg>"));         // ромашковое поле
    }
    if (millis() - swi > 480000) {
      swi = millis();
    }

    client.println(F("<div style=\"position: absolute; top: 42px; left: 90px\">"));   // блок Котельная
    client.println(F("<h1>Котельная:</h1>"));
    client.println(F("<h2>Котёл подача:  "));    client.println(d1);    client.println("&deg;");    client.println("<br />");
    client.println(F("Котёл возврат: "));    client.println(d2);    client.println("&deg;");    client.println("<br />");
    client.println(F("Тёплый пол подача:"));    client.println(d5);    client.println("<br />");
    client.println(F("Тёплый пол возврат:"));    client.println(d6);    client.println("&deg;");    client.println("<br />");
    client.println(F("Бойлер:"));    client.println(d7);    client.println("&deg;");    client.println("<br />");
    //client.println(F("Давление отопления:"));    client.println(d9p);    client.println("Bar.");    client.println("<br />");

    client.println(F("Давление водоснабж.:"));   client.println("Bar.");    client.println("<br />");

    client.println("</h2></div>");

    client.println(F("<div style=\"position: absolute; top: 42px; left: 500px\">"));   // блок Температурные параметры
    client.println(F("<h1>Температурные параметры:</h1>"));
    client.println(F("<h2>Температура на улице:  ")); client.println(toutside); client.println("&deg;"); client.println("<br />");
    client.println(F("Влажность: ")); client.println(hum); client.println("&#37;"); client.println("<br />");
    client.println(F("Атмосф. давление:")); client.println(p); client.println(F("мм.рт.ст.")); client.println("<br /><br />");
    client.println(F("Дом:")); client.println(celsius1); client.println("&deg;"); client.println("<br />");
    client.println(F("Вход:")); client.println(celsius2); client.println("&deg;"); client.println("<br />");
    client.println(F("Гараж:")); client.println(d11); client.println("&deg;"); client.println("<br />");
    client.println(F("Котельная:")); client.println(d10); client.println("&deg;"); client.println("<br />");
    client.println(F("Скважина:")); client.println(d12); client.println("&deg;"); client.println("</div>");

    client.println(F("<div style=\"position: absolute; top: 42px; left: 980px\">"));   // блок Баня
    client.println(F("<h1>Баня:</h1>"));
    if (BanTM) {
      client.println(F("<h2>Парная:  ")); client.println(db1); client.println("&deg;"); client.println("<br />");
      client.println(F("Комната: ")); client.println(db2); client.println("&deg;"); client.println("<br />");
      client.println(F("Тёплый пол:")); client.println(db3); client.println("&deg;"); client.println("<br />");
      if (db4 != 0) {
        client.println(F("<p><font color=\"red\">Нагрев включен</font></p>"));
      }
      else {
        client.println(F("<br />Нагрев выключен"));
      }
    }
    else {
      client.println(F("<h2>Нет данных</h2>"));
    }
    client.println("</div>");

    client.println(F("<div style=\"position: absolute; top: 42px; left: 1230px\">"));   // блок Расход фильтров
    client.println(F("<h1>Фильтры:</h1>"));
    client.println(F("<h2>Мех.:  ")); client.println(F("&nbsp;&nbsp;&nbsp;&nbsp;")); client.println(d12); client.println("&#37;"); client.println("<br />");
    client.println(F("Ca Mg: ")); client.println("&nbsp;"); client.println(d14); client.println("&#37;"); client.println("<br />");
    client.println(F("Fe:")); client.println(F("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;")); client.println(d15); client.println("&#37;"); client.println("<br />");
    client.println("</div>");
    /*
      if (frchtd) {
      client.println(F("<div style=\"position: absolute; top: 420px; left: 400px\">"));   // Авария
      client.println(F("<h1><p><blink><font color=\"red\">АВАРИЯ! АВАРИЯ! АВАРИЯ! АВАРИЯ! АВАРИЯ!</font></blink></p></h1>")); client.println("</div>");
      }
    */
    client.println("</html>"); //------------------------- Закончили страницу -------------------------------
    delay(50);

    client.stop();
    Serial.println(millis());
  }
}
// -------------------------------------------------- SD карта ------------------------------------------------------------------------------

void SDcard()
{
  //if ((millis() - registr) > treg && m % 5 == 0) {                      // таймер для записи регистратора на 5 мин и кратно 5 мин.
  if ((millis() - registr) > 10000) {
    String logStringData = "";                                          // формирование строки с данными
    String Bm = "";                                                        // переменная для минут меньше 10, чтобы минуты на дисплее были с нулём
    if (m < 10) {
      Bm = "0" + String(m);
    }
    else {
      Bm = String(m);
    }
    String Bh = "";                                                        // переменная для часов меньше 10, чтобы часы на дисплее были с нулём
    if (h < 10) {
      Bh = "0" + String(h);
    }
    else {
      Bh = String(h);
    }
    // формируем строку с данными
    logStringData = "; Темп. скв. jhlkuytjhgkjhfuyrtedoytpiojhkljho876rtytgfljh";
    //Serial.println(logStringData);
    String DirectName = "20" + String(Y) + "/" + String(M);                // Создаём имя папки из месяца и года
    String logStringName = DirectName + "/" + String(d) + ".txt";          // формируем текстовый файл на один день максимум 12 знаков в названии файла
    //Serial.println (logStringName);
    if (SD.mkdir(DirectName)) {                                            // создаём на SD указанную территорию, может включать в себя вложенные папки, разделенные прямым слешем "/"
      // Открываем файл, Если файла с таким именем не будет, ардуино создаст его.
      File dataFile = SD.open(logStringName, FILE_WRITE);
      // Если все хорошо, то записываем строку:
      if (dataFile) {
        dataFile.println(logStringData);                                     // в файл записываем строку данных с переводом строки
        dataFile.close();                                                    // закрываем файл
        //SendDataP("page0.p1.pic", 3);                                        // ЗЕЛЁНЫЙ значёк
        Serial.println(F("Запись прошла на SD"));
        Zu = true;                                                           // флаг для печати нужного значка в цикле печати
      }
      else {
        //SendDataP("page0.p1.pic", 4);                                        // КРАСНЫЙ значёк
        Serial.println(F("Ошибка записи на SD!"));
        Zu = false;                                                          // флаг для печати нужного значка в цикле печати
      }
      registr = millis();
    }
  }
}

 

b707
Offline
Зарегистрирован: 26.05.2017

alexbel620017 пишет:

Может модуль этот старый больной?....

Не обманывай себя, Маша, ты беременна...