1 (edited by zelenburg 2017-02-12 17:47:52)

Topic: Проблема операций с системным временем

Добрый день!
конфиг - wemos D1, esp8266, программа включения 4-х нагрузок(светодиоды, много)
-=суть извращения - при включении светодиодов (24шт х 3w) первые 0,00021 сек ток составляет примерно 1500А. контакты обгорают, нужно ограничить пусковой ток - вначале включаем последовательно сначала лампу накаливания, за полсекунды конденсаторы светодиодов заряжаются, а затем включаем 220 напрямую к LED. Искры нет)) профит!
Задача - замыкать предварительную цепь(D9, D8, D7, D6) сразу по команде со смарта,  основная цепь (D5,D4,D3,D2) включается через полсекунды (RequiredDelay).
===КОД===



#define REMOTEXY_MODE__ESP8266WIFI_LIB
#include <ESP8266WiFi.h>
#include <RemoteXY.h>

// настройки соединения
#define REMOTEXY_WIFI_SSID "CapsMan"
#define REMOTEXY_WIFI_PASSWORD "321321321"
#define REMOTEXY_SERVER_PORT 6377
long previousMillis = 0;  //по идее время нажатия кнопки на смарте
long RequiredDelay = 5000;  // по идее время задержки между основной и предварительной цепью

// конфигурация интерфейса 
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
  { 4,0,59,0,6,5,1,2,0,8
  ,8,22,11,2,79,78,0,79,70,70
  ,0,2,0,8,21,22,11,2,79,78
  ,0,79,70,70,0,2,0,8,34,22
  ,11,2,79,78,0,79,70,70,0,2
  ,0,8,47,22,11,2,79,78,0,79
  ,70,70,0 };
 
// структура определяет все переменные вашего интерфейса управления
struct {

    // input variable
  uint8_t switch_1; // =1 если переключатель включен и =0 если отключен
  uint8_t switch_2; // =1 если переключатель включен и =0 если отключен
  uint8_t switch_3; // =1 если переключатель включен и =0 если отключен
  uint8_t switch_4; // =1 если переключатель включен и =0 если отключен

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

  // New variables
} RemoteXY;
#pragma pack(pop)

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

#define PIN_SWITCH_1 D9  // ПРЕДВАРИТЕЛЬНЫЙ ЗАМЫКАТЕЛЬ ПЕРВОЙ ЦЕПИ
#define PIN_SWITCH_2 D8  // ПРЕДВАРИТЕЛЬНЫЙ ЗАМЫКАТЕЛЬ ВТОРОЙ ЦЕПИ
#define PIN_SWITCH_3 D7
#define PIN_SWITCH_4 D6
#define PIN_SWITCH_11 D5  // ОСНОВНОЙ ЗАМЫКАТЕЛЬ ПЕРВОЙ ЦЕПИ
#define PIN_SWITCH_21 D4  // ОСНОВНОЙ ЗАМЫКАТЕЛЬ ВТОРОЙ ЦЕПИ
#define PIN_SWITCH_31 D3
#define PIN_SWITCH_41 D2


void setup()
{
  RemoteXY_Init ();
  Serial.begin(9600);
  pinMode (PIN_SWITCH_1, OUTPUT);
  pinMode (PIN_SWITCH_2, OUTPUT);
  pinMode (PIN_SWITCH_3, OUTPUT);
  pinMode (PIN_SWITCH_4, OUTPUT);
  pinMode (PIN_SWITCH_11, OUTPUT);
  pinMode (PIN_SWITCH_21, OUTPUT);
  pinMode (PIN_SWITCH_31, OUTPUT);
  pinMode (PIN_SWITCH_41, OUTPUT);

  // TODO you setup code
 
}

