Ein per Stecker mit dem CAN-Bus und der Stromversorgung des Fahrzeuges verbundenes Gehäuse schützt alle verwendeten Hardware-Komponenten vor Wasser und Staub. Beim Einschalten des RasPi muss dieser selbstständig alle Programme laden und mit der Datenaufzeichnung in der Datenbank beginnen – er kommt im Fahrzeug ja ohne Tastatur und Monitor zum Einsatz.
Jr_candump
Das Startskript aus Listing 6 nimmt beim Hochfahren des RasPi alle notwendigen Schritte vor. Die erste Zeile des Skripts aktiviert die Netzwerkschnittstelle des CAN-Adapters. Anschließend startet das modifizierte Candump-Programm jr_candump mit den dazugehörigen Parametern.
Listing 6
ifconfig can0 up /home/pi/can-utils/jr_candump can0 -D &
Dieses Programm wurde so abgeändert, dass sich die empfangenen Daten über die neue Option -D in eine Datenbank [6] schreiben lassen. Nach dem Programmstart erstellt Jr_candump eine Datenbank, legt in dieser mit dem SQL-Statement aus Zeile 1 von Listing 7 eine Tabelle an und bereitet dann das SQL-Statement aus Zeile 2 für das Speichern der Daten vor.
Listing 7
CREATE TABLE if not exists candata(ID float, TIMESTAMP float, YAWRATE varchar(4), ACCY varchar(4), ROLLRATE varchar(4), ACCX varchar(4), ACCZ varchar(4), FUELTEMP varchar(4), WATERTEMP varchar(4), OILPRESSURE varchar(4), OILTEMP varchar(4)) ENGINE = MEMORY INSERT INTO candata (ID, TIMESTAMP, YAWRATE, ACCY, ROLLRATE, ACCX, ACCZ, FUELTEMP, WATERTEMP, OILPRESSURE, OILTEMP) VALUES (?,?,?,?,?,?,?,?,?,?,?)
Wie der Schluss von Zeile 1 zeigt, liegt die Datenbank im Hauptspeicher des RasPi: Für das direkte Speichern auf der SD-Card laufen die Daten zu schnell ein. Abschließend verknüpft Jr_candump die richtigen Variablen mit den entsprechenden Platzhaltern im INSERT-Statement aus Zeile 2. Nach dem Vorbereiten der Datenbank ruft Jr_candump bei jedem Empfang einer CAN-Nachricht eine Funktion zu deren Auswerten auf – den Kernteil davon sehen Sie in Listing 8.
Listing 8
switch (frame.can_id) {
case 0x713:
sprintf(fueltemp, "%02x", frame.data[4]);
sprintf(watertemp, "%02x", frame.data[7]);
sprintf(oilpressure, "%02x", frame.data[0]);
sprintf(oiltemp, "%02x", frame.data[5]);
InsertCANframe();
break;
/* nächste CAN-ID ... */
}
Die Auswerteroutine unterscheidet über eine Switch-Anweisung die CAN-ID der eingehenden Nachricht und schreibt entsprechend die aktuell empfangenen Daten in die richtigen Variablen. Es folgt ein Aufruf der Funktion InsertCANframe(). Diese erhöht den Zähler der ID, welche die einzelnen Datensätze der Datenbank nummeriert, und schreibt die Werte der Variablen mit dem zuvor vorbereiteten Statement in die Datenbank.
Visualisierung der Daten
Auf dem RasPi läuft ein Apache-Webserver, der mit einer kleinen PHP-Anwendung die Daten aus der Datenbank ausliest und online darstellt. Die Daten werden dabei mit Ajax ständig aktualisiert und mittels des jQuery-Frameworks [7] jqPlot [8] visualisiert (Abbildung 6). Das Team an der Box erhält damit online Zugriff auf alle relevanten Parameter.
Das Laden der Messwerte aus der Datenbank übernimmt ein per Ajax in Abständen von drei Sekunden aufgerufenes PHP-Skript, das die Daten in Form einer JSON-Datei übergibt. Eine etwas gekürzte Version dieses Skripts zeigt Listing 9. Wie Sie dort sehen, übergibt der Code bei jedem Aufruf des Skripts die letzte bereits empfangene ID ($maxID), um nur die neuen Daten abzufragen.
Listing 9
<?php
$maxID = $_GET["maxID"];
$mysqlhost="localhost";
$mysqluser="user";
$mysqlpwd="****";
$mysqldb="jr_data";
$connection=mysql_connect($mysqlhost, $mysqluser, $mysqlpwd);
mysql_select_db($mysqldb, $connection);
$sql="SELECT * FROM candata WHERE ID > ".$maxID;
$result = mysql_query($sql);
$cnt = 0;
while ($row = mysql_fetch_object($result)) {
$ID[$cnt] = $row->ID;
$TIMEST[$cnt] = $row->TIMESTAMP;
$FUELTEMP[$cnt] = hexdec($row->FUELTEMP);
$WATERTEMP[$cnt] = hexdec($row->WATERTEMP);
$OILPRESSURE[$cnt] = hexdec($row->OILPRESSURE);
$OILTEMP[$cnt] = hexdec($row->OILTEMP);
$cnt++;
}
$result = array(
"NEWid" => $ID,
"NEWtime" => $TIMEST,
"NEWfueltemp" => $FUELTEMP,
"NEWwatertemp" => $WATERTEMP,
"NEWoilpressure" => $OILPRESSURE,
"NEWoiltemp" => $OILTEMP
);
print(trim(json_encode($result)));
?>
Als Ergebnis erscheinen die aktuellen Daten mit drei bis fünf Sekunden Verzögerung auf der Webseite. Dabei bietet jqPlot sehr umfangreiche Möglichkeiten – ein sehr einfaches Beispiel für das Darstellen eines Javascript-Arrays zeigen Listing 10 und Abbildung 7.
Listing 10
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Öltemperatur-Plot</title>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.jqplot.min.js"></script>
<link rel="stylesheet" type="text/css" href="jquery.jqplot.css" />
</head>
<body>
<div id="chartdiv" style="height:200px;width:500px; "></div>
<script type="text/javascript">
var oeltemperatur = new Array(50,53,55,50,52,60,60,50,53,50);
$.jqplot('chartdiv', [oeltemperatur], {
axes:{
xaxis:{
label:'Zeit'
},
yaxis:{
label:'Öltemperatur'
}
}
});
</script>
</body>
</html>
Erweiterungen
Neben dem Auslesen und Auswerten von Fahrzeugdaten über den CAN-Bus übernimmt der RasPi im Rennwagen noch weitere Aufgaben: So bindet er beispielsweise eine WLAN-fähige, im Fahrzeug montierte Action-Cam ans Internet an (Details siehe Kasten “Live-Video”). Damit kann das Boxen-Team das Rennen auch aus der Sicht des Fahrers live mitverfolgen.







