Fuelly Forums

Fuelly Forums (https://www.fuelly.com/forums/)
-   Experiments, Modifications and DIY (https://www.fuelly.com/forums/f9/)
-   -   diy mpg gauge (https://www.fuelly.com/forums/f9/diy-mpg-gauge-5319.html)

EvilToothpaste 02-26-2009 03:30 PM

Bnapalm,
 
2 Attachment(s)
Sounds like a good school project. I like the C++, and would be interested to see the final. I know more about that than I do Java, but still not much. I am most familiar with Python.

I made a quick schematic of the circuit I used and attached it below. I have a 6.8 zener only because that's what I had laying around. This particular circuit requires at least 12 volts on its input which means it can only be used on the injectors (my injectors make a 14.7V square wave with a 48V spike at the end of each pulse). You might be able to use it on Vss, actually, but only if it has at least 12v peak to peak. I used the same opposing diode circuit that Skewbe used for my Vss because I was too lazy to drag my o-scope out again to measure it after I had finally found the wire. Worked for him so I just went with it.

I can give you my sound file, but I don't have any gallon values for you because I haven't calibrated my stuff yet. I know that I topped out at 35mph, but that's all the info I have. hope it helps.

...except it's way too large. I'll have to email it to you. message me your email address and I'll send it tomorrow.

bnapalm 02-26-2009 10:53 PM

OK, I sent my e-mail address to you in a private message. Thank you! :)

itjstagame 04-13-2009 11:11 AM

Cool people are doing stuff!

I should clean up my code so people can see if it's useful at all. I wish I had stereo line input so I could debug it and get it working. I have both of my sources to an 1/8" jack but don't have stereo input, I've boughten a PCMCIA and Usb sound card that bought said stereo line input and lined, only mono. Most laptops I look at only have mono too, it's infuriating.

Anyway, let me go over the program a bit.

EvilToothpast: First, in you picture, the values on the right, is this the 8bit value, 0-256? The reason for the negatives is that when we look at the values in Java they're a signed int, that is, -127-127. I'm not sure why or how to change this, but basically that red line in each of your pictures would be 0.

So if the downward pulse is an injector fire, I'd set your injThreshold to anything negative, -100 looks about right but you can see that anything below -10 or -20 is only during a pulse.

For VSS it's the same thing, it's just a square wave and we just want to count cycles, so pick either 80 or -100 and it 'should' work. I say should because it really <b>WON'T</b> work. If you look in the code it does this:
if (val > vssThreshold
and
if (val < injThreshold

So that is, it expects injThresh to be negative and vssThress to be positive, nothing else will work unless you change the code. Based on your picture I'd set inj to -50 and vss to 80.

Now the fudge factors, those turn the useless counts of pulses into useful data. That is, the code isn't super sophisticated, it just checks every Hz (basically checks some times / sec based on sample rate) and if the 8bit value is ever above or below a threshold it sets increments a value.

Then at the rate that we update the front end screen (say once / second or so), we look at how many inj pulses there were, divide by fudge and call it gallons / second (or screen refresh time) and same with vss, we take number of vss cycles / fudge and get miles/second.

Here's the code again:

public double miles() {
return vssTot / distanceFudge;
}


public double gallons() {
return injHiTot / fuelFudge;
}

It really doesn't matter, after you calibrate once it will be right, but basically the fuelFudge is how many inj pulses it'd take to equal 1 gallon and the DistanceFudge is number of VSS cycles for one mile.

EvilToothpaste 04-14-2009 03:12 PM

Quote:

Originally Posted by itjstagame (Post 132428)
So that is, it expects injThresh to be negative and vssThress to be positive, nothing else will work unless you change the code. Based on your picture I'd set inj to -50 and vss to 80.

I will post what my values were when I get to my laptop, but I'm pretty sure I tried about every value from -100 to +100 for both Vss and Inj. I'm still getting nonsense for gallons.

Maybe I should invert the signal? It looks like mine is inverse of Skewbe's wave image from the first page. I'm sure that can be done in code somehow ... can I get a few Java pointers on where to find it?

itjstagame 05-19-2009 12:21 PM

Sorry I disappeared there.

Everything happens here and looking at it again I'm very stupid, the -127-128 can be changed at your will, looks like it just gets a byte by default and turns it in to those int values.

Here's the code with my own comments:


void processChunk(byte[] b, int c) {
double ih = 0; #injections, some amount of fuel
double vt = 0; # vss pulses
double rev = 0; # revs of engine

# Read all bytes that happened since we were here last in 2 byte chunks (left and right at 8bit)
for (int x = 0; x < c; x += 2) {

#the first channel (left?) is vss and here's were it manipulates the byte into an int between -127 to 128
int val = ((int) b[x] & 255) - 127;
if (val > vssThreshold && vg) {
# If it's greater than the threshold then add one to the pulse count
vt++;
//System.out.println(" vss going hi "
// + (current.sampleCount + (x / 2)));
vg = false;
}
if (val < 0) {
vg = true;
}

# Parsing the next channel, injector and turning into -127 to 128
val = ((int) b[x + 1] & 255) - 127;
if (val < injThreshold) {
# if less than the threshold then set ig to true
ig = true;
}
if (ig && val > 0)
{
rev += 1;
}
if (val > 0)
ig = false;
# These are my own changes to try to captures revs but it looks wrong rereading it now. Basically I just want to +1 to ih if we're ever less than threshold, but I was doing other stuff to try to count rpms, so I could get < threshold 3 bytes in a row but wanted that to count as 1 revolution (just a longer injection pulse).
if (ig)
ih++;
}
instant.Update((double)c / 2, ih, vt, rev);
current.Update((double)c / 2, ih, vt, rev);
tank.Update((double)c / 2, ih, vt, rev);
if (coastTest.coasting && instant.instantmph()<=coastTest.startmph() ) {
if (instant.instantmph()>=coastTest.endmph()) {
coastTest.UpdateDrag(instant.acceleration(), instant.instantmph());
} else { coastTest.coasting=false; }
}
}


So after looking over it (well my modified code), the real code will be similar but I still say -50 and 80 look good based on your signals, this will trigger correctly to turn a pulse in the audio into an injection or vss pulse.

Gallons are probably way off because your fuel fudge isn't calibrated right.

Gallons is simply the total number of injections we've gotten since last reset (so per/sec for instant, /min for current and /tank for tank) divided by fuelFudge:
public double gallons() {
return injHiTot / fuelFudge;
}

So even though you have the right amount of injections you still need to have the fudge right before the value will make sense. His fudge was
fuelFudge=8000000.00 by default for a 4 cyl (EDIT: this was a 3 Cyl metro, doh!)

You could try calculating, like ignore injector openning closing time and just assume it's 300cc/min injectors and we're sampling every 44Khz * 60 (secs in a min) so 1.136 * 10^4 cc/cycle if on, 1 cc = 0.000264172052 US Gallons, so
3 * 10^-8 gallons/cycle. We're dividing by fudge though, not multiplying so invert: 33.3 * 10^6

This is just completely off the cuff but matches fairly closely to the 8 * 10^6 default value. Keep in mind this is one injector you're watching, if you've got a 4cyl with 4 300cc/min injectors we'd have to divide that 33.3 by 4 (that is we're giving 4 times the weight to each pulse because there were actually 4 of them), that's 8.3 * 10^6.

My truck has only 2 throttle body injectors, I think 500-600cc/min each, but basically I just took the 8 * 10^6 default, dividing by 5.7 (thought being that 8 was for total injections to a 1L metro). Still haven't been able to debug in car to know if that value is useful though.


NOTE! Also, it seems obvious that each thing to needs to be on a particular channel. I'm not sure if skewbe mentioned that, but the code clearly works this way. You'd could swap the inj and vss blocks in ProcessChunk if you think you're reading the wrong channel for each. I was just guessing that left was first though.

EDIT: Yeah, skewbe set up VSS as the left channel and inj as the right, so that's probably why it appears first, though looking at it again, the for loop works backwards. We have an array of byte and look at them 2 at a time starting with 0, I'm not sure how this array is given to us or filled but to work the way I imagine in my head, the code uses it like this:
cycle 5 -> cycle 1
RL RL RL RL RL RL
Because it's saying b[0] is the 1st cycle's left or vss and b[1] is right, then adding 2 and saying b[2] is left and b[3] is right.

Skewbe can you comment? I finally have a laptop (and now the truck is dead) so looking to set this up in the Festy and have at it, hopefully sooner rather than later!

EvilToothpaste 06-01-2009 07:04 AM

Well, I wish I could help with your code. The RPM's is a good idea.

I have some ideas of how to debug my problem, but I need to compile Skewbe's code. I've just been running his MPG.zip up to now.

I don't think the fudge-factor is the problem because there is zero change in the gallons value when I rev the engine.

itjstagame 06-10-2009 10:29 AM

Gallons is total gallons used, not GPH or somekind of immediate value.

the 'gallon' is the smallest unit in Skewbe's code. Look at his code and compare to last post, I only have 2 small changes, everything I said in the last post applies to his code that you're using.

itjstagame 06-23-2009 01:09 PM

Could your issue be channel swap?

skewbe set up VSS as the left channel and inj as the right. I noticed on mine that my VSS was obviously the right channel (oops), so I made a simple mod to swap channels based on a config setting.

itjstagame 06-25-2009 02:41 PM

Ok, so I was getting a lot of 'randomness' everytime I tried using the app, even with now sound input.

I've determined that skewbes code to take b[x] - 127 to flip the bit and make it unsigned works fine for playback WAVs, but for real live running it fails.

The reason, he was asking for PCM_SIGNED in the main thread, but then he's flipping the bit later, so I changed this to PCM_UNSIGNED and all works great now. I'm not sure if all WAVs are unsigned by default or that's a seperate setting but now at least I've got this code is a reasonably good shape and trying to make a good coast down solver.

dkjones96 07-10-2009 11:59 AM

Okay, so I've been doing a little(a lot of) research.

I think I can build a system almost exactly like the SG for a hair over $55. It would include the ability to download new features and data logging to a memory card for manipulation later.


All times are GMT -8. The time now is 05:01 PM.

Powered by vBulletin® Version 3.8.8 Beta 1
Copyright ©2000 - 2024, vBulletin Solutions, Inc.