Hi there,
I'm currently building a Mini Cooper with an engine swap. I need to get the VSS signal right for the ECU and speed gauge. The correction is necessary due to different tire dimensions.
I know there are existing products out there, but I was ambitious that I could build something myself.
So this is the information I got:
- VSS signal is a 0-5V rectangular signal with 50% duty cycle
- 4 Pulses per wheel turn
So I did some calculations to get an idea about the timing:
Figures for 1KPH
Car | Tire circumferences(m) | Wheel turns per second | Pulses per second | us/pulse |
---|---|---|---|---|
Donor | 1,792 | 0,155009... | 0,620039... | 1612800 |
Mini | 1,536 | 0,180844... | 0,723379... | 1382400 |
Figures for 200KPH
Car | Tire circumferences(m) | Wheel turns per second | Pulses per second | us/pulse |
---|---|---|---|---|
Donor | 1,792 | 31,0019... | 124,0079... | 8064 |
Mini | 1,536 | 36,1689... | 144,6759... | 6912 |
There might be some calculation errors, but anyway - this gives an idea about the dimensions for the pulse width. So based on what I've read about the precision, this should generally be possible.
However, I can't get my head around what's the best strategy to read a pulse at an input pin and do some kind of "on-the-fly" conversion and forward the newly calculated signal to a dedicated output pin.
I roughly calculated that I need to extend the pulse by 16% - so this is a sketch I came up with - not tested yet since the car is currently not in running condition.
My idea is to use interrupts to detect two rising edges - since I know that it's a 50% duty cycle, I will calculate the high time at a later stage. So as soon as I have the complete pulse length, I stop the interrupts and generate a 50% duty-cycle signal that is extended by the mention 16%. This should "lower" the speed signal and give me more correct values.
Following things I'm aware of but couldn't come up with an idea to solve:
- detecting and correctly implementing the potential micros() rollover after some time
- evaluating the impact that i will loose track of the next pulse while I'm generating the modified pulse and sending it to the output
// all those variables
volatile float timeNow = 0;
volatile float timeOld = 0;
byte pinInterrupt = 2;
byte pinPulse = 6;
float valCorrection = 1.166666;
float pulseOld = 0;
float pulseNew = 0;
float halfPulse = 0;
void setup() {
// put your setup code here, to run once:
attachInterrupt(digitalPinToInterrupt(pinInterrupt), recTime, RISING);
pinMode(pinPulse, OUTPUT);
digitalWrite(pinPulse, LOW);
}
void loop() {
// put your main code here, to run repeatedly:
if ((timeOld > 0) && (timeNow > timeOld)) {
// stop listening for interrupts to do calculation and singal generation
// detachInterrupt(digitalPinToInterrupt(pinInterrupt));
noInterrupts();
pulseOld = timeNow - timeOld; // calculate the actual pulse (RISE to next RISE)
pulseNew = valCorrection * pulseOld; // adapt the actual pulse to the target (with correction)
halfPulse = pulseNew/2.0; // calculate duration for 50% duty signal
digitalWrite(pinPulse, HIGH);
delayMicroseconds((int)halfPulse); // keep pin HIGH for the duty cycle
digitalWrite(pinPulse, LOW);
delayMicroseconds((int)halfPulse); // keep pin low to complete the "pulse"
// reattach interrupt to continue recording, hopefully should not miss a signal at all
//attachInterrupt(digitalPinToInterrupt(pinInterrupt), recTime, RISING);
interrupts();
}
}
void recTime() {
timeOld = timeNow;
timeNow = micros();
}
Did some do something comparable and maybe give me some hints that I maybe started totally wrong at the beginning?
Thank you!