Bad things happen when programmer finds a soldering iron

Cananka, the Raspberry Pi HAT: Components

[This post is part three in the series.]

Usually behind component selection for any project there is a method in the madness. I will try to go through mine. :)

For the most visible part of board, we are going to need a nice CAN bus connector. I personally prefer Phoenix connectors for this purpose. As we are dealing with low voltages, I feel their MCV series is a great choice. It is a 3.81 mm pitch connector allowing for 8 A of current. Better yet, it is a two part connector so you can wire your plug in peace only connecting it to board once ready.

On the bottom we need to have a 40-pin female header. Final distance between our board and Raspberry, per specification, has to be 10-12 mm. However, that doesn’t mean your header has to be that high. Male header on Raspberry is already 2.5 mm. As long as our connector is between 7.5 and 9.5 mm, all is good.

First electronics component is easy - in order to satisfy HAT specification we need EEPROM for our settings. Here we pretty much take recommended circuit and roll with it. Maximum current CAT24C32 will take on write is 2 mA from 3.3 V rail.

Component selection is primarily driven by requirements and rarely we can see it as clear as here: As we need existing Linux driver to support our board, we are pretty much boxed into selecting MCP2515 as our CAN controller. Another obvious choice would be SJA1000 but that one is a few times more expensive. As Raspberry header pins are using 3.3V signal level, we will power it from 3.3 V rail in order to avoid level translator. Maximum of 10 mA will be used from 3.3 V rail.

Clock for MCP2515 can be up to 25 MHz but I’ve decided upon 16 MHz as this figure fits nicely with Raspberry’s divisor controlling SPI bus. It wouldn’t hurt to use higher clock-rate but 16 MHz is a value I use often in another project so I had component handy.

For CAN bus we also need transceiver and of course there is no single answer on which to select. For isolation we can go either with a dedicated isolator (e.g. Si8421 paired with MCP2561) or we can use one of rare isolated CAN bus transceivers.

As isolated transceiver already needs two power supplies, we can avoid level translator and keep each side on its own preferred level. Signal side will be powered on 3.3 V and CAN bus side will be on 5 V. One device that matches these requirements is ISO1050. Not exactly cheap but not too expensive considering it is all-in-one solution. Maximum current of 3 mA on 3.3 V side fits well within our restrictions. On its 5 V side we need 75 mA maximum from the isolated 5 V rail.

Typical application circuit for ISO1050 also mentions additional protective diodes and we shouldn’t forget those too. Searching for basic two-channel TVS diodes supporting 30V and above (in case we get to work with 24 V CAN bus) PESD1CAN comes as a first choice. And guess what NXP tells intended usage is? Yep, CAN bus protection.

There is a big chance we will need to terminate our CAN bus with 120 Ω resistor. For this purpose a place for two 1206 resistors is available. Combined this allows for about 1 W power dissipation, depending on the exact resistors used. Considering transceiver short-circuit current is 105 mA at 12 V, we are cutting it a bit close for the worst-case scenario. But, as such peak currents are not going to last for long, even at 24 V this should be sufficient.

My plan is to use nice Phoenix connectors and simply get through-hole resistor next to the wires. ISO 11898 even recommends such cable termination since that way you can disconnect node without impacting bus. What I definitely don’t want is header or DIP switch controlling this.

Speaking of which, in order to power up our 5 V goodness, we need isolated DC-to-DC power converter. Many of them come in 4-pin SIP interface and can be directly substituted for one another. I opted for ROE-0505S as it is cheap, small, uses standard pinout, and 200 mA it offers is more than sufficient for our needs. It is a bit finicky at low currents so we should put a LED to waste some of that (e.g. 15 mA). Taking into account its efficiency of 79%, we will use around 110 mA from Raspberry’s 5 V rail.

