Reading external interrupt pin

Go To Last Post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,
I'm trying to write a simple impulse disruption filter.

My 2Mhz atmega128 receivig digital signal on INT7 pin (signal quality is quite good).
I've setup INT7 to be triggered on both slopes.

Goal of filter is to exclude incoming signal disruption shorter than 20ms (where shortest signal logical 0 or 1 is 150ms)

Idea:
When interrupt is triggered I save its state to memory and launch 20ms timer. Timer is in CTC mode and will trigger compare interrupt after 20ms. In timer interrupt handler i'm checking if current INT0 pin is same as 20ms ago, if so, its treated as good impulse, otherwise dismissed.

Here is code snippet

volatile bool CThrottle::xIntLevel;

TCCR3B |= _BV(WGM32) | _BV(CS31); //CTC 20ms to comp. match.
OCR3A |= 5000;

int main()
{
   while(1);
}

ISR(INT7_vect)
{ 
   //save current state & launch timer.

   xIntLevel = (PINE & _BV(7));
   TCNT3 = 0;
   ETIMSK |= _BV(OCIE3A);
}

ISR(TIMER3_COMPA_vect)
{
   //after 20ms check if state changed
   	if(xIntLevel == (PINE & _BV(7)))
	{
	   //handle good impulse.
	}
	ETIMSK &= ~_BV(OCIE3A);

}

And this is not working, it catches like every second impulse.
and if i change it to this

ISR(TIMER3_COMPA_vect)
{
   //after 20ms check if state changed
        bool lol = (PINE & _BV(7))
   	if(xIntLevel == lol)
	{
	   //handle good impulse.
	}
	ETIMSK &= ~_BV(OCIE3A);

}

it works much better, but rarely ommits some impulses too.

Can't figure whats wrong with 1st interrupt implementation.
Can I even read PIN state when its configured external interrupt?

Any other ideas what might be wrong.
Ideas for better filters are welcomed too :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd go the opposite route: have a timer-based interrupt routine sample your pin every 1/2/5 ms, and then decide based on the actual and previous state of this pin if your received pulse is valid.

Einstein was right: "Two things are unlimited: the universe and the human stupidity. But i'm not quite sure about the former..."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sajmon5544 wrote:
Can I even read PIN state when its configured external interrupt?
Yes - just read it as you would read any other pin

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd second that suggestion. As well as filtering, you could have the timer tick implement other soft timers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Nooo, i was poking pcb designer to connect this signal to ext int for some time, cant switch to timed polling now :)
Beside, this approach have some weaknesses.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Using interrupts can have some serious weaknesses as well. Read my tutorial in the traps when using interrupts. Timed polling is the more robust method.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Goal of filter is to exclude incoming signal disruption shorter than 20ms (where shortest signal logical 0 or 1 is 150ms)

Especially with the slow signals involved, the approach I'd use would be nearly identical to key/button debouncing.

I'm just an old bit-pusher, but I cannot grasp your criteria. If the needed pulse width for a high or a low is 150ms in one state then how can anything shorter be "ignored". E.g. you have a confirmed high, and now get 30ms low and then return to high. What state is your signal then?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Nooo, i was poking pcb designer to connect this signal to ext int for some time, cant switch to timed polling now

Why not? You can use the same pin for either interrupt or polling and the PCB designer will never know what you code does!

Not sure what context you use "poking" in, the mind boggles!

Charles Darwin, Lord Kelvin & Murphy are always lurking about!
Lee -.-
Riddle me this...How did the serpent move around before the fall?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ICP3 is also on that pin, so why not use that and reject any pulse width < 20 mS ?

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

All right, all right guys!
After some time spent on fighting with this (not filter itself, but general impulse handling) i've finally gave up.

Followed You tip and it was idd a better solution, practicly everyting started working alot better with 1st compilation.

However, final problem I was unable to solve, was strange external interrupt self triggering...just out of the blue, I watched input signal on oscilloscope and interrupt sometimes tiggered without any visible disruption. I have 10k pullup resistor. Anyway I wasted so much time on this i don't exactly care what was wrong.

theusch wrote:
E.g. you have a confirmed high, and now get 30ms low and then return to high. What state is your signal then?

"ignore treshold" is 20ms, so my signal will be high again in the end, also all signal changes will be hadnled as good impulses.
The thing is, this signal comes from schmitt trigger, i know it shouldnt happen but sometimes I get several, like 10ms long spikes before actual state change comes.

Quote:
Not sure what context you use "poking" in, the mind boggles!

Nah, sorry, english is not my native lang. Nevermind ;)

Thanks everyone!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Turn off your mobile phone!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hello everyone,
i have a problem with interrupts i am using the atmega16
see the code :

ISR(INT0_vect)
{
PORTB = 0xff;
}
int main()
{
DDRA = 0xff;//(1 << PA0);
DDRB = 0xff;
DDRD &= ~(1 << PD2);
// eint0();

while(1)
{
PORTA ^= 0xff;
_delay_ms(500);
}
}

eint() is the initialisation of the interrupt even though i commented it . it was not showing any output on the port
if i remove that isr i am getting the output i.e glowing the led whats the problem. if the same isr i give below main then its working please explain me the mechanism of the isr programming yar!!!!
try this code and see the output removing isr and puting isr the output was peculiar .
plzz help me out ......

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
hello everyone,
i have a problem with interrupts i am using the atmega16
And you couldn't make your OWN thread on this instead of hijacking someone else's thread?
Quote:
eint() is the initialisation of the interrupt
And you couldn't be bothered with showing us that code?

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sorry dude , dont grow angry here is the eint() code

void eint0()
{
   MCUCR |= (1 << ISC00)|(1 << ISC01);
   GICR |= (1 << INT0);
   SREG |= 0X80;
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i got the mistake dude thanks