Неблокирующий скетч
Пока что часть этого кода работает нормально, но реле 1 то включается, то выключается, а не остается выключенным.
Моя цель — включить реле 7, подождать 3 с, включить реле 8, подождать 10 с, включить реле 6, подождать 10 с, выключить реле 7, подождать 10 с, включить реле 5, подождать 3 с, включить реле 6. выкл, подождите 10 с, включите реле 5, подождите 3 с, выключите реле 6, подождите 10 с, включите реле 4, подождите 3 с, выключите реле 5, подождите 10 с, включите реле 3, подождите 3 с, выключите реле 4, подождите 10 с , включите реле 2, подождите 3 секунды, выключите реле 3, подождите 10 секунд, включите реле 1, подождите 10 секунд, выключите реле 1, подождите 3 секунды, выключите реле 8, без зацикливания, только одна последовательность.
Мне нужна помощь.
int RelayPompe = 2;
int RelayVanne7 = 3;
int RelayVanne6 = 4;
int RelayVanne5 = 5;
int RelayVanne4 = 6;
int RelayVanne3 = 7;
int RelayVanne2 = 8;
int RelayVanne1 = 9;
const unsigned long eventInterval1 = 10000;
const unsigned long eventInterval2 = 3000;
const unsigned long eventInterval3 = 15000;
const unsigned long eventInterval4 = 20000;
unsigned long previousTime1 = 0;
unsigned long previousTime2 = 0;
unsigned long previousTime3 = 0;
unsigned long previousTime4 = 0;
void setup() {
Serial.begin(9600);
pinMode(RelayPompe, OUTPUT);
pinMode(RelayVanne1, OUTPUT);
pinMode(RelayVanne2, OUTPUT);
pinMode(RelayVanne3, OUTPUT);
pinMode(RelayVanne4, OUTPUT);
pinMode(RelayVanne5, OUTPUT);
pinMode(RelayVanne6, OUTPUT);
pinMode(RelayVanne7, OUTPUT);
digitalWrite(RelayPompe, HIGH);
digitalWrite(RelayVanne1, HIGH);
digitalWrite(RelayVanne2, HIGH);
digitalWrite(RelayVanne3, HIGH);
digitalWrite(RelayVanne4, HIGH);
digitalWrite(RelayVanne5, HIGH);
digitalWrite(RelayVanne6, HIGH);
digitalWrite(RelayVanne7, HIGH);
}
void loop() {
unsigned long currentTime = millis();
if (currentTime - previousTime1 >= eventInterval1) {
digitalWrite(RelayPompe, LOW);
previousTime1 = currentTime;
}
if (currentTime - previousTime2 >= eventInterval2) {
digitalWrite(RelayVanne1, LOW);
previousTime2 = currentTime;
}
if (currentTime - previousTime3 >= eventInterval3) {
digitalWrite(RelayVanne2, LOW);
previousTime3 = currentTime;
}
if (currentTime - previousTime4 >= eventInterval4) {
digitalWrite(RelayVanne1, HIGH);
previousTime4 = currentTime;
}
}
@Agili, 👍-1
Обсуждение1 ответ
Для такого рода вещей я был бы склонен создать массив (возможно, структур), описывающий, что вы хотите, чтобы реле делали, а затем написать программу, которая проходит через этот массив, выполняя каждую "инструкцию" в последовательности. Таким образом, он отделяет то, что вы хотите сделать, от того, как вы хотите, чтобы это было сделано (если это имеет смысл).
Итак, вы можете создать простую структуру:
typedef struct {
uint8_t relays;
uint32_t postDelay;
} RelayState;
Затем вы можете создать массив, используя эту структуру для описания ваших состояний реле. Использование растрового изображения для ваших реле (бит 0 — это реле 1, бит 1 — это реле 2 и т. д.) означает, что вы можете упаковать все в одно целое число и описать реле в двоичной записи:
RelayState states[] = {
{ 0b01000000, 3000 }, // Реле 7 включено, подождите 3 секунды
{ 0b11000000, 10000 }, // Реле 8 включено, подождите 10 секунд
{ 0b11100000, 10000 }, // Реле 6 включено, подождите 10 секунд
{ 0b10100000, 10000 }, // Реле 7 выключено, подождите 10 секунд
{ 0b10110000, 3000 }, // Реле 5 включено, подождите 3 секунды
// ... так далее ...
{ 0, 0 } // Маркер конца массива
};
Если вы когда-нибудь захотите изменить последовательность, вы просто измените содержимое этого массива без необходимости связываться с остальной частью вашей программы.
Также может быть полезно создать массив контактов реле:
const uint8_t relayPins[8] = { 9, 8, 7, 6, 5, 4, 3, 2 };
Теперь вам просто нужно написать небольшую программу, которая должна иметь дело только с текущей записью в массиве - установить реле в соответствии с первой частью, затем задержать в соответствии со второй частью и перейти к следующей записи. Что-то вроде:
void setup() {
// Установить выводы реле на выходы
for (int i = 0; i < 8; i++) {
pinMode(relayPins[i], OUTPUT);
}
// Устанавливаем начальное состояние из первой записи в массиве
setRelays(states[0].relays);
}
void loop() {
static uint32_t ts = millis(); // Память на время
static uint8_t pos = 0;
if ((millis() - ts) >= states[pos].postDelay) { // Наше время истекло
ts = millis(); // Записываем время
pos++; // переход к следующей записи
if ((states[pos].relays == 0) && (states[pos].postDelay == 0)) { // Маркер последнего входа
pos = 0; // Начнем снова с начала
}
setRelays(states[pos].relays);
}
}
// Небольшая вспомогательная функция для установки реле в соответствии с растровым изображением
void setRelays(uint8_t bm) {
for (int i = 0; i < 8; i++) {
digitalWrite(relayPins[i], bm & (1 << i));
}
}
Примечание: этот код не тестировался, он просто написан "экспромтом" и может даже не компилироваться. Но в любом случае это должно дать вам общее представление о методологии.
Формат растровых изображений очень прост. Это просто двоичное представление числа, где каждый бит соответствует одному реле. Включите этот бит, и соответствующее реле включится.
- Ретранслятор 1: 0b00000001
- Ретранслятор 2: 0b00000010
- Реле 3: 0b00000100
и т. д. Просто установите 1, чтобы реле было включено, и 0, чтобы реле было выключено в этот момент времени.
Итак, включение реле 1 – это 0b00000001, затем включение реле 4 – 0b00001001, а затем повторное выключение реле 1 – 0b00001000 (реле 4 все еще включено).
Я понял, мне нужно написать весь двоичный код для всех контактов, я попробую, @Agili
Пожалуйста, объясните мне, как добавить больше записей в массив: {0b01000000, 3000}, @Agili
что такое {0b01000000, 3000} и как добавить все реле?, @Agili
0bxxxxxxxx — это состояние каждого из 8 реле. 3000 - это сколько мс задержать., @Majenko
3000 - это задержка мс, но 0bxxxxxxxx, как добавить все 8 реле, которые управляют для ее создания?, @Agili
Решите, какие реле вы хотите включить, а какие выключить — реле 8 слева, а реле 1 справа. 1 для включения, 0 для выключения. Таким образом, включение реле 1, 5 и 7 будет 0b01010001., @Majenko
- C++ против языка Arduino?
- Как использовать SPI на Arduino?
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Ошибка: expected unqualified-id before 'if'
- Что лучше использовать: #define или const int для констант?
- Функции со строковыми параметрами
- Библиотека DHT.h не импортируется
- ошибка: ожидаемое первичное выражение перед токеном ','
какое реле 1?, @jsotola
пожалуйста, пересмотрите то, что вы написали ... кажется, есть некоторые ошибки, @jsotola
@jsotola «RelayPompe имеет номер 1 и подключен к контакту 2 платы Arduino», @Agili
представленный вами код не выполняет постоянный цикл RelayPompe, если только Arduino не перезагружается повторно... добавьте код отладки, чтобы определить, что происходит, @jsotola
вы читали ваше описание желаемой последовательности? ... кажется, есть ошибка, которая портит синхронизацию, @jsotola
все равно не могу разобраться., @Agili
вы сказали «подождите 10 секунд, включите реле 5, подождите 3 секунды, включите реле 6» дважды подряд, @jsotola
это система полива, мне нужно сначала включить реле 1, которое подключено к электромагнитному клапану 1, затем включить реле 8, которое подключено к водяному насосу, и оставить его включенным до конца последовательности, затем включить реле 2 - электромагнитный клапан 2 через 3 секунды выключить реле 1. затем через 10 с включите реле 3-электромагнитный клапан 3, затем через 3 с выключите реле 2 ... до реле 8-электромагнитный клапан 8, в конце выключите реле 8-водяной насос и завершите последовательность. кстати, 3s и 10 только для тестирования позже будут изменены на более длительный период, @Agili