Существует ли что-то наподобие wait until ?

Rotar
Offline
Зарегистрирован: 18.11.2017

Доброго времени суток.

Для одного проекта решил использовать Arduino (ранее на ней только лампочки мигал)

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

Вот код:

int mot = 8; //драйвер мотора
int mag = 6; //реле магнита

void setup() 
 { 
 pinMode(mot, OUTPUT); 
 pinMode(mag, OUTPUT);
 pinMode(2, INPUT); 
 } 
 
 void loop() 
 { 
  
if(digitalRead(2)==HIGH) //если кнопку зажали
  {
digitalWrite(mag,LOW); //отключаем магнит 
  
  // вот тут должно стоять что-то типо "wait until" но такого не существует :(
  
if (digitalRead(2)==LOW)//если кнопку отжали 
{
 digitalWrite(mot,HIGH);
 delay (1000);           // проворавчиваенм мотор на 1 сек
 digitalWrite(mot,LOW);
 
 digitalWrite(mag,HIGH); //включаем магнит 

}
}
}

Косяк в том, что мотор проворачивается и при нажатии и при ОТжатии кнопки. Хочется такую функцию, которая бы "удерживала" код, пока ключ не разомкнется.

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Вы забыли написать что Вам нужно сделать, потому я ничего не могу посоветовать.

В тексте же написан полный бред. Смотрите, в строке 14 Вы проверяете, что "digitalRead(2)==HIGH", а затем ПОД ЭТИМ if'ом в строке 20 проверяете что "digitalRead(2)==LOW".

Вы понимаете, что условие в строке 20 никогда не будет истинным? Вернее будет, но только в том уникальном случае, если состояние кнопки успеет поменяться между строками 14 и 20, а это несколько микросекунд.

Rotar
Offline
Зарегистрирован: 18.11.2017

Да заметил , бред xD
Вот там хочется написать wait until (digitalRead(2)==LOW) но так нельзя.

А алгоритм действий выглядит так :

- Включили arduino
- Реле магнита включено сразу
- Зажимаем кнопку -> Реле отключается
- Ждем пока кнопка не отожмется
- Кнопка отжалась -> провернули мотор, включили реле на магнит
- Ждем пока кнопку опять зажмут 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Ну, если уж очень хочется, то: wait until (digitalRead(2)==LOW)  => while(digitalRead(2) != LOW) 

LoneDog
Offline
Зарегистрирован: 22.10.2013

так алгоритм будет выполняться ...

int mot = 8; //драйвер мотора
int mag = 6; //реле магнита
int count_of_action = 1; содержит количество повторов секундного вращения двигателя при отжатой кнопке чтобы при старте не 
// срабатывал мотор мы посчитаем что было одно срабатывание

void setup()
{
  pinMode(mot, OUTPUT);
  pinMode(mag, OUTPUT);
  pinMode(2, INPUT);
  digitalWrite(mag, HIGH); //включаем магнит
}

void loop()
{
  if (digitalRead(2) == HIGH) //если кнопку зажали
  {
    digitalWrite(mag, LOW); //отключаем магнит
    count_of_action = 0;
  }
  
  if (digitalRead(2) == LOW) //если кнопку отжали
  {
    if (count_of_action <= 0)
    {digitalWrite(mot, HIGH);
    delay (1000);           // проворавчиваенм мотор на 1 сек
    digitalWrite(mot, LOW);
    digitalWrite(mag, HIGH); //включаем магнит
    count_of_action++;
    }
  }
}

 

Rotar
Offline
Зарегистрирован: 18.11.2017

LoneDog пишет:

так алгоритм будет выполняться ...

int mot = 8; //драйвер мотора
int mag = 6; //реле магнита
int count_of_action = 1; содержит количество повторов секундного вращения двигателя при отжатой кнопке чтобы при старте не 
// срабатывал мотор мы посчитаем что было одно срабатывание

void setup()
{
  pinMode(mot, OUTPUT);
  pinMode(mag, OUTPUT);
  pinMode(2, INPUT);
  digitalWrite(mag, HIGH); //включаем магнит
}

void loop()
{
  if (digitalRead(2) == HIGH) //если кнопку зажали
  {
    digitalWrite(mag, LOW); //отключаем магнит
    count_of_action = 0;
  }
  
  if (digitalRead(2) == LOW) //если кнопку отжали
  {
    if (count_of_action <= 0)
    {digitalWrite(mot, HIGH);
    delay (1000);           // проворавчиваенм мотор на 1 сек
    digitalWrite(mot, LOW);
    digitalWrite(mag, HIGH); //включаем магнит
    count_of_action++;
    }
  }
}

 

