A Quick Overview
In this tutorial we are going to discuss Libraries.
If you are reasonably new to coding, and you have been grabbing example code from the Internet to have a “play” with Sensors and the like, you have probably come across libraries.
Typical examples contain the the import line of code similar to the following.
from RPLCD import CharLCD
In most cases you have enthusiastically added it to your code as instructed, your project works and you have thought nothing more of it. in most cases somebody has done the heavy lifting work, released it under GPL or MIT or similar licence for others to use. This is the power of open source and generally you are free to use it for many purposes as long as you follow the licence terms.
If you have purchased a project kit with a whole lot of sensors, the instructions have explained how to load all the code for the kit, and also installed all the libraries. You might have run through a few projects, and you have the benefit that the libraries that you need are already installed, so when you add your import line, it just works.
If this is the level that you want to remain, then that’s absolutely fine. However if you want to move forward, learning more, interfacing and integrating devices, then you need to learn about libraries, how to use them, and ultimately developing your own libraries or forking and expanding existing libraries.
Ultimately, libraries in their most simplistic form are a set of functions that perform repetitious or long winded tasks that can be called from your application.
It should be stated that while you are importing one library into your code, the library it is calling, may actually import several other libraries itself. A typical real world example of this based on the i2c tutorial on this website, and the image below is not comprehensive, but it shows the libraries being imported.
Using the above as an example, you can break up each of the “modules” into the following
SMBUS – manages the I2C communications via the i2c_smbus driver
RPLCD – Manages the LCD functionality (backlight off etc), and manipulating and presenting the data to the LCD device to display.
Logic_Analyzer_i2c.py – Your code which determines the string and variables you want to send and any other affects (e.g. flashing the message)
Please don’t take the above descriptions as strict, as some functions can be handled by any of the “modules”, however its nice when there are some proper demarcation lines.
Do I need to use libraries?
Absolutely not, you do not need to use libraries. If you feel comfortable writing everything in one file, then you go for it. Then ask yourself the following questions
- Is it reliable?
- Is it manageable?
- Is it extensible? (Can I or anyone else continue to add to it)
- Is it reusuable (saving you time on your next application/project)
- Is it good use of my time (to reinvent the wheel) ?
Ok I am making assumptions here, particularly about your application, but my answers come from probably 30+ years of coding in various languages.
Lets look at this a different way. If you have been given a complex task (non computer related), one of the first things you would do as leader, manager, foreman etc, is to divide and conquer the task, or in better management words, delegate, meaning break up the tasks, into smaller manageable chunks.
But lets take that last key word a little further, we don’t just delegate, we delegate to the people that we feel can handle the task assigned to them, utilising their strengths, and when challenges arise, talk to each one about their area, that they know best, and resolve the issues.
So lets move this back to our use of Libraries (at the higher level)
SMBUS – This author specialises in low level calls utilising the SMBus driver to communicate utilising i2c, and one of the important functions of dealing with multiple devices on the bus. This author has studied the SMBUS driver and understands its limitations, but importantly how get the most out of it, and in some cases, work around known bugs, or different versions, adding code to catch these issues.
RPLCD – This author specialises in dealing with the intricacies of the LCD display in the data format required by the LCD display. Not just that but their library handles a few common displays, and they has a good handle of how to interface with the SMBUS library. This author has studied the LCD Data sheets, understands its capabilities, understands various similar products and codes to accept these products as well.
Logic_Analyzer_i2c.py – Then we come to your code which determines the string and variables , handling the input from the user, you may be involved in writing a GUI, but more importantly (and in some cases just as important as the other Authors, you provide the overall idea or vision. Your speciality might be with computer based Alarm systems, and this LCD display forms a little, but important part of the whole design.
I hope I am coming across convincingly, but if not lets take it a little further, and almost falls into the hands of the next section. One of the benefits of utilising another authors work, is that they, in many cases, have worked out the nuances of working with particular devices, such as a temperature sensor that needs 0.5ms reset time, before it can handle further 1-wire transmissions, the developer as identified the issue and accounted for it in their library.
Identifying a Library to use
This is one of the harder parts, is locating a library that you can use, as you might find that you might have a choice of 6-7 libraries that your could quickly locate. Some of the critical things that I look for are :
- Has the library been updated regularly with regular commits to the project
- Is the original author involved with the library
- Does the library contain most of the functionality that I am looking for.
- What was the library written in
- Can I read and understand what the library (important) is doing
- Has the author strong commented their code
- Has the author documented their library (important)
- Has it been written to support the target hardware and operating system
- If I had to change the library (e.g. found to be buggy or no longer supported or available), how much re-coding is needed of my main application.
If I was to provide a real world example, lets look at the i2c LCD tutorial on this website. Whilst putting the tutorial together, I needed a library that anyone could obtain so that they can follow the tutorial and utilise the code.
One library I looked at, without really looking at it, appeared to have a recent update, seem to have most of the basics, but when used for the tutorial, it had one main issue, it didn’t work. I ended up with a program that basically just hung when it came to write to the LCD Display. No error messages, no timeout. So I took a more detailed look (what I should have done the first time). What I found was:
- No documentation
- Coding was not well commented
- Missing several features I was after such as backlight control, and many other similar smaller features.
- Appears that the author wrote this library to meet their exact needs and didn’t appear to be a nice rounded library
- But the biggest issue was that the author appeared to have no way or passing the bus address to their library. In effect, it was written for their own use and expected the device on a particular address on the bus (that’s why the application hung – trying to talk to a non-existent device)
- That last item also shows that they may not have had a complete handle of the subject, so what other limitations am I going to come across.
So now we have discussed a library that failed or was not suitable, lets look at the RPLCD Library that we finally selected for that tutorial (after an hour of really looking closely at it). Its features were :
- Overall Project Description showing it being used on a Raspberry Pi and with an LCD1602 style display
- Reasonably extensive documentation
- They gave credit even for the inspiration
- They list the implemented features – basically all the ones I was after
- It is python 2 and 3 compatible
- They have listed the dependencies
- Listed the supported I2C supported chipsets
- Listed the compatible LCD Controllers (HD44780, ST7066)
- I understood the Library code and what it was doing and felt comfortable adding further functionality to the library if needed
- This code worked not just with I2C, but also with GPIO and PIGPIO libraries for interfacing the LCD without the I2C daughterboard.
- What finally made the decision was the TestSuite, so I could test compatibility before I settled on this library, and besides the TestSuite provided code that I could use if necessary in my own application.
So as you can see, your choice of Library can have a major impact on your project, both in terms of time and capability. Just remember you are not limit to looking at PyPI for your libraries (although i find most of what I need there), but you also have library.io and of course github as well and many more.
Using C Libraries with Python
So far our focus on using libraries has been utilising Python libraries (libraries utilising Python code). For 90% of your projects that is all that you need.
However you have heard that C or C++ is much faster or more adept at interfacing with drivers etc.
C Libraries are useful, when you need fast execution or time critical execution, and yes Python (lets keep it simple – the version you are using on your Raspberry Pi) can utilise C Libraries. This is another topic which we might cover in a later article. I mention it now in case you come across code that utilises a C Library.
Well I hope that provides a quick run down on libraries, and we will cover it as a tutorial, setting you your first library and utilising it. Check the roadmap to confirm progress