General Program Flow and Timing (cool project)

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey Guys,

I am using an Atmega 328p (8mhz) as a fuel injection controller. This is my first 'real' project that does something of significance instead of just tinkering. My main concern is how I should setup all my programmable devices, and when I should poll them or use interrupts. I am using quite a few things on the uC such as PWM, USART, ADC and general timer. I'll give you a quick rundown of how my minimal system will work. Basically there is a mass airflow sensor (MAF) that reads the intake air charge in g/sec. This is sent to the ADC to determine the amount of fuel/air mixture that the engine will need. From this, the uC calculates the injector pulse width and outputs a varying time from either 4.0ms to 60ms. Also, there is an RPM sensor on the flywheel to determine the engine speed. With these three basic things, the engine should run in a pre-mapped fuel mode without needing a closed loop device such as an o2 sensor. I also want to send out the current data (pulse width, rpm..etc) through the serial port to be monitored in a terminal window.

As it stands, I have most of this stuff coded and working except the rpm sensor (which will probably be a hall sensor), but my code seems cumbersome and inefficient. I am curious as to what the optimal way to run my programmable devices would be.

I heard people talking about having the adc/usart etc using interrupts and then servicing them in the main loop. If I were to do this I guess I would need to make my own flags for each ISR; then in the main loop I would service the flag if it was set? Does this seem right?

Timing is fairly critical as I don't want to miss an injection shot or something. I want to inject fuel once every 4 engine rotations (when the intake opens) which will be running anywhere from 600 to 4000rpm. Would it be better to have my ADC free-running and continuously reading the MAP sensor, or just do it once right before I calculate the pulse width? I am also a little curious as to how I am going to determine where the engine is in the cycle so I can shoot the fuel in at the right time.

Lastly, I want to send a data stream to a pc so I can view the variable data, but I don't want it to hinder any calculations. Should I setup a timer to interrupt once every second and then maybe send out the serial data once a second? Is this a good way of doing this?

Sorry for the long post. This has been a really fun project so far and I would like it to work as efficiently as possible.

Christan

Chief Tinkerer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Obviously you've studied MegaSquirt in great detail? They've obviously cracked all of this - the high level program design strategies, rpm and crank position detection etc etc...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MartinM57 wrote:
Obviously you've studied MegaSquirt in great detail? They've obviously cracked all of this - the high level program design strategies, rpm and crank position detection etc etc...

no I have not, but I will check it out.

Chief Tinkerer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think it is time to start diving into interrupt driven stuff. That will take a large load off of your main program flow.
also dive into an event system. that should get you going again to increase the efficiency of you processor and the load on the main loop.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For a reasonably simple ecu, the main calculations can work in a loop- say every 10ms. Not much changes within that time.you can run the adc polled and maybe do some calcs whilst the adc is converting. At the end of your calc cycle, copy the injection time etc for the timer isrs to use. Why inject every 4 revs? A four stroke engine has an intake cycle every 2 revolutions. You can fire the injectors at any time, not the most optimal method but has been used extensively. To do sequential injection and fire at intake you might want to use a micro with better timers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Christan,

I can try to offer some general guidelines.

Figure out the timing of the critical sections of your code. You can do this with a simulator, a 'scope and toggling pin or by using a spare timer.

Decide which sections have to run at a precise frequency (as opposed to "fast enough").

For your PC upload, consider using a TX interrupt, which has a very low overhead. As long as your data can be sent before your main loop finishes, you will be fine. If not, your transmission will be backlogged which means your data transmission determines the upper bound of your loop frequency.

Speaking of frequency, it seems your "main loop" frequency is determined by the engine speed (4000rpm -> 67Hz). Am I correct here or am I missing something. If so, this means all of your code must have a worst case run time of 15ms.

One point did confuse me a bit. If you wish to perform an injection every 4 revolutions, that's an injection every 60ms. You also said the injection pulse can be up to 60ms wide. If I understand you correctly, that means you may wish to attempt an injection IMMEDIATELY after finishing the last one. Further, if your engine speed is above 4000rpm, you won't be able to perform a 60ms injection every 4 revolutions because one injection will still be in progress when the next is scheduled to begin.

I look forward to hearing more,
Michael Jamet

