1

Topic: Read timeout error, Write error: Broken pipe

Поясните, как избавиться от ошибок: Read timeout error и Write error: Broken pipe

Имеем Arduino_pro_mini + ESP-01. Подключение Enernet через WI-FI
Работа.
Организован цикл 5 сек. В течение первой секунды происходит измерение от датчиков температуры DS18b20, далее вычисление по алгоритму программы и вывод данных по RemoteXY и дальнейшее ожидание до завершение 5 сек цикла.
Функции delay() не использую.
При подключении через USB кабель все работает.
Привожу лог подключения:

        192.168.1.14
       
1    10:20:14.995    App version 4.7.13, API 28
2    10:20:14.995    Device started
3    10:20:14.995    Ethernet connection started
4    10:20:15.000    WiFi network bound (129)
5    10:20:15.000    Connecting to 192.168.1.14:6377...
6    10:20:15.252    Connecting to 192.168.1.14:6377...
7    10:20:15.264    Connection established
8    10:20:15.285    Receiving GUI configuration...
9    10:20:16.288    Read timeout error
10    10:20:16.289    Receiving GUI configuration, try 2 ...
11    10:20:17.291    Read timeout error
12    10:20:17.291    Receiving GUI configuration, try 3 ...
13    10:20:26.440    Read timeout error
14    10:20:26.440    Receiving GUI configuration, try 4 ...
15    10:20:26.464    GUI configuration received
16    10:20:26.474    Receiving variables...
17    10:20:31.477    Read timeout error
18    10:20:31.477    Receiving variables, try 2 ...
19    10:20:36.481    Read timeout error
20    10:20:36.481    Receiving variables, try 3 ...
21    10:20:36.481    Write error: Broken pipe
22    10:20:36.483    Disconnect

На скорости 9600 иногда удается подключиться.
При цикле 2 сек подключиться удавалось на скорости 38400

2

Re: Read timeout error, Write error: Broken pipe

Пришлите ваш скетч

3

Re: Read timeout error, Write error: Broken pipe

Скетч состоит из двух файлов. Второй -это отдельно вынесенные функции. При необходимости добавлю этот второй файл.
Обратите внимание, что если поместить RemoteXY_Handler (); вот таким образом

do
    {    
    RemoteXY_Handler (); //ВНИМАНИЕ!!! ЕСЛИ RemoteXY_Handler (); включить здесь, то программа работает!!!
..........
}

Смотрите в конце скетча. Но это противоречит вашему алгоритму

/*
   -- Kotel Lite_WIFI --
   
   This source code of graphical user interface 
   has been generated automatically by RemoteXY editor.
   To compile this code using RemoteXY library 2.4.3 or later version 
   download by link http://remotexy.com/en/library/
   To connect using RemoteXY mobile app by link http://remotexy.com/en/download/                   
     - for ANDROID 4.5.1 or later version;
     - for iOS 1.4.1 or later version;
    
   This source code is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.
    
 Скетч использует 26162 байт (85%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 1524 байт (74%) динамической памяти, оставляя 524 байт для локальных переменных. Максимум: 2048 байт.

*/  
 
//////////////////////////////////////////////
//        RemoteXY include library          //
//////////////////////////////////////////////

// определение режима соединения и подключение библиотеки RemoteXY 
#define REMOTEXY_MODE__ESP8266_HARDSERIAL

#include <RemoteXY.h>

// настройки соединения 
#define REMOTEXY_SERIAL Serial
//#define REMOTEXY_SERIAL_SPEED 115200
//#define REMOTEXY_SERIAL_SPEED 9600
//#define REMOTEXY_SERIAL_SPEED 19200
#define REMOTEXY_SERIAL_SPEED 38400

#define REMOTEXY_WIFI_SSID "XXXXXXX"
#define REMOTEXY_WIFI_PASSWORD "12345678"
#define REMOTEXY_SERVER_PORT 6377



