Jump to content
abecedarian

LM3S8962 / LM3S2110 Engine Management System

Recommended Posts

To be general purpose, there are issues which must be addressed in the hardware interface and software interpretation of the sensors and triggers.

 

Sensors:

Obviously, we would like to re-use any sensors the vehicle provides. So code would need a way to support those. In addition, providing parameters to support common, off-the-shelf sensors could be provided, correct? For instance provide in-built support for various manufacturer's air, coolant and MAP sensors?

 

Triggers:

Obviously (again), support for different crank and cam triggers / pick-ups would be required.

 

See why I'm also looking at existing projects for this?

 

I am leaning towards being modular in the implementation, but not all-inclusive. I've already enough to do trying to figure out a basic system to run my motorcycle without the added overhead of figuring out how to run everyone else's engine. ;)

Share this post


Link to post
Share on other sites

Divide and conquer

 

*work in progress*

 

LM3S8962 board:

Idle state is lowest power mode, waiting for a signal to indicate the key has been turned on.

 

Power on:

Bring all inputs and outputs up is a safe state.

Power fuel pump on for 3 seconds to prime injection.

Sample TPS, coolant and air temperature sensors, and MAP (and barometric sensor if installed).

Determine if cold-start enrichment is needed and calculate amount based on coolant temp.

Calculate ambient air density from initial MAP (or baro) and standard constants.

Check for button press on device indicating user wants to modify settings prior to starting the engine:

If button is pressed within 5 seconds of power on means user wants to adjust something so provide GUI for setup and tuning via on-board buttons and oled:

Check for uSD card. If card is present, read and compare configuration settings to flash-stored data.

If SD == flash, assume flash has current settings. Send relevant settings to LM3S2110 device board.

If SD != flash, prompt user via on-board oled to choose:

A.) Import SD data and back-up Flash internally or to SD. Ask if user wants automatically discard Flash backup the next time the ignition is turned off.

If the user chose "Yes", SD contents are committed automatically, Flash back-up is deleted, unit powers down when the key is turned off.

If user chose "No", device will wait 5 minutes for a key press before turning off.

If a key is pressed, display will wake and prompt to keep or discard settings imported from SD.

If user chooses "Keep", remove Flash backup from SD card and power down the unit.

If user chooses "Discard", Flash backup is restored then deleted from SD and the unit powers down.

B.) Cancel.

 

Starting the engine:

Receives input indicating "Start" button was pressed (button does not need to be held down).

Apply power to O2 sensor. (If used- I'm still undecided).

Turn on fuel pump.

Beep 5 times, indicating preparing to start.

Begin sampling sensors:

- TPS, MAP and intake air temp as often as practicable, should be at least ??? times per second

- Coolant temperature and O2 (if installed): at least ??? times per second

Calculate desired fuel injector pulse width and send to device board.

Turn on starter relay.

Receive RPMs from device board:

If RPM's are sufficient to indicate the engine is running:

Turn off starter relay.

Enter normal running mode.

If within 5 seconds, RPMs aren't sufficient to indicate engine is running:

Turn off fuel pump.

Turn off starter relay.

Request from device board:

Last ignition timing setting (should be roughly constant until engine is within 15% or target idle speed)

Intervals between last 8 consecutive crank trigger events.

Intervals between last 4 consecutive cam trigger events.

{Any other variables I might later think to include.}

Send signal to device board to put all outputs in a safe state.

Beep the speaker and display on screen (scrolling) for 5 minutes:

Intake air and coolant temps.

MAP and TPS measurements.

Air/fuel ratio target.

Last RPM reading from device board.

Last crank and cam intervals.

{Any other variables I might later think to include.}

Power down and do not permit re-starting until key has been turned off.

 

 

 

Power down procedure:

Put all inputs and outputs in a safe state.

Send request to device board to put all inputs and outputs in a safe state.

Go through "save data" procedures mentioned above if necessary.

Power down.

 

LM3S2110:

Idle state is lowest power mode, waiting for a signal to indicate the key has been turned on.

 

receives general fuel requirements as calculated by the main board

accepts Interrupts generated by crankshaft and camshaft events

calculates engine RPM

calculates ignition timing and fuel injection timing

triggers ignition and injection events

 

*still work in progress*

Edited by abecedarian

Share this post


Link to post
Share on other sites
Guest Stellarisiti

You have been busy this weekend.

Share this post


Link to post
Share on other sites

You have been busy this weekend.

I agree. :)

