Archive | January, 2019

General PCB design tips

07 Jan19

General PCB design tips

When I made my first PCBs, I had no idea what I was doing. I played around with Fritzing and looking back on those designs, it's a wonder that some of them worked at all. I now make many designs per year and most of my income is from creating electronics and writing the accompanying software for customers. This post sums up all those tiny things I wish I knew when starting out creating my first circuit boards.

PCB layout

Laying out PCBs is something you'll learn as you go along. There’s lots of things you don’t do like placing delicate signals near a switching buck converter or let signals run anywhere without a good ground plane nearby. Learn to use ground planes correctly for both preventing traces from becoming antennas (they do!) and as a way to dissipate heat when needed. Watch video tutorials showing how to design boards from scratch. There’s so many thing that experienced designers know, but only will share as they stumble upon it while designing.

Always read the last pages of datasheets where they suggest PCB copper layouts for that specific chip. These will usually also suggest clever placement and sizing of passives like capacitors and resistors.

Rounded corners

The FR4 glass fiber that PCBs typically are made from are really sharp. You don't need to make many PCBs to understand how clever this is, but you are likely to make sharp corners until the first time you cut your finger or the pocket in your backpack where you put the boards to transport them.

Always add mounting holes

You may not need them initially, but there is seldom any cost to adding them. Use 3mm holes since Nylon studs are easily available for this. Buy the big kit of nylon M3’s, not just a small one. Having these holes on the board makes fixing the board or fixing things to the board so much easier.

Always add a button and a LED

If you use a microcontroller, just do this. You don't need to populate these on the board as long as you added the footprints, but if something does not work as expected these makes debugging so much easier. Most projects will need a status led or button input at some time, so it's just nice to have it on the board.

Always trust the DRC

This feature in any EDA program will tell you the obvious errors in your design. I have never seen it report something incorrectly so I don't ever doubt what it says. If there is an error or unconnected component and it's hard to spot the location on the board, remember that it may be at both ends of that wire. Hunt the error down and never ignore these warnings.

Also - never submit a board without running the Design Rule Check (DRC) before exporting the files. I once managed to send a board off for fabrication without any GND and 5V. If I only used the DRC one last time before submitting, I would have saved both time and money.

Always add test points

If the Microcontroller on your board comes in a small package, it's critical that you add test points. I always add several of these for anything I may want to measure such as analog signals, sensors and voltage. It's so easy to remove them from a design, but it's a massive time saver to just solder up a wire when you need to test something more than once.

Reading datasheets

One of the core things you do when creating PCBs is reading datasheets. Here's a few things I wish that someone told me with regards to just that.

Pin defaults

See a line above or below the RESET pin? It tells how you should tie a pin by default. This is also called Active High. There is also Active Low, but that's less common.

RL

