0

Increasing the speed of execution of the adafruit feather
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Increasing the speed of execution of the adafruit feather

by lalit01 on Tue Apr 03, 2018 12:03 pm

Hi,

I am planning to run some psycho physics experiments, where timing is critical. I have purchased an Adafruit Feather M0 WiFi - ATSAMD21 + ATWINC1500.

I would like to know how to improve the speed of my program. For example in arduino uno, I have read that writing to registers directly instead of using digital write saves about 50 clock cycles based on the following posts:

http://stackabuse.com/speeding-up-arduino/

http://www.instructables.com/id/Fast-di ... r-Arduino/

How do I go about doing the same on the feather? And also do you have any other suggestion on how to increase the efficiency of the program?

Thank you

lalit01
 
Posts: 5
Joined: Thu Sep 07, 2017 3:54 pm

Re: Increasing the speed of execution of the adafruit feathe

by PaulRowntree on Tue Apr 03, 2018 12:34 pm

Interesting!
Could you give some more details on what you are doing? Do you need more speed, more precision on timing between events? What are the timescales that you need to work with?

PaulRowntree
 
Posts: 347
Joined: Sun Apr 03, 2016 12:41 am

Re: Increasing the speed of execution of the adafruit feathe

by lalit01 on Tue Apr 03, 2018 8:40 pm

Hi,

I am measuring EEG signals specifically looking at ERP's(Evoked Response Potentials) which is basically the brains response to a stimulus/event. I working with timescales of the order of 10-350ms.

I will be presenting multiple events at precise intervals which would be triggered by the Digital pins of the feather which would require me to have both speed and precision in the execution with minimal jitter.

I am planning to run my experiments using psychtoolbox for matlab and I am hoping to talk to the feather over serial COM ports.

lalit01
 
Posts: 5
Joined: Thu Sep 07, 2017 3:54 pm

Re: Increasing the speed of execution of the adafruit feathe

by PaulRowntree on Tue Apr 03, 2018 10:42 pm

I don't know enough about the innards of these chips to know how the various interrupts, timers etc affect timing. I have built very time critical data acquisition systems using Parallax Propeller processors... completely deterministic, with hardware timers. Not as easy to work with as the Arduino IDE and more resource limited than the M0 (which is why I'm here!)

PaulRowntree
 
Posts: 347
Joined: Sun Apr 03, 2016 12:41 am

Re: Increasing the speed of execution of the adafruit feathe

by franklin97355 on Wed Apr 04, 2018 3:49 am

If you want to forgo the Arduino environment entirely you could use Atmel Studio and write in assembly for the time-sensitive code sections.

franklin97355
 
Posts: 19030
Joined: Mon Apr 21, 2008 2:33 pm
Location: Lacomb, OR.

Re: Increasing the speed of execution of the adafruit feathe

by lalit01 on Sun Apr 08, 2018 8:15 pm

Thanks for the responses, I will try them out. Do you happen to have any examples or any links you can point me to where atmel studio is used for the feather microcontrollers?

lalit01
 
Posts: 5
Joined: Thu Sep 07, 2017 3:54 pm

Re: Increasing the speed of execution of the adafruit feathe

by plutonic on Wed Apr 25, 2018 5:42 pm

The Cortex M0 is so much faster than an Atmega that 10-350ms might not require any particular optimization effort if you're programming in C. 10 ms is fairly slow in the scheme of things. There is also the new Metro M4 that runs at 2x the clock speed of the M0. I don't know if either the M0 or M4 can guarantee cycle accurate consistency in timing loops, and/or whether they have a cycle-counting timer available. A more extreme idea might be a Beaglebone, which has two Programmable Realtime Units (PRU's). These are 32-bit on-chip coprocessors that I think run at 200 mhz, which have no caches or pipelines, so they have deterministic timing. The next thing past that would be an FPGA.

I think as long as you're in the 1+ millisecond range you're fine with normal software on a Cortex-M. You can probably get to the low microseconds with careful programming, before having to resort to special realtime cpu's. The Neopixel LED strips need an 800 khz pulse signal (although the timing tolerances are fairly loose) and people control those by software bit-banging even from the Arduino.

plutonic
 
Posts: 41
Joined: Wed Jan 06, 2016 3:21 am

Re: Increasing the speed of execution of the adafruit feathe

by westfw on Wed Apr 25, 2018 6:39 pm

I have read that writing to registers directly instead of using digital write saves about 50 clock cycles

Unfortunately, while you can get some speedup by bypassing digitalWrite(), it's not nearly as dramatic as it is on an AVR.
The AVR has some special purpose instructions for writing to IO pins, so it can (under some circumstances) write an IO port in a single cycle (62.5ns) ARMs don't have such instructions (RISC, you know), so the minimum write to an IO port takes more cycles, and the "extra overhead" of digialWrite() is less, percentage-wise. (With AVR you can get a ~50x speedup. With SAMD2x, it might be more like 8x. Combined with the SAM's higher clock rate, it may not be worth it...

That said, digitalWrite() still does things that don't need to be done for many cases, and it does them in what I would call a not-very-optimized way, so you could easily speed things up by:
1) remembering the location of the IO port, instead of re-deriving it from the "pin number" each time.
2) ditto for bitmask.
3) avoid error-checking EVERY TIME.

The source code for digitalWrite() is where anyone can look at it...
https://github.com/arduino/ArduinoCore- ... ital.c#L74

4) skip the backward-compatibility hack where writing a 1 while the port is in input mode turns on pullups.
User avatar
westfw
 
Posts: 1427
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: Increasing the speed of execution of the adafruit feathe

by westfw on Thu Apr 26, 2018 2:33 am

Being the curious sort, I did some tests with digitalWrite() and "faster alternatives."
(I used a sparkfun SAMD21 board; it should be the same...)

A while(1) loop with nothing but alternating digitalWrite()s runs at about 310kHz. That's (only?) about twice as fast as an Arduino Uno (148kHz), which is a bit disappointing.

A "best effort" loop does about 12MHz - nearly 40x faster than digitalWrite(). That's worse than I expected. :-(
(the 12MHz waveform is pretty icky. Adding some no-ops to get it closer to a square wave gets you around 8MHz.)
(A "best effort" AVR loop does about 4MHz. There's some extensive discussion on AVR pin-toggling here: http://forum.arduino.cc/index.php?topic=4324.0 )

Code: Select all | TOGGLE FULL SIZE
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, 0);
}

#define FAST 0

void loop() {
#if FAST
  PortGroup *port = & PORT_IOBUS->Group[g_APinDescription[LED_BUILTIN].ulPort];
  uint32_t mask = 1ul << g_APinDescription[LED_BUILTIN].ulPin;
  while (1) {
    port->OUTCLR.reg = mask;
    port->OUTSET.reg = mask;
  }
#else
  while (1) {
    digitalWrite(LED_BUILTIN, HIGH); 
    digitalWrite(LED_BUILTIN, LOW);
  }
#endif
}
User avatar
westfw
 
Posts: 1427
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: Increasing the speed of execution of the adafruit feathe

by westfw on Tue May 22, 2018 7:05 pm

A Metro M4 runs the digitalWrite() loop at about 1.2MHz, and 30MHz for the "direct port IO."
User avatar
westfw
 
Posts: 1427
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Please be positive and constructive with your questions and comments.