This project is out of date! Please check the new version at: Carberry Info Panel 2.0
Intro
One of Carberry possibilities is to read the car diagnostic values if connected directly to the OBD port. After several researches on different cars we have outlined a table with the OBD standard codes for most car manufacturers. In this way, it is possible to request, through the Carberry daemon, the desired information to lay it out in a software. The available values via OBD are several, such as:
- Water Temp
- Turbo Pressure
- RPM
- Speed
- Air Temperature
- Fuel level
- Oil Temperature
- ...
How we did this
Raspberry Software Limit - QT5 Solution
The first problem in order to draw with Raspberry some gauges was the hardware acceleration, in fact at the moment with none of OS available for Raspberry is possible to get a Desktop Session Hardware Accelerated, that means that all graphic calculations that should be manage by SoC GPU are managed by SoC CPU with an higher resource usage and a worst result. A gauge that moves slowly or lagged is useless... After tons of web searches and tests:
- HTML5 render by browser in desktop
- HTML5 render by kiosk-browser
- Weston Wayland protocol, that allows a desktop accelerated but not to execute (for the moment) a browser
- ....
I found that the UNIQUE solution, for the moment, to allow to an application to use the Raspberry Hardware Acceleration was to use the QT5 programming language.
How to install QT5 on Raspberry
QT5 unfortunately is not available on Raspbian repository, and for this reason must be built manually. There are two ways to do that:
- Cross-Compile configuration: that means use an x86 PC to compile QT5 directly for Raspberry ARM Soc, that's the fastest (just 5-6 hours) solution but, in my opinion, the more complex. Here a guide to do that: https://qt-project.org/wiki/RaspberryPi_Beginners_guide
-
Native Build:
that means use the Raspberry CPU to compile all QT5 source code. That was the solution I used. Here the guide followed by me:
http://qt-project.org/wiki/Native_Build_of_Qt5_on_a_Raspberry_Pi
Pay attention because this process will take at least 30 hours with a Raspberry overclocked to 900Mhz and the Video Memory limited to 16MB.
Remember that Raspbian must be modified in order to work with Carberry, you could do that following this guide: http://www.carberry.it/wiki/carberry:rpi:linux:distrib:raspbian_yourself
How to draw Gauges - QML
After 30 hours we have our Raspberry with QT5 successfully installed and we are ready to create our QT5 application. Now I don't know nothing about QT programming language, I'm a web designer and I know "only": HTML, CSS3, JavaScript, PHP and use a programming language like QT5 that's very similar to C++ it's not so easy. For this reason I decided to use just QML (Qt Meta Language) that has a syntax very close to JavaScript and allows to create simple graphic UI. To create some gauges I used a ready online project: https://github.com/lemirep/QtQuickCarGauges. But some modifications were necessary because the source code renders a canvas bar each time that the needle moves up or down, this feature reduces dramatically the Raspberry performance. So I decided to comment all the parts of the source code related to this canvas render, you could find my ready Project at bottom of this Paragraph. Carberry OBD Info Panel Project draws 5 gauges:
- Speed
- RPM
- Water Temp
- Turbo Pressure
- Fuel Level
Carberry OBD Info Panel Project Download: Carberry - OBD Info Panel - QT Project
How to update gauge value
In order to update the gauge value we need to communicate with the Carberry Socket. I'm not able to communicate with the Carberry Socket directly through QT5 so I used the possibility of QML to integrate also JavaScript in order to execute Ajax calls to a PHP script, written by me, that communicates with the socket and returns a JSON output. To run PHP I installed NGINX + PHP-FPM that reduces at minimum the use of CPU.
In the main.qml
file we can find 2 javascript functions:
function update_speed_rpm_turbo()
{
var action = "update_speed_rpm_turbo";
var doc = new XMLHttpRequest();
var params = "action="+ action +"&method=json";
doc.onreadystatechange = function()
{
if (doc.readyState == XMLHttpRequest.DONE)
{
var obj = JSON.parse(doc.responseText);
speed_value = obj.speed;
rpm_value = parseFloat(obj.rpm);
turbo_value = parseFloat(obj.turbo);
}
}
doc.open("post", url, true);
doc.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
doc.setRequestHeader("Content-Encoding", "UTF-8");
doc.setRequestHeader("Content-length", params.length);
doc.setRequestHeader("Connection", "close");
doc.send(params);
}
function update_water_fuel_voltage()
{
var action = "update_water_fuel_voltage";
var doc = new XMLHttpRequest();
var params = "action="+ action +"&method=json";
doc.onreadystatechange = function()
{
if (doc.readyState == XMLHttpRequest.DONE)
{
var obj = JSON.parse(doc.responseText);
if(obj.water > 50)
{
water_value = obj.water;
}
else
{
water_value = 50;
}
fuel_value = obj.fuel;
voltage_value = parseFloat(obj.voltage);
}
}
doc.open("post", url, true);
doc.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
doc.setRequestHeader("Content-Encoding", "UTF-8");
doc.setRequestHeader("Content-length", params.length);
doc.setRequestHeader("Connection", "close");
doc.send(params);
}
Called by 2 timers that work at different speed:
Timer
{
interval: 100
repeat: true
running: true
onTriggered:
{
parent.update_speed_rpm_turbo();
}
}
The first timer calls the function update_speed_rpm_turbo()
every 100ms because these information must be updated as fast as possible.
The function calls a PHP called ajax_commands.php
that returns a JSON output with the value of SPEED, RPM and TURBO.
Timer
{
interval: 5000
repeat: true
running: true
onTriggered:
{
parent.update_water_fuel_voltage();
}
}
The second timer calls the function update_water_fuel_voltage()
every 5 seconds because are information that don’t require a fast update.
The function calls a PHP called ajax_commands.php
that returns a JSON output with the value of WATER TEMPERATURE and FUEL LEVEL.
How the socket communication works
As previously said the communication between QML and the socket is managed by PHP, that opens a connection to 127.0.0.1
at the port 7070
where the Carberry daemon runs, sends the right command, as described in the wiki
http://www.carberry.it/wiki/carberry:cmds:subsys:obd:query:mode01,
read the value, return the value in JSON format. In this table you find which information could be request to the car and how to format the result:
MODE 01 | |||
---|---|---|---|
PID | INFORMATION | UNIT | FORMULA |
04 | ENGINE USAGE | % | \(\frac{A*100}{255}\) |
05 | ENGINE WATER TEMPERATURE | °C | \(A-40\) |
0B | TUBO PRESSURE | kPa | \(A\) |
0C | RPM | RPM | \(\frac{A*255+B}{4}\) |
0D | SPEED | km/h | \(A\) |
0E | ANTICIPO | ° | \(\frac{A-128}{2}\) |
0F | AIR TEMPERATURE (ENGINE) | °C | \(A-40\) |
11 | THROTTLE POSITION | % | \(\frac{A*100}{255}\) |
2F | FUEL LEVEL | % | \(\frac{A*100}{255}\) |
33 | WHEATHER PRESSURE | kPa | \(A\) |
42 | BATTERY VOLTAGE | V | \(\frac{A*256+B}{1000}\) |
46 | WHEATHER AIR TEMPERATURE | °C | \(A-40\) |
49 | THROTTLE PEDAL | % | \(\frac{A*100}{255}\) |
4A | THROTTLE PEDAL | % | \(\frac{A*100}{255}\) |
The PHP script is available here: Carberry - OBD Info Panel - PHP Script
Compile and Run
To run the QML application we need just to copy the project folder to /home/pi
Enter in the directory
cd /home/pi/Carberry_InfoPanel
Run QMAKE
qmake
Build the application
make
To run the application
./Carberry_InfoPanel
To run the application on boot we need to edit the /etc/rc.local
file
sudo nano /etc/rc.local
Add before exit 0
/home/pi/Carberry_InfoPanel/Carberry_InfoPanel
The PHP script must be placed in the Webserver Document Root (by default) is /var/www
OBD Connections
The OBD connections can be found at this link: http://www.carberry.it/wiki/carberry:hardware:parallel_connection
Downloads
- Carberry OBD Info Panel Ready Image (8GB SD required): Carberry - OBD Info Panel - V1.0
- Carberry OBD Info Panel QT Project: Carberry - OBD Info Panel - QT Project
- Carberry OBD Info Panel PHP Script: Carberry - OBD Info Panel - PHP Script
For more information visit the dedicated topic in our forum.