Вот если честно - Вы ожидаете, что кто-то будет эти сотни строк у себя в голове прокручивать, чтобы понять, где стек пропарывает кучу?
я подозреваю, что когда String инициируется строкой с нечетным числом кавычек, в памяти начинается бардак. а твое мнение?
У меня нет никакого мнения, ибо программная проблема может быть усугублена неудачно подобранной библиотекой и кривым монтажом. При таком объеме кода и уровне подготовки автора можно полгода переписываться, в итоге обнаружив высохший конденсатор в БП. Без сборки макета только случайно отыщется баг.
И при нечетном числе кавычек, равно как и скобок, компилятор вывалится в ошибку.
Именно так и сделано. Я не знаю почему при переносе кода на форум эти кавычки "портятся".
С не прикрытыми кавычками компилятор ошибки выдаёт.
ОК, тогда начните с того, что добавьте макррос F() во все строчки длиной более 5-7 символов и посмотрите,насколько станет больше свободной памяти.
В остальном я согласен с Садман41 - к сожалению, вы себя так зарекомендовали, что я категорически не доверяю вашим спсобностям программировать, поэтому ошибка (и далеко не одна) может быть где угодно, вообще на ровном месте
Вот если честно - Вы ожидаете, что кто-то будет эти сотни строк у себя в голове прокручивать, чтобы понять, где стек пропарывает кучу?
я подозреваю, что когда String инициируется строкой с нечетным числом кавычек, в памяти начинается бардак. а твое мнение?
У меня нет никакого мнения, ибо программная проблема может быть усугублена неудачно подобранной библиотекой и кривым монтажом. При таком объеме кода и уровне подготовки автора можно полгода переписываться, в итоге обнаружив высохший конденсатор в БП. Без сборки макета только случайно отыщется баг. И при печатном числе кавычек, равно как и скобок, компилятор вывалился в ошибку.
Все (!) соединения на пайке, каждый модуль шунтирован электролитом и керамикой, БП трансформаторный с линейным стабилизатором (не импульсный преобразователь). Осциллограф показывает идеальную форму питания, равно как и форму импульсов на SPI. Уровни импульсов тоже 5 и 3,2 вольта.
Именно так и сделано. Я не знаю почему при переносе кода на форум эти кавычки "портятся".
С не прикрытыми кавычками компилятор ошибки выдаёт.
ОК, тогда начните с того, что добавьте макррос F() во все строчки длиной более 5-7 символов и посмотрите,насколько станет больше свободной памяти.
В остальном я согласен с Садман41 - к сожалению, вы себя так зарекомендовали, что я категорически не доверяю вашим спсобностям программировать, поэтому ошибка (и далеко не одна) может быть где угодно, вообще на ровном месте
Я код и так сократил - повырезал всё не участвующее. Остались только части связанные с этими тремя модулями.
Лично я бы в такой ситуации, при наличии подозрений на железо, сделал бы скетч, в котором работа со всей периферией была активной, но простой - типа постоянного чтения\установки статусов. Если проблема действительно в сочетании комплектующих - новый скетч повиснет так же быстро.
Евгений, автор все равно не знает ответа. Давайте я за него.
Мне кажется что строки 116-118 написана по аналогии со строкой 115. То есть, собственно это и есть определение переменных типа String. А что, разве тут ошибка? Скобки, конечно, лишние, а больше никаких проблем не вижу.
Используются эти переменные в строках 397 - 408... в блоке отправки СМС, ныне закомментированном
Напрасно. Вопрос-то был на самом деле такой: "стоит ли напрягаться и пытаться тебе помогать - или тебе только готовый скетч поможет?". Я надеялся получить ясный ответ от ТС :-(
Вопрос-то был на самом деле такой: "стоит ли напрягаться и пытаться тебе помогать - или тебе только готовый скетч поможет?"
о том, что ТС полный дуп и "программирование не его" - я ему в ветке уже раза три написал. Я уже скорее не ему помогаю, мне просто любопытно, сколько же еще невообразимых ляпов он насажал в этом, нехитром вообще-то, коде...
Вот этот скетч с участием модулей 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("°"); client.println("<br />");
client.println(F("Котёл возврат: ")); client.println(d2); client.println("°"); client.println("<br />");
client.println(F("Тёплый пол подача:")); client.println(d5); client.println("<br />");
client.println(F("Тёплый пол возврат:")); client.println(d6); client.println("°"); client.println("<br />");
client.println(F("Бойлер:")); client.println(d7); client.println("°"); 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("°"); client.println("<br />");
client.println(F("Влажность: ")); client.println(hum); client.println("%"); client.println("<br />");
client.println(F("Атмосф. давление:")); client.println(p); client.println(F("мм.рт.ст.")); client.println("<br /><br />");
client.println(F("Дом:")); client.println(celsius1); client.println("°"); client.println("<br />");
client.println(F("Вход:")); client.println(celsius2); client.println("°"); client.println("<br />");
client.println(F("Гараж:")); client.println(d11); client.println("°"); client.println("<br />");
client.println(F("Котельная:")); client.println(d10); client.println("°"); client.println("<br />");
client.println(F("Скважина:")); client.println(d12); client.println("°"); 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("°"); client.println("<br />");
client.println(F("Комната: ")); client.println(db2); client.println("°"); client.println("<br />");
client.println(F("Тёплый пол:")); client.println(db3); client.println("°"); 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(" ")); client.println(d12); client.println("%"); client.println("<br />");
client.println(F("Ca Mg: ")); client.println(" "); client.println(d14); client.println("%"); client.println("<br />");
client.println(F("Fe:")); client.println(F(" ")); client.println(d15); client.println("%"); 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();
}
}
}
я подозреваю, что когда String инициируется строкой с нечетным числом кавычек, в памяти начинается бардак. а твое мнение?
на самом деле в коде вот так, просто когда вы вставляете в форум, часть строки вырезается
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\">")); // из мурманска в ПитерИменно так и сделано. Я не знаю почему при переносе кода на форум эти кавычки "портятся".
С не прикрытыми кавычками компилятор ошибки выдаёт.
я подозреваю, что когда String инициируется строкой с нечетным числом кавычек, в памяти начинается бардак. а твое мнение?
У меня нет никакого мнения, ибо программная проблема может быть усугублена неудачно подобранной библиотекой и кривым монтажом. При таком объеме кода и уровне подготовки автора можно полгода переписываться, в итоге обнаружив высохший конденсатор в БП. Без сборки макета только случайно отыщется баг.
И при нечетном числе кавычек, равно как и скобок, компилятор вывалится в ошибку.
Именно так и сделано. Я не знаю почему при переносе кода на форум эти кавычки "портятся".
С не прикрытыми кавычками компилятор ошибки выдаёт.
ОК, тогда начните с того, что добавьте макррос F() во все строчки длиной более 5-7 символов и посмотрите,насколько станет больше свободной памяти.
В остальном я согласен с Садман41 - к сожалению, вы себя так зарекомендовали, что я категорически не доверяю вашим спсобностям программировать, поэтому ошибка (и далеко не одна) может быть где угодно, вообще на ровном месте
я подозреваю, что когда String инициируется строкой с нечетным числом кавычек, в памяти начинается бардак. а твое мнение?
Все (!) соединения на пайке, каждый модуль шунтирован электролитом и керамикой, БП трансформаторный с линейным стабилизатором (не импульсный преобразователь). Осциллограф показывает идеальную форму питания, равно как и форму импульсов на SPI. Уровни импульсов тоже 5 и 3,2 вольта.
Именно так и сделано. Я не знаю почему при переносе кода на форум эти кавычки "портятся".
С не прикрытыми кавычками компилятор ошибки выдаёт.
ОК, тогда начните с того, что добавьте макррос F() во все строчки длиной более 5-7 символов и посмотрите,насколько станет больше свободной памяти.
В остальном я согласен с Садман41 - к сожалению, вы себя так зарекомендовали, что я категорически не доверяю вашим спсобностям программировать, поэтому ошибка (и далеко не одна) может быть где угодно, вообще на ровном месте
Я код и так сократил - повырезал всё не участвующее. Остались только части связанные с этими тремя модулями.
С макросами так и сделал уже.
С макросами так и сделал уже.
насколько прибавилось памяти?
Прибавилось прилично - было свободно 1607 байт, сейчас 3287
Добил остальные принты - свободно стало 4174
Лично я бы в такой ситуации, при наличии подозрений на железо, сделал бы скетч, в котором работа со всей периферией была активной, но простой - типа постоянного чтения\установки статусов. Если проблема действительно в сочетании комплектующих - новый скетч повиснет так же быстро.
точно огромный HTML с картинками надо бы выкинуть.
Да, так и сделаю, но это уже завтра, спасибо.
точно огромный HTML с картинками надо бы выкинуть.
Выкидывал! - та же хрень...
Сейчас с освободившимся ОЗУ ещё раз убрал HTML (печатает одну надпись на странице без картинок) - посмотрю как будет
Нет, виснет. Заметил - если в скетче есть Serial.print то работает дольше, если скетч маслает без задержек, то "конец" наступает гораздо быстрее......
Я код и так сократил - повырезал всё не участвующее. Остались только части связанные с этими тремя модулями.
С макросами так и сделал уже.
И где он? Новый код?
#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("°"); client.println("<br />"); client.println(F("Котёл возврат: ")); client.println(d2); client.println("°"); client.println("<br />"); client.println(F("Тёплый пол подача:")); client.println(d5); client.println("<br />"); client.println(F("Тёплый пол возврат:")); client.println(d6); client.println("°"); client.println("<br />"); client.println(F("Бойлер:")); client.println(d7); client.println("°"); 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("°"); client.println("<br />"); client.println(F("Влажность: ")); client.println(hum); client.println("%"); client.println("<br />"); client.println(F("Атмосф. давление:")); client.println(p); client.println(F("мм.рт.ст.")); client.println("<br /><br />"); client.println(F("Дом:")); client.println(celsius1); client.println("°"); client.println("<br />"); client.println(F("Вход:")); client.println(celsius2); client.println("°"); client.println("<br />"); client.println(F("Гараж:")); client.println(d11); client.println("°"); client.println("<br />"); client.println(F("Котельная:")); client.println(d10); client.println("°"); client.println("<br />"); client.println(F("Скважина:")); client.println(d12); client.println("°"); 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("°"); client.println("<br />"); client.println(F("Комната: ")); client.println(db2); client.println("°"); client.println("<br />"); client.println(F("Тёплый пол:")); client.println(db3); client.println("°"); 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(" ")); client.println(d12); client.println("%"); client.println("<br />"); client.println(F("Ca Mg: ")); client.println(" "); client.println(d14); client.println("%"); client.println("<br />"); client.println(F("Fe:")); client.println(F(" ")); client.println(d15); client.println("%"); 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(); } //} } }Вот...
А что написано в строках №№ 116-118?
И где определены используемые там переменные?
В блоке "SIM800" для отправки смс с телеметрией.
Евгений, убегаю на работу, буду ближе к вечеру.
Не понял ответа, в каком блоке, у него номера строк есть? И первая часть вопроса осталась без ответа - что там вообще написано?
Евгений, автор все равно не знает ответа. Давайте я за него.
Мне кажется что строки 116-118 написана по аналогии со строкой 115. То есть, собственно это и есть определение переменных типа String. А что, разве тут ошибка? Скобки, конечно, лишние, а больше никаких проблем не вижу.
Используются эти переменные в строках 397 - 408... в блоке отправки СМС, ныне закомментированном
Вопрос-то был на самом деле такой: "стоит ли напрягаться и пытаться тебе помогать - или тебе только готовый скетч поможет?"
о том, что ТС полный дуп и "программирование не его" - я ему в ветке уже раза три написал. Я уже скорее не ему помогаю, мне просто любопытно, сколько же еще невообразимых ляпов он насажал в этом, нехитром вообще-то, коде...
Не понял ответа, в каком блоке, у него номера строк есть? И первая часть вопроса осталась без ответа - что там вообще написано?
Используются в строках 397-416, 418
Понятно, значит вопрос о том, "что именно там написано" Вы проигнорировали уже во второй раз. Ладно, хозяин - барин.
Присвоение идёт в этих же строках - 397-416
Вы про то что при объявлении не указано что в них?
String s1 = "", s2 = "", s3 = "", s4 = "", s5 = "", s6 = "", s7 = "", s8 = "", s9 = "", s10 = "", s11 = "", s12 = "", s13 = "", s14 = "", s15 = "", s16 = "";
Так правильно?
Вот этот скетч с участием модулей 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("°"); client.println("<br />"); client.println(F("Котёл возврат: ")); client.println(d2); client.println("°"); client.println("<br />"); client.println(F("Тёплый пол подача:")); client.println(d5); client.println("<br />"); client.println(F("Тёплый пол возврат:")); client.println(d6); client.println("°"); client.println("<br />"); client.println(F("Бойлер:")); client.println(d7); client.println("°"); 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("°"); client.println("<br />"); client.println(F("Влажность: ")); client.println(hum); client.println("%"); client.println("<br />"); client.println(F("Атмосф. давление:")); client.println(p); client.println(F("мм.рт.ст.")); client.println("<br /><br />"); client.println(F("Дом:")); client.println(celsius1); client.println("°"); client.println("<br />"); client.println(F("Вход:")); client.println(celsius2); client.println("°"); client.println("<br />"); client.println(F("Гараж:")); client.println(d11); client.println("°"); client.println("<br />"); client.println(F("Котельная:")); client.println(d10); client.println("°"); client.println("<br />"); client.println(F("Скважина:")); client.println(d12); client.println("°"); 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("°"); client.println("<br />"); client.println(F("Комната: ")); client.println(db2); client.println("°"); client.println("<br />"); client.println(F("Тёплый пол:")); client.println(db3); client.println("°"); 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(" ")); client.println(d12); client.println("%"); client.println("<br />"); client.println(F("Ca Mg: ")); client.println(" "); client.println(d14); client.println("%"); client.println("<br />"); client.println(F("Fe:")); client.println(F(" ")); client.println(d15); client.println("%"); 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(); } } }Может модуль этот старый больной?....
Не обманывай себя, Маша, ты беременна...