stopping a DC motor with interrupt

So I have a DC motor that can turn both way's but my problem is that when I press my button for a external interrupt the motor needs to stop until I release the button. I will include my code and setup

int switchstate = 0;
int switchstate_2 = 0;
int pin_status = 0;
void setup() {
pinMode (2, INPUT); // interrupt button
pinMode (4, INPUT); // button for the other way
pinMode (6, OUTPUT); // H-bridge right way
pinMode (3, OUTPUT); // H-bridge on/off
pinMode (5, OUTPUT); // H-bridge left way
attachInterrupt (0, IRS, FALLING);
}

void loop() {
analogWrite (3, 127);
pin_status = digitalRead (5);
  if (pin_status == LOW){
  digitalWrite (5, LOW );
  delay (100);
  digitalWrite (6, HIGH);
  }
switchstate = digitalRead (4);
if (switchstate == HIGH){
digitalWrite (6, LOW);
delay (100);  
digitalWrite (5, HIGH);
    
  }
}

void IRS(){
 digitalWrite (6, LOW);
 digitalWrite (5, LOW);
}

deadlyscout:
So I have a DC motor that can turn both way's but my problem is that when I press my button for a external interrupt the motor needs to stop until I release the button. I will include my code and setup''

But you only stop the motor inside your interrupt code, which may take only a millisecond, then the rest of your code carries on from where ever it was interrupted.
There is absolute NO reason to try interrupts to test the instant a switch is pressed.
You need to determine WHEN the switch is pressed and when it is released.
Paul

That is not what interrupts are for!

As a beginner, it is incredibly unlikely that interrupts will be useful to you.

A common "newbie" misunderstanding is that an interrupt is a mechanism for altering the flow of a program - to execute an alternate function. Nothing could be further from the truth! :astonished:

An interrupt is a mechanism for performing an action which can be executed in "no time at all" with an urgency that it must be performed immediately or else data - information - will be lost or some harm will occur. It then returns to the main task without disturbing that task in any way though the main task may well check at the appropriate point for a "flag" set by the interrupt.

Now these criteria are in a microprocessor time scale - microseconds. This must not be confused with a human time scale of tens or hundreds of milliseconds or indeed, a couple of seconds. A switch operation is in this latter category and even a mechanical operation perhaps several milliseconds; the period of a 6000 RPM shaft rotation is ten milliseconds. Sending messages to a video terminal is clearly in no way urgent,

Unless it is a very complex procedure, you would expect the loop() to cycle many times per millisecond. If it does not, there is most likely an error in code planning; while the delay() function is provided for testing purposes, its action goes strictly against effective programming methods. The loop() will be successively testing a number of contingencies as to whether each requires action, only one of which may be whether a particular timing criteria has expired. Unless an action must be executed in the order of mere microseconds, it will be handled in the loop().

So what sort of actions do require such immediate attention? Well, generally those which result from the computer hardware itself, such as high speed transfer of data in UARTs(, USARTs) or disk controllers.

An alternate use of interrupts, for context switching in RTOSs, is rarely relevant to this category of microprocessors as it is more efficient to write cooperative code as described above.

void IRS(){ sp. "void ISR () {"

TheMemberFormerlyKnownAsAWOL:

void IRS(){

sp. "void ISR () {"

That will mess with OPs code who attached the interrupt to a function called IRS...

I think it might work if you change this:

void IRS()
{
  digitalWrite (6, LOW);
  digitalWrite (5, LOW);
}

to this:

void IRS()
{
  digitalWrite (6, HIGH);
  digitalWrite (5, HIGH);
}

Your 'loop()' is looking at the state of Pin 5 and if it is LOW it sets Pin 6 to HIGH. By setting both to HIGH the motor will stop and stay stopped. Unfortunately, you have no code to start the motor again when you release the stop button.

This is one way to do it without interrupts. We watch for changes in the inputs from the buttons. When a button is pressed or released, we act on it. All buttons are wired between the pin and Ground so we can use the internal pull-up resistor.

const byte ButtonCount = 3;
const byte ButtonPins[ButtonCount] = {2, 7, 4};
enum ButtonNames {ForwardButton, ReverseButton, PauseButton};
const unsigned long DebounceTime = 30;


boolean ButtonWasPressed[ButtonCount];  // Defaults to 'false'
boolean ButtonChangedState[ButtonCount];  // Defaults to 'false'


const int MotorPinA = 5;
const int MotorPinB = 6;
const int MotorEnablePin = 3;


boolean GoingForward = true;  // Keep track of the last selected direction so we can end a pause


unsigned long ButtonStateChangeTime = 0; // Debounce timer common to all buttons


void setup()
{
  Serial.begin(115200);


  pinMode(MotorPinA, OUTPUT);
  pinMode(MotorPinB, OUTPUT);
  pinMode(MotorEnablePin, OUTPUT);


  analogWrite(MotorEnablePin, 127);  // Set for half speed


  for (byte i = 0; i < ButtonCount; i++)
  {
    pinMode (ButtonPins[i], INPUT_PULLUP);  // Button between Pin and Ground
  }
}


void loop()
{
  checkButtons();
}


void checkButtons()
{
  unsigned long currentTime = millis();


  // Update the buttons
  for (byte i = 0; i < ButtonCount; i++)
  {
    boolean buttonIsPressed = digitalRead(ButtonPins[i]) == LOW;  // Active LOW
    ButtonChangedState[i] = false;


    // Check for button state change and do debounce
    if (buttonIsPressed != ButtonWasPressed[i] &&
        currentTime  -  ButtonStateChangeTime > DebounceTime)
    {
      // Button state has changed
      ButtonStateChangeTime = currentTime;
      ButtonChangedState[i] = true;
      ButtonWasPressed[i] = buttonIsPressed;
    }
  }


  // Act on the the buttons
  for (byte i = 0; i < ButtonCount; i++)
  {
    if (ButtonChangedState[i])
    {
      if (ButtonWasPressed[i])
      {
        switch (i)
        {
          case ForwardButton:
            GoingForward = true;
            digitalWrite(MotorPinA, LOW);
            digitalWrite(MotorPinB, HIGH);
            break;


          case ReverseButton:
            GoingForward = false;
            digitalWrite(MotorPinA, HIGH);
            digitalWrite(MotorPinB, LOW);
            break;


          case PauseButton:
            digitalWrite(MotorPinA, LOW);
            digitalWrite(MotorPinB, LOW);
            break;
        }
      }
      else
      {
        // Button was just released


        if (i == PauseButton)  // We only care about the release of the pause
        {
          // Pause released.  Resume the direction.
          if (GoingForward)
          {
            digitalWrite(MotorPinA, LOW);
            digitalWrite(MotorPinB, HIGH);
          }
          else
          {
            digitalWrite(MotorPinA, HIGH);
            digitalWrite(MotorPinB, LOW);
          }
        }
      }
    }
  }
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.