To power Raspberry Pi from CAN bus power, we get to use another DC-to-DC converter. Unfortunately Raspberry Pi is a hungry beast so we must get into bigger and more expensive choices. After taking literally every DC-to-DC converter capable of producing 5 V / 1.5 A from 12 V source available at Digikey and getting theirs pinouts, I’ve noticed essentially two groups with a few outliers. First group was of devices measuring 32 x 10 mm. These devices run around $25 and all share same pinout (e.g. JTF0824S05). Another group came in 25 x 25 mm size, sharing the same pinout, but unfortunately at a slightly more expensive $30 (e.g. JCM1512S05).

With board measuring only 65 x 56 mm, both would fit, but square one would be much easier to place due to camera slot so I’ve decided to go with that. While those are more expensive devices, for some reason they offer higher current output than their rectangular cousins so 2 A is the norm here. Fact all devices in this group use the same pinout means it will be easy to find replacement if original choice (S24SE05002NDFA in my case) becomes unavailable.

We also need a simple 2 A fuse on power-back circuit together with an ideal diode circuit as recommended by HAT specification. As with any DC-to-DC converter we have to keep minimum load in mind (usually around 10%) but Raspberry Pi is hungry device so we can ignore it this time. Even if we do not meet it, nothing bad will happen as only effect is that supply will go out of spec. As Raspberry Pi doesn’t use 5 V directly but goes over another DC-DC converter, we are safe even in sleep mode.

For those wondering why the heck we are accounting for each mA, answer lies mostly in Raspberry Pi header and 3.3 V rail. Maximum current we should pull is around 50 mA. Anything more and you might make for an unstable system unless you use a separate voltage regulator bringing beefier 5 V rail into play. On 5 V rail we are pretty much only limited by power supply used. If using normal 2 A supply, you should have round-about 500 mA available provided there are no hungry USB devices connected. If you kept with accounting, we have 15 mA usage from 3.3 V rail and 110 mA on 5 V. Well within the spec.

Onto the board.

Cananka, the Raspberry Pi HAT: Requirements

[This post is part two in the series.]

Signalling-wise you can see CAN bus as 5V based but its automobile roots make 12V supply voltage quite common and that is what I am actually using at home. Annoying thing when using 12V is that every CAN board has to drop voltage to 5V needed for logic. Good thing is that you are carefree with longer cable runs. When using 5V, even drop of 10% is a problem and 12V can give you much more breathing room.

Considering I will connect this device to the potentially harsh world, it would be splendid to have its CAN bus portion completely electrically isolated from the Raspberry Pi board. Therefore it will need a major screwup on the input interface to take Raspberry to its death. As CAN bus can span quite a lot of distance and you don’t know all components will be on the same power circuit, this will also help to deal with ground loops and all those different potentials.

Having CAN driver isolated also means we have to power it from somewhere. While my “slave” devices obtain power from the 12V line, for HAT I’ve decided to go with on-board DC-to-DC converter. This makes my device essentially compatible with any CAN bus, regardless of its voltage. Removing external power from consideration also makes it less likely to have a outside high-currents flowing around.

Of course, it would be nice if we could power Raspberry Pi from our CAN power rail. Since isolation is name of the game, we need DC-to-DC converter capable of at least 1.3A (preferably 2A) at 5V. As these modules are usually expensive, this has to be optional part. And yes, back-powering device should be safe even if user forgets to unplug it from USB.

On mechanical side, in addition to HAT basic requirements, possibility of having the HAT on while Raspberry Pi is in the case would be desired. Official case is preferred but other cases should be taken into consideration. This will greatly limit component placement and it could even impact size as, on the first glance, the official HAT dimensions might be a smidge too big for the official case.

On software side it would be ideal to make a board compatible with existing CAN device driver already present in Linux. Default settings for device should be as close as possible to defaults used by that driver. While creating your own driver is possible and not that complicated considering simplicity of a CAN bus, it makes a little sense to create something you will have to compile every time when new OS is installed if you can go with something already present in the kernel.

Onto the component selection.

Cananka, the Raspberry Pi HAT

Illustration

[This the first post in the series.]

