For car enthusiasts and DIY mechanics, understanding your vehicle’s performance in real-time is invaluable. By leveraging Bluetooth Obd2 Android Torque Obdii technology, you can transform your Android device into a powerful diagnostic tool and live data dashboard. This guide will walk you through setting up a system to monitor your car’s data using these tools, pushing the boundaries of automotive insight.
What You Need to Get Started
Before diving in, ensure you have the following components ready:
- OBD2 Bluetooth Adapter: This is the hardware interface that plugs into your car’s OBDII port and wirelessly transmits data. Ensure it’s compatible with Android devices.
- Android Device: Your smartphone or tablet will host the Torque Pro app and display the real-time data.
- Torque Pro App: A popular and feature-rich Android app that reads data from the OBD2 adapter.
- Node-RED Server (Optional but Recommended): Node-RED is a flow-based programming tool that allows you to process and visualize the data received from Torque, and even integrate it with other systems. While optional for basic data viewing in Torque, it significantly expands the system’s capabilities for logging and advanced monitoring.
- MySQL Database (Optional): If you want to log and store your vehicle’s data for historical analysis, a MySQL database can be integrated using Node-RED.
Setting Up Torque Pro for Data Logging and Web Server Upload
The first step is configuring the Torque Pro app to collect and transmit the data.
- Connect OBD2 Adapter: Plug your Bluetooth OBD2 adapter into your car’s OBDII port. Typically located under the dashboard on the driver’s side.
- Pair Bluetooth: Pair the OBD2 adapter with your Android device via Bluetooth settings.
- Configure Torque Pro:
- Open the Torque Pro app and go to Settings.
- Navigate to Data Logging and Upload.
- Select what to log: Choose “All PIDs” or customize by selecting specific PIDs (Parameter IDs) you want to monitor, such as RPM, speed, coolant temperature, etc. Selecting specific PIDs can optimize data transmission if you have particular parameters in mind.
- Upload to web server: Check this option to enable data transmission to a web server.
- Webserver URL: Enter the URL of your Node-RED server endpoint. If your Node-RED server is running on
your.nodered.server
at port1880
and you want to use the endpoint/torque
, the URL will be:http://your.nodered.server:1880/torque/
.
Node-RED Flow for Receiving and Processing OBD2 Data
Now, let’s set up the Node-RED flow to receive data from Torque Pro. Below is a sample flow configuration you can import into Node-RED. This flow is designed to:
- Receive HTTP GET requests from Torque Pro.
- Send an “OK!” response to Torque Pro to acknowledge data reception.
- Extract and process specific data points (PIDs) from the payload.
- Optionally store the raw JSON data and individual parameters in an MQTT broker or MySQL database.
- Display real-time gauges on a Node-RED dashboard.
[
{ "id": "2ce0055.8743efa", "type": "tab", "label": "Torque", "disabled": false, "info": "" },
{ "id": "67436221.b54c0c", "type": "http in", "z": "2ce0055.8743efa", "name": "", "url": "/torque", "method": "get", "upload": true, "swaggerDoc": "", "x": 221, "y": 143, "wires": [ [ "f98f22cc.807ba", "557d7766.022168", "33d571b3.db242e", "69b56cf.77bc694", "683933fa.d76f1c", "ab2ff853.e8b808", "c005b8b1.f06b98", "96abaa53.c70988", "ee5bc723.594bf8", "dfdc4763.7a8fd8", "cee9fa09.98b6d8", "f2d748c5.d92da8", "936bc33f.bcd27", "97ab65f2.1a0728" ] ] },
{ "id": "f98f22cc.807ba", "type": "http response", "z": "2ce0055.8743efa", "name": "", "statusCode": "", "headers": { "OK!": "" }, "x": 1290, "y": 140, "wires": [] },
{ "id": "557d7766.022168", "type": "change", "z": "2ce0055.8743efa", "name": "Barometer", "rules": [ { "t": "move", "p": "payload.kff1270", "pt": "msg", "to": "payload", "tot": "msg" }, { "t": "set", "p": "topic", "pt": "msg", "to": "torque\phone\barometer", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 731, "y": 403, "wires": [ [ "536ae3f0.1980dc", "5ef6a21e.75ce4c" ] ] },
{ "id": "3b30fefa.3f9012", "type": "ui_gauge", "z": "2ce0055.8743efa", "name": "", "group": "9b558fbc.438aa", "order": 1, "width": "6", "height": "6", "gtype": "gage", "title": "RPM", "label": "RPM", "format": "{{value}}", "min": 0, "max": "7000", "colors": [ "#00b500", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1061, "y": 443, "wires": [] },
{ "id": "33d571b3.db242e", "type": "change", "z": "2ce0055.8743efa", "name": "RPM", "rules": [ { "t": "move", "p": "payload.kc", "pt": "msg", "to": "payload", "tot": "msg" }, { "t": "set", "p": "topic", "pt": "msg", "to": "torque\vehicle\rpm", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 721, "y": 443, "wires": [ [ "3b30fefa.3f9012", "5ef6a21e.75ce4c" ] ] },
{ "id": "69b56cf.77bc694", "type": "change", "z": "2ce0055.8743efa", "name": "Mass Air Flow Rate", "rules": [ { "t": "move", "p": "payload.k10", "pt": "msg", "to": "payload", "tot": "msg" }, { "t": "set", "p": "topic", "pt": "msg", "to": "torque\vehicle\mafrate", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 761, "y": 483, "wires": [ [ "7ee21162.28cdb", "5ef6a21e.75ce4c" ] ] },
{ "id": "683933fa.d76f1c", "type": "change", "z": "2ce0055.8743efa", "name": "Throttle Position", "rules": [ { "t": "move", "p": "payload.k11", "pt": "msg", "to": "payload", "tot": "msg" }, { "t": "set", "p": "topic", "pt": "msg", "to": "torque\vehicle\throttle", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 751, "y": 523, "wires": [ [ "3765c6b.fb70f3a", "5ef6a21e.75ce4c" ] ] },
{ "id": "ab2ff853.e8b808", "type": "change", "z": "2ce0055.8743efa", "name": "Coolant Temp", "rules": [ { "t": "move", "p": "payload.k5", "pt": "msg", "to": "payload", "tot": "msg" }, { "t": "set", "p": "topic", "pt": "msg", "to": "torque\vehicle\coolant", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 741, "y": 563, "wires": [ [ "258b6f62.e82ab" ] ] },
{ "id": "c005b8b1.f06b98", "type": "change", "z": "2ce0055.8743efa", "name": "Volage", "rules": [ { "t": "move", "p": "payload.kff1238", "pt": "msg", "to": "payload", "tot": "msg" }, { "t": "set", "p": "topic", "pt": "msg", "to": "torque\obd\voltage", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 721, "y": 603, "wires": [ [ "5b8bdb33.d96134", "5ef6a21e.75ce4c" ] ] },
{ "id": "96abaa53.c70988", "type": "change", "z": "2ce0055.8743efa", "name": "Vacuum", "rules": [ { "t": "move", "p": "payload.kff1202", "pt": "msg", "to": "payload", "tot": "msg" }, { "t": "set", "p": "topic", "pt": "msg", "to": "torque\vehicle\vacuum", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 731, "y": 643, "wires": [ [ "913a6311.540cd", "5ef6a21e.75ce4c" ] ] },
{ "id": "3765c6b.fb70f3a", "type": "ui_gauge", "z": "2ce0055.8743efa", "name": "", "group": "9b558fbc.438aa", "order": 2, "width": "3", "height": "3", "gtype": "donut", "title": "Throttle Position", "label": "%", "format": "{{value}}", "min": 0, "max": "100", "colors": [ "#00b500", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1091, "y": 523, "wires": [] },
{ "id": "ee5bc723.594bf8", "type": "change", "z": "2ce0055.8743efa", "name": "Speed", "rules": [ { "t": "move", "p": "payload.kd", "pt": "msg", "to": "payload", "tot": "msg" }, { "t": "set", "p": "topic", "pt": "msg", "to": "torque\vehicle\speed", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 721, "y": 683, "wires": [ [ "c3863c64.b8c2d", "5ef6a21e.75ce4c" ] ] },
{ "id": "c3863c64.b8c2d", "type": "ui_gauge", "z": "2ce0055.8743efa", "name": "", "group": "ea9cdc42.4bbc8", "order": 0, "width": 0, "height": 0, "gtype": "gage", "title": "Speed", "label": "MPH", "format": "{{value}}", "min": 0, "max": "100", "colors": [ "#00b500", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1061, "y": 683, "wires": [] },
{ "id": "7ee21162.28cdb", "type": "ui_gauge", "z": "2ce0055.8743efa", "name": "", "group": "9b558fbc.438aa", "order": 3, "width": "2", "height": "3", "gtype": "wave", "title": "Mass Air Flow", "label": "g/s", "format": "{{value}}", "min": 0, "max": "100", "colors": [ "#00b500", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1091, "y": 483, "wires": [] },
{ "id": "536ae3f0.1980dc", "type": "ui_gauge", "z": "2ce0055.8743efa", "name": "", "group": "26a930d9.ff8c", "order": 0, "width": "3", "height": "3", "gtype": "gage", "title": "Barometer", "label": "units", "format": "{{value}}", "min": "800", "max": "1100", "colors": [ "#00b500", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1071, "y": 403, "wires": [] },
{ "id": "dfdc4763.7a8fd8", "type": "change", "z": "2ce0055.7a8fd8", "name": "Speed GPS", "rules": [ { "t": "move", "p": "payload.kff1001", "pt": "msg", "to": "payload", "tot": "msg" }, { "t": "set", "p": "topic", "pt": "msg", "to": "torque\phone\speed", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 741, "y": 723, "wires": [ [ "535662ad.f1628c", "5ef6a21e.75ce4c" ] ] },
{ "id": "535662ad.f1628c", "type": "ui_gauge", "z": "2ce0055.8743efa", "name": "", "group": "26a930d9.ff8c", "order": 0, "width": "3", "height": "3", "gtype": "gage", "title": "Speed GPS", "label": "MPH", "format": "{{value}}", "min": 0, "max": "100", "colors": [ "#00b500", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1081, "y": 723, "wires": [] },
{ "id": "5b8bdb33.d96134", "type": "ui_gauge", "z": "2ce0055.8743efa", "name": "", "group": "ea9cdc42.4bbc8", "order": 0, "width": "3", "height": "3", "gtype": "gage", "title": "Voltage", "label": "V", "format": "{{value}}", "min": "9", "max": "15", "colors": [ "#ff0000", "#008000", "#ff0000" ], "seg1": "13", "seg2": "14.3", "x": 1071, "y": 603, "wires": [] },
{ "id": "b0123228.4a063", "type": "ui_gauge", "z": "2ce0055.8743efa", "name": "", "group": "9b558fbc.438aa", "order": 5, "width": "3", "height": "3", "gtype": "gage", "title": "Coolant Temp", "label": "F", "format": "{{value}}", "min": 0, "max": "250", "colors": [ "#00b500", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1081, "y": 563, "wires": [] },
{ "id": "913a6311.540cd", "type": "ui_gauge", "z": "2ce0055.8743efa", "name": "", "group": "9b558fbc.438aa", "order": 6, "width": "3", "height": "3", "gtype": "donut", "title": "Vacuum", "label": "", "format": "{{value}}", "min": "-20", "max": "0", "colors": [ "#00b500", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1071, "y": 643, "wires": [] },
{ "id": "cee9fa09.98b6d8", "type": "json", "z": "2ce0055.8743efa", "name": "", "pretty": false, "x": 751, "y": 198, "wires": [ [ "3b9be5d8.84e04a" ] ] },
{ "id": "f2d748c5.d92da8", "type": "function", "z": "2ce0055.8743efa", "name": "Parse Date", "func": "var date = parseInt(msg.payload.time);nnmsg.payload = new Date(date* 1).toLocaleString([], { hour12: true}).slice(0, 19).replace('T', ' ');nreturn msg;", "outputs": 1, "noerr": 0, "x": 730, "y": 780, "wires": [ [ "88bfc628.5727b8" ] ] },
{ "id": "88bfc628.5727b8", "type": "ui_text", "z": "2ce0055.8743efa", "group": "26a930d9.ff8c", "order": 1, "width": 0, "height": 0, "name": "Last Update", "label": "Updated", "format": "{{msg.payload}}", "layout": "row-spread", "x": 1070, "y": 780, "wires": [] },
{ "id": "258b6f62.e82ab", "type": "function", "z": "2ce0055.8743efa", "name": "CtoF", "func": "var tempc = msg.payload;n tempf = tempc * 9/5 + 32;n tempf = Math.round(tempf * 10) / 10;n msg.payload = tempf;n return msg;", "outputs": 1, "noerr": 0, "x": 910, "y": 560, "wires": [ [ "b0123228.4a063", "5ef6a21e.75ce4c" ] ] },
{ "id": "936bc33f.bcd27", "type": "change", "z": "2ce0055.8743efa", "name": "IntakeTemp", "rules": [ { "t": "move", "p": "payload.kf", "pt": "msg", "to": "payload", "tot": "msg" }, { "t": "set", "p": "topic", "pt": "msg", "to": "torque\vehicle\intake", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 730, "y": 840, "wires": [ [ "a6732e91.735a9" ] ] },
{ "id": "ee354102.4a8d8", "type": "ui_gauge", "z": "2ce0055.8743efa", "name": "", "group": "9b558fbc.438aa", "order": 4, "width": "3", "height": "3", "gtype": "gage", "title": "Intake Temp", "label": "F", "format": "{{value}}", "min": 0, "max": "250", "colors": [ "#00b500", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1070, "y": 840, "wires": [] },
{ "id": "a6732e91.735a9", "type": "function", "z": "2ce0055.8743efa", "name": "CtoF", "func": "var tempc = msg.payload;n tempf = tempc * 9/5 + 32;n tempf = Math.round(tempf * 10) / 10;n msg.payload = tempf;n return msg;", "outputs": 1, "noerr": 0, "x": 899, "y": 837, "wires": [ [ "ee354102.4a8d8", "5ef6a21e.75ce4c" ] ] },
{ "id": "3b9be5d8.84e04a", "type": "change", "z": "2ce0055.8743efa", "name": "", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "torque\raw", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1034, "y": 202, "wires": [ [ "5ef6a21e.75ce4c" ] ] },
{ "id": "5ef6a21e.75ce4c", "type": "mqtt out", "z": "2ce0055.8743efa", "name": "", "topic": "", "qos": "0", "retain": "true", "broker": "fee1fac2.261a88", "x": 1292, "y": 193, "wires": [] },
{ "id": "97ab65f2.1a0728", "type": "function", "z": "2ce0055.1a0728", "name": "copy to json", "func": "msg.payload.json = JSON.stringify(msg.payload);nreturn msg;", "outputs": 1, "noerr": 0, "x": 770, "y": 100, "wires": [ [ "72347975.0e2688" ] ] },
{ "id": "72347975.0e2688", "type": "function", "z": "2ce0055.8743efa", "name": "Create query in topic", "func": "var out = "INSERT INTO torque_json (timestamp,json)"nvar date = Number(msg.payload.time);nout = out + "VALUES ('" + new Date(date* 1).toISOString().slice(0, 19).replace('T', ' ') + "','" nout = out + String(msg.payload.json) + "');"n nmsg.topic=out;nnreturn msg;", "outputs": 1, "noerr": 0, "x": 960, "y": 100, "wires": [ [ "dba0040d.49d798" ] ] },
{ "id": "dba0040d.49d798", "type": "mysql", "z": "2ce0055.8743efa", "mydb": "4cd2c8.ee368d38", "name": "", "x": 1300, "y": 100, "wires": [ [] ] },
{ "id": "9b558fbc.438aa", "type": "ui_group", "z": "", "name": "Motor", "tab": "ac99e377.fdb83", "order": 1, "disp": true, "width": "9" },
{ "id": "ea9cdc42.4bbc8", "type": "ui_group", "z": "", "name": "Van", "tab": "ac99e377.fdb83", "order": 2, "disp": true, "width": "6" },
{ "id": "26a930d9.ff8c", "type": "ui_group", "z": "", "name": "Phone", "tab": "ac99e377.fdb83", "order": 3, "disp": true, "width": "6" },
{ "id": "fee1fac2.261a88", "type": "mqtt-broker", "z": "", "broker": "mqtt.YOUR.SERVER", "port": "1883", "clientid": "nodered", "usetls": false, "compatmode": true, "keepalive": "60", "cleansession": true, "willTopic": "", "willQos": "0", "willPayload": "", "birthTopic": "", "birthQos": "0", "birthPayload": "" },
{ "id": "4cd2c8.ee368d38", "type": "MySQLdatabase", "z": "", "host": "drobo5n.YOUR.SERVER", "port": "3306", "db": "openhab", "tz": "CST" },
{ "id": "ac99e377.fdb83", "type": "ui_tab", "z": "", "name": "Torque", "icon": "fa-car", "order": 2 }
]
Understanding the Node-RED Flow
- HTTP In Node (
http in
): This node, with the ID"67436221.b54c0c"
, is configured to receive HTTP GET requests at the/torque
endpoint. Torque Pro will send data to this URL. - HTTP Response Node (
http response
): The node"f98f22cc.807ba"
immediately responds to Torque Pro with an “OK!” message. This is crucial because Torque Pro expects a response to confirm successful data upload. - Change Nodes (
change
): Nodes like"557d7766.022168"
,"33d571b3.db242e"
, etc., are used to extract specific PIDs from themsg.payload
. For example,"557d7766.022168"
extracts the Barometer reading (payload.kff1270
) and sets themsg.topic
for further processing. - Gauge Nodes (
ui_gauge
): Nodes like"3b30fefa.3f9012"
,"3765c6b.fb70f3a"
, etc., are dashboard gauge widgets to visualize the real-time data. They are grouped under UI groups like “Motor”, “Van”, and “Phone” for organized display. - Function Nodes (
function
):"f2d748c5.d92da8"
(Parse Date): Converts the timestamp from Torque into a readable date and time format."258b6f62.e82ab"
&"a6732e91.735a9"
(CtoF): Converts Celsius temperatures to Fahrenheit for Coolant Temp and Intake Temp respectively."97ab65f2.1a0728"
(copy to json): Converts the entiremsg.payload
to a JSON string."72347975.0e2688"
(Create query in topic): Constructs a MySQL INSERT query to store the JSON data in a database.
- JSON Node (
json
): Node"cee9fa09.98b6d8"
parses the incoming payload as JSON. - MQTT Out Node (
mqtt out
): Node"5ef6a21e.75ce4c"
publishes processed data to an MQTT broker. This is useful for integrating the data with other home automation or monitoring systems. - MySQL Node (
mysql
): Node"dba0040d.49d798"
inserts data into a MySQL database. Note: You need to configure the MySQL database connection details in the Node-RED settings (MySQLdatabase
configuration"4cd2c8.ee368d38"
).
Alt text: Node-RED flow diagram illustrating the process of receiving, processing, and displaying data from a Bluetooth OBD2 Android Torque OBDII setup, showing nodes for HTTP input, data parsing, gauge displays, and database integration.
Setting up the Node-RED Flow
- Import the Flow: In your Node-RED dashboard, go to the menu, select “Import,” and paste the JSON code provided above.
- Configure MQTT Broker (Optional): If you want to use MQTT, configure the MQTT broker node (
"fee1fac2.261a88"
) with your MQTT server details. - Configure MySQL Database (Optional): If you want to log data to MySQL, configure the MySQL database node (
"dba0040d.49d798"
) with your database credentials and ensure theMySQLdatabase
configuration ("4cd2c8.ee368d38"
) is correctly set up. - Deploy the Flow: Click the “Deploy” button in Node-RED to activate the flow.
- Access the Dashboard: Access your Node-RED dashboard to view the real-time gauges displaying your vehicle’s data. The dashboard tab is labeled “Torque”.
Optional MySQL Database Integration for Data Logging
If you chose to include MySQL integration, ensure you have:
- MySQL Server Running: You need a MySQL server instance accessible to your Node-RED server.
- Database and Table Created: Create a database (e.g.,
openhab
) and a table (e.g.,torque_json
) with appropriate columns. The provided flow is set up to insert data into a table namedtorque_json
with columnstimestamp
andjson
.
The “Create query in topic” function node in the flow generates the necessary SQL INSERT statements.
Benefits of Using Bluetooth OBD2 Android Torque and Node-RED
- Real-time Vehicle Monitoring: View live data from your car’s sensors on a customizable dashboard.
- Data Logging and Analysis: Record vehicle data for later analysis, performance tracking, and diagnostics.
- Customizable Dashboards: Create personalized dashboards in Node-RED to display the parameters most relevant to you.
- Integration with Other Systems: Use MQTT to integrate vehicle data with home automation platforms or other monitoring systems.
- Enhanced Vehicle Diagnostics: Go beyond basic OBD2 code reading and understand the nuances of your vehicle’s operation.
Conclusion
By combining Bluetooth OBD2 Android Torque OBDII tools with the flexibility of Node-RED, you create a powerful system for vehicle diagnostics and monitoring. Whether you’re a car enthusiast, a DIY mechanic, or someone interested in vehicle data analysis, this setup provides valuable insights and opens up a world of possibilities for understanding your car’s performance. Start exploring and unlock the data your car has to offer!