1

This what the program does:

There is 1 button to start/stop the engine, when the motor is running the green LED will go on, when stopped the red LED is on. The second button is used to change the direction of the DC-motor. When the temperature is above 20° the motor will stop and the servo motor will go to the position of the red LED. Otherwise the servo motor is in a neutral position. When the engine is running there a music playing that should sound as a car.

So what my problem is if I pressed the button to stop the DC-motor but the music is still playing it won't stop. I read something about a break. Can you combine this with the attachInterrupt()? I also found something called interrupts() and noInterrupts(). What do I need to so when I pressed the button the DC-Motor directly stops and the led turns red?

The init

#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;

The setup()

void setup() {
  //Leds setup
  pinMode(greenLed, OUTPUT);
  pinMode(redLed, OUTPUT);
  digitalWrite(redLed, HIGH);
  //buttons
  pinMode(buttonToStartStopTheDcMotor, INPUT);
  pinMode(buttonToShowToChangeTheDirectionOfTheDCMotor, INPUT);
  //DC motor
  pinMode(input1OfTheDCMotor, OUTPUT);
  pinMode(input2OfTheDCMotor, OUTPUT);
  digitalWrite(input1OfTheDCMotor, LOW);
  digitalWrite(input2OfTheDCMotor, HIGH);
  //pwm signal
  pinMode(pwmInputOfTheDCMotor, OUTPUT);
  //Servo
  servo.attach(servoPin);
  //interrupts
  attachInterrupt(digitalPinToInterrupt(buttonToStartStopTheDcMotor), readTheChangeToStartStop, RISING );
  attachInterrupt(digitalPinToInterrupt(buttonToShowToChangeTheDirectionOfTheDCMotor), readTheChangeToChangeDirection, RISING );
}

The 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);
}

The function readTheChangeToStartStop():

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

The function readTheChangeToChangeDirection():

void readTheChangeToChangeDirection () {
  changeDirection = !changeDirection;
}

The function changeTheStatusOfTheEnginePlaying():

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

The function changeTheStateOfTheLights():

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

The function startTheDCMotorAndStopIt():

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

The function changeTheDirectionOfTheDCMotor():

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

The function changeToRedLight():

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

The function changeToNeutral():

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

The function 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;
    }
  }
}

Solution

A big thanks to @ratchet freak

I need to change my loop() to this:

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();
}

I also needed to change the 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;
   }
}

And the least is to set the isEngineSoundsPlaying equal to HIGH, I changed the function startTheDCMotorAndStopIt() for:

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

1 Answer 1

2

The key will be to split up playCarMusicStart and instead create a playCarMusicStep that will do just one iteration of the loop and returns. Call it every time in loop() akin to blinkWithoutDelay.

In playCarMusicStart you then setup the playing state so it starts playing correctly.

And when you need to stop it you then stop the music by setting the correct variable.

4
  • You mean this with blinkWithoutDelay arduino.cc/en/Tutorial/BlinkWithoutDelay
    – Steven
    Commented Apr 19, 2018 at 13:42
  • The music loops takes 7400ms so when I pressed the button how can I stopped immediately without waiting 7400ms
    – Steven
    Commented Apr 19, 2018 at 14:00
  • by returning immediately after starting the music and calling the function again when new processing needs to occur for the next note/pauze Commented Apr 19, 2018 at 14:03
  • Thanks I updated the question with the solution a big thanks for helping me!
    – Steven
    Commented Apr 19, 2018 at 14:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.