As I got myself a Raspberry Pi, I started thinking about connecting some electronics to it. And in Raspberry world you can either just connect some wires to connector or go about making a HAT.

Raspberry Pi HAT specification defines both mechanical properties and a minimum of electronics while still allowing you to do whatever you please with available IO. Pretty much the only strict requirements here are board size (65x56 mm), hole placement, and presence of a special EEPROM with board identification data. A bit more complicated than bare wiring but simple enough.

Armed with knowledge of what’s needed, I had to decide what I’ll actually make. As I played a lot with CAN bus lately, it seemed as a reasonable choice. Not only I go with something familiar on a first try but I get to connect it to the rest of my humble CAN bus world.

Early into the project one has to decide on a name. In this case the name was obvious - Canberry. Unfortunately it was obvious to someone else too as there is already a project with that name. Lesser man would give up here as not only the name is taken but it is taken by a really similar project. However, project is not exactly the same and differences will make exercise worth-while.

With the preferred name taken, choice fell onto CanPi. Guess what - there is also project named CANPi out there. One guess at what it is about. :)

For a while I’ve settled onto Can314 and actually used it for a few days in my notes until, unrelated to electronics, I was playing with Red Hat. Suddenly its younger sister Fedora came to mind. As fedora is type of hat, what else to call Raspberry Pi HAT than Candora. Name seemed good for a while but I wasn’t completely happy.

However, now I had an idea. With the help of Wikipedia hat page I’ve came upon a few other names inspired by hats: Canbeen, Canullo, Canetto, Canouch… just to name a few.

But at the end Cananka, a name based upon Russian ushanka hat, won. Not only it is easy to pronounce but Google only finds 7100 matching pages.

With the name selected, onto the requirements.

No Delays.h

After not touching project for a while, using MPLAB X 3.26 with a newer XC8 compiler (1.37) brought me error: (141) can't open include file "delays.h": No such file or directory. For some reason delays.h got cut from the environment. Fortunately, the only function I’ve used from that header was Delay10KTCYx - one you can directly replace with a _delay macro.

For example

Delay10KTCYx(6);

can be directly substituted for:

_delay(60000);

But that works only up to 19 - values 20 and above will give you error: (1355) in-line delay argument too large.

For those we can always create a more direct substitute:

void Delay10KTCYx(unsigned char count) {
    do {
        _delay(10000);
    } while(--count != 0);
}

Using AN20 on PIC16LF1559

For one pet project, I decided to use Microchip’s PIC16LF1559. as it was close to perfect as far as my needs went in that particular scenario. So I got all parts, soldered it onto the board and it almost worked perfectly.

Single thing that gave me trouble was light detection. It seemed as if ADC converter was giving me nonsense. I check and rechecked my code multiple times as this was the first time I’ve dealt with this chip. It took me a while before I remembered to check errata sheet. And, lo and behold, there was an known issue: “AN20 is not internally connected to the ADC bus when AD2CON0’s CHS bit select the pin.” And guess which pin I decided to use for light sensor?

Initialization of ADC is something that will slightly vary with application but what follows is a reasonable starting point:

ADCOMCONbits.ADFM = 1;      //right-justified
ADCOMCONbits.ADCS = 0b111;  //Frc (clock derived from A/D RC oscillator)
ADCOMCONbits.ADPREF = 0b00; //Vref is Vdd
AD2CON0bits.CHS = 20;       //select AN20
AAD2CHbits.CH20 = 1;        //AN20 is connected to ADC2

This will nicely work around the issue by using AN20 on the secondary channel. Not an ideal situation but it was ok in my case as I had no other plans for secondary channel anyhow.

Reading a value is a bit different than when dealing with a usual, single-channel, setup:

uint16_t getAdcValue(void) {
    AD2CON0bits.ADON = 1; //Turn on ADC

    AD2CON0bits.GO  = 1;
    while (AD2CON0bits.GO_nDONE) { nop(); } //Wait for A/D convert complete

    AD2CON0bits.ADON = 0; //Turn off ADC

    if (AADSTATbits.AD2CONV) {
        return AD2RES1;
    } else {
        return AD2RES0;
    }
}

