Sunday, April 24, 2016

Routing High Speed Signals and USB

Eventually in most hobbyists' path, one will end up working with high speed signals. These days so many microcontrollers support USB and even ones that don't can use software USB. Of course using a microcontroller is the answer to every engineering problem, right? Most of us just work with USB 2.0 connected directly to a microcontroller for uploading and serial communications. With advent of the USB Tester, I have learned more about USB than I ever thought I would. Recently I have dived into USB 3. Which compared to 2.0, is so much more sensitive to your PCB routing as I found through trial and error. I have seen many projects on the various blogs and for sale on the usual sites that don't follow or even try to route correctly. With USB 2.0 for the most part you can get away with it and it will still work. To help save you some time, I would like to share my findings that should help prevent PCB re-spins just due to USB not working. This is by no means an exhaustive guide to high speed routing as there are plenty of application notes across the web for that. I will list a few at the end of this post that I found helpful.

I am not by any means an expert on high speed signals, but I have learned enough to get the job done. In the end I was fortunate that my desktop PC had the first USB 3 controller made by Renasas which is much more sensitive than my laptop so I knew if it worked it would work for anyone. 

Diagram of USB Differential Pair (Wikipedia)

High speed signals use differential pairs instead of a single trace or a clock / data pair like I2C. By using a pair of traces you can cancel out noise. One is positive and the other negative. The idea is that electromagnetic interference would affect both signals and therefore would be canceled out since the receiving end looks at the difference of the two. Using a 2 channel oscilloscope you can connect to both signal and do a bit of math to see the resulting signal.

With USB 2.0 I was able to get away with branching (breaking out D+/D-). These are terms that you will come across with working with high speed signals. 
  • Branching is when the traces are not direct from one point to another and have a split.
  • Stubs is if the signal hits a via with a pin in it from the top layer instead of the bottom layer to from a straight path. 
USB 2.0 only uses 1 differential pair vs USB 3 which uses 2 for full duplex operation. If you are using the Type-C connector you have duplicates of each pair plus for reversibility and extra signals for detecting orientation and other signal types.

USB Type-C Pin Out (Credit someone on the internet)

Important things to consider while laying out your board. 
  • Calculate trace width and spacing to maintain 90Ohm differential (Calculator) This will also depend on the PCB you will be using. In my case OSHPark lists the specs of their PCB.
  • Maintain trace length of each pair. CAD tools have a differential pair routing tool along with meander to adjust traces for matching. A better way is to add a little length on the end of the short trace before connecting to your pad instead of having to meander which will affect the 90Ohm differential target. It can take a bit of time though to get it just right.
  • Use as few vias as possible as they affect signal integrity.
  • Route using 45degree angles instead of 90. I think this is to avoid reflections. 
  • Avoid stubs by using a via before routing to a through hole part so you are on the bottom layer. 
  • As much as possible, route above/below a continuous ground plane. On 2 layers boards this is pretty much impossible. With USB 3 it really should be a 4+ layer board. 
  • Signals should be on the outer layers. 
  • As always use the shortest path possible. (The Wozinack way ;))
  • Another one that may be hard to do is don't cross signals above or below another signal. Ideally there should be a ground plane there anyway. 
  • One way to avoid inverted pairs having to cross over each other is to mirror a part but then you have to deal with parts on both sides which may or may not be an issue for you. You should check with your assembly house if going that route. I have been able to reflow boards twice in this case. Surface tension usually keeps parts them from falling off. 
  • Remember that higher speed signals travel along the skin of the copper so surface area is your friend and reduces impedance and attenuation on the signal. (More info)
  • Type-C cable only has 1 pair of differential pairs for USB 2.0 on the A side of the connector. B is unconnected. So I believe that means you should tie A and B together or maybe there is a mux IC for USB 2.0.

USB 3 Differential Pairs Example

It seems a lot to take in for a hobbyist but after awhile it starts to make sense. PCBs are getting cheaper so if it doesn't work out you can keep trying different designs until it works. 

Here is my settings in Eagle CAD for a 2 layer board from OSHPark pictured above.

Eagle CAD Differential Trace Settings

