Transistor interferes with Interrupt?

Hi at all,

i build the circuit shown in the image to control a simple motor with analogWrite, depending on the mode which is selected via button, which is registered als “pinMode(2, INPUT_PULLUP)”.

My problem is that the interrupt is sometimes triggered without pressing the button, but only when the pwm is set with a value of >70 %.
i also tried a normal input for the button with an pullup resistor, without effect. without the connected motor the interrup works fine…

is the curcuit itself ok, or did i forget something?

Thanks!!

pwm_interrupt.jpg

You might as well attach (or post) your sketch now.

Btw: Mode "impulsiveControl" works fine.

#######################################################################################################

// +++++++++ PINs +++++++
const int m_iPinMotor1 = 5;
const int m_iPinMotor2 = 9;
const int m_iPinLedMotor1 = 8;//++++
const int m_iPinLedMotor2 = 11;//++++
const int m_iPinButton1 = 3;//InterruptPIN
const int m_iPinButton2 = 2;//InterruptPIN

// +++++++++ Potis +++++++
int m_iValuePoti1 = 0;
int m_iValuePoti2 = 0;
volatile float m_fPwmPoti1 = 0.0;
volatile float m_fPwmPoti2 = 0.0;

// +++++++++ Systemstate +++++++
int m_iMode = 0;
int m_iModeMotor2 = 0; //Modus fuer Motor 2 (off-on-async)
long m_lLastCycleTime = 0;

// +++++++++ Systemeigenschaften +++++++
const int m_iNumberOfModes = 2;
const int m_iNumberOfMotor2Modes = 3;

volatile long lastDebounceTime = 0; // the last time the interrupt was triggered
volatile long lastDebounceTimeB1 = 0; // the last time the interrupt was triggered

void setup() {
pinMode(m_iPinButton1, INPUT);
pinMode(m_iPinButton2, INPUT_PULLUP);
pinMode(m_iPinMotor1, OUTPUT);
pinMode(m_iPinMotor2, OUTPUT);
pinMode(m_iPinLedMotor1, OUTPUT);
pinMode(m_iPinLedMotor2, OUTPUT);
attachInterrupt(0, setm_iModeMotor2, FALLING);
attachInterrupt(1, setMode, FALLING);
m_lLastCycleTime = millis();
}

// the loop routine runs over and over again forever:
void loop() {
m_iValuePoti1 = analogRead(A1);
m_fPwmPoti1 = (float) m_iValuePoti1/1023;
m_iValuePoti2 = analogRead(A2);
m_fPwmPoti2 = (float) m_iValuePoti2/1023;
setSystemValues();

long currentTime = millis();

if(m_iMode == 1) //Analog/Smooth
{
analogWrite(m_iPinMotor1, m_fPwmPoti1255);
analogWrite(m_iPinMotor2, m_fPwmPoti2
255);
}
else if (m_iMode == 2) //Impulsiv
{
impulsiveControl();
}
else
{
digitalWrite(m_iPinMotor1, LOW);
digitalWrite(m_iPinMotor2, LOW);
digitalWrite(m_iPinLedMotor1, LOW);
digitalWrite(m_iPinLedMotor2, LOW);
}

delay(1); // delay in between reads for stability
}

void impulsiveControl()
{
digitalWrite(m_iPinMotor1, HIGH);
digitalWrite(m_iPinMotor2, HIGH);
delay((m_fPwmPoti1*500));
digitalWrite(m_iPinMotor1, LOW);
digitalWrite(m_iPinMotor2, LOW);
delay((1-m_fPwmPoti1)*500);
}

void setMode()
{
long currentTime = millis();

if ((currentTime - lastDebounceTimeB1) > 450)
{
lastDebounceTimeB1 = currentTime;
m_iMode++;
if(m_iMode > m_iNumberOfModes) m_iMode = 0;
}
}

void setm_iModeMotor2()
{
long currentTime = millis();

if ((currentTime - lastDebounceTime) > 450)
{
lastDebounceTime = currentTime;
m_iModeMotor2++;
if(m_iModeMotor2 > m_iNumberOfMotor2Modes) m_iModeMotor2 = 0;
}
}

I do not understand why you need an interrupt for a manual switch.
Polling is adequate or do I misunderstand?

Whenever a microcontroller behaves oddly when a motor is attached, electrical noise is a strong suspect.

How about stripping that down to essentials - running PWM and getting an Interrupt and see how that works?

Could your power supply be crapping out when PWM > 75% ?

I could have this wrong, but my understanding (possible flawed) is:

  1. that the void loop ( ) should have sparing code and everything else going on in other functions
  2. the function that the interrupt branches to should be short on code, too

From the Arduino.cc Reference:
Note
Inside the attached function, delay() won't work and the value returned by millis() will not increment.
http://arduino.cc/en/Reference/AttachInterrupt

I do not think the interrupts are needed. Put your debounce logic in the main loop.
I suspect you did not do this because of the statement delay(1);
delay() is evil. I repeat delay() is double evil.
It is most unfortunate that so many example use this function.
Loop without this evil statement and control time of events with time interval logic. You have it half-implemented already.
{delaymicroseconds() is ok and sometimes necessary.}
If you keep your loops fast, a few millseconds at most, most input can be handled with polling.

I wish to comment on another response.

  1. that the void loop ( ) should have sparing code and everything else going on in other functions
  2. the function that the interrupt branches to should be short on code, too

(1) This is good programming style but has no technical significance.
Moving code to subroutines makes the main loop easier to understand.
(2) I agree keep interrupt handling code short, but the real issue is to get out of interrupt mode as fast as possible.

i use interrupts, because its a nice feature for asynchronous input and polling is not really my favorite.

i want to understand what is going on in the curcuit at "high load", but i unfortunately dont have a scope to look at the signals.
the strange thing is that the interrupts work without the analogwrite. Even the state with the digitalWrite-commands it working.

i use interrupts, because its a nice feature for asynchronous input and polling is not really my favorite.

It sounds like you are in a Linux or Windows mindset.
Microcontroller programs invariably run in a (hopefully) fast loop. Polling for inputs is their main activity. If you keep your loop time below 5 milliseconds then almost every input can be polled. Interrupts lead to complexity and difficult debugging issues, as you have discovered. I use interrupts only when necessary. For example detecting the echo return from an ultrasonic sensor is too fast for polling.
Asynchronous input also must occur in communications protocols.

Of course if you are using interrupts just for fun, then go for it. Just remember that a program with 3+ interrupts can become a debugging nightmare.

i want to understand what is going on in the curcuit at "high load"

Motor noise remains a prime suspect. How is the motor powered? Is it independent of the Arduino?