For my purpose it made sense to turn on/off ADC as needed - for some other scenarios it might be better just to leave it always on. But interesting bit comes when reading a value - ADC saves it interleaved between two registers: AD2RES0 and AD2RES1. Code simply had to make sure to read correct one.

And this, slightly roundabout process, finally got the project working.

Date in a MPLAB Hex File Name

Illustration

Every compilation in MPLAB results in the same file - Source.production.hex (yes, assuming you are not doing debug build). This is perfectly fine if we want to program it immediately. However, what if we need to store files somewhere else and, god forbid, under different name?

Answer is simple enough. Under Project Properties, Building there is a post build step option. Enable it and get code for copy in. In my case, I wanted to have hex file copied to Binaries directory:

${MKDIR} "Binaries" && ${CP} ${ImagePath} "Binaries/Whatever.${OUTPUT_SUFFIX}"

But simple copy is not necessarily enough. It would be great if we could include date in the file name. And there problems start - there is pretty much no documentation for build commands at all. Only way to figure things out is to see how they are setup by the platform itself in nbproject/Makefile-default.mk and nbproject/Makefile-local-default.mk. To cut a long story short, there is a way to get output from external command. Just wrap any command in completely unexpected $(shell ) pseudo-variable.

In order to get actual date I prefer using code>gdate (comes with MPLAB installation). Using it our line becomes:

${MKDIR} "Binaries" && ${CP} ${ImagePath} "Binaries/Whatever.$(shell gdate +%Y%m%d).${OUTPUT_SUFFIX}"

Finally after build we will have both our usual Source.production.hex and also a copy of it under Whatever.20150128.hex.

How Fast Can You Charge?

Recently I saw SONICable Indiegogo project promising to double the charging speed on computer. It is supposedly an advanced USB cable with a magic switch cutting your charge times in half. But not everything is as it seems.

First onto a topic of “unleashing double the charge power of the regular charge cable”. As you might know, USB standard limits current to any USB device at 500 mA. What is not obvious from this is that even now you can have devices pulling much more than this - all the way until small fuse stops you. Devices obeying the standard pull 500 mA because they are well behaving citizens - not because USB restricts them from more. Just measure current of any USB cup warmer. :)

Some devices, mobile phones in particular, also have a fast charging mode that triggers when they detect a wall charger. Detection method itself used to be different for every manufacturer. Fortunately they got standardized into two camps - Apple and everybody else. Leaving Apple aside, most phones use USB Battery Charging Specification. Deep in technical text there is a Dedicated Charging Port (DCP) detection method consisting of “short D+ to D- through resistance RDCP_DAT”. At end specification we have RDCP_DAT defined as maximum resistance of 200 Ω. In laymans terms - just connect the freaking D+ and D- wire together.

Since standard USB cable has four wires (5V, D-, D+, and GND - let’s forget about ID for now), whole high-tech solution is to connect two wires together. That will make device think it is connected to a wall charger and that it can stop being good 500 mA citizen. It is the phone who will then pull around 1000 mA (rarely more) from computer. Since fuses on USB port are intentionally overdimensioned, computer will generally allow it.

There are thousands of YouTube videos alone showing you how you can do this. All you need is to get an old USB cable and cut it open. Then short data wires (white and green) together and voila - you have a cable giving you 1000 mA magic.

There are devices enabling this on eBay. Quick Google search found me The Practical Meter and USB Meter Pro on Kickstarter using exactly the same “magic” as SONICable. Heck, even my UsbAmps uses exactly the same principle from 2013 onward as a button option. Unofficially, there were people seeing me use small screwdriver to connect D+/D- lines way before that. :)

This functionality is nothing special, nothing secret, nothing patentable, and definitely not magic. Paying for a $25 cable promising you magic when all it does is enabling something you can get either for free or for fraction of a cost is crazy in my opinion. To be completely fair, just based on images, it does look as a nice cable - those with fashion in mind might be able to justify $25 cable. Just don’t buy it for its technology.