void loop()
{
  RemoteXY_Handler ();

  previousMillis = millis();
 
  digitalWrite(PIN_SWITCH_1, (RemoteXY.switch_1==0)?LOW:HIGH);
  digitalWrite(PIN_SWITCH_2, (RemoteXY.switch_2==0)?LOW:HIGH);
  digitalWrite(PIN_SWITCH_3, (RemoteXY.switch_3==0)?LOW:HIGH);
  digitalWrite(PIN_SWITCH_4, (RemoteXY.switch_4==0)?LOW:HIGH);

  while(previousMillis + RequiredDelay >= millis())
  {
  }

  Serial.print(previousMillis); Serial.print("  "),
  Serial.println(millis());

  digitalWrite(PIN_SWITCH_11, (RemoteXY.switch_1==0)?LOW:HIGH);
  digitalWrite(PIN_SWITCH_21, (RemoteXY.switch_2==0)?LOW:HIGH);
  digitalWrite(PIN_SWITCH_31, (RemoteXY.switch_3==0)?LOW:HIGH);
  digitalWrite(PIN_SWITCH_41, (RemoteXY.switch_4==0)?LOW:HIGH);

}

===конец кода====
===на мониторинге порта вылетает :

Soft WDT reset

ctx: cont
sp: 3ffef2e0 end: 3ffef4e0 offset: 01b0

>>>stack>>>
3ffef490:  0000001d 3fff066c 3fff031c 3ffee4ac 
3ffef4a0:  3fffdad0 00000000 3ffee380 40201fc8 
3ffef4b0:  feefeffe feefeffe feefeffe 3ffee4ac 
3ffef4c0:  3fffdad0 00000000 3ffee4a4 40203710 
3ffef4d0:  feefeffe feefeffe 3ffee4c0 40100718 
<<<stack<<<
?€И?)Ќю

Это происходит из-за цикла while
Евгений, или кто ещё из знатоков, помогите нубу))))

2

Re: Проблема операций с системным временем

По моему у вас логика построена совсем не так, как задумано.

Както так должно быть:

void setup()
{
  RemoteXY_Init ();
  Serial.begin(9600);
  pinMode (PIN_SWITCH_1, OUTPUT);
  pinMode (PIN_SWITCH_2, OUTPUT);
  pinMode (PIN_SWITCH_3, OUTPUT);
  pinMode (PIN_SWITCH_4, OUTPUT);
  pinMode (PIN_SWITCH_11, OUTPUT);
  pinMode (PIN_SWITCH_21, OUTPUT);
  pinMode (PIN_SWITCH_31, OUTPUT);
  pinMode (PIN_SWITCH_41, OUTPUT);

  // TODO you setup code
  previousMillis_1 = millis();
  previousMillis_2 = millis();
  previousMillis_3 = millis();
  previousMillis_4 = millis();
}

void loop()
{
  RemoteXY_Handler ();
 
  digitalWrite(PIN_SWITCH_1, (RemoteXY.switch_1==0)?LOW:HIGH);
  digitalWrite(PIN_SWITCH_2, (RemoteXY.switch_2==0)?LOW:HIGH);
  digitalWrite(PIN_SWITCH_3, (RemoteXY.switch_3==0)?LOW:HIGH);
  digitalWrite(PIN_SWITCH_4, (RemoteXY.switch_4==0)?LOW:HIGH);

  if (RemoteXY.switch_1==1) { //Проверяем, прошла ли команда на включение со смарта PIN_SWITCH_1
    previousMillis_1 = millis() + RequiredDelay; //Прибавляем к текущему счетчику необходимую задержку
    if (previousMillis_1 <= millis()) { //Ждем когда задержка пройдет
      digitalWrite(PIN_SWITCH_11, (RemoteXY.switch_1==0)?LOW:HIGH);
    }
  }

  if (RemoteXY.switch_2==1) { //Проверяем, прошла ли команда на включение со смарта PIN_SWITCH_2
    previousMillis_2 = millis() + RequiredDelay; //Прибавляем к текущему счетчику необходимую задержку
    if (previousMillis_2 <= millis()) { //Ждем когда задержка пройдет
      digitalWrite(PIN_SWITCH_21, (RemoteXY.switch_2==0)?LOW:HIGH);
    }
  }

  if (RemoteXY.switch_3==1) { //Проверяем, прошла ли команда на включение со смарта PIN_SWITCH_3
    previousMillis_3 = millis() + RequiredDelay; //Прибавляем к текущему счетчику необходимую задержку
    if (previousMillis_3 <= millis()) { //Ждем когда задержка пройдет
      digitalWrite(PIN_SWITCH_31, (RemoteXY.switch_3==0)?LOW:HIGH);
    }
  }

  if (RemoteXY.switch_4==1) { //Проверяем, прошла ли команда на включение со смарта PIN_SWITCH_4
    previousMillis_4 = millis() + RequiredDelay; //Прибавляем к текущему счетчику необходимую задержку
    if (previousMillis_4 <= millis()) { //Ждем когда задержка пройдет
      digitalWrite(PIN_SWITCH_41, (RemoteXY.switch_4==0)?LOW:HIGH);
    }
  }
}

