Go Down

Topic: Mega 1280: Only 1 Interrupt Pin is Working? (Read 4094 times) previous topic - next topic

Swim100flyy

I have a problem with interrupts on my arduino MEGA (1280)....My Interrupt 0 (Pin 2) works perfectly, however, none of my other interrupt pins seem to work. Here's an abbreviated portion of my code:
Code: [Select]
#include <avr/interrupt.h>  // define interrupts library

void setup()
{
   Serial.begin(9600);  // Used for debugging and telemetry
   attachInterrupt(0, iTrigger, RISING); // Digital Pin 2
   attachInterrupt(1, kTrigger, RISING); // Digital Pin 3
}

void loop()
{
   if (rpmcount >= 3){ tachometer(); } // Update RPM every 3 counts, increase for resolution decrease for faster updates 
   if (speedcount >= 3) { speedometer(); } // Update SPEED every 3 counts, increase for resloution decrease for faster updates
}

void iTrigger() // Tachometer Interrupt
{
   rpmcount++;     //Each rotation, this interrupt function is run once.
}

void kTrigger() // Speedometer Interrupt
{
   speedcount++;   //Each gear rotation, this interrupt function is run once.
}



Any ideas?

Thanks :)

retrolefty

Yes, I believe your variables speedcount and rpmcount need to be made global and volatile. I believe you have a variable scoping problem as written.

http://arduino.cc/en/Reference/Volatile

http://arduino.cc/en/Reference/Scope

Lefty

Swim100flyy

My apologies, I had that but forgot to include it.

I made this quick testing code:
Code: [Select]
#include <avr/interrupt.h>  // define interrupts library
#include "math.h"

volatile byte Acount;
volatile byte Bcount;
volatile byte Ccount;
volatile byte Dcount;
volatile byte Ecount;
volatile byte Fcount;


void setup()
{
   Serial.begin(9600);  // Used for debugging and telemetry
   attachInterrupt(0, iTrigger, RISING); // Digital Pin 2
   attachInterrupt(1, jTrigger, RISING); // Digital Pin 3
   attachInterrupt(2, kTrigger, RISING); // Digital Pin 21
   attachInterrupt(3, lTrigger, RISING); // Digital Pin 20
   attachInterrupt(4, mTrigger, RISING); // Digital Pin 19
   attachInterrupt(5, nTrigger, RISING); // Digital Pin 18
   Acount=0;
   Bcount=0;
   Ccount=0;
   Dcount=0;
   Ecount=0;
   Fcount=0;
}

void loop()
{
    Serial.println("----------------------------");
  Serial.print("Interrupt 0: ");
  Serial.println(Acount);
  Serial.print("Interrupt 1: ");
  Serial.println(Bcount);
  Serial.print("Interrupt 2: ");
  Serial.println(Ccount);
  Serial.print("Interrupt 3: ");
  Serial.println(Dcount);
  Serial.print("Interrupt 4: ");
  Serial.println(Ecount);
  Serial.print("Interrupt 5: ");
  Serial.println(Fcount);
    Serial.println("----------------------------");
}

void iTrigger() // Tachometer Interrupt
{
   Acount++;     //Each rotation, this interrupt function is run once.
}

void jTrigger() // Speedometer Interrupt
{
   Bcount++;   //Each gear rotation, this interrupt function is run once.
}

void kTrigger() // Tachometer Interrupt
{
   Ccount++;     //Each rotation, this interrupt function is run once.
}

void lTrigger() // Speedometer Interrupt
{
   Dcount++;   //Each gear rotation, this interrupt function is run once.
}

void mTrigger() // Tachometer Interrupt
{
   Ecount++;     //Each rotation, this interrupt function is run once.
}

void nTrigger() // Speedometer Interrupt
{
   Fcount++;   //Each gear rotation, this interrupt function is run once.
}



The purpose is to determine which interrupts work....It seems I can only get 2 interrupts to work (interrupt 0 and interrupt 4).