Michael Jamet

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The timing critical part is reading the rpm and the injector timing. The calcs can be asynchronous and dont have to be tied to rpm. The only interrupts that should be needed are: input capture, output compare, timer overflow and the usart rx/tx. Ignition timing hasnt been mentioned, that would take another output compare. In terms of engine performance, more is to be gained by ignition control vs fuel control.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I got the impression (unstated) from post #1 that it was a diesel engine (given the rpm limit)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Another link for you. A friend of mine, Fred, set this up
DIYEFI.org

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the tips guys, they have gotten me thinking. Also I wanted to clarify on the engine a little. It is a 4stroke single piston gasoline engine that I have to use. I won't be touching the ignition and leaving it intact. The whole point of this project is to built a stand-alone fuel injection system. After a little research it looks as though the injection pulses can be at any given time in the combustion cycle which makes things a little easier.

As for interrupts, why are you thinking I would need a timer overflow interrupt? Not quite sure what you may be thinking.

Right now I have a linear hall sensor to measure RPM, but I think a digital one might be easier to interface. Then I could just have it trigger an external interrupt every pulse.

Chief Tinkerer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The timer overflow can be used as a system tick for general timing. I would connect a digital hall sensor to the input capture (ICP) pin rather than an external interrupt.

The downside of firing the injector when the intake valve is not open is that the fuel wets the intake wall. This affects emissions and throttle response which is why you dont see this technique being used in more modern vehicles. It was common practice in the 80's and early 90's.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does the intake valve start to open before TDC on the exhaust stroke? I guess the 'momentum' of the bang going down the exhaust pipe causes a suction? So you need to be able to start to open the injector with almost usec timing. I think it takes a couple ms to open, then its squirting at the WOT rate for the time you have computed, then 4ms to close. Does the intake close right at BDC or after? Anyway, the intake is open for MORE than the intake stroke. I know you have a single cyl engine, but here's my question: If it was a 6 cyl, then the total fuel flow would be 6 times the flow of one cyl? I had 'heard' that at WOT, the injectors were just open all the time, but that makes no sense to me. Anyone know fer sure?

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How do you change the engine speed? Don't you need a throttle position sensor for that?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Bob, depending on the cam timing, the intake can overlap the exhaust event. This is usually on high performance engines and the design of the exhaust affects the performance. You want to limit the max duty cycle for the injectors - maybe 70-80% otherwise they may overheat. When you fire the injector is irrelevant - there is enough heat in the intake to keep at least some of the fuel as vapour. Besides it doesnt have to hang around too long. The big V8s had TPI (throttle body injection) and on some it was totally asynchronous with the engine. As long as there was the right amount of fuel available, all was ok.

Sensing throttle position isnt entirely necessary as known the mass air flow and rpm you can estimate the required amount of fuel. However, you want throttle position in order for acceleration enrichment and knowing when you should be idling. You also need to know air temp, battery voltage (this affects the injector opening time) and engine temp.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I just read that it is a single cylinder. You want to add fuel every other engine rotation. I would think the fuel pulse range may be more typically start at 1mS however the injector opening time is near that value.

It is best to sample many MAP readings to get an idea of the cylinder filling. It is possible to measure RPM and feed a timer compare to generate multiple a/d samples in sync to engine speed.

It is possible to gather the trigger by using a signal from the present ignition system. It takes some work to condition the signal. Source could be points (the wire that is shorted to stop the engine), or a CT on the spark plug wire (like on timing light).

With MAP and engine temperature sensor, you should be able to do a nice job of fuel control.

pV = nRT is your friend (T is in Kelvin). By fueling every other revolution (720 engine degrees), RPM is accounted for except the VE vs RPM, this is what your fuel table adds.

You will need prime fuel and possibly start enrichment.

Enjoy

It all starts with a mental vision.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And more.

The serial communications will work fine. Use interrupt to set flag for received character, then process outside isr. I have used 500mS timer to throw out real-time info, and external data requests at rates as high as 10mS without problems at 57,600 baud.

In my system the calculation update for fuel and ignition is about 1mS. This leaves plenty of time.

It is important to use integer math for efficiency. It is also important to understand the use of shared variables (used by isr and calculations).

It all starts with a mental vision.