// конфигурация интерфейса  
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
  { 255,0,0,124,0,123,3,10,13,4,
  130,0,96,50,4,1,1,14,130,0,
  90,38,10,1,1,14,130,0,68,38,
  10,1,1,1,130,1,2,0,96,4,
  2,26,130,1,29,27,24,26,1,17,
  130,1,23,37,6,16,1,17,130,1,
  23,27,6,10,1,17,130,1,3,17,
  15,10,1,17,130,1,18,17,21,10,
  1,17,67,4,7,21,6,5,1,24,
  29,4,67,4,35,36,6,6,1,24,
  29,4,130,1,0,27,23,26,1,17,
  67,4,7,36,6,6,1,24,29,4,
  67,4,14,7,9,6,1,24,29,5,
  129,0,5,17,11,3,1,8,208,146,
  208,176,208,189,208,189,208,176,209,143,
  0,129,0,37,48,5,3,1,8,208,
  151,208,176,208,187,0,129,0,60,34,
  14,2,1,8,208,147,208,190,209,128,
  209,143,209,135,208,176,209,143,32,208,
  178,208,190,208,180,208,176,0,129,0,
  50,60,8,2,1,8,208,146,208,176,
  208,189,208,189,208,176,209,143,32,0,
  129,0,50,56,9,2,1,8,208,154,
  208,190,208,188,208,189,208,176,209,130,
  208,176,0,67,5,59,58,9,5,1,
  24,28,6,67,5,59,53,9,5,1,
  24,29,6,67,5,60,36,9,5,1,
  8,22,6,67,5,90,48,8,5,1,
  24,29,6,129,0,71,45,15,2,1,
  8,208,158,208,177,209,128,208,176,209,
  130,208,186,208,176,32,208,190,208,177,
  209,137,208,176,209,143,0,66,129,68,
  53,22,5,1,9,29,66,129,68,58,
  22,5,1,9,28,129,0,78,22,0,
  3,1,17,0,67,5,83,27,10,5,
  1,24,29,6,130,1,79,24,4,9,
  1,29,129,0,84,24,10,2,1,8,
  208,148,209,139,208,188,208,190,209,133,
  208,190,208,180,0,67,6,60,0,8,
  5,1,33,28,5,67,6,60,5,8,
  5,1,9,29,5,131,1,0,57,8,
  5,1,2,31,49,0,131,0,9,57,
  8,5,2,2,31,50,0,129,0,29,
  17,9,3,1,8,208,154,208,190,209,
  130,208,181,208,187,0,129,0,6,5,
  6,5,1,8,226,152,148,0,129,0,
  41,1,18,2,1,33,71,32,208,191,
  209,128,208,190,208,179,208,189,208,190,
  208,183,44,32,208,188,194,179,47,208,
  188,208,181,209,129,0,68,21,2,4,
  96,51,2,8,2,135,1,5,19,129,
  0,49,7,9,2,1,33,81,44,32,
  208,188,194,179,47,208,188,208,181,209,
  129,0,66,129,68,0,32,5,1,33,
  28,130,1,77,33,14,11,1,17,65,
  14,78,37,12,4,1,129,0,23,5,
  9,6,1,2,32,226,152,128,32,0,
  129,0,15,0,6,7,1,31,226,152,
  129,0,65,14,30,20,7,6,1,67,
  5,95,10,5,3,1,32,13,5,67,
  5,68,10,5,3,1,32,13,5,66,
  129,68,5,32,5,1,9,29,66,129,
  68,48,22,5,1,9,28,67,6,83,
  18,18,3,1,32,161,13,129,0,83,
  14,16,2,1,32,32,208,148,208,189,
  32,45,32,208,167,209,129,32,45,32,
  208,156,208,189,45,208,161,208,181,208,
  186,0,65,12,44,28,8,4,1,129,
  0,30,28,14,2,1,24,208,154,208,
  190,208,189,208,180,208,184,209,134,208,
  184,208,190,208,189,208,181,209,128,0,
  129,0,5,1,12,2,2,2,81,32,
  208,188,194,179,47,208,188,208,181,209,
  129,32,47,49,48,0,129,0,22,1,
  14,2,2,133,208,166,208,184,208,186,
  208,187,208,190,208,179,209,128,208,176,
  208,188,208,188,208,176,0,129,0,40,
  1,17,2,2,1,208,147,208,190,209,
  128,209,143,209,135,208,176,209,143,32,
  208,178,208,190,208,180,208,176,44,194,
  176,67,0,129,0,61,1,9,2,2,
  5,208,163,208,187,208,184,209,134,208,
  176,44,194,176,67,0,129,0,78,1,
  7,2,2,19,208,151,208,176,208,187,
  44,32,194,176,67,0,67,4,74,16,
  8,6,1,27,17,6,67,6,59,16,
  15,6,1,32,17,8,129,0,66,13,
  7,3,1,32,81,44,32,208,188,194,
  179,0,130,0,99,38,1,13,1,14,
  130,0,63,41,1,12,1,1 };
  
// структура определяет все переменные и события вашего интерфейса управления 
struct {

    // output variables
  char text_3[4];  // =строка UTF8 оканчивающаяся нулем 
  char text_1[4];  // =строка UTF8 оканчивающаяся нулем 
  char text_2[4];  // =строка UTF8 оканчивающаяся нулем 
  char text_4[5];  // =строка UTF8 оканчивающаяся нулем 
  char text_7[6];  // =строка UTF8 оканчивающаяся нулем 
  char text_6[6];  // =строка UTF8 оканчивающаяся нулем 
  char text_5[6];  // =строка UTF8 оканчивающаяся нулем 
  char text_8[6];  // =строка UTF8 оканчивающаяся нулем 
  int8_t level_3; // =0..100 положение уровня 
  int8_t level_4; // =0..100 положение уровня 
  char text_9[6];  // =строка UTF8 оканчивающаяся нулем 
  char text_10[5];  // =строка UTF8 оканчивающаяся нулем 
  char text_11[5];  // =строка UTF8 оканчивающаяся нулем 
  float onlineGraph_1_var1;
  float onlineGraph_1_var2;
  float onlineGraph_1_var3;
  float onlineGraph_1_var4;
  float onlineGraph_1_var5;
  int8_t level_11; // =0..100 положение уровня 
  uint8_t led_2_r; // =0..255 яркость красного цвета индикатора 
  uint8_t led_2_g; // =0..255 яркость зеленого цвета индикатора 
  uint8_t led_1_r; // =0..255 яркость красного цвета индикатора 
  uint8_t led_1_g; // =0..255 яркость зеленого цвета индикатора 
  char text_13[5];  // =строка UTF8 оканчивающаяся нулем 
  char text_14[5];  // =строка UTF8 оканчивающаяся нулем 
  int8_t level_1; // =0..100 положение уровня 
  int8_t level_2; // =0..100 положение уровня 
  char text_15[13];  // =строка UTF8 оканчивающаяся нулем 
  uint8_t led_3_r; // =0..255 яркость красного цвета индикатора 
  char text_12_0[6];  // =строка UTF8 оканчивающаяся нулем 
  char text_12[8];  // =строка UTF8 оканчивающаяся нулем 

    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0 

} RemoteXY;
#pragma pack(pop)

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////


