Вопрос по алгоритму

Сделал пока по своему алгоритму 3 девайса, пишущие в один канал. Публиковать можно не чаще 11 сек. Чтоб не возникло коллизий, у каждого устройства это время разное 15, 19 и 23 сек. Также разная задержка на старте (при одновременном включении) 0, 5 и 10 сек.
Особенность в том, что устройства работают самостоятельно, не зная друг о друге. При отключении или включении каждого устройства, оно вклинивается в очередь и не мешает другим.
Так как каждое устройство перезаписывает данные других полей, то может произойти так, что девайс отвалился, а его данные висят на канале. Для этого сделал чтоб очередные публикуемые данные отличались не менее чем на 0.0015. Если другие девайсы видят чьи то неизменные данные, то просто обнуляют их.
Пару недель отработало, проблем не заметил.

Спойлер
[code]

#include "ThingSpeak.h"
//#include "secrets.h"
#include <ESP8266WiFi.h>
#include <OneWire.h>

#define DEBUG 1  //закоментировать эту строку, если не нужна отладка
#ifdef DEBUG
#define DEBUG_BEGIN(x)     Serial.begin(x)
#define DEBUG_PRINT(x)     Serial.print(x)
#define DEBUG_PRINTLN(x)   Serial.println(x)
#else
#define DEBUG_BEGIN(x) 
#define DEBUG_PRINT(x)
#define DEBUG_PRINTLN(x)
#endif 

#define PERIOD_WRITE_CHENEL 19; //15 сек для первого передатчика, 19, 23 для других 
#define START_DELAY 5 //0 сек для первого, 5 для второго, 10 для третьего
#define FIELD_MODIFY_1 1
#define FIELD_MODIFY_2 2// отсчет с 1, а массив с 0
#define FIELD_MODIFY_3 8//9
#define SECRET_SSID "TP-LINK_123456"    // replace MySSID with your WiFi network name
#define SECRET_PASS "12345678"  // replace MyPassword with your WiFi password
#define CHENEL_ID  1234567 //номер канала thingspeak
#define READ_APIKEY   "UXXXXXXXXXXXXX3"
#define WRITE_APIKEY  "0XXXXXXXXXXXBZ"

OneWire dsAir  (5);//D1  поле 2  (36,6->35) (0->(-0.8)) 
OneWire dsCoop (4);//D2  ПОЛЕ 1  (36,6->36.2)(0->0.125) 

float tempAir, tempCoop; 
char ssid[] = SECRET_SSID;   // your network SSID (name) 
char pass[] = SECRET_PASS;   // your network password
WiFiClient  client;

unsigned int lastSec, setLastSec = PERIOD_WRITE_CHENEL; 

unsigned long channelNumberGH_1 = CHENEL_ID;
const char * readAPIKey = READ_APIKEY;
const char * writeAPIKey = WRITE_APIKEY;
enum {WIFI_START_CONNECT, IS_WIFI_CONNECTED, GET_LAST_DATA_AGE, READ_WRITE_FIELDS, STOP};
int automataStatesEsp = WIFI_START_CONNECT;

String lastSecString;
unsigned long startTimeOutEsp, timeOutMs, periodWriteToChenel = 60000;
int  statusCode = 0;
float valFields[8], prevValFields[8];

void readSensors();  
void runAutomataEsp();
void setTimeOutForNextStep(unsigned long, int);
bool isTimerElapsedEsp();
void setTimeOutEsp(unsigned long);

void setup() {
  DEBUG_BEGIN(115200);
  WiFi.mode(WIFI_STA); 
  ThingSpeak.begin(client);  
  delay(START_DELAY);
}

