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.
not a Wiznet lover
October 23, 2014 at 12:35amThe Arduino often uses Wiznet peripherals:
one of the best in the world to kill the Ethernet bandwidth.
In theory, you expect 10 Mbps or 100 Mbps.
In practice, you get 10 kilobits …
C
July 1, 2015 at 4:57pmHi there heist planner/reverse hacker 🙂
I am an explosive developer/software expert asking you for some advice.
I am building a control board for one of my models and this time have decided to also include a computer interface, so have incorporated an Arduino uno into my project instead of just plain circuits. I’m not an electronic expert of any sort but i manage by applying basic logic and allot of trial and error.
Anyway, I have a single Arduino. It is operating the folowing:
An LCD display
A 4 button operation panel i made using an LS148 ic
A L293 operating 2 small motors
A servo
A dark sensor
And a temperature sensor
Oh and also serial communication.
Everything is working great, but slow (or so it appears).
If i push a button it takes the board about a second to pick up on the signal while an external led indicator show the circuit using the LS148 is working as it should. (I basically chained the 1-4 inputs and checking the truth table on the board to determine which button was pressed). Or pick up on a signal sent from the dark sensor for example. It appears as if the whole code in the arduino runs at a cycle of once per second.
When i remove the LCD everything works fast(er) and so goes when i remove other parts. So my question is, have i overloaded it?
I am on the verge of ordering another board (which i am going to do anyway), but in this case it is purely due to my belief that if i connect the LCD with the whole display code onto one board and the rest of the sensors and chips to another it will solve my problem.
What say yee?
MB
September 12, 2015 at 8:55pmHeyy.. Servo might be consuming too much power. Try using a mosfet and a different power source to switch the servo.. Also you have to use a different power source to run motors.. ( for ic293)..
Sorry, i don’t know much about LCDs
Dave Lar
January 18, 2016 at 5:30pmIssue of slow comes from the system response of standard library items. For example, the liquid crystal display library takes on order 40 mSec to update a 16×2 display. For my system, trying to design around this when I need 1 mSec resolution is difficult. Most Arduino libraries make no mention of the speed it takes. For a new developer they can be running into many issues and then comprise good design just getting things working. As a software engineer by trade and a hobbyist on the weekend, I must design completely different on Arduino and pay close attention to the speed of the library calls. I do this however because I do not have time anymore to get simple things working, I just want it to work and find I am knowledgeable enough on the constraints to design around them. Also, the development tools for a specific microcontroller are expensive.
If anything, Arduino promotes poor software design in the way they teach examples and lack of interrupt options for periodic events. I realize they have to strike a balance but the environment is really tough and does nothing to teach a new developer how to structure a good project. When it does come to timing, functions like millis() and micros() return long, 4 byte values on a 8 bit machine is extremely inefficient. Since float does not do what is intended, it should be omitted to avoid confusion of it doing something it does not. It does make things simple to get stated, but at a price.
A better approach would be to have a multi thread kernel in place and teach entry level from this view. This approach would allow standard calls can be in a lower priority thread and my application where timing is critical can be in a higher level thread. Something more then what is present is needed. Timing on standard items is really a must. If real time performance is what you need, it is definitely required to study run time of your code for a good system. The Parallax Propeller really has a better architecture for splitting things up.
Just my two cents!
Ccweb1
July 12, 2016 at 7:05pmI just wanted to post a solution to the above problem listed by c. I was having the same problem my project has simpler parts, and my sensor was picking up every now and then. If I took the lcd code out of the loop, or in my case just stopped it from updating the lcd the loop was extremely fast and wuld pick up my sensor every time.
So my solution will be to use the lcd but if no changes need to be made to lcd my script will bypass writing to the lcd.
Hope this helps others out there with a the same conundrum