And remember - with USB 3.1, its new connector, and a new USB Power Delivery standard all this will become pretty much irrelevant side note in the history of USB.

Detecting Watchdog Reset in XC8

Illustration

Watchdog is probably one of the best PIC microcontroller features. Yes, it would be great if you would write perfect code and program would not get stuck in the first place, but let’s face it: mistakes are going to be made. And really, are you going to write timeout code around every communication routine just so you can detect one in million error?

In 99% of cases, you will just turn on WDT timer in your config bits and count on it to reset microcontroller if something goes wrong. If watchdog times out, program will start from scratch and all is good. For all practical purposes, watchdog-initiated restart is same as normal start. Or is it?

Most PIC microcontrollers clear their ~TO bit in STATUS register as a way to detect watchdog restart. However, if you try to read that from your XC8 compiled C program it will seem that every microcontroller start is normal. It will report any timeout. Cause? Because your compiler is clearing STATUS register before your program starts running.

If you are interested in watchdog timeouts, first you need to tell your compiler to preserve startup status for you. This can be done by going into project properties, selecting XC8 linker category and checking Backup reset condition flags item. Now your compiler will give you access to two special variables: __timeout and __powerdown. These variables will be copy of ~TO and ~PD states respectively.

If you read datasheet carefully you will notice that ~TO will be 0 if timeout has occurred. Thus code to check for it would look something as:

void main() {
    ...

    if (^^__timeout == 0^^) { //value 0 means there was a timeout
        //this restart is due to the watchdog timeout - do something here
    }

    ...
}

PS: Procedure described here is specific to XC8 compiler. But same principle applies with most other compilers too.

Jelly Bean PICs

It used to be easier years ago when I started playing with Microchip microcontrollers. You pretty much had only PIC16F84 readily available and that was the PIC you used for anything. Today situation is very different. There is probably a different microcontroller for any purpose you can imagine. However, with time, I more-less standardized on a few of them.

Theme is common. I work mostly with 5 V power supply so anything that can work directly of that is highly desirable. Pretty mandatory is at least one UART port because that is something I use more often than not. I2C and SPI are also high on the list but they sort of go hand-in-hand with aforementioned USART so I rarely specifically search for them.

For most of things I do speed is rarely of concern and any PIC with internal oscillator (keeping component count low) will usually do. Exception is when it comes to USB and CAN bus that are really finicky in that respect.

Quite often my PIC of choice has multiple family members so I can easily go between memory sizes and/or pin counts. Also high on the list are old and proven designs everybody else uses. Why do development around a new and/or unknown PIC if you cannot buy it 90% of the time.

Since most of my soldering is done by hand any PIC that cannot be obtained in SSOP or similar package is automatically out of picture. Having it in DIP format is a small plus but I personally don’t really care about it.

Without a further ado, here is my list of PIC chips I always have available:

PIC16F1826

If I don’t have any special needs I will most probably end up using this little gem. It is rather small in size with only 20 pins SSOP (18-pin DIP), 16 of which can be used for I/O (not all models are this pin-efficient). Alongside 256 bytes of RAM, it also has 256 bytes of data EEPROM available. Basic model has only 2K of programming space but upgrade to 4K model (PIC16F1827) is completely painless.

Features include 10-bit ADC (12 channels), specialized capacitive touch module (12 channels), good UART, and support for both I2C and SPI. It goes up to 32 MHz, all that on internal oscillator module. Only thing you need to connect one of these is 1.8-5.5 V power supply and a small decoupling capacitor.

Price (in quantities of 1) is always less than $2.

PIC16F1934

If I need to connect PIC to LCD, I keep going back to this one 40-pin beast. With total of 36 I/O lines controlling 3 digit LCDs is trivial and that is not even maximum it can support. This basic model has similar (to PIC16F1826) memory configuration. However, next two models (PIC16F1937 and PIC16F1939) double the RAM and program memory each, all the while keeping full hardware and software compatibility.

