PDA

View Full Version : Attach Interrupt question



keithg
11-09-2012, 01:44 PM
Trying to test the attach interrupt function in the ArduinoIDE and on teensy3. This compiles and loads with the teensyduino beta6. I have a wire between 13 and 0 and I get no pulses counted in the ISR. The loop counts and runs, I see the pulse_train going 1 and 0 and the led is flashing. I assume I am doing something wrong. I use similar code in a breadboard with a Mega and count pulses from a pump and it works flawlessly. I am investigating moving this to a Teensy3 and wanted to investigate this function. I assume I am doing something wrong. Why do I get no ISR service?


/* sketch to verify external interrupt...
*/

#include <LiquidCrystal_I2C.h>
#include <Wire.h> // needed for i2c display

LiquidCrystal_I2C lcd(0x20);

int pulse_out = 13; // pulses out on 13
int int_input = 0; // interrupt on 0
int count;
int loop_num = 0;

float dispensed = 0; // dispensed volume
boolean pulse_train = false;

void setup()
{
// set up display
lcd.begin(16,2);
lcd.clear();
// set up pins in and out
pinMode(pulse_out,OUTPUT);
attachInterrupt(int_input, counterloop, FALLING); // pin 0 pulses input
}
void loop()
{
dispensed = count;
lcd.setCursor(0,0);
lcd.print(dispensed,0);
// flop the output and boolean var each time through loop
if (pulse_train == true) {
digitalWrite(pulse_out,false);
pulse_train = false; }
else {digitalWrite(pulse_out,true);
pulse_train = true; }
lcd.setCursor(0,1);
lcd.print(pulse_train);
loop_num++;
lcd.setCursor(5,0);
lcd.print(loop_num);
delay(1000);
}

// ISRs for counting fluid transfer
void counterloop() { // loop to totalize
count = count + 1; }

jwmelvin
11-09-2012, 05:01 PM
Don't you have to define count as a volatile int?

keithg
11-09-2012, 05:28 PM
Don't you have to define count as a volatile int?

Yes, good catch. I will try it again and see if that small edit fixes it.

Regards,

Keith

el_supremo
11-09-2012, 05:51 PM
I have the same problem when using a DS3234 SPI (DeadOn RTC).
The debugging code in loop(), when SQW_TEST is defined, just looks for the falling edge of SQW and toggles the LED on Pin 14 on and off as it should. The LED does not blink if I try attaching the interrupt instead (with SQW_TEST undefined). The attach works on a Nano.



#include <SPI.h>
/*
Just wire it up like this.
Pin 13 SCK
Pin 12 MISO
Pin 11 MOSI
Pin 10 SS
*/


const int RTC_SELECT_PIN=10; //chip select

// RTC interrupt (SQW) connected to this pin.
// The interrupt routine then toggles LED_PIN
#define RTC_ALARM_PIN 2

// NOTE THAT PIN 13 CAN'T BE USED AS A LED OUTPUT
// BECAUSE THE SPI library uses it
#define LED_PIN 14

volatile short outbit = 0;

//=====================================
void rtc_int(void)
{
// Toggle the LED pin
outbit ^= 1;
digitalWrite(LED_PIN, outbit);
}

//=====================================
void setup()
{
pinMode(10, OUTPUT);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);

// Set up the RTC interrupt pin
pinMode(RTC_ALARM_PIN, INPUT_PULLUP);

RTC_init();

// When SQW_TEST is not defined use the interrupt
// otherwise do a simple test in loop() to ensure that SQW is working

//#define SQW_TEST
#ifndef SQW_TEST
attachInterrupt(0, rtc_int,FALLING);
#endif

}


int sqw_state = 0;
//=====================================
void loop()
{
// A simple test just to make sure that SQW is running

#ifdef SQW_TEST
if(sqw_state == 0) {
if(digitalRead(RTC_ALARM_PIN))sqw_state = 1;
return;
} else {
if(digitalRead(RTC_ALARM_PIN))return;
// simulate the interrupt
outbit ^= 1;
digitalWrite(LED_PIN, outbit);
sqw_state = 0;
return;
}
#endif
}

//=====================================
void RTC_init(void)
{

pinMode(RTC_SELECT_PIN,OUTPUT); // chip select
// start the SPI library:
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE1); // both mode 1 & 3 should work
//set control register

digitalWrite(RTC_SELECT_PIN, LOW);
SPI.transfer(0x8E);
// Rate select = 00 (1Hz)
// Interrupt Control off (to permit square wave output)
// Disable Alarm 1 and 2
SPI.transfer(0x00);
digitalWrite(RTC_SELECT_PIN, HIGH);
delay(10);

}


Pete

keithg
11-10-2012, 02:40 AM
I looked over the sketches. I did not set the variable as volatile, but it works on the Arduino Mega. On Teensy 3.0 it does not work if it is volatile int or just int.

Keith

keithg
11-10-2012, 03:59 AM
I grabbed beta 7 and tried it again. Made a couple edits and something is still wrong as I do not seem to have any interrupt activity.

loop_num increases
pulse_train oscillates between 0 and 1
the LED flashes
count stays at 0 with no change...


/* sketch to verify external interrupt...
version 2
*/