Eagle CAD Length Settings

There is a minimum error in length but I always try to get it 100% matched.

Links I found during my research: (PDF) (Good one with cable wiring) (PDF) (PDF) (PDF) (Skin Effect) (Links to calc) (Calculator)

Monday, March 21, 2016

Quest for a Logic Analzyer

Since I started this adventure in hardware I have wanted to get an logic analyzer. I have an older but good oscilloscope that only goes so far when it comes to digital logic signals. I could go for the Saleae, but if I am going to do that I would rather sprint for the higher end model which is an easy $400+. In the mean time I was on a quest to find a low cost option. Upon my travels of the interwebs I found a few options. There's Dangerous Prototype's bus pirate (which I have) or their openbench logic. There are also the microcontroller options using, say, a Teensy or STM32. Then when I came across the BeagleLogic, it seemed like it fit what I had in mind. And actually, if I remember correctly, I saw it during the Hackaday Prize 2015. Funny how you end up somewhere on the Internet you've been before but have long forgotten.

The BeagleLogic is a logic analyzer based on the Beaglebone created by Kumar Abhishek, a semi-finalist of the Hackaday Prize Best Product 2015. What makes the BeagleLogic special is it uses the BeagleBone PRUs which are basically 200Mhz microcontrollers attached to the ARM CPU with shared memory. This is one thing that sets the BeagleBone apart from other SBCs. I have always been interested in the PRUs but they are a bit complicated and I've yet to have the time to investigate. I wish Ti would make an easy way to use them like Arduino did for microcontrollers. For me it's more of the lack of time to learn them when I have so much going on with other projects.


  • 100MSPS
  • 14 Channels (13,14 require you to disable eMMC)
  • 320MB Capture Buffer
  • 5V tolerant inputs
  • Web Interface
  • Capture interfaces from the BeagleBone itself
  • Opensource 

At the moment, you have to make your own BeagleLogic. There isn't a place to order it. In addition, you need your own Beaglebone. Hardware wise, all it provides is the ability to probe up to 5V. since the BeagleBone ADCs only accept 1.8V signals. The BeagleLogic is fairly simple to make with the help of OSHPark. With a bit of drag soldering it would be easy to hand solder as well. I opted to order a stencil from OSHStencils and use my re-flow oven just to make it look nice and professional.

OSHPark Shared Project: (Just click order now)

Bill of Materials:

  • You don't need the EEPROM parts anymore but the footprints are on the PCB if needed.
  • The transistor BSS138 was out of stock on Digikey so I ordered samples from Fairchild. 
  • I did have some issues with the cape affecting the power on boot process. It's okay during a reset though. So you can't attach it till after you power up. 
Software is where the magic happens. There is a pre-made image for the BeagleBone with everything loaded and configured to use the BeagleLogic. It's a recent image based on Debian instead of the older Armstrong builds. The nice thing is that it doesn't flash the eMMC so you can leave your existing setup alone and just pop in the SD card when you need your logic analyzer. Which is another reason that makes it a good option. I can still use the BeagleBone hardware for other projects and not keep it collecting dust in between uses.

BeagleLogic is setup to be used in two ways. One is the web based interface. Just power it up and fire up your web browser. You can use the USB NIC which will put the BeagleBone at or plug in the on-board Ethernet or even use WiFi with a USB dongle. Plenty of options for connecting to it.

There aren't many options in the web interface but it's a great start to be expanded. In my case I couldn't get the "Dump Raw Data" option to work, unless it saves to the BeagleBone and it's not downloaded via the browser which is what I was expecting. If you have a I2C bus that only talks a few times a second, it can be challenging to find the data just by scrolling. There is software triggering but you can't use it via the web interface. You can by means of the command line, which is the second way to capture your data.

The command line tools are provided by the Sigrok software suite. The output file can be exported to the desktop app, PulseView to do protocol decoding.

First you have to capture from the command line and specify how you want to trigger, which channels and the sample rate / sample limit.

debian@beaglebone:~$ sigrok-cli -d beaglelogic -c samplerate=5m -o -C P8_45,P8_46 --samples=10000 -t P8_45=e,P8_45=e