#include <TimerOne.h> //прерывания

//Используем  Bounce2, хотя это не обязательно,так как используем сенсорные кнопки TTP223
#include <Bounce2.h>


#include <OneWire.h>


#include <DallasTemperature.h> 
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F,16,2);

///////////////////////////////////////////////////////////////////////////
#include "RTClib.h"//----------Расчет интервалов времени-----------------//
//TimeSpan;        //----------Функция для расчет интервалов времени--------//

int16_t ts ;    // переменная для хранения день, час....................//
uint32_t T_interval ;    // интервал, секунды                            //
uint32_t T_interval_0 ; // начало работы счетчика времени
/////////////////////////////////////////////////////////////////////////
//Кнопка

#define Kn1 7// кнопка  для Pro_mini

#define Signal_HL 9//выход Сигнализация1 (светодиод)для Pro_mini

float GAZ = 6.939;//принято 02.01.2016 для пересчета в м.куб/мес (мес =30.5 дня)
float GAZ_Q; //для пересчета в м.куб/тактб где такт =5 мсек

//Пользовательские символы  /* битовые маски*/

byte char1[8] = {
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B11111,
};

byte char2[8] = {
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B11111,
  B11111,
};

byte char3[8] = {
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B11111,
  B11111,
  B11111,
};

byte char4[8] = {
  B00000,
  B00000,
  B00000,
  B00000,
  B11111,
  B11111,
  B11111,
  B11111,
};

byte char5[8] = {
  B00000,
  B00000,
  B00000,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
};

byte char6[8] = {
  B00000,
  B00000,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
};

byte char7[8] = {
  B00000,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
};

byte char8[8] = { //символ градуса
  B11100,
  B10100,
  B10100,
  B11100,
  B00000,
  B00000,
  B00000,
  B00000,
};

#define ONE_WIRE_BUS 3// Датчики к 3 входу Pro mini

OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

DeviceAddress Thermometer1 = {// "зал",  (28 FF F5 3D 63 15 02 07)
  0x28, 0xff, 0xf5, 0x3d, 0x63, 0x15, 0x02, 0x07
}; 

DeviceAddress Thermometer2 = { // "ПК",  (28 FF 4C 54 63 15 02 B8)//
  0x28, 0xff, 0x4c, 0x54, 0x63, 0x15, 0x02, 0xb8
}; 

DeviceAddress Thermometer3 = { // "ванная",  ( 28 FF 3B 43 63 15 03 64)

  0x28, 0xff, 0x3b, 0x43, 0x63, 0x15, 0x03, 0x64
}; 
DeviceAddress Thermometer4 = { // "Улица",  (28 FF 11 40 63 15 03 A9)
  0x28, 0xff, 0x11, 0x40, 0x63, 0x15, 0x03, 0xa9
}; 

DeviceAddress Thermometer5 = { // "горячая вода"  0x28, (28 ff f0 53 63 15 02 50)
  0x28, 0xff, 0xf0, 0x53, 0x63, 0x15, 0x02, 0x50
}; 

DeviceAddress Thermometer6 = { // "обратка в комнатеа", датчик DS18B20 (28 c8 42 e7 03 00 00 61)
  0x28, 0xc8, 0x42, 0xe7, 0x03, 0x00, 0x00, 0x61
}; 

DeviceAddress Thermometer7 = {  // "обратка в ванной",  (28 FF 5E 42 63 15 03 28)
  0x28, 0xff, 0x5e, 0x42, 0x63, 0x15, 0x03, 0x28
}; 

DeviceAddress Thermometer8 = { // "обратка  котел"  (28 ff a1 3c 63 15 02 02)
  0x28, 0xff, 0xa1, 0x3c, 0x63, 0x15, 0x02, 0x02
}; 

DeviceAddress Thermometer9 = { // "дымоход", датчик  (28 ff 4b 42 63 15 03 86)
  0x28, 0xff, 0x4b, 0x42, 0x63, 0x15, 0x03, 0x86
}; 

unsigned long currentMillis;//текущее время
unsigned long previousMillis;// "текущее время предыдущего цикла" для расчетов
//unsigned long print_previousMillis;//текущее время для печати
unsigned long index_time = 0;// число измерительных главных циклов от начала запуска программы (то же самое, что текущее время программы)
unsigned long Summa_time_OGO_1 = 0;    //счетчик циклов времени, работает когда котел включен
unsigned long index_kalibr = 0;// число измерительных главных циклов от начала Калибровки
unsigned long Summa_time_OGO_1_kalibr = 0;    //счетчик циклов времени, работает когда котел включен от начала калибровки
unsigned long Summa_temp; // временная переменная

const unsigned long OnTime = 5000; // длительность одного полного цикла измерения 5000 мсек(33 коррекция на частоту кварца)
unsigned long delta; //длительность рабочего цикла программы (все остальное ожидание завершения 5 сек)
int flag; //флаг цикла, =0 при выполнении внутри главного цикла, если =1 то переход к началу следующего главного цикла

