I agree, at least partially, yes, a periodic callback can easily enable a programmer to burn far too much CPU time. But does that really mean it shouldn't be available at all? If they really need to check something periodically, consider the alternatives.
If it's polled in loop(), together with lots of other stuff, the polling has tremendous jitter, and the worst case times can become really horrible if Serial.print() or some other function blocks. The Bounce library is a great example, where failure to keep each loop() execution short enough could possibly miss a short duration button press entirely!
Given the choice between a novice using a library that silently burns 6% of the CPU time for highly reliable performance versus reliability hinging upon that novice user's ability to constrain the total worst-case time that loop() runs, I'd go for highly reliable easy-to-use libraries.
Today, that choice is already made in many libraries, which commandeer the timers for this sort of purpose. Perhaps they use slightly less CPU time than they otherwise would, but the trade-off is interfering with PWM on certain pins, incompatibility with other code using those timers, and lack of portability between chips.
There are a lot of trade-offs. I don't have any perfect answers that avoid all potential undesirable outcomes. But I do believe a periodic interrupt-context callback can be useful, especially for library authors. Just because it can't be done perfectly doesn't mean it isn't worth doing. I believe, despite imperfections, it could offer a much better alternative to how some things are currently done.
Yup, all code is in flash on AVR, so any callback would need to be a RAM-based pointer which is tested at runtime. Any implementation would eat a bit more CPU time, even if the feature is never used, just for checking the pointer.
My 2 main implementation concerns are how to allow multiple callbacks, since this is likely to be used by libraries without the user being aware, and what to do if the callback uses too much CPU time (eg, about 16200 CPU cycles).
One possible way to deal with the CPU time issue would be to re-enable interrupts before calling. A flag would need to be set, so if the timer0 interrupt happens again before it returns, no additional callbacks are made.
Enabling multiple functions needs to work. A library like Ethernet could really benefit, so it could flush partial packets after a short timeout, rather than the horribly inefficient approach of placing every call to Serial.write() into its own packet. But if a project uses Ethernet, which might use a timer callback without the user's knowledge, the user will still expect to be able to have their own callback, or use some other library which also requires a callback.
Maybe a linked list with malloc makes sense? Or maybe a small fixed size table might work?
I know 1000 Hz (actually 976 Hz) rate would be nice for some applications. But if the API offers one callback for every timer0 ISR, and if multiple callbacks can be registered, even if the functions do very little, such a scheme could quickly consume all available CPU time calling several every tick. A slower callback rate, like 244 Hz or 97.6 Hz could still be very useful.
If an application or library really needs a high rate of timer interrupts, it's best path is to commandeer one of the other timers, rather than getting a CPU-hogging callback from timer0. Several libraries do this today, and having looked at several of them, their needs are pretty specialized. I do not believe a scheme for sharing timer0 will work well for applications which need good performance.
But it would be really useful for slower things, like implementing automatic timeouts, debouncing pushbuttons, etc.
Thanks for this list. While I have pretty much no control over the official Arduino IDE and environment, I'm always looking for ideas to incorporate into Teensyduino.
Teensyduino already has #1 and #5 for, for 0022 and earlier, and also 1.0-rc1.
The F() macro and flash string support appearing in 1.0 was contributed by me, with help and input from Mikal Hard and Brian Cook, both on the Arduino developers list and in private followups. I realize the _P suffix is commonly used by avr-libc and other programs. It was discussed, but there was strong consensus it wasn't Arduino's API style. Had I gone with a _P suffix, this contribution never would have been accepted (it took many months as-is to convince the Arduino Team to merge it).
Something they did not accept, but I tried to contribute, was F() flash-string integration with the String class. So you can use F() with XYZ.print(), but not with anything that takes the newer String objects.
Teensyduino has a heavily optimized delayMicroseconds(), which works for 0 and also small values, with exactly cycle-accurate delays for the common const input case. If anyone wants to see it in Arduino, the code is available. I doubt it ever be accepted, because my coding style and extreme use of inline assembly is not consistent with Arduino's coding style. But if you want this fixed, it is indeed fixed in Teensyduino and the code is open source (after installing, look in hardware/teensy/cores/teensy).
#3 is on my serious wish-list. I worked on some elf/drawf parsing code to extract the call tree and stack framing info from the debug data inside the .elf file. It's quite tricky, and of course if recursion is detected you can't know worst-case stack use. I may never get this written, but I really, really want to have this feature, since running out of RAM really sucks.
I'm also really interested in #2, but if I develop it for Teensyduino and Arduino proper never accepts it, I wonder how much use it would ever get? The huge benefit I see is for libraries. I was considering a table of perhaps 5 or 10 callbacks, which could be triggered at something like 100 Hz (so with 10, the ISR would never need to call more than one). That way, if the user needs 1 or 2, and uses a couple libraries than each need 1 tick callback, everything would still work nicely.
I'm open to ideas on this, and there's a very good chance I'll implement it in Teensyduino at some point, but my hope is the Arduino developers can at least buy into the idea and commit to an outline of the API... so it doesn't end up being a contribution they'll never accept. (while many things I've contributed are now part of Arduino, on average most of the stuff I try to contribute never gets used... eg, look at issue #140).
Anyway, my point of this lengthy rambling post is I am indeed working on some of this stuff for Teensyduino, and a couple have been available for over a year. I generally do try to contribute my improvements back to Arduino when they're general to the hardware, but usually it takes a very long time for any contribution to be accepted into Arduino proper, and often they just sit unused indefinitely.
Joystick and Midi are available in Teensyduino, so it's probably only a matter of time until they're ported or reimplemented in Leonardo. If you have a Teensy 2.0, you can use them in Arduino now!
Audio would be really interesting. LUFA does it, with callback and/or tightly coded loops to keep up the speed..... but how would an audio stream integrate with Arduino? Would you pass blocks of samples with Mic.write(buffer, len); ? It's be really easy to get a buffer underrun.
Due to the underwhelming response, I'm not planning to work further to contribute this feature to the larger Arduino community. The source is there if anyone wants to use it, or continue to improve it and advocate its use.
If you're using Teensy, the data transfer goes pretty fast, since it's full USB speed. I recently discovered that Teensy can go even faster. It turns out much of the time is wasted waiting for operating system scheduling. I'm planning to overhaul the process to use overlapping async I/O to remove the dependency on operating system scheduling. I like things to go fast!
The process for official Arduino boards isn't under my control. In fact, with Teensyduino, I try very hard to make sure I don't accidentally alter anything about how non-Teensy boards work. That's why you need to copy that line into boards.txt to enable this.
Without more info, I can't know why it's recompiling everything.
If you're willing to try more, here's a few suggestions.
1: Can you post the verbose messages. On 1.0-beta4, enable in the preferences. On 0022, hold the shift key. The speedup only applies to "upload", not "verify".
2: Can you post your boards.txt file? There's several boards in the file, so make sure you're added this line for the board you're using.
3: Can you tell me which operating system and which board you're using? I have most combinations here. While it should work on all, I've only tested a small set of all the possible permutations (eg, only Uno and Teensy 2.0 on Windows, etc)
4: Could you reinstall Teensyduino 0.98? If you have 0.97 or earlier, there was a bug parsing the dependency files. It turns out the Windows and Mac versions have extra white space which isn't present on the Linux version.
I wrote code that cuts several seconds off the normal compile/upload time. Here's a little video I made yesterday to demonstrate.
This works much like Make, Ant and other build systems, by reusing the previously compiled files from the last time. I actually wrote this almost a year ago, but it was considered too risky to use in Arduino until more people have tested it and confirmed it really works. So the code sat unused and forgotten for almost a year!
Well, now that Arduino 1.0 is here (or will be in a few days), I'm hoping to revive this and hopefully get enough people to test so it can someday become part of Arduino.
If you're using a non-Teensy board, you'll also have to edit boards.txt. The line that enables it looks like this:
You should notice a substantial speedup compiling the same sketch. Hopefully when you switch sketches, board types, or have multiple windows open at once... stale code from one should not be used again in another.
If you give this a try, working or not, please take a moment to comment on issue 638.
If i understand you right you modify the libs so they work with Teensy that they would no longer work on an Arduino Board?
Oh no, not anything like that!! I always aim to preserve compatibility.
In fact, in the process of porting to Teensy, I often find libraries that were hard-coded to work only with the 168/328 chips. I usually add support for Arduino Mega and Sanguino too. For example, the Firmata library, which is now pre-installed on every Arduino Uno and Arduino Mega, became compatible with the Mega boards only because of my work to add a hardware abstraction layer. To get an idea of the type work I've done, take a look at libraries/Firmata/Boards.h inside your arduino-0022 directory. Several other libraries work on Arduino Mega only because of the Teensy porting effort!
I always attempt to contact the original author(s) and contribute my changes. Usually, when I can find the author's contact info, they publish the changes in a new version. In some cases, I've discovered and fixed bugs too (eg, OneWire was horribly buggy). In a few cases, it's turned out the library was pretty much abandoned code and I've become the de-facto maintainer.
Recently some of the hardware abstractions I've developed for libraries are (finally) being included into the Arduino core. Some libraries (eg, SDfat) have also made use of hardware abstractions I've proposed but haven't (yet) been accepted by the Arduino Team.
I definitely do not patch libraries to work exclusively with Teensy, and in most cases I've gone to quite a lot of extra effort to build robust hardware abstraction layers that support many boards and allow for new boards to be added easily.
Then again, some libraries are already very portable, so all I do it test and document.
But nice to see someone else had the same idea and made a central list for a 3rd party board. If you know of any way to support this application i would be happy.
I'll take a look at Ardulibrary soon. Maybe I could publish a page in the format it expects, so it could query the list I have?
Or if there's more work to create a central list, at least the work I've done so far might help. I only tend to test/port/document the "major" libraries. But a quick look at my list shows several that aren't on the 2 lists I saw mentioned in this thread.
As you can see, I still have quite a number of them to test. Usually when I add one to this list, I buy the necessary hardware - but often it sits for weeks or months due to lack of available time.
A few months ago, I added a feature to the Teensyduino installer (which automatically adds the Teensy-specific files to Arduino) to optionally install any of the tested libraries. Virtually all the libraries are only a few relatively small files. Just copying them all into installer didn't enlarge it very much, less than 1 megabyte.
Several times I considered making a java-based tool right inside the IDE - which does pretty much the same thing your nice-looking application does. The really hard part, though, is the last of a central database of all the libraries. Maybe my efforts can help, at least a bit, or I might be able to contribute in some way?
I believe you should still give the library a try.
The FreqMeasure library measures precise pulse length. If you only want to measure 1 pulse, you can do that. Just call available() and read() to discard everything measured before your pulse begins, and then available() / read() to read only your 1 pulse. After you've got the result you need, just don't bother calling the functions anymore. When you do need to make another measurement, just be sure to call them to discard any measurements it made that you don't want.
FreqMeasure will give you vastly superior results.