C4 Tech/Performance L98 Corvette and LT1 Corvette Technical Info, Internal Engine, External Engine

C4 Arduino-RaspberryPI Dashboard

Thread Tools
 
Search this Thread
 
Old Nov 3, 2025 | 02:38 PM
  #61  
Ailvard's Avatar
Ailvard
Thread Starter
Advanced
All Eyes On Me
Liked
Loved
Community Favorite
 
Joined: Aug 2023
Posts: 70
Likes: 26
From: Texas
Default

Originally Posted by JoBy
I am working on a new Arduino code that reads the 160 baud data, similar to https://www.comvette.com/ but a different solution.
It is based on detecting falling and rising flanks using interrupts, and also decoding the bit stream to a completed byte data package.
Output format is one row for each complete data package, each data byte as HEX and space as delimiter.
The Raspberry does not have to bother with sync bytes or sync bits, just decoding the content.

Output as bit stream is simple to implement, and sync bits can be added to simulate "comvette" format.

I have my old ECM on the desk sending data, and the Arduino is very stable at reading.
I don't have the engine noise and I have to add some filtering for that.
Interesting. I gave Arduino work on decoding, and send to raspberry only values, so raspberry is focused on Display only. The problem with decoding of the ALDL on Arduino - is it takes all of the performance and clock from it, so it is hard to squeeze anything between the read attempts. I will probably add one ESP32 in addition to Arduino to read and decode ALDL.
So the architecture would look like:
ECU -> ESP32 -> Arduino Mega -> Raspberry
Car sensors -> Arduino Mega -> Raspberry
Reply
Old Nov 3, 2025 | 03:56 PM
  #62  
JoBy's Avatar
JoBy
Melting Slicks
25 Year Member
Liked
Loved
Community Favorite
 
Joined: Mar 2001
Posts: 2,150
Likes: 304
From: Timra, Sweden
Default

Originally Posted by Ailvard
Interesting. I gave Arduino work on decoding, and send to raspberry only values, so raspberry is focused on Display only. The problem with decoding of the ALDL on Arduino - is it takes all of the performance and clock from it, so it is hard to squeeze anything between the read attempts. I will probably add one ESP32 in addition to Arduino to read and decode ALDL.
So the architecture would look like:
ECU -> ESP32 -> Arduino Mega -> Raspberry
Car sensors -> Arduino Mega -> Raspberry

Using interrupts is way more efficient than polling the digital input to measure the pulse length. With the time critical edge detection handled by interrupt, the decoding part of the code is not time critical. I am using an Arduino Nano.
I was not able to use both positive edge and negative edge interrupts on the same pin, so I put the same ALDL signal on two inputs. There is a change interrupt but then you have to also read the pin to determine positive or negative flank.


This is an example of switching from MPG-data to full ALDL data:

