M177 W213 Data Logger (aka know how much power your car actually makes)
Subscribehttps://datazap.me/u/muffinflavored/runs-v2
I'm still tweaking it to have better units (PSI for boost for example) but... yeah. No JB4, no bFlash, no gimmicky Bluetooth OBD-II unreliable nonsense. Just take your laptop in your car and go
works with $15 Chinese Tactrix Openport clone
that's a stock run, i'm adding estimated/calculated rear wheel horsepower and all sorts of crap tomorrow
this doesn't use SAE J1979 identifiers that all of those iOS/Android apps do. I reverse engineered all of the German identifiers from Xentry for ECU/TCU/CPC_NG and figured out the scale factors to convert the hex into their appropriate human readable units
I need to fix ThrottleValvePosition so I can prove where CPC_NG does torque limiting when wide open throttle, and I need to increase the interval because right now it's at like 300ms (which is trash, needs to be 50ms-100ms)
I'm still tweaking it to have better units (PSI for boost for example) but... yeah. No JB4, no bFlash, no gimmicky Bluetooth OBD-II unreliable nonsense. Just take your laptop in your car and go

works with $15 Chinese Tactrix Openport clone
that's a stock run, i'm adding estimated/calculated rear wheel horsepower and all sorts of crap tomorrow
this doesn't use SAE J1979 identifiers that all of those iOS/Android apps do. I reverse engineered all of the German identifiers from Xentry for ECU/TCU/CPC_NG and figured out the scale factors to convert the hex into their appropriate human readable units
I need to fix ThrottleValvePosition so I can prove where CPC_NG does torque limiting when wide open throttle, and I need to increase the interval because right now it's at like 300ms (which is trash, needs to be 50ms-100ms)
Quote:
i’m not really looking to sell it or distribute itOriginally Posted by EkS
Is it going to work with all M177 equipped vehicles or just the W213?
nobody on these forums really cares enough
probably 20 people on the forums run a tune and 0 of them need/want logs
it would work for c63s
raudiace4
MBWorld Fanatic!
close
- Join DateJun 2014
- LocationIL
- Posts:1,589
-
iTrader Positive Feedback0
-
iTrader Feedback Score(0)
- Vehicle(s) I drive19 E63s, 23 M3 compX, B9 SQ5
-
Likes:395
-
Liked:683 Times in 378 Posts
Quote:
nobody on these forums really cares enough
probably 20 people on the forums run a tune and 0 of them need/want logs
it would work for c63s
I'm one of those 20 lol.Originally Posted by MuffinFlavored
i’m not really looking to sell it or distribute itnobody on these forums really cares enough
probably 20 people on the forums run a tune and 0 of them need/want logs
it would work for c63s
Good work man, love the passion.
here is some code for you guys
Code:
const calculateFactor = (min, max, size) => {
const range = Math.abs(min) + max
return range / (size == 1 ? 0xFF : 0xFFFF)
}
const scale = (min, max, size, value) => {
const factor = calculateFactor(min, max, size)
return (value * factor) + min
}
const scaleSigned = (min, max, size, value) => {
const factor = calculateFactor(min, max, size)
if (size === 1) {
const positive = (value & (1 << 7)) === 0
if (positive) {
return value * factor
}
return (value - 0xFF) * factor
} else {
const positive = (value & (1 << 15)) === 0
if (positive) {
return value * factor
}
return (value - 0xFFFF) * factor
}
}
const formatGear = (value) => {
return value
}
const formatRpm = (value) => {
const min = 0
const max = 16383.75
const size = 2
const unit = 'rpm'
return scale(min, max, size, value)
}
const formatSpeed = (value) => {
const min = 0
const max = 4096
const size = 2
const unit = 'km/h'
return scale(min, max, size, value)
}
const formatLoad = (value) => {
const min = 0
const max = 1536.00933
const size = 2
const unit = '%'
return scale(min, max, size, value)
}
const formatTorque = (value) => {
const min = -2048
const max = 2047.9375
const size = 2
const unit = 'Nm'
return scaleSigned(min, max, size, value)
}
const formatThrottlePedalPosition = (value) => {
const min = 0
const max = 100.006410
const size = 2
const unit = '%'
return scale(min, max, size, value)
}
const formatThrottleValvePosition = (value) => {
const min = 0
const max = 6553.5
const size = 2
const unit = '%'
//return scale(min, max, size, value) TODO: debugging
return value
}
const formatAmbientPressure = (value) => {
const min = 0
const max = 2559.993705
const size = 2
const unit = 'psi'
const scaledValue = scale(min, max, size, value)
return scaledValue * 0.0145038 // hPa -> psi
}
const formatBoost = (value) => {
const min = 0
const max = 5119.921875
const size = 2
const unit = 'psi'
const scaledValue = scale(min, max, size, value)
return scaledValue * 0.0145038 // hPa -> psi
}
const formatWastegate = (value) => {
const min = 0
const max = 99.998474
const size = 2
const unit = '%'
return scale(min, max, size, value)
}
const formatShortTermFuelTrim = (value) => {
const min = -1536
const max = 1535.953125
const size = 2
const unit = '%'
return scaleSigned(min, max, size, value)
}
const formatFuelPressureHigh = (value) => {
const min = 0
const max = 32.7675
const size = 2
const unit = 'psi'
const scaledValue = scale(min, max, size, value)
return scaledValue * 145 // MPa -> psi
}
const formatFuelPressureLow = (value) => {
const min = 0
const max = 6553.5
const size = 2
const unit = 'psi'
const scaledValue = scale(min, max, size, value)
return scaledValue / 6.895 // kPa -> psi
}
const formatIgnitionTiming = (value) => {
const unit = 'degrees'
const min = -96
const max = 95.25
const size = 1
return scaleSigned(min, max, size, value)
}
const formatTemperature = (value) => {
const unit = 'C'
const min = -48
const max = 143.25
const size = 1
return scale(min, max, size, value)
}
const formatLambda = (value) => {
const min = 0
const max = 15.99054
const unit = 'ratio'
const size = 2
return scale(min, max, size, value)
}
const formatIntakeManifoldPressure = (value) => {
const min = 0
const max = 5119.921875
const unit = 'psi'
const size = 2
const scaledValue = scale(min, max, size, value)
return scaledValue * 0.0145038 // hPa -> psi
}
const formatMassAirFlow = (value) => {
const min = 0
const max = 6553.5
const size = 2
const unit = 'g/s'
const scaledValue = scale(min, max, size, value)
return scaledValue / 3.6 // kg/h -> g/s
}
const formatKnock = (value) => {
const min = 0
const max = 1
const unit = 'flag'
return value
}
// format is [requestArbitrationId, dataIdentifier, name, formatter, size]
module.exports = [
// 1. general (gear + rpm + speed)
[0x7E5, 0x6340, 'Gear', formatGear, 1], // Ganganzeige_aktuell_eingelegter_Gang
[0x7E0, 0x2000, 'RPM', formatRpm, 2], // Motordrehzahl
[0x7E5, 0x6346, 'Speed', formatSpeed, 2], // Fahrzeuggeschwindigkeit
// 2. load
// LoadAdapted Momentenadaption_Teillast
[0x7E0, 0x2001, 'CalculatedLoad', formatLoad, 2], // Motorlast
// 3. torque (target + actual)
// TorqueReducedActual Momentenanforderung Durch Reduzierstufe Ist
// TorqueReducedTarget Momentenanforderung Durch Reduzierstufe Soll
// [0x7E0, 0x6000, 'EngineTorque', formatTorque], // Motordrehmoment
[0x7E5, 0x6256, 'TorqueActual', formatTorque, 2], // Istmoment_Verbrennungsmotor
[0x7E5, 0x6257, 'TorqueTarget', formatTorque, 2], // Sollmoment_Verbrennungsmotor
//[0x7E5, 0x625A, 'CoordinatedTorqueTarget', formatTorque], // Sollmoment_aus_der_Momentenkoordination
// 4. accelerator pedal
[0x7E0, 0x2029, 'ThrottlePedalPosition', formatThrottlePedalPosition, 2], // Pedalwertgeber
// 5. throttle valve
// [0x7E0, 0xD023, 'ThrottleValvePosition', formatThrottleValvePosition, 2], // Drosselklappenwinkel
// 6. boost (target + actual)
[0x7E0, 0x2040, 'AmbientPressure', formatAmbientPressure, 2], // Umgebungsdruck
[0x7E0, 0x2018, 'IntakeManifoldPressure', formatIntakeManifoldPressure, 2], // Saugrohrdruck
[0x7E0, 0x207A, 'BoostActual', formatBoost, 2], // Ladedruck_korrigiert
[0x7E0, 0x2077, 'BoostTarget', formatBoost, 2], // Ladedruck
// 7. wastegate duty cycle
[0x7E0, 0xD062, 'WastegateDutyCycle', formatWastegate, 2], // Wastegate
// 8. fuel trims (short term)
[0x7E0, 0x6088, 'ShortTermFuelTrim1', formatShortTermFuelTrim, 2], // Gemischadaption_Additiv_Lernwert_Links
[0x7E0, 0x6087, 'ShortTermFuelTrim2', formatShortTermFuelTrim, 2], // Gemischadaption_Additiv_Lernwert_Recht
// 9. fuel pressure (high + low)
[0x7E0, 0x2071, 'FuelPressureHigh', formatFuelPressureHigh, 2], // Kraftstoffdruck_Hochdruck
[0x7E0, 0x2098, 'FuelPressureLow', formatFuelPressureLow, 2], // Kraftstoffdruck_Niederdruck
// 10. ignition timing
[0x7E0, 0xD010, 'IgnitionTiming', formatIgnitionTiming, 1], // ROZ_Korrektur_Zundwinkelausgabe
// 11. temperatures (ambient + coolant + intake + oil)
[0x7E0, 0x5030, 'AmbientTemp', formatTemperature, 1], // Aussenlufttemperatur
//[0x7E0, 0x2013, 'CoolantTemp', formatTemperature, 1], // Kuehlmitteltemperatur
[0x7E0, 0x2014, 'IntakeAirTemp', formatTemperature, 1], // Ansauglufttemperatur_im_Saugrohr_Bank1
//[0x7E0, 0x2095, 'OilTemp', formatTemperature, 1], // Oeltemperatur
// 12. afr / lambda (before kat = wideband; after kat = narrowband)
[0x7E0, 0x6252, 'MassAirFlow', formatMassAirFlow, 2], // Luftmasse_Vorgabe
[0x7E0, 0x2046, 'LambdaAcutal1', formatLambda, 2], // O2_Sonde_Vor_Kat_Lambda_Recht
//[0x7E0, 0x2047, 'LambdaAcutal2', formatLambda, 2], // O2_Sonde_Vor_Kat_Lambda_Links
[0x7E0, 0x6144, 'LambdaTarget1', formatLambda, 2], // Lambda_Sollwert_Links
//[0x7E0, 0x6143, 'LambdaTarget2', formatLambda, 2], // Lambda_Sollwert_Recht
// 13. knock
[0x7E0, 0x2006, 'KnockSensor', formatKnock, 1], // Klopfsensor
]
the ISO-TP/UDS code to group 20 data identifiers into 1 request to make data logging/polling much faster:
Code:
const { isoTpSend } = require('./iso-tp')
const startDiagnosticSession = async (device, arbitrationId, mode) => {
return isoTpSend(device, arbitrationId, 0x10, [mode])
}
// do not define more than 20 to one data identifier
const dynamicallyDefineIdentifier = async (device, requestArbitrationId, dataIdentifier, definitions) => {
const output = []
output.push(0x01) // defineByIdentifier subfunction
output.push(dataIdentifier >> 8) // dynamicallyDefinedDataIdentifier
output.push(dataIdentifier & 0xFF) // dynamicallyDefinedDataIdentifier
for (let i = 0; i < definitions.length; ++i) {
const definition = definitions[i]
const definitionDataIdentifier = definition[1]
const definitionSize = definition[4]
output.push(definitionDataIdentifier >> 8) // sourceDataIdentifier
output.push(definitionDataIdentifier & 0xFF) // sourceDataIdentifier
output.push(0x01) // positionInSourceDataRecord
output.push(definitionSize)
}
return isoTpSend(device, requestArbitrationId, 0x2C, output)
}
const clearDynamicallyDefinedIdentifier = async (device, requestArbitrationId, dataIdentifier) => {
const output = []
output.push(0x03) // clearDynamicallyDefinedDataIdentifier subfunction
output.push(dataIdentifier >> 8) // dynamicallyDefinedDataIdentifier
output.push(dataIdentifier & 0xFF) // dynamicallyDefinedDataIdentifier
return isoTpSend(device, requestArbitrationId, 0x2C, output)
}
module.exports = {
startDiagnosticSession,
dynamicallyDefineIdentifier,
clearDynamicallyDefinedIdentifier
}
some bull**** formula i found online to calculate realtime horsepower/volumetric efficiency/load estimates given airflow + temperature + barometric pressure:
probably as good as bFlash/Autotuner, better/as good as JB4 without the cost or having to hook up crazy **** to your car
https://datazap.me/u/muffinflavored/...log=0&data=3-5
updated logs, much better frequency/logging. i'm convinced you don't even need dragy. i can read the spedometer every 10ms. traction isn't really an issue 100-200km/h AWD so... i'll do some tests to compare how close they are in terms of accuracy (GPS vs OBD, which would be powering the dash)
Code:
if anybody with a tactrix openport wants the code hit me up, i'll share how to set it up. it's slick and it's better than HP Tuners (they use OBD service 01 which is ***/trash/slow/incomplete compared to this)// from https://atgtraining.com/atg-volumetric-efficiency-calculator/
const calculateVolumetricEfficiency = ({engineSize, cylinder, drivetrainLoss, rpm, maf, iat, pressure, mafSelection, iatSelection, pressureSelection}) => {
let val = 0, cid = 0, lb = 0, degc = 0, degf = 0, tempK = 0, v = 0, molorMass = 0.28705, gb_air_vol = 0, gsec = 0
let gb_theo_air_vol = 0, lMin = 0, estV = 0, load = 0, cylAir = 0, refCylAir = 0, estGross = 0, estRWHP = 0
cid = engineSize / 0.0163871
if (mafSelection == 'g/sec') { // g/sec
lb = maf * 0.00220462 * 60
} else { // lb/min
gsec = maf / (0.00220462 * 60)
maf = gsec
lb = gsec * 0.00220462 * 60
}
if (iatSelection == 'F') { // fahrenheit
degc = (iat - 32) * 5 / 9
} else { // celsius
degf = iat * 9 / 5 + 32
degc = (degf - 32) * 5 / 9
}
tempK = degc + 273.15
degc = (degc).toFixed(2)
tempK = (tempK).toFixed(2)
if (pressureSelection == 'kPa') { // kPa
} else if (pressureSelection == 'in/hg') { // in/hg
pressure = pressure / 0.2953
} else { // psi
pressure = pressure / 6.895
}
v = (maf * tempK * 0.28705) / pressure
gb_air_vol = v * 60
gb_theo_air_vol = engineSize * rpm / 2
estV = (gb_air_vol / gb_theo_air_vol) * 100
cylAir = maf * 120 / (rpm * cylinder)
refCylAir = engineSize * 1.168 / cylinder
estGross = lb * 10
estRWHP = estGross * (1 - drivetrainLoss)
load = (cylAir / refCylAir) * 100
return {
volumetricEfficiency: estV,
theoreticalLoad: load,
whp: estRWHP
}
}
module.exports = {
calculateVolumetricEfficiency
}
probably as good as bFlash/Autotuner, better/as good as JB4 without the cost or having to hook up crazy **** to your car
https://datazap.me/u/muffinflavored/...log=0&data=3-5
updated logs, much better frequency/logging. i'm convinced you don't even need dragy. i can read the spedometer every 10ms. traction isn't really an issue 100-200km/h AWD so... i'll do some tests to compare how close they are in terms of accuracy (GPS vs OBD, which would be powering the dash)
5soko
Senior Member
close
- Join DateOct 2018
- LocationNYC
- Posts:497
-
iTrader Positive Feedback0
-
iTrader Feedback Score(0)
- Vehicle(s) I driveAMG
-
Likes:144
-
Liked:416 Times in 174 Posts
Quote:
if anybody with a tactrix openport wants the code hit me up, i'll share how to set it up. it's slick and it's better than HP Tuners (they use OBD service 01 which is ***/trash/slow/incomplete compared to this)
probably as good as bFlash/Autotuner, better/as good as JB4 without the cost or having to hook up crazy **** to your car
https://datazap.me/u/muffinflavored/...log=0&data=3-5
updated logs, much better frequency/logging. i'm convinced you don't even need dragy. i can read the spedometer every 10ms. traction isn't really an issue 100-200km/h AWD so... i'll do some tests to compare how close they are in terms of accuracy (GPS vs OBD, which would be powering the dash)
Very nice log! I like the parameters, esp boostactual and boost target.. Originally Posted by MuffinFlavored
some bull**** formula i found online to calculate realtime horsepower/volumetric efficiency/load estimates given airflow + temperature + barometric pressure:
Code:
// from https://atgtraining.com/atg-volumetric-efficiency-calculator/
const calculateVolumetricEfficiency = ({engineSize, cylinder, drivetrainLoss, rpm, maf, iat, pressure, mafSelection, iatSelection, pressureSelection}) => {
let val = 0, cid = 0, lb = 0, degc = 0, degf = 0, tempK = 0, v = 0, molorMass = 0.28705, gb_air_vol = 0, gsec = 0
let gb_theo_air_vol = 0, lMin = 0, estV = 0, load = 0, cylAir = 0, refCylAir = 0, estGross = 0, estRWHP = 0
cid = engineSize / 0.0163871
if (mafSelection == 'g/sec') { // g/sec
lb = maf * 0.00220462 * 60
} else { // lb/min
gsec = maf / (0.00220462 * 60)
maf = gsec
lb = gsec * 0.00220462 * 60
}
if (iatSelection == 'F') { // fahrenheit
degc = (iat - 32) * 5 / 9
} else { // celsius
degf = iat * 9 / 5 + 32
degc = (degf - 32) * 5 / 9
}
tempK = degc + 273.15
degc = (degc).toFixed(2)
tempK = (tempK).toFixed(2)
if (pressureSelection == 'kPa') { // kPa
} else if (pressureSelection == 'in/hg') { // in/hg
pressure = pressure / 0.2953
} else { // psi
pressure = pressure / 6.895
}
v = (maf * tempK * 0.28705) / pressure
gb_air_vol = v * 60
gb_theo_air_vol = engineSize * rpm / 2
estV = (gb_air_vol / gb_theo_air_vol) * 100
cylAir = maf * 120 / (rpm * cylinder)
refCylAir = engineSize * 1.168 / cylinder
estGross = lb * 10
estRWHP = estGross * (1 - drivetrainLoss)
load = (cylAir / refCylAir) * 100
return {
volumetricEfficiency: estV,
theoreticalLoad: load,
whp: estRWHP
}
}
module.exports = {
calculateVolumetricEfficiency
}
if anybody with a tactrix openport wants the code hit me up, i'll share how to set it up. it's slick and it's better than HP Tuners (they use OBD service 01 which is ***/trash/slow/incomplete compared to this)
probably as good as bFlash/Autotuner, better/as good as JB4 without the cost or having to hook up crazy **** to your car
https://datazap.me/u/muffinflavored/...log=0&data=3-5
updated logs, much better frequency/logging. i'm convinced you don't even need dragy. i can read the spedometer every 10ms. traction isn't really an issue 100-200km/h AWD so... i'll do some tests to compare how close they are in terms of accuracy (GPS vs OBD, which would be powering the dash)
MB World Stories
The Best of Mercedes & AMG
ExploreQuote:
Great work here!
thanks man! please, buy a $15 chinese tactrix openport and use my code. you’ll love it, i promise! Originally Posted by 5soko
Very nice log! I like the parameters, esp boostactual and boost target.. I use HP tuners, and non of that is available, man would that be great to have.Great work here!
Quote:
Thanks man!!Originally Posted by MuffinFlavored
thanks man! please, buy a $15 chinese tactrix openport and use my code. you’ll love it, i promise!
Very interesting post.
I will to buy one.
This is valid? --> https://es.aliexpress.com/item/33019...archweb201603_
some pretty pictures to prove she works 
makes JB4 look stupid! jk :P

