View Single Post
Old 08-25-2013, 04:26 PM   #18 (permalink)
t vago
MPGuino Supporter
 
t vago's Avatar
 
Join Date: Oct 2010
Location: Hungary
Posts: 1,807

iNXS - '10 Opel Zafira 111 Anniversary

Suzi - '02 Suzuki Swift GL
Thanks: 830
Thanked 708 Times in 456 Posts
Quote:
Originally Posted by pgfpro View Post
Nice Work!!!

How many hours so far do you have in this???
Thank you!

I think that I have put in about 6 hours, actually coding and debugging the pressure correction code. However, I spent about a week, looking at square root (and other math) algorithms, trying to get some inspiration. In the end, I figured that a simple approach was best. Coding the filtering algorithms for reading MAP voltage took about another couple of hours.

Here's the code that I am going to test later on today, on the road.

Code:
void readMAP(void) {

	static unsigned long wp;
	static unsigned int sample;

	sampleCount = sampleTickLength - 1; // reset sample timer counter

	sample = sample + 3 * analogValue; // first order IIR filter - filt = filt + 3/4 * (reading - filt)
	sample >>= 2;

	wp = (unsigned long)(sample - analogFloor);
	wp *= (unsigned long)analogSlope;
	wp /= 1000ul;
	pressure[MAPpressureIdx] = (unsigned int)wp;

	// if vehicle is not running and is not moving, it's a fair bet that the intake manifold contains atmospheric pressure
	if (!(dirty & dirtyGoodVSS) && !(dirty & dirtyGoodInj)) pressure[baroPressureIdx] = pressure[MAPpressureIdx];

	// calculate differential pressure seen across the fuel injector
	wp = (unsigned long)pressure[fuelPressureIdx] + (unsigned long)pressure[baroPressureIdx] - (unsigned long)pressure[MAPpressureIdx];
	pressure[injPressureIdx] = (unsigned int)wp;

	// to get fuel pressure ratio, multiply differential pressure by denominator factor (1 << 12), then divide by fuel system pressure
	wp <<= 12;
	wp /= (unsigned long)pressure[fuelPressureIdx];

	// calculate square root of fuel pressure ratio
	pressure[injCorrectionIdx] = iSqrt((unsigned int)wp);

}

unsigned int iSqrt(unsigned int n) {

	unsigned long w = 4096; // square factor guess
	unsigned int t = 4096; // proposed square root
	int d; // difference between guess and proposed
	int od = 0;

	for (uint8_t x = 0; x < 5; x++) {

		od = d;
		d = n - (unsigned int)w;
		d >>= 1;
		t += d;

		od += d;

		if ((d == 0) || (od == 0)) break;

		w = (unsigned long)t * (unsigned long)t;
		w >>= 12;

	}

	return t;

}
Bemchmark testing reveals that readMap() takes about 110 us to execute, and iSqrt() takes about 33 us.
  Reply With Quote