Interrupts not firing!?

I'm using a OMNIPOLAR Hall effect sensor works really fine with the below sketch:

// constants
const int hallPin = 7; // the number of the hallsensor pin

// variables will change:
int hallState = 0; // variable for reading the pushbutton status
const int led = 13;
void setup() {
Serial.begin(9600);
// initialize the pushbutton pin as an input:
pinMode(hallPin, INPUT);
pinMode(led, OUTPUT);
}

void loop(){
// read the state of the pushbutton value:
hallState = digitalRead(hallPin);

if (hallState == HIGH) {
Serial.println("MAG");
digitalWrite(led, HIGH);
}
else {
Serial.println("NO MAG");
digitalWrite(led, LOW);
}

delay(200);
}

But fails when i use the interrupts i have checked things are written fine in the code , im using the internal pull-ups resistors on pin 7 and Hall Sensor hooked to it which acts as a Switch.

const int led = 13;
const int inpin = 7;

void hallgetterHIGH()
{
  Serial.print('Hall sensor receiving Mag');
  digitalWrite(led, HIGH);
}
void hallgetterLOW()
{
  Serial.print('Hall Sensor LOW');
  digitalWrite(led, LOW);
}
void setup() {
  Serial.begin(9600);
  interrupts();
  pinMode(inpin, INPUT);// using the pin as an input(hall sensor acts as a switch)
  digitalWrite(inpin, HIGH);
  pinMode(led, OUTPUT);
  attachInterrupt(2, hallgetterHIGH, RISING);
  attachInterrupt(2, hallgetterLOW, LOW);
}

void loop() {
  
}

1 You have two attachInterrupt() statements using the same pin, you can only have one statement per pin.

2 You are wiring the the sensor to the wrong pin, Interrupt(2....) is only avalible on mega boards and is assosicated with pin # 21.

3 I haven't analyzed your code as until you get the interrupt pin numbers correct nothing else will matter.

From the arduino reference for attachInterrupt:

Specifies a function to call when an external interrupt occurs. Replaces any previous function that was attached to the interrupt. Most Arduino boards have two external interrupts: numbers 0 (on digital pin 2) and 1 (on digital pin 3). The Arduino Mega has an additional four: numbers 2 (pin 21), 3 (pin 20), 4 (pin 19), and 5 (pin 18).

Lefty

2 referring to Nick Gammon's interrupt definition he defined the interrupts are supported by ATmega 328 and mega never uses an ATmega328 page > http://www.gammon.com.au/forum/?id=11488

i mean as per that post it is something CHIP specific not BOARD specific

ANy way thanks for your help! it works but what does Nick means by this then:

Available interrupts

Below is a list of interrupts, in priority order, for the Atmega328:

1 Reset
2 External Interrupt Request 0 (pin D2) (INT0_vect)
3 External Interrupt Request 1 (pin D3) (INT1_vect)
4 Pin Change Interrupt Request 0 (pins D8 to D13) (PCINT0_vect)
5 Pin Change Interrupt Request 1 (pins A0 to A5) (PCINT1_vect)
6 Pin Change Interrupt Request 2 (pins D0 to D7) (PCINT2_vect)
7 Watchdog Time-out Interrupt (WDT_vect)
8 Timer/Counter2 Compare Match A (TIMER2_COMPA_vect)
9 Timer/Counter2 Compare Match B (TIMER2_COMPB_vect)
10 Timer/Counter2 Overflow (TIMER2_OVF_vect)
11 Timer/Counter1 Capture Event (TIMER1_CAPT_vect)
12 Timer/Counter1 Compare Match A (TIMER1_COMPA_vect)
13 Timer/Counter1 Compare Match B (TIMER1_COMPB_vect)
14 Timer/Counter1 Overflow (TIMER1_OVF_vect)
15 Timer/Counter0 Compare Match A (TIMER0_COMPA_vect)
16 Timer/Counter0 Compare Match B (TIMER0_COMPB_vect)
17 Timer/Counter0 Overflow (TIMER0_OVF_vect)
18 SPI Serial Transfer Complete (SPI_STC_vect)
19 USART Rx Complete (USART_RX_vect)
20 USART, Data Register Empty (USART_UDRE_vect)
21 USART, Tx Complete (USART_TX_vect)
22 ADC Conversion Complete (ADC_vect)
23 EEPROM Ready (EE_READY_vect)
24 Analog Comparator (ANALOG_COMP_vect)
25 2-wire Serial Interface (I2C) (TWI_vect)
26 Store Program Memory Ready (SPM_READY_vect)

Look at lines 4, 5, and 6. There can be a pin change interrupt defined that triggers when any pin on a port changes. Probably should be referred to as a port change interrupt.

There are 3 ports on the UNO and other non-Megas, so there are 3 interrupt vectors.

Attachinterrupt only works with External Interrupt Request pins, 2 avalible for the 328p and 5 avalible on the mega per the pin numbers I posted prior.

Lefty

Succesful INterrupter:

const int led = 13;
const int inpin = 3;
unsigned long interrupt_time;

void hallgetterHIGH()
{
  Serial.println('Hall sensor receiving Mag');
  digitalWrite(led, HIGH);
  interrupt_time = millis();
  Serial.println(interrupt_time);
}
/*void hallgetterLOW()// commented could be i need it in future
{
  Serial.print('Hall Sensor LOW');
  digitalWrite(led, LOW);
}*/
void setup() {
  Serial.begin(9600);
  interrupts();
  pinMode(inpin, INPUT);// using the pin as an input(hall sensor acts as a switch)
  digitalWrite(inpin, HIGH);
  pinMode(led, OUTPUT);
  attachInterrupt(1, hallgetterHIGH, CHANGE);
  
}

