For all the parts to this project, click here! Smart Doorbell System
The Smart Doorbell System is an idea for a wireless and portable bell-push/chime system with hopefully better range and features than expected from existing systems!
This blog post covers a couple of things. It discusses how to implement sounds (music or sound effects) on a microcontroller, and secondly, for anyone wishing to build their own Texas Instruments ARM Cortex-M boards, it discusses how to use custom boards with TI’s USB Debugger and the Tag-Connect system, which is explained below.
Connecting the Debugger to Custom Boards
The Smart Doorbell System has a custom circuit board with a TI microcontroller with embedded Bluetooth LE functionality. It needs a programmer to get the microcontroller uploaded with firmware. Ordinarily this is achieved on a development board using a USB connection and on-board debugging circuitry, however the Smart Doorbell bell-push module is tiny and there is no on-board programmer, just some pads for a Tag-Connect cable to press on to.
An external programmer, called the Texas Instruments XDS110 will be used.
The XDS110 comes with various cables for popular connection schemes using dual-in-line headers, however I wished to use the Tag-Connect system which relies on no connector on the PCB, just some tiny pads that the springy prongs can press against. The Tag-Connect system is essentially a ribbon cable with a dual-in-line socket at one end, and the prongs at the other.
So, I needed an adaptor to convert from the XDS110 connector to dual-in-line header pins that the Tag-Connect cable can attach to.
There isn’t a lot to the design; as mentioned it just has a couple of connectors for interfacing the Tag-Connect cable to the XDS110 cable. The connector required to attach to the XDS110 is Samtec FTR-110-51-L-D-A.
I thought I’d try a fancy oval shape. There are two portions; the larger portion isn’t for connecting to the Tag-Connect cable, but is just a generic breakout board for non-standard wiring when (say) prototyping.
I figured it could be useful to annotate each pin on the underside:
It has submitted it to the PCB factory but I’m still waiting for the boards to arrive, so it is currently untested (EDIT - now tested! See below for a video of how to use the adaptor). However, the files are attached, in case anyone else wants to try such an adaptor too (for personal use, not for commercial sale). This should work for any Texas Instruments ARM Cortex-M device (not just the CC2640R2), connecting using the XDS110 debugger and a Tag-Connect cable. To see how this connects to the microcontroller, please see the schematic here: Smart Doorbell System – Part 5 – Final Bell Push Circuit and Antenna Design . One important thing to be aware of when using Tag-Connect, is that the springy pins are numbered like a dual-inline-package (DIP) IC with pins numbered sequentially along a row, but the 10-way ARM Cortex-M connector has pins numbered like a dual-in-line (DIL) header, i.e. odd numbering on one row and even numbering on the other.
The video here shows how to connect up the adaptor and XDS110.
FM Music Synthesizer
The Smart Doorbell system needs sound generation capability, whether that is used for chimes/tones or for complete tunes. The hardware for this comprises of a digital to analog converter (DAC) that is connected to a serial I2S interface to the microcontroller. This interface allows the microcontroller to send a stream of 16-bit digital information that will get converted to sound.
Basic software to communicate over this interface was discussed in the earlier blog post. Now I needed to build a more useful sound effect or music synthesizer because just a sine wave alone is quite boring to listen to.
There are many things that can be done, and the approach I took was to implement the core of a music synthesizer. Music (or sound effects; the difference is not important in terms of the software that needs to be written to implement it) can be synthesized in different ways. One technique that was very popular in the 1980’s and 1990’s was FM synthesis. It was attractive to keyboard manufacturers such as Yamaha because it required very little RAM (which was expensive at that time), it could produce quite realistic instrument effects, and also it eliminated many of the disadvantages of analog synthesizers (analog synths required lots of set-up time, they were drifty in tone, and couldn’t easily be shrunk down to a single chip!). I got the chance to explore it briefly a while ago; some information is written here: Sound Synthesis and the Billion Dollar Paper
The technique uses the concept of operators that are assembled together to form a voice. An operator is an oscillator with two inputs; amplitude and frequency. A ‘voice’ is the particular combination or algorithm formed from multiple operators and input values that together create an instrument-like final sound. As an example, one of the most popular keyboards with FM synthesis was the Yamaha DX7. It had six operators and these could be assembled into one of 32 different combinations. By changing the input parameters to the combination, there were practically unlimited voice (instrument) possibilities.
For the Smart Doorbell, I implemented four operators, assembled into just one combination/algorithm. The algorithm can be easily changed if desired. More operators can be introduced if needed. They take up very little RAM, but they do consume processing power, so 4 seemed a good compromise for a proof-of-concept until the code can be optimised.
The diagram here shows what was implemented; this is not my diagram, it is from the original paper written by the inventor of FM Synthesis, John Chowning, called The Synthesis of Complex Audio Spectra by Means of Frequency Modulation. For this project I decided to replicate this diagram as closely as I could in the software.
The AND gate style of symbols are not actually AND gates, but represent an operator. There are four operators, called OPER_0..3 in the diagram. If there is a sine wave symbol then that operator is functioning to generate a sine wave output. There is also the possibility to set an operator to generate a different shape instead such as an envelope shape. The convention used is that the left side input represents an amplitude value, and the right side input is the desired frequency.
So, if the left side is set to the number 10, and the right side is set to the number 100, then the output of the operator will be a sine wave with frequency 100Hz and amplitude of 10. The triangle shape is used to sum outputs. In the diagram, the blue lines between the blocks are essentially like patches of wire but in software. It could also be built entirely in hardware if desired. By combining these blocks and setting the initial parameters (shown in blue text at the top of the diagram) then interesting sounds are formed. John Chowning suggested in his paper the particular values that would correspond to some typical musical instrument sounds such as the clarinet.
Turning the diagram into code was fairly straightforward, but is complicated by the fact that some accuracy is needed. The human ear is quite sensitive to errors. I made the mistake of using 16-bit arithmetic nearly everywhere in the code, but with hindsight I should have used 32-bits. Still, as a proof-of-concept it works.
This is the six-line code block I came up with that represents the diagram, and it is easy to follow how it maps to the diagram:
ug4=oper_run(OPER_0, instrument.amplitude, instrument.note_duration_reciprocal); ug5=oper_run(OPER_1, instrument.deviation2, instrument.note_duration_reciprocal); ug6=instrument.deviation1+ug5; ug1=oper_run(OPER_2, ug6, instrument.modulation_freq); ug2=instrument.carrier_freq+ug1; ug3=oper_run(OPER_3, ug4, ug2);
The oper_run function runs the oscillator just for one iteration or sample, so this code needs to run in a loop for as long as the musical note needs to play for. So, at 16,000 samples per second, the code block also needs to be executed 16,000 times per second.
The operators are initially set up to the conditions that are written at the top of the block diagram. The actual musical note that is played is contained in the ‘carrier freq’ parameter shown there. Once the note has been played fully, then that parameter is updated and then the operators are run again repeatedly until the next note has completed too. In this way an entire tune can be played. If multiple notes need to be played simultaneously (i.e. polyphonic synthesizer) then the code block needs to be executed for those notes too, and the output is summed.
Incidentally different combinations of operators, forming different algorithms, are what are printed on the top of many music keyboard synths from the 1980/1990's. They are a reference to any musician who wishes to choose an algorithm and provide custom parameters to invent their own instrument effects.
The code was implemented in C and with no additional libraries required, so that it is as portable as possible. As mentioned it is merely proof-of-concept code written in a few evenings and needs to be modified to use 32-bit maths for better quality. It also needs some optimisation and tidying up. The envelope shaping takes up most of the resources, because the code models the Attack/Decay/Sustain/Release shape using some floating point calculations. These should be eliminated because this code runs 16,000 times a second. In all other places in the code, simpler calculations are used. Some things are pre-calculated and look-up tables are used. For example, no sine wave is computed and instead there is a look-up table containing 1000 samples of a complete sine wave.
Although the design challenge entry uses dev-boards and custom hardware, the synthesizer code is completely portable so anyone can try it, even on a PC or a Raspberry Pi. It is attached in a to this blog post, the file is called synth.tar. To use it, type the following:
tar xvf synth.tar cd synth make ./synth
The last command will execute it and will generate a standard WAV file called out.wav that can be played with (say) aplay on Linux, or Windows Media Player. For the Smart Doorbell system, the same code is used except that instead of saving the digital audio stream to a file, it is instead sent over the I2S interface to a DAC board.
The ten weeks or so for this design challenge are flying by. I hope this project can complete. I definitely took a risk thinking that I could get up-to-speed with a new microcontroller and develop circuits and code for it during weekends and evenings, but it is what it is and let the chips : ) fall where they may. I’m still optimistic the PCBs and code can be worked on over the next nine days!
Hopefully the circuit boards should arrive later this week.