Loading...
  Show Posts
Pages: [1] 2 3
1  General Category / General Discussion / Interrupt heresy - reactions? on: September 21, 2012, 08:28:27 pm
Standard advice on ISRs from the forums often includes one or more of the following:
  • avoid putting too much inside an ISR - keep them lean and mean
  • simply set a flag of some kind in the ISR, then poll that flag in the main loop and do the bulk of any processing required there
  • dont use function calls in the ISR
  • you cant use anything that uses interrupts inside the ISR, including importantly, timing functons like millis(), and
  • comms using the Serial class
   

So why is this advice being offered, and does it always apply?
 
The argument seems to run t like this. Some sources of interrupts are random in the sense that there is no telling when or how often they will occur. There is therefore no guarantee that the ISR will have finished servicing one interrupt before the next interrupt of the same type occurs. To handle fully this situation of 'overlapping' interrupts within the ISR itself, the ISR code would have to be re-entrant. Since ISRs are tricky to code/debug at the best of times, and writing safe re-entrant code is even more difficult, so keep things as simple as possible by disabling interrupts inside ISRs.
   
Occasionally an incoming interrupt that follows close on the heels of a similar interrupt will be missed while you are busy processing the first interrupt, but in many cases this is acceptable. This is presumably the reason that the AVR processor has been designed to automatically disable further interrupts just before calling an ISR.

As a result, on the Arduino, unless you take counter-measures, all interrupts arriving during the processing of an ISR will supposedly be lost (unless they persist in some way until after the ISR has finished processing).
   
In that light, the standard advice starts looking very wise:
        keep ISRs short (or you will miss even more interrupts)
        don't use functions (they may contain code that uses interrupts, and this will fail)
        dont use millis, or Serial in an ISR since these use interrupts
   
But notice the large price you are paying for adopting this so-called 'safe' approach
        occasional lost interrupts (lost accuracy?)
        occasional loss of characters during serial communications (now you may have to protect more thoroughly against
          dropped characters, eg more complex protocol, slower comms)
        inability to use standard timing mechanisms inside ISRs (may mean resorting to custom built timinig mechanisms)
        inability to use standard comms inside ISRs (makes debugging ISRs much more difficult, may have to resort to flashing LEDs etc)
        inaccuracy of timing mechanisms outside ISRs (since the millis() will not be counting while the ISR is running, and
          will therefore always be running slow, by an undetermined amount)
        loss of structure (avoiding function calls), and/or redundant coding (replacing function calls) for fear of using
          function calls inside the ISR

In some cases, you may nevertheless conclude that this is the right solution on balance.
   
BUT ...
       
In many situations, the nature of the interrupts involved is such that they are guaranteed to arrive serially (one at a time), and sufficiently spaced out so that concurrent invocation of the ISRs is never an issue.
   
Take the situation where there are only two types of interrupts: interrupts from a timer (A), and interrupts from a serial interface (B). You may get an A and a B arriving at the same time, but never two As or two Bs at the same time. Since the interrupts from any one source are guaranteed to arrive serially, you don't require re-entrant code in the ISR for either type of interrupt. Consequently you dont require the 'simplification' of switching off further interrupts in the ISR.

You can't stop the AVR chip from switching off interrupts before calling an ISR, but you CAN switch them back on again as soon as you're in the ISR (simply make     sei();    the first instruction of your ISR.)

If this situation applies to you (and I believe it to be quite common) you're life as an ISR writer will be greatly enhanced:
  •       you'll very rarely miss an interrupt (the time when interrupts are disabled will be extremely small), and so you either don't have to cope with that possibility, (either in terms of extra code, or lost precision) or the impacts of occasional missed interrupts are greatly reduced
  • you can start using normal timing mechanisms like millis() for timing inside your ISR
  • your millis timer will not run slow
  • comms using Serial outside the ISR will be unaffected (since the ISR involved with Serial can now interrupt your custom ISR)
  • you can use Serial comms within the ISR, whicjh is especially valuable for debugging
  • you can safely use most function calls within the ISR without worrying about any embedded use of interrupts
  • you dont have to worry unduly about the size of the ISR - since you're no longer under the same time pressure, and you're not missing interrupts
     

