Controlling PWM with Multiple Interrupts

Hi all,

I have the following code:

int motor = 11; // Attach the motor to pin 11
int pot = A0; // Attach the potentiometer to Analog 0
int sp = 0;   // the speed to run the motor at
int potValue = 0; // The current value of the potentiometer

int fsindicator = 13;         // The pin to change if "full speed" is set to "on"
volatile int fullspeed = LOW; // The interrupt for fullspeed (HIGH == On, LOW == Off)
volatile int pnum = 0;        // The Pattern Number to use (0 == Off)
volatile int pstate = LOW;    // The interrupt value for the patterns (HIGH == On, LOW == Off)

void setup()  // setup loop
{
  pinMode(fsindicator, OUTPUT);          // Set the Full Speed Indicator as an output
  attachInterrupt(0, fullpower, CHANGE); // Monitor interrupt 0 for switching to full power
  attachInterrupt(1, patterns, CHANGE);  // Monitor interrupt 1 for switching patterns
  pinMode(motor, OUTPUT);                // Declare the motor as an output
  pinMode(pot, INPUT);                   // Declare the pot as an input
  Serial.begin(9600);                    // Open the serial communication port so we can read the serial monitor
}

void loop()
{
  // If we're set for full speed, go for it
  if ( fullspeed == HIGH ){
    sp = 0;
    analogWrite(motor, sp); // Set the motor speed to 100%

  }
  // Check to see if we should be using a pattern
  else if ( pnum != 0 ){
      // Whilst the pattern is in use, pulse the motor
      while ( pnum != 0) {
        analogWrite(motor, 0);
        delay(1000);
        analogWrite(motor, 128);
      }
  }
  // Otherwise, read from the pot and set the value accordingly
  else
  {
    potValue = analogRead(pot); // reads the voltage from the potentiomter and saves in potValue
    sp = map(potValue, 1024, 0, 255, 0);
    analogWrite(motor, sp); // Write the remapped speed
  }
  digitalWrite(fsindicator, fullspeed);
  Serial.print(sp);
  Serial.print("t");
  Serial.print(fullspeed);
  Serial.print("t");
  Serial.print(pnum);
  Serial.print("n");
}

void patterns()
{
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  // If interrupts come faster than 200ms, assume it's a bounce and ignore
  if (interrupt_time - last_interrupt_time > 200) 
  {
    if ( pstate == HIGH){
      pnum = random(1,5);
    }
    else 
    {
      pnum = 0;
    }
    pstate = !pstate;
  }
  last_interrupt_time = interrupt_time;
}

void fullpower()
{
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  // If interrupts come faster than 200ms, assume it's a bounce and ignore
  if (interrupt_time - last_interrupt_time > 200) 
  {
    fullspeed = !fullspeed;
  }
  last_interrupt_time = interrupt_time;
}

The idea behind it is that the speed of a motor can be controlled via PWM using a potentiometer, however there are two additional buttons on the control panel.

The first button (interrupt 0) should override the value from all other settings and set the motor to full speed. This works.

The second button (interrupt 1) should override the value of the pot but not the first interrupt and set the motor to pulse mode.

At the moment the pot controls the speed fine, the first switch sets the motor to full speed however the second interrupt doesn't appear to work even when the first switch is set to OFF.

I've not played with interrupts before, however the pulsing pattern may need to be interrupted by the first switch even if it is mid-pulse, so I'm fairly sure that interrupts are the way to go here.

I'm open to alternative approaches to this, let me know if you need a circuit diagram and I'll try and get one put together.

Thanks in advance,

Matt

I had an email saying that there was a reply to this, but the reply seems to have disappeared - the email I have said that there was "another way" without using Interrupts - can someone explain what that other way might be?

Hi,
If all you want to do is go from variable to two different motor speeds with two buttons and a potentiometer, then a couple of if statements checking the button status should be enough.

Button 1 LOW, Button 2 LOW speed = analog input
Button 1 HIGH, speed = full
Button 2 HIGH and Button 1 LOW, speed = pulse mode

Use millis in your pulse and do not use delays.

Tom.... :slight_smile:

See the very first post in this forum. You should not be using interrupts for this and they do not do what you think.

Mark

holmes4:
See the very first post in this forum. You should not be using interrupts for this and they do not do what you think.

Mark

Brilliant, thanks Mark, that looks like exactly what I am looking for.

Matt

TomGeorge:
Hi,
If all you want to do is go from variable to two different motor speeds with two buttons and a potentiometer, then a couple of if statements checking the button status should be enough.

Button 1 LOW, Button 2 LOW speed = analog input
Button 1 HIGH, speed = full
Button 2 HIGH and Button 1 LOW, speed = pulse mode

Use millis in your pulse and do not use delays.

Tom.... :slight_smile:

Thanks Tom :slight_smile: