I've built an off-road buggy and added a custom Hall effect speed sensor to work with the ECU and display speed on the dashboard. The issue is the sensor's pulse rate doesn't match what the ECU expects. At 87mph, for example, the ECU is looking for 100Hz pulses.
I'm planning to use an Arduino to correct this, to produce the correct pulse rate for the ECU and to display the speed on a dashboard display. The straightforward approach I'm considering is having the Arduino count pulses over one second intervals to calculate speed, then update both the display and adjust the pulse output for the ECU accordingly. This method introduces a potential two-second delay in the speed reading to the ECU.
Would you share your ideas and experiences on the most appropriate software pattern for calculating speed, that ensures stable results and ideally minimizes lag to the ECU?
All you need, I suspect, is to use digitalRead(), digitalWrite(), map() and micros() functions.
Use digitalRead() and micros() to measure the period between input pulses. Use map() to translate that into a suitable output pulse period. Then use digitalWrite() and micros() to create the output pulses.
You didn't mention what speed produces 100Hz from your sensor.
The ECU is a factory black box. Nothing can be changed inside of it or adjusted. Maybe in the future I'll fit an adjustable ECU, but for now that's not a priority as that's no easy job.
I believe the speed adjustment should be within approx 20% (judging by the extent of the drivetrain changes). But until I take some measurements I won't know for certain.
I don't object to using an Arduino as it will also mediate between other sensor incompatibilities around the car such as fuel sensor.
So the input signal (an input for the Arduino) is close to 100Hz at 87 mph ? within 20% ?
Do you know if it is always higher or lower ?
Is the 87 mph the maximum speed ?
A better approach to measure the input pulse frequency might be to measure the interval between successive pulses and calculate the frequency as 1/interval. This would introduce a lag that is only one or two pulse intervals rather than a couple seconds.
What exactly do these pulses represent? e.g. "1 pulse is 1 revolution of the engine" or some such.
Hi @ Koepel@PaulRB, I've yet to measure what rate the sensor produces as the car has a highly modified drivetrain. But it should be within 20% judging by the extent of the drivetrain mods. Not sure if it would be 20% more or 20% less.
display the speed on a dashboard display.
Can you give more details about this?
Sure @PaulRB . I thought that since I'm fitting the Arduino it could also take care of some other requirements including displaying the vehicle speed, maybe to a segment display. This isn't hugely important, the motor sports regs don't even require a speedo. But if the Arduino is capturing this data, it may as well display it to the driver.
Is the 87 mph the maximum speed ?
@Koepel , 87mph is just the speed the ECU expects at 100Hz. It could equally be quoted as 115Hz at 100mph. I doubt the car will go over 50mph as it's designed for low speed trials with suspension not suitable for high speeds.
What exactly do these pulses represent?
@MrMark , the speed sensor is connected to the output shaft that goes to the axles. Four pulses per rotation of the driveshaft.
@paulrb, thank you, I'll check that code out tonight.
Hi @zx80, change in wheels and change in differentials. The sensor is also different, custom machined, but it reads the same number of pulses per rotation. The ECU originally used a reed switch, new sensor uses Hall effect.
@PaulRB , thank you, you've gone above and beyond! Took me a while to understand the code. You're measuring the duration of an input pulse and generating a proportional output pulse. I think there's an issue in the last IF statement, which seems to wait 1 second before generating the next pulse. As the ECU is looking for rate of pulses rather than duration of the LOWs, this will need adjusting.
I'm not too familiar with the etiquette on t his forum, can I click the Checkbox on @PaulRB 's solution if its close enough or should only 100% complete solutions be accepted?
@ZX80 , thanks for those links. However the question is about the code to correct the offset, rather than how to calculate the offset.
Sorry, I wrote it in a hurry and didn't add many comments. But essentially you've got it, except that it is not measuring the pulse duration, but the pulse period, i.e. the time between the start of one pulse and the start of the next pulse. That's equivalent to the frequency. The pulse duration/length is less relevant. The pulses durations might be quite short, and might not vary with the frequency/roadspeed.
The part you didn't get was the last part:
1 millisecond!
I assumed there would be some minimum pulse width that the ECM would require to register the pulse. If it works at 1000us, halve it until it stops working. If it doesn't work, double it until it starts working.
It's up to you to decide, but I would think it a bit premature right now, it doesn't sound like you've actually tested it yet. Plus, your next request will be for choosing and coding for a display. It may be best not to start a new topic for that, because the forum members reading this topic are already familiar with the project.
I think what your saying is that the HIGH half of the pulse is very short and irrelevant, as the ECU just sees the total "wave" ? If so then very clever, I would never have thought of that !
I'm going to mark as SOLVED as I have a few other priorities, to get the buggy compliant with regs so that I can take it to some events. For now the engine seems content just knowing that the car is moving, ie any speed reading is better than no reading.
In the mean time I get an hour free each evening to get on with the Arduino code. I just need to find a way to get Wokwi to simulate the hall sensor.
It might be. We don't really know what the ECU sees, but my assumption would be that
it measures the pulse frequency, by timing the time between leading edges of the pulses, or, it counts the pulses over a time period (either way, the length of the pulses may be irrelevant).
It might not register a pulse that's very short, because it may need the pulse to be a certain minimum length, otherwise it might be missed, or, it might deliberately ignore very short pulses, assuming they are noise/interference.
But I could be wrong, and the pulse length is vitally important.
What worries me from your responses, is that you don't have an oscilloscope. That will make it difficult to figure out what the output signal from your sensor actually looks like, or what the Arduino is outputting looks like. A scope would be invaluable. Most auto workshops have them.
Hi Paul. I have a basic automotive oscilloscope. The original sensor in the "donor car" that I took the engine and ECU from was just a reed switch. The transfer box (a 4x4 gearbox), would turn a mechanical speedo cable, which would drive an old school mechanical speedo gauge and a reed switch. It seemed pointless to reproduce such a dated system, and I'm using a different transfer box anyway so it wouldn't have worked. I have a mini lathe so I made a cute sensor that fitted neatly into the speedo cable hole. I plugged a diagnostic tool into the ECU to check that it was registering readings from my home made Hall sensor, which it does.
One thing that surprised me is that the ECU could read a reed switch spinning over 100 Hz, I'm told those things "bounce like crazy", so the ECU must have some fancy software filtering.
What I could do is programme an Arduino to send some test pulses, and check the ECU registers them.
I'm very excited about using an Arduino at the heart of this buggy. I've bought dashboard lights, and I'm even thinking of having the Arduino control the radiator fan.
How many turns of the driveshaft does it take to make the wheel turn exactly 1 turn? How many pulses are generated? What is the wheel / tire circumference?