Is there any reason why they wouldn't be functioning?

davekw7x

#3
Apr 28, 2011, 12:14 am Last Edit: Apr 28, 2011, 12:29 am by davekw7x Reason: 1

...testing code:...Is there any reason why they wouldn't be functioning?


What do you have connected to those input pins?  Switches to +5 with pulldown resistors on each pin?  Or what?


Regards,

Dave

Swim100flyy

Yessir. I have a second arduino that is sending off High/Low's (through a 1k resistor) at different intervals.

davekw7x


...second arduino that is sending off High/Low's ...at different intervals.

Is there one external signal and all of the input pins tied together or are there six different external signals?

How often are the external interrupts generated?

Have you tried slowing things down to a few interrupts per second for each pin and putting a 1000 millisecond delay in the loop() function so that you can make absolutely sure that each pin has time to get several interrupts between loops?  (And to make sure that you can actually see the count?)

Have you tried just attaching one interrupt (to one pin) at a time and seeing if each one counts?


Regards,

Dave

Swim100flyy

I am running the Mega with the code above, having all of the interrupts waiting for an input. Once it is seen, it serial prints a character out.

The second arduino (diecimila) is doing a HIGH (delay 100) Low (delay 100) loop.

The Mega's interrupt 0 (on pin 2) picks up the signal just fine. Both arduinos are grounded to eachother. I manually take the output signal wire and touch it to each of the interrupt pins on the Mega.

Here's the kicker...

Sometimes a different interrupt will trigger, but it cannot be repeated (possibly capacitive noise?)

I tried:   GND -----/\/-----Signal In-------/\/------Interrupt Pin
                         10k          |              1k
                                        |

to filter noise. It works perfect on interrupt 0, but not on any of the other interrupt pins.

davekw7x

#7
Apr 28, 2011, 01:58 am Last Edit: Apr 28, 2011, 03:08 am by davekw7x Reason: 1

I am running the Mega with the code above, having all of the interrupts waiting for an input. Once it is seen, it serial prints a character out.
The code that you posted prints out all of the counters as fast as it can go through the loop.

Quote from: Swim100flyy

The second arduino (diecimila) is doing a HIGH (delay 100) Low (delay 100) loop.
So, put a delay(1000) or delay(2000) or some such thing at the bottom of the loop to let you see what is going on.


Quote from: Swim100flyy

I tried:...

Here's my suggestion:  Enable internal pullups on all input pins.

Forget the 10K to ground.

Connect the external signal to each input pin (one at a time) through the resistor and tell us what happens.

Make sure the grounds are really connected solidly together through as short a wire as you can arrange.


Regards,

Dave

On the Mega1280:
Code: [Select]

// Pin numbers for the external interrupt inputs are
// for Arduino Mega boards.
//
// Tested on Mega1280
//
//  davekw7x
//

#include <avr/interrupt.h>

volatile byte Acount;
volatile byte Bcount;
volatile byte Ccount;
volatile byte Dcount;
volatile byte Ecount;
volatile byte Fcount;


void setup()
{
   Serial.begin(9600);
   //
   // Set pullup resistors on external interrupt pins
   //
   digitalWrite(2, HIGH);
   digitalWrite(3, HIGH);
   digitalWrite(18, HIGH);
   digitalWrite(19, HIGH);
   digitalWrite(20, HIGH);
   digitalWrite(21, HIGH);
   //
   // Connect pins to interrupt routines
   //
   attachInterrupt(0, iTrigger, RISING); // Digital Pin 2
   attachInterrupt(1, jTrigger, RISING); // Digital Pin 3
   attachInterrupt(2, kTrigger, RISING); // Digital Pin 21
   attachInterrupt(3, lTrigger, RISING); // Digital Pin 20
   attachInterrupt(4, mTrigger, RISING); // Digital Pin 19
   attachInterrupt(5, nTrigger, RISING); // Digital Pin 18
}

