For the second post about Arduino misconceptions, there is the a common idea circulating that the Arduino is “slow”. Most frequently I hear this in the context of reacting to user input, dealing with multiple sensors, using LED or LCD displays, or acting as part of a control loop. People advise faster microcontrollers such as the ARM Cortex series.
Let’s look at the fundamentals here:
- The ATmega328P on the Arduino boards runs at 16MHz – that’s 16 million cycles per second.
- The ATmega328P instructions take between 1 and 3 clock cycles (with the exception of the subroutine related instructions which take 4 or 5). The average is somewhere between 1 and 2 for most compiled C code.
- We can then infer than the ATmega328P can carry out at least 8 million instructions per second!
- It’s hard to directly translate these instructions to lines of C code. What looks simple in C can take tens of instructions, and what looks complex can be done in one.
- We can still say that the ATmega328P is going to tear through your code at a rate of knots, far faster than most people imagine.
So why do people say it is slow? I’d say the following reasons:
- It is 16MHz, and most people’s PCs and phones operate in the 1GHz range, so it doesn’t sound like much. The ATmega328P is performing entirely different tasks though.
- It is 8bit, and most modern processors are 32 or 64 bit. This doesn’t have many implications for projects using the Arduino though (but will be related to my next misconception!)
- The frequent use of delay() in Arduino code. Delay() causes the processor to just churn – it can’t do anything else whilst it is running. So if you have 4 buttons which are meant to turn on 4 respective LEDs for 2s, the system becomes unresponsive if you use delay() for the 2s.
- The frequent use of Serial.print() in most code for debugging or status reports. Arduino pre-1.0 uses to block when sending data out using the serial port. That meant an 80 character string output at 9600bps (the default, for some reason), would take over 80ms, during which time the processor could do nothing else! Even now that it uses interrupts, strings still take a long time to output.
- Slow digitalRead and digitalWrite – these two functions are orders of magnitude (~60 cycles) slower than direct port access (~1 cycle!). Heavy I/O can look slow or latent as a result.
- Bad code – the Arduino is exceptionally easy to use without understanding any of the underlying concepts of microcontrollers. As a result, code is sometimes simply bad.
A faster microncontroller can mask some of these issues, but without understanding some key concepts (interrupt handling and well structured state machines), you are going to be up against the same wall again in no time.
That’s not to say that faster microcontrollers aren’t needed sometimes – anything with heavy number crunching needs something more – but for a lot of situations an Arduino is more than capable in the hands of a good developer.