Справка по переключателю Arduino uno

Я строю коробку, которая запустит генераторную установку. У него есть две кнопки: "Запустить" и "остановить". Я хотел бы, чтобы кнопка "Запуск" могла запускаться (и оставаться постоянной) до тех пор, пока не будет нажата во второй раз, я уже немного разобрался в этом, но именно здесь я застрял. Я бы хотел, чтобы кнопка "Стоп" останавливала только двигатель (как отдельная функция). Итак, мой вопрос в том, как мне интегрировать вторую кнопку (стоп) для выполнения этой задачи?

int LEDYelState=0;
int LEDRedState=0;
int LEDGrnState=0;
int RELAYRedState=0;
int RELAYYelState=0;
int RELAYGrnState=0;
int LEDRedPin=10;
int LEDYelPin=9;
int LEDGrnPin=8;
int RELAYRedPin=7;
int RELAYYelPin=6;
int RELAYGrnPin=5;
int buttonPin=13;
int buttonNew;
int buttonOld=1;
int dt=100;
int buttonOff;
int buttonPinOff=12;
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
pinMode(LEDRedPin, OUTPUT);
pinMode(buttonPin, INPUT);
pinMode (LEDYelPin,OUTPUT);
pinMode (LEDGrnPin, OUTPUT);
pinMode (RELAYRedPin, OUTPUT);
pinMode (RELAYYelPin, OUTPUT);
pinMode (RELAYGrnPin, OUTPUT);
pinMode (buttonPinOff, INPUT);
}
void loop() {
buttonNew=digitalRead(buttonPin);
buttonOff=digitalRead(buttonPin);
if(buttonOld==0 && buttonNew==1){
  if (LEDRedState==0){
    digitalWrite(LEDRedPin,HIGH);
    LEDRedState=1;
    digitalWrite(RELAYRedPin,LOW);
    RELAYRedState=1;

    digitalWrite(LEDYelPin, HIGH);
    LEDYelState=1;
    digitalWrite(RELAYYelPin, LOW);
    RELAYYelState=1;
    delay (8000);
    digitalWrite(LEDYelPin,LOW);
    digitalWrite(RELAYYelPin,HIGH);

    digitalWrite (LEDGrnPin,HIGH);
    LEDGrnState=1;
    digitalWrite (RELAYGrnPin, LOW);
    RELAYGrnState=1;
    delay(2000);
    digitalWrite  (LEDGrnPin,LOW);
    digitalWrite (RELAYGrnPin,HIGH);
    RELAYGrnState=1;
  }
  else{
    digitalWrite(LEDRedPin, LOW);
    LEDRedState=0;
    digitalWrite(RELAYRedPin, HIGH);
    RELAYRedState=0;
    digitalWrite(LEDYelPin,LOW);
    LEDYelState=0;


  }
}
buttonOld=buttonNew;
delay(dt);


}

, 👍1

Обсуждение

отделите функцию запуска двигателя от функции нажатия кнопки ... объявите логическую переменную ... назовите ее, например, "run"... когда это правда, тогда двигатель работает ... когда это ложь, то двигатель останавливается ... если вы нажмете "Пуск", то сделайте "выполнить" истинным ... если вы нажмете start еще раз, то сделаете run false ... когда вы нажмете stop, то сделаете run false, @jsotola

Не могли бы вы дать мне какой-нибудь код, который я могу увидеть, например, который может сработать ? Твое здоровье Брайан, @Bryan Moore


1 ответ


1

Сначала общая подсказка: правильно сделайте отступ в коде. Это значительно облегчает чтение и облегчает обнаружение логических ошибок.

Еще одним улучшением было бы назвать контакты теми же именами, что и вы, когда объясняете нам проблему. Я ожидал найти int buttonRunPin и int buttonStopPin.

Первая проблема, которую я вижу, это:

buttonNew=digitalRead(buttonPin);
buttonOff=digitalRead(buttonPin);

Это считывает одну и ту же кнопку дважды. Вы, вероятно, хотели прочитать две разные кнопки: кнопку "выполнить" и кнопку "остановить".

Следующий вопрос, который я вижу, это:

delay(8000);
delay(2000);

В течение этих 10 секунд вы можете нажимать и отпускать кнопку много раз. Но поскольку в течение этого времени digitalRead() отсутствует, нажатие кнопки не будет распознано.

То же самое относится и к

int dt=100;
delay(dt);