//Массив
float Mass[16] = {0};         // массив для хранения прмежуточных значений температуры
//Mass[0] температура текущего датчика 1...9
//Mass[1] ...Mass[8] для хранения средних значений температуры
//Mass[9]хранит данные "дымоход" от предыдущего замера
//среднее датчика "дымоход" не сохраняются
float Cels[10] ;//температура текущего датчика 0...8 ;    [9]- хранит данные "дымоход" от предыдущего замера

float M_OGO[16] ; //[3...15] архивные значений K_OGO -(м3/мес);[3]- K_OGO_sredii (м3/мес);[0]- текущее значение K_OGO(м3/мес);
// M_OGO[1]- температура горячей воды в радиаторах (t5_горячая вода + t6_обратка в комнате)/2   усредненная за период Калибровки
// M_OGO[2] температурный напор(t1_зал - t4_улица) усредненый за период Калибровки

float g_1;                 //скорость изменения температуры "дымохода" - град/сек
float DT_1 = 0.2;         //пороговая скорость град/сек при нагреве котла
float DT_0 = -0.2;        //пороговая скорость град/сек при охлаждении котла
float K_OGO = 0;         //"Коэффициент загрузки котла"
float K_OGO_sredii = 0; //усредннный за период работы программы "Коэффициент загрузки котла",
float K_OGO_kalibr = 0; //"Коэффициент загрузки котла" при Калибровки

int flag_OGO = 0;        // флаг котла, 0 - при охлаждени и 1 при нагреве котла
int print_OGO = 0;         //флаг для записи данных и вывод информации (1- вывод)

int time_OGO_1 = 0;    //счетчик циклов времени, работает когда котел включен в течении одного цикла
int time_OGO_0 = 0;    //счетчик циклов времени, работает когда котел отключен в течении одного цикла
//int OGO_line = 7;        //начальная строка с которой начинается ввод данных в таблицу сводных параметров

//флаги для вывода на экран lcd

int status_kalibr = false ;//калибровка отключена
int status_alarm = 0;//сигнализация отключена
//int menu =true;//флаг МЕНЮ_0
int Zima_Leto; //Zima_Leto = температура горячей воды (граница Зима/Лето)

int N_OGO = 0;    //счетчик числа измерений K_OGO
//int N_data = 170;// В теле симулятора данных
int Os_0 = 180;  // "0%" шкалы  (180 м3/час-мес)
int Os_1 = 420;  // "100%" шкалы (420 м3/час-мес)
char Znak[2];// хранит полуотсчеты ординат графика

// ---------Кнопки, меню-----------

Bounce knopka1 = Bounce();// Bounce () — инициализация объекта Bounce под именем "knopka1"

const unsigned long pressed_long = 2000; // долговременное нажатие = 2 секунды
const int num_modes = 2; // максимальный номер режима (0,1,2)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
//short int max_mode = num_modes + 1; // вспомогательная переменная
unsigned long pressed_moment; // момент нажатия кнопки
int current_mode = 0; // текущий режим

//---------------Сигнализация-------------------
int takt = true;//номер такта: 0,1


 //--------------Уровень=0..100 положение уровня ---------//
int va_1;
int Qmin =150; // начало шкалы (0%) = 150 м.куб/месяц
int Qmax =450; // конец шкалы (100%) = 450 м.куб/месяцп

float Q_temp; //временная переменная