In fact you can see that it is the very act of inhibiting further interrupts that is making the writing of ISRs seem difficult - by keeping interrupts enabled, most of the problems evaporate.

However it all hinges on the nature of the interrupts you are trying to handle:
          with random interrupts there is a real issue to solve: you can either accept the processor default (further interrupts inhibited) or you can write re-entrant code (tricky);
          with serial, spaced out interrupts, there is no big issue - why not re-enable interrupts at the start of the ISR and then just programme normally.

I know it's heresy, and I'm expecting a fatwa, but I'm old and ugly - bring it on.
2  Using Arduino / Storage / Re: Looking for guidance on data storage: EEPROM vs memory stick, vs SDcard on: July 15, 2012, 06:23:55 pm
Hi Crossroads / Nick

I took a look at that fancy soldering kit, and on reflection dont want to go that way. I think I'll give Nick's I2C / EEPROM a go. No problem with pins, and Nick has provided a really first class tutorial on his site on how to put it all together. I'll close this for now, until I get the part and give it a go.

Thanks for your help.
3  Using Arduino / Storage / Re: Looking for guidance on data storage: EEPROM vs memory stick, vs SDcard on: July 12, 2012, 05:54:51 pm
Hi CrossRoads

I'm gonna follow your lead here, but I starting from scratch, and I haven't a clue what to do with the breakout board!!

How do i "mount" the part on the breakout - do I need a soldering iron?

And then what do I do with the breakout board - does it have pins coming out of it that will fit into a breadboard? I have the Arduino attached to a breadboard that came with my "experimentation kit", so once it's on the breadboard I can make all the connections I need to.

The Ocean Controls Thermocouple Multiplexor shield covers the Uno almost completely, but repeats most of the pins of the Uno. It also provides a fairly extensive area full of holes, which I presume I could use for locating the FRAM when I've got it all sorted out.

Feeling very wet behind the ears!

kenny
4  Using Arduino / Storage / Re: Looking for guidance on data storage: EEPROM vs memory stick, vs SDcard on: July 12, 2012, 01:09:02 pm
Thanks for all feedback

Despite what i said about not wanting to get into "hacking", this FRAM looks amazing, its cheap as chips, and doesn't look TOO complicated - (may regret saying that). However I didnt really follow all that stuff about SPI modes, etc, on the data sheet. Can you reassure me that I dont need an electronics degree to make this work? Can you point me at any resources that would help a non-hardware guy to get this up and running?

The other thing is that, if I understood the stuff on the link you gave me, the chip only comes in surface mount format - is that correct? and if so, how do I attach it to my Uno?
5  Using Arduino / Storage / Looking for guidance on data storage: EEPROM vs memory stick, vs SDcard - SOLVED on: July 12, 2012, 11:26:02 am
Hi guys,

I'm making a controller to control several kilns at the same time. I'm using my PC as the front end where the firing procedure is specified, and also as the backend where the data is displayed and analysed.

The Arduino will be given its "instructions" with the PC connected. I will then unplug the PC and use it for other things. Arduino will control the kilns and log temperatures over a number of hours, currently to EEPROM. Given the limited size of the on-board EEPROM, I'm looking at other solutions for storing the data, and subsequently uploading it to the PC. I'm looking for as close to plug and play as I can get, not a solution where I have to hack about, either in terms of hardware or software.

I considered a USB memory stick (plenty of storage, and avoids an upload over the serial interface). I looked at the Sparkfun USB Host Shield. It talks about interfacing with a lot of stuff, but I don't see a plain old memory stick. Is this just taken for granted, or do I need software to correctly format my data on the stick so that Windows can access it?