Using WinSCP on Windows you can copy the output file to your desktop and open it with PulseView. The PulseView binary for various operating systems are available.

From this point, select the protocol using the last icon on the toolbar. Finally just click the protocol tab to configure it. (This took a bit to figure out.) Select the pins that map to clock and data in this case.

If you need to, look at timing use the cursors tool.

The BeagleLogic is a great inexpensive logic analyzer especially if you have a BeagleBone laying around collecting dust as I did. (It was supposed to eventually be for a robot project but now I want to use the new BeagleBone Blue.) The BeagleLogic has a lot of potential to be a full feature tool. One big thing that is missing is the ability to connect to it directly form the host without having to copy a file each time. I haven't tried running PulseView directly on the BeagleBone then using VNC to connect. Even as is, it's a useful tool and a good place to start if you have never used a logic analyzer. Be sure to visit Kumar's blog There is a lot of good info - especially on PRUs. I had actually came across it researching some STM32 SDIO stuff earlier this year.

Due to the nature of OSHPark, I have two extra fully assembled. If anyone is interested in them please send me an email. william at blog domain.

Here are some other links with more info on BeagleLogic and Sigrok.

Correction: The BeagleLogic doesn't need the ADC's but the BeagleBone GPIO's are only 3.3V

Sunday, December 20, 2015

openHAB Last Sensor Update

A few of the sensor nodes are battery powered so it is important to know if they have stopped transmitting. My previous system (which is still feeding openHAB) tracks last seen time stamp. In openHAB you have to set an item and a rule to handle that. This is one of the items at the bottom of this post that is required to remove my reliance on DomotiGa.

All this requires is one item to store the time stamp and a rule to update it whenever the sensor item receives a change. The only catch in my case is if the new value is the same as the current, it seems it is not triggered as an update. I am not sure if it is DomotiGa not sending or openHAB not triggering. So during the night I don't get as many updates. It's fine for now because when I setup a JeeNode to MQTT bridge, I can have that trigger the time stamp regardless if there is a sensor value change.

DateTime        office_lastupdate       "Last Update [%1$tm.%1$td.%1$tY %1$tr]" 

You can use this site to help you format the datetime to suit your needs.