Code:
21:54:53.918 -> 40 00 00 00 34
21:54:54.261 -> 40 00 00 00 34
21:54:54.600 -> 40 00 00 00 34
21:54:54.940 -> 40 00 00 00 34
21:54:55.280 -> 40 00 00 00 34
21:54:55.620 -> 40 00 00 00 34
21:54:55.960 -> 40 00 00 00 34
21:54:56.300 -> 40 00 00 00 34
21:54:56.640 -> 40 00 00 00 34
21:54:56.980 -> 40 00 00 00 34
21:54:57.320 -> 40 00 00 00 34
21:54:57.659 -> 40 00 00 00 34
21:54:57.998 -> 40 00 00 00 34
21:54:58.338 -> 40 00 00 00 34
21:54:58.679 -> 40 00 00 00 34
21:54:59.019 -> 40 00 00 00 34
21:54:59.359 -> 40 00 00 00 34
21:54:59.699 -> 40 00 00 00 34 00 A8 00 5E 01 11 00 00 00 00 1C 82 00 01 00
21:55:00.888 -> 44 F0 E2 0A FF 00 A8 00 5E 01 56 00 00 00 00 1C 92 00 01 00
21:55:02.078 -> 44 F0 E2 0A FF 00 A8 00 5E 01 B6 00 00 00 00 1C 92 00 01 00
21:55:03.267 -> 44 F0 E2 0A FF 00 A8 00 5E 01 CE 00 00 00 00 3C 82 00 01 00
21:55:04.455 -> 44 F0 E2 0A FF 00 A8 00 5E 01 1E 00 00 00 00 1C 82 00 01 00
21:55:05.643 -> 44 F0 E2 0A FF 00 A8 00 5E 01 11 00 00 00 00 1C 92 00 01 00
21:55:06.831 -> 44 F0 E2 0A FF 00 A8 00 5E 01 96 00 00 00 00 1C 92 00 01 00
21:55:08.021 -> 44 F0 E2 0A FF 00 A8 00 DE 01 B6 00 00 00 00 3C 82 00 01 00
21:55:09.208 -> 44 F0 E2 0A FF 00 A8 00 DE 01 F6 00 00 00 00 1C 82 00 01 00
21:55:10.398 -> 44 F0 E2 0A FF 00 A8 00 5E 01 1E 00 00 00 00 1C 92 00 01 00
21:55:11.587 -> 44 F0 E2 0A FF 00 A8 00 5E 01 FE 00 00 00 00 1C 92 00 01 00
21:55:12.777 -> 44 F0 E2 0A FF 00 A8 00 5E 01 96 00 00 00 00 3C 82 00 01 00
21:55:13.967 -> 44 F0 E2 0A FF 00 A8 00 5E 01 56 00 00 00 00 1C 82 00 01 00
21:55:15.155 -> 44 F0 E2 0A FF 00 A8 00 DE 01 F6 00 00 00 00 1C 92 00 01 00
21:55:16.346 -> 44 F0 E2 0A FF 00 A8 00 5E 01 CE 00 00 00 00 1C 92 00 01 00
21:55:17.536 -> 44 F0 E2 0A FF 00 A8 00 5E 01 FE 00 00 00 00 3C 82 00 01 00
21:55:18.724 -> 44 F0 E2 0A FF 00 A8 00 5E 01 11 00 00 00 00 1C 82 00 01 00
Binary format
Code:
22:40:05.181 ->  01000100 11110000 11100010 00001010 11111111 00000000 10101000 00000000 01011110 00000001 00010001 00000000 00000000 00000000 00000000 00011100 10010010 00000000 00000001 00000000
22:40:06.404 ->  01000100 11110000 11100010 00001010 11111111 00000000 10101000 00000000 11011110 00000001 10010110 00000000 00000000 00000000 00000000 00011100 10010010 00000000 00000001 00000000
22:40:07.560 ->  01000100 11110000 11100010 00001010 11111111 00000000 10101000 00000000 01011110 00000001 10110110 00000000 00000000 00000000 00000000 00111100 10000010 00000000 00000001 00000000
22:40:08.761 ->  01000100 11110000 11100010 00001010 11111111 00000000 10101000 00000000 01011110 00000001 11110110 00000000 00000000 00000000 00000000 00011100 10000010 00000000 00000001 00000000
22:40:09.958 ->  01000100 11110000 11100010 00001010 11111111 00000000 10101000 00000000 01011110 00000001 00011110 00000000 00000000 00000000 00000000 00011100 10010010 00000000 00000001 00000000
22:40:11.140 ->  01000100 11110000 11100010 00001010 11111111 00000000 10101000 00000000 01011110 00000001 11111110 00000000 00000000 00000000 00000000 00011100 10010010 00000000 00000001 00000000
22:40:12.329 ->  01000100 11110000 11100010 00001010 11111111 00000000 10101000 00000000 01011110 00000001 10010110 00000000 00000000 00000000 00000000 00111100 10000010 00000000 00000001 00000000
22:40:13.518 ->  01000100 11110000 11100010 00001010 11111111 00000000 10101000 00000000 01011110 00000001 01010110 00000000 00000000 00000000 00000000 00011100 10000010 00000000 00000001 00000000
22:40:14.707 ->  01000100 11110000 11100010 00001010 00110100
22:40:15.047 ->  01000000 00000000 00000000 00000000 00110100
22:40:15.386 ->  01000000 00000000 00000000 00000000 00110100
22:40:15.726 ->  01000000 00000000 00000000 00000000 00110100
22:40:16.065 ->  01000000 00000000 00000000 00000000 00110100
22:40:16.419 ->  01000000 00000000 00000000 00000000 00110100



These are the two interrupts that just store timestamps of falling and rising signal in a buffer. Then the main program anayzes these timestamps to determine length of positive and negative pules.


Code:
void fallingInterrupt()
{
timeBufferHead = incIndex( timeBufferHead, TIME_BUFFER_SIZE );
fallingTimeBuffer[timeBufferHead] = micros();
}

void risingInterrupt()
{
risingTimeBuffer[timeBufferHead] = micros();
}

Last edited by JoBy; Nov 3, 2025 at 04:42 PM.
Reply
Old Nov 3, 2025 | 06:36 PM
  #63  
