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

    clean up is done... time for fun.

     

    Sharp eyed folks out there might recognize, that most all the parts are in place for performing ignition management. The tach event array tkEv[] holds the TDC for each cylinder. By subtracting a value for total advance from each of the TDCs a coil event (coEv[]) angle is obtained. This is done simply in a short loop in the 1mS ignition process while the engine is running, similar to the loop to set the tkEv[] values during engine off. The value of total advance is calculated once, then applied to the tkEv in the loop. The other part of the operation is the start of dwell for each event, the dwell is a value that provides sufficient time to charge the coil, but not too much beyond fully charging the coil. This value is also captured as an angle, and the start of event (cost[]) is calculated by subtracting the dwell angle from the coil event angle. This is also done in the loop. The calculation of dwell angle is also a one time operation, and then applied in the loop.

     

    That wordy explanation, works out to just a few lines of code.

    UWord coEv[8];
    UWord coSt[8];
    
    void rtUpdateIgn(void) {
    ...
        updateTotAdv();
        updateDwlAng();
    ...
        if (tmOut > 0) {
    ...
            for (c = 0; c < cylCt; c++) {
                coEv[c] = tkEv[c] - getTotAdv();
                coSt[c] = coEv[c] - getDwlAng();
            }
    ...

     

    The two functions getTotAdv() and getDwlAng() return the angle of advance, and the angle of dwell calculated the one time.

     

    The last part is to include the operation in the scheduler, in the same way as the tach. The difference being, coil operation passes the cylinder number for cases where the operation is coil on plug, so the call to setCoil() has the coil number as well as the state.

     

                if ((min < coSt[c]) && (coSt[c] <= max)) { ft = (SLong)(coSt[c] - pa) * bs / PART2; ignCoHi(c, ft, tm); }
                if ((min < coEv[c]) && (coEv[c] <= max)) { ft = (SLong)(coEv[c] - pa) * bs / PART2; ignCoLo(c, ft, tm); }

     

    and the same for the other range of min/max

                if ((min < coSt[c]) || (coSt[c] <= max)) { ft = (SLong)(coSt[c] - pa) * bs / PART2; ignCoHi(c, ft, tm); }
                if ((min < coEv[c]) || (coEv[c] <= max)) { ft = (SLong)(coEv[c] - pa) * bs / PART2; ignCoLo(c, ft, tm); }

     

    The coil process takes over the fast timer operation, and the tach is moved to the slow operation.

     

    You might ask what values should go in total advance and dwell angle, and you are right to ask. For now, something like 20 degrees (1820) for dwell and 8 degrees (728) for dwell should be fine. To run some preliminary testing, the routines updateTotAdv() and updateDwlAng() can be stubbed out, and the getTotAdv() and getDwlAng() just return the constant values.

     

    Now it's getting fun.

     

    Jack

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

    clean up is done... time for fun.

     

    Sharp eyed folks out there might recognize, that most all the parts are in place for performing ignition management. The tach event array tkEv[] holds the TDC for each cylinder. By subtracting a value for total advance from each of the TDCs a coil event (coEv[]) angle is obtained. This is done simply in a short loop in the 1mS ignition process while the engine is running, similar to the loop to set the tkEv[] values during engine off. The value of total advance is calculated once, then applied to the tkEv in the loop. The other part of the operation is the start of dwell for each event, the dwell is a value that provides sufficient time to charge the coil, but not too much beyond fully charging the coil. This value is also captured as an angle, and the start of event (cost[]) is calculated by subtracting the dwell angle from the coil event angle. This is also done in the loop. The calculation of dwell angle is also a one time operation, and then applied in the loop.

     

    That wordy explanation, works out to just a few lines of code.

    UWord coEv[8];
    UWord coSt[8];
    
    void rtUpdateIgn(void) {
    ...
        updateTotAdv();
        updateDwlAng();
    ...
        if (tmOut > 0) {
    ...
            for (c = 0; c < cylCt; c++) {
                coEv[c] = tkEv[c] - getTotAdv();
                coSt[c] = coEv[c] - getDwlAng();
            }
    ...

     

    The two functions getTotAdv() and getDwlAng() return the angle of advance, and the angle of dwell calculated the one time.

     

    The last part is to include the operation in the scheduler, in the same way as the tach. The difference being, coil operation passes the cylinder number for cases where the operation is coil on plug, so the call to setCoil() has the coil number as well as the state.

     

                if ((min < coSt[c]) && (coSt[c] <= max)) { ft = (SLong)(coSt[c] - pa) * bs / PART2; ignCoHi(c, ft, tm); }
                if ((min < coEv[c]) && (coEv[c] <= max)) { ft = (SLong)(coEv[c] - pa) * bs / PART2; ignCoLo(c, ft, tm); }

     

    and the same for the other range of min/max

                if ((min < coSt[c]) || (coSt[c] <= max)) { ft = (SLong)(coSt[c] - pa) * bs / PART2; ignCoHi(c, ft, tm); }
                if ((min < coEv[c]) || (coEv[c] <= max)) { ft = (SLong)(coEv[c] - pa) * bs / PART2; ignCoLo(c, ft, tm); }

     

    The coil process takes over the fast timer operation, and the tach is moved to the slow operation.

     

    You might ask what values should go in total advance and dwell angle, and you are right to ask. For now, something like 20 degrees (1820) for dwell and 8 degrees (728) for dwell should be fine. To run some preliminary testing, the routines updateTotAdv() and updateDwlAng() can be stubbed out, and the getTotAdv() and getDwlAng() just return the constant values.

     

    Now it's getting fun.

     

    Jack

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
Children
No Data
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