void setup() {
    
    
     RemoteXY_Init (); 
  //Уровень=0..100 положение уровня 
  
  RemoteXY.level_1 = 1; 
  RemoteXY.level_2 = 1; 
  RemoteXY.level_3 = 1;
  RemoteXY.level_4 = 1;
 

        //-------------------Определим точность измерения температуры--------------//
  sensors.setResolution(Thermometer1, 10); //t1 - зал
  sensors.setResolution(Thermometer2, 10);  //t2 - ПК
  sensors.setResolution(Thermometer3, 10);  //t3 - ванная
  sensors.setResolution(Thermometer4, 10);  //t4 - улица

  sensors.setResolution(Thermometer5, 10);  //t5 - горячая вода
  sensors.setResolution(Thermometer6, 10);  //t6 - обратка в комнате
  sensors.setResolution(Thermometer7, 10);  //t7- обратка в ванной
  sensors.setResolution(Thermometer8, 10);  //t8 - обратка  котел

  sensors.setResolution(Thermometer9, 11);  //t9 - дымоход (11 бит, повышенная точность)

  lcd.init();   // initialize the lcd_I2C для Pro_mini
  
    lcd.backlight();//Включение подсветки дисплея.
    
   
   // ---------Регистрируем и запиваем свои пользовательские символы в память LCD ---------------//
  lcd.createChar(1, char1); 
  lcd.createChar(2, char2);
  lcd.createChar(3, char3);
  lcd.createChar(4, char4);
  lcd.createChar(5, char5);
  lcd.createChar(6, char6);
  lcd.createChar(7, char7);
  lcd.createChar(8, char8); //градус


pinMode(Kn1,INPUT);//настраивает pin , INPUT
digitalWrite(Kn1, HIGH);
 
knopka1.attach(Kn1);// устанавливает пин, к которому подключена кнопка и подключает на этом выводе встроенный подтягивающий резистор

knopka1.interval(5); // устанавливает время антидребезга в миллисекундах

pinMode(Signal_HL, OUTPUT); //
digitalWrite(Signal_HL, HIGH);//Включаем светодиод

Zima_Leto =25;// Zima_Leto = температура горячей воды (граница Зима/Лето)

GAZ_Q = float (GAZ *100 / 527040); //м.куб/такт есть цена одного 5 мс такта в м.куб

T_interval_0 = millis();// фиксация текущего времени в милисекундах запуска программы
previousMillis = T_interval_0;

}

  void loop()  {
     
     RemoteXY_Handler ();
     
//-------------------------- Сигнализация-------------------------------------
   
  if(flag_OGO ==true){//При ВКЛЮЧЕНИИ КОТЛА  мигает светодиод
  
  Timer1.initialize(500000); // set a timer of length 0.5 сек (500000) microseconds (or 0.1 sec - or 10Hz) 
  Timer1.attachInterrupt( timerIsr ); // timerIsr - Функция запускаемая при прерывании
  }
  else {Timer1.attachInterrupt(timerIsr_0);//
  }
//--------------------------END Сигнализация------------------------------------- 


  if (current_mode == 0)  {   //"Температура" -ГАСИМ значек "/"
     lcd.setCursor(2,1);
   lcd.print(" ");//значек " "
   }
  
  if (current_mode == 1)  {   //"Параметры котла" -ГАСИМ значек "/"
     lcd.setCursor(10,1);
   lcd.print(" ");//значек " "
   }
    
    
    //----------------СТАРТ подпрограммы измерения температуры
  
    sensors.requestTemperatures();    //Перевести все датчики в режим измерения температуры
  
  Cels[1] = Celsius(Thermometer1);
  Cels[2] = Celsius(Thermometer2);
  Cels[3] = Celsius(Thermometer3);
  Cels[4] = Celsius(Thermometer4);
  Cels[5] = Celsius(Thermometer5);
  Cels[6] = Celsius(Thermometer6);
  Cels[7] = Celsius(Thermometer7);
  Cels[8] = Celsius(Thermometer8);
  //Cels[9] = Celsius(Thermometer8);// используеться как переменная для расчетов далее
  
  Cels[0] = Celsius(Thermometer9);// в ячейку "0"
    

    ////////////////////////////////////////////////////////////////////////
    //----------- Вывод текущей температуры RemoteXY----------------------//
    ///////////////////////////////////////////////////////////////////////
    
  
    dtostrf(Cels[1],2,0,RemoteXY.text_1); 
      
    dtostrf(Cels[2],2,0,RemoteXY.text_2);   
      
    dtostrf(Cels[3],2,0,RemoteXY.text_3);   
      
    dtostrf(Cels[4],3,0,RemoteXY.text_4);   
      
    dtostrf(Cels[5],4,1,RemoteXY.text_5);   
      
    dtostrf(Cels[6],4,1,RemoteXY.text_6);

    dtostrf(Cels[7],4,1,RemoteXY.text_7);
  
    dtostrf(Cels[8],4,1,RemoteXY.text_8);

    dtostrf(Cels[0],5,1,RemoteXY.text_9); 
    
  //****************************Контроль ЗИМА-ЛЕТО или погасание котла**********************************//
  // ***Если температура горячей воды меньше чем 25 градусов, значит  Котел не греет = ( ЛЕТО или погас)/********//
  
  if (Cels[5] < Zima_Leto) { // Котел не греет, значит ЛЕТО или погас
  RemoteXY.led_1_r = 0;// цвет фона, темный
  RemoteXY.led_1_g = 0;//
  }
  else {
  RemoteXY.led_1_r = 125;// желтый цвет
  RemoteXY.led_1_g = 125;//
  }

        ////---Сигнализация для RemoteXY --------------------//
  if (flag_OGO ==true) {// При ВКЛЮЧЕНИИ КОТЛА  мигает светодиод
    RemoteXY.led_2_r = 255;// тогда включаем красный цвет индикатора
  RemoteXY.led_2_g = 0;
  }// 
  else {                       // иначе
    RemoteXY.led_2_r = 0;     // 
  RemoteXY.led_2_g = 255;   //включаем зеленный цвет индикатора
  }

///////////////////////////////////////////////////////
//***************Расчеты*****************************//
/////////////////////////////////////////////////////////

  //--------------хранит в памяти сумму температур----------------------------

  for(int j=1; j <9; j++) {//хранит в памяти сумму температур для расчета средних

  Mass[j-1] = Cels[j] + Mass[j-1];  //Mass[0...7] 
    
}

    //------------------------------ВЫДЕЛЕНИЕ особых точек---------------------------------------------
  
  if (index_time == 0)  {    //начальный цикл
      Cels[9] = Cels[0];  //запись начального значения до начала расчетов
    }
    
    g_1 = (Cels[0] - Cels[9])/5;  //Первая производная - скорость изменения температуры град/сек (5 это время между циклами, сек)

    Cels[9] = Cels[0];    //сохранили текущую температуру "дымоход" в ячейке массива

    //------------------------Установка флага flag_OGO по параметру DT---------------------------------

    if (g_1 >= DT_1)  {    //котел включен
      flag_OGO = true;
    }

    if (g_1 <= DT_0)   {    //котел отключен
      flag_OGO = false;
    }
  
    //-----------------------------считаем число циклов в течении которого котел включен/отключен---------

    if (flag_OGO == true) {      //котел включен / Калибровка
      time_OGO_1++  ;            //счетчик циклов времени, работает когда котел включен в течении одного цикла нагрев/охлаждение
    Summa_time_OGO_1 ++ ;   // число измерительных главных циклов (5 мс) от начала старта когда котел включен
    
    if (status_kalibr == true) {  //Калибровка 
    Summa_time_OGO_1_kalibr ++;//счетчик циклов времени, работает когда котел включен от начала калибровки
    }

    }
    
    //----------------------------Расчет среднего значения "коэффициента загрузки котла" / Калибровка --------------
    index_time++ ;
    K_OGO_sredii =  100.0 * Summa_time_OGO_1 / index_time ;
    
    if (status_kalibr == true) {  //Калибровка 
    
    M_OGO[1] =M_OGO[1]*index_kalibr;//сумма температура горячей воды в радиаторах предыдущего цикла
    M_OGO[1] = M_OGO[1] + (Cels[5] + Cels[6])/2; //температура горячей воды в радиаторах
    M_OGO[2] =M_OGO[2]*index_kalibr;//сумма температурных напоров предыдущего цикла
    M_OGO[2] = M_OGO[2] + (Cels[1] - Cels[4]); //сумма температурных напоров = (t_зал - t_улица)
        
    index_kalibr++;//считает время работы в режиме Калибровка
    M_OGO[1] = M_OGO[1]/index_kalibr; //dR - средняя температура горячей воды в радиаторах
    M_OGO[2] = M_OGO[2]/index_kalibr; //dT - средний температурный напор (t_зал - t_улица)
    
    K_OGO_kalibr = 100.0 * Summa_time_OGO_1_kalibr / index_kalibr; //K_OGO_sredii за период калибровки
        }
    else {// обнулить 
      Summa_time_OGO_1_kalibr = 0;
      index_kalibr = 0;
      M_OGO[1] = 0;
      M_OGO[2] = 0;
      }
    if (flag_OGO == false)    {      //котел отключен
    time_OGO_0++  ;       //увеличиваем счетчик на +1

    print_OGO = true;      //флаг разрешения печати в момент включения котла
    }
    

  //------------------------------------ РАСЧЕТЫ ЗА ЦИКЛ (нагрев/охлаждение) работы котла-----------------------------------
  
    if ((flag_OGO && print_OGO) == true) {     //котел включен, печать разрешена в com порт

       
    time_OGO_0 = time_OGO_1 + time_OGO_0; //счетчик - число измерений на однин рабочий цикла котла (нагрев+охлаждение)
    
    K_OGO = 100.0 * time_OGO_1 / time_OGO_0 ; //"Коэффициенте загрузки котла" , нормирован на 100%
    
     //-------------------------средняя температура по датчикам (зо один цикл работы котла---------------------
   
  for(int j=0; j <8; j++) {//сумму температур / время цикла

  Mass[j] = Mass[j] / time_OGO_0; //расчет среднего значения
  Mass[j+8] = Mass[j];  //сохранить среднее в Mass[8] = Mass[15]для вывода на lcd
  
  }
     
    //-------------------- ЗАПИСЬ в массив архивных данных- K_OGO------------------------
    
    M_OGO[0] = K_OGO * GAZ;//м3/мес
        
     if(N_OGO < 13){// запись в массив архивных данных
    
    M_OGO[3+N_OGO] = M_OGO[0];// данные вводятся в ячейки с 3...11(всего 13 ячеек)
    }
    else
    { //при достижении правого края: сдвиг экрана влево с 4 по 16 позиции и печать в крайнию праввую ячейку данных
    for(int j=3; j <15; j++) {

    M_OGO[j] = M_OGO[j+1]; //сдвиг ячеек справа -налево и 
    }
    M_OGO[15] = M_OGO[0]; // 
}
    //-----------------флаги и счетчики по завершению цикла------------------------
  
    for(int j=0; j <8; j++) {//обнулить счетчики суммы температур [0...7]
    Mass[j] = 0;
    }
     
 // OGO_line++ ;// переход к следующей строке
  time_OGO_0 = 0;
  time_OGO_1 = 0;

  print_OGO = false; //печать только в течении одного цикла
  N_OGO++ ; //счетчик числа измерений K_OGO ("Коэффициента загрузки котла" ). 
 
  }
    /////////////////////////////////////////////////////////////////////
    //------------окончание цикла  РАСЧЕТЫ ЗА ЦИКЛ   ////////////////////
    /////////////////////////////////////////////////////////////////////
  
  M_OGO[3] = K_OGO_sredii * GAZ;// Перезапись в ячейку данных с затиранием "0" отсчета
   
   ////////////////////////////////////////////////////////////////////////////////////////////
   //--------------Q м.куб/мес нормируем 0..100 делений графического ндикатора(уровень)------//
   ////////////////////////////////////////////////////////////////////////////////////////////
 
 
  va_1 = int(M_OGO[3]);
  va_1 = constrain(va_1, Qmin, Qmax);
    va_1 = map(va_1, Qmin, Qmax, 1, 100);
      RemoteXY.level_11 = va_1; // Средний расход
  
  va_1 = int(M_OGO[4]);
  va_1 = constrain(va_1, Qmin, Qmax);
    va_1 = map(va_1, Qmin, Qmax, 1, 100);
      RemoteXY.level_1 = va_1; // текущий расход газа
  
  ////////////////////////////////////////////////////////////////////////////////
 //-------Графический индикатор температуры в обратке системы отопления-----------//
 ///////////////////////////////////////////////////////////////////////////////////
 
 va_1 = int(Cels[8]);//температура обратки общая
  va_1 = constrain(va_1, 0,60);//температура обратки общая от 0 до 60 град
    va_1 = map(va_1, 0, 60, 1, 100);
      RemoteXY.level_2 = va_1; //температура обратки общая
 
 
  va_1 = int(Cels[6]);//температура обратки в комнате
  va_1 = constrain(va_1, 0,60);//температура обратки общая от 0 до 60 град
    va_1 = map(va_1, 0, 60, 1, 100);
      RemoteXY.level_3 = va_1; //температура обратки в комнате
 
  va_1 = int(Cels[7]);//температура обратки в ванной
  va_1 = constrain(va_1, 0,60);//температура обратки общая от 0 до 60 град
    va_1 = map(va_1, 0, 60, 1, 100);
      RemoteXY.level_4 = va_1; //температура обратки в ванной
 
            
//--------------Строки--------------------------//
  
  dtostrf(M_OGO[3],3,0,RemoteXY.text_10); //Прогноз расход (средний расход от начала измерений)
  dtostrf(M_OGO[0],3,0,RemoteXY.text_11); //текущее расход

  
  // Печать Легенды ( Qmin и Qmax)
  
  itoa(Qmax,RemoteXY.text_13, 10);
  
  itoa(Qmin, RemoteXY.text_14,10);
  

    /////////////////////////////////////////////////////////////////////////////////
    // ----------------------Считаем объем газа ----------------------------------//
    //////////////////////////////////////////////////////////////////////////////

        // печать целой части с одним знаком после запятой
    Summa_temp = Summa_time_OGO_1;//
        float Q_temp = Summa_temp * GAZ_Q;
        
unsigned long q_temp = Q_temp *1000; //       12345
    int Zeloe = q_temp/1000; // 12345/100 =12, остаток 345
    int Z2_3 =q_temp%1000; // временное хранение остатка 345     
    int    Z1 = Z2_3/100 ; // 345/10 =3, остаток 45
        Z2_3 =Z2_3%100; // = 45

    sprintf(RemoteXY.text_12,"% 4d.%1d", Zeloe,Z1); //123.1
    
    sprintf(RemoteXY.text_12_0,"%-02d",Z2_3); //23



        
 ///////////////////////////////////////////////////////////
   //--------------Графика-------------------------------//
   /////////////////////////////////////////////////////////
 
  RemoteXY.onlineGraph_1_var1 = M_OGO[0]/10.0; // текущий расход масштабируем шкалу на 10
  //RemoteXY.onlineGraph_1_var2 = 20.0; // пока не определена
  
  RemoteXY.onlineGraph_1_var3 = Cels[5]; // горячая вода масштабируем шкалу на 10
  RemoteXY.onlineGraph_1_var4 = Cels[4]; //улица
  RemoteXY.onlineGraph_1_var5 = Cels[1]; // зал
  
  
//////////////////////////////////////////////////////////////////////////  
//********************LCD***********************************************//
/////////////////////////////////////////////////////////////////////////

//--------------------МЕНЮ_0 (ЭКРАНЫ lcd) ------------------------------//

// current_mode == 0, 1 и 2
  
  if(current_mode == 0)  { //ekran0 "Температура"
  
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(Cels[1],0); //"зал"
  lcd.print("\10 ");//значек "градуса"
  lcd.print(Cels[2],0); //"ПК"
  lcd.print("\10 ");
  lcd.print(Cels[3],0); //"ванная"
  lcd.print("\10 ");
  lcd.print(Cels[4],0); //"улица")
  lcd.print("\10");
  
  lcd.setCursor(0, 1);
  lcd.print(Cels[5],0);//горячая вода
  lcd.print("/");
  lcd.print(Cels[6],0); //"обратка в комнате" (среднее)
  lcd.print("\10");
  lcd.setCursor(7,1); 
  lcd.print(M_OGO[0],0);//"K_OGO м3/мес"
  lcd.setCursor(10, 1);
  lcd.print("month"); //месяц --Отключен русский текст  lcd.print("\2743/\274ec");  //м3/мес"{188,51,47,188,101,99,'\0'}; //м3/мес
  
  }

  if (current_mode == 1)  { // ekran1 "Параметры котла"
   
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(Mass[12],1);  //"горячая вода" (среднее)
  lcd.print("\10");//значек "градуса"
  lcd.setCursor(6,0); 
  lcd.print(Cels[0],1); //температура  "дымоход"
  lcd.print("\10");
  lcd.setCursor(11,0); 
  lcd.print("k");
  lcd.print((K_OGO),1);
    
  lcd.setCursor(0, 1);
  lcd.print(Mass[13],1);  //"обратка в комнате" (среднее)
  lcd.print("\10");//значек "градуса"
  lcd.print(Mass[14],1);  //""обратка в ванной" (среднее)
  lcd.print("\10");//значек "градуса"
  lcd.setCursor(10, 1);
  lcd.print("/");
  lcd.print(Mass[15],1);  //"обратка котел" (среднее)
  lcd.print("\10");//значек "градуса"
} 
    
  
  if (current_mode == 2)  { //ekran2 "Потребление газа в месяц"
  
  lcd.clear();
  for(int i=3; i<16; i++){
  Zn(M_OGO[i],Os_0, Os_1,Znak);//(в массив Znak[] возвращаются ординаты для верхней и нижней строки (K_OGO в м3/мес)
  
  lcd.setCursor(i,0);
  lcd.print(Znak[0]); 
  
  lcd.setCursor(i,1);
  lcd.print(Znak[1]); 
    }
  lcd.setCursor(0,0);//текущий K_OGO
  lcd.print(M_OGO[0],(0)); 
  
  lcd.setCursor(0,1);
  lcd.print( M_OGO[3],(0)); //K_OGO_sredii
} 
    
  do
    {    
    //RemoteXY_Handler (); //ВНИМАНИЕ!!! ЕСЛИ RemoteXY_Handler (); включить здесь, то программа работает!!!
    //yield();
    
  // --------------МЕНЮ для knopka1---------------------------------

  if (knopka1.update()) {//если произошло событие
  
    if (knopka1.read()== 1) //если кнопка нажата mode_knopka =1, для TTP223
    {
    pressed_moment = millis(); // запоминаем время нажатия
    
    }
    else { // кнопка отпущена
     
      if((millis() -pressed_moment) <pressed_long)  // если кнопка была нажата кратковременно
      {
     
      current_mode++; // увеличиваем счетчик текушего режима
       if (current_mode >= (num_modes+1)) current_mode = 0;
     
    lcd.backlight();// Подсветка включена  
    }
    else{ // кнопка удерживалась долго          
       
    lcd.noBacklight();//Подсветки дисплея отключена
    pressed_moment = 0; // обнуляем момент нажатия
    }
    
  }
 }


    currentMillis = millis(); // текущее время в миллисекунд
    
  }
  while ((currentMillis -previousMillis) < OnTime); //если меньше,то повтор этого цикла до достижения 5000 мс
   // while ((currentMillis -previousMillis) < 2000); //отладка111
//---------Вывод времени работы от запуска RemoteXY-------------//
  //T_interval = millis();// мсек
  T_interval = (currentMillis - T_interval_0)/1000; //Продолжительность работы программы, сек
  
    TimeSpan(ts)=T_interval;
    sprintf (RemoteXY.text_15, "%02d-%02d-%02d-%02d", ts.days(),ts.hours(),ts.minutes(),ts.seconds());//текстовая строка  
  previousMillis = currentMillis;
  }