LWesthaver's Avatar
LWesthaver
Burning Brakes
Conversation Starter
Liked
Community Favorite
Top Answer: 1
 
Joined: Dec 1999
Posts: 984
Likes: 154
From: Columbia MD
Default

Originally Posted by JoBy
Using interrupts is way more efficient than polling the digital input to measure the pulse length. With the time critical edge detection handled by interrupt, the decoding part of the code is not time critical. I am using an Arduino Nano.
I was not able to use both positive edge and negative edge interrupts on the same pin, so I put the same ALDL signal on two inputs. There is a change interrupt but then you have to also read the pin to determine positive or negative flank.


This is an example of switching from MPG-data to full ALDL data:


Code:
21:54:53.918 -> 40 00 00 00 34
21:54:54.261 -> 40 00 00 00 34
21:54:54.600 -> 40 00 00 00 34
21:54:54.940 -> 40 00 00 00 34
21:54:55.280 -> 40 00 00 00 34
21:54:55.620 -> 40 00 00 00 34
21:54:55.960 -> 40 00 00 00 34
21:54:56.300 -> 40 00 00 00 34
21:54:56.640 -> 40 00 00 00 34
21:54:56.980 -> 40 00 00 00 34
21:54:57.320 -> 40 00 00 00 34
21:54:57.659 -> 40 00 00 00 34
21:54:57.998 -> 40 00 00 00 34
21:54:58.338 -> 40 00 00 00 34
21:54:58.679 -> 40 00 00 00 34
21:54:59.019 -> 40 00 00 00 34
21:54:59.359 -> 40 00 00 00 34
21:54:59.699 -> 40 00 00 00 34 00 A8 00 5E 01 11 00 00 00 00 1C 82 00 01 00
21:55:00.888 -> 44 F0 E2 0A FF 00 A8 00 5E 01 56 00 00 00 00 1C 92 00 01 00
21:55:02.078 -> 44 F0 E2 0A FF 00 A8 00 5E 01 B6 00 00 00 00 1C 92 00 01 00
21:55:03.267 -> 44 F0 E2 0A FF 00 A8 00 5E 01 CE 00 00 00 00 3C 82 00 01 00
21:55:04.455 -> 44 F0 E2 0A FF 00 A8 00 5E 01 1E 00 00 00 00 1C 82 00 01 00
21:55:05.643 -> 44 F0 E2 0A FF 00 A8 00 5E 01 11 00 00 00 00 1C 92 00 01 00
21:55:06.831 -> 44 F0 E2 0A FF 00 A8 00 5E 01 96 00 00 00 00 1C 92 00 01 00
21:55:08.021 -> 44 F0 E2 0A FF 00 A8 00 DE 01 B6 00 00 00 00 3C 82 00 01 00
21:55:09.208 -> 44 F0 E2 0A FF 00 A8 00 DE 01 F6 00 00 00 00 1C 82 00 01 00
21:55:10.398 -> 44 F0 E2 0A FF 00 A8 00 5E 01 1E 00 00 00 00 1C 92 00 01 00
21:55:11.587 -> 44 F0 E2 0A FF 00 A8 00 5E 01 FE 00 00 00 00 1C 92 00 01 00
21:55:12.777 -> 44 F0 E2 0A FF 00 A8 00 5E 01 96 00 00 00 00 3C 82 00 01 00
21:55:13.967 -> 44 F0 E2 0A FF 00 A8 00 5E 01 56 00 00 00 00 1C 82 00 01 00
21:55:15.155 -> 44 F0 E2 0A FF 00 A8 00 DE 01 F6 00 00 00 00 1C 92 00 01 00
21:55:16.346 -> 44 F0 E2 0A FF 00 A8 00 5E 01 CE 00 00 00 00 1C 92 00 01 00
21:55:17.536 -> 44 F0 E2 0A FF 00 A8 00 5E 01 FE 00 00 00 00 3C 82 00 01 00
21:55:18.724 -> 44 F0 E2 0A FF 00 A8 00 5E 01 11 00 00 00 00 1C 82 00 01 00

Binary format

