Включение одного реле с отключением всех остальных

Otto
Offline
Зарегистрирован: 26.06.2016

Здравствуйте, нужна помощь.

Есть 4 реле и 3 светодиода, нужно реализовать что бы при включении одного реле со светодиодом все оставшиеся 3 реле со светодиодами отключались. Так же при включении на другое реле включался другой светодиод, а все предыдущие отключались. То есть 2 реле или LED НЕ должны одновременно быть включены.
К примеру:

Вкл. 1 реле и 1 LED, все остальное Off;
Вкл. 3 реле и 3 LED, все остальное Off;
Вкл. 4 реле, все остальное LED и реле Off.

Сделать это с помощью digitalWrite без проблем можно, вот только будет очень много комбинаций с включением реле по таймерам на разные время и получается очень много раз писать digitalWrite очень грамоздко и отжирает памяти много (в старом проекте так реализовано сейчас).

Отлично подходит управление через регистры портов в бинарной системе одной строчкой:
DDRD =  0b00100010;
Вот только теряется возможность универсально в начале скетча переназначить пин для смены на другую ногу реле или LED и для переноса на другой МК может быть несовместимость с портами.

Может знаете какой  нибудь способ как к примеру с помощью #define добавить универсальности, либо как нибудь с помощью массивов уменьшить кол-во вызовов digitalWrite?

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Массивы и циклы использовать не пробовал ?

rkit
Offline
Зарегистрирован: 23.11.2016

Kakmyc пишет:
Массивы и циклы использовать не пробовал ?

У него памяти на 7 вызовов нет, куда уж тут массивы.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Одну функцию написать - входной параметр=номер реле которое надо включить. В теле ВСЕ реле/диоды выключаешь и ОДНО реле/диод (номер во входном параметре) включаешь.

Otto
Offline
Зарегистрирован: 26.06.2016

Нашёл Макросы Аскольда Волкова.

Вот только примеры с управлением по одному пину на порту:
 

#define _PORTB(bitt,HL) HL?PORTB|=1<<bitt:PORTB&=~(1<<bitt)

void setup() {
  DDRB = 0xFF;
}

void loop() {
  _PORTB(5, 1);
  delay(1000);
  _PORTB(5, 0);
  delay(1000);
}

А хотелось бы управление сразу свем портом "DDRD =  0b00100010;"...

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Otto пишет:

А хотелось бы управление сразу свем портом "DDRD =  0b00100010;"...

Маска не подходит?

Kakmyc
Offline
Зарегистрирован: 15.01.2018
const int outPin[4]={2,3,4,5};
int nPin=0;//порядковый номер реле/диода которые нужно включить

void setup(){
    for (int i=0;i<4;i++)pinMode(outPin[i],OUTPUT);
}

void loop(){
    if(nPin>0&&nPin<=4){
        for(int i=0;i<4;i++){
            nPin==i+1?digitalWrite(outPin[i],1):digitalWrite(outPin[i],0);
        }
    }
}

 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Otto не туда вас несет ! Откуда уверенность что на другом МК вообще есть DDRD ?

Kakmyc по вашему коду будут короткие моменты, когда будут включены два реле ! Иногда это приводит к белому дыму на силовой части ...

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Komandir пишет:

Otto не туда вас несет ! Откуда уверенность что на другом МК вообще есть DDRD ?

Kakmyc по вашему коду будут короткие моменты, когда будут включены два реле ! Иногда это приводит к белому дыму на силовой части ...

 

Ну никто не запрещает сначала выключить всё, а потом уже включать то что надо.

Реальная задача решается исходя из входных данных, а для вакуума и так сойдёт.

Otto
Offline
Зарегистрирован: 26.06.2016

Komandir пишет:

Одну функцию написать - входной параметр=номер реле которое надо включить. В теле ВСЕ реле/диоды выключаешь и ОДНО реле/диод (номер во входном параметре) включаешь.

Спасибо за полезный совет. Это то, что нужно одной строчкой.
Работает так, как мне нужно, благодарю за идею о которой не додумался.

Вот демонстрационный пример:

//Реле
#define RELAY1 6    // Режим 1 - ПОНИЖЕННАЯ скорость первого режима через конденсатор
#define RELAY2 5    // Режим 1 - Низкая скорость
#define RELAY3 4    // Режим 2 - Средняя скорость
#define RELAY4 3    // Режим 3 - Высокая скорость

//Led индикация
#define LED_GREAN 8   // Зелёный светодиод для индикации режима 1
#define LED_BLUE  7   // Синий светодиод для индикации режима 2
#define LED_RED  10   // Красный светодиод для индикации режима 3


const byte Relay_Array[4] = {RELAY1, RELAY2, RELAY3, RELAY4};   // Массив реле
const byte Led_Array[3] = {LED_GREAN, LED_BLUE, LED_RED};       // Массив LED


void WriteRelLed(byte pin_Rel, byte pin_Led) {
  //Выключаем все РЕЛЕ
  digitalWrite(RELAY1, HIGH);
  digitalWrite(RELAY2, HIGH);
  digitalWrite(RELAY3, HIGH);
  digitalWrite(RELAY4, HIGH);
  delay(15);  // Ждём, пока контакты реле разъединятся
  digitalWrite(Relay_Array[pin_Rel - 1], LOW); // Вкл. нужное реле

  //Выключаем все LED
  digitalWrite(LED_GREAN, LOW);
  digitalWrite(LED_BLUE, LOW);
  digitalWrite(LED_RED, LOW);
  digitalWrite(Led_Array[pin_Led - 1], HIGH);  // Вкл. нужный LED
}

