element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Ben Heck Featured Content
  • Challenges & Projects
  • element14 presents
  • element14's The Ben Heck Show
  • Ben Heck Featured Content
  • More
  • Cancel
Ben Heck Featured Content
Forum Engine Management
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Ben Heck Featured Content to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • Replies 63 replies
  • Subscribers 48 subscribers
  • Views 4644 views
  • Users 0 members are here
Related

Engine Management

jack.chaney56
jack.chaney56 over 9 years ago

Hi Ben,

I am a programmer with a very small amount of skill with circuits, and am looking to create a platform for an engine management system, using an Arduino Mega 2560. I had done a bit of the coding, when I ran into some timing issues with the built in Arduino manager, so I switched over and started using AVR Studio and a programmer to go directly to the chip itself.  The code looks like it should work ok, but now I need some additional circuits to handle the energy levels of coils and injectors (Something like IGBTs). Sensors are being run through simple dividers (no protection yet), and cam and crank inputs are through a simple comparitor

 

Let me know what you think,

Jack

  • Sign in to reply
  • Cancel

Top Replies

  • jack.chaney56
    jack.chaney56 over 7 years ago +2
    Back again... After a bit of time away seeking enlightenment (and a steady paycheck), I am ready to get back to work on my project. I have continued to play around with the code and a number of components…
  • jack.chaney56
    jack.chaney56 over 7 years ago +2
    I want to start this thing right, so the shopping list for people that want to play along at home: Raspberry Pi - version is not significant if you don't mind a slow response when using Eclipse, but 3B…
  • jack.chaney56
    jack.chaney56 over 7 years ago +2
    Start off with two things. First, I forgot (neglected) to provide instruction on how to get the compiled code onto the Nano. Fault of familiarity; having done the process so many times, I had shifted to…