#include <LiquidCrystal_I2C.h>
#include <Wire.h> // needed for i2c display

LiquidCrystal_I2C lcd(0x20);

int pulse_out = 12; // pulses out on 12
int led = 13; // flash LED with pin 12
int int_input = 0; // interrupt on 0
volatile int count = 0; // interrupt counter
int loop_num = 0; // loop counter
boolean pulse_train = false;

void setup()
{
// set up display
lcd.begin(16,2);
lcd.clear();
// set up pins in and out
pinMode(pulse_out,OUTPUT);
pinMode(led, OUTPUT);
attachInterrupt(int_input, counterloop, FALLING);
}
void loop()
{
lcd.setCursor(0,0);
lcd.print(count);
// flop the output and boolean var each time through loop
if (pulse_train == true) {
digitalWrite(pulse_out,LOW);
digitalWrite(led, LOW);
pulse_train = false;
}
else {
digitalWrite(pulse_out,HIGH);
digitalWrite(led, HIGH);
pulse_train = true;
}
lcd.setCursor(0,1);
lcd.print(pulse_train);
loop_num++;
lcd.setCursor(5,0);
lcd.print(loop_num);
delay(1000); // wait a second
}

// ISR for counting pulses
void counterloop() {
count = count + 1; }

DougALug
11-10-2012, 02:39 PM
I am just wondering. According to the Arduino documentation, int0 is tied to pin 2 or pin 3 (depending on the model). Have you tried putting a jumper from pin 12 to pin 2 or 3? Just a thought.

Paul
11-10-2012, 03:15 PM
On Teensy 3.0, INT0 is pin 0, INT1 is pin 1, INT2 is pin 2, and so on.

Every pin digital supports attachInterrupt()

el_supremo
11-10-2012, 04:29 PM
Arrghhhh. Of course. The RTC is now ticking along nicely with interrupts.

Thanks Paul.
Pete

keithg
11-10-2012, 05:13 PM
On Teensy 3.0, INT0 is pin 0, INT1 is pin 1, INT2 is pin 2, and so on.
Every pin digital supports attachInterrupt()

Paul,

Any insight on what I am doing wrong? I have the teensy 3.0 on a breadboard and have tried connecting pin 0 (next to ground) to pin 13 and pin 12 (using the sketch above) and do not seem to be getting any interrupt 'action'. The output (pin 12) appears to be working fine as I can flash an led. I connect it directly to pin 0 and my ISR does not appear to be increasing the variable. I am using Beta 7 of your Arduino environment on x64 linux.

I need to complete 2 projects before the end of the year both of which need attachInterrupt to work in arduino IDE. I would rather use a teensy 3.0 than anything else due to size and performance. Any help appreciated.

Keith

keithg
11-14-2012, 04:11 AM
Any help on this? I edited the code so that it can be run with the serial monitor. The concept of this sketch is to have one output (pin 12) toggle high and low and have an interrupt (int 0) read the resulting square wave.

The real project will have a motor or a zero crossing detector and I just want to test to see if this function, attachInterrupt, on teensy 3 works as it does on Arduino. Can someone please try this sketch out and either confirm that this is broken or possibly direct me to my mistake? To run this code, all I think you should need is a connection between digital pin 12 and digital pin 0 and a usb cable...

I am running TeensyDuino beta 7.

in the serial monitor,
count is the counter in the ISR (this should increase but stays at 0)
Pulse Train is the toggling output on pin 12
loop is the number of times the loop has run..


/* sketch to verify external interrupt...
version 3 serial port
*/

int pulse_out = 12; // pulses out on 12
int led = 13; // flash LED with pin 12
int int_input = 0; // interrupt on 0
volatile int count = 0; // interrupt counter
int loop_num = 0; // loop counter
boolean pulse_train = false;

// ISR for counting pulses
void counterloop()
{
count = count + 1;
}

void setup()
{
// set up display
Serial.begin(115200);
// set up pins in and out
pinMode(pulse_out,OUTPUT);
pinMode(led, OUTPUT);
attachInterrupt(int_input, counterloop, FALLING);
}
void loop()
{
Serial.print("count:");
Serial.print(count);
// flop the output and boolean var each time through loop
if (pulse_train == true) {
digitalWrite(pulse_out,LOW);
digitalWrite(led, LOW);
pulse_train = false;
}
else {
digitalWrite(pulse_out,HIGH);
digitalWrite(led, HIGH);
pulse_train = true;
}
Serial.print(" Pulse Train:");
Serial.print(pulse_train);
loop_num++;
Serial.print(" loop:");
Serial.println(loop_num);
delay(500); // wait a half second
}

mercapto
11-14-2012, 12:09 PM
I had the same problem, that an Interrrupt is only detected if you define the pin with pinmode.

So try to add in the setup section:

pinMode(int_input, INPUT)

Joerg

keithg
11-14-2012, 12:23 PM
I had the same problem, that an Interrrupt is only detected if you define the pin with pinmode.

So try to add in the setup section:

pinMode(int_input, INPUT)

Joerg

Joerg,

That fixed it! Now on to the bigger project, thanks.

This illustrates a difference to the Arduino boards, so it may be useful to document it somewhere.

Regards,

Keith