Старт/конец событий с помощью milis

Я хочу запустить реле, запустить его на 3 секунды, остановить на 10 секунд и повторить.

Я не могу использовать задержку, потому что у меня моторный драйвер запускается/останавливается каждые 100 мили.

Поэтому я собрал этот код, но он не работает. Любая помощь приветствуется.

Задержка 500 мс, чтобы остановить слишком много отладочной информации.

Кроме того, по какой-то причине tenSecondsBool переключается в значение true, как только вы запускаете код.

unsigned long threeSeconds=3000; // время, которое нам нужно ждать
unsigned long threeSecondsMillis=0; //millis() возвращает беззнаковое длинное значение.
unsigned long fourSeconds=7000; // время, которое нам нужно ждать
unsigned long fourSecondsMillis=0; //millis() возвращает беззнаковое длинное значение.



unsigned long previousMillis=0; //millis() возвращает беззнаковое длинное значение.
bool ledState = false; // переменная состояния для светодиода
bool led2State = false; // переменная состояния для светодиода
unsigned long tenSecondMilis=0; //millis() возвращает беззнаковое длинное значение.
unsigned long tenSeconds=10000; // время, которое нам нужно ждать

unsigned long paliGasiMilis=0; //millis() возвращает беззнаковое длинное значение.
unsigned long paliGasi=1000; // время, которое нам нужно ждать

unsigned long ventMilis=0; //millis() возвращает беззнаковое длинное значение.
unsigned long ventInt=100; // время, которое нам нужно ждать

bool threeSecondBool = false;
bool tenSecondBool = false;

int Fin1 = D7;

#define enA D1
#define in1 D2 
#define in2 D3
#define button 4

int rotDirection = 0;
int pressed = false;

void setup() {
  Serial.begin(9600); // отправка и получение на скорости 9600 бод
  pinMode(enA, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(button, INPUT);
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  pinMode(Fin1, OUTPUT);
  digitalWrite(Fin1, HIGH);
  threeSecondBool = false;
  tenSecondBool = false;
}

void loop() {


 unsigned long currentMillis = millis(); // получаем текущее время

 if ((unsigned long)(currentMillis - tenSecondMilis) >= tenSeconds) {
    Serial.print("---------------\n");
    Serial.print("10 second end\n");
    Serial.print("---------------\n");
    tenSecondBool = true;
    tenSecondMilis = millis();
} 

Serial.print("10 second bool = ");
Serial.print(tenSecondBool);
Serial.print("\n");
Serial.print("3 second bool = ");
Serial.print(threeSecondBool);
Serial.print("\n");

 if (tenSecondBool) {
  if ((unsigned long)(currentMillis - threeSecondsMillis) >= threeSeconds) {
   Serial.print("---------------\n");
   Serial.print("3 second end\n");
   Serial.print("---------------\n");
   threeSecondBool = true;
   threeSecondsMillis = millis();
  }
 }

if (!tenSecondBool && threeSecondBool){
  Serial.print("Both triggered!\n");
  digitalWrite(Fin1, HIGH);
}

if (!tenSecondBool && !threeSecondBool){
  Serial.print("Both triggered!\n");
  digitalWrite(Fin1, HIGH);
}

if (tenSecondBool && threeSecondBool){
  threeSecondBool = false;
  tenSecondBool = false;
  digitalWrite(Fin1, LOW);
}

delay(500);

  if ((unsigned long)(currentMillis - ventMilis) >= ventInt) {
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    ventMilis = millis();
  } else {
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);    
  }


}

, 👍1


2 ответа


Лучший ответ:

1

Если вам нужен таймер с миллисекундами и разными интервалами, вы можете изменить интервал.

Для начала я использую Мигание без задержки и заимствовал "relay_is_on" из ответа автора Эдгар Боне.

unsigned long previousMillis;
unsigned long interval;
bool relay_is_on;

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    if (relay_is_on) {
      // Реле было включено, теперь выключите его.
      interval = 10000;
      digitalWrite (relayPin, LOW);
      relay_is_on = false;
    } else {
      // Реле было выключено, теперь включите его.
      interval = 3000;
      digitalWrite (relayPin, HIGH);
      relay_is_on = true;
    }
  }
}

Глобальным переменным можно задать начальное значение (например, 3000 для интервала) или их можно установить в функции setup(). Вы должны выбрать, с чего вы хотите начать. Например, возможна задержка в одну секунду или одну минуту перед запуском.

,

2

Ваш код несколько сбивает с толку, вероятно, потому, что в нем слишком много переменные. Для выполнения того, что вы описываете, программе нужно только помните две вещи:

  • находится ли реле во включенном или выключенном состоянии?
  • когда в последний раз реле меняло состояние?

Они могут быть представлены следующим образом:

bool relay_is_on = false;
unsigned long last_relay_change = 0;

Тогда я рекомендую вам использовать описательные имена для ваших переменных и константы. Вызов константы threeSeconds бесполезен. У него нет дополнительная ценность по сравнению с простым вводом 3000. Имея константу с именем RELAY_ON_TIME делает его более понятным для чего он предназначен. Это общее соглашение называть константы заглавными буквами, чтобы они стояли out относительно переменных:

const uint8_t RELAY_PIN = ...;
const unsigned long RELAY_ON_TIME  =  3000;  //  3 s ON
const unsigned long RELAY_OFF_TIME = 10000;  // 10 s OFF

Благодаря этому можно периодически включать и выключать реле. достигается следующим образом:

void loop()
{
    unsigned long now = millis();
    if (relay_is_on && now - last_relay_change >= RELAY_ON_TIME) {
        // Выключать.
        digitalWrite(RELAY_PIN, LOW);
        relay_is_on = false;
        last_relay_change = now;
    }
    if (!relay_is_on && now - last_relay_change >= RELAY_OFF_TIME) {
        // Включать.
        digitalWrite(RELAY_PIN, HIGH);
        relay_is_on = true;
        last_relay_change = now;
    }
}
,