rule "Last Update Office"
        Item office_lightlevel received update or
        Item office_temp received update or
        Item window_office received update
        office_lastupdate.postUpdate(new DateTimeType())

 Text item=office_lastupdate valuecolor=[office_lastupdate>300="red",>240="purple",>120="orange",>0="green",<0 data-blogger-escaped-code="" data-blogger-escaped-red="">

Using the value color option you can quickly at a glance look at the time since update based on the color. Just adjust the values in seconds.


openHAB Proximity Update

Just a quick update to the proximity tracking. The original post was just using Bluetooth which tends to not be completely reliable. So we need a backup such as WiFi. OpenHAB has a binding that can check for network devices. Between this and the device scan script for BT, we are set.

Just need to add an item for each device you want to track on the network. This can be used to see if a laptop is on or even check to make sure a sensor or something it alive.

Install the NetworkHealth binding - sudo apt-get install openhab-addon-binding-networkhealth

There isn't much in openhab.cfg to figure. I just setup the cache period to 60. Just restart openHAB if you make a change and load it to the new binding.

Switch  wifi_Will               "Will Wifi"            (gNetwork)      {nh="Note5"}
Switch  wifi_Jenn               "Jenn Wifi"            (gNetwork)      {nh="Jenn-iPhone"}

The devices in the items config can be an IP address or host name. Using the hostname allows you to not have to set a static IP or reservation in DHCP. I already had reservations so these host names are set in the router. It looks like in iOS you can't change the host name but setting it in my router allowed me to control it. Android uses the device name you set in settings.

 Group item=gNetwork icon="present"

I put both devices in a group and just used that to add it to the sitemap. Then you can easily add more devices to track.

Then just update the occupied rule to take the other items into account.

rule "Update Presence to home"
        Item wifi_Will changed from OFF to ON or
        Item wifi_Jenn changed from OFF to ON or
        Item device_WillPhone changed from OFF to ON or
        Item device_WillPhone changed from OFF to ON

rule "Update Presence to away"
        Item wifi_Will changed from ON to OFF or
        Item wifi_Jenn changed from ON to OFF or
        Item device_WillPhone changed from ON to OFF or
        Item device_WillPhone changed from ON to OFF
        if(wifi_Will.state==OFF && wifi_Jenn.state==OFF && device_WillPhone.state==OFF && device_JennPhone.state==OFF){


There is a bug in the rule though, the occuipedState isn't quite working. Everyone leaves and it's still on. So I will need to troubleshoot that a bit more. (Hmm... I noticed I am using postUpdate vs sendCommand...)


openHAB and Fireplace Rules Part 5

Now that everything is humming along we can make some fancy rules. This includes creating a flexible timer and auto mode based on room temperature. I went through a lot of iterations but ended up with some nice rules that work well. I will post the current version here but any updates will be maintained on Github.

Monday, December 14, 2015

openHAB the Fireplace and Rules Part 4

If you haven't read part 1, part 2, and part 3. Start there and I will wait for you here. Welcome back! Now we get to do all of the fun stuff now that we have software control of the fireplace. We can have some real fun adding features. The original remote does have a set point and scheduling options but we never used that and of course you couldn't trigger remotely or based on other triggers. The features I had in mind are listed below.
  • On/Off
  • Keep original remote functionality
  • Timer
  • Temperature set point
  • Remote turn on/auto when temp is under a certain value and we are coming home
    • This would be instead of setting up scheduling
Part of this comes from that fact that the fireplace heats better than the wall heater we have at least for that part of the apartment, which we spend a lot of time in. The hardest part was getting openHAB control vs the physical remote to play nicely together. Finally the solution was to abstract the openHAB web input versus the remote. This uses four switch items.

Switch  tempFire_Switch "Fireplace Manual"        (gHeating)      {zwave="4:command=SWITCH_BINARY"}
Switch  tempFire_Web    "Fireplace"       (gHeating,gLeave)
Number  tempFire_ADC    "Fireplace ADC [%d]"      (gHeating)      {zwave="4:command=SENSOR_MULTILEVEL"}
Switch  tempFire_Remote "Fireplace Remote [%s]"   (gHeating)

The first one, tempFire_Switch is the one that controls the relay and therefore the fireplace directly. This one will not be in the sitemap and only controlled via rules. The tempFire_Web is the input from a user using openHAB and tempFire_Remote is the physical remote. The tempFire_ADC number item is the input from the ADC relay that lets us update the remote status without interfering with the actual fireplace.

openHAB the Fireplace and Wiring Part 3

Now that the relay works we can do the final wiring. Read part 1 and part 2 to see how we got here. It's been a rabbit hole for sure, but don't fret, we are on our way out!  Compared to everything else, the wiring is the easiest part. The fireplace uses a simple switch to control it as it is a millivolt system which generates its own power (from the heat of the pilot) to trigger the gas valve. Ripe for hacking. In the end for safety (and for long term vacancies), I decided to wire the local override switch as a hard disable. That way if we are gone for the weekend or during the Summer months, I can disable it. Just in case there is a network glitch or something the fireplace can't turn on even if the relay does. Turns out this is also useful during testing of the rules so the fireplace isn't turning on and off consistently.

Basically the connections are one side of the fireplace switch connection goes parallel with the side switch then to the relay negative. Then the positive of the relay is direct to the fireplace. Then the original receiver is wired to the relay ADC input.

Simple. I used some electrical tape just so I can easily remove it, this being an apartment and all. Now we can close oFf the fireplace and play with openHAB.

Monday, December 7, 2015

openHAB and our Fireplace Part 2 and OpenZWave

Finally, the MimoLite replay has arrived. Even though it was Amazon Prime, it look about five days to land in my eager hands. At least it was free shipping! In Part 1 we looked at a solution to control the fireplace via our openHAB network. Now the fun part of actually installing it. I set aside an evening after work for the installation. Of course when projects seem simple, they end up taking a lot longer.

MimoLite Relay