переключение двух реле без задержки с помощью millis

У меня есть Arduino-uno и два реле. Каждое реле имеет два включения по две секунды через равные промежутки времени. общее время цикла реле 1 и реле 2 составляет 1800 секунд. реле 1–2 вкл., 360 выкл., 2 вкл., 600 выкл., 2 вкл., 430 выкл., 2 вкл., 402 выкл. реле 2 - 12 выкл., 2 вкл., 358 выкл., 2 вкл., 606 выкл., 2 вкл., 478 выкл., 2 вкл., 338 выкл. Может кто-нибудь помочь мне с кодом для этого, пожалуйста.

, 👍1

Обсуждение

У обоих общее время 1800, тогда я полагаю, они должны быть синхронизированы. Вы можете начать с создания массива или структуры с числами. Пример мигания без задержки выполняется с интервалом в 1 секунду. Используйте этот интервал в 1 секунду для проверки массива или структуры. Использовали ли вы раньше перечисление для определения чисел для действий?, @Jot

Когда используется мигание без задержки, первая секунда равна одной секунде после включения Arduino. PinMode для реле 1 отключает его. Это означает, что после включения Arduino или после сброса реле 1 отключается на одну секунду. Все хорошо? Предполагая, что ВЫСОКИЙ выход включает реле, а НИЗКИЙ выход выключает реле., @Jot

Да, общее время обоих реле составляет 1800 секунд, и обычно ВЫСОКИЙ уровень выключает реле, а НИЗКИЙ включает реле. Я уже несколько раз пробовал работать с кодом мигания без задержки (по совету), но не знаю, как закодировать в коде время включения и выключения - Джерри., @Jerry

А как насчет массивов, перечислений и структур? ты знаком с ними?, @Jot

Вместо того, чтобы задавать мне все те вопросы, на которые я могу ответить лишь частично, потому что у меня мало знаний в этой области. Не проще ли дать мне работоспособный набросок, чтобы я мог попробовать с ним поиграть? Или это сложно или невозможно?, @Jerry


2 ответа


2

это типичное приложение для Мигания без задержки

,

-1
// Включаем и выключаем светодиоды в определенное время.
//
// Когда на цифровом выходе высокий уровень, реле выключено.
// Когда на цифровом выходе НИЗКИЙ уровень, реле включено.

enum actionEnum {
  RELAY1_ON,
  RELAY1_OFF,
  RELAY2_ON,
  RELAY2_OFF,
};

struct tableStruct {
  unsigned int time;
  actionEnum action;
} const table[] = {
  { 0, RELAY1_ON},
  { 2, RELAY1_OFF},
  { 2 + 360, RELAY1_ON},
  { 2 + 360 + 2, RELAY1_OFF},
  { 2 + 360 + 2 + 600, RELAY1_ON},
  { 2 + 360 + 2 + 600 + 2, RELAY1_OFF},
  { 2 + 360 + 2 + 600 + 2 + 430, RELAY1_ON},
  { 2 + 360 + 2 + 600 + 2 + 430 + 2, RELAY1_OFF},
  //осталось 402, всего 1800
  { 0, RELAY2_OFF},         // не нужен, он уже выключен
  { 12, RELAY2_ON},
  { 12 + 2, RELAY2_OFF},
  { 12 + 2 + 358, RELAY2_ON},
  { 12 + 2 + 358 + 2, RELAY2_OFF},
  { 12 + 2 + 358 + 2 + 606, RELAY2_ON},
  { 12 + 2 + 358 + 2 + 606 + 2, RELAY2_OFF},
  { 12 + 2 + 358 + 2 + 606 + 2 + 478, RELAY2_ON},
  { 12 + 2 + 358 + 2 + 606 + 2 + 478 + 2, RELAY2_OFF},
  //осталось 338, всего 1800
};

const unsigned int totalTime = 1800;  // общее количество секунд для последовательности
unsigned int seconds;

unsigned long previousMillis;
const unsigned long interval = 1000;  // 1000 мс — это одна секунда

const int relay1Pin = 2;
const int relay2Pin = 3;

void setup() {
  Serial.begin(9600);

  // Реле выключено, когда на выводе высокий уровень.
  // Включите выходной уровень перед установкой pinMode.
  // Затем выходной сигнал меняется с плавающего на высокий,
  // и реле не будет активировано.
  digitalWrite(relay1Pin, HIGH);
  pinMode(relay1Pin, OUTPUT);
  digitalWrite(relay2Pin, HIGH);
  pinMode(relay2Pin, OUTPUT);
}

void loop() {
  // Таймер на одну секунду с миллисами
  if (millis() - previousMillis >= interval) {
    previousMillis += interval;

    // Таблица сканирования
    for (int i = 0; i < int(sizeof(table) / sizeof(tableStruct)); i++) {
      if (table[i].time == seconds) {
        switch (table[i].action) {
          case RELAY1_ON:
            Serial.println("Relay 1 on");
            digitalWrite(relay1Pin, LOW);  // низкий = реле включено
            break;
          case RELAY1_OFF:
            Serial.println("Relay 1 off");
            digitalWrite(relay1Pin, HIGH);  // высокий = реле выключено
            break;
          case RELAY2_ON:
            Serial.println("Relay 2 on");
            digitalWrite(relay2Pin, LOW);   // низкий = реле включено
            break;
          case RELAY2_OFF:
            Serial.println("Relay 2 off");
            digitalWrite(relay2Pin, HIGH);  // высокий = реле выключено
            break;
          default:
            Serial.println("Error, a bug in the sketch");
            break;
        }
      }
    }

    seconds++;
    if (seconds >= totalTime) {
      seconds = 0;
    }
  }
}
,

Большое спасибо. Я собираюсь попробовать это и дам вам знать., @Jerry

@Джерри, я протестировал его и подтвердил, что он работает в соответствии с предоставленной вами информацией., @Jot

Работает отлично, большое спасибо, Джерри., @Jerry

@ Джерри, я рад, что это работает для тебя. Вы видите, как это работает? В таблицу можно поместить любую команду. Например: «измерить температуру» или «подать звуковой сигнал». В таймере с точностью до одной секунды вся таблица сканируется, чтобы проверить, нужно ли что-то сделать., @Jot