void loop() {


}

NOW i got to extend the code to find the time differential between current pulse and previous pulse from hall sensor.

First though, you need to learn the difference between " and '

@Awol there are many write outs i have done but i always forget this ' and " diff.

Issuing a Serial.println() inside an ISR looks a bit odd to me, but due to my limited experience with inerrupts and hall sensors I won't comment further.

I suggest you search the threads of the last two or three days in this section: there was a user battling with interrupts and time measurements. His problem was similar to yours (IIRC). I can't find the link right now...

Found!

http://arduino.cc/forum/index.php/topic,86292.0.html

HTH

MROMANI i already have this technique on my mind as the last resort the reason im not incorporating it is because interrupts fire in response to a hall sensor changing state so if i use two interrupts then i have to use two hall sensors and that i want to avoid.

Till then im working continuously on the code which can get me differential in between interrupts if im not able to work this out then definitely i'll work with two interrupts and two hall sensors.

How often is your hall-effect sensor triggered? Serial printing in an interrupt is generally not a good idea. At most, you could print one character to indicate that the interrupt was triggered. You are printing a whole lot of data 35-40 characters per time it is triggered.

If the time between pulses is long enough, millis() is sufficient. If it is shorter, micros() might be a better choice.

Variables used in interrupts should be declared volatile. Your variables are not.

To determine the rpm (assuming that the device being measured is rotating), you need to determine how many interrupts have occurred in a given period of time, or determine the time between two successive interrupts. A single time value and no count is not going to give you what you need.

HI there PaulS ,This is a code just to play with and test the working of Hall sensors as now i have become well versed with these hall sensors of their working now i will get through to my main aim.

By long or short what you exactly mean how much?(the wheels can go like 5-10 rotations per second):

If the time between pulses is long enough, millis() is sufficient. If it is shorter, micros() might be a better choice.

I know how to get time between two different interrupts but what about knowing time between the same interrupt being fired at different intervals?

I know how to get time between two different interrupts but what about knowing time between the same interrupt being fired at different intervals?

volatile unsigned long currInterrupt = 0;
volatile unsigned long prevInterrupt = 0;
volatile unsigned long interruptInterval = 0;

void hallgetterHIGH()
{
   currInterrupt = millis();
   if(prevInterrupt > 0)
   {
      interruptInterval = currInterrupt - prevInterrupt;
   }
   prevInterrupt = currInterrupt;
}

PaulS Thanks! got it

So know the code becomes this:

const int led = 13;
const int inpin = 3;
volatile unsigned long currInterrupt = 0;
volatile unsigned long prevInterrupt = 0;
volatile unsigned long interruptInterval = 0;
unsigned long speed_kmh;

void hallgetterHIGH()
{
  Serial.println("Receiving Mag");
  digitalWrite(led, HIGH);
  Differential_Calc();
}
void Differential_Calc()
{
   currInterrupt = millis();
   if(prevInterrupt > 0)
   {
      interruptInterval = currInterrupt - prevInterrupt;
   }
   prevInterrupt = currInterrupt; 
   Serial.println(interruptInterval);
}  
/*void hallgetterLOW()
{
  Serial.print('Hall Sensor LOW');
  digitalWrite(led, LOW);
}*/
void setup() {
  Serial.begin(9600);
  interrupts();
  pinMode(inpin, INPUT);// using the pin as an input(hall sensor acts as a switch)
  digitalWrite(inpin, HIGH);
  pinMode(led, OUTPUT);
  attachInterrupt(1, hallgetterHIGH, CHANGE); 
}

[glow=yellow,2,300]void loop() {
  speed_kmh = 1.884/(interruptInterval/1000/3600);//1.884 mtrs circumference of wheel,
  Serial.println(speed_kmh);//to get Speed in Kmh i have divided with 1000/3600
}[/glow]

Please take special interest in highlighted code to check it.

  interrupts();

Interrupts are enabled by default. You do not need to explicitly enable them, unless you have disabled them.

  speed_kmh = 1.884/(interruptInterval/1000/3600);//1.884 mtrs circumference of wheel,

The interruptInterval variable, 1000, and 3600 are all ints. The time will be divided by 1000 to give a whole number of seconds. The number of seconds will be divided by 3600 to give a whole number of hours. The value 1.l884 will be divided by the number of hours. Unless your interrupts are very far apart, you might want to reconsider using integer arithmetic.

The equation could be re-arramged to perform multiplication, instead of 3 divisions. Multiplication is faster, and truncation is less of an issue.

Interrupts are enabled by default. You do not need to explicitly enable them, unless you have disabled them.

Thanks for reminding Paul actually when the interrupts weren't working at that time i wrote this(in the past).

speed_kmh = 1.884/(interruptInterval/0.28); //rounded of value of

now is it fine, well division needs to happen to get the speed value, what you say? and the data type of speed_kmh is taken as unsigned long is it fine? or what would you suggest?

speed_kmh = 1.884/(interruptInterval/1000/3600); is the same as speed_kmh = 1884/(interruptInterval/3600); which is the same as speed_kmh = (1884UL*3600UL)/interruptInterval;

One multiplication, one division, greatest accuracy.

the data type of speed_kmh is taken as unsigned long is it fine?

An unsigned int will hold a value up to 65,535 kph. If you are planning to go faster than that, you need to unsigned long AND I want to watch.