I am working on a Arduino project using the Uno. The project contains a significant amount of code. I would like to create a library and I may even share it later on. What guidelines should I follow while designing the library?
2 Answers
There are a lot of points that you should keep in mind while designing a library. As you will probably, end up sharing your work with others, it is extremely important to follow consistent design patterns. Keep in mind that other users will be of extremely varying skill levels, so design an easy to use library, to the maximum extent possible.
Basic Tips
Pin Map
Provide a basic pin map that your library is expecting. Do not keep the pin mapping static but allow the user to make changes easily.
Working Library
One of the first things that you should try to ensure is that your library is working. If it isn't, clearly state so. You wouldn't want to end up wasting your time trying to work with broken software, so dont let others do so as well.
Basic Readme
Mention very clearly which board(s) the library was designed for, on which it was tested, and what board(s) is it expected to work. Specify the generation (version) of every board mentioned here.
Interfaces
The next thing is that you should have clearly defined interfaces. A working library with convoluted interfaces is frustrating. This will help you yourself use the library later on, and will make things easier for other users. This should be one of the most important aspects to keep in mind.
Whether you follow a top-down or a bottom-up approach, the interfaces should always be clear in your mind. In a bottom-up approach, this may and will be hard, but it should not be ignored. Otherwise, you will end up with a overly complex library which may not be usable.
Special Functions
If you have any functions that use some special board characteristics, make sure to make these functions stand out, mention in the readme and also in the comments.
Busy Waits
There might be scenarios where you might have to use a busy wait. Such functions, depending on program logic, may prevent normal control flow thus causing trouble while in the middle of a critical task. Try to use interrupts or other algorithms, if possible. If not, then clearly mention mark any such functions.
Comments
Make sure to keep commenting every small and big change you make. Write nice long comments for all of the critical functions and smaller ones for others. Explicitly describe your interface, each argument, what it does, and what it returns. This is a lot of extra work, but will be immensely helpful for both you and others. If you have any functions that may not work across different board(s), mention it here. If these are intermediate functions being used by other functions and may be necessary, mention in the Readme.
Consistency
Make sure everything, even the comments, are consistent across the .h
and .cpp
files.
Keep only related functions within a single file. Having a few small, but logically consistent, modules is better than one huge file with everything in it.
Advanced Tips
Detailed Readme
Write a clear readme file describing the library, its abilities, any problems or bugs, and basic usability. Use a separate file for defining and explaining each interface as described above.
Directory Structure
Once the library becomes large dividing it into directories may be needed. This is not easily possible while using the arduino-ide. But, if you reached this far, you probably are an advanced Arduino user and use more powerful development tools. If not, this is the universe telling you to do so.
Licensing
Be sure to add a license.
Version Control
Use a VCS tool such as Git or SVN. This will make it much easier to see changes made, revert to old versions, spot error causing code, and even collaborate with others.
AshRj's answer is very good - I have just 2 points to add to it.
Point 1: Documentation
AshRj recommended to write a detailed readme. Whilst this can be good practice, it can quickly get out of hand with larger libraries - indeed, even at a few thousand lines (which is really not much), a readme will have almost no benefit. My recommendation would be to go one step further and use the equivalent of Javadocs for C++ - as this answer explains (it's on Stack Overflow), Doxygen is a very useful tool for keeping documentation manageable and to hand (no-one wants to edit a 10K line readme file...)
Point 2: Directories
Again contrasting against AshRj's answer, always use directories. Even if you only have 10 files, maybe even with just 7 or 8. I know it sounds a bit stupid, but it's future-proofing your work, and if you don't start early you'll just end up with a mess of files. Directories aren't just for large projects - small ones should use them as well. Just remember that in C++ (the de-facto Arduino language), directories are ignored when including files from a library - they exist as a code-management tool only.