Code:
22:40:05.181 -> 01000100 11110000 11100010 00001010 11111111 00000000 10101000 00000000 01011110 00000001 00010001 00000000 00000000 00000000 00000000 00011100 10010010 00000000 00000001 00000000
22:40:06.404 -> 01000100 11110000 11100010 00001010 11111111 00000000 10101000 00000000 11011110 00000001 10010110 00000000 00000000 00000000 00000000 00011100 10010010 00000000 00000001 00000000
22:40:07.560 -> 01000100 11110000 11100010 00001010 11111111 00000000 10101000 00000000 01011110 00000001 10110110 00000000 00000000 00000000 00000000 00111100 10000010 00000000 00000001 00000000
22:40:08.761 -> 01000100 11110000 11100010 00001010 11111111 00000000 10101000 00000000 01011110 00000001 11110110 00000000 00000000 00000000 00000000 00011100 10000010 00000000 00000001 00000000
22:40:09.958 -> 01000100 11110000 11100010 00001010 11111111 00000000 10101000 00000000 01011110 00000001 00011110 00000000 00000000 00000000 00000000 00011100 10010010 00000000 00000001 00000000
22:40:11.140 -> 01000100 11110000 11100010 00001010 11111111 00000000 10101000 00000000 01011110 00000001 11111110 00000000 00000000 00000000 00000000 00011100 10010010 00000000 00000001 00000000
22:40:12.329 -> 01000100 11110000 11100010 00001010 11111111 00000000 10101000 00000000 01011110 00000001 10010110 00000000 00000000 00000000 00000000 00111100 10000010 00000000 00000001 00000000
22:40:13.518 -> 01000100 11110000 11100010 00001010 11111111 00000000 10101000 00000000 01011110 00000001 01010110 00000000 00000000 00000000 00000000 00011100 10000010 00000000 00000001 00000000
22:40:14.707 -> 01000100 11110000 11100010 00001010 00110100
22:40:15.047 -> 01000000 00000000 00000000 00000000 00110100
22:40:15.386 -> 01000000 00000000 00000000 00000000 00110100
22:40:15.726 -> 01000000 00000000 00000000 00000000 00110100
22:40:16.065 -> 01000000 00000000 00000000 00000000 00110100
22:40:16.419 -> 01000000 00000000 00000000 00000000 00110100




These are the two interrupts that just store timestamps of falling and rising signal in a buffer. Then the main program anayzes these timestamps to determine length of positive and negative pules.


Code:
void fallingInterrupt()
{
timeBufferHead = incIndex( timeBufferHead, TIME_BUFFER_SIZE );
fallingTimeBuffer[timeBufferHead] = micros();
}

void risingInterrupt()
{
risingTimeBuffer[timeBufferHead] = micros();
}
@JoBy That's a really interesting approach. Much more sophisticated than my bit-banging approach. Would you be willing to share the code? I'd love to see it!

-Wes
Reply
Old Nov 3, 2025 | 08:18 PM
  #64  
tequilaboy's Avatar
tequilaboy
Melting Slicks
 
Joined: Aug 2003
Posts: 3,399
Likes: 394
From: Lakeville MI
Default

Idle fuel rate should be about 6 lbs/hr. So you're dividing by a factor of 10 somewhere.

I think its happening here:

if(timeInterval > 0 && timeInterval < 10.0) {
// Calculate real-time fuel consumption in lb/hr gallons/hr
float unitsRate = fuelIncrement / timeInterval;
float maxInjectorFlow = 8.0 * (current.fuelConstant / 32.0); // lb/hr gallons/hr
float fuelConsumptionLbHr = 0.0;

if(unitsRate > 0) {
float dutyCycle = unitsRate / 255.0;
fuelConsumptionLbHr = maxInjectorFlow * dutyCycle;
}

}

For a one second interval:

dutyCycle = fuelIncrement / 255.0; /* maybe multiply by 100 here */

Also fuelIncrement could be 255 (100% DC).

Edit: I think what you have now is ok but is really gallons/hr. Not lbs/hr. Sorry for the confusion with the above. I didn't want to create a Pull Request (too much like work).

Last edited by tequilaboy; Nov 3, 2025 at 10:35 PM.
Reply
Old Nov 4, 2025 | 08:43 AM
  #65  
JoBy's Avatar
JoBy
Melting Slicks
25 Year Member
Liked
Loved
Community Favorite
 
Joined: Mar 2001
Posts: 2,150
Likes: 304
From: Timra, Sweden
Default

The data displayed in dash is instant / average MPG and Range. None of them has a time factor.

Instant Miles per Gallon.
distance / fuel usage
Both are available from the data stream.
It does not matter if you skip a sample, you get both the double distance and the double usage. ( As long as the increase is less than 255 for both )

Stock injectors = 22 Lb/Hr * 8 = 176 Lb/Hr
176 Lb/Hr / 6 Lb/Gal = 29.33 Gall/Hr total flow rate at 100% duty

