High Performance Sub 1GHz RF Project
This week, I’m building a high-performance sub-1GHz transceiver that I want to use as a standalone Internet of Things node using the ARM Cortex M3 microcontroller. As with my other projects, this project is open source and published on GitHub for you to use as the basis of your own design, or to use as-is. The RF schematic and layout are production proven, as are the microcontroller schematic and all footprints on the board. However, do keep in mind that this specific board has not been through volume production, so you should still perform your own validations. The radio is tuned for 433MHz operation, but you can change the balun and the matching network component values to those in the Texas Instruments app notes for either 868MHz or 915MHz operation if you desire a higher frequency.
I’m utilizing the Texas Instruments CC1125 transceiver in this design since I’ve used it in past projects and it’s proven to have incredible real world performance. With simple dipole antennas and no amplification stages, the CC1125 at 433MHz is capable of 25km line of sight operation, and with a yagi antenna instead, I have had reliable links out to 150km line of sight. In my projects, the transceiver has broken the sound barrier and been to the edge of space whilst performing flawlessly! On paper, the link budget and performance for a single chip transceiver IC offered by the CC1125 is hard to match from any other vendor.
By utilizing a transceiver such as the CC1125 in your design, you have complete control over the communication protocol which can allow more flexibility for specific applications than a general purpose standard protocol such as LoRAWAN, ZigBee or other popular options. Even though this approach requires more firmware development and testing time, its benefits when requiring absolute range with minimal power can be well worth the effort.
For the microcontroller, I’m using the NXP LPC1549 in a 48 pin QFN package. This is one of my favorite microcontrollers as it has a relatively unique IO configuration. The core and package separate, so almost all hardware peripherals are able to be mapped to any physical pin with the exception of I2C, USB, DAC and the single wire debug pins. For a generic IoT node such as this project, the NXP LPC1549 allows me to break out 4 of the GPIO/ADC pins to a terminal block which can be utilized as a multi-purpose input/output if required. One of the USART ports could be mapped to those pins giving UART or SPI access, or timers for either input or output. When you need to have a flexible microcontroller, there aren’t many options other than the Cypress PSoC line that approach the configurability of the LPC1549.
This is also my first project in the Altium Designer 20 open beta, so I’m really looking forward to trying out some of the neat new features!
In order to have the highest performance link possible, this project needs to step out of the realms of pre-certified modules and into intentional radiator territory. This project has not been through RF certification, or even pre-certification, with any laboratory. As such, the schematic has an abundance of ferrites on the board to reduce the chances of radiated emissions in any cables connected to the board, as well as to reduce the chance of outside interference.
Should you utilize the design for your own project, you will need to certify the product prior to sale as an intentional radiator, rather than an unintentional radiator. This can be expensive, at US$12,000-$20,000 but brings with it extreme RF range, incredible performance, and complete control over your protocol and antenna options.
Starting the Design
I’m going to start out the schematic capture with the RF module, as it’s the most complicated part of the project. I always set up the schematic symbols for ICs to use the left side for power, decoupling and other such pins, and the right side for the ‘user’ functionality. After that, we need to add some passives to our schematic. First, we add a decoupling capacitor for every power supply pin, and then add the other decoupling capacitors the transceiver requires.
The reset pin is connected to the microcontroller via a pull-up resistor to allow the microcontroller to reset the transceiver if something goes awry. I haven’t had to use this functionality before, but it’s always nice to have peace of mind that your microcontroller can reset the transceiver if it feels that it needs to.
The CC1125 and its power connections
Next, I fill out the non-RF components and connections on the right side. The SPI port gets connections for the microcontroller, and we add a 32MHz oscillator. The microcontroller could provide a clock signal instead, but given that we’re after absolute performance, the best option is a high-precision crystal. This could be taken a step further with the implementation of a Temperature Compensated Crystal Oscillator (TCXO) or a Voltage Compensated/Temperature Compensated Crystal Oscillator (VCTCXO). The CC1125 handles the 20ppm frequency stability and tolerance of the ABM8G series just fine as it performs tracking on the signal it is receiving. Furthermore, a good pre-amble in the protocol allows the transceiver to account for frequency drift, even from doppler frequency shift of supersonic travel relative to the linked transceiver.
It now has RF connections as well
As in my previous project, when working without a database library, I like to add generic symbols to the sheet that I can quickly shift-drag to clone for laying out the schematic. Before starting the RF network, I add an inductor, capacitor, and resistor with an RF optimized footprint (similar to IPC High Density) to my sheet so I can quickly clone them and then apply the component parameters for each individual part from the Manufacturer Part Search panel.
Three shift-draggable passives save a lot of time
At this point, I lay out the BALUN and the matching network for the design, while simultaneously looking at DigiKey for each component in the network. I prefer to use DigiKey simply because I’ve used their search for so many years I know how to find exactly what I’m looking for in the least amount of time.
Find the Right Capacitor
For the RF capacitors in this project, we don’t want to just use any old general purpose or decoupling capacitor. While the design is only going to operate at 433MHz, which it’s not as critical as multi-gigahertz designs, we are working with an incredibly sensitive receiver and trying to get every last bit of performance from it. The RF capacitors are more expensive than the regular ones, however, we’re using so few of them in the design that it won’t increase the total BOM cost by a large percentage.
On DigiKey I filter by RF in the Applications attribute. This gives me high Q, low-loss capacitors to look at.
If this design was of higher frequency, I’d be going through the datasheets for each option to find an optimal solution—for this project though, simply having an RF specific capacitor and ensuring it is high Q, low loss in its features is sufficient.
Find The Right Inductor
It’s now time to find the inductors on Digi-Key. I’m looking for wire-wound inductors specifically because these will have a higher Q, and therefore higher performance. I’ll filter for wire-wound in addition to my normal filters (in stock, cut tape, active, 0402.)
This design is intended to be an optimal performance one, so I further filter by Q @ Freq. before selecting specific part numbers to assign to the components in the schematic. First, I’ll sort by price @ 100 qty (to give a more realistic price sort) and then look down the Q @ Freq column to get an idea for where I might get a slightly higher value than the cheapest. In my search, most results are 20 to 25, however, without much additional expense, there is a 30 @ 250MHz option, so I’m going to set my minimum filter to 30 @ 250MHz for Q @ Freq. Now, I can filter for the actual value of the inductor I require and, before confirming the cheapest well-stocked option as the part I will use, I have another look down the Q column to see if there is anything a little better without much additional cost. For some of the higher inductance parts, the highest available Q on DigiKey is 25, so I have to drop my filter down to that when necessary.
For each of the inductors in the design, there is just one of each value, except for the 15nH and 27nH inductors of which there are two. The low quantities allow us to sometimes slightly improve performance at very little additional cost. As an example, at a quantity of 100 components, the 27nH inductor is available for $0.1484 for the 5% tolerance option, or $0.1518 for the 2% tolerance option. Both have a Q of 30 @ 250Mhz, so it’s a no brainer to spend the extra fraction of a cent for the 2% option on this low-volume part.
The higher-end inductors available at DigiKey that meet my requirements are typically going to be from the Murata LGW15 series, which DigiKey doesn’t always stock well. Typically, when designing a board I’d prefer to see a couple of reel quantities in stock, but with some of these components—such as the 15nH inductor—there are fewer than 200 units in stock. Mouser typically has higher quantities of stock, so a quick check on Octopart is always worth the time if I’m worried about how well-stocked these might be globally prior to committing to the design.
Back to the schematic, I have both the balun and the impedance matching networks captured. The component values are based on past designs that have been simulated and production-proven. Texas Instruments have app notes which include the recommended networks and component values for 868MHz and 915MHz operation, which make an excellent starting point for designs at those frequencies.
Tuning the balun network connected to the LNA inputs and the impedance matching network connected to the antenna is very critical for high performance
The balun converts our unbalanced network connected to the antenna into the balanced network, which the transceiver requires for it’s LNA inputs. The matching network provides impedance matching for the transceiver and antenna. These are both critical to ensuring optimal receive sensitivity and maximum transfer of electromagnetic energy both into and out of the device.
At this point, I could just go ahead and place our antenna connector after the 22nH inductor, but I want to add a low-pass filter here instead. The CC1125 has good rejection of unwanted noise, but the many times I have used the CC1125, nearby powerful transmitters on other frequencies could still swamp the transceiver. The modern world is already full of cellular and WiFi signals, nevermind intentionally placing another transmitter in close proximity to the transceiver. So in my mind, the tradeoff of the input loss on the filter versus dealing with potential interference is worth it.
A low pass and an antenna, and now we have a fully functional transceiver
I’m using a Mini Circuits LFCN-490+ which has a very low loss for a relatively high rejection of anything over 490MHz. The filter does have an orientation, which should be taken into account whether the device will be mostly transmitting or mostly receiving. However, in reality, I haven’t noticed much difference in performance between orientations.
Given the current state of the design, it’s going to be difficult to tell Altium that I want all of these traces to have an impedance of 50 ohms. I’m going to add a directive for each wire in the network, which will apply the Net Class ‘RF’. This will give me something to reference in the design rule on the PCB.
For human readers, I’m also changing the width and color of the wires to clearly identify them as RF nets.
This little optimization takes no time and makes the schematic more legible
With the transceiver schematic complete, it’s time to move onto the microcontroller. Again, I start with the left side of the microcontroller symbol to supply power. The LPC1549 is perfectly happy with far less decoupling and filtering than I’m providing here, however, as this is an RF product I want to ensure the microcontroller has clean power and won’t have any opportunities to be disturbed by (or radiate) electromagnetic energy.
This is also an IoT node that might be reading or outputting analog signals, so I’m going to separate the analog supply from the digital supply with another ferrite and a larger capacitor to ensure the analog performance is as optimal as possible.
I’m also going to supply a 12MHz clock signal from another ABM8G series oscillator. The microcontroller has an internal oscillator but it’s not particularly accurate when compared to the external crystal. The design needs to have excellent frequency stability on the microcontroller to ensure any protocol implemented in the firmware has tight timings, allowing frequency hopping schemes to be reliably implemented.
The NXP LPC1549 microcontroller with power and xtal pins connected on the left side
As mentioned above, this microcontroller is pretty special in that I don’t need to pay too much attention to what connects where. This article is being written as I go through the design, so I consider my connections for the microcontroller below to be a first pass as to where connections will be. This microcontroller allows easy routing of the circuit board, as the connections can be rearranged to meet the incoming traces in the cleanest way possible. That means the screenshot below is likely to be very out of date by the time routing is complete.
Specific pins on the right side are irrelevant to the proper functioning of the microcontroller, and will be changed during the routing process
The ISP pins are both pulled up with 10k resistors, which will make the on-chip programmer start up as a USB flash drive if it has no firmware, otherwise, it will boot up the programmed firmware. On a development board, it’s convenient to connect those pins to buttons, along with the reset button, to allow you to always start the microcontroller up as a USB flash drive to save the need for a JTAG to put new firmware on the board. During production, however, the configuration in the schematic makes a lot of sense, as it allows the firmware to be installed without anything more than a computer and a USB cable. There’s a 10 pin (5x2, 1.27mm pitch) SWD connector provided on the board for connecting to a JTAG if required.
I want the device to be capable of being powered over USB cable during development or onsite debugging, but typically be powered by a terminal block power connector. Therefore, I’m using a simple diode to separate the power connections, so that in the event that both are connected simultaneously, the computer which the device is connected to via USB will be protected. The microcontroller will use the USB_VBUS_I connection to determine if there is a USB cable present.
The USB cable also has ESD protection in the form of an ESD protection diode that is specifically designed for USB interfaces. This cheap diode could save the microcontroller from an ESD event as the USB port is connected or touched.
USB micro connection with ESD protection featuring the PRTR5V0U2X diode
To provide connectivity to sensors and power, I’m using pluggable terminal blocks. Despite their cost, I absolutely love this style of connector for devices such as this. You can prepare cable harnesses that can be plugged into your device without the need for crimping tools, and a field engineer can connect whatever sensor the customer might need with just a screwdriver. Because they are pluggable, you can easily swap out the device or sensor should you need to, or prepare the cable harness and device separately. They give you the best of both worlds when it comes to terminal blocks and pluggable connectors!
Keeping the field service engineer and customer in mind, I’m using an 8 pin connector for the 4 main inputs. This allows each input to have a matching ground pin. When connecting sensors that you don’t know about at product design time, it is much easier for the end user to provide the ground reference and signal together. If we knew exactly what was going to be plugged into the header, it might have made more sense to just have one common ground and perhaps even a single power pin on the port, but in our case, we don’t know at design time what could be connected. Remember that the microcontroller is very flexible for pinning, so you could potentially also connect an SPI device to this header.
The user terminals are going to use pluggable terminal blocks with separate ground connections provided
We also have an output for the digital-to-analog converter, because that could be useful. Finally, a UART interface is exposed, as we don’t know what type of sensor might be required for data collection or integration.
I did mention earlier in the article that I was going to go a little crazy with ferrites. Connecting user supplied cables to an RF device is a really great way to fail an RF certification. Not to mention, the certification process requires all possible cables to be connected! Therefore, I’m adding ferrites to every connection. They shouldn’t interfere with any signal under 1MHz in any meaningful way but will mitigate errant EMI on these connections.
When it comes to low frequency signals, you can never have too many ferrite beads
The final connection is that of the power pin. I’m using two relatively expensive voltage regulator ICs that provide a lot of protection, including protection against reversing input polarity, so I don’t need to provide anything more than a ferrite bead or pi filter on the input. However, if you wanted to save some money on this design, switching out the voltage regulators will likely be the first step. In this case, you can add reverse polarity protection as shown below, using a P-Channel MOSFET. Typically, you would use an N-Channel MOSFET for such protection due to their lower RDS-ON, but we have multiple grounds exposed to the end-user, which could create a path for a reverse polarized connection to cause damage. Therefore, we isolate the high side of the input connection with a P-Channel MOSFET. This is much more efficient than using a standard diode.
Now that the schematic reached a point at which layout can begin, I annotate the schematic to give every component a designator and get started on the board layout. As this is an impedance controlled board, the first stop is going to be the layer stack manager.
I’m setting up the layer stack to match the 4 layer stack from JLC PCB, an extremely low cost Chinese circuit board manufacturer that offers impedance control as a standard option.
We can get the 4 layer stack board parameters from JLC PCB - these could vary for you depending on the manufacturer you choose
Once my layer stack is created, I can use the Impedance tab at the bottom to open the impedance control side bar. I’m creating an impedance profile for the 50 ohm RF connection, as well as that for the 90 ohm USB differential pair.
The 50 ohm RF connection impedance profile, S50
Both of these impedance profiles will then be used in design rules to set the trace width for the net classes associated with them.
The 90 ohm USB connection impedance profile, D90
Before transferring the components to the board, I compile the project to check for errors. Normally, nothing comes up, but this time the check has caught a couple of things.
I completely forgot to add the LEDs for link and status indicators I had intended to have on the board. Altium caught the nets having only one pin, which is a fantastic ‘reminder’ to add those components! It also caught a problem with 3 capacitors for which the wire was not quite touching the component after I changed grid settings.
After fixing those issues, I successfully executed the engineering change order to add all my components to the board!
All the components are placed off board, however, they aren’t arranged as we’d like them to, and we’ll get to that later
As always at this point, I shift my designators off to my ‘Designators’ mechanical layer by using the PCB Filter: IsDesignator AND OnLayer('Top Overlay')
Then change the properties of the selected items to be on the other layer, centered, and with TrueType font.
Before I move any components, I want to get my impedance and differential pair rules set so I don’t forget.
Opening the design rules window, I can add a routing width rule for the RF impedance. Because I previously set the net class with the directive in the schematic, and the impedance profile in the board stack, creating the rule is as simple as selecting the RF net class and checking the box to use the impedance profile.
The impedance profiles S50 and D90 we created earlier come in handy now
Next, I add the Differential Pairs Routing rule for the USB connection. When creating the schematic, I added the diff pair annotation to the USB data lines, so they show up on the rule automatically, as does the impedance profile I created when building the layer stack. This is one area of Altium that has improved greatly in recent versions, with the setup of impedance matching being much simpler and better defined than it ever has in past versions—at least in my opinion!
Now that the board is configured, I can finally start moving components around. I like to start out by grouping components together into what I consider logical groups. Components that would go together on the board—such as all the parts for a voltage regulator—fall into their respective groups, and so do connectors and their passives, and any ICs and passives that would be placed right next to them.
Altium Designer’s cross select tool, and ‘Arrange components within area’ tools make this a breeze. You can access the ‘Arrange components within area’ tool from the main menu, but I find it faster to access from the Utilities toolbar.
Arranging our components in logical blocks before we place them on the board
Very quickly, the board starts to look a little more logical than the giant mass of components I had after the engineering change order to add the components to the board was executed.
I try to lay out each block of components off board, in a way that would be most comfortable to process later. By doing this layout in isolation, I can work on optimizing the component arrangement to best support clean routing and good electrical practices without worrying about how much space I have to work with.
We can now look inside each block in isolation and arrange them in a way that would provide the best routing experience
Once all of the components groups are laid out, I start trying to fit everything together like a jigsaw puzzle on the board. I knew from the start that I wanted to have the connectors down one side of the board, which would make this a long narrow design. Coincidentally, this works well with the relatively long train of passive components for the RF network.
When all the connectors are lined up, the board needs to be around 70mm long and the maximum width of the layed out components with room to route around them gives me a board 32mm wide. I could likely shave as much as 10mm off this width if I wanted to, but we’re not aiming for an ultra compact design. In the past, I have laid out a very similar schematic to this in just 36mm x 22mm using a 6 layer board with blind vias, and obviously without the large terminal blocks. You can achieve a very compact solution with this design if you need to.
Originally, I wanted to have the microcontroller at the top with the USB jack on the end of the board, but this didn’t look very efficient to route. The layout below fits well as a first pass design, which can be optimized as the routing progresses. The power supplies are well separated so any heat from the linear regulators will be spread out sufficiently, and there is plenty of copper pour area around them for sinking heat.
I also have my fiducials placed as closely as possible to the two main ICs to aid in machine vision. These will be local fiducials which the pick and place machine can check prior to placing the ICs, to ensure nothing has moved during placement. There are no global board-level fiducials, as typically I would have these on the panel to move them off the board. I like to add the fiducials early on, as it can be quite a challenge to fit them in if after routing if you forget them.
The board with all the components placed
In 3D view, it doesn’t look as though any component will be hard to assemble from being blocked by tall components around it. The terminal blocks would be placed last after SMT assembly so they don’t influence the ease of assembly.
Everything looks easy to assemble, now it’s time to move on to routing
I’m excited to try out some of the new routing features in Altium Designer 20. The new “any angle” interactive routing looks fantastic for BGA and HDI work, but it’s also going to be fantastic for RF layouts where you want smooth flowing traces without any hard edges or corners for RF to emit from. The first tracks I routed were the RF network, just so I could try it out!
Any angle interactive routing offers a very satisfying experience
For my first attempt using the tool, it seemed very intuitive, and certainly far easier than previous designs I have routed(which took a lot more segments to achieve the same end result). The main thing I learned using this tool is that you need to just let it do it’s thing – if you try to over-manage the trace by routing short segments as you would have needed to in previous versions, it can struggle to give you a nice looking trace. If you just take the trace where you want it without locking anything in along the way, you end up with a very smooth and efficient track.
For the RF section, I have a polygon pour on layer 3 for the voltage supply to the IC, layer 2 is a ground plane, and layer 4 will also have a ground polygon, so I’m trying to avoid using it as much as possible. As we are going for a high performance design that needs to be compliant with regulations, I like to overdo my ground and power connections. Every ground pin or pad gets its own via to the ground plane to ensure a low impedance return path. Every supply pin is also getting its own via, and will have a matching via at the voltage regulator.
There will be a ground pour on the top layer as well.
The microcontroller after it has been routed
I routed the microcontroller in a similar fashion, but did not need the power polygon on the 3rd layer as the VDD and VDDA pins are grouped fairly close together. The top of the board ended up being mostly fan out of the components and power distribution, with the majority of the connectivity between the transceiver and microcontroller being on the bottom layer.
The top layer (red)
Any angle interactive differential pair routing on the USB data lines was very satisfying to route. I love the way the two traces flow together from the vias and around corners. This makes me want to work on a high speed design just to play with the new routing more!
Pushing traces around on the bottom of the board to get them nicely grouped together is a definite improvement over AD19 with far less ‘creative’ artifacts generated. The new routing engine performed quite well on this relatively simple board.
There are a couple of artifacts around the USB connector showing unrouted nets, however, this was from a bug that is already fixed for the next release version of the beta. Ah, the joys of beta testing!
The bottom layer (blue)
This brings us to an electrically complete board, but not a finished one. The board is looking a bit bare at the moment, and we have no indication as to which connectors do what.
The electrically complete bare-looking board
The top side of the board doesn’t have a lot of room to add labels, so I’m simply going to add a little tag at the corner of each connector block to identify it from the top. The majority of the silkscreen work will be on the bottom of the board. I feel the little tags make the board look a lot more complete. A logo or product name would go very nicely between the ADC connector block and the RF transceiver, and a revision number or such would probably fit quite nicely between the mounting hole and the transceiver to finish the board off. However, as we don’t have a product name for this project, I’ll leave those out.
Looks a bit nicer with tags added to terminal blocks
The bottom of the board gets my usual boxes for someone to initial that they have completed the QC of the board, as well as the dates the board was manufactured and installed. I like to keep track of this on the circuit board as it makes it a little easier to figure out how long a board has been in use when an issue arises on a customer site. This can allow better failure tracking to determine if there is an issue related to a component’s mean life expectancy between failures, which may need to be addressed in a future revision.
The space between these blocks and the labeling for the terminal blocks could have a printed serial number/barcode added for further product tracking, as well as provide somewhere to place certification marks.
I have to admit, of all the enhancements in Altium Designer 20, the one I was most excited about was text justification. It might seem like a small thing, but when labeling pins like this, the vertical-center justification was really nice. I found that I could get much better positioning of the text blocks on this board than I have been able to in the past. I found that I could set the horizontal and vertical justification of the text blocks to where I needed the drag handle to be, and then change the justification back to where I wanted the text to sit within the block. By changing the justification in this way, I was able to precisely position the text block and then have the justification as I wanted it. Changing the justification of the text does not move the text block itself, unlike in some other software. This is a great thing for layout work!
The bottom layer of the board after the silkscreen has been added
Finishing Off The Product
A board designed to be installed at a customer’s premises should really have an enclosure to protect it from ESD, debris, and make it look finished. While I don’t mind designing enclosures in mechanical CAD software, I prefer to leave it to those with more experience. I put up a job post on the freelancing site Upwork to see if I could find someone to design an enclosure that I could 3D print for low volume, but still take a potential higher volume injection mould into consideration. This allows the design to stay the same even once the design exceeds low volume prototypes, which makes the certification cost worth while.
I felt quite lucky to find a Danish freelancer who had only recently signed up to the site willing to complete my project at a low cost to get his first project review. After sending him the STEP and Parasolid exports from Altium, I had a very stylish enclosure ready to go in just a couple of days! I really admire the design styles of the Danes and other Nordic countries.
3D render of the finished board within its newly designed enclosure
Using This Design
This design is released as open source on GitHub. You can download the project yourself and do what you want with it. If you want to use the design as is, go for it! The schematics are production-proven, so you can feel free to use blocks of the schematic for your own projects.
Firmware development on the LPC1549 is painless with either the LPCOpen libraries or using MBED.