Как закодировать 4 реле, чтобы они срабатывали с интервалами, а не последовательно?
Код:
//ДЛЯ АЭРОПОННОЙ СИСТЕМЫ С ДАТЧИКОМ КОМНАТНОЙ ТЕМПЕРАТУРЫ И ВЛАЖНОСТИ
//И 4 КАМЕРЫ ДЛЯ ВЫРАЩИВАНИЯ С РАЗНЫМ ВРЕМЕНЕМ ОПРЫСКИВАНИЯ
// УПРАВЛЕНИЕ РЕЛЕ
#define RELAY1_PIN 2
#define RELAY2_PIN 3
#define RELAY3_PIN 4
#define RELAY4_PIN 5
//Библиотеки
#include <DHT.h>;
//Константы
#define DHTPIN 6
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
//Переменные
int chk;
float hum;
float temp;
void setup()
{
Serial.begin(9600);
Serial.println("SENSOR RUNNING");
dht.begin();
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
pinMode(RELAY3_PIN, OUTPUT);
pinMode(RELAY4_PIN, OUTPUT);
}
void loop()
{
delay(2000);
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t))
{
Serial.println("CONNECTION ERROR");
return;
}
Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.print(" *C ");
Serial.println(" ");
delay(2*1000);
{
// ДЛЯ РЕЛЕ
digitalWrite(RELAY1_PIN, HIGH);
delay(2*1000); // ждать 2 секунды ON
digitalWrite(RELAY2_PIN, HIGH);
delay(3*1000); // ждем 3 секунды ON
digitalWrite(RELAY3_PIN, HIGH);
delay(4*1000); // ждем 4 секунды ON
digitalWrite(RELAY4_PIN, HIGH);
delay(5*1000); // ждем 5 секунд ON
digitalWrite(RELAY1_PIN, LOW);
digitalWrite(RELAY2_PIN, LOW);
digitalWrite(RELAY3_PIN, LOW);
digitalWrite(RELAY4_PIN, LOW);
delay(5*60*1000);
}
}
Этот код не делает того, что я хочу. Как сделать их независимыми?
@Carlos Imperial, 👍1
Обсуждение1 ответ
Лучший ответ:
Вот код, который может вам помочь; не говоря о температуре и влажности:
// константы
// число или реле
const int relays = 4;
// выводы для реле
const int relayPins[] = {2, 3, 4, 5};
// время цикла реле
const unsigned long relayTimes[] = {
5*60*1000, // 5 мин
60*60*1000, // 1 час
2*60*60*1000, // 2 часа
12*60*60*1000 // 12 часов
};
// реле длительности
const unsigned long relayOntimes[] = {
1000, // 1 секунда
10*1000, // 10 секунд
60*1000, // 1 минута
60*60*1000 // 1 час
};
// время для реле
// сохраняем последний раз
unsigned long relayElapsed[] = {0, 0, 0, 0};
// состояние каждого реле
int relaystate[] = {0, 0, 0, 0};
// вспомогательная функция для обработки каждого реле
void relay_helper(unsigned long t, unsigned long &elapsed, int pin, int &state, unsigned long delta, unsigned long ontime)
{
// в зависимости от состояния мы делаем разные вещи
switch (state)
{
case 0: // состояние 0 выключено, подождите, пока не пройдет время
if ((t-elapsed) > delta)
{ // затем
state = 1; // установить состояние на
elapsed = t; // сбросить время
digitalWrite(pin, HIGH); // включать
}
break;
case 1: // состояние 1 включено, подождите, пока не пройдет время
if ((t-elapsed) > ontime)
{ // затем
state = 0; // устанавливаем состояние выключено
elapsed = t; // сбросить время
digitalWrite(pin, LOW); // выключать
}
break;
}
}
void setup()
{
unsigned long start = millis();
for(int i = 0; i < relays; i++) // для каждого вывода
{
pinMode(relayPins[i], OUTPUT); // установить его для вывода
digitalWrite(relayPins[i], LOW); // и выключаем
relayElapsed[i] = start;
}
}
void loop()
{
unsigned long tm = millis();
for(int i = 0; i < relays; i++)
{
relay_helper(tm, relayElapsed[i], relayPins[i], relaystate[i], relayTimes[i], relayOnTimes[i]);
}
// делаем другие циклы
}
Основная идея заключается в том, что единственный способ делать что-то одновременно — это очень быстро делать что-то последовательно, мы не можем использовать delay(), потому что это цикл занятости, во время delay() больше ничего не может произойти, поэтому мы следите за временем и когда пора включать реле мы его включаем, а когда пора выключать выключаем.
Еще один вариант — написать класс для каждого ретранслятора:
class Relay
{
public:
Relay(int pin, unsigned long delta, unsigned long ontime);
~Relay();
process(unsigned long t);
private:
unsigned long delta;
unsigned long ontime;
unsigned long last; // истекло
int pin;
};
Затем можно создать массив из них:
Relay[] relays = {
Relay(2, 5*60000, 1000),
Relay(3, 60*60000, 10000),
Relay(4, 2*60*60000, 60000),
Relay(5, 12*60*60000, 60*60000)
};
поместите код из setup в конструктор, а код из помощника в процесс и, наконец, вызовите его в цикле в цикле.
Первый показанный способ — это то, как это можно было бы сделать без классов C++, а второй — с ними!
- Может ли кто-нибудь помочь мне с моим проектом?
- Как сделать очень долгую функцию delay(), несколько часов
- Разница между «time_t» и «DateTime»
- Получение BPM из данного кода
- Создание таймера с использованием часов реального времени с указанием времени начала и остановки
- Причины, по которым нельзя подключать реле непосредственно к цифровому контакту Arduino
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Генерация стабильной частоты
Пожалуйста, разместите актуальный **вопрос**, а не код. Чего вы хотите добиться на самом деле? Я и многие другие не станем смотреть на ваш код, пока не узнаем, что нам нужно ответить. Если вы четко объясните свою проблему, а затем зададите конкретный вопрос, это, скорее всего, поможет., @morbo
Сделайте правильный отступ в коде. Как бы то ни было, он никак не скомпилируется, и, как вы должны видеть, следить за потоком исключительно сложно., @stevieb
подумайте о своем заголовке ... требование «не в последовательности» не имеет смысла ... что, если «в интервалах» окажется «в последовательности» ... вы хотите предотвратить активацию реле, если это произойдет?, @jsotola
Хотя вопрос **далеко** не ясен, похоже, ответ может заключаться в том, чтобы вы научились [Мигать без задержки](https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay)., @Edgar Bonet