I considered EEPROM (I've already developed for this - presumably an easy upgrade path for me). I looked at an inexpensive module from dfrobot. It mentions their Interface Shield For Arduino, without being clear whether I really need this. The Arduino playground  article it links to says there isn't a library, but offers some code - not too encouraging.

I considered an SD card, but the shield I looked at seems to conflict with the pin usage on the thermocouple multiplexor board that I'm using (The multiplexor uses SPI and uses D4,5,6,7,9,12,13; the SD shield uses D 8 to 13). Presumably its perfectly all right to share the SPI standard pins 10 to 13, but I cant work out whether the other pins present a problem.

Each avenue is full of ambiguity for me, probably because i'm not used to this low level stuff.

Any overall advice (best direction to pursue, warnings), specific product/project experiences, or help clarifying any of the above would be appreciated.

Sorry about the long post

Kenny
6  Using Arduino / Programming Questions / Re: health check on an ISR please - COMPLETED - THANKS on: July 11, 2012, 04:02:59 am
Thanks for all contributions
7  Using Arduino / Interfacing w/ Software on the Computer / Re: Gobetwino is running very slow after a few hours - anyone else had this? on: July 11, 2012, 03:47:03 am
Hi Mikael

Started another test before I had your latest reply - ran it without the GBT status window and without the internal GBT logging - everything running fine with my files after 8 hours.

Now I'll add back the status window and see what happens.
Kenny
8  Using Arduino / Programming Questions / Re: health check on an ISR please on: July 09, 2012, 07:03:26 pm
Hi PaulS

nor does the compiler do anything clever to make a routine into an ISR.

The reason I asked was because somewhere along the line I came across this article

http://www.clickpdf.com/pdfview/1sijpke/programming/c-c-programming-interrupt-service-routine-calling-functions-Interrupt%20Service%20Routine%20calling%20functions.pdf

which suggested that compilers do indeed take account of the peculiarities of an ISR. Perhaps only for more sophisticated compilers?
9  Using Arduino / Programming Questions / Re: health check on an ISR please on: July 09, 2012, 04:51:27 pm
Hi guys

I have included the cli / sei  wrappers and the routine appears to be working fine for the moment (with SPI calls included).

Still have an outstanding question:

How does the compiler know that a routine is an ISR - is it clever enough to determine this through the Timer1 class invocation?

Thanks all for your help.

Kenny
10  Using Arduino / Interfacing w/ Software on the Computer / Re: Gobetwino is running very slow after a few hours - anyone else had this? on: July 09, 2012, 04:41:16 pm
Hi Mikmo,

Some further data for you.

I left a session running two hours ago; When i returned, the problem had also returned with similar symptoms: input window running slowly, fan on - no duplication this time though.

I called up Task Manager, and found that GBT was using more than 50% of cpu. Memory usage was 51 Megabytes!!!! Page faults were up to 60,000,000!!!

I unplugged the USB to the Arduino. The outputs stopped immediately of course, but the input screen is still processing the inputs that must have been stacked up in the input buffer - it's now 30 minutes since I unplugged  and its still going!!!

This confirms your memory theory I think.

What is your current estimate of when the next version will be released? I would like to continue using GBT if possible, but I cant wait more than a month.

I have a few suggestions for you for the next version:
  • have a command type, like RFLIN, but which reads fixed length records - this could be opened for random access, and would thereby avoid the need to read from the start each time. Open it for shared access if possible.
  • have a new command, similar to LGFIL, which anticipates the need to constantly update the same file. Keep it open for appending until the user issues another command signalling that he needs access to it, at which point you can close it.
  • allow for the deletion of command types
  • allow for some customization of your own log - this would in many cases eliminate the need for a separate user log file - they could simply extract their data from the system log

Regards
kenny
11  Using Arduino / Interfacing w/ Software on the Computer / Re: Gobetwino is running very slow after a few hours - anyone else had this? on: July 09, 2012, 11:58:54 am
I'm on Windows XP.

Do you recall that I mentioned some repetition of GBT responses in the Output text box - would that symptom tend to favour any of your theories?

You mention the Windows limit. Is there possibly a delay involved from Windows when the text box gets very full,  a delay that affects GBT's ability to service the next incoming request from Arduino, so that it gets behind?

There were two log files were in use when the problem occurred, one as I described previously, and the other a reflection of all traffic between GBT and Arduino, in essence a duplicate (in "user" language) of your own log. It also would get quite large.

However I'm having difficulty in understanding why the size of the log files should make any difference - surely you are simply appending to the end of them. Would size affect the time taken to do that?

I can understand some size issues with respect to the RFLIN command, since presumably you are obliged to read through the file sequentially to access the record I requested. However as I said this file is short, so unlikely to be the culprit?

Thanks for giving it your attention
Kenny
12  Using Arduino / Programming Questions / Re: health check on an ISR please on: July 09, 2012, 09:23:51 am
Wow - can hardly keep up with the response - thanks again!

Hi WildBill

Is there any reason why these eight sensors cannot be triggered all at once (albeit serially)?

My understanding of the Ocean Controls thermocouple multiplexor shield is that there is only one chip that does the "conversion", and so the process of reading all eight is a serial one. Initiate for T1, 220 ms, read T1, initiate for T2, 220 ms, read T2, etc. I have combined the read for one thermocouple with the initiate for the next, to get

Initiate for T1,
220 ms,
read T1 and initiate for T2,
220 ms,
read T1 and initiate for T3,
etc

So my choice is I think, either slice my other processess into approximately 250 ms chunks, or use the interrupt system. (Other routes?)


Hi PaulS
Now you've got me worried. Does that mean anyone using SPI is essentially barred from employing their own interrupts?
13  Using Arduino / Programming Questions / Re: health check on an ISR please on: July 09, 2012, 09:09:04 am
Hi AWOL

"Time critical" is i think a relative term, and not restricted to the realm of microseconds, even if that's where interrupts are normally employed. My criticality is measured in seconds, not microseconds. It's just that I have some high priority processes measured in tenths of a second, and other lower priority processes measured in several seconds. What attracts me to the interrupt mechanism is not its lightening speed, but the implicit prioritisation that it gives. Am I missing something?

kenny
14  Using Arduino / Interfacing w/ Software on the Computer / Re: Gobetwino is running very slow after a few hours - anyone else had this? on: July 09, 2012, 08:58:04 am
Hi MikMo

There are two type of log files, one of which can grow to a considerable size. A single thermocouple can generate a reading every three seconds, each requiring a string of about 10 characters to be transmitted.  Then GBT adds in the time stamp (about 20 character).

That makes 30 * 24hrs a day * 60mins per hour * 60 secs per min / 3secs  = .9 MB per day

The kiln can be continuously operational for over a week in some circumstances, although typically a firing is less than 24 hours. So a maximum of say 7 MB.

There are up to eight thermocouples, but the data from each thermocouple goes to a separate log.

The file involved with RDFIL will rarely get above 100 records long.

severe memory fragmentation caused by repeadetly opening large files.

Which part of the environment do you suspect of doing the fragmenting? - GBT, Windows, something else?

Hope this helps. I will try and run GBT tonight.

Kenny
15  Using Arduino / Programming Questions / Re: health check on an ISR please on: July 09, 2012, 08:34:58 am
Hi TC World - thanks - your reply came in as I was writing my previous response, which gives a bit more background.

Your approach is my fall-back, but it puts a restriction on the other things I do in the main loop, several of which could potentially take many seconds to accomplish, in any case longer than my 3 seconds limit. The ISR solution I was suggesting accomplishes two things: it gives priority to the time-critical reading (and subsequent resetting of the relays), and relieves me of the job of splitting my other processes down into sub-second chunks.

Unless I have misunderstood, your current proposal won't do this - is there a variant of it that addresses my requirements?
Thanks

Thanks Makenko - understood

kenny
Pages: [1] 2 3