Fuel increment is 256 per second at 100% duty = 256 * 3600 = 921600 increments per hour at 100% duty.
Factor in data stream = 122.

29.33 / ( 921600 * 122 ) = 0.000000261 Gallons per fuelIncrement * fuelFactor.

distanceIncrement : probably 1 / 4000 mile (or 1 / 2000 mile.)

MPG = ( distanceIncrement / 40000 ) / ( fuelIncrement * fuelFactor * 0.000000261 )


======================================== ===============
instant MPG = 958 * distanceIncrement / ( fuelIncrement * fuelFactor )
======================================== ===============


Average - rolling average is a good approach and very easy to change filtration time scale.
Filter factor = F.
New average = ( Old average x F + New value ) / ( F + 1 )
F = 0 => New average = New value
F = 100 => New average = 99% Old average + 1% New value


Range is
Average MPG * Gallons remaining in tank.
Reply
Old Nov 4, 2025 | 06:22 PM
  #66  
JoBy's Avatar
JoBy
Melting Slicks
25 Year Member
Liked
Loved
Community Favorite
 
Joined: Mar 2001
Posts: 2,150
Likes: 304
From: Timra, Sweden
Default

Looking at the MPG data stream for my 1984 ECM, the size factor is 34 hex = 52 decimal.
The 1988 data stream posted is 1111010 = 122 but that is not correct because one bit is missing.
The preciding sync bit is correct (0) so the correct value is 11110100 or 11110101 = 244 or 245 decimal.

The 1984 has two injectors, one bigger.
67+68 Lb/Hr = 135 Lb/Hr total and a size factor of 52 decimal.
The 1988 has eight injecors, each 22 Lb/Hr = 176 Lb/Hr total and a size factor of 244 decimal.

Injectors are 30% bigger and the factor is 470% bigger.

There could be different factors in the cluster calculations also....

Anyway, for 1988 with fuel factor 244.

If 4000 pulses per mile:

Instant MPG = 1916 * distanceIncrement / ( fuelIncrement * fuelFactor )

If 2000 pulses per mile:
Instant MPG = 3832 * distanceIncrement / ( fuelIncrement * fuelFactor )

Reply
Old Nov 4, 2025 | 08:36 PM
  #67  
Ailvard's Avatar
Ailvard
Thread Starter
Advanced
All Eyes On Me
Liked
Loved
Community Favorite
 
Joined: Aug 2023
Posts: 70
Likes: 26
From: Texas
Default

Originally Posted by JoBy
The data displayed in dash is instant / average MPG and Range. None of them has a time factor.

Instant Miles per Gallon.
distance / fuel usage
Both are available from the data stream.
It does not matter if you skip a sample, you get both the double distance and the double usage. ( As long as the increase is less than 255 for both )

Stock injectors = 22 Lb/Hr * 8 = 176 Lb/Hr
176 Lb/Hr / 6 Lb/Gal = 29.33 Gall/Hr total flow rate at 100% duty

Fuel increment is 256 per second at 100% duty = 256 * 3600 = 921600 increments per hour at 100% duty.
Factor in data stream = 122.

29.33 / ( 921600 * 122 ) = 0.000000261 Gallons per fuelIncrement * fuelFactor.

distanceIncrement : probably 1 / 4000 mile (or 1 / 2000 mile.)

MPG = ( distanceIncrement / 40000 ) / ( fuelIncrement * fuelFactor * 0.000000261 )


======================================== ===============
instant MPG = 958 * distanceIncrement / ( fuelIncrement * fuelFactor )
======================================== ===============


Average - rolling average is a good approach and very easy to change filtration time scale.
Filter factor = F.
New average = ( Old average x F + New value ) / ( F + 1 )
F = 0 => New average = New value
F = 100 => New average = 99% Old average + 1% New value


Range is
Average MPG * Gallons remaining in tank.
Thanks for the correction. One important note - I'm not sending pulses from VSS to ECU, so it doesn't have range or MPG available. Only valid data would be the Fuel Flow calculation (which I'm already taking). At the same time - the VSS counter data is already in my Arduino (I'm converting it from pulses to voltage), so I'm calculating MPG and Range directly in Arduino.

In a meantime I separated the ALDL reading to a separate ESP32 from Arduino and sending fuel data from it. The benefit I see - is not affecting performance for main data processing in Arduino. And also, I still have a plenty of performance in ESP32 in case I need to read and process more advanced data (25 byte instead of 5) and on a higher baud from ECU in future if needed.

