Cirqoid blogging again - laser range finder with TFT display
Posted on March 24, 2015.
It's really been a very long while since our last blog post. Such long that we even got an email asking if we are still in business. Fear not - we absolutely certainly are. We've been struggling for quite some time to meet the demand on Cirqoids, so we focused our efforts on streamlining the production. It meant we had to sacrifice some other things and blogging was among them. Things start to look brighter now, so here we are with a new post.
We got a LIDAR-Lite laser range sensor and we wanted to see what it is capable of:
We also had a 2.2" LCD display module with ILI9341 controller lying around and wanted to see if it can be used as a generic output device for small projects like that - something a bit fancier than 16x2 text LCD but not a full blown display which requires plenty of MCU resources. This controller uses SPI bus, so connection is supposedly relatively straight-forward and there's no need for a powerful MCU.
On top of that, we regularly get questions if Cirqoid is any good for 0402 components. For whatever reason, so far we have been sticking to 0603 components. So we could only reply that we don't see any reasons why something would go wrong with 0402s. Thus, we threw in a couple of 0402 resistors so that next time we could confidently say that we've been there and done that.
And finally we wanted to evaluate alternatives to Eagle - our EDA of choice, at the moment. We started to get a feeling, that the layout process is more involving with Eagle than it could have been. Thus, we decided to take a DipTrace for a spin - we've heard some good things about it. There's not much to loose here - even if we don't fall in love with it, we'll have a Gerbers export tutorial for another EDA.
The idea of the project was to have a board, which would monitor the presence of an object in front of the sensor, by continuously measuring the distance and comparing it to pre-selected value. We thought of a board which attaches to the display and has a connector to hook up a range finder. The display would continuously output current reading on the green background if the distance is within the range, or on the red background otherwise. Thus, there would be a button to set the distance. As the laser itself uses IR waves, we decided we would add a 3.3V output for a laser pointer, so that we could see where we are aiming with the sensor.
So here we are - armed with a LIDAR and a display, we downloaded a free version of DipTrace (same as Eagle, it has a free version with limited functionality for non-commercial use ) and started our design. We tend to use STM32 controllers as a default choice. With a LIDAR on I2C bus and a display on SPI, more or less any MCU would do the trick. This got us to STM32F0 series - the simplest in STM32 family. Now, having to drive a 320x240 display would probably need some flash and RAM and we wanted to estimate how much, so that we could choose a particular chip.
As we have some familiarity with ChibiOS and µGFX we looked no further. We wrote a firmware initializing the screen and writing something there. It came out at ~40Kb of code with RAM requirements at 5Kb. Quite considerable for displaying several digits on the screen. We could probably go into some optimizations to shed some size and get it below 32Kb and 4Kb respectively, but hey - given what their cost is, who cares. Let it be 64Kb flash and 8Kb RAM. This way we ended up with STM32F030C8T6TR. It comes in LQFP-48 package with 0.5mm pitch between leads - perfectly doable with Cirqoid.
DipTrace didn't have the MCU we've chosen in its library, so we had to draw that ourselves. Not a deal breaker - we would have to do that in Eagle anyway. Other components were some commonly used passives, so as expected they were all in the library. As a nice bonus there was even a switch button, which we happened to have at hand (though without a 3D model). With some playing around it turned out that somewhat sluggish zoom operation in DipTrace can be greatly improved when using Windows GDI graphics Mode (View → Graphics Mode → Windows GDI in the menu bar). Text seems to look prettier when rendered as TrueType, as opposed to vector (View → Part Markings → Font → True Type, View → Connection to Bus → Font → True Type and View → Pin Numbers → Font → True Type).
Learning DipTrace's interface we gradually came up with the schematics. This is what we got as a result - LIDAR board schematics.pdf. So far so good. And we liked the DipTrace - after just one board we already felt more at home with it than with Eagle.
Having finalized the schematics, it was time for a layout. This is what we mostly didn't like about Eagle. As we already anticipated after drawing schematics, layout was a nicer process than it would have been in Eagle. One thing where we had to compromise was the contour of the board. We prefer to have contour drawn with lines, leaving small tabs between them to keep the board in the laminate until we are done with it. DipTrace wasn't really against, but it refused to render a 3D preview of the board if it didn't have continuous outline. This way we ended up with two outlines - one for us and one for the DipTrace. That's something we can live with. This is what the board is going to look like:
There were trillions of header connectors in the library, so we probably didn't choose the most precise match for the Molexes were were about to use and for the female header connector we intended to use for the display. We'll have to go through the list of available connectors.
This layout has all SMD components on top layer and all the connectors and a button on the bottom layer. We did it this way because the header that we intended to use for display connection could only be soldered from one side (remember, the holes are not plated through). Thus all the traces of this connector need to be on the layer which is accessible for soldering. As majority of the traces tend to be on the components layer, the connectors had to go to the bottom.
Exporting layout to cirQWizard
In DipTrace this process involves three steps.
First of all, gerber files had to be exported (this feature is accessible via menu File → Export → Gerber). Click on "Files" button takes us to the window, where we can choose the names and extensions for the output files. That's how it is supposed to look:
Pay attention to zeros at X and Y offsets - we had 10 in both of these fields initially. It proved to be important later down the road. After that click on "Export all" saves all selected layers with appropriate names and extensions.
Then the drilling file was exported (via File → Export → N/C Drill). Our success formula here was to click on "Auto" button and then on "Export".
The file is saved with the wrong name and extension (wrong for our purpose, that is). Thus it needs to be renamed:
This frightful extension change isn't as terrible as it looks to be.
And finally it was the turn of components pick and place file - unsurprisingly, located in File → Export → Pick and Place. This how this screen should look:
The file needs to be saved with the same name and "Excel CSV" type. Then the extension has to be changed to .mnt (again, despite the dreadful warning about the possible harm of extension change).
As every EDA software has its own opinion on what pick and place format should be (sometimes configurable to a certain extent, sometimes not), cirQWizard uses a configurable regular expression to parse these files. This means cirQWizard needs to be configured to recognize a new format. To get this format recognized we came up with the following regular expression:
It had to go to Settings → Application → Centroid file format in cirQWizard.
Producing the board
Now everything was set to mill the board. The top layer is fairly uncomplicated, except for the MCU chip, which has 0.5mm pitch pads. In such situations we prefer to start with a larger V tool - 0.2-0.5mm to mill everything except for the fine traces. This creates nice separation everywhere, where it's possible, takes less time, compared with doing the entire board with the smaller tool, and wears slightly less expensive bit.
Here's the screenshot of the parameters we used for this operation:
We tend to use 2 additional passes around both traces and pads. It does increase milling time, but provides additional traces separation and saves plenty of time while soldering and troubleshooting the board.
Then we were only left with the pads of the MCU. We changed the bit to the smaller V tool - 0.1-0.15mm and milled the pads (all other traces were disabled to save the time). Here's the screenshot of the parameters for the second operation:
As at this stage we were left with the fine traces, there was no point in using additional passes - the clearance didn't allow for them anyway.
There weren't many traces on the bottom layer, and none of them had fine clearances. So it was all milled with the larger V tool.
This is the board after milling:
We experimented with the feeds while dispensing the paste and apparently, we didn't get enough solder paste of the oscillator pads. It didn't look too bad, but when the board went into the oven, the air convection started to move the oscillator around the board. We got the board out of the oven and removed the crystal before it was too late. So, after the reflow the board had almost all SMD components:
It was time for the most boring part of the process: soldering vias and connectors. In this board we soldered diode leads between the layers. We had to solder SWD connector on the components side, as it turned out, on the opposite side it would go into the SD cart slot. This is the board with after all soldering was finished:
Every now and then people ask how much time it takes to make a board with Cirqoid. For this particular board, milling (including drilling and contour milling) took an hour. Populating with components and reflow took about another hour - even when there's not that much components on the board, taking a tape out of the envelope, cutting of a piece, peeling off a film, putting the tape back takes amazing amount of time. It was getting late by the time we got to manual soldering, so we forgot to clock that. But it probably took again something like an hour.
And, by the way, yes - 0402 resistors made their way to the board without any objections.
Having the board ready it was time to actually make the firmware not only compile, but also work. We got a little bit stuck with getting I2C bus working in Chibios. It turned out PAL mode of SDA and SCL pins in addition to PAL_MODE_ALTERNATE had to be set to PAL_STM32_OTYPE_OPENDRAIN mode (and not to PAL_MODE_OUTPUT_OPENDRAIN, which resets the PAL_MODE_ALTERNATE). Otherwise MCU was trying to actively drive them to the VCC level, instead of letting them float. This resulted in 1.5V signal instead of 0V when the laser was trying to pull the line down to ground. This caught us off guard and took some time to figure out.
Another issue that we faced was that gdispFillArea() function of µGFX (which, as the name suggests, fills an area with a uniform color) was taking enormous amount of time (several seconds for the entire screen). We verified that it's not the timing issue on SPI bus and assumed that's either because of less than optimal ILI9341 driver implementation in µGFX or just the way it is meant to be. We didn't feel inclined to dive into the internals of the driver, so we chose to get rid of the area fill operations where it was possible. It turned out reasonably well, and as a side effect we saved quite a bit of flash and RAM space while optimizing the performance. The resulting binary was using ~13k of flash and ~2k of RAM. Yikes, we could've easily gone for 16k flash, 4k RAM MCU. What a waste of 0.50€!
With both electronics and firmware ready, we fixed everything to a piece of plywood:
Now it was time for the rewarding moment of playing with just finished new toy:
Project's schematics, layout and gerber files as well as the source code of the firmware are available on github: https://github.com/cirqoid/lidar-board