Subscribe to and share this blog by clicking the links to the right -->
By: Gabriel Staples
Written: 5 Jan. 2014
Last Updated: 20 Oct. 2016
-added info on __attribute__ syntax - 25 Sept. 2015
-added more __attribute__((__packed__)) and #pragma pack(1) links to bottom - 4 Sept. 2015
-macro comment addition to Intermediate section - 20 June 2015
-added Expert links section - 9 May 2015
-links edited at bottom - 5 March 2015
-added another Advanced link - 24 Feb 2015
-added Vilros starter kit links to bottom - 7 Feb 2015
-added source code link for my RC car read PWM sketch - 2 Nov. 2014
-added a bunch of new links at bottom of article (mostly Intermediate) - 14 June 2014
-added details and corrections pertaining to microcontrollers being used in servos - 17 March 2014
-added link to (incomplete, but functional) touch lamp code - 20 Oct. 2016
Be sure to check out the links and resources at the end of this article, as they are EXTREMELY useful to anyone who uses Arduino microcontroller development boards!
Other Related or Interesting Articles:
- Parallel Charging Your LiPo Batteries
- Propeller Static & Dynamic Thrust Calculation
- Bungee-Launched "Stingray" Free Flight Glider
- Beginner RC Airplane Setup
- TED Talk - Massimo Banzi: How Arduino is open-sourcing imagination
So, you may be wondering why I haven't written an article in the last few months. To be honest, writing a well-informed article, with plots, pictures, and sources takes vast amounts of time, and life gets busy. However, I should also tell you that I have been heavily involved in Arduino microcontroller programming for the last several months, and I have spent countless hours learning about and programming Arduino. I have now built up a variety of Arduino tools and resources that I use, including dozens of bits of test code, many projects and programs, and hundreds of files, links, and resources. I have even written some code and functions which I have seen nowhere else, which I think are very valuable, and which I intend to periodically share here on my blog. In other words, I think I have some useful things to contribute to the vast world of Arduino, some of which will help bridge the world between Radio Control, robotics, and Arduino microcontroller programming. Though I am constantly learning, and constantly seeking help from resources and people who know much more than I, I would consider myself a very informed Arduino user with a sound, yet constantly growing, understanding of electricity, electrical engineering, programming, and computer science.
Why have I recently been doing Arduino programming instead of doing Radio Control stuff?
Learning Arduino is doing Radio Control stuff. It turns out that the world of Radio Control is
completely inundated with microcontrollers and programming--though perhaps very few Radio Control guys/gals are aware of this. A microcontroller is, in short, a miniature computer, which operates as intimately with hardware as is possible for code to do. It is designed to control the physical world around us. RC devices are controlled by them. The Arduino development board utilizes Atmel-brand microcontrollers. The Arduino therefore is an incredibly capable little computer which makes customizing your RC experience, adding additional sensors or functionality, or even turning your RC device into an Unmanned Aerial Vehicle (UAV), Unmanned Aerial System (UAS), or Unmanned Ground Vehicle, possible! With Arduino, you can take a standard RC device and make it an autonomous or semi-autonomous robot. The limit of what you can do is only constrained by your ingenuity and imagination!
Microcontrollers in Radio Control Today
Without microcontrollers, like those used by the Arduino development platform, RC as we know it today would not exist! Though I have become knowledgeable on the subject very quickly, I have been doing Arduino microcontroller programming for less than a year. It wasn't until approximately April 2013 that I first picked up an Arduino and made it blink, and it wasn't until approximately July 2013 that I actually caught the vision. Now it's time for you to catch the vision too!
When I fly an RC airplane, here's where microcontrollers are used:
- The transmitter (Tx): I know for a fact my computer-based Tx uses at least one microcontroller. That's the "computer" in the radio that stores and changes settings, shows your settings on a display, and creates the PPM (Pulse Position Modulation) signal which comes out the trainer port in the back of the radio. I don't know for sure, but I believe there is also an additional microcontroller in the RF (Radio Frequency) module which actually sends the signal out over the airwaves. I presume that if this one exists in the RF module, it would be what controls the pseudo-random 2.4Ghz frequency hopping algorithm.
- The receiver (Rx): Every one of my 2.4Ghz Rx's uses a microcontroller to read in the signal, process it, separate the channels, and send out individual channel signals as PWM (Pulse Width Modulation) signals. These PWM signals are what go to the servos and ESC (Electronic Speed Controller).
- The Electronic Speed Controller (ESC): Every ESC must have a microcontroller. Brushed speed controllers use one to chop the battery voltage via PWM, in order to throttle the motor. Brushless speed controllers use one to chop the battery voltage via PWM, in order to throttle the motor, as well as to do a very complicated commutation algorithm, based on feedback, which times the switching and "rotating" of electrical signals around the motor in order to allow the electromagnets to push and pull on the permanent magnets, in just the right places and at just the right times, in order to cause the motor to rotate.
- The servos (some). Though many servos use integrated circuits (ICs), some servos have an embedded microcontroller chip to decode the incoming PWM signal from the Rx, read a potentiometer to decipher their position, and move themselves to a commanded position, using potentiometer feedback, to ensure they get there. This is what servos must do, and though the servos I have looked at use an Integrated Circuit (IC) like the AA51880 Servo Motor Controller, some more advanced servos are programmable and have customizable gains, slew rates, and other control parameters, and use embedded microcontrollers rather than ICs. One such servo is the open-source "OpenServo."
- The charger. Every smart charger uses a microcontroller. It is safe to assume that if it has a display, it uses a microcontroller.
- Your voltage checker and/or low voltage alarm. I use a voltage checker on the ground to verify battery voltage and cell balance before and after each flight. It uses a microcontroller. I opened it up and checked. I also use a low voltage alarm on my plane to beep when my battery is low. It uses one too.
So, each and every time I fly an airplane, there are at least 5 places microcontrollers are used. Each device that uses a microcontroller must have specially-designed code on it to perform very specific tasks, that a computer programmer (or someone like you or me) put there! In a single flight, I may be using up to 10 or more (for sure I am using at least 5) microcontrollers just to make it happen. Now, with the power of Arduino, I can learn to customize and enrich my RC experience by turning my RC devices into robots, by creating custom code (firmware) to load onto an Arduino and put on my airplane or car in order to make it do...whatever I want!
Arduino video: Reading the throttle signal from an RC car receiver, and using it to change the blink rate of an LED (could be used as a head-lamp or tail light on the car, for instance): [source code]
My Arduino History:
- Sometime during the beginning of 2013: My good friend Michael Cardoza, a high school Spanish Teacher (and great person to inspire one to try new Arduino and electronics projects), showed me his Arduino. I had no idea what that was. I wasn't very interested. Didn't look very impressive, and to me, it wasn't related to RC (boy was I wrong!).
- 13 April 2013: I made a used Arduino Duemilanove blink. It took me ALL day on Saturday to accomplish this (prob. 8~10 hrs.). This was a very rough transition into microcontroller programming, as the stinking thing was used and had a bad bootloader. I eventually figured out how to reload the bootloader onto it using a USBasp AVR programmer I had picked up earlier from HobbyKing, but never used until that day. (By the way, the USBasp programmer uses....guess what....a microcontroller! :) ).
- July 2013: I picked up the Arduino again. This time, I caught the vision.
- By October 2013: I had become completely absorbed in Arduino microcontroller programming, as a new primary hobby for the time being (it will always be part of my RC endeavors now). I began doing various projects and things, some being quite complicated and difficult for me, to continue learning Arduino.
- Today (5 Jan. 2014): I continue making leaps and bounds, as able, in my understanding of and ability to use Arduino microcontroller programming.
To date (13 April 2013 to 5 Jan 2014), I estimate (via some calculations I just did) that I have spent approximately 472 hrs. learning about and/or doing Arduino microcontroller programming or learning about and doing related circuit analysis and electrical engineering. Arduino and microcontrollers are such an amazing tool.
- BE SURE TO CHECK THESE OUT - these are really fantastic learning sources!
Arduino Starter Kits:
- I really like the Vilros-brand kits purchased on Amazon! Vilros gives you high-quality parts and kits with outstanding value for your money.
- Amazon search for "vilros arduino"
- Vilros Arduino Arduino Uno Ultimate Starter Kit + LCD Module -- Includes 72 page Instruction Book, $63, my personal favorite Arduino starter kit!
- http://arduino.cc/en/Main/Products - it is very important that you thoroughly understand your Arduino --learn all about your particular Arduino board here!
- http://learn.adafruit.com/category/learn-arduino - absolute beginner tutorials--very fantastic website and information!
- http://arduino.cc/en/Tutorial/HomePage - hundreds of beginner tutorials and examples
- http://arduino.cc/en/Reference/HomePage - Arduino reference page -- you will come here often! If you aren't regularly referencing these pages, you should be! You can also find the entire Arduino Reference right on your computer by going to Help --> Reference right inside the Arduino IDE (Integrated Development Environment). This is SUPER useful when working offline.
- http://forum.arduino.cc/ - the Arduino forum - ask your questions and get help here
- Programming Arduino Getting Started with Sketches, By Simon Monk, $8.48 - GREAT BOOK; also teaches the basics of writing your own Arduino libraries.
- Programming Arduino Next Steps: Going Further with Sketches, By Simon Monk, $12.89 - GREAT BOOK; among many other things, teaches some more advanced input/output and signal processing techniques for Arduino, as well as how to write your own Arduino libraries.
- http://playground.arduino.cc/Main/LibraryList - hundreds of user-contributed Arduino Libraries to expand what you can do with your Arduino!
- Libraries I have contributed have names which begin with "eRCaGuy," so do a search for "eRCaGuy" on this page and you'll see my libraries.
- http://playground.arduino.cc//Main/InterfacingWithHardware - tons of user-contributed code and examples to interface with hardware
- http://playground.arduino.cc//Main/InterfacingWithSoftware - tons of user-contributed code and examples to interface with software (including data-logging and plotting, live data display, controlling your Arduino via a GUI on your computer, etc)
- http://www.cplusplus.com/ - Arduino is based on C/C++. As you become an intermediate user, you need to know that you are NOT limited just to the functions on the main Arduino Reference page. Rather, you have access to nearly *any* standard C/C++ function.
- AVR Libc reference pages - This link contains a list of all of the C functions (organized by header files, .h files) that are available for use on ATmega microcontrollers/Arduino!
- For a real description, & examples, of how to use one of these functions, however, I recommend simply Googling the function name you want, as follows: ex: I want to know how to use "scanf," so I Google "scanf c", and the first link that pops up is this: http://www.cplusplus.com/reference/cstdio/scanf/.
- Or, let's say I don't know that "scanf" exists, but I want to know how to read parts of a string, out of a string. So, I Google "c read parts of a string", and the first link I find is this: http://bytes.com/topic/c/answers/221802-how-read-part-string. Now, I read their code and see that "scanf" is used in their code, so I can either look for the reference page for this function on Cplusplus.com directly, *or* I can Google "scanf c", as described above, to find a good reference page describing it in detail.
- Alternatively, you can simply go directly to http://www.cplusplus.com/, or other similar C/C++ websites, and search for the function you want to use. Again, an Arduino can use virtually any C/C++ function, since that's what its language is based on!
- If any C/C+ function you find does *not* work on Arduino, or acts strangely, however, go back to reference the AVR-libc pages, as AVR-libc is what actually implements the C/C++ language for Atmel's AVR microcontrollers, and not 100% of the functions are implemented. Some deviations may exist. Therefore, some things on cplusplus.com, for example, might not work on the Arduino, but everything in AVR-libc will!
- AVR Libc FAQ
- For ex: see the section titled "Can I use C++ on the AVR?", among many others...
- Learn to write macros, for example, in place of very short functions or repeated operations. Macros are very useful, and you should probably begin to learn to understand and use them as an intermediate programmer. See the top of the "Expert" section below for more information and links. Many of the Arduino "functions," as shown on the Arduino Reference page are actually precompiler operations, in the form of macros in this case, rather than true functions. Macros are basically just textual substitutions in your code, and they get substituted into your code by the precompiler *before* the compiler interprets and converts your C code.
- By Ken Shirriff:
- http://www.righto.com/2009/07/secrets-of-arduino-pwm.html - an absolutely FANTASTIC article on the intricacies of controlling the low-level PWM capabilities of an AVR microcontroller on an Arduino
- By Nick Gammon:
- http://gammon.com.au/interrupts - an IMMENSELY USEFUL and well-written article, by Nick Gammon, on AVR microcontroller interrupts
- http://www.gammon.com.au/forum/?id=11504 - another EXTREMELY USEFUL article by Nick Gammon, on AVR microcontroller timers and counters
- http://www.gammon.com.au/forum/?id=11497 - Power saving techniques for microprocessors - very useful if you want your Arduino project to run for a very long time, on battery power, utilizing sleep modes, without a voltage regulator, etc etc.
- http://playground.arduino.cc/Main/TimerPWMCheatsheet - excellent info. to help you modify your Arduino PWM output frequencies quickly
- ATmega328 Datasheet:
- http://www.atmel.com/Images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet.pdf - this is the 660 pg. datasheet of the Atmel ATmega 328 microcontroller, used by most Arduinos -- this is an absolutely ESSENTIAL document if you plan on doing low-level Arduino microcontroller programming, including direct manipulation of its timers, ports, registers and things
- Find the main ATmega 328 webpage here: http://www.atmel.com/devices/atmega328p.aspx
- By Mikal Hart :
- http://arduiniana.org/ - Arduiniana - Arduino wisdom and gems by Mikal Hart
- http://yourduino.com/sunshop2/ and http://arduino-info.wikispaces.com/ - I have found a lot of good, useful info here.
- Learn to use the C Preprocessor, and write Macros (writing macros is a very important skill, as many of the core Arduino "functions," such as lowByte(), highByte(), bitWrite(), etc, are actually macros).
- The following macros are defined in "Arduino.h" (found on your hard drive at Arduino\hardware\arduino\avr\cores\arduino\Arduino.h), for example:
- #define lowByte(w) ((uint8_t) ((w) & 0xff))
- #define highByte(w) ((uint8_t) ((w) >> 8))
- #define bitRead(value, bit) (((value) >> (bit)) & 0x01)
- #define bitSet(value, bit) ((value) |= (1UL << (bit)))
- #define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
- #define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
- The C (& C++) Preprocessor (and Macros) tutorial
- C Preprocessor Directives
- Arduino Core Library C/C++ Soure Code - Learn to answer your own questions about how Arduino works by reading its C/C++ Source Code for yourself!
- View it on your hard drive, in the Arduino installation directory.
- View it on GitHub here: https://github.com/arduino/Arduino - use the search box at the top to search the Arduino source code repository, which is very useful to find the definition of various macros or functions you are looking for, since it searches *inside* the files too, not just the file names!
- Compiler Optimization settings: learn to change the GCC compiler optimization settings to optimize your compiled C/C++-to-Assembly-code for compiled size vs run-time speed, etc.
- Instructables.com: Arduino IDE 1.6.x compiler optimisations = faster code, by Bodmer
- Use #pragma GCC optimize ("-O2"), for example, at the top of your code to change optimization level without having to edit the Arduino platform.txt file (which was described on the Instructable above) - https://gcc.gnu.org/onlinedocs/gcc-4.8.4/gcc/Function-Specific-Option-Pragmas.html
- Learn how to use gcc Attributes (ex: "__attribute__ ((aligned (4)));", "__attribute__ ((__packed__)))", etc.
- Function Attributes
- Variable Attributes
- Type Attributes
- Attribute Syntax (more here)
- Key points:
- "You may optionally specify attribute names with ‘__’ preceding and following the name. This allows you to use them in header files without being concerned about a possible macro of the same name. For example, you may use the attribute name __noreturn__ instead of noreturn."
- "Type Attributes: An attribute specifier list may appear as part of a struct, union or enum specifier. It may go either immediately after the struct, union or enum keyword, or after the closing brace. The former syntax is preferred..."
- Structure Packing & Data Alignment
- http://stackoverflow.com/questions/30038172/adding-unused-elements-to-c-c-structure-speeds-up-and-slows-down-code-executio - links & general info; also info on Data Alignment in the answer by Collin Dauphinee.
- http://www.catb.org/esr/structure-packing/ - Structure Packing
- http://www.songho.ca/misc/alignment/dataalign.html - Data Alignment
- More on "__attribute__((__packed__))" [<--gcc only] and "#pragma pack(1)" [<--preferred]
- *****Q: What's the difference? http://stackoverflow.com/questions/32208805/what-is-the-difference-between-attribute-packed-and-pragma-pack1
- A: "__attribute__((__packed__))" is for gcc (GNU C++) compiler only, whereas "#pragma pack(1)" was originally a Microsoft Visual C++ directive, and is now available in gcc and most compilers. Also: the former applies to the definition it is attached to only; the latter (#pragma pack(1)) applies from that point on, until undone by calling #pragma pack() with no arguments.
- *****+https://gcc.gnu.org/onlinedocs/gcc/Structure-Packing-Pragmas.html. Key points:
- #pragma pack(n) simply sets the new alignment [to n, where n is a power of 2, ex: 1, 2, 4, 8, 16]; see the Microsoft link below as well
- #pragma pack() sets the alignment to the one that was in effect when compilation started
- *****Microsoft's description of "pack". Key points: "pack takes effect at the first struct, union, or class declaration after the pragma is seen. pack has no effect on definitions. Calling pack with no arguments sets n to the value set in the compiler option."
- ****Google search for "pragma pack"
- Writing efficient C code for an 8-bit Atmel AVR Microcontroller
- AVR035 Efficient C Coding for AVR - doc1497
- AVR4027 Tips and Tricks to Optimize Your C Code for 8-bit AVR Microcontrollers - doc8453 -
- Viewing Arduino C/C++ "disassembled" (Assembly language) code
- Todo: add links here; ex: how to produce a professional product perhaps...
A Few Great Arduino Libraries Worth Mentioning:
- Arduino Playground:
- Libraries: (Main Arduino user-contributed library list--this link copied from above under the "Intermediate" links): http://playground.arduino.cc/Main/LibraryList
- Snippets And Sketches for Arduino: http://playground.arduino.cc/Main/SketchList
- By Me: click on my "Table of Contents" link at the top of my website, then look under the "ARDUINO LIBRARIES" heading for a list.
- By Ken Shirriff:
- Arduino-IRremote - http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html
- By Mikal Hart:
- http://arduiniana.org/ - see his libraries list in the right-hand pane
- By Duane B:
- http://rcarduino.blogspot.com/2012/10/arduino-serial-servos-20-servos-4-pins.html - he has some great servo code snippets and libraries for the advanced user. For example: control 20 servos using only 4 pins and 2 x 4017 dirt-cheap decade counter IC chips.
- Base code on his website: http://rcarduino.blogspot.com/2012/08/arduino-serial-servos.html
- Also look for anything by Adafruit/LadyAda (Limor Fried) and Simon Monk, of course.
- Adafruit provides code and libraries for nearly every single product they sell. They are one of the #1 supporters of Arduino in the world, and they are US-based!
- Sparkfun can be a good resource too--also US-based!
Other Inspiring Links:
- TED Talk - Massimo Banzi (the primary founder of Arduino) - How Arduino is Open-Sourcing Imagination
If you like this article, please be sure to subscribe to my blog, tweet and like it on Facebook! Links to like and subscribe can be found just below, and at the upper-right of my blog. Look for the "Subscribe & Share" section to the top-right! Also, feel free to leave comments below.