4

Re: Read timeout error, Write error: Broken pipe

Понятно.
Во всех рекомендациях не применять delay () имеется ввиду как раз то что у вас не должно быть задержек в основном цикле loop () что бы  RemoteXY_Handler () вызывался как можно чаще. Если он вызывается как у вас один раз в 5 секунд, то и связь у вас так же обрабатывается один раз в 5 секунд, и конечно же обрывается по таймауту.
Вы просто вместо delay () написали свой, но суть от этого не поменялась.
Или измените программу, или добавьте в ваш цикл ожидания вызов RemoteXY_Handler ().

uint32_t time = 0;
void loop () {
  RemoteXY_Handler ();
  if (millis () - time  >= 5000) {  // вызываем нашу задачу каждые 5 секунд
    time = millis ();
    my_task_handler ();
  }
}

или так

uint32_t time;
void loop () {
  RemoteXY_Handler ();
  time = millis ();
  my_task_handler ();

  while (millis () - time  < 5000) {  // ждем когда закончатся 5 секунд но вызываем обработчик RemoteXY
    RemoteXY_Handler ();
  }
}

5

Re: Read timeout error, Write error: Broken pipe

1.По сути, ниже приведенная конструкция  это второй пример в вашем ответе.
   Вызываем обработчик RemoteXY_Handler () в коде ожидания до завершения 5 секундного цикла

  void loop()  {

 // Код программы
 ....................
 //Ожидание завершения программы
 do
    {    
    RemoteXY_Handler (); 
    
  // Обработчик кнопок---
    
  }
   while (millis () - time  < 5000)
  
}