Wil try to assemble everything together (thanks that ESP32 is a tiny device) and test it.
Reply
Old Nov 4, 2025 | 08:44 PM
  #68  
Ailvard's Avatar
Ailvard
Thread Starter
Advanced
All Eyes On Me
Liked
Loved
Community Favorite
 
Joined: Aug 2023
Posts: 70
Likes: 26
From: Texas
Default

And this is how I measure distance and speed.

The architecture:
VSS pulses → LM2907 frequency-to-voltage converter → Analog voltage (0-5V)

Arduino - voltage to speed:
float readSpeedometerMPH() {
int analog_value = analogRead(speedometerPin); // Read A8
float voltage = analog_value * (5.0 / 1023.0); // Convert to voltage

if (voltage < 0.1) {
mph = 0.0; // Below 0.1V = zero speed
} else {
mph = voltage * 37.5; // Calibration: 37.5 MPH per volt
}

return mph;
}
Raspberry: Speed to Distance:
delta_time_ms = current_time - last_speed_update_time
if delta_time_ms > 0 and current_speed > 0.1: # Only when moving
# Calculate distance increment in miles
distance_increment = (current_speed * delta_time_ms) / 3600000.0 # MPH * ms -> miles

# Update odometer values
persistent_data.data["total_odometer"] += distance_increment
persistent_data.data["trip_odometer"] += distance_increment
I calibrated speed by GPS - the difference is +-1mph.
LM2907 has perfect linearity, so I guess it should work.
Reply
Corvette Stories

The Best of Corvette for Corvette Enthusiasts

story-0

10 Ugly Corvettes That We Still Kinda Love

 Joe Kucinski
story-1

Top 10 Most Expensive Corvettes Ever Sold on Bring A Trailer

 Brett Foote
story-2

10 Things Every Corvette Owner Needs (2026 Edition)

 Michael S. Palmer
story-3

8 Most "Only Corvette Owners Understand" Quirks and Problems

 Pouria Savadkouei
story-4

10 Reasons the C6 Z06 is Still A Performance Benchmark After 20 Years

 Joe Kucinski
story-5

How Much Horsepower Every Corvette Engine "LOST" in 1972

 Joe Kucinski
story-6

Top 10 DOs and DON'Ts for Protecting Your Convertible Top!

 Michael S. Palmer
story-7

Top 10 Most Explosive Corvettes Ever Made: Power-to-Weight Ratio Ranked!

 Joe Kucinski
story-8

150 hp to 1,250 hp: Every Corvette Generation Compared by the Specs That Matter

 Joe Kucinski
story-9

8 Coolest Corvette Pace Cars (and Replicas) of All Time

 Verdad Gallardo
Old Nov 5, 2025 | 04:44 AM
  #69  
tequilaboy's Avatar
tequilaboy
Melting Slicks
 
Joined: Aug 2003
Posts: 3,399
Likes: 394
From: Lakeville MI
Default

Notes for clarification: 122 decimal (or 0x7A) is the correct stock value for 1986-1988 Corvettes (variable name: KDISFSA in the original source and was commented as: 'GL/HR' INJECTOR FLOW RATE IN GALLONS / HOUR).

$32: LC70C: FCB 122 ; Gals/Hr Inj flow rate ; CALIB = Arg * 32, (3.8125 G/Hr)

$32B: LC712 FCB 122 ; Gals/Hr Inj flow rate ; Num = Arg * 32, (3.8125 G/Hr)

The equivalent value (and address) was changed to 118 (or 0x76) for 1989 Corvettes:

$6E: LC620: FCB 118 ; Gal/hr SCALE FACTOR arg = Gal/hr x 32

For 24 lb/hr injectors, the value should be set to: 128 (4 G/Hr).

Not sure why the preceding 0 after the sync bit (0) is being dropped in the data that has been presented. The bit stream should appear as 0 01111010.

Last edited by tequilaboy; Nov 5, 2025 at 06:02 AM.
Reply
Old Nov 5, 2025 | 08:24 AM
  #70  
JoBy's Avatar
JoBy
Melting Slicks
25 Year Member
Liked
Loved
Community Favorite
 
Joined: Mar 2001
Posts: 2,150
Likes: 304
From: Timra, Sweden
Default

Originally Posted by tequilaboy
Notes for clarification: 122 decimal (or 0x7A) is the correct stock value for 1986-1988 Corvettes (variable name: KDISFSA in the original source and was commented as: 'GL/HR' INJECTOR FLOW RATE IN GALLONS / HOUR).