void loop()
{
   Serial.println("----------------------------");
   Serial.print("Interrupt 0: ");
   Serial.println(Acount,DEC);
   Serial.print("Interrupt 1: ");
   Serial.println(Bcount,DEC);
   Serial.print("Interrupt 2: ");
   Serial.println(Ccount,DEC);
   Serial.print("Interrupt 3: ");
   Serial.println(Dcount,DEC);
   Serial.print("Interrupt 4: ");
   Serial.println(Ecount,DEC);
   Serial.print("Interrupt 5: ");
   Serial.println(Fcount,DEC);
   delay(2000);

}

void iTrigger()
{
   Acount++;
}

void jTrigger()
{
   Bcount++;
   
}

void kTrigger(
{
   Ccount++;
}

void lTrigger()
{
   Dcount++;
}

void mTrigger()
{
   Ecount++;
}

void nTrigger()
{
   Fcount++;
}


On the driving Duemilanove:
Code: [Select]

void setup()
{
   pinMode(13, OUTPUT);
}

void loop()
{
   digitalWrite(13, HIGH);
   delay(100);
   digitalWrite(13, LOW);
   delay(100);
}


(Make sure that the grounds are securely connected.)

Swim100flyy

Alright.. So I was able to do some more testing today.

Davekw7x - you were right on track with the problem. For future people having the same issue as me, this is my solution:

1. Apparently the MEGA does not handle interrupt functions the same way that the smaller arduino's do. It is advantageous to declare all of the interrupt functions (if you have more than 1) BEFORE you declare your void setup() and void loop() functions. http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1172808516/1

2. The volatile byte VARIABLE_NAME prints out characters and symbols in the serial output, but not numbers. I changed this variable declaration for a counter to be volatile int COUNT. This made much more logical sense. I don't know whether or not it changed anything low-level wise, but it logically makes sense to see how many pulses have been interrupt counted on the serial output.

3. I changed all of my interrupt pins to enable the Pull-up Resistors like Davekw7x suggested:

Code: [Select]
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(18, HIGH);
    digitalWrite(19, HIGH);
    digitalWrite(20, HIGH);
    digitalWrite(21, HIGH);


and removed the 10k resistors to ground (to steer away from noise).



So in all - a combination of those 3 changes made the interrupts function properly!


My last question -
  with the duemilanove looping High, Delay, Low, Delay, it is essential grounding out the pull-up resistor on the MEGA, allowing the interrupt to be read.     However, in implementation I will be reading the square wave output from a Camshaft sensor on an engine. I'm a bit concerned that the signal will never fully ground out (I.E. It should theoretically go 0-5v, but in practice it might be 0.5-4.8v). Will this still register as an interrupt?

Thanks a lot!

Mike.

davekw7x

#9
Apr 28, 2011, 11:38 pm Last Edit: May 02, 2011, 08:36 am by davekw7x Reason: 1

...
1. Apparently the MEGA does not handle interrupt functions the same way that the smaller arduino's do.
I'm not sure what you are getting at.  I showed the code that I used for testing on my Mega1280.  The code is exactly the same as I used with  my '328P boards (except, obviously, I only had two external interrupts for the smaller CPUs).

Quote from: Swim100flyy

... I changed ...This made much more logical sense.
I was trying to use code reasonably similar to yours rather than impose my coding style or design methodology.   The point was to get consistent results (with your particular test setup) from all external interrupt input pins.

Quote from: Swim100flyy

So in all - a combination of those 3 changes made the interrupts function properly!

Huzzah!!!
Now that you know it can be done, there are lots of ways to hook things up and to use the interrupt information, depending on your real application requirements.

Quote from: Swim100flyy

My last question -
...I will be reading the square wave output from a Camshaft sensor on an engine....


With off-board mechanical (or other) sensors, I would normally use optical isolators to convert external voltage or current values to logic values into the Arduino.  This helps protect against ground noise (and other noisy stuff) that could not only cause measurement errors, but could actually be destructive.


Regards,

Dave

Go Up