For all parts to this project, click here! Smart Doorbell System
Introduction
The Smart Doorbell System is an idea for a home bell-push/chime system with better range and features than expected from existing systems!
The project will use a Texas Instruments integrated circuit (IC) called the CC2640R2F which internally contains Bluetooth functionality (this will be a wireless doorbell system!) and built-in microcontroller too.
Since this design challenge is a complete project, I ought to share the design process, and an important part of this concerns how to get started with a new chip – I’ve never used the CC2640R2F before, but this should not be scary or a problem generally – it is an opportunity to try to succeed.
There is no right or wrong way to do things, but I will just describe the process I personally follow when using a new chip for the first time. There are some advantages to carefully selecting a chip where you know the manufacturer has put in the effort to produce a reliable development environment and software libraries with user-friendly application programming interfaces (APIs), because these will reduce the learning curve and make one productive quicker.
If you’re interested to know more about the doorbell project then check out part 1 or part 2, otherwise read on here, to see how to use a new microcontroller.
Development Environment and APIs
Often I prefer using parts from certain manufacturers. The fact is, despite nearly all microcontrollers these days being based on ARM Cortex-M cores, there are many extras which can make life easier or harder. The microcontroller core alone is only part of the picture. What also matters are the integrated peripherals, ease of programming and debug, development environment and supplied firmware API and quality for the integrated peripherals.
Most manufacturers these days supply an integrated development environment based on a custom version of Eclipse which is open source. This is really nice, because it provides for some familiarity. I always know I should click on the hammer icon to build the code, and click on the bug icon to run or debug the code.
Texas instruments development boards have a built-in programmer and debugger, so no extra hardware is needed. All that is required, is to download the development environment (it is called Code Composer Studio or CCS) and start writing code.
CCS is a large, comprehensive piece of software because it supports many hundreds (if not thousands) of devices in the Texas Instruments portfolio. In recent years a more lightweight option has become available called CCS Cloud. It is a browser-based version of CCS that does not need to be downloaded. It allows any low-performance PC to be used, without taking up CPU, memory or disk resources beyond what the web browser needs. CCS Cloud is excellent, and I sometimes use it, but for this project I decided to use the original locally-installed CCS.
Another important consideration is the supplied library code (and example code) and the application programming interface or API. One reason why Arduino is so popular is because for the most part the API is extremely simple and is consistent across different Arduino’s. If you’ve learnt to use the Arduino Uno, then you can use the Arduino Mega and so on.
In the software engineering world another popular API is called the Portable Operating System Interface or POSIX. It is defined by a standards body (the Institute for Electrical and Electronic Engineers or IEEE). POSIX is generally adhered to for large operating systems (OS) such as Linux. Linux cannot generally run on small microcontrollers (there are exceptions but they have significant limitations), and so POSIX has in the past been less important for microcontrollers. There were other standards more suited for microcontrollers. These standards defined how tasks or processes could be started up on a microcontroller, how interaction could occur, and how typical resources such as timers and communication could be used. One example would be uITRON which was popular in Japan.
Texas Instruments has taken great care to produce a set of APIs that closely mirror those available with Linux; they are very POSIX-like, so that there is familiarity, but also lean enough to meet real-time performance needs that microcontroller use-cases may demand.
For anyone coming from a classical software engineering background, it would be a delight to use.
The APIs are separated into areas of functionality such as task/process related (very similar to the pthread API on Linux!) and network communication related (very similar to the socket API as devised by the famous W. Richard Stevens and also used in Linux today). If you like standards and you like Linux, then you’ll really like the TI APIs.
Building a Hardware Test Bed
For the Smart Doorbell System, the initial test bed was straightforward. The CC2640R2F chip is available on development boards called CC2640R2 LaunchPad (the red boards in the photo). I used one board to simulate the bell push module, and the other board to act as the chime module.
For the chime module, some audio capability is required. I wish to use digital audio since high quality sounds and flexibility is needed. A standard digital audio interface, I2S, is supported by the CC2640R2F chip, so I decided to use that. To convert to analog audio, a digital to analog converter (DAC) board is used. For now it is a board (purple board in the photo below) I created in an earlier audio project, actually intended for a BeagleBone Black, but since I2S is a standard, it will work with the CC2640R2F too. For the final design there will be a smaller and more cost-effective implementation.
The Texas Instruments LaunchPad boards come with a handy pinout diagram (shown on the left side of the photo). I wrote on it what pins I'm using, and it will become part of the final documentation.
How to use Example Code and Other People’s Code in general
Working with a new platform, and exploring and using example code can be daunting because everyone writes code in their own style and it can take a while to understand how the functionality was split up into objects and functions, processes and the order of execution, and what communication is going on between different bits of code, and where all this stuff is, within the directory structure. Good documentation helps, but even this can be insufficient.
The techniques that can be used to make sense of this also lend themselves to any software project. I used the same techniques each time a third party provided code to me during commercial projects, or when coming on board to a software project half-way.
These ideas are just from personal experience, there may be better ways too.
1. Read the design documents!
It may sound obvious, but there is lots to glean from the design documentation and microcontroller reference manuals.
2. Get familiar with the functionality
Running the code and observing output is really useful. As part of this, I may try different stimulus into the software, to see what it outputs.
3. Enable debug and log files
Log files and debug (this could also be added by you in different areas of the software and then re-compiled) is useful to show the path of execution. Even an LED can help with this, to see how far the code executes.
4. Use operating system (OS) features
Some operating systems will provide tools for exploring code. This can allow you to see how many threads have been created, what and when system calls are being made (i.e. what OS features is the application relying on?) and what resources the code is using (such as CPU and memory consumption).
5. Use code browsing tools
Something I find very useful is to take the source code and run software like Source Insight against it. The software will search the code for variables and function names, and build up a database. Then, you can click on these names and the software will very quickly reveal where the variable or function was defined, and what other areas of code reference them too. Source Insight is not free, but the trial license provides enough time to study the source code that you apply to it. I use it less these days, because development environments like CCS have sophisticated tools already built-in for code browsing. If you right-click on any function and select Open Declaration then CCS will open up the correct header file.
6. Identify the design patterns that the project uses
Most software is not developed in a random fashion. Instead, frameworks and structures are used to perform tasks that frequently occur in code. Some of these patterns are classic and will be described in books on computing.
7. Take notes
There are various ways to document code yourself, I take the easy route and just scribble file names, function names and any important things I need to remember as I go. These are just mental aids to help when it comes to start modifying code.
Using a combination of the techniques listed above, the supplied example code for the CC2640R2 was modified. The example code has a menu system that allows for controlling the board from a USB UART connection. I added to the menu, so that I could simulate a button push directly from there, rather than having to push a real button. This isn’t for laziness; it allows me to develop and test code even if I do not have the hardware wired up to the board. I partially wrote this report while traveling (Milan), and some other parts of the design challenge will be written during some further travels soon. If it is not possible to be able to take a lot of hardware, then it is useful to have the ability to simulate hardware actions and see responses from the USB UART menu system and later attach hardware as needed.
Next Steps
Now that I'm back from travels, I can begin work on coding the digital audio portion; I've connected up the I2S interface to the oscilloscope, so that I'm ready to debug!
Top Comments