Parents
  • jack.chaney56
    jack.chaney56 over 7 years ago

    Coming to the end of phase 1 of the project. I am attaching a zip file with the source to this stage. The next stuff starts getting into engine theory and why timing of certain events is more critical than others.... Oh dear, I have a nice zip file, and can't find how to attach it here. I will do some searching, then attach it as soon as I figure it out.  On to engine theory stuff...

     

    When the ignition event occurs (piston ignition), there is a downward force on the piston which is converted into a rotational force by the piston rod and crankshaft. When this happens, there is a similar force in the opposite direction which produces a wobble of the motor. Because things are generally bolted down, the motor doesn't jump out of the compartment, however the force still is there. The goal is to reduce the effect caused by this rocking motion. The solution implemented is to have the pistons fire in a sequence to balance out the forces. This is why engines implement a firing sequence Chevy uses 18436572 for an 8 cylinder motor. It is possible to keep this sequence stored someplace in an array, and just read the array value based on the sequence number in the coil firing sequence, and for many, many operations, this is the method used.  But I looked at the problem, and said, how do I make this easier for the controller. The solution became simple, just save the angle in the array properly.  For the Chevy 8 cylinder example; cylinder 1 is zero degrees, cylinder 8 is at the first position past 0, or 90 degrees. cylinder 4 is in the second positon, or 180 degrees, cylinder 3 is next at 270, etc.  When the exercise is over, the array of positions is (using our radians and the tkEv array).

    tkEv[0] = 0;

    tkEv[1] = 57344;

    tkEv[2] = 24576;

    tkEv[3] = 16384;

    tkEv[4] = 40960;

    tkEv[5] = 32768;

    tkEv[6] = 49152;

    tkEv[7] = 8192;

     

    Which is how it gets stored in the calibration section, along with the cylinder count (8). The calisthenics can be performed in the user interface for the calibration program. Returning to the program, the window is compared to each cell of the array and when the value is within the window, the event is scheduled. it can be seen that the counter for doing the comparison, now holds the proper cylinder number.

     

    Next thing to look at is the issue of "advance". For those that don't know already, in a cylinder, fuel and air are mixed to produce a flammable mixture, then under pressure, the mixture is ignited by a spark. The ignition of the fuel mixture is not instantaneous. In super slow motion, it is interesting to see the burning of the mixture occurs in a traveling wave. The goal is to maximize the impact of the wave at the point of TDC, so the greatest amount of energy is transferred to the down stroke of the power cycle. Because the rate of burn changes based on pressure and does not happen instantaneously, the command to ignite fuel happens before the cylinder reaches TDC. This is called the advance, and is measured as an angle. As the speed of the motor increases, the angle of advance also increases to compensate for the burn rate remaining generally the same. However, the rate of burn is somewhat dependent on pressure as well, so there is also a pressure compensation that needs to be factored in. Earlier in the compression cycle means the pressure value is lower, also, if the intake volume, measured by manifold air pressure (MAP), is lower or higher, the compression value changes as well. The good news is, the change in compression based on cylinder position sort of balances out because it generally increases to a stable amount and the RMS value (this is sort of based on a sinusoidal curve), stays pretty static, the MAP is the governing factor and the lower the MAP the more time is needed, so the advance increases. We have identified two components that influence the value of advance, the RPM and the MAP. The ignition is actually a chemical reaction called oxidation. Because it is a chemical reaction, the ambient temperature of the container (cylinder) also factors into rate of reaction. This means that temperature will also need to be factored into the value of total advance.

     

    Sounds a little like this is getting into some complex math during runtime. The rule in embedded systems is a table is always faster. So, how to use a table in this case. Quite simply, if the table is a two dimensional array, with one axis as the RPM and the other as MAP, the table can be constructed so the value of advance resides at the array cell based on the RPM and MAP coordinates. However, for a reasonable range of MAP values and RPM speeds, the array would tend to become very large. In order to keep the table size reasonable, some math is necessary. The technique is called planar interpolation. You may be familiar with linear interpolation where one value X0 and another value X1 and the f(x) values Y0 and Y1 that equate. Any point Yn along the line segment, can be calculated based on the Xn point. The equation is:

                      Xn x (Y1 - Y0)

    Yn = X0 + ---------------------

                          (X1 - X0)

     

    Similarly this operation can be done in two dimensions. The difference is, instead of using two end points, the operation uses the four corner points of a plane. The corner points are Z0, Z1, Z2, and Z3 and relate to X0, X1, Y0, and Y1 where Z0 is the value at (X0,Y0), Z1 is at (X1,Y0), Z2 at (X0,Y1), and Z3 at (X1,Y1). The formula resolves to:

     

    Z0(X1-Xn)(Y1-Yn) + Z1(Xn-X0)(Y1-Yn) + Z2(X1-Xn)(Yn-Y0) + Z3(Xn-X0)(Yn-Y0)

    ----------------------------------------------------------------------------------------------

                                           (X1-X0)(Y1-Y0)

     

    Thats the formula, I'll add it to code in a little while. I want to save this so it isn't lost (lots of editing)

     

    Jack

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
Reply
  • jack.chaney56
    jack.chaney56 over 7 years ago

    Coming to the end of phase 1 of the project. I am attaching a zip file with the source to this stage. The next stuff starts getting into engine theory and why timing of certain events is more critical than others.... Oh dear, I have a nice zip file, and can't find how to attach it here. I will do some searching, then attach it as soon as I figure it out.  On to engine theory stuff...

     

    When the ignition event occurs (piston ignition), there is a downward force on the piston which is converted into a rotational force by the piston rod and crankshaft. When this happens, there is a similar force in the opposite direction which produces a wobble of the motor. Because things are generally bolted down, the motor doesn't jump out of the compartment, however the force still is there. The goal is to reduce the effect caused by this rocking motion. The solution implemented is to have the pistons fire in a sequence to balance out the forces. This is why engines implement a firing sequence Chevy uses 18436572 for an 8 cylinder motor. It is possible to keep this sequence stored someplace in an array, and just read the array value based on the sequence number in the coil firing sequence, and for many, many operations, this is the method used.  But I looked at the problem, and said, how do I make this easier for the controller. The solution became simple, just save the angle in the array properly.  For the Chevy 8 cylinder example; cylinder 1 is zero degrees, cylinder 8 is at the first position past 0, or 90 degrees. cylinder 4 is in the second positon, or 180 degrees, cylinder 3 is next at 270, etc.  When the exercise is over, the array of positions is (using our radians and the tkEv array).

    tkEv[0] = 0;

    tkEv[1] = 57344;

    tkEv[2] = 24576;

    tkEv[3] = 16384;

    tkEv[4] = 40960;

    tkEv[5] = 32768;

    tkEv[6] = 49152;

    tkEv[7] = 8192;

     

    Which is how it gets stored in the calibration section, along with the cylinder count (8). The calisthenics can be performed in the user interface for the calibration program. Returning to the program, the window is compared to each cell of the array and when the value is within the window, the event is scheduled. it can be seen that the counter for doing the comparison, now holds the proper cylinder number.

     

    Next thing to look at is the issue of "advance". For those that don't know already, in a cylinder, fuel and air are mixed to produce a flammable mixture, then under pressure, the mixture is ignited by a spark. The ignition of the fuel mixture is not instantaneous. In super slow motion, it is interesting to see the burning of the mixture occurs in a traveling wave. The goal is to maximize the impact of the wave at the point of TDC, so the greatest amount of energy is transferred to the down stroke of the power cycle. Because the rate of burn changes based on pressure and does not happen instantaneously, the command to ignite fuel happens before the cylinder reaches TDC. This is called the advance, and is measured as an angle. As the speed of the motor increases, the angle of advance also increases to compensate for the burn rate remaining generally the same. However, the rate of burn is somewhat dependent on pressure as well, so there is also a pressure compensation that needs to be factored in. Earlier in the compression cycle means the pressure value is lower, also, if the intake volume, measured by manifold air pressure (MAP), is lower or higher, the compression value changes as well. The good news is, the change in compression based on cylinder position sort of balances out because it generally increases to a stable amount and the RMS value (this is sort of based on a sinusoidal curve), stays pretty static, the MAP is the governing factor and the lower the MAP the more time is needed, so the advance increases. We have identified two components that influence the value of advance, the RPM and the MAP. The ignition is actually a chemical reaction called oxidation. Because it is a chemical reaction, the ambient temperature of the container (cylinder) also factors into rate of reaction. This means that temperature will also need to be factored into the value of total advance.

     

    Sounds a little like this is getting into some complex math during runtime. The rule in embedded systems is a table is always faster. So, how to use a table in this case. Quite simply, if the table is a two dimensional array, with one axis as the RPM and the other as MAP, the table can be constructed so the value of advance resides at the array cell based on the RPM and MAP coordinates. However, for a reasonable range of MAP values and RPM speeds, the array would tend to become very large. In order to keep the table size reasonable, some math is necessary. The technique is called planar interpolation. You may be familiar with linear interpolation where one value X0 and another value X1 and the f(x) values Y0 and Y1 that equate. Any point Yn along the line segment, can be calculated based on the Xn point. The equation is:

                      Xn x (Y1 - Y0)

    Yn = X0 + ---------------------

                          (X1 - X0)

     

    Similarly this operation can be done in two dimensions. The difference is, instead of using two end points, the operation uses the four corner points of a plane. The corner points are Z0, Z1, Z2, and Z3 and relate to X0, X1, Y0, and Y1 where Z0 is the value at (X0,Y0), Z1 is at (X1,Y0), Z2 at (X0,Y1), and Z3 at (X1,Y1). The formula resolves to:

     

    Z0(X1-Xn)(Y1-Yn) + Z1(Xn-X0)(Y1-Yn) + Z2(X1-Xn)(Yn-Y0) + Z3(Xn-X0)(Yn-Y0)

    ----------------------------------------------------------------------------------------------

                                           (X1-X0)(Y1-Y0)

     

    Thats the formula, I'll add it to code in a little while. I want to save this so it isn't lost (lots of editing)

     

    Jack

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
Children
  • jack.chaney56
    jack.chaney56 over 7 years ago in reply to jack.chaney56

    ...as expected, I checked my work after my panic of loosing all my work and noticed the linear interpolation was a little wrong. The X0 + should be a Y0 +

     

    sorry again

    Jack

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube