Как остановить цикл при использовании attachInterrupt для отслеживания изменения кнопки

Вот что делает программа:

Имеется 1 кнопка для запуска/остановки двигателя, когда он работает. загорится зеленый светодиод, при остановке загорится красный светодиод. Второй Кнопка используется для изменения направления вращения двигателя постоянного тока. Когда температура выше 20°, двигатель остановится, а серводвигатель будет Перейдите в положение красного светодиода. В противном случае серводвигатель находится в состоянии Нейтральное положение. При работающем двигателе играет музыка, которая должна звучать как автомобиль.

Итак, в чём моя проблема: если я нажимаю кнопку остановки двигателя постоянного тока, но музыка продолжает играть, она не останавливается. Я читал о break. Можно ли объединить это с attachInterrupt()? Я также нашёл такие функции, как interrupts() и noInterrupts(). Что нужно сделать, чтобы при нажатии кнопки двигатель постоянного тока сразу останавливался, а светодиод загорался красным?

Инициализация

#include <Servo.h>
#include "notebook.h";
#include "themes.h";

const int input1OfTheDCMotor = 9;
const int input2OfTheDCMotor = 10;
const int pwmInputOfTheDCMotor = 6;
const int buttonToStartStopTheDcMotor = 2;
const int buttonToShowToChangeTheDirectionOfTheDCMotor = 3;
const int greenLed = 12;
const int redLed = 8;
const int tempSensor = A0;
const int servoPin = 11;
Servo servo;


volatile byte stateOfTheButtonToStartStopTheDCMotor = LOW;
bool isRunning = LOW;
bool changeDirection = LOW;
bool isEngineSoundsPlaying = HIGH;

setup()

void setup() {
  //Настройка светодиодов
  pinMode(greenLed, OUTPUT);
  pinMode(redLed, OUTPUT);
  digitalWrite(redLed, HIGH);
  //кнопки
  pinMode(buttonToStartStopTheDcMotor, INPUT);
  pinMode(buttonToShowToChangeTheDirectionOfTheDCMotor, INPUT);
  //двигатель постоянного тока
  pinMode(input1OfTheDCMotor, OUTPUT);
  pinMode(input2OfTheDCMotor, OUTPUT);
  digitalWrite(input1OfTheDCMotor, LOW);
  digitalWrite(input2OfTheDCMotor, HIGH);
  //ШИМ-сигнал
  pinMode(pwmInputOfTheDCMotor, OUTPUT);
  //Сервопривод
  servo.attach(servoPin);
  //прерывания
  attachInterrupt(digitalPinToInterrupt(buttonToStartStopTheDcMotor), readTheChangeToStartStop, RISING );
  attachInterrupt(digitalPinToInterrupt(buttonToShowToChangeTheDirectionOfTheDCMotor), readTheChangeToChangeDirection, RISING );
}

Цикл ()

void loop() {
  int valueOfTheSensor = analogRead(tempSensor);
  float voltage = (valueOfTheSensor / 1024.0) * 5.0;
  float temp = (voltage -0.5) * 100;
  if (temp >= 20.00) 
    isRunning = LOW;
  }
  changeTheStateOfTheLights(isRunning);
  startTheDCMotorAndStopIt(isRunning);
  changeTheDirectionOfTheDCMotor(changeDirection);
}

Функция readTheChangeToStartStop():

void readTheChangeToStartStop () {
  isRunning  = !isRunning;
  changeTheStatusOfTheEnginePlaying();
}

Функция readTheChangeToChangeDirection():

void readTheChangeToChangeDirection () {
  changeDirection = !changeDirection;
}

Функция changeTheStatusOfTheEnginePlaying():

void changeTheStatusOfTheEnginePlaying (){
  if (isRunning == HIGH){
    isEngineSoundsPlaying = HIGH;
  } else {
    isEngineSoundsPlaying = LOW;
  }
}

Функция changeTheStateOfTheLights():

void changeTheStateOfTheLights(bool stateOfLight) {
  digitalWrite(greenLed, stateOfLight);
  digitalWrite(redLed, !stateOfLight);
}

Функция startTheDCMotorAndStopIt():

void startTheDCMotorAndStopIt(bool isRunning){
  if (isRunning == HIGH) {
    digitalWrite(pwmInputOfTheDCMotor, HIGH);
    playCarMusicStart();
    changeToNeutral();
  } else {
    digitalWrite(pwmInputOfTheDCMotor, LOW);
    changeToRedLight();
  }
}

Функция changeTheDirectionOfTheDCMotor():

void changeTheDirectionOfTheDCMotor(bool changeDirection) {
  digitalWrite(input1OfTheDCMotor, changeDirection);
  digitalWrite(input2OfTheDCMotor, !changeDirection);
}

Функция changeToRedLight():

void changeToRedLight() {
  servo.write(0);
  delay(15);
}

Функция changeToNeutral():

void changeToNeutral() {
  servo.write(40);
  delay(15);
}

Функция playCarMusicStart():

void playCarMusicStart(){
  if (isEngineSoundsPlaying == HIGH) {
    for (int thisNote = 0; thisNote < (sizeof(carSounds_note)/sizeof(int)); thisNote++) {
      int noteDuration = 1000 / carsounds_duration[thisNote];
      tone(4, carSounds_note[thisNote], noteDuration);
      int pauseBetweenNotes = noteDuration * 2.70;
      delay(pauseBetweenNotes);
      noTone(4); 
      isEngineSoundsPlaying = LOW;
    }
  }
}

Решение

Огромное спасибо @ratchet freak

Мне нужно изменить мой loop() на это:

void loop() {
  int valueOfTheSensor = analogRead(tempSensor);
  float voltage = (valueOfTheSensor / 1024.0) * 5.0;
  float temp = (voltage -0.5) * 100;
  if (temp >= 20.00) {
    isRunning = LOW;
  }
  changeTheStateOfTheLights(isRunning);
  startTheDCMotorAndStopIt(isRunning);
  changeTheDirectionOfTheDCMotor(changeDirection);


  playCarMusicStart();
}

Мне также нужно было изменить PlayCarMusicStart():

void playCarMusicStart(){
  if (isEngineSoundsPlaying == HIGH && currentNote < (sizeof(carSounds_note)/sizeof(int))) {
      int noteDuration = 1000 / carsounds_duration[currentNote];
      tone(4, carSounds_note[currentNote], noteDuration);
      int pauseBetweenNotes = noteDuration * 2.70;
      delay(pauseBetweenNotes);
      noTone(4);
      currentNote++;
   } else {
      currentNote = 0;
   }
}

И самое меньшее — это установить isEngineSoundsPlaying равным HIGH, я изменил функцию startTheDCMotorAndStopIt() на:

void startTheDCMotorAndStopIt(bool isRunning){
  if (isRunning == HIGH) {
    isEngineSoundsPlaying = HIGH;
    digitalWrite(pwmInputOfTheDCMotor, HIGH);
    changeToNeutral();
  } else {
    isEngineSoundsPlaying = LOW;
    digitalWrite(pwmInputOfTheDCMotor, LOW);
    changeToRedLight();
  }
}

, 👍1


1 ответ


Лучший ответ:

2

Ключевым моментом будет разделение playCarMusicStart и создание вместо него playCarMusicStep, который выполнит только одну итерацию цикла и вернётся. Вызывайте его каждый раз в loop(), аналогично blinkWithoutDelay.

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

А когда вам нужно остановить музыку, вы останавливаете ее, устанавливая правильную переменную.

,