Car enthusiasts can use a GPS enabled device to track their times on race tracks or AutoX courses. These devices are usually standalone and provide high accuracy times based on previously stored map location data. Then can also sometimes interface with the car via the OBDII protocol to get interesting information.
After looking at the current on market devices for tracking cars at competitive events I thought they were over priced. It was hundreds of dollars for a device that used GPS to time how long it took to drive between two points. It was then closer to a thousand dollars if you also wanted to record OBDII data from the car.
I thought that I could do all of this myself. It didn’t seem too hard to run Linux, attach a GPS sensor, OBDII reader and screen and write some code to process/display it all.
I have a background in electrical engineering and work as a software engineer. I have designed PCBs at university so I thought I could figure it all out. I bought some books and started researching.
After starting some basic investigation and research I settled on using a Pine64 board for the CPU and designing my own PCB for GPS and OBDII. I could connect a screen via HDMI and mount it all together in a small package which I could power from the car.
I used SparkFun to get development boards which I could test with then I could implement something similar in my own PCB design.
A long story short, I developed and manufactured a v1 PCB (https://github.com/DashSight/Pine64-Mezzanine-Card) which I debugged with just a voltmeter and reading schematics and datasheets. Unfortunately due to mistakes by me and part availability issues the v1 PCB didn’t really work at all.
I then developed a v2 PCB (https://github.com/DashSight/Pine64-Mezzanine-Card) and had that manufactured by a PCB assembly company. The entire design was done in KiCAD and is open source on GitHub. I also debugged this with just a voltmeter and found a few minor issues. I did speed a lot of time trying to identify what ended up being a bad solder joint.
All while doing this I was building my own Linux distribution (using OpenEmbedded) and writing a program in C with Gtk for the GUI.
Eventually I had something that kind of worked. I had a multi-threaded GUI in C, a HDMI attached monitor with touch support via USB. This was all held together by a 3D printed case I has designed.
Unfortunately it ended up being too big. The HDMI meant it was both too thick and too wide to handle the cable and connection. So I decided to swap to a MIPI DSI attached screen, with an I2C touch controller.
It turns out there was already Linux kernel patches being upstreamed for the Pine64 screen. So I built those and started getting the screen working.
This was a nightmare. I was stuck with no output (as it didn’t work the first time). No worries, I would just get UART going and debug the issue.
What I didn’t know was that UART0 on the board was broken. I was using the other UARTS for GPS, OBDII and WiFi. I wasted hours trying to get UART0 (the default for serial access) working. Eventually I tried using another UART, got that working and debugged the screen issue. I thought I was just not connecting or setting up the UART correctly, but it turned out to be a board issue. At this point I decided I needed a Logic Analyser, as I wasn’t going to go through that pain again.
Now I have a much smaller enclosure, with a LCD attached via MIPI (just like in phones). My PCB provides GPS and OBDII connections. I re-wrote the app in Rust, so I have a Gtk gui that the user interfaces with (https://github.com/DashSight/DashSight).
Next I thought it would be cool to have an accelerometer. I bought an accelerometer online form SparkFun to test before extending my PCB. I connected it all up and nothing worked. No worries, now I have a Saleae Logic Analyser (https://www.saleae.com).
With the help of the LA, I could figure out that nothing from the I2C bus was happening. I debugged this to a bug in my kernel device tree. After fixing that I could see data on the bus, but it still wasn’t working. Using the LA’s I2C decoding I could see the packet going to an address, but no response. After checking the data sheet I realised I had to ground the selection pin to have the slave accelerometer work at that address, after fixing that and connecting the !CS pin I had the accelerometer connecting and working!
In this case the LA didn’t offer anything I wouldn’t have figured out eventually. It just reduced the time spent debugging something as I could see exactly what was going on.
After awhile though the I2C bus would stop working. Using the LA with the analogue input I could see that even though I had the I2C master set to pull-up the line it wasn’t enough. I saw very curved waveforms when the bus transitioned from low to high.
I realised that even though I had it working with the I2C master pulling up the line, it wasn’t strong enough. So I added some pull-up resistors to the I2C bus and the LA showed a much better result.
This issue is something that I don’t think I would have figured out (at least not for certain) without the Saleae Logic Analyser. It worked most of the time that it would have been a nightmare to debug the real issue. The analogue view from the LA was incredibly useful.
I’m still actively working on the project, adding new features such as temperature reading and an IMU. After spending a fair bit of time I have realised why the current options are so expensive. There is a large amount of work required just to get accurate GPS data, yet alone all of the other work.