But then, I do often ramble a lot before I start producing results.

 

A former "boss" used to get mad because I would stand around, looking around for an hour or more even, before I began work.

But he was hard-pressed to find any faults with the work I did afterwards.

 

The addage is: "measure twice, cut once". The implication is planning ahead and verifying what was done follows the plans seldom results in failure.

 

 

 

 

Did I mention the plan I have for using an MSP430G2553 as a state machine in order to simulate the motorcycle for use to feed back triggers and such to this?

Share this post


Link to post
Share on other sites

* air / fuel calculations *

 

Here's one of the tricky parts: calculation of exactly how much air is entering the engine in order to determine how much fuel to inject.

 

The simplest is direct measurement with a MAF (Mass Air Flow) sensor. But my bike doesn't have one; I have MAP sensors instead.

And I know of no MAF sensors rated for a 500cc engine to substitute in.

 

With MAP sensors, I know differential pressure between atmospheric and the intake system between the throttles and cylinders.

Theoretically, if I know how much air the engine can suck in, I can extrapolate backwards the amount of air entering the system.

But here's where it gets tricky.... Even though I know how much air the engine can theoretically ingest- it's displacement, because

various factors like the throtthle, intake and exhaust valve timing affect how quickly air can get in at various RPM's, I have an unknown

to deal with- "Volumetric Efficiency". For lack of a better explanation, it's a ratio between how much can and how much actually does get in.

Much simplified: I know various things about what the engine is doing. I know RPM, intake pressure, ambient air pressure and temperature.

 

Rather straight-forward (but involved) calculations can get me in the ball-park, but not quite there due to that "VE" term:

 