makes JB4 look stupid! jk :P
Junior Member
Quote:

makes JB4 look stupid! jk :P
i have tactrix openport2.0Originally Posted by MuffinFlavored
some pretty pictures to prove she works 
makes JB4 look stupid! jk :P
can you tell me how to use the code to datalogg :-)
Quote:
if anybody with a tactrix openport wants the code hit me up, i'll share how to set it up. it's slick and it's better than HP Tuners (they use OBD service 01 which is ***/trash/slow/incomplete compared to this)
probably as good as bFlash/Autotuner, better/as good as JB4 without the cost or having to hook up crazy **** to your car
https://datazap.me/u/muffinflavored/...log=0&data=3-5
updated logs, much better frequency/logging. i'm convinced you don't even need dragy. i can read the spedometer every 10ms. traction isn't really an issue 100-200km/h AWD so... i'll do some tests to compare how close they are in terms of accuracy (GPS vs OBD, which would be powering the dash)
Hello,Originally Posted by MuffinFlavored
some bull**** formula i found online to calculate realtime horsepower/volumetric efficiency/load estimates given airflow + temperature + barometric pressure:
Code:
// from https://atgtraining.com/atg-volumetric-efficiency-calculator/
const calculateVolumetricEfficiency = ({engineSize, cylinder, drivetrainLoss, rpm, maf, iat, pressure, mafSelection, iatSelection, pressureSelection}) => {
let val = 0, cid = 0, lb = 0, degc = 0, degf = 0, tempK = 0, v = 0, molorMass = 0.28705, gb_air_vol = 0, gsec = 0
let gb_theo_air_vol = 0, lMin = 0, estV = 0, load = 0, cylAir = 0, refCylAir = 0, estGross = 0, estRWHP = 0
cid = engineSize / 0.0163871
if (mafSelection == 'g/sec') { // g/sec
lb = maf * 0.00220462 * 60
} else { // lb/min
gsec = maf / (0.00220462 * 60)
maf = gsec
lb = gsec * 0.00220462 * 60
}
if (iatSelection == 'F') { // fahrenheit
degc = (iat - 32) * 5 / 9
} else { // celsius
degf = iat * 9 / 5 + 32
degc = (degf - 32) * 5 / 9
}
tempK = degc + 273.15
degc = (degc).toFixed(2)
tempK = (tempK).toFixed(2)
if (pressureSelection == 'kPa') { // kPa
} else if (pressureSelection == 'in/hg') { // in/hg
pressure = pressure / 0.2953
} else { // psi
pressure = pressure / 6.895
}
v = (maf * tempK * 0.28705) / pressure
gb_air_vol = v * 60
gb_theo_air_vol = engineSize * rpm / 2
estV = (gb_air_vol / gb_theo_air_vol) * 100
cylAir = maf * 120 / (rpm * cylinder)
refCylAir = engineSize * 1.168 / cylinder
estGross = lb * 10
estRWHP = estGross * (1 - drivetrainLoss)
load = (cylAir / refCylAir) * 100
return {
volumetricEfficiency: estV,
theoreticalLoad: load,
whp: estRWHP
}
}
module.exports = {
calculateVolumetricEfficiency
}
if anybody with a tactrix openport wants the code hit me up, i'll share how to set it up. it's slick and it's better than HP Tuners (they use OBD service 01 which is ***/trash/slow/incomplete compared to this)
probably as good as bFlash/Autotuner, better/as good as JB4 without the cost or having to hook up crazy **** to your car
https://datazap.me/u/muffinflavored/...log=0&data=3-5
updated logs, much better frequency/logging. i'm convinced you don't even need dragy. i can read the spedometer every 10ms. traction isn't really an issue 100-200km/h AWD so... i'll do some tests to compare how close they are in terms of accuracy (GPS vs OBD, which would be powering the dash)
Can you explain how to make the logs?
Thank you.
I.T. Guy
MBWorld Fanatic!
close
- Join DateMar 2011
- LocationCanada
- Posts:2,496
-
iTrader Positive Feedback0
-
iTrader Feedback Score(0)
- Vehicle(s) I drive2023 E63S Wagon
-
Likes:2,153
-
Liked:1,574 Times in 845 Posts
BUMP! Back from the dead!
Beuller? Beuller?
Beuller? Beuller?
Damn I am late to this party/thread. Are you still around here and able to share how to go about this procedure? Cheers 