Работает, но мотор норовит прокрутиться сразу по нажатию кнопки 

kalapanga
Offline
Зарегистрирован: 23.10.2016

Rotar пишет:

Работает, но мотор норовит прокрутиться сразу по нажатию кнопки 

Дребезг, наверное. Вверху этого раздела несколько прикреплённых тем про кнопки есть - почитайте.

Rotar
Offline
Зарегистрирован: 18.11.2017

А если пойти совершенно другим путём, допустим использовать case и счетчик?

Но может ли arduino засечь изменения в сигнале (HIGH и LOW) единожды? 
То есть LOW -> case 1, HIGH -> case 2, LOW -> case 3 (здесь, после вращения моторам, возвращаем n = 1), LOW -> case 1

Как думаете, правильно рассуждаю?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Rotar пишет:
Как думаете, правильно рассуждаю?
Не -а . Нужно устранять дребег программно. А это значит код усложнится.

Rotar
Offline
Зарегистрирован: 18.11.2017

Да дребизга нет, просто код LoneDog'а мою же ошибку повторяет, а именно строки 19 и 24.
 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Rotar пишет:

А алгоритм действий выглядит так :

- Включили arduino
- Реле магнита включено сразу
- Зажимаем кнопку -> Реле отключается
- Ждем пока кнопка не отожмется
- Кнопка отжалась -> провернули мотор, включили реле на магнит
- Ждем пока кнопку опять зажмут 

Давай я в псевдокоде с комментариями напишу, остальное - дело техники, что называется ;) Ок?

Button button(BUTTON_PIN);

void setup()
{
	//Включили arduino
	//Реле магнита включено сразу	
	relayOn();
}

void loop()
{
	// Зажимаем кнопку -> Реле отключается
	if(button.isPressed())
	{
		relayOff();
	}
	
	// Ждем пока кнопка не отожмется
	while(button.isPressed())
	{
		delay(1);
	}
	
	// Кнопка отжалась -> провернули мотор, включили реле на магнит
	rotateMotor();
	relayOn();
	
	// Ждем пока кнопку опять зажмут  - по сути, заходим на следующий цикл loop
}

Этот код - блокирующий, с полностью неблокирующей обработкой будет сложнее. И, ещё раз обращаю внимание - это псевдокод, он не будет компилироваться, и предназначен лишь для демонстрации алгоритма. Если код наполнить конкретной логикой, включая антидребезг при проверке кнопки на нажатие - всё будет работать согласно алгоритму.

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Зря Вы про антидребезг не слушаете а стоите на своем. С антидребезгом все будет работать.Пробуйте

#define buttonPin1 2
int mot = 8; //драйвер мотора
int mag = 6; //реле магнита
bool count_of_action = 1; //содержит количество повторов секундного вращения двигателя при отжатой кнопке чтобы при старте не 
// срабатывал мотор мы посчитаем что было одно срабатывание
bool kn_start = 0;
bool fl_start = 1;
uint32_t time;

void setup()
{
  pinMode(mot, OUTPUT);
  pinMode(mag, OUTPUT);
  pinMode(buttonPin1, INPUT);
  digitalWrite(mag, HIGH); //включаем магнит
}

void loop()
{
//Проверяем кнопку - 
  if (digitalRead(buttonPin1) != fl_start) { //Если сигнал изменился
    fl_start = !fl_start;
    time = millis();
  }
  if(!kn_start == digitalRead(buttonPin1) && millis() - time > 20){
    kn_start = digitalRead(buttonPin1);
  }
  
  if (kn_start == HIGH) //если кнопку зажали
  {
    digitalWrite(mag, LOW); //отключаем магнит
    count_of_action = 0;
  }
  
  if (count_of_action == 0 && kn_start == LOW) //если кнопку отжали
  {
    digitalWrite(mot, HIGH);
    delay (1000);           // проворавчиваенм мотор на 1 сек
    digitalWrite(mot, LOW);
    digitalWrite(mag, HIGH); //включаем магнит
    count_of_action = 1;
    
  }
}

 

Rotar
Offline
Зарегистрирован: 18.11.2017

vosara пишет:

Зря Вы про антидребезг не слушаете а стоите на своем. С антидребезгом все будет работать.Пробуйте

Признаю, зря. Все как часы заработало !
Как я понял в вашем коде применяется "чувствительность" на изменение сигнала ?
Честно сказать даже не догадывался как это и близко реализовать. Теперь буду знать. Спасибо большое !