Если вы нажмете кнопку в течение этих 100 мс, это не будет замечено.

К сожалению, чтобы исправить это, вам нужно изучить совершенно новую концепцию: прерывания. И что еще хуже, не все контакты поддерживают прерывания. На Arduino Uno это только вывод 2 и вывод 3, что означает, что вам нужно будет изменить настройку оборудования (потому что вы используете вывод 12 и 13). Поместите обе кнопки от контакта на землю, чтобы она закрывалась при нажатии.

Затем вы должны подготовить прерывание в процедуре setup ():

pinMode(buttonPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(buttonPin), toggleRun, CHANGE);
pinMode(buttonPinOff, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(buttonPinOff), toggleStopped, CHANGE);

Вы также определяете глобальные переменные для состояния кнопок:

volatile bool running = false;
volatile bool stopped = false;

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

Далее, вам нужны два метода, которые выполняются всякий раз, когда происходит прерывание, т. Е. вы нажимаете кнопку:

void toggleRun() {
    running = !running;
}
void toggleStopped() {
    stopped = !stopped;
}

Примечание: приведенный выше шаблон x = !x; является короткой и эффективной формой

if (x == false) {
    x = true;
}
else if (x == true) {
   x = false;
}

Как только у вас все это будет, вам больше не понадобятся две функции digitalRead ().

Боюсь, я не понял, что должен делать ваш код. У вас есть много переменных состояния, которые, кажется, бесполезны, и особенно они не соответствуют двигателям. Например, как только RELAYGrnState установлен в 1, он никогда не возвращается к 0.

Вот что у меня в итоге получилось:

int LEDYelState=0;
int LEDRedState=0;
int LEDGrnState=0;
int RELAYRedState=0;
int RELAYYelState=0;
int RELAYGrnState=0;
int LEDRedPin=10;
int LEDYelPin=9;
int LEDGrnPin=8;
int RELAYRedPin=7;
int RELAYYelPin=6;
int RELAYGrnPin=5;
int buttonPin=13;
int buttonNew;
int buttonOld=1;
int dt=100;
int buttonOff;
int buttonPinOff=12;

volatile bool running = false;
void toggleRun() {
    running = !running;
}

volatile bool stopped = false;
void toggleStopped() {
    stopped = !stopped;
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(LEDRedPin, OUTPUT);
  pinMode (LEDYelPin,OUTPUT);
  pinMode (LEDGrnPin, OUTPUT);
  pinMode (RELAYRedPin, OUTPUT);
  pinMode (RELAYYelPin, OUTPUT);
  pinMode (RELAYGrnPin, OUTPUT);

  pinMode(buttonPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(buttonPin), toggleRun, CHANGE);
  pinMode(buttonPinOff, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(buttonPinOff), toggleStopped, CHANGE);
}

void doSomething() {
  digitalWrite(LEDRedPin,HIGH);   // red LED is on
  LEDRedState=1;
  digitalWrite(RELAYRedPin,LOW);  // red motor off? others unclear
  RELAYRedState=1;

  digitalWrite(LEDYelPin, HIGH);  // yellow LED and red LED are on
  LEDYelState=1;
  digitalWrite(RELAYYelPin, LOW);  // yellow motor off?
  RELAYYelState=1;
  delay (8000);
  digitalWrite(LEDYelPin,LOW);     // red LED on
  digitalWrite(RELAYYelPin,HIGH);  // yellow motor on

  digitalWrite (LEDGrnPin,HIGH);  // red and green LED are on
  LEDGrnState=1;
  digitalWrite (RELAYGrnPin, LOW);  // green motor off
  RELAYGrnState=1;
  delay(2000);
  digitalWrite  (LEDGrnPin,LOW);    // red LED on
  digitalWrite (RELAYGrnPin,HIGH);  // green motor on
  RELAYGrnState=1;
}

void doLess() {
  digitalWrite(LEDRedPin, LOW);     // red LED off
  LEDRedState=0;
  digitalWrite(RELAYRedPin, HIGH);  // red motor on
  RELAYRedState=0;
  digitalWrite(LEDYelPin,LOW);      // yellow LED off
  LEDYelState=0;
}

void loop() {
  if(running){
    if (!stopped){
      doSomething();
    }
    else{
      doLess();
    }
  }
  delay(dt);
}
,

Я принял все это к сведению, спасибо, теперь я постараюсь разобраться с вашими советами ... еще раз спасибо., @Bryan Moore