External interrupt (INT0), Timer1 and I2C simultaneously -- possible ?

Hi,

Is it possible to reliably service an ISR tied to external interrupt (INT0 - Pin#2) being triggered at around 5kHz, toggle a pair of digital pins based on Timer1, and also do I2C communication with another uC (peripheral), simultaneously on an Arduino (ATmega328) ?

What are some of the challenges I might expect, and what might be the potential solutions ?

Thanks,
f74

Since the interrupt, timer and I2C are mostly done in hardware I would think that there would be no problem doing them all. Of course you have not said anything about what work needs to be done by the ISR, how often the Timer1 timings might have to be changed, nor how much data is being transferred over i2c.

Thanks John.

Please find further information about what I am trying to do.

  • Ext interrupt ISR - Looks for a valid signal pattern, while rejecting high frequency noise. Once valid signal pattern is found, it is assembled in a circular buffer to form a command-packet, and then matched against upto 10 command-packets. On finding match a call-back is invoked with command-id, and 1 octet of data.

  • Timer1 - Used to generate command-packets/response or heartbeat. The precise timing is used to generate the signal pattern (H/L durations), and also to time the sending of heartbeats. Heartbeats are equally spaced, but might have to be sent to 1-64 addresses. Heartbeats have tolerance against loss and slight delay.

  • I2C - Is used for comm with only 1 other processor, and the data rate required is actually quite low. 100-150bps

Does that change anything from the feasibility standpoint ?

Heartbeats are equally spaced, but might have to be sent to 1-64 addresses.

What does this mean? If you are bit banging serial to 64 pins then there's a problem.

Looks for a valid signal pattern,

What does this mean? An full FFT would be an issue, testing for a high pin no worries.

Ext interrupt ISR - Looks for a valid signal pattern, while rejecting high frequency noise.

This appears to be the main job of the app. You will not do all this in an ISR but still not enough info to tell how this would be done.


Rob

Thanks Rob.

The pattern is something like (High,600us),(Low,1200us),(High,1200us),(Low,600us) or other such combination of High & Low for specific duration (within 10-15% +/- tolerance), on INT0, with ISR attached for both edges to INT0. Sorry, if I gave an impression of an analog arbitrary waveform signal. Anyhow, this ISR I have it working already. My main worry is, would it be expecting too much to also have I2C (for communication with another uC), and a Timer1 based ISR to send similar patterns.

As for the 64addresses, it was I believe an unnecessary detail, causing more confusion than helping. For all we care, we could consider it to be part of the data being sent. But if you are really keen to know, this pattern is being fed to a RF transmission module. I just one Digital Pin in output mode for this for the data, and one Digital Pin as chip-select.

Well in principle I would say you can do all this but the devil is in the details, for example this small matter

I just one Digital Pin in output mode for this for the data, and one Digital Pin as chip-select.

Are you bit banging out a pin as well?


Rob

Indeed, bit-banging.

See what I mean, a throw-away line about "64 addresses" and "unnecessary detail" turns out to be a very processor-intensive piece of code. For all we know this bit-banging could use 90% of the processor time.

I think you need to detail exactly what has to happen and how often, in nice clear point form suitable for us simple engineers, with no afterthoughts like

"BTW, must be able to spell check War and Piece on the side" :slight_smile:

_____-
Rob

Honest oversight, probably because I didn't know any better. This current project of mine has challenged me well beyond my knowledge of embedded programming and AVR uC. So let me try to spell out details.

The uC is performing 3 primary tasks:

Task-1)
Continuously reading (via the external interrupt on pin#2) a RF module. The ISR does some low level decoding of the signal, and also filtering out high frequency noise. The signal is encoded such that each bit (0/1) & sync pattern, is represented by 4 level transitions, spaced differently for each bit. My ISR is invoked roughly every 50us due to the "noise", but with a small set of instructions, it determines that the transition isn't valid signal and returns. If valid transitions are found, bit-level decoding is performed, and result is pushed into a ring-buffer. The ring-buffer is monitored within main loop() continuously, trying to decode the string of bits into a valid message. A message has address and data bits. After decoding the message, I need to check if the message is indeed for this node, i.e. check the address, and invoke a callback function (registered at startup), to handle the message.

Task-2)
Act as an I2C slave, receiving commands from another uC, intermittently, and sharing status updates back. Also if there is any interesting event detected, that is informed back to the master.

Task-3)
Periodically uC also needs to generate a pattern of level transitions, with variation in delay between the transitions, in a way very similar to the received signal from the RF module. This generated pattern of level transitions, which make up the message-packet, is fed to the RF module for transmission. This is what I was hoping to use Timer1 for, i.e. to space out (precisely) the level transitions, that take care of the lowest level of encoding.

Coming to 64-addresses, the wireless comm data is packetized. A packet has 6 bits of address, and 6 bits of data. Each node (s.a. this Arduino / equivalent device) has a unique address, and that is how they communicate with each other. The transmission of actual message packets is "bursty", i.e. the devices could be silent for long periods, except for a periodic Heartbeat message (similar to Watchdog in theory). Non-heartbeat message transmission might happen as fast as say 100 message/sec but for a brief period (1-2 seconds), or several hours apart.

What this means is --

  1. Noise filtering logic is the highest overhead and "always-on", but this part of the logic in ISR is fairly short. I haven't counted instructions, but it is the bare minimal logic of comparing last transition timestamp and this one, checking against min. valid signal transition length and discard as noise if it is shorter. Very rarely, some noise transitions do get characterized as valid signal, and further processing filters it.

  2. The logic of processing valid transmission, including Heartbeat messages happens (in the main loop(), not in ISR) i.e. to validate address, validate other message contents etc., and forming Heartbeat-Ack message, or other message is performed (again in main loop()). The communication between ISRs (i.e. one which is EXT INT0 ISR for data reception, and one which is Timer1 ISR for timing the sending of data) is using ring-buffers (with overflow indicator).

  3. Finally, there is the I2C communication with a main processor. Potentially something like a Beagleboard running a Linux based GUI rendering a map of activities in this wireless network, and providing some sort of automated "game commentary". The wireless network is a bunch of sensors that read open/close of gates in a mega-maze to track participants and their movement.

50uS is pretty frequent especially given that you lose maybe 8uS just servicing the interrupt. That leave 42uS to do all the above.

When you are generating the output waveform you would presumably lose another 8uS bringing the free time down to 34uS (assuming the same frequency as the input)

The I2C is hardware driven but still another interrupt occasionally.

Have we lost the bit banging now, I hope so :slight_smile:

I think things are getting petty tight.

Your input waveform is in the order of 600/1200uS, why the 50uS interrupt?


Rob