Использование mills() вместо задержки() на реле, не обеспечивающих надежное переключение

Я знаю, что мне следует опубликовать некоторый код, который, возможно, будет чище, но на самом деле мне просто нужен ответ на проблему, с которой я часто сталкиваюсь при использовании mills() вместо >delay(), создавая рождественскую гирлянду.

Может быть, это я, но у меня не происходит постоянного переключения механических реле, когда я пытаюсь использовать время mills() для переключения реле. Мне кажется, что код отключает реле, а затем отключает реле за миллисекунды и на самом деле не фиксирует реле, как я получаю с помощью delay(). Такова ли природа выбора mills(), когда вывод запускается в каждом цикле, но на самом деле не является выводом в течение всего цикла процесса? Теперь, если это правда, то есть ли хороший способ зафиксировать реле без использования delay()?

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
//


  unsigned long currentMillis = millis();
  unsigned long previousMillis = millis();
  int interval_on = 2000; // Продолжительность времени включения

  unsigned long currentMillis_off = millis();
  unsigned long previousMillis_off ;
  int interval_off = 2000; // продолжительность перерыва

//
#define button 4
int Lite_1=0;


RF24 radio(7, 8); // CE, ДНС

const byte address[6] = "00001";
boolean buttonState = 0;

unsigned long time;

void setup() {
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
  Serial.begin(9600);
}

void loop() {
  unsigned long currentMillis = millis();        // должно быть в цикле
   unsigned long currentMillis_off = millis();  // Должно быть в цикле
  // const char text[] = "Привет, мир";
 // radio.write(&text, sizeof(text));
  //задержка(1000);

   // задержка(5); Удален, чтобы помочь в выборе времени.
   // radio.stopListening(); удалено, чтобы помочь в выборе времени
   // Lite_1 = 1;
    radio.write(&Lite_1, sizeof(Lite_1));
  // задержка(1000) ;
 // Lite_1 = 0;
 // radio.write(&Lite_1, sizeof(Lite_1));
  // задержка(250);



  if (Lite_1 == 0 && currentMillis - previousMillis > interval_off) 
    {
    previousMillis = currentMillis;
    previousMillis + 10;
    previousMillis_off = currentMillis_off  ;
    Lite_1 = 1;
    Serial.println(currentMillis);    // печатаем время с момента запуска программы
      }
    //Отлаживать
  // Serial.print("Время: ");
 // time = millis();

 // Serial.println(время); // печатаем время с момента запуска программы
// Serial.println(currentMillis); // печатаем время с момента запуска программы
// Serial.println(предыдущийМиллис); // печатаем время с момента запуска программы
// Serial.println(предыдущийMillis_off); // печатаем время с момента запуска программы
 // Serial.println(currentMillis_off); // печатаем время с момента запуска программы
  //задержка(250);


    if (Lite_1==1 && currentMillis_off - previousMillis_off > interval_on) 
       {
    previousMillis_off = currentMillis_off;
    previousMillis = currentMillis;
    previousMillis + 10;
    Lite_1 = 0;
    Serial.print("OFF: ");
    Serial.println(previousMillis_off);    // печатаем время с момента запуска программы
    }

  }

, 👍-1

Обсуждение

Правильно отформатируйте свой код, отредактировав вопрос, выбрав код и нажав кнопку {} на панели инструментов редактора или нажав Ctrl+k на клавиатуре., @chrisl

В какой части кода вы переключаете реле? Я не вижу функции digitalWrite() или чего-то подобного, с помощью которого можно было бы что-то переключить. Только последовательный выход., @chrisl

Что ему делать? Это включение реле на полсекунды с паузой в 2 секунды? Это непрерывно или вызвано каким-то событием? Пожалуйста, добавьте дополнительную информацию к вашему вопросу., @Jot

Рон, ты не сможешь отвечать на комментарии, пока не зарегистрируешься на SE. Проверьте свою электронную почту., @Juraj

Можете ли вы объяснить роль nrf24L01 в этом коде? Могут быть и другие способы достижения необходимой вам функциональности., @MichaelT

«Роль nrf24L01» — это код устройства Wi-Fi, насколько я понимаю., @Ron Needham

Программа открывает сетевое соединение с другим араудуино в сети., @Ron Needham

Никакой цифровой записи, поскольку он просто сообщает другому Arduino выполнить функцию цифровой записи при Lite_1 = 1., @Ron Needham


1 ответ


-1

Что-то вроде этого работает.

  unsigned long currentMillis;
  unsigned long previousMillis;
  unsigned long nextEventTime;

  unsigned long interval_on  = 2000;        // продолжительность времени включения
  unsigned long interval_off = 2000;        // продолжительность перерыва

  bool Lite_1;

  void setup() {

    previousMillis = millis();

    Lite_1 = false;                                     // начинаем с начала цикла выключения
    nextEventTime = previousMillis + interval_off;      // начинаем с начала цикла выключения

    Serial.begin(9600);
    Serial.print("starting in OFF cycle\t");
    Serial.println(previousMillis);
  }

  void loop() {

    if (millis() > nextEventTime) {                     // проверяем интервал перед выполнением любых других проверок

    currentMillis = millis();

    if (Lite_1) {

      nextEventTime = currentMillis + interval_off;     // выполняем расчет только один раз
      Serial.print("OFF:\t");

    } else {

      nextEventTime = currentMillis + interval_on;
      Serial.print("ON:\t");
    }

    Lite_1 = !Lite_1;                           // инвертируем значение
    Serial.println(currentMillis);              // печатает время с момента запуска программы
    }
  }
,

Когда значение добавляется к значению из миллис, а затем сравнивается с миллисами, это вызывает проблему опрокидывания. Всегда вычитайте предыдущий миллис из текущего миллиса., @Jot

Тогда как мне выполнить эту математику, если я не могу добавить к Millis()?, @Ron Needham

Я считаю, что это можно сделать с помощью nextEventTime - currentMillis > интервал_of. Неформально говоря, выполнение этого вычитания вместо сложения гарантирует, что мы собираемся выполнять неравенство с небольшим числом, а не с числом, которое потенциально достаточно велико, чтобы перевернуться, когда к нему добавляется интервал_off., @Cort Ammon

Во-первых, какова цель объявления всех переменных глобальными? Во-вторых, if (millis() > nextEventTime) — это не будет работать должным образом в момент ролловера millis()., @AnT