{required fuel} = (36000000) * [engine displacement in cubic inches] * [air density]) / ([# cylinders] * [stoicihiometric air/fuel ratio] * [injector flow rate in lbs/hour]) * (1/[# injectors])

note- 36000000 is the number of 1/10 milliseconds in an hour, which is necessary because the injector flow rate is specified in pounds per hour and the injector pulse width is calculated in milliseconds; if injector rating was specified as cc/min, the number of 1/10 millimeters in a minute would be used: 600000.

 

In my case:

[engine displacement in cubic inches] = 30.32197

[air density] = (0.0391568 * ( [MAP sensor reading in kPa] * 10 - 31.0) ) / ( ( [air temp in F] + 459.7) * 1728)

- - - - - - - - - - {the above are barometric air pressure and ambient temperature}

[# cylinders] = 2

[stoichiometric air/fuel ratio] = 14.7 for gasoline, 9.765 for E85, 9 for ethanol

[injector flow rate in lbs/hour] = 37.1

[# injectors] = 2

 

From there, the injector pulse width (in milliseconds) = {required fuel} * VE * (intake manifold MAP (in kPa)) * (any other compensations for intake air temp, desired air/fuel ratio, etc) + (accelerator enrichment- needed only to compensate for a sudden twist of the throttle) + (injector open / closing time compensations in milliseconds)

... or at least that's the theory.

 

Since required fuel was initially calculated to reference barometric air pressure and temperature, VE compensates for how much air actually gets in. When the turbo has overcome the restrictions in the intake manifold and is pumping exactly the engine displacement worth of air into the engine, VE would = 1. At idle, VE may be 0.35 (or similar value), and at full boost it may be greater than 1.45; feasible since 19 psi boost = ~230 kPa and ambient is ~102 kPa...but gasoline produces slightly more bang with a richer fuel mixture and additional fuel is also needed to help cool the cylinders and prevent detonation.

 

 

So unless someone can come up with a way to factor out VE, I'm stuck with it. I could use feedback from an O2 sensor to target the desired air/fuel ratio at a given RPM and throttle position, but that's fixing the issue after the fact and just one bad calculation, or O2 failure would cause bad damage to the engine.

Share this post


Link to post
Share on other sites

* crankshaft position / ignition timing *

 

Sort of a scratchpad here, gathering and sharing my thoughts, so please bear with me if I'm repeating myself, myself....

 

Looking at the rear of the engine, two crank position sensors, right +40 degrees from vertical, left -40 from vertical, crankshaft rotation is counter-clockwise.

Right cylinder fires, crank turns 440 degrees (360 + 80 cylinder separation), left cylinder fires, crank turns 280 degrees, repeat (440 + 280 = 720):

(not quite to scale, but close)

 

stroke:   igniton	   exhaust
cylR   ----|------------------|--------------
cylL   --------|------------------|----------
stroke:	    exhaust		  igniton

 

So I need to establish correlation between piston positions, corresponding cam sensors and intake / exhaust valves and determine the easiest way to accurately resolve crankshaft position to within 0.1 degree or better, if possible.

 

Remembering that the crank "tooth" leads piston TDC by 25 degrees, and assuming the right cylinder triggers first, if the right cam sensor triggers at TDC, the duration between the two triggers should give me a representation of crankshaft insight to RPM at that time. Then, knowing the left cylinder lags the right cylinder by 80 degrees, I may be able to increase the accuracy by comparing the delay between those triggers' signals, and carrying that forward through the next cycle:

 

cylR ----|------------------|--------------
camR -----|--------------------------------
cylL --------|------------------|----------
camL ----------------------------|---------

 

Of course, if the cam sensor triggers could offset elsewhere in relation to the crankshaft position, but may be able to be handled similarly- would just have to determine their position. By knowing the relative positions of the sensors to each other, it would be possible to predict what the interval to the next trigger should be, and from there be able to compensate for an accelerating or decelerating crankshaft and maintain accurate ignition timing.

 

I'm looking at having 3 interrupts per revolution. 10000 is the practical redline of the engine so:

10000 (RPM) / 60 = 166.67 (Rev/second) * 3 (interrups per rev) = ~500 interrupts per second.

 

Do you think the 2110 can handle that, the ignition advance calculations and triggering ignition (one ignition event per revolution)?

Share this post


Link to post
Share on other sites

* sensor, trigger, fuel injectors, ignition coils & interfacing to the board(s)

* this is a general list and would vary based on necessity / application

* what I want to initially provide for, configurable during operation.

 

Required sensors:

TPS. Type: linear. Output: analog resistance corresponding to throttle position. Range: will vary by unit; from datasheet or field testing. Connections: 0v, 5v, signal return.

MAP: Type: linear. Output: analog resistance corresponding to absolute pressure. Range: will vary by unit; from datasheet or field testing. Connections: 0v, 5v, signal return.

CLT: Type: linear. Output: analog resistance corresponding to coolant temperature. Range: will vary by unit; from datasheet or field testing. Connections: 5v, signal return.

IAT: Type: linear. Output: analog resistance corresponding to intake manifold air temperature. Range: will vary by unit; from datasheet or field testing. Connections: 5v, signal return.

 

Optional sensors:

Baro: Type: linear. Output: analog resistance corresponding to absolute pressure. Range: will vary by unit; from datasheet or field testing. Connections: 0v, 5v, signal return.

AAT: Type: linear. Output: analog resistance corresponding to ambient air temperature. Range: will vary by unit; from datasheet or field testing. Connections: 5v, signal return.

KNK: Type: (to be determined- may be digital or analog / acoustical). Output: digital or analog based on type.

NBO2: Type: analog: Output: voltage relating to exhaust O2. Range: ~0.1v<>0.9v1. Connection: signal; may require external voltage and ground.

WBO2: Type: analog: Output: voltage relating to exhaust. Range: ~0.1v<>~5v2. Connection: signal; may require external components to operate.

 

 

Other inputs:

Start button press.

4 inputs for crank / cam triggers, each individually enabled / disabled by software: hall effect, optical or variable reluctor. Provides flexibility to use various trigger types & configurations. Possible configurations could include: crankshaft wheel + cam sync; dual crank + dual cam sync; cam position + cam sync.

Vehicle speed. Not necessary, but could have uses such as fuel economy calcs?

 

 

Outputs:

2 or 4 ignition outputs. Logic level or switched ground output.

2 or 4 injector outputs. Logic level output. User provides "peak and hold" or "saturated" driver transistor.

Fuel pump relay.

Starter relay.

 

 

Any comments?

 

 

 

 

 

1)- Approximately 0.5v out means the air/fuel mixture is at the stoichiometric ratio for gasoline. Above means it's lean and below means it's rich, but how much lean or rich cannot be determined accurately. Most ECU's using this type of sensor oscillate between rich and lean, trying to keep an average of 0.45-0.5 volts over a period of time.

2)- A roughly linear output which correlates to air/fuel ratios from ~8:1 (very rich) to ~18:1 (very lean).

Edited by abecedarian

Share this post


Link to post
Share on other sites

Having some issues with compiling code... this is proabably due to re-using code from another individual who likely had a more liberal compiler.

But basically, CCS doesn't like defining arrays based on runtime variables, and for whatever reason, using malloc related work-arounds won't compile either.

 

int get_packet( fixed *p, int numbytes ) /* retrieve packet from serial in queue	*/
{			 /* packets are some number of fixed point values */
union			 /* plus an 8 bit checksum	 */
 {								
   u_char tchar[numbytes];		

.... 

 

Is valid C99 code, but CCS baulks at it.

 

Maybe I should say "Meh" and remove the code and write a different handler. This is part of a serial (RS232) / terminal interface for another EFI system but since I'm not planning on using that ,it probably could go away. I'll just have to remove / alter dependancies on this function.

 

 

 

I also have a warning that "u_long" can't be assigned to an entity of the type "long *".

But I'm trying to address the critical errors which keep the code from compiling, then I'll address type casting.

... and then figure out how to make it work.

Share this post


Link to post
Share on other sites

 

But basically, CCS doesn't like defining arrays based on runtime variables, and for whatever reason, using malloc related work-arounds won't compile either.

 

malloc is generally frowned upon in memory constrained devices (for obvious reasons). I didn't even know that it was included in the std lib, but if not you could probably implement your own (with all the risks associated). Make sure you also provide a heap in the linker script.

 

I also have a warning that "u_long" can't be assigned to an entity of the type "long *".

 

You're trying to assign an unsigned long to a pointer to a signed long. AFAIK that should be possible (as both pointers and longs are 32bits wide), but it really isn't the correct thing to do (I don't really know what you're trying to do).

Share this post


Link to post
Share on other sites

malloc is generally frowned upon in memory constrained devices (for obvious reasons). I didn't even know that it was included in the std lib, but if not you could probably implement your own (with all the risks associated). Make sure you also provide a heap in the linker script.

 

 

 

You're trying to assign an unsigned long to a pointer to a signed long. AFAIK that should be possible (as both pointers and longs are 32bits wide), but it really isn't the correct thing to do (I don't really know what you're trying to do).

 

 

It's some code from another EFI project, part of a serial communication parsing function. Nothing I really need for my project unless I choose to add that capability.

 

I imported the code just to see what compile errors I would get. http://sourceforge.n...ource=directory The people who started it moved on the do Megasquirt.

 

I'm looking at various projects as learning tools, seeing how others did things.

Share this post


Link to post
Share on other sites

I received word from the open5xxxecu.org site that the code is indeed free to use.

 

Now, to decide if I want to keep with their use of cocoOS as an rtos or strip it out.

Share this post


Link to post
Share on other sites

Now, before anyone says I should get the software running before working on the hardware, I have to say that knowing what hardware I have to work with gives insight to what the software has to do.

 

So....Providing power to the system and sensors, and interfacing those with the MCU.

The Eval kit requires +5Vdc as do most of the sensors. Therefore, an isolated, well filtered and well-regulated (and protected) system is required. I do not believe I should provide 2 systems: one for the board itself, and another for the sensors: my intuition says I should have them on the same system so they have the same power and ground references. The board and sensors should source and return to their own ground plane, ideally routed away from other wires which carry high voltages or high transient voltages.

 

The crankshaft and camshaft VR's are another story.The camshaft sensors can generate between -5VDC and +20VDC, depending upon RPM's: lower RPM's make corresponding low voltage. The profile on the trigger wheel is what causes the off-center generation of voltages.

 

This is the pulse train from the cam sensors with the cam rotating at approximately 6000 RPM (equating to 12000 crankshaft RPM), and you can see the bias towards positive voltage instead of the typical equidistant positive/negative swing one would expect from VR's:

8084607859_9502706453_n.jpg

 

Below is a view of the cam lobe, looking at it from the rear/bafck of the engine (it and the crankshaft rotate counter-clockwise from this view). You can see the sharp rise (at around 4-5 o'clock) then the tapering off of the profile, which is what causes the bias towards positive voltage output (the single lobe drives both cam sensors):7713778064_c721333c32_n.jpg

 

Normally, one would capture the negative 0 volt crossing of a VR sensor as that would be when the tip of the trigger is leaving the centerline of pickup but... interference from the other sensor (note coincident negative pulses when the other sensor goes positive in the photo above) precludes that option. Therefore, I need these to trigger when going positive... more about that in a moment.

 

The crankshaft, on the other hand, can swing from -150Vdc to +150Vdc. Sorry, no 'scope capture of that. But these do output what would be expected from a VR sensor: equal positive and negative swings in voltage, corresponding with entering, transitioning through and exiting the sensor's envelope. And these, I need to trigger on the zero negative edge since the sensors generate positive voltage as the "tooth" enters the sensor and quickly shifts to negative voltage as the "tooth" passes the centerline of the sensor.

 

Significant isolation between the cam and crank sensors and the main board / controller is requried due to the high voltages the sensors can generate.The crank sensors should be okay using LM1815 (http://www.ti.com/lit/ds/symlink/lm1815.pdf), but they may need some resistors added inline to limit the positive peak to negative peak voltage, or maybe I can find a more appropriate device to handle those sensors. The cam sensors however, since I want positive-going triggers MAY work with the LM1815 if I can find a way to invert their signal, i.e. maybe wire backwards so they generate +4 <> -20 Vdc output. Further research indicates the cam sensors can be detected positive going negative so the LM1815 would suffice. The four wires from the two sensors are un-shielded from each other and is what's causing the cross-talk. Since I'm going through the trouble of re-wiring most of the engine electrical, two individual, shielded conductors will be used.

 

 

*Ignition coils-I intend on using GM LS2 coils which require +12v and ground, and a high (+3 to +5Vdc) then low signal of 5-6ms duration to trigger fire. Some coils require longer "dwell" time in order to build up the field to cause spark when the field collapses, but these don't, and actually limits dwell to ~8ms making any attempts to lengthen the dwell irrelevant: longer dwell is not needed.

 

*Injectors-After computing the injector duration, there has to be some way of triggering them. LM1949 (http://www.ti.com/li...link/lm1949.pdf) seems to be a decent way of dealing with the Low-Z injectors I am using. Turn it on, hold it on as long as needed then off, all with 5V logic; it handles the rest (with appropriate transistors to handle the 12v the injectors require of course). The alternative is using PWM to hold the injectors open, which I think is not the best way due to needing the processor to intervene with PWM calcs... it's much easier to turn an output on and off than it is to try PWM'ing multipe outputs.Any thoughts?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×