Had a bit of a mission set out for myself to get QD3 logging directly to my dyno.
Bits of info were scattered every where so thought id make a post with it all in 1 place.
Here is what I came up with for processing QD3 serial string.
Use it how youd like.
Code:
using System;
using System.Collections;
using System.Windows.Forms;
namespace QD3_processor
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//String to test
byte[] byteData =
{
0X46, 0X26, 0Xc7, 0X05, 0X05, 0Xed, 0X00, 0X5d, 0X02, 0X74, 0X08, 0X48, 0X00, 0X80, 0Xb1, 0X22, 0X57, 0X0a, 0X49, 0X46, 0X00, 0X93, 0X23, 0X25, 0X22, 0X7c, 0X00, 0Xff, 0Xff, 0X00, 0X93, 0Xa9, 0Xa2, 0X72, 0Xbc, 0X02, 0XA8, 0XA0, 0X00, 0X00, 0X5D
// 0X46, 0X26, 0X5f, 0X08, 0X02, 0Xed, 0X01, 0X80, 0X08, 0X74, 0X00, 0X65, 0X00, 0X80, 0Xf5, 0X25, 0X57, 0X0a, 0X49, 0X46, 0X00, 0X8f, 0X3f, 0X2b, 0X29, 0X7b, 0X00, 0Xff, 0Xff, 0X00, 0X8f, 0Xa9, 0Xa2, 0X75, 0Xfc, 0X02, 0X00, 0X00, 0X00, 0X00, 0X96
};
//Calls decode of QD3 data stream.
QD3Decode(byteData);
}
private void QD3Decode(byte[] byteData)
{
byte rpmLowRaw = byteData[2]; // Low Byte of RPM
byte rpmHighRaw = byteData[3]; // High Byte of RPM
byte ignRaw = byteData[9]; // Ignition Timing Raw
byte o2Raw = byteData[11]; // Oxygen Sensor Byte
byte vtecRaw = byteData[19]; // Vtec Engaged Yes/No
byte vssRaw = byteData[20]; // Vehicle Speed Sensor Byte
byte batteryRaw = byteData[21]; // Battery Byte
float mapRaw = byteData[22]; // Map Sensor Byte
byte tpsRaw = byteData[24]; // Throttle Position Sensor Byte
byte iatRaw = byteData[25]; // Intake Air Temp Byte
byte ectRaw = byteData[33]; // Engine Coolant Temp Byte
byte injLowRaw= byteData[7]; // Injector low Byte
byte injHighRaw= byteData[8]; // Injector high Byte
byte knockraw = byteData[10]; // Knock sensor Byte
byte cel1 = byteData[36]; // Cel Byte1
byte cel2 = byteData[37]; // Cel Byte2
byte cel3 = byteData[38]; // Cel Byte3
byte cel4 = byteData[39]; // Cel Byte4
//RPM
float rpm = 1875000 / ((rpmHighRaw * 256) + rpmLowRaw);
//Injectors
double injms = ((((256.0 * injHighRaw ) + injLowRaw) - 24.0) / 4.0 ) / 57;
double dutycycle = Math.Round(rpm * injms / 1200,0,MidpointRounding.AwayFromZero);
//Knock retard
double knock = (0.25 * knockraw);
//Ignition Advance
double ign = (0.25 * ignRaw) - 6;
//O2 sensor voltage 0-5V
double O2 = o2Raw / 51.0;
//TPS %
double TPS = (0.472637 * tpsRaw) - 11.46119;
//Battery Voltage
double battery = (26.0 * batteryRaw) / 275.0;
//Map Voltage
float mapvolt = mapRaw / 51;
//Map Mbar
float map = (1764 / 255) * (mapRaw) * 2 + 6;
//Map inghg
double inHg = -10.87 * ((mapRaw) * 5 / 256) + 30.48;
//vtec code
var bits = new BitArray(vtecRaw);
bool vtec = bits[0];
//Speed kph
double speed = vssRaw; //Do what ever conversion here
//IAT C
double iat = iatRaw;
iat = iat / 51;
iat = (0.1423* Math.Pow(iat, 6)) - (2.4938* Math.Pow(iat, 5)) + (17.837* Math.Pow(iat, 4)) - (68.698* Math.Pow(iat, 3)) + (154.69* Math.Pow(iat, 2)) - (232.75* iat) + 284.24;
iat = ((iat - 32)*5)/9;
//ECT C
double ect = ectRaw;
ect = ect / 51;
ect = (0.1423 * Math.Pow(ect, 6)) - (2.4938 * Math.Pow(ect, 5)) + (17.837 * Math.Pow(ect, 4)) - (68.698 * Math.Pow(ect, 3)) + (154.69 * Math.Pow(ect, 2)) - (232.75 * ect) + 284.24;
ect = ((ect - 32) * 5) / 9;
// CRC CHECKING CODE HERE
int checksum = byteData[0];
int x = 0;
while (x < 39)
{
x++;
checksum = checksum + byteData[x];
}
byte calchecksum = (byte)(checksum & 0xff);
if (calchecksum == byteData[40])
{
//Check sum matched code here
//MessageBox.Show("checksum match");
}
else
{
//Checksum failed code here.
}
// Read error codes
string errorstring = Reverse(ToBitsString(cel1)) + Reverse(ToBitsString(cel2)) + Reverse(ToBitsString(cel3)) + Reverse(ToBitsString(cel4)); ;
char[] OBD1DTCL = errorstring.ToCharArray();
int i = 0;
while (i < 31)
{
if (OBD1DTCL[i].ToString() == "1")
{
//Message box for each code (Code number = i + 1.
MessageBox.Show("error code " + (int.Parse(i.ToString())+1).ToString());
}
i++;
}
}
//Converts a byte to a 8 bit
public static string ToBitsString(byte value)
{
return Convert.ToString(value, 2).PadLeft(8, '0');
}
//Inverts the bit string to make storing error codes as a 0-32 bit array easier.
public string Reverse(string text)
{
if (text == null) return null;
char[] array = text.ToCharArray();
Array.Reverse(array);
return new String(array);
}
}
}