Pages: 1 2 [3]   Go Down
Author Topic: How to create 3th interrupt  (Read 3807 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 178
Posts: 12290
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Why bother saving SREG and then restoring it? Why not just use the matching sei() call with cli()
There are times when sei() is not safe to use.  The pattern I presented is always safe to use with a very minimal cost (I believe one more machine instruction).  Basically, there's less to remember and understand so mistakes are less likely.

Quote
Secondly, isn't retrieving the value of the counter an indivisible call?
No.  Anything larger than a byte is not atomic.  (That's not entirely true.  A few 16 bit operations are atomic.  But less to remember + low cost = good so we'll always use the code I presented, right?  smiley-grin)

Quote
It would matter if he were retrieving the value, modifying it, and then writing back, but in this case he is simply retrieving the value.
It is not possible for an 8 bit processor to perform any operation atomicly on a 32 bit value.  Just reading the value requires four machine instructions; an interrupt can occur between any of them.

Quote
I do not understand why that must portion of code must be atomic.
Does the explanation above help or do I need to provide more details?
Logged

Oppuurs, Belgium
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK guys, it seems this is getting pretty complex (at least for me)  :-?.

Let me explain a bit what I'm trying to do:

I need to count pulses from 3 sensors:
  • Counter1: idle = low, pulse = high, max 1 pulse every +/- 10 secs, and every hour this pulse stays high for about 60 secs
  • Counter2: idle = low, pulse = high, max 3 pulses in 1 sec
  • Counter3: idle = high, pulse = low, max 2 pulses in 1 sec, pulse can stay low for several hours

In my current setup I just count the pulses in the loop(), push the counter values over serial to my PC every 30 secs and reset them to 0, but people told me that i will miss pulses this way. So I'm looking for a more robust/safer way to count the pulses.

Seen that there are only 2 attachInterrupts, I was looking to or add a 3th interrupt, or don't use attachInterrupt and create the 3 interrupts manually.

I'm getting great help and feedback from this wonderful community but as mentioned at the beginning of this post, it seems to become complex. Now I'm asking myself: Is this complexity needed for what I'm trying to accomplish?

In the near future, I will be replacing the serial/usb connection to my pc with a wireless connection (RFM12B).
I also have 1-Wire devices connected to this arduino, but if you guys suggest me that it would make more sense to move this to another arduino, i will do so.

Thats about what i have at the moment, but lets focus for the moment on the counter part as that is the most important one for me.

Thanks in advance,

EriSan500
Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Why not use interrupts for the two fastest pulse sources and monitor the slowest in loop, this will work if the pulse duration is always longer than the pulse duration.
What is the duration of the pulses and what else is your application doing in loop?
Logged

Oppuurs, Belgium
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mem,

Pulse duration:
  • Counter1: on average 1 sec, with once an hour about 60secs
  • Counter2: 90ms iirc (need to check the datasheet at home)
  • Counter3: variable. This is a pulse contact on a water meter.

For the rest my loop checks if 30 secs are passed, and if so, send the counters to the serial and reset them to 0 again.
I also read a bunch of 1-wire temp sensors (mix of DS18S20 and DS18B20) every 60 secs, and push those readings straight to serial.

Greetings,
EriSan500
Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Counter 1 looks do-able from within loop.  You can monitor the duration of your loop with something like this.
Code:
unsigned long startTime = 0;
unsigned long minDuration = 999999;

void loop()
{
  startTime = millis();

  // your loop code here

  unsigned long dur = millis() - startTime;
  if(dur < minDuration)
  {
    minDuration = dur;
    Serial.print("Minimum loop duration is ");
    Serial.println(dur);    
  }  
}
If the minimum loop duration is well under 1000 (1 second) then you should be ok handling counter 1 in loop
« Last Edit: December 17, 2009, 05:56:02 am by mem » Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 175
---
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@Coding Badly

Great explanations. Can you please elaborate more on the following or provide some reading material. The AVR libc documentation on sei is rather brief.

Quote
There are times when sei() is not safe to use.
Logged

Waterloo, Canada
Offline Offline
Full Member
***
Karma: 1
Posts: 242
Engineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I too need an explanation.  I found this in interrupt.h...
Code:
# define sei()  __asm__ __volatile__ ("sei" ::)

I don't understand how this could be unsafe.
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 178
Posts: 12290
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


Unfortunately, my replies have turned into a distraction.  I'd like to continue the ISR discussion here...

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1261124850/0#0
Logged

Pages: 1 2 [3]   Go Up
Jump to: