Arduino is slow? What? This instructable will show just how slow a part of Arduino is, and how to fix it.
It’s true – more specifically, Arduino’s digitalWrite command takes a considerable amount of time. If you are just switching on a LED once or something, you won’t be able to notice it. However, I realized how slow it was while I was trying to use a TLC5947 PWM driver. That requires the microcontroller to shift in 288 bytes each time! Each byte required about 12 digitalWrites, for a total of 3456 digitalWrites each time I wanted to shift in new data to the TLC5947.
How long did that take? 30 seconds of just digitalWrite!
But there is a solution – using “true c” style commands, or what the AVR GCC (GNU C Compiler) uses. The brains behind Arduinos are ATMega168s or ATMega328s. The AVR community typically uses “true c” commands to program these chips, using AVR Studio 4. The advantage of using these “true c” commands is that it does exactly what you tell it to do.
But before we get in to these commands, we must get familiar with port and pin definitions in the next step!
(If you predict you will like this instructable, feel free to vote for the Arduino contest!)
Arduino users know that the pins are labeled as digital 0-13 and analog 0-5. The makers behind Arduino used this for simplicity. The actual ATMega chip’s pins are labeled differently, however. Each pin has an assigned letter and number. The numbers range from 0-7. For example, pins can be A0-A8, B0-B8, and so on. All of the AVR 8-bit pins are labeled this way.
To help you clarify which digital/analog pin corresponds to which AVR pin, see the chart below.
My Seeeduino has a LED built in on digial pin 13. So, looking at the chart, its real pin would be B5.
Next I will show you what the actual C command is.
PORTB |= 0b00100000;
PORTB &= ~0b00000000;
If you don't use the logic operators, but just the equal "=" sign, all the pins are going to be set like the byte you sent, not just pin B5. In the case where you set B5 high, you would set all ohter B pins to low.
This is pretty safe if your sketch is simple and doesn't do much multitasking or multiplexing of pins, but can get perilous if you've got a complex one.
In function void loop():
Error: 'PB5' was not declared in this scope.
I use 0018 software.
I used form PORTB = B.....;
and it took 3808 vs 284 microseconds.
I'm trying to get TLC5945 communicating with arduino, no luck with digitalWrites, hopefully this version works.
Me, I'm trying to PWM on all the pins of an Arduino Duemilanove to dim some LEDs.
If anyone has problems, replace
" PORTB |= _BV(PB5);
PORTB &= ~_BV(PB5);"
with:
"PORTB = 0b00100000;
PORTB = 0b00000000;"
Which should toggle PB5 like the original code. PB5 shouldnt have to be declared, as winAVR should recognize it as a pin, but arduino 0018 may be doing something funky with that.
Or how do you program an Arduino in this way?
Can you use the Arudino's usb ftdi connection?
Please elaborate. Thanks!
You can use AVR Studio 4, however it is quite complicated and you cannot use the usb connection, you will need a ISP programmer to burn the programs.
http://www.arduino.cc/en/Reference/PortManipulation
The description at the top of the page says "Port registers allow for lower-level and faster manipulation of the i/o pins of the microcontroller on an Arduino board."
Wayne
Here's my fav bitwise link: AVR bit tutorial
Other than that, it's a good 'ible...
horrible pun was unintended
SPI doesn't use the USART, it uses SS/MOSI/MISO/SCK, the latter 3 are used for ISP programming also.
hmmm, i notice that there's no longer any range checking on pin numbers. although this speeds things up i wonder what havoc a pinMode or digitalWrite to some out of range value might wreak.
How does the ShiftOut() command compare to this? Looking at the arduino reference it seems to be dedicated for this task (if the SPI pins are available..)
Would be nice if someone posts some numbers, since i do not own an arduino to test with..