2. my_task_handler (); - поясните про эту функцию

Спасибо за быстрый ответ

6

Re: Read timeout error, Write error: Broken pipe

Внес в скетч изменения вот такого типа

uint32_t time;
void loop () {
  RemoteXY_Handler ();
  time = millis ();
  my_task_handler ();

  while (millis () - time  < 5000) {  // ждем когда закончатся 5 секунд но вызываем обработчик RemoteXY
    RemoteXY_Handler ();
  }
}

Ардуино подключился на скорости 115200 бод
Респект!

7

Re: Read timeout error, Write error: Broken pipe

Ранее в топике

bukinay1 wrote:

Выложите, как пример для "новой" библиотеки, подключение для двух потоков
на модулях ESP8266 Wi-Fi и модуле HM-10  для кнопки Button

был приведен пример добавления модуля HM-10 к WI-FI соединению.
После того, как удалось запустить, по приведенной рекомендации, Arduino Pro mini с ESP-01 на скорости 115200 бод решил добавить модуль блютуз HM-10. Добавил строчку в код

void setup() {
  RemoteXY_Init ();
  remotexy->addConnection (new CRemoteXYStream_SoftSerial (10,11, 9600));  // added line, RX, TX, Speed
}

При компиляции скетча получил сообщение об ошибке.

exit status 1
expected type-specifier before 'CRemoteXYStream_SoftSerial'

Что сделано неверно?

8

Re: Read timeout error, Write error: Broken pipe

Если вы хотите использовать SoftSerial, то вам необходимо подключить библиотеку SoftwareSerial перед подключением RemoteXY:

#include <SoftwareSerial.h>
#include <RemoteXY.h>