ARDUINO Обработка массива кнопок

Blackfin

✩✩✩✩✩✩✩
31 Мар 2021
8
0
Доброго времени суток! Есть такая задача: 3 емкости с поплавковыми выключателями, 3 соленоидных клапана и насос. При отправке команды на пополнение: 1. Открыть клапан на одну или несколько емкостей где поплавок разомкнут; 2. Включить насос; 3. Если емкость наполнилась до истечении времени - закрыть клапан и остановить насос. Сообразил вот такой код:
C++:
#include "BluetoothSerial.h"

BluetoothSerial SerialBT;

int Pump = 19;
int SV[] = {16, 17,18};
int Sw[] = {34, 35, 36};

int state = 0;

void setup() {
   Serial.begin(115200);
  SerialBT.begin("Water_Fill");
  Serial.println("The device started, now you can pair it with bluetooth!");

  pinMode(Pump, OUTPUT);
  for (byte i = 0; i < 3; i++) {
   pinMode(SV[i], OUTPUT);
   digitalWrite(SV[i], LOW);
   pinMode(Sw[i], INPUT);
 }
  
  digitalWrite(Pump,LOW);
}

void loop() {
 if(SerialBT.available() > 0){ 
    state = SerialBT.read(); 
    Serial.println(state);

 for (byte i = 0; i < 3; i++){
 if (digitalRead(Sw[i]) == HIGH){
    if (state == 'a') {
    digitalWrite(SV[i], HIGH);
    digitalWrite(Pump,HIGH);
    delay(10000);
    digitalWrite(Pump, LOW);
    digitalWrite(SV[i], LOW);
       }
    }
  }
} 
else {
  state = 0;
  }
}
Работает, но не совсем. Получилось, что открывает только один клапан даже если разомкнуты два или все три поплавка. Подскажите как сделать что бы правильно работало?
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
А что тут думать. как только натыкается на 1-ый разомкнутый выключателями программа открывает клапан и включает насос. А потом тупо ждет 10 секунд. И только потом переходит к проверке следующего клапана. 10 секунд мотор молотит , что происходит с выключателем непонятно, перелив рано или поздно гарантирован.
 

Blackfin

✩✩✩✩✩✩✩
31 Мар 2021
8
0
А что тут думать. как только натыкается на 1-ый разомкнутый выключателями программа открывает клапан и включает насос. А потом тупо ждет 10 секунд. И только потом переходит к проверке следующего клапана. 10 секунд мотор молотит , что происходит с выключателем непонятно, перелив рано или поздно гарантирован.
Дык об том и весь вопрос! Я ведь и спрашивал чего бы дописать и подправить чтобы так не происходило.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
1) Начните с того, что уберите задержку. совсем.
2) Условие включение мотора - открыт хотя бы один поплавок.
3) Условие выключения мотора - закрыты ВСЕ поплавки
4) При открытом поплавке (если я правильно) понял надо открыть клапан, при закрытом - хакрыть. Это все делается в цикле и без всяких задержек.

Самая простая проверка, почти исключающая логические операции:
Берете переменную и записываете в нее 0.
При открытии клапана увеличиваете ее на 1.
После проверки всех поплавков проверяете эту переменную и если он 0, то выключаете мотор, иначе - включаете.


ДОПОЛНЕНИЕ, нота-бене, пост-скриптум.
Вот еще подумал.... delay все же нужен. Вернее как таковой он вреден, но что бы было проще вам же надо делать его просто в цикле loop, отдельной строкой, НО! И ЭТО ВАЖНО! по условию! А условие такое. если мотор выключен, то сделать delay, а если включен, то без него. Тогда мотор не будет включаться от каждого волнения в баке, а выключится сразу после наполнения.
 

sochirom

✩✩✩✩✩✩✩
12 Май 2021
6
0
Я не понял логики, зачем мы ждем 10 сек?
Возможно тут необходим аварийный протокол, вдруг поплавок не сработает, что бы избежать разлива!
Попробуй так.

#include "BluetoothSerial.h"

BluetoothSerial SerialBT;

int Pump = 19;
int SV[] = {16, 17, 18};
int Sw[] = {34, 35, 36};

bool stateWork[] = {0, 0, 0};

int state = 0;

void setup() {
Serial.begin(115200);
SerialBT.begin("Water_Fill");
Serial.println("The device started, now you can pair it with bluetooth!");

pinMode(Pump, OUTPUT);
for (byte i = 0; i < 3; i++) {
pinMode(SV, OUTPUT);
digitalWrite(SV, LOW);
pinMode(Sw, INPUT);
}

digitalWrite(Pump, LOW);
}