Както так
В данном коде задержка на включение обрабатывается для каждого PIN_SWITCH отдельно
Возможно все упростить, оставить только один PIN_SWITCH команды со смарта и обрабатывать все вместе
Я не знаю деталей задачи

3

Re: Проблема операций с системным временем

Да, в таком варианте выключаться нагрузка не будет smile

Чтобы выключалась надо проверять текущее состояние PIN_SWITCH_1,2,3,4 и отрабатывать изменения
Например так:

  if (RemoteXY.switch_1!=digitalRead(PIN_SWITCH_1)) { //Проверяем, прошла ли команда на включение со смарта PIN_SWITCH_1
    digitalWrite(PIN_SWITCH_1, (RemoteXY.switch_1==0)?LOW:HIGH);
    previousMillis_1 = millis() + RequiredDelay; //Прибавляем к текущему счетчику необходимую задержку
    if (previousMillis_1 <= millis()) { //Ждем когда задержка пройдет
      digitalWrite(PIN_SWITCH_11, (RemoteXY.switch_1==0)?LOW:HIGH);
    }
  }

4

Re: Проблема операций с системным временем

В коде необходимо избегать каких либо задержек. Это неверный стиль программирования.
1. Пока у вас выполняется задержка, что то может случиться и это не будет отработано контроллером.
2. RemotrXY не будет своевременно отрабатывать события связи, как итог - связи не будет или будет паршивая.

Время необходимо проверять в каждом цикле loop.

5

Re: Проблема операций с системным временем

вчера делал проект с применением библиотеки, функции в которой имеет задержку. выяснил что если задержка более 0,25 секунды, то связь обрывается, в итоге поставил задержку в 0,2 секунды, но даже так команда от смартфона до контроллера идет секунд 5.
такой вопрос, обработчик   RemoteXY_Handler ();  находится в главном цикле, можно ли его продублировать в других циклах при необходимости? а то приходится всё делать в главном цикле избегая любых других циклов

6

Re: Проблема операций с системным временем

Используется не задеожка а счетчик таймера, задержек в таком варианте нет

7

Re: Проблема операций с системным временем

Vasiliy wrote:

Используется не задеожка а счетчик таймера, задержек в таком варианте нет

Да. Подход верный. Задержек в цикле loop нет. Хороший пример использования таймера.

  if (RemoteXY.switch_1!=digitalRead(PIN_SWITCH_1)) { //Проверяем, прошла ли команда на включение со смарта PIN_SWITCH_1
    digitalWrite(PIN_SWITCH_1, (RemoteXY.switch_1==0)?LOW:HIGH);
    previousMillis_1 = millis() + RequiredDelay; //Прибавляем к текущему счетчику необходимую задержку
    if (previousMillis_1 <= millis()) { //Ждем когда задержка пройдет
      digitalWrite(PIN_SWITCH_11, (RemoteXY.switch_1==0)?LOW:HIGH);
    }
  }

Но у кода есть некоторые ошибки, не связанные с RemoteXY. Выполнять поставленную задачу к сожалению не будет.

8

Re: Проблема операций с системным временем

mefi73 wrote:

вчера делал проект с применением библиотеки, функции в которой имеет задержку. выяснил что если задержка более 0,25 секунды, то связь обрывается, в итоге поставил задержку в 0,2 секунды, но даже так команда от смартфона до контроллера идет секунд 5.
такой вопрос, обработчик   RemoteXY_Handler ();  находится в главном цикле, можно ли его продублировать в других циклах при необходимости? а то приходится всё делать в главном цикле избегая любых других циклов

RemoteXY_Handler () можно вызывать несколько раз в цикле loop.