In datasheets you'll often see a resistor marked as RL (lower pos L) and it's never documented what this means. I guess the reason it's not explained is that anyone with an electronics background will learn this at school? RL stands for Resistive Load and it's just there to explain that it represents your Load (what you're driving with your circuit). This can be a LED, motor, microcontroller or whatever, but RL is just something you're expected to know.

What the HEX?

Why do all datasheets obsess with these Hex numbers? Why can't they just use normal numbers? It's a matter of convenience and they're only there because they are easier to use than base-10. It's just not obvious until someone points it out.

A microcontroller is either 8 bit, 16bit or something more. That’s a bunch of one’s and zeros? To set bit 1 of an empty byte (b00000000), you just add 0x1 (b00000001). To set the second bit you add 0x2 and so on: 0x4, 0x8… But notice what happens for the upper 4 bits. You add 0x10, 0x20, 0x40 and 0x80. You can see a practical example in the ADS124S08 class I've published. You can set Bit 6 with 0x20 and bit 7 with 0x40 -> set both by adding them. Very clever when you see how it works out!

What EDA software should you use?

Hard one to answer but I get the question often, so I add my thoughts here. When you're just starting out, it's easiest to use a tool that you know someone using already. That way you have someone to ask as you progress beyond what you can learn from Youtube. If you don't know anyone, just drop by your local Hackerspace or check out the tons of tutorials available on Youtube. Popular choices are KiCad, EasyEDA, Eagle and Fritzing. Fritzing is the ideal choice for beginners, but it's unfortunately it is no longer actively maintained.

I primarily use KiCad and it's become a really good tool. I often find Open Source software to be either command-line based (and good) or half-working with a half-baked UI. KiCad is both well working and has a good UI. This is thanks to CERN supporting the software and making it their tool of choice. If it's good enough for CERN, it's more than good enough for me. KiCad is better than the former versions of Eagle that I have used (more intuitive), but the Fusion360 integration tempts a bit, so I'll likely poke into Eagle in 2019 to test it out.

Expect this article to be expanded over time. Got more good advice? Post it in the comments below!

 

Persistence of Vision with APA102

05 Jan19

Persistence of Vision with APA102

Back in April 2018 I made a board to play around with a few things I've wanted to learn. I added LiPo charging, a voltage boost circuit and the cheapest STM32 microcontroller I could find that offers USB connectivity. The main idea was to use this to make a Persistance Of Vison (POV) setup to play around with. I only had time to test the first iteration eight months later, but the second iteration is now up and running.

I've only just gotten it working, but it shows great promise already! The first version had several bugs (as expected), but none so critical that they couldn't be worked around. I got the LiPo charging and boost working on first try, but it didn't work just as expected when plugging in USB. To improve on this, I added a switch IC (TPS2113A) that would toggle between USB and battery as needed, but I didn't read the fine print so this circuit started oscillating and failed. I now have a much simpler and completely fool-proof solution to this using a clever MosFet switch. The shape of the first PCB made it hard to spin, so I fixed also that in the second version.

Why NeoPixels can't do POV

I've used ws2811 and ws2812 (often referred to as NeoPixels) programmable LEDs before, but they're not suited for Persistance Of Vision applications since the refresh is too slow.


Incorrect refresh produces a dot pattern

NeoPixels also have a lot of issues since they require very precise timing. This makes it very hard to use them with anything that also requires a wifi connection or anything that could disturb the timing. The APA102 is different. It has a dedicated clock channel that you can run at any speed so it will work with any computer, also Rasberry Pi and other things that can't offer precise timing. This requires an extra pin, but that's a very cheap price to pay to save all the hassle with NeoPixels.

The APA102 is also called DotStar or SuperLed and it comes in two form factors. The most common one is the 5050 (5x5mm) package, but it also comes in a 2020 (2x2 mm) version that offers the same light intensity in a smaller and cheaper package. The refresh rate of these are super-fast so they're well suited for POV applications when done correctly. A big thanks to Tim for his great writeups on all types of programmable LEDs! They've been of great help throughout the years.

POV with APA102-2020

If you're working on an Arduino-like platform, you can probably find a good project to start from. There is however no pre-made library for the STM32F0. I found a good place to start with this code, but the setting of max brightness is done incorrectly here so it won't work. The LED can be dimmed by adjusting the RGB channels, but you also have a power saving feature in the chip that you can set from 0 to 31 (32 steps). For POV, we need the LED to always be on and to do that, we set it to maximum brightness (31). I didn't fully understand how the first lib did this wrong, but after searching Github for apa102 and disregarding platform I found this code doing it right. Re-reading the datasheet I found that you can easily simplify this quite a bit and ignore storing the INIT and GLOBAL bits since these will always be 0xFF and I came up with this simplified solution.

With full brightness, all LEDs show as a continuous line.

The only thing that is STM32 specific here is the sendRaw-method. Replace this with how the platform of your choice does SPI and you can use it with Atmel AVR, Microchip, Parallax or whatever your favorite MCU is. The code will also work with the larger APA-102 LEDs. The Gist displays a beautiful rainbow pattern thanks to the super-smooth color methods used in many of Adafruit's libraries.

Further plans

Next up is displaying text and images, while I wait for the third iteration of the PCB to be fabricated. There's loads of great tools for converting images to C arrays, but I’ll make some custom code for displaying text also. The third iteration will have 100 pixels as well as an accelerometer/gyro combo so it can be used for POI-applications in addition to POV. For now I’m happy with storing data in the microcontroller itself, but I’ll eventually look into adding a simple Bluetooth wireless transfer to a Flash Memory chip so the device can be updated without USB or STLinkV2 programmer.

 

Getting started with STM32F0

04 Jan19

Getting started with STM32F0

I use the Particle Platform a lot and these have been based on STM32F4 up until the new Mesh radios they just delivered. The STM32 series is massive. There's microcontrollers for every need and budget, so I figured it would be a good learning experience to work with one of the cheapest ones available?

After some looking at datasheets, it looked like the STM32F070F6P6 was a good option for my POV-project. For just a few of these, you pay $1.5 per MCU. If you make something in volume (as in 2500), the price drops to $0.70 and below. If you only need a few pins, such an MCU can be a great budget alternative. It's a full 32bit microcontroller with all peripherals you'll typically need and it has the possibility of programming it via USB. It's cheap but has somewhat limited options and not too many pins.

Getting it up and running

Getting it up was super easy. No external components are required to run at 8Mhz, so you just slap the chip on a board and add pins to program and debug it (SWDIO + SWCLK). You can find a STLink v2 programming adapter on Ebay for less than $2, so this really is an affordable development platform. The drawback of running the chip without a crystal is that the internal RC oscillator is not precise enough that you can use USB. On the second iteration of the board, I added the crystal, but then realised that you need to upload a custom USB bootloader as the chip's don't come with one as stadnard. I still have not figured out how to make this work with my IDE, but I'll get there eventually. Speaking of IDE's for STM32 - I've now tried a few and the development experience is far from the 1-click Arduino installer. They're much more IDE's than the Arduino glorified text editor, but the install process is not as smooth.

      After testing some more it turned out that the STM32F070F6 line cannot use USB along with both I2C, Serial debug and Serial data. It simply does not have the required pins to do it? I can remap some pins to get USB working (PA9/PA10 -> PA11/PA12), but that prevents me from using an I2C based IMU. There is also the “minor issue” that the Virtual Com port driver takes up more than the available RAM in this rather constrained device… To work around this I’ll design the third version of the board based on the STM32F070CBT6. This is a 48 pin chip rather than just 20 pins. The price goes up to $2.26 per chip for 10+ and to $1.15 in volume. Its more expensive, but also offers 4 times the memory (128Kb) and that’ll come in handy to get USB working.

It also turns out that the MPU-6050 Accelerometer and Gyro I wanted to use is $8.31 from Digikey or Farnell? That’s for the IC alone. You can buy assembled MPU-6050 modules with all the required extra parts for $0.70 from Aliexpress. I already have 20 of them from another project, so I’ll just add holes to solder these modules in, rather than place them on the board. Reduces the price of each board and swift to solder in.

Setting up clock speeds and the rest of the hardware was really easy using the graphical tools provided in CubeMX. One of the very nice features of the STM32 family is that all pins can be setup as most anything. Want your analog pins on one side? Sure. Just set them up that way. Want two SPI controllers? Sure - just add them to the ports you want. The STM32F0 family is a little more limited than the STM32F4 that I'm used to, but they're still quite flexible. You can also set this up “by hand”, but using CubeMX to generate a set of files to start from is quite smooth. Just select your IDE, and CubeMX will generate suitable project files and a setup for that IDE. The main file will be full of comments indicating where you should put your code. If you follow this, you can then re-run the CubeMX tool to change pin config at any time without it overwriting your code.

What IDE to use?

The first IDE that I tried out was Atollic TrueSTUDIO for STM32 9.1. For an integrated IDE on Windows, this was rather clumsy to set up. I got it working, but it was far from a one click installer? I had expected it to be more plug and play. For my Mac I setup System Workbench for STM32 from OpenSTM32. Having worked with several Eclipse based tools before, this was easy to setup but it's kind of clumsy that the supplied downloads (both from OpenSTM32 and ST) have to be started from command line. ST supplies what looks like OSX installers, but these fail miserably and they've done so for many years. Given how popular Mac's are with developers, it's surprising that they don't even document this but rather just pretend to have a working solution.

It's also surprising that we still don't have proper 1-click installers for stuff like this in 2019. It's not super hard to install System Workbench with all required dependencies, but it's far from simple for a novice. They do however provide great written documentation to follow.

Both TrueSTUDIO and Workbench works well. You get access to full debug capabilities via stlink + openocd and both IDE's are completely free. Workbench is also Open Source. There's also commercial IDE's out there that support the STM32F0 family such as Keil's MDK-ARM and IAR Systems Embedded Workbench. I don't have $2-5k to drop on testing a platform on my spare time, but if you already have this software it's probably a little smoother to get things up and compiling.

Working with it

STM32's do not come with anything resembling an Arduino API, so it may take a little getting used to doing everything "manually" if you come from a more "managed platform". To turn on an output pin, you do something like this:

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET);