void loop() {
  readSensors();
  runAutomataEsp();   
} 
//====================================
void runAutomataEsp(){//подкл ВИФИ, читаем lastSec, читаем поля, модифицируем, отправляем, ждем
  switch (automataStatesEsp) {
         
    case WIFI_START_CONNECT: //
      WiFi.disconnect();
      WiFi.begin(ssid, pass);
      setTimeOutForNextStep(10e3, IS_WIFI_CONNECTED);
      DEBUG_PRINTLN("WIFI_START_CONNECT");
      break;
      
    case IS_WIFI_CONNECTED: //
      if(WiFi.status() == WL_CONNECTED){
        setTimeOutForNextStep(1, GET_LAST_DATA_AGE);
        DEBUG_PRINTLN("WIFI_CONNECTED");
      }
      else if( isTimerElapsedEsp()){
        automataStatesEsp = WIFI_START_CONNECT;             
      }    
      break;

    case GET_LAST_DATA_AGE:
      if( isTimerElapsedEsp()){  
        int statusCode = 0;
        lastSecString = ThingSpeak.readRaw(channelNumberGH_1, "/feeds/last_data_age.txt?", readAPIKey);
        statusCode = ThingSpeak.getLastReadStatus();
       // Serial.println("last_sec: " + lastSecString + " second");
        DEBUG_PRINTLN(statusCode);
        if(statusCode == 200){
          lastSec = lastSecString.toInt();
          DEBUG_PRINT("lastSec=");  DEBUG_PRINTLN(lastSec);
          if(lastSec >= setLastSec){
            automataStatesEsp = READ_WRITE_FIELDS;
          }
          else{
            unsigned long timeMs = (setLastSec - lastSec) * 1000UL; //сколько мс до следующего запроса lastSec
            DEBUG_PRINT("timeMs=");  DEBUG_PRINTLN(timeMs);
            setTimeOutEsp(timeMs);//через timeMc код в этом кейсе выполнится снова
          }
        }
        else{
          setTimeOutForNextStep(2000, IS_WIFI_CONNECTED);
        }
      } 
      break;

    case READ_WRITE_FIELDS:
    {
      int error = 0;    
      error = readFields(); //читаем все поля,
      printFields();
      statusCode = ThingSpeak.getLastReadStatus();
      DEBUG_PRINT("statusCode=");  DEBUG_PRINTLN(statusCode);
      DEBUG_PRINTLN();
      if(error == 0){  
        setValFields();//  модифицируем.
        setFields();
        statusCode = ThingSpeak.writeFields(channelNumberGH_1, writeAPIKey);     
        if(statusCode == 200){
          setTimeOutForNextStep(periodWriteToChenel, STOP);//ждем следующую публикацию
          DEBUG_PRINTLN("STOP");
        }
        else setTimeOutForNextStep(2000, IS_WIFI_CONNECTED);
      }
      else setTimeOutForNextStep(2000, IS_WIFI_CONNECTED);
    }      
      break;
    case STOP:
      if( isTimerElapsedEsp()){
         automataStatesEsp = IS_WIFI_CONNECTED;
      }
      break;
  }
}   
//===================================
void setTimeOutForNextStep(unsigned long ms, int nextStep){
  setTimeOutEsp(ms);
  automataStatesEsp = nextStep;
}
//====================== 
 void setTimeOutEsp(unsigned long ms) {
  startTimeOutEsp = millis();
  timeOutMs = ms;
}
//==================
bool isTimerElapsedEsp() {
  if (millis() - startTimeOutEsp > timeOutMs) {
    timeOutMs = 0xFFFFFFFF;//останавливаем таймер
    return 1;
  }
  return 0;
}

