I have been very busy working on this project since the last update, and I think I have something worthwhile to show now. During that time I have gotten bluetooth to work, rebuilt the display module, and done a ton of programming. I guess I will get started with explaining bluetooth first.
I ordered a new Raspberry Pi A+ to use for this project. It was needed because of its smaller and improved form-factor, and because of the many new GPIO pins it exposes. The latter is very important. In order to get audio to the FM transmitter, I can either run a short cable from the pi's audio output to the transmitter, or try to get audio out the GPIO header. Going the cable route takes up more space, increases complexity (another cable), and increases price. After doing a bit of research, I discovered that you can redirect the GPIO pins that the PI uses for audio to other select pins by messing with the Device Tree. However, the old Raspberry Pi B I have only exposes one of those valid pins, leaving me with only mono audio. Fortunately, the Raspberry Pis with the revised pin header exposes both pins needed for stereo audio.
With that out of the way, my next task was getting Bluetooth working. Only attempt this is you enjoy being in pain, and dreaming about bluetooth hell (which is a real place). Many guides for making it work exist, and while they worked, the results were not up to my standards. I wanted better sound quality, less latency, and better automation. I don't want to have to get my phone out and connect it to the Pi whenever I get in my car, or reconnect it if it disconnects by itself for whatever reason. What kind of manual loser do you take me for? So now begins the process of changing settings until results change/improve, image the sd card, screw it up somehow, reimage the sd card, find that something stopped working for no reason, start over, and repeat until you start screaming. After I have all but given up on decent quality automatic bluetooth, I find that the versions of bluez and pulseaudio provided by apt-get are severely out of date and missing many features that I need. Soon after, I find this forum thread and follow its instructions as a last-ditch attempt to make it work. It worked perfectly. Not longer after, I get an auto connection script going that forces the phone to connect whenever it's in range.
With that problem solved, my next task was rebuilding the display module. I decided to go with one of the 14 pin ATTinys as the primary microcontroller for the display module, either an ATTiny84 or 44. It's small, cheap, and easy to work with. I got it to handle button inputs, led brightness control, light sensor input, LCD control, and communicate with the Pi. However, it was not originally going to do all of that. Since the LCD can be controlled over i2c, I figured I would be able to make the Pi control it directly, and turn the ATTiny into an i2c slave. Of course it's never that easy. The LCD would refuse to talk to the Pi if it was alone, and would try to take the QN8027 down with it if it was connected at the same time. My makeshift logic analyzer has shown that it was trying to respond to the Pi's requests, but I could not determine why it was not working. After more screaming and attempts to make it work, I scrapped that idea and gave the LCD control job to the ATTiny instead. It works there somehow, so I won't complain. I am left with using serial for bidirectional communication between the Pi and the display module. And like always, there was a problem with that. The only small bidirectional serial library for the ATTiny which didn't require a crystal that I could find, was more or less broken. After some more sacrifices to satan, I found a fork of it which did work, so that's nice.
Eventually I somehow managed to get the whole program size down to less than 4096 bytes, allowing me to use the cheaper ATTiny44. I was able to accomplish that by stripping down the already stripped down serial library, making the Pi handle everything LCD related (except for very low level stuff), and enter the scary world that is Port Manipulation. It's no where near as pretty as using digitalWrite or analogRead, but it uses significantly less space. The display module is essentially a glorified GPIO expander now, but it works.
Next I had to integrate the display module with the pi, which means writing all the code for the Pi side. This was mostly straightforward, even though I did have to relearn Python. The video below shows a small part of what I have accomplished so far. There is no music playing because I did not take the time to set up my radio for some reason.
My next tasks include programming the rest of the code on the Pi, adding OBD2 functionality, finishing up the power supply, testing, and PCB design.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.