Due to its bigger size, it has 14-channel 10-bit ADC and 16-channel capacitive touch module. It goes without saying that UART, I2C, and SPI are all supported. Internal oscillator is same respectable 32 MHz as is the need for 1.8-5.5 V power supply. A bit more careful decoupling is going to require three capacitors.

This family has also a smaller PIC16F1933, PIC16F1936, and PIC16F1938 members I sometime use. From software perspective they are the same as their bigger brothers but, since they have lower pin count, you cannot just drop them instead of larger device.

Price for one is $2.50.

PIC18F25K80

This microcontroller is a beast. In its small package (28-pin) it has whooping (for a microcontroller) 32K of a programming memory acompanied with 1K of a data EEPROM and 3.5K of RAM. Its hardware-compatible upgrade (PIC18F26K80) improves program memory to 64K. This family also has bigger members in 40 and 64-pin configuration but they are not drop-in replacements.

ADC is 12-bit (8 channels) which is pretty much the best you can find in any microcontroller and there is a support for two UART devices at the same time. Of course that it also supports I2C and SPI but my main reason for using it lies in its CAN bus support. Just add a CAN bus driver and you are good to go.

This is still 1.8-5.5 V device but one has to take a bit bigger care with decoupling since Vddcore needs a bit larger capacitor than standard 100 nF we’ve come to expect. Also notice that CAN bus functionality pretty much requires you to have external oscillator so getting everything setup is a bit more work.

For one you’ll pay about $3.50 but it is worth it.

PIC18F26J50

Whenever I need to play with USB, this is my go-to chip. This 28-pin device has 64K of program memory, 3.5K of RAM and unfortunately no data EEPROM. But fear not, you can use program memory for settings. If you don’t need a lot of program memory, you can use smaller PIC18F25J50 and PIC18F24J50 but I’ve found that anything USB related usually wants 64K as a minimum. Of couse, you can also go to higher pin count with PIC18F46J50 if that is what you need.

You also get standard 10-bit ADC (10 channels), 2 UART modules and, of course, I2C and SPI support. Internal oscillator goes up to 48 MHz and it is precise enough to allow for USB interaction. This device also has a really configurable pinout so it’s great for a size-constrained designs. Unfortunately its power supply has to be 2.0-3.6 V, it needs pull-up resistor for reset control, and multiple decoupling capacitor sizes require you to have quite a few supporting components. It gets expensive and crowded pretty fast.

There is a promising PIC16F1459 which does offer a bit more modern architecture and a simpler 1.8-5.5 V life but I find 8K programming memory really restrictive when dealing with anything USB.

One PIC will cost you slightly less than $4.50.

No Drilling, Please

Illustration

As I managed to do create a holly grail of electronics - double sided PCB without any vias, only remaining step was to get it made.

Usually this would consists of uploading board gerbers to OSH Park and getting payment sorted out. However, this time I was greeted with error: “I can’t find a drills file”. Mind you, this was expected since I really didn’t have a drill file, but unfortunately this wasn’t a warning I could skip. So I contacted support.

I really didn’t expect any quick answer since I raised ticket on December 31st after 16h PST. Surprisingly I got the solution almost immediately. It wasn’t possible to upload design without drills but Dan (yep, Laen doesn’t handle support any more) suggested a file with drill locations all falling outside of board. Their filtering process would then remove those as invalid and my drill-less board would be ready for manufacturing.

While this solution was acceptable for one-off job, it got me thinking whether there was something a bit more elegant and less error-prone if I create some bigger board in the future. To solve it properly I had to have a drill file without any drills. To the Excellon specification!

With a bit of testing, I got to the minimum of content that OSH Park parser would still consider a valid drill file. It is essentially just defining one drill tool, selecting it for work and then finishing script without ever drilling a hole:

M48
INCH
T01C0.0394
%
T01
T00
M30

Empty drill file is available for download.