$32: LC70C: FCB 122 ; Gals/Hr Inj flow rate ; CALIB = Arg * 32, (3.8125 G/Hr)

$32B: LC712 FCB 122 ; Gals/Hr Inj flow rate ; Num = Arg * 32, (3.8125 G/Hr)

The equivalent value (and address) was changed to 118 (or 0x76) for 1989 Corvettes:

$6E: LC620: FCB 118 ; Gal/hr SCALE FACTOR arg = Gal/hr x 32

For 24 lb/hr injectors, the value should be set to: 128 (4 G/Hr).

Not sure why the preceding 0 after the sync bit (0) is being dropped in the data that has been presented. The bit stream should appear as 0 01111010.

Ok,

How to interpret this row?
$32: LC70C: FCB 122 ; Gals/Hr Inj flow rate ; CALIB = Arg * 32, (3.8125 G/Hr)

$32: -> Code revision in the ROM chip? 1986=$32, 1987-88=$32B

LC70C: -> Address in chip?

FCB ?

122 -> Value

; Gals/Hr Inj flow rate ; CALIB = Arg * 32, (3.8125 G/Hr) -> comment
122 / 32 = 38125 and that matches value in brackets.
To get the decimal correct, 38125 / 10000 is the value for one hour of 100% duty.
Stock injectors = 22 Lb/Hr / 6 = 3.67 G/Hr
The calibration is only for one injector ?
Why the difference between 3.81 and 3.67 ?

Reply
Old Nov 5, 2025 | 10:44 AM
  #71  
tequilaboy's Avatar
tequilaboy
Melting Slicks
 
Joined: Aug 2003
Posts: 3,399
Likes: 394
From: Lakeville MI
Default

For 86-88, the stock injectors are actually close to 23 lb/hr (calibration-wise):