//=================================================================
int readFields(){
  float deltaVal;
  int numArr = 0, error = 0;
  static byte countErrorFields[8] = {0};
  for(int i=1; i<=8; i++){   //модифицируемые поля читать не надо 
    if(i==FIELD_MODIFY_1 || i==FIELD_MODIFY_2 || i==FIELD_MODIFY_3) continue;
    numArr = i - 1;
    prevValFields[numArr] = valFields[numArr];
    valFields[numArr] = ThingSpeak.readFloatField(channelNumberGH_1, i, readAPIKey); 
    if(ThingSpeak.getLastReadStatus() != 200) {
      error = 1;
      DEBUG_PRINTLN("error=1");
      setTimeOutForNextStep(2000, IS_WIFI_CONNECTED);
      return error;
    }
    else{
      error = 0;
      if(valFields[numArr] > -0.001 && valFields[numArr] < 0.001){
        valFields[numArr] = 0;
        countErrorFields[numArr] = 0;
      }
      else{
        deltaVal = prevValFields[numArr] - valFields[numArr];
        if(deltaVal > -0.001 && deltaVal < 0.001){//если поле не обновилось
          if( ++countErrorFields[numArr] > 3){
            countErrorFields[numArr] = 0;
            valFields[numArr] = 0;
            prevValFields[numArr] = 0;
          }
        }     
        else{ //если поле обновилось
          countErrorFields[numArr] = 0;
        }
      }
    }
  }
  return error;
}
//===============================================================
void printFields(){
   DEBUG_PRINTLN(valFields[0]);
   DEBUG_PRINTLN(valFields[1]);
   DEBUG_PRINTLN(valFields[2]);
   DEBUG_PRINTLN(valFields[3]);
   DEBUG_PRINTLN(valFields[4]);
   DEBUG_PRINTLN(valFields[5]);
   DEBUG_PRINTLN(valFields[6]);
   DEBUG_PRINTLN(valFields[7]);
}
//=====================================================================
void setValFields(){
  static float delta = 0.0015;
  static byte flag = 0;
  float deltaVal;
  int n1, n2, n3;
  n1 = FIELD_MODIFY_1 - 1;
  n2 = FIELD_MODIFY_2 - 1;
  n3 = FIELD_MODIFY_3 - 1;

  prevValFields[n1] = valFields[n1];
  prevValFields[n2] = valFields[n2];
  prevValFields[n3] = valFields[n3];
  valFields[n1] = mapFloat(tempCoop, 0.125, 36.2, 0, 36.6);// с учетом калибровки
  valFields[n2] =  mapFloat(tempAir, -0.8, 35., 0, 36.6);
  valFields[n3] = millis() / 1000;
  deltaVal = prevValFields[n1] - valFields[n1];
  if(deltaVal > -0.001 && deltaVal < 0.001){
    valFields[n1] += delta;
    flag = 1;
  }
  deltaVal = prevValFields[n2] - valFields[n2];
  if(deltaVal > -0.001 && deltaVal < 0.001){
    valFields[n2] += delta;
    flag = 1;
  }
  deltaVal = prevValFields[n3] - valFields[n3];
  if(deltaVal > -0.001 && deltaVal < 0.001){
    valFields[n3] += delta;
    flag = 1;
  }
  if(flag) { delta *= -1; flag = 0; }
}
//======================================================================
void setFields(){
  int n=0;
  for(int i=1;  i<=8; i++){
    ThingSpeak.setField(i, valFields[n]);
    n++;
  }
}
//=======================================================================
void readSensors(){
  static byte flag = 0;
  static unsigned long periodSensors=0, prevMillis=0; 
  if(millis() - prevMillis >= periodSensors){ 
    DEBUG_PRINTLN("readSensors");
    prevMillis = millis();
    if(flag == 0){
      startConvert(dsAir);
      startConvert(dsCoop);
      flag = 1;
      periodSensors = 800;
    }else{
      tempAir = getTemp(dsAir); 
      tempCoop = getTemp(dsCoop); 
      flag = 0;
      periodSensors = 5200;
    }
  }
}
//=====================================================
void startConvert(OneWire & ds){
  ds.reset(); 
  ds.write(0xCC);
  ds.write(0x44);
}
//=======================================================
float getTemp(OneWire & ds){//возвр. полож. и отрицательную Т
  float t = 0;//При опросе раз в 2 сек Т датчика поднимается на 0.3-0.4С
  uint8_t bufData[9]; 
  ds.reset();     
  ds.write(0xCC);
  ds.write(0xBE);
  ds.read_bytes(bufData, 9); 
  if(OneWire::crc8(bufData, 8) == bufData[8] ) {  // проверка CRC
    t = (int16_t)((bufData[0] | (bufData[1]) << 8)) * 0.0625;  
  }
  else t = -33.33;   // ошибка измерения
  return t;
}
//===============================
float mapFloat(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

[/code]


В библиотеке ThingSpeak файл ThingSpeak.h нужно заменить на тот что ниже.