void setup() {
  Serial.begin(9600);
  
  for (byte r = 0; r < 4; r++) pinMode(Relay_Array[r], OUTPUT); //Назначаем все РЕЛЕ как ВЫХОД
  for (byte l = 0; l < 3; l++) pinMode(Led_Array[l], OUTPUT);   //Назначаем все LED как ВЫХОД

  //По умолчанию все РЕЛЕ выключены (инверсия, при HIGH реле выключены)
  for (byte r = 0; r < 4; r++) digitalWrite(Relay_Array[r], HIGH);  //Назначаем все РЕЛЕ как ВЫХОД
  for (byte l = 0; l < 3; l++) digitalWrite(Led_Array[l], LOW);     //Назначаем все LED как ВЫХОД
}

void loop() {
  WriteRelLed(1, 1);
  Serial.println("Вкл: Реле 1 и LED 1");
  Serial.println(digitalRead(RELAY1));
  Serial.println(digitalRead(RELAY2));
  Serial.println(digitalRead(RELAY3));
  Serial.println(digitalRead(RELAY4));
  Serial.println();
  Serial.println(digitalRead(LED_GREAN));
  Serial.println(digitalRead(LED_BLUE));
  Serial.println(digitalRead(LED_RED));
  Serial.println();
  delay(5000);  // Для удобства изучения результатов между в мониторе порта

  WriteRelLed(2, 2);
  Serial.println("Вкл: Реле 2 и LED 2");
  Serial.println(digitalRead(RELAY1));
  Serial.println(digitalRead(RELAY2));
  Serial.println(digitalRead(RELAY3));
  Serial.println(digitalRead(RELAY4));
  Serial.println();
  Serial.println(digitalRead(LED_GREAN));
  Serial.println(digitalRead(LED_BLUE));
  Serial.println(digitalRead(LED_RED));
  Serial.println();
  delay(5000);

  WriteRelLed(3, 3);
  Serial.println("Вкл: Реле 3 и LED 3");
  Serial.println(digitalRead(RELAY1));
  Serial.println(digitalRead(RELAY2));
  Serial.println(digitalRead(RELAY3));
  Serial.println(digitalRead(RELAY4));
  Serial.println();
  Serial.println(digitalRead(LED_GREAN));
  Serial.println(digitalRead(LED_BLUE));
  Serial.println(digitalRead(LED_RED));
  Serial.println();
  delay(5000);

  WriteRelLed(4, 1);
  Serial.println("Вкл: Реле 4 и LED 1");
  Serial.println(digitalRead(RELAY1));
  Serial.println(digitalRead(RELAY2));
  Serial.println(digitalRead(RELAY3));
  Serial.println(digitalRead(RELAY4));
  Serial.println();
  Serial.println(digitalRead(LED_GREAN));
  Serial.println(digitalRead(LED_BLUE));
  Serial.println(digitalRead(LED_RED));
  Serial.println();
  delay(5000);
}

 

b707
Offline
Зарегистрирован: 26.05.2017

фи... незачет...

судя по примеру, ты схватил не идею, а подскахку.

Если б понял идею - то и вывод в Сериал в ЛУПе тоже сделал бы процедурой, а не тупо копировал четыре одинаковых куска кода...

Otto
Offline
Зарегистрирован: 26.06.2016

Это просто демонстрация и всё, мне нужна только функция из примера

b707
Offline
Зарегистрирован: 26.05.2017

Ага, это просто демонстрация того, что ты не умеешь думать сам, можешь только копировать готовые решения...

Otto
Offline
Зарегистрирован: 26.06.2016

Хватит дичь пороть. Твои стёбы не интересны )

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Otto пишет:

Это просто демонстрация и всё, мне нужна только функция из примера

Тупая функция. В сетапе, значит, хватило ума реле/светодиоды в цикле отключать, а в функции не хватило )))

b707
Offline
Зарегистрирован: 26.05.2017

v258 пишет:

В сетапе, значит, хватило ума реле/светодиоды в цикле отключать, а в функции не хватило )))

наверно там где он это списал, в сетапе были циклы. а в остальной программе нет :)

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Более того, она (функция) не соответствует требованиям из первого поста

Otto пишет:

Вкл. 1 реле и 1 LED, все остальное Off;
Вкл. 3 реле и 3 LED, все остальное Off;
Вкл. 4 реле, все остальное LED и реле Off.

Хотелось бы мне посмотреть, как ТС будет реализовывать третью строку ))

b707
Offline
Зарегистрирован: 26.05.2017

v258 пишет:

Хотелось бы мне посмотреть, как ТС будет реализовывать третью строку ))

да очень просто - скопирует готовую функцию, уберет в ней включение диода и сохранит под новым именем... это его любимый стиль программирования - "копи-паст" называется :)

Вот, для сравнения - его код шестилетней давности: http://arduino.ru/forum/programmirovanie/upravlenie-rele-po-mqtt-na-arduino

Все ровно так же - куча одинаковых кусков кода, размноженных Ctrl-C - Ctrl-V.