From $32:
;------------------------------------------------------
; INJ FLOW RATE
; 23#/HR INJECTORS
;
; Double Fire #/h = 10158.8/cal val
; Single Fire #/h = 20317.6/cal val
;------------------------------------------------------
LC3CF: FDB 0441 ; Double Fire Prod of Inj Flow rate
; cal = Sec/gm * (256 * 5)
;
; 0.344/sec/g,
; (1/0.344/sec/g) = 2.902 g/sec
; 2.902 g/sec * 3.6 = 10.448 kg/hr, (23.034#)
;
LC3D1: FDB 0882 ; Single Fire Prod of Inj Flow rate
; cal = Sec/gm * (256 * 10)
; 0.344/sec/g, 2.902 g/sec * 3.6 = 10.448 kg/hr, (23.034#)
;------------------------------------------------------

From $32B:
;----------------------------------
; INJECTOR FLOW RATES
;
;-----------------------------------
; DOUBLE FIRE
LC3D6: FDB 441 ; 0.5742 Sec/Grm, Prod of Inj Flow rate
; Num = (sec/grm * 256) * 5

; SINGLE FIRE
LC3D8: FDB 882 ; 0.5742 Sec/Grm, Prod of Inj Flow rate
; Num = (sec/grm * 256) * 10

For 89, the stock injectors are actually close to 22.4 lb/hr (calibration-wise):
From $6E:
;----------------------------------
; INJ FLOW RATE
; 22.3#/HR INJECTORS
;
; Double Fire #/h = 10158.8/cal val
; Single Fire #/h = 20317.6/cal val
;----------------------------------
LC3D7: FDB 0454 ; 0.355 sec/gm, INJ FLOW RATE, DOUBLE FIRE
; cal = Sec/gm * (256 * 5)
;
; (1/0.355/sec/g) = 2.819 g/sec
; 2.819 g/sec * 3.6 = 10.150 kg/hr, (22.377#)
;----------------------------------
LC3D9: FDB 0908 ; 0.3547 sec/gm, INJ FLOW RATE, SINGLE FIRE
; ARG = (GMS/SEC * 256) * 5
;
; (1/0.355/sec/g) = 2.819 g/sec
; 2.819 g/sec * 3.6 = 10.150 kg/hr, (22.377#)
;----------------------------------
Reply
Old Nov 6, 2025 | 11:14 AM
  #72  
Ailvard's Avatar
Ailvard
Thread Starter
Advanced
All Eyes On Me
Liked
Loved
Community Favorite
 
Joined: Aug 2023
Posts: 70
Likes: 26
From: Texas
Default

Tested yesterday - seems more or less working. I decided to make this logic - when car is not running - showing GPH, and when car is running - showing MPG or L/100 km.
I uploaded video of testing - not under real load as car was on the jack stand, so wheels where just freely spinning. But the road drive showed better results. (Didn't put the Dashboard bezel, so it doesn't look very pretty)






Now need to fix fuel level calculation (I reverted its logic so it shows empty when its full and need to add speedometer smothering logic (due to the refresh rate and noise from VSS - its a bit erratic in the range of +- 2 mph, which is annoying.

Will start sharing the Schematics and full code in Github soon.

... And I think need some rest from the project - its occupying me since June
Reply
Old Nov 12, 2025 | 06:22 PM
  #73  
Ailvard's Avatar
Ailvard
Thread Starter
Advanced
All Eyes On Me
Liked
Loved
Community Favorite
 
Joined: Aug 2023
Posts: 70
Likes: 26
From: Texas
Default

Ok, so some updates from me.
1. uploaded all required (and latest) files to my GitHub page -> https://github.com/yahor-chupin/corv...erry-dashboard
2. Added full description and requirements in README.md file
3. Finalized Wiring diagram (attaching here) -> critics and comments are welcome! If it is too small - here is a link to a bigger version: https://github.com/yahor-chupin/corv..._dashboard.jpg
4. Todo: need to add list of the components with Amazon links and that's pretty much it.


Reply
Old Nov 14, 2025 | 10:10 PM
  #74  
reubenaj's Avatar
reubenaj
Intermediate
All Eyes On Me
 
Joined: Sep 2025
Posts: 33
Likes: 5
From: Baltimore, MD area
Default

Thanks for sharing!
Reply
Old Nov 19, 2025 | 10:41 PM
  #75  
-=Jeff=-'s Avatar
-=Jeff=-
Race Director
25 Year Member
All Eyes On Me
Photogenic
Community Favorite
 
Joined: Mar 1999
Posts: 12,597
Likes: 237
From: Bartlett Illinois
Default

Awesome and thanks for sharing!!

Reply




All times are GMT -4. The time now is 06:21 PM.

story-0
10 Ugly Corvettes That We Still Kinda Love

Slideshow: 10 ugly Corvettes that we still kinda love.

By Joe Kucinski | 2026-06-03 10:34:17


VIEW MORE
story-1
Top 10 Most Expensive Corvettes Ever Sold on Bring A Trailer

A lot of money has changed hands at the online auction house over the years.

By Brett Foote | 2026-06-03 10:21:50


VIEW MORE
story-2
10 Things Every Corvette Owner Needs (2026 Edition)

Slideshow: 10 great gifts Corvette enthusiasts actually want for Father's Day!

By Michael S. Palmer | 2026-06-03 11:09:53


VIEW MORE
story-3
8 Most "Only Corvette Owners Understand" Quirks and Problems

Slideshow: These are the quirks, annoyances, and oddly lovable problems that every Corvette owner eventually learns to live with.

By Pouria Savadkouei | 2026-05-28 09:31:39


VIEW MORE
story-4
10 Reasons the C6 Z06 is Still A Performance Benchmark After 20 Years

Slideshow: 10 reasons why the C6 Z06 is still a performance benchmark after 20 years.

By Joe Kucinski | 2026-05-27 17:20:09


VIEW MORE
story-5
How Much Horsepower Every Corvette Engine "LOST" in 1972

Slideshow: How much horsepower every Corvette engine lost in 1972.

By Joe Kucinski | 2026-05-27 16:54:53


VIEW MORE
story-6
Top 10 DOs and DON'Ts for Protecting Your Convertible Top!

Slideshow: How to Protect A Convertible Top: 10 DOs & DON'Ts

By Michael S. Palmer | 2026-04-03 00:00:00


VIEW MORE
story-7
Top 10 Most Explosive Corvettes Ever Made: Power-to-Weight Ratio Ranked!

Slideshow: The 10 most explosive Corvettes ever built based on power-to-weight ratio.

By Joe Kucinski | 2026-05-20 07:23:03


VIEW MORE
story-8
150 hp to 1,250 hp: Every Corvette Generation Compared by the Specs That Matter

Slideshow: From C1 to C8 we compare every Corvette generation by the numbers.

By Joe Kucinski | 2026-05-12 16:54:12


VIEW MORE
story-9
8 Coolest Corvette Pace Cars (and Replicas) of All Time

Slideshow: Some Corvette pace cars became collectible legends, while others perfectly captured the look and attitude of their era.

By Verdad Gallardo | 2026-05-11 09:50:51


VIEW MORE