To turn it off, it's something like this:

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);

Lot's of CAPS and everything is defined as constants, so having an IDE that has some intellisense to open and inspect is required. It's nowhere near as "verbal" as Arduino's digitalWrite, but its just another way to do things? If you play around with several platforms, you'll soon realise that this is how it works in the MCU-business. Neither Microchip, Atmel, Parallax, STM or any other vendor offer APIs that resemble anything you know already. They all want you to go deep down and toggle registers on the chip rather than use convenient and familiar methods that can gloss over how the chip works.

They do however give you a hardware abstraction layer (HAL). It's not anywhere near as complex as just working with registers, but  it's also not exactly smooth? To use GPIO you first have to enable the pheripheral. Then you use the following commands to set a pin as ouput:

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

This is equivalent of Arduino's single line pinMode command. No problem, it's just more work. I'm sure this is MUCH faster, but in general I do not care if something is a little slower if it’s easier to remember. If all the code is Open Source so I can learn from it, that will save me in the very few and narrow cases where I need to save a nanosecond or ten? You could of course just write your own pinMode commands if you think this is how it should be.

I know some ppl that prefer to not use any tools and rather go for the 83 page manual for the specific chip, the 91 page programming manual, the 779 page reference for the familiy of chips or the many hundred of documents detailing how features such as DMA, RTC, PWM will work in detail. If you're one of them - then good for you as you won't need to worry about what to do with your spare time?

I on the other hand think good thing they made CubeMX to type all the config out for you and include HAL files :-)
It’s not what I’m used to, but it does the job well and I don’t mind learning multiple ways to skin a cow.