void loop() {
if (SerialBT.available() > 0) {
state = SerialBT.read();
Serial.println(state);

if (state == 'a') {stateWork[] = {1, 1, 1}; state = 0;}

for (byte i = 0; i < 3; i++) {

if (digitalRead(Sw) == HIGH ) { // Если пришла команда и есть не долив
workTimer = millis() + maxTime; // Устанавливаем задержку
digitalWrite(SV, HIGH); // включаем клапан
digitalWrite(Pump, HIGH); // и насос

} else { // выключаем клапана
digitalWrite(SV, LOW);
if (stateWork[0] == 0 && stateWork[1] == 0 && stateWork[2] == 0) {digitalWrite(Pump, LOW);} Если все клапана закрыты выключаем насос
stateWork = 0;
}
}
}
}
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
@rGlory, На включение будет, а на выключение не знаю. Зависит от того на сколько высоко поплавки работают.Но в любом случае не через delay выключать. Можно выключать через 5-10 сек после того, как все поплавки замкнулись (или разомкнулись, я уже не помню), это все не сложно , для того кто умеет.

По вопросам человек не программист, пусть сделает такой вариант, как я описал, он прост в реализации.
 

Blackfin

✩✩✩✩✩✩✩
31 Мар 2021
8
0
Я не понял логики, зачем мы ждем 10 сек?
Delay потому что я знаю примерное время наполнения емкости. Весь вопрос в том чтобы одновременно открывались все клапана у которых замкнут поплавок, а не какой то один.
 

poty

★★★★★★✩
19 Фев 2020
3,230
940

@Blackfin, мне кажется здесь нужно независимое управление. Поплавок срабатывает при полном опустошении ёмкости?
 

sochirom

✩✩✩✩✩✩✩
12 Май 2021
6
0
@Blackfin, Дело в том, а если емкость опустошена на половину, тогда будет перелив.
Тут долив нужно делать по срабатыванию поплавка и все!
 

Blackfin

✩✩✩✩✩✩✩
31 Мар 2021
8
0
Переполнения не должно быть, т.к delay сработает примерно на 3/4 наполнения.
По вопросам человек не программист
Я только учусь :). Логика понятна, но что-то с реализацией туплю. Если не сложно помогите с кодом.
 

Blackfin

✩✩✩✩✩✩✩
31 Мар 2021
8
0
Поплавок стоит на нижнем уровне, чтобы отслеживать наполнение надо ставить еще один поплавок на верхний уровень, а я хочу обойтись только одним.
 

poty

★★★★★★✩
19 Фев 2020
3,230
940
П.3 тогда нужно вообще исключить, так как определить состояние, описанное в нём невозможно.
Наполнение управляется включением насоса и открытием клапана. Независимое управление позволит выполнить все задачи.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
Понятно, тогда обязательно нужно запоминать задержку, но не по delay

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

Blackfin

✩✩✩✩✩✩✩
31 Мар 2021
8
0
Отсчет времени с момента включения насоса.
Обозначил переменную int Sw_state = 0; Как теперь в коде запомнить состояние каждого из поплавков и руководить клапанами?
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
так же как и раньше:
if (digitalRead(Sw) == HIGH){
// А вот тут увеличить переменную на 1
}

Но раз насос включать с любого поплавка, то это уже не нужно.
Тогда можно так:
if (digitalRead(Sw) == HIGH){

// Тут сделать по условие если мотор выключен, то включить мотор и запомнить время включения
}


И далее по коду , если с момента включения мотора прошло больше 10 секунд и мотор включен, то выключить его,
 

sochirom

✩✩✩✩✩✩✩
12 Май 2021
6
0
Какой ход поплавка от включения до выключения? Может его хватит для долива?
Я думаю нужно замерить время опустошения баков, к примеру 30 мин.
Когда сработал поплавок на долив, ждем еще 30 мин, потом доливаем.
 

Blackfin

✩✩✩✩✩✩✩
31 Мар 2021
8
0
Избыточное цитирование
Какой ход поплавка от включения до выключения? Может его хватит для долива?
Я думаю нужно замерить время опустошения баков, к примеру 30 мин.
Когда сработал поплавок на долив, ждем еще 30 мин, потом доливаем.
Нет не хватит. Там буквально сантиметр, а емкость высотой 1.5 метра.
 

Blackfin

✩✩✩✩✩✩✩
31 Мар 2021
8
0
Избыточное цитирование
так же как и раньше:
if (digitalRead(Sw) == HIGH){
// А вот тут увеличить переменную на 1
}

Но раз насос включать с любого поплавка, то это уже не нужно.
Тогда можно так:
if (digitalRead(Sw) == HIGH){

// Тут сделать по условие если мотор выключен, то включить мотор и запомнить время включения
}


И далее по коду , если с момента включения мотора прошло больше 10 секунд и мотор включен, то выключить его,
Для меня главное чтобы одновременно открывались все клапана у которых разомкнуты поплавки, а с тем что кодом который я навоял открывается всегда только один!