As part of my project trying to do a DIY (Android-based) in-car screen system I’ve decided to use Arduino as the halfway house between hard buttons, info from the car (like its being in reverse) and whatever sensors, and the Raspberry Pi running Emteria OS. I’ve written an Android app and accompanying project for Arduino – they on GitHub.
The GitHub Repos
- The Android One here. IMPORTANT NOTE: Because I delve into system USB permissions, this app needs installed as a system app. This is quite a protracted procedure to set up (though easy when done successfully the first time).
- The Arduino One here. I used Visual Studio and the Visual Micro plugin for writing the Arduino app, so the GitHub is in the form of a Visual Studio project – but easy to move over to Arduino IDE.
I used a single analog pin to detect presses from the 5 old hard button (MENU, INFO, MAP, MEDIA & A/V) in the centre-dash – just because I liked it. By closing the various buttons you change the reading on the analog pin by changing the resistance of the circuit. It does mean that the resistance values are dependant on what resistors you use (or have handy in my case). I did not do the Ohms law math for mine – I used a multimeter. The circuit below and some code examples are on this stack exchange post.
When the car put into reverse, pin 9 on the car harness goes high (to 12V). I used a voltage divider to drop this to 5V as to not fry the Arduino. This is connected to an analog pin. Just google voltage divider.
I also stuck DHT11 temperature-humidity sensor. This connects to a digital pin (and +5, GND too). I googled ‘Where is the external temperature sensor in most cars?‘. Answer: various. But in the wing mirror seems a good bet, or down near the front somewhere. This article was explaining that the sensors don’t ‘suffer’ from wind chill…in fact, air molecule hitting the sensor would actually make the temperature too high (<<1 degree). Humidity will be affected by air movement around the sensor.
USB Serial and my Newly-Coined Protocol, HDP
I had a spare Arduino Leonardo, which does not support USB hosting. I found this library where you just communicate over USB using serial comms (i.e. you ‘send’ using
turns up at the other end of the USB cable for you to parse ;).
I invented my own protocol, which I am naming Honey Doughnut Protocol (HDP), after my dog:
- Its one way from the Arduino to Android. To deal with not send properly & not received properly messages, I just sent them a couple of times and deal with quickly-repeated-but-the-same-messages-actually the-same-message on the Android side.
- To send you just use1Serial.print()
… the new line means nothing on the Android end (unless you tell it otherwise!). Before realising this I spent a bit of time scratching my head.
- End-of-message is the character1#
. That’s it 🙂
- Single characters are button presses (e.g.1m
is map button), or1f
for forward and1r
for reverse on the gear-stick.
- The temp-humidity data is set as1t25h85
This is all taken care of by the inaccurately named
<a id="13cb318f94b0ae36b1ca0d05802bbe37-57f0c4c4070c35552b9eccb696afe6a950656f75" class="js-navigation-open" title="BackgroundUsbSerialService.java" href="https://github.com/aegis1980/Subaru_android/blob/master/app/src/main/java/com/fitc/com/subaru/BackgroundUsbSerialService.java">BackgroundUsbSerialService</a>
– inaccurate as it runs as a foreground service. The service sticks all incoming data in a queue data structure and parses it the ‘message-by-message’ (i.e
MainActivity lets the user set what hard button starts what app, (e.g. pressing ‘Map’ starts Google Maps). Also, the user can select with USB camera app starts when the car goes into reverse.
There are a couple more things I rolled into the app:
- USB permissions. The app needs to be installed as a system app. When the Android device boots the app used this system access to allow USB device permissions to the Arduino, but also the USB camera and BTSSM which I am using for ECU data (with USB OBD2 wire). This means that the USB devices are just ‘connected’ straight off and also the user is not presented with the permissions dialog. At some point I’ll stick how I did this in a post.
- A home screen widget that shows the temp and humidity – it’s updated every time that info comes in from the DHT11 on the Arduino.
I could have left out the Arduino and used the GPIO pins on the Raspi. The stock ‘full version’ Android SDK doesn’t have anything to let you get at these easily, of course, Google Things does though: I am sure someone much brighter than me could get the one going on the other.
SDK-apart, I don’t think it’s actually too difficult to get at the GPIOs as you would in Linux – some Java code around this would be pretty easy.
Actually, post-rationalising has made me wonder if the Raspi GPIO route was the way to go. Introducing the Arduino means I’ve had to code that as well, and make Android and Arduino play together. Also, I can update software on the Android via ADB over wi-fi, but actually have to hard-wire the Arduino to update that (though I am looking at ways to update code on Arduino via Android).
The advantage of using the Arduino is that its a microcontroller, so just better suited to the task (I read that somewhere), and it has analog pins.
Anyhow – next time!