Arduino as ECU?
#141
I started putting together a program in C#.. once it does something i'll compile it and send it over to you for testing.
Tomaj
#142
But regardless of the the fuel calculation (I will explain what I'm using as a test shortly), the end result is that the amount of fuel in the engine is determined by how long the injectors are open. Now the ECU will try to open the injectors for just the right amount of time to get the right amount of fuel in the engine for complete combustion (too little fuel and we start forming nitrous oxide, too much fuel and unburnt hydrocarbons get in to the exhaust). This command simply adds or subtracts the requested amount of microseconds from whatever the ECU has worked out that the injectors need to be open for... If you write a value of 1000, the injectors will be open for an extra millisecond (on top of what the ECU thinks should be) so the mixture will be rich, if you write a value of -2500, the injectors will be opened for 2.5milliseconds less than the ECU has worked out and the mixture will be lean. This is a gross adjustment and is basically like the choke on a carburettor
My fueling code at the moment assumes no loading on the engine, since it still hasn't been tested in a real engine, it is safe to say it's not going to be put in a car and driven around. This means the injector open time is a linear function of the AFM open amount (I.e. The amount of air introduced into the manifold).
So if the AFM is reading 0 volts, the injectors are open for 0 microseconds, if the AFM is reading 5volts (maximum air intake), the injectors are open for 12000microseconds (90% duty cycle at 8000RPM). It is a very simple way to do it, but should be sufficient for testing.
I started putting together a program in C#.. once it does something i'll compile it and send it over to you for testing.
Tomaj
Tomaj
#143
there's monomac... since this is a simple program porting may be easy. I also may look into doing this in java (But i hate programming in java, i can't get around to liking eclipse. any better simple IDEs?)
about the fueling "delta", i dont mean to be harsh but i don't see the value in that, may as well just leave that off until we can get the full 2D lookup working.
Also regarding AFM, i think most people around here are going to be using a MAP sensor. With the MS the MAP sensor is built into the unit, but for the arduino i guess we'll need an external one. Either way, the concept is the same (i think), higher voltage = higher pressure / more air.
about the fueling "delta", i dont mean to be harsh but i don't see the value in that, may as well just leave that off until we can get the full 2D lookup working.
Also regarding AFM, i think most people around here are going to be using a MAP sensor. With the MS the MAP sensor is built into the unit, but for the arduino i guess we'll need an external one. Either way, the concept is the same (i think), higher voltage = higher pressure / more air.
#144
OK the 1st version of "Arduiciu" is ready, it basically lists the serial ports available on the computer, lists common port speeds, allows you to open the serial port, has several non functioning buttons, and one button the "Get ECU status", which hypothetically will work.
I've uploaded it in a zip file, let me know if it works.
I've uploaded it in a zip file, let me know if it works.
#145
about the fueling "delta", i dont mean to be harsh but i don't see the value in that, may as well just leave that off until we can get the full 2D lookup working.
Also regarding AFM, i think most people around here are going to be using a MAP sensor. With the MS the MAP sensor is built into the unit, but for the arduino i guess we'll need an external one. Either way, the concept is the same (i think), higher voltage = higher pressure / more air.
#146
OK the 1st version of "Arduiciu" is ready, it basically lists the serial ports available on the computer, lists common port speeds, allows you to open the serial port, has several non functioning buttons, and one button the "Get ECU status", which hypothetically will work.
I've uploaded it in a zip file, let me know if it works.
I've uploaded it in a zip file, let me know if it works.
Really excited!!!
#148
Planning for the macos version)
#151
Coming up ASAP!
As the thread starter, I'm actually surprised you don't have one already
Very simple to get going. Buy the Arduino Uno, download the Arduino software (you can do this first if you prefer), copy and paste my ECU code into te Arduino IDE, plug Uno into your computer, hit upload... Done
This has to be the simplest way to get into Microcontroller development.
A word of warning, my code does require a CAS signal to run, otherwise it will just wait at the sync section of code. If you have a real CAS you can connect up then that would be perfect... Or you could use a second microcontroller to generate the CAS signal as I currently do.
I'll need to get an arduino i think so i can really play w/the ECU source too.. How hard is it to get that side working?
Very simple to get going. Buy the Arduino Uno, download the Arduino software (you can do this first if you prefer), copy and paste my ECU code into te Arduino IDE, plug Uno into your computer, hit upload... Done
This has to be the simplest way to get into Microcontroller development.
A word of warning, my code does require a CAS signal to run, otherwise it will just wait at the sync section of code. If you have a real CAS you can connect up then that would be perfect... Or you could use a second microcontroller to generate the CAS signal as I currently do.
Last edited by bloodline; 10-26-2010 at 03:35 AM.
#152
I found this (among others).. Apparently by searching for "arduino piggyback" and other terms i was able to find other interesting projects.
http://thedeltaecho.wordpress.com/20...ublic-release/
It seems there are a few people out there already experimenting with arduinos as ECUs in various forms.
I've e-mailed the guy working on this project to see how he's doing and whether he thinks there's any possibility of making a more generic system.
Tomaj
http://thedeltaecho.wordpress.com/20...ublic-release/
It seems there are a few people out there already experimenting with arduinos as ECUs in various forms.
I've e-mailed the guy working on this project to see how he's doing and whether he thinks there's any possibility of making a more generic system.
Tomaj
#153
I found this (among others).. Apparently by searching for "arduino piggyback" and other terms i was able to find other interesting projects.
http://thedeltaecho.wordpress.com/20...ublic-release/
It seems there are a few people out there already experimenting with arduinos as ECUs in various forms.
I've e-mailed the guy working on this project to see how he's doing and whether he thinks there's any possibility of making a more generic system.
Tomaj
http://thedeltaecho.wordpress.com/20...ublic-release/
It seems there are a few people out there already experimenting with arduinos as ECUs in various forms.
I've e-mailed the guy working on this project to see how he's doing and whether he thinks there's any possibility of making a more generic system.
Tomaj
Wow, I never managed to find any arduino ECU projects, my google skills are weak
This guy seems to be quite far ahead already, I will make sure his licence is compatible with mine and then read over his code.
I've already started my v0.6 codebase (only plotted on paper at the moment) with yet another significant change, moving away from the "busy wait" that I used to sync in the v0.5 code, to using interrupts. This will make my serial code work better, at the moment is isn't really working very well at all... It seems to be crashing your app now :(
-Edit- If you want to get into Arduino devlopment, I notice that you can get cheap Arduino clones on EBay, the "Seeduino" seems to get good reviews too (make sure you get one with the AVRMega328 CPU and running at 16Mhz, or my code won't work)
#154
Hello Miata enthusiasts...
I'm the author of the 2JZduino project and theDeltaEcho wordpress site linked to above.
ctxspy send me an e-mail to bring my attention here.
In brief, I've had preliminary success running an Arduino-based project as a piggyback on a 2JZ-GE (the 3L inline 6 used in the Lexus IS300, Toyota Altezza, Toyota Supra [non turbo]). It currently intercepts and delays crank sensor pulses (delays ignition timing), intercepts and scales injector signals (fuel mixture), and simulates narrowband O2 sensor output based on wideband O2 sensor input (programmable closed-loop AFR).
For more info I'll defer to my blog for now.
Anyway, if it turns out there is a project here to develop a more advanced Arduino-ECU I'd be happy to be involved in any way that's helpful.
I'll admit I haven't had time to read this thread in detail (just quickly perused it) but I will do that later today.
-Mitch
[Edit: P.S. I did see some early discussion in this thread about whether an Arduino was fast enough to handle engine control... this analysis and simulation was an early part of my work for 2JZDuino. See here...
http://thedeltaecho.wordpress.com/20...or-capability/ ]
I'm the author of the 2JZduino project and theDeltaEcho wordpress site linked to above.
ctxspy send me an e-mail to bring my attention here.
In brief, I've had preliminary success running an Arduino-based project as a piggyback on a 2JZ-GE (the 3L inline 6 used in the Lexus IS300, Toyota Altezza, Toyota Supra [non turbo]). It currently intercepts and delays crank sensor pulses (delays ignition timing), intercepts and scales injector signals (fuel mixture), and simulates narrowband O2 sensor output based on wideband O2 sensor input (programmable closed-loop AFR).
For more info I'll defer to my blog for now.
Anyway, if it turns out there is a project here to develop a more advanced Arduino-ECU I'd be happy to be involved in any way that's helpful.
I'll admit I haven't had time to read this thread in detail (just quickly perused it) but I will do that later today.
-Mitch
[Edit: P.S. I did see some early discussion in this thread about whether an Arduino was fast enough to handle engine control... this analysis and simulation was an early part of my work for 2JZDuino. See here...
http://thedeltaecho.wordpress.com/20...or-capability/ ]
Last edited by Mitch_1979; 10-28-2010 at 09:48 AM. Reason: P.S. added
#155
Hello Miata enthusiasts...
I'm the author of the 2JZduino project and theDeltaEcho wordpress site linked to above.
ctxspy send me an e-mail to bring my attention here.
In brief, I've had preliminary success running an Arduino-based project as a piggyback on a 2JZ-GE (the 3L inline 6 used in the Lexus IS300, Toyota Altezza, Toyota Supra [non turbo]). It currently intercepts and delays crank sensor pulses (delays ignition timing), intercepts and scales injector signals (fuel mixture), and simulates narrowband O2 sensor output based on wideband O2 sensor input (programmable closed-loop AFR).
For more info I'll defer to my blog for now.
Anyway, if it turns out there is a project here to develop a more advanced Arduino-ECU I'd be happy to be involved in any way that's helpful.
I'll admit I haven't had time to read this thread in detail (just quickly perused it) but I will do that later today.
-Mitch
[Edit: P.S. I did see some early discussion in this thread about whether an Arduino was fast enough to handle engine control... this analysis and simulation was an early part of my work for 2JZDuino. See here...
http://thedeltaecho.wordpress.com/20...or-capability/ ]
I'm the author of the 2JZduino project and theDeltaEcho wordpress site linked to above.
ctxspy send me an e-mail to bring my attention here.
In brief, I've had preliminary success running an Arduino-based project as a piggyback on a 2JZ-GE (the 3L inline 6 used in the Lexus IS300, Toyota Altezza, Toyota Supra [non turbo]). It currently intercepts and delays crank sensor pulses (delays ignition timing), intercepts and scales injector signals (fuel mixture), and simulates narrowband O2 sensor output based on wideband O2 sensor input (programmable closed-loop AFR).
For more info I'll defer to my blog for now.
Anyway, if it turns out there is a project here to develop a more advanced Arduino-ECU I'd be happy to be involved in any way that's helpful.
I'll admit I haven't had time to read this thread in detail (just quickly perused it) but I will do that later today.
-Mitch
[Edit: P.S. I did see some early discussion in this thread about whether an Arduino was fast enough to handle engine control... this analysis and simulation was an early part of my work for 2JZDuino. See here...
http://thedeltaecho.wordpress.com/20...or-capability/ ]
I have been working on this Arduino ECU project for a while, the this thread is getting a bit large and unfriendly. But I have got quite far now, you can find my latest code at sourceforge, under the project title of MiataBrain
I had a few obstacles to overcome using the Arduino, but I think I have solved all the major issues with the time critical and structural components of the code.
All that needs to be added now is the fuel calculation/table, I'm using a linear advance (that follows the factory settings) on the spark timing for now... but that can easily be replaced.
The two functions that need to be completed are (and really need to be tested in a real engine to get right):
sparkTime() // which returns the advance based on the engine state.
setInjFlowTime() // which returns the time the injector needs to be open based on the engine state.
I know that you are not working on a Mazda MX5, but you might be able to adapt the code, though it is hardcoded to the MX5 CAS...
#156
I found this (among others).. Apparently by searching for "arduino piggyback" and other terms i was able to find other interesting projects.
http://thedeltaecho.wordpress.com/20...ublic-release/
It seems there are a few people out there already experimenting with arduinos as ECUs in various forms.
I've e-mailed the guy working on this project to see how he's doing and whether he thinks there's any possibility of making a more generic system.
Tomaj
http://thedeltaecho.wordpress.com/20...ublic-release/
It seems there are a few people out there already experimenting with arduinos as ECUs in various forms.
I've e-mailed the guy working on this project to see how he's doing and whether he thinks there's any possibility of making a more generic system.
Tomaj
The command: 33 63 65 04 to request all data has been shortened to 63 65 04... the 33 command identifier byte was unnecessary and complicated/slowed the receive code on the arduino...
The ardunio will now respond to that request with 13 byte response (this will change as we need it to).
The first 4 bytes are a long unsigned value, the number of microseconds per half revolution of the crank... from this it is trivial to establish the RPM of the engine.
The second 4 bytes are the injector flow time, that is to say the duty cycle of the injectors in microseconds.
The third 4 bytes are the number of rotation ticks (512 per revolution) advance of the spark. At the moment I have it programmed that the spark always tries to advance the spark so that the spark fires about 1600 microseconds before TDC. The packet is terminated with a 06 as required by the spec.
Not sure what else we need at this time, but I'm sure we will think of something.
Make sure you flush you serial receive buffer before sending any commands or requests. The Arduino sends some random garbage during startup (and possibly other times, if any debug code is left in), so if you are not expecting any data from the arduino, reject anything as rubbish.
I have moved my code to version 0.6 now (available at https://sourceforge.net/projects/mia...ataBrain_v0.6/ ), which is fully interrupt based, timing is now accurate to 16 microseconds (or about half a degree of revolution at 8000RPM).
#157
Hi bloodline,
I just finished looking through your code. There are some nice simplicities in how you've built structs and variables... makes it rather nice to read compared to my project.
A couple of thoughts that came to mind as I went through it. They are timing related though and I haven't worked through how much more leniant the Miata engine is on timing (the 2ZJ has a 34 tooth crank wheel requiring Arduino to respond every 5 degrees). Anyway...
From "MiataBrain_v0_62.pde":
setup(), line 265: Is it possible for a Crank signal to occur during Serial.println("") and that it gets missed or the synchronization doesn't happen as expected?
aquireAnalog(), line 358: I'm sure you know analogRead() will suspend program flow until the ADC completes. The 4 sequential reads I think should probably consume about 1-2 ms. At redline this is on the order 90deg. I don't think you can afford to miss fuel injection by that much. The approach I took for ADC was to use an interrupt handler for ADC.complete, which processes the result, sets the next channel, kicks off the next ADC, and returns. This also affords a much larger ADC prescaler which seemed necessary because of the signal impedances I was metering.
datalink(), line 291: similar comments to above, running dataLink serially to your injector control logic I'd be wary of missing critical injector events by a substantial margin... but maybe that's what you intend to handle with the ring buffer TODO.
Maybe these thoughts will help. Cool project though, and I appreciate the cleanliness of the code. I'm actually considering now that a standalone might be more feasible on an Arduino than a piggyback for ECU (less logic load in a standalone).
-Mitch
I just finished looking through your code. There are some nice simplicities in how you've built structs and variables... makes it rather nice to read compared to my project.
A couple of thoughts that came to mind as I went through it. They are timing related though and I haven't worked through how much more leniant the Miata engine is on timing (the 2ZJ has a 34 tooth crank wheel requiring Arduino to respond every 5 degrees). Anyway...
From "MiataBrain_v0_62.pde":
setup(), line 265: Is it possible for a Crank signal to occur during Serial.println("") and that it gets missed or the synchronization doesn't happen as expected?
aquireAnalog(), line 358: I'm sure you know analogRead() will suspend program flow until the ADC completes. The 4 sequential reads I think should probably consume about 1-2 ms. At redline this is on the order 90deg. I don't think you can afford to miss fuel injection by that much. The approach I took for ADC was to use an interrupt handler for ADC.complete, which processes the result, sets the next channel, kicks off the next ADC, and returns. This also affords a much larger ADC prescaler which seemed necessary because of the signal impedances I was metering.
datalink(), line 291: similar comments to above, running dataLink serially to your injector control logic I'd be wary of missing critical injector events by a substantial margin... but maybe that's what you intend to handle with the ring buffer TODO.
Maybe these thoughts will help. Cool project though, and I appreciate the cleanliness of the code. I'm actually considering now that a standalone might be more feasible on an Arduino than a piggyback for ECU (less logic load in a standalone).
-Mitch
#158
A couple of thoughts that came to mind as I went through it. They are timing related though and I haven't worked through how much more leniant the Miata engine is on timing (the 2ZJ has a 34 tooth crank wheel requiring Arduino to respond every 5 degrees). Anyway...
If you trawl back through this thread you can see the timing diagrams I built with the help of the members here, from that I was able to make the code. Basically, the Miata engine only has two timing pulses per crank revolution (actually I did toy with a more elaborate timing system that used the cam pulse as well, but it didn't improve timings in my tests).
From "MiataBrain_v0_62.pde":
setup(), line 265: Is it possible for a Crank signal to occur during Serial.println("") and that it gets missed or the synchronization doesn't happen as expected?
setup(), line 265: Is it possible for a Crank signal to occur during Serial.println("") and that it gets missed or the synchronization doesn't happen as expected?
aquireAnalog(), line 358: I'm sure you know analogRead() will suspend program flow until the ADC completes. The 4 sequential reads I think should probably consume about 1-2 ms. At redline this is on the order 90deg. I don't think you can afford to miss fuel injection by that much. The approach I took for ADC was to use an interrupt handler for ADC.complete, which processes the result, sets the next channel, kicks off the next ADC, and returns. This also affords a much larger ADC prescaler which seemed necessary because of the signal impedances I was metering.
But in tests I found the Analog read function to block (as you point out) for upto 200 microseconds. My solution (which went against my original goal), was to set the prescaler at 1Mhz (21 microseconds per acquisition)... You are quire right that in a real engine, I might need a slower capture time... my solution would be to amplify and condition the signal with external hardware (a simple transistor and low pass filter should do, or even an op-amp...).
I have an interrupt based analog read function... but I fear that it might make the code a little too hard for beginners/less advanced programmers to read. Part of my design goal is for this code to be simple for anyone to have a go at using
I think you are probably right about this, and we will have to see how a real engine handles it...
datalink(), line 291: similar comments to above, running dataLink serially to your injector control logic I'd be wary of missing critical injector events by a substantial margin... but maybe that's what you intend to handle with the ring buffer TODO.
Maybe these thoughts will help. Cool project though, and I appreciate the cleanliness of the code. I'm actually considering now that a standalone might be more feasible on an Arduino than a piggyback for ECU (less logic load in a standalone).
-Mitch
-Mitch
I have though about your timing system, with the 34 tooth wheel... I think actually it would be rather easy to modify my code to use that... also with that resolution, timing would be much tighter
The required modification would be in the crankPulseInterrupt() function, where all I need to do is check for a high or low signal... for your timing wheel, that would need to be a bit more complex, and count the number of pulses (and call the correct function accordingly) and also the RPM calculation could be moved there (which would be nice)... everything thing else would remain the same.
#159
Hey Mitch, good to see you posting here.
Sorry i haven't gotten back to your e-mail, been preoccupied with getting my car running on my MS2.
I'll probably be getting an arduino as a christmas gift, so then i'll be more active in this project.
Mitch, bloodline, now that you've each seen the other's code, any ideas on how to proceed? Is there an opportunity to create a cooperative team project here?
Sorry i haven't gotten back to your e-mail, been preoccupied with getting my car running on my MS2.
I'll probably be getting an arduino as a christmas gift, so then i'll be more active in this project.
Mitch, bloodline, now that you've each seen the other's code, any ideas on how to proceed? Is there an opportunity to create a cooperative team project here?
#160
Mitch, bloodline, now that you've each seen the other's code, any ideas on how to proceed? Is there an opportunity to create a cooperative team project here?
I also think he is spot on about the need for asynchronous analogue reads... And would be delighted if he could build a new analogue section
I have an osciliscope hooked up to the injector signals and it is clear that the duty cycle is larger than it should be :(
If either of you want to join the sourceforge project, please send me a request and I will add you.
For my part, I want to optimize the code a bit more (and probably move it to an OOP design, as my earlier mbed port uses, to make the code cleaner).