Arduino as ECU?
Disclaimer: I know next to nothing about this stuff.
Anyone ever think about using an Arduino as an ECU? http://arduino.cc/en/Main/ArduinoBoardMega The Mega is coincidental, has nothing to do with megasquirt ( i think ). Some potential benefits to using this as a platform to build onto:
Now feel free to tell me why this won't work :) |
probably not enough program memory. also the 8bit mcu is less powerful than a ms2. Now if you start talking about like a avr32 then you are talking. Have fun writing it from scratch though.
|
Parallax propeller could probably get the job done. Nifty little microcontroller. However, once you take the price and the amount of work into account, MS looks pretty awesome :)
|
|
Originally Posted by Jeff_Ciesielski
(Post 617414)
Parallax propeller could probably get the job done. Nifty little microcontroller.
Originally Posted by neogenesis2004
(Post 617410)
probably not enough program memory.
I'm sure the Arduino is plenty powerful, I just can't personally imagine wanting to spend the time it would take, when the MS2/3 codebase is already so well developed. Just wish they'd fucking let us see the fucking schematics for the fucking MS3 and the fucking MS3X that they've been keeping so fucking secretive on fear that some fucker will clone the fucking thing, with no regard for all the fucking people out there who don't give a fuck about copycats and just want to be able to properly optimize their fucking I/O circuits. Fuckers... |
I saw the title of this thread and said aloud "Holy shit"
I wouldnt want to program that shit |
Not with an Arduino, but the "megasquirt project" started out as a more open-source code on a simple microcontroller.
PS- I love Arduinos |
Originally Posted by Joe Perez
(Post 617443)
I'm sure the Arduino is plenty powerful, I just can't personally imagine wanting to spend the time it would take, when the MS2/3 codebase is already so well developed. Just wish they'd fucking let us see the fucking schematics for the fucking MS3 and the fucking MS3X that they've been keeping so fucking secretive on fear that some fucker will clone the fucking thing, with no regard for all the fucking people out there who don't give a fuck about copycats and just want to be able to properly optimize their fucking I/O circuits.
Fuckers... |
The difference between the arduino and the 68HC908 is that the Arduino language is a varient of c, while the 68HC908 used assembly language. It would take a whole lot more memory, flash, cpu cycles to accomplish the same thing on an Arduino.
Of course the MS-II was written in c, and has a similar amount of ram and a similar cpu. However the MS-II's cpu has twice the flash (64k) as the Arduino (32k). So your code would have to be approx half the length of the MS-II. It would be a little bit worse than that since the Arduino language has so much abstraction going on. Then again... you could use an Arduino Mega, which has 128k of flash. :) The other issue you might have with the Arduino is timing. I'm not sure that the Arduino's timing is fine grained and accurate enough, and I'm not sure that the Analog inputs are fast enough (with the abstraction). Even the MS-II had to use assembly language for reading the analog inputs. You could use straight c or assembly language on the arduino... but then it wouldn't really be an arduino. |
That said... I do have an Arduino in the proto area of my megasquirt =)
|
The arduino "language" is just c++ functions that have been premade to help nubs. You can still code in its simple compiler using c++ only, giving you a finer control. The compiler still converts it to assembly so both still get their bits set from assembly inthe end.
Additionally, the arduino just uses a Atmel AVR chip while the MS chip is a freescale chip. Both have C++ compilers available, and both can also be coded solely in assembly. Both are VERY similar chips, main difference actually being 8bit on the AVR and I believe the MS2 is 16bit. The MS3 is 32bit so the comparable Atmel chip would be from the AVR32 family. A large reason AVR chips are so massively used is because a great open source GCC compiler exists for it and it also has a tremendous forum support. Freescale and other chips often require more expensive toolchains in order to fully utilize high level languages like C++. |
I know a guy working on a FOSS ECU for the duinos. If I can get hold of him again, I can try to put you in touch, if you're any good as a dev.
MS3 - it's worse than you think. There is self destruct code built into the thing such that if you do certain things that might be indicative of trying to clone it, it deletes everything and bricks it, yay. LOL @ neo's comment "Fuck the fucking fuckers!!!" Re propeller chips, there is a guy obsessed with them on diyefi.org/forum with a thread and project using 2 chips to produce an EMS. Finally, FreeEMS isn't dead despite the total lack of updates to the website and any information on what has been happening. Here is an out of date thread on it : https://www.miataturbo.net/megasquirt-18/diyefi-org-freeems-future-true-diy-engine-management-19077/ I got a car running and m2cupcar tuned it (fuel only) by feel, picking up midrange and 5mph top speed on the flat. I did that 8 or 9 months ago in the US of A. First run and drives were in Florida at the end of a 13500 mile road trip that started in California with AbeFM :-) I guess I started and ended the trip with miata guys! In any case, I've been doing some closed source EMS work for a guy from the US who flew me in to do it, and then into China for a month each. There is a video of that here : http://www.youtube.com/watch?v=QvJgyuzoako Lots of good things are coming from us soon (where soon is a relative term). Fred. |
Hippy fred with long hair is lulz.
|
Originally Posted by rb26dett
(Post 617862)
I know a guy working on a FOSS ECU for the duinos. If I can get hold of him again, I can try to put you in touch, if you're any good as a dev.
MS3 - it's worse than you think. There is self destruct code built into the thing such that if you do certain things that might be indicative of trying to clone it, it deletes everything and bricks it, yay. LOL @ neo's comment "Fuck the fucking fuckers!!!" Re propeller chips, there is a guy obsessed with them on diyefi.org/forum with a thread and project using 2 chips to produce an EMS. Finally, FreeEMS isn't dead despite the total lack of updates to the website and any information on what has been happening. Here is an out of date thread on it : https://www.miataturbo.net/showthread.php?t=19077 I got a car running and m2cupcar tuned it (fuel only) by feel, picking up midrange and 5mph top speed on the flat. I did that 8 or 9 months ago in the US of A. First run and drives were in Florida at the end of a 13500 mile road trip that started in California with AbeFM :-) I guess I started and ended the trip with miata guys! In any case, I've been doing some closed source EMS work for a guy from the US who flew me in to do it, and then into China for a month each. There is a video of that here : http://www.youtube.com/watch?v=QvJgyuzoako Lots of good things are coming from us soon (where soon is a relative term). Fred. I read your thread about the free ems, seems interesting. I have no relevant abilities myself (my experience is with php, perl .NET and a little Java, no nuts and bolts programming really), but i figured the arduino could be a good base to work off of (especially the 'mega') due to the large number of inputs, wide availability, low cost, and support base. -Tomaj |
Oh, it's definitely a GREAT base to get into embedded programming. Once you get it down you can move into AVR programming in general and use the regular GCC AVR compiler with something like Programmer's Notepad (my personal fav). The compiler has all the MCU bits built in, so when you look at the datasheet and you see say a timer called TIM1 or something, you can directly set those bits, clear them, or use them in a function.
Once you can code for the AVR in straight C++ you can translate that into programming for basically any MCU. |
Originally Posted by ctxspy
(Post 617403)
Disclaimer: I know next to nothing about this stuff.
Anyone ever think about using an Arduino as an ECU? http://arduino.cc/en/Main/ArduinoBoardMega The Mega is coincidental, has nothing to do with megasquirt ( i think ). Some potential benefits to using this as a platform to build onto:
Now feel free to tell me why this won't work :) Hi there, I'm currently working on using a Arduino - "Duemilanove" as a custom ECU. let me know if you want to share ideas! Software is my area, so the hardware side is quite a learning curve! |
I have an AEM ECU running in "parallel mode". My NB factory ECU is doing idle, emissions, etc. I recently installed a 12 tooth Trackspeed trigger wheel for better ignition accuracy.
I have a Dueminalove for generating an NB crank signal, and the AFM signal it expects. I agree with what neogen and Joe wrote above.... If you want to dabble in what it takes to write ECU code, go browse diyefi.com. |
Arduino ECU hardware shield prototypes
I have had an "very alpha" Arduino Mega ECU shield designed and have two prototypes. I started to test basic functionality of sensors, VR decoding etc, but I haven't progressed very far from that due to work getting in the way. I will post all the Eagle files and pics of prototype h/w to start discussion if anyone wants me to.
|
I have been reading ECU theory and the software seems pretty straightforward. My hope would be to make a direct drop in replacement for the existing ECU for my '91 Miata.
The AVR328 is a lot more powerful and has a lot more memory than the existing 6800 based ECU. The AVR is a very strong math performer and also includes a hardware multiplier so with it we can be less reliant upon precomputed tables (which the existing unit uses almost exclusively). I decided to use the Arduino "Duemilanove", as it offers 6 Analogue inputs and 14 Digital I/O (6 of which have been set up for PWM), this seems to be enough to monitor and control the Miata engine. It also has a built in USB transceiver, which allows for simple debuging and also direct control of the board while in use via any laptop with a terminal (I use a custom AT command set to control the board). My first port of call, is to use the Arduino as a data capture device, as I need to know what the existing ECU is seeing from the Engine, and consequently what signals it sends back and when. Has anyone already tried this? I can't seem to find any Miata ECU data captures. Also, looking at the engine diagram, it looks like my version of the ECU doesn't control the ignition timing (the ignitors seem to handle that themselves), is that right? Many thanks for your help! |
You need to think about IO and accuracy of IO. IE, you need to think about timers, in particular, hardware timers! Without massive CPU speed, these are critical in getting accurate RPM/Position inputs and accurate ignition angle outputs and fuel pulsewidths. Without those things, you may as well have MegaSquirt 1 :-p
|
Originally Posted by bloodline
(Post 632692)
Also, looking at the engine diagram, it looks like my version of the ECU doesn't control the ignition timing (the ignitors seem to handle that themselves), is that right?
So you need to control the ignition timing. |
Many thanks all! So the ECU does actually decide the spark time :)
Also the AVR provides microsecond timers, I think this is high enough resolution for an ECU. I assume that the time between the TDC of consecutive cylinders is 1875 micro seconds (at 8000 RPM, the top of the Miata's engine range), this is enough time to determine the injector time and spark time. Have I forgotten something? |
Slightly Related link for Arduinos
Have you seen diydrone.com ?
They use Arduinos - and gps and lots of other cool stuff. Check it out. No affiliation, blah, blah. Pretty cheap boards available there. Actually kind of scary - wouldn't take a lot more effort to make something lethal out of it... |
Originally Posted by bloodline
(Post 632692)
I need to know what the existing ECU is seeing from the Engine, and consequently what signals it sends back and when. Has anyone already tried this? I can't seem to find any Miata ECU data captures.
Also, looking at the engine diagram, it looks like my version of the ECU doesn't control the ignition timing (the ignitors seem to handle that themselves), is that right?
Originally Posted by bloodline
(Post 632864)
Also the AVR provides microsecond timers, I think this is high enough resolution for an ECU.
Have I forgotten something? I still think you're nuts, but in a reverent sort of way. :D |
I could hardly get my boe-bot (basic stamp I think) to follow the black line....I cant imagine the development time you would need to run a FI motor!
I did one of the MPGuino's for the beater civic to track mileage...pretty cool little toy - but I wouldnt try to make it into a EMS considering my MS-2 was retardidly simple in comparison to doing something like what your considering...but more power to ya if you do |
Originally Posted by Joe Perez
(Post 632896)
Over the course of the various mainstream aftermarket ECU projects, the Miata's I/O have been extremely well documented. Some of it I've done myself. There's not exactly one single place to go for all of it, but it's around. What year engine will you be working with? I may be able to point you in the correct direction.
Nope. The ECU asserts a logic high to the ignitor to start the dwell period, and then pulls the signal low again when it's time to fire the plugs. So far as I know, pretty much every modern ignition system works this way. Well, except for EDIS, but that's about as modern as a horse in my book. So far as I am aware, the MS1e and MS2e aren't even using hardware timers for ignition triggering- they're just doing it in software and bit-banging the outputs. Good enough for a claimed 10us accuracy. Not saying this is the best way of doing it- in the case of the MS, they're reserving the hardware timers for fuel pulsewidth calculation. If your CPU has enough hardware resources to do both fuel and spark with timer interrupts, more power to you. :bigtu: Analog inputs, PWM outputs, high-precision timers, sounds like the lot of it. When you toss out all the emissions and body-control stuff, it takes surprisingly little to make an engine run. Two crank/cam position inputs, a MAP or MAF input, O2, maybe TPS if you're feeling exotic. Two or four outputs for spark and fuel (dealer's choice), a PWM output for idle control, a couple of relay drivers to control the fuel pump and the fans... Not a lot, really. So far I have identified: 5 Analogue inputs: 1. Airflow 2. Throttle Position 3. Coolant Temp 4. O2 Sensor 5. Oil Pressure (I have a real sender on my car... so might as well use it at some future date). 5 Analogue outputs (PWM): 1. Throttle Servo (which would be the ISC valve on a stock engine). 4. Injectors (though I plan to handle these in a special way, for better accuracy) ;) 2 Digital inputs: 1. CamA (1 pulse per revolution) 2. CamB (4 pulses per revolution) 4 Digital outputs: 1. IgnitorA 2. IgnitorB 3. Coolant fan 4. Coolant valve (not sure if the MX5 has this and instead uses a mechanical thermostat). The Arduino also includes a USB data link, so you can monitor the system in real time and adjust settings all via a laptop :) I still think you're nuts, but in a reverent sort of way. :D |
Originally Posted by bloodline
(Post 633003)
My Engine is a stock '91, 1.6 engine. some timing charts would be nice, so I can see when the injectors (and for how long) and coils fire with respect to the CAS. As I understand it, the MX5 CAS has a Single Cylinder 1 TDC pulse and 4 timing pulses for each came revolution.
The first signal gives four evenly-spaced pulses per cam revolution, where each pulse corresponds to one spark event. I refer to this as the CKP (Crankshaft Position) signal, which is also called "Ne" by some people. It's the white wire, which goes to pin 2E of the ECU. The second signal gives not one but two pulses per cam rotation, of unequal length. I call this one CMP (Camshaft position) and it's also referred to as the "G" signal. Yellow or yellow/blue at pin 2G of the ECU. The leading edges of these pulses are the same, but the trailing edges are different. The rising edge of CMP always occurs while CKP is low. But one falling edge occurs while CKP is still high, the other after CKP has gone low. Forgive the crudity of this sketch, I took these measurements while the floppy drive on my old scope was broken. It's not perfectly to scale, but the times I've penciled in are accurate: http://img33.picoodle.com/img/img33/...Pm_11fbb80.gif Traces 3 and 4 are the two spark outputs. I honestly can't remember which one is cyls 1/4 vs. 2/3, but they're labeled "B" (brown wire) and "B/Y" (brown/yellow wire). more discussion here: https://www.miataturbo.net/megasquirt-18/sanity-check-inverted-primary-trigger-required-jimstim-29726/ Ah, OK... I think I need a better ECU pinout diagram.... :) http://img38.imagefra.me/img/img38/7...mm_c75ab89.gif http://img38.imagefra.me/img/img38/7...nm_c108fcf.gif http://img38.imagefra.me/img/img38/7...om_e52e7a9.gif The AVR has a nice set of external interrupts, so that is my preferred method. Speaking of which, just FYI, the stock CAS is a load of rubbish. Not only that, but since it's belt-driven, it tends to jump around at high RPM relative to the crank. You'll be much better off installing a wheel and sensor directly on the crank pulley. 5 Analogue inputs: 1. Airflow 2. Throttle Position 3. Coolant Temp 4. O2 Sensor 5. Oil Pressure (I have a real sender on my car... so might as well use it at some future date). 5 Analogue outputs (PWM): 1. Throttle Servo (which would be the ISC valve on a stock engine). 4. Injectors (though I plan to handle these in a special way, for better accuracy) ;) 2 Digital inputs: 1. CamA (1 pulse per revolution) 2. CamB (4 pulses per revolution) 4 Digital outputs: 1. IgnitorA 2. IgnitorB 3. Coolant fan 4. Coolant valve (not sure if the MX5 has this and instead uses a mechanical thermostat). Also, fuel pump, aircon again, boost control (if that's your thing), etc. Well, right now it's just a bit of fun... but if we can make it work, I'm sure we would all appreciate a fully adjustable ECU that could be had for about $60 in total |
Originally Posted by bloodline
(Post 633003)
Actually, the project I'm working on grew out of my investigation to replace the throttle cable with a servo... By using a servo to control the throttle, we don't need a TPS
Will you use it to linearize throttle response or to do traction control? |
You'll need to implement crank position detection based on constant angular acceleration, or how the MS does it, the alpha/beta/gamma algorithm.
You'll have to think about this scenario: Say you have a crank tooth at 20* BTDC. YOu know when that tooth passes, you're at 20*BTDC. Let's say at some condition you need to spark at 22*. The previous tooth passed (say at 80*BTDC), and you set a timer interrupt with the predicted time it takes for 58* to pass. Then before the calculated time for 58* passes, here comes the 20* BTDC tooth, because the engine is accelerating faster than you assumed. If the 20* tooth arrives before when you think the 22* time comes, you need to override the wait and spark it. BTW I think the Parallax Propeller is better suited for this. Multiple interrupts are messy things for real time control. The Propeller is an 8-core uP, which is very fast. It is better to dedicate one of the cores for crank angle prediction duty, one for ignition, one for fuel, and you have 5 more .. than to take a single core uP and make it do all that. It's better to dedicate uP's for single tasks, and to do timing with continuous polling than to use interrupts. Search for propeller on diyefi.org, there's a guy who's enamored with it, and has written extensively about it. |
Originally Posted by JasonC SBB
(Post 633191)
Say you have a crank tooth at 20* BTDC. YOu know when that tooth passes, you're at 20*BTDC. Let's say at some condition you need to spark at 22*.
(...) BTW I think the Parallax Propeller is better suited for this. One thing I've never been clear on is whether the timing of the hub rotation is completely deterministic. IOW, is it possible for one cog to "seize" the hub, like in the old days of Token Ring networking, when a host failed to pass the token? On the plus side, you'd have the advantage of being able to code only the "interrupt cog" in assembly, while doing everything else in SPIN. |
|
No, nothing I've ever read actually seems to describe the mechanism by which the hub services the cogs. At least, I think I'm interpreting the design correctly. My perception is that any given cog can only access main memory and I/O when the hub is pointing at that particular cog, and if this is true (and I'm not saying it is) then I'd love to know exactly what controls the rotation of the hub and whether it's possible for a cog to "foul" the hub.
|
If I understand your Q correctly, AFAIK the cogs can read shared mem any time, but can only write to em when the hub is pointing at it. And, the hub runs independently of the cogs. The cogs have "private" memory.
re IO: "Unlike many multicore CPUs, this is a microcontroller. The bus doesn't connect to the part's pins so memory cannot be expanded. In fact, other than power and a couple of housekeeping pins, the device has just 32 I/O connections to the outside world. And herein lies another bit of clever quirkiness: each of those I/O lines goes to all of the cogs. If configured as outputs, the result is the logical OR of all of the cog's assertions. If cog 0 sets pin 23 to a zero, and cog 5 drives it high, the output will be high. Odd, huh? But this is a part meant for control applications. If a pin were tied to a warning light, any cog can easily, and without any complex interprocessor communications code, turn the light on." |
My interpretation of the logical chip diagram is that each cpu has an output register and an output select. The hub connects to all cpu's output register and select. Essentially the hub is just RAM with a built in multiplexer. According to the datasheet, memory collisions on write operations can occur and need to be accounted for in software design. Reads however are trivial and any of the cpus can read whatever is in RAM at any time. Even simultaneously as long as they both want the same data. That was my interpretation at least.
Their high level drawing looks misleading to me. They picture it as a spinning wheel that just goes clockwise giving each cpu a write operation every 8 cycles. In fact an cpu can write any time as long as none of the others write at the same time. So a cpu could in fact just continue to write as long as the others don't need to. I also noticed that there are no true hardware interrupts built in to the CPU at all. Their reasoning is that interrupts were built for a single core world where you couldn't waste precious cpu cycles constantly monitoring an input. I don't fully buy that excuse, there are many times when a hardware interrupt would be usefull no matter how many cores you have. As for memory expandability, there is 0 reason you could not hook up an external sram or flash to an i/o pin and just use it as an spi interface. Thats is pretty standard fair for any mcu. Their 32Kb max system ram is kind of a huge joke to me though for a modern 32bit multi core mcu. I also think they are wasting significant resources including a graphics architecture into the chip. Any small modern lcd will have a driver built into it that just communicates serially. Its pretty easy to do and has much higher resolution and color support that way. I'd trade the graphics stuff for more onboard ram any day. |
Ok, did some further reading...
All cogs have shared access to all I/O pins. For pins configured as outputs, the state of the pin is a logical OR of all states being written to it. So if one cog is writing a 0 to a given pin and another is writing a 1, the pin will be high. It appears that all access to shared memory is controlled by the hub, both read and write, and that the hub rotates continuously, taking 16 clock cycles to complete a full revolution. Here's a note from the Propeller Assembly Instruction Master Table: Note 1: Clock Cycles for Hub Instructions: Hub instructions require 7 to 22 clock cycles to execute depending on the relation between the cog’s hub access window and the instruction’s moment of execution. The Hub provides a hub access window to each cog every 16 clocks. Because each cog runs independently of the Hub, it must sync to the Hub when executing a hub instruction. The first hub instruction in a sequence will take from 0 to 15 clocks to sync up to the hub access window, and 7 clocks afterwards to execute; thus the 7 to 22 (15 + 7) clock cycles to execute. After the first hub instruction, there will be 9 (16 – 7) free clocks before a subsequent hub access window arrives for that cog; enough time to execute two 4-clock instructions without missing the next hub access window. To minimize clock waste, you can insert two normal instructions between any two otherwise-contiguous hub instructions without any increase in execution time. Beware that hub instructions can cause execution timing to appear indeterminate; particularly the first hub instruction in a sequence. So, while there doesn't seem to be the possibility of any given cog delaying other cogs from hub access, there's also no determinism in how long it will take to initiate a shared memory access operation. Shouldn't matter for these purposes. The lack of an interrupt is kind of weird. Looks like you pretty much have to dedicate a cog to either polling one or more pins in round-robin fashion, or if you need faster performance, leave a cog sitting idle waiting for a state-change on one particular pin. That'd probably be the best thing here. Let a cog sit and wait for a CKP rising edge. When it happens, start a timer, then wait for the falling edge, and when you see that, look at CMP to see whether it's still high or not in order to determine absolute engine phase. |
"There is no concept of yielding with Spin or cog code. In fact, there are no interrupts. Everything is designed to be polled although it is possible for cog code to wait for a change on the IO lines."
"There are no interrupts: just assign a cog to the activity. It makes you think about a very different paradigm when processors are abundant." |
I agree with Joe on the lack of interrupts. To me it sounds like they are saying, "since you have 8 cores, there is no need for interrupts because you have so much more resources to waste polling inputs!"
It looks liek I must misunderstand how the hub works. I do not like that it is "spinning" all the time at all. I want complete control over what core can access memory at any given time in my code execution. Multi cores for computing, and memory with a simple memory controller that can handle memory requests so that there are no collisions. A simple request for access and a yes or no response would work. Just seems more efficient. I doubt I would ever choose the Propeller for any projects for myself. Based on the stuff we have discussed and also because there is a distinct lack of low level information on it, even in is datasheet. Not a fan... |
Since we've now dreailed this thread properly, I will share an amusing observation.
Am I the only one who thinks that this business of timing instructions to fit between hub access cycles sounds a lot like some of the old optimization techniques that folks used to pull in the days of drum memory? The Story of Mel, in particular, springs to mind. |
Lol... The propeller is a very interesting chip, but things like lack of interupts and other design decisions put me off trying it out... I hope other manufactured try a more traditional approach to multicore MCUs...
Anyway... If I could get back on topic (if only for a bit ;) )... The pinouts and timing diagrams are good stuff Joe, many thanks! I didn't realise the standard engine used a batch injection, I assumed it was sequential :) In terms of sensors, I think for the time being it is best to just stick with what came with the engine... though I am fascinated by the MAP sensor, it seems like a vastly superior way to determine the mass of air, but is computationally more expensive (or will require a large lookup table). I was lead to believe that the CAS worked differently to how your timing diagram would suggest... I was expecting a standard industrial rotary encoder. "Signal A" giving a single pulse for a complete revolution, and "Signal B" giving 4 equal pulses for a single revolution. This woulds allow me to use "Signal A", to synchronise the MCU with the engine valve positions, and use "Signal B" for timing. With this assumption, I built a simple mathematical model for Cylinder 1 running at 8000rpm(the fastest the engine can run). In this model I assume the first stroke from TDC is an induction stroke. Also the time taken to complete all four strokes of the engine cycle is 7500 microseconds (1875 microseconds per stroke). The "Piston Position" curve is displacement from BDC in mm (The 1.6 Miata stroke is 83.6mm). The injector for this cylinder is held open 1200 microseconds (just as an example, the real time would obviously be determined by the amount of air in the manifold). The ignitor fires on the timing pulse for the 3rd stroke (just as an example, the real time of ignition would be determined by the RPM). The other cylinders would follow the same cycle, offset by their respective positions in the cycle :) http://www.cutiemish.com/1CylinderModel.png I will attempt to adjust my model to fit with the real Miata CAS sensor :( |
Originally Posted by bloodline
(Post 633811)
I didn't realise the standard engine used a batch injection, I assumed it was sequential :)
From 1989 through 1993, the ECU has only two injector channels and thus uses batch-injection. Injectors 1 & 3 are on one channel, with 2 & 4 on the other. From 1994 onwards, there are four injector channels and injection is fully sequential. (California-spec cars got this in 1993.) Ignition is wasted-spark in all MX5s from 1989 through 2005, with cylinders 1&4 paired on channel 1, and 2 & 3 on channel 2. I am fascinated by the MAP sensor, (...) but is computationally more expensive (or will require a large lookup table). To me, this seems much easier to implement (both computationally and from a design standpoint) than trying to model the engine's airflow characteristics into a formula. It's certainly been done, but it's not exactly mainstream. I was lead to believe that the CAS worked differently to how your timing diagram would suggest... I was expecting a standard industrial rotary encoder. "Signal A" giving a single pulse for a complete revolution, and "Signal B" giving 4 equal pulses for a single revolution. There are some CASs which do work that way- with four pulses per rev on CKP and one pulse per rev on CMP. But all 1989-1997 MX5s use the 4/2 pattern, which is an old Mitsubishi standard, commonly used on the 4G63 engine family. This pattern allows for quicker engine starting, as you only have to wait a maximum of 1/2 cam revolution before you can sync up and start firing the ignition (assuming wasted-spark), whereas with a 4/1 pattern you'd have to wait up to 1 full cam revolution. In 1999, it got even more complex. The NBs have a cam signal which gives a total of three pulses per rev, and four unevenly-spaced teeth on the crankshaft. Decoding that thing is such a pain in the arse that on the MS1, for instance, the developers simply gave up. Here's a diagram which shows roughly 1.5 cycles' worth of NA and NB sensor signals, without the ignition signals: http://img38.imagefra.me/img/img38/7...wm_5981b1a.gif I thought I'd taken one of the injector phasing relative to CMP, but I can't seem to find it at the moment. Regardless of year, these are all open-collector outputs, normally pulled up to +5. Be aware that they are notoriously noisy and flaky; debounce is of critical importance. The best which I've found for the job is the MAX9924 / 9926. This woulds allow me to use "Signal A", to synchronise the MCU with the engine valve positions, and use "Signal B" for timing. |
Hmmm, ok, these uneven pulse rates on the CAS seem to be an effort to compensate for slow micro-controllers...
If I take the hardware side of this further, I would have to replace the CAS with something more useful, also the injector wiring would have to be replaced to get sequential injection... while I'm at it, I might as well replace the MAS with a MAP... This is far more than I wanted to do... I'm a software guy really :) Ok, I guess what I want now is a diagram showing the piston no.1 position vs the CAS pulses for the NA (pre '93)... that way I can adjust my model to get it's timing from the original CAS. Note: I discovered how noisy a car's electrical system is during my investigation regarding the throttle servo project I mentioned earlier. I decided to use a standard HItech HS422 servo (not ideal for the hot, dirty environment of a car engine bay, but can be easily protected, is very powerful and is very cheap). And I had to resort to shielded cabling and a simple low pass filter algorithm on my sampling code (the AVR328 is a powerful beast) to reduce the electrical noise on the analog lines to an acceptable amount... |
It is de rigeur in system design to bandlimit signals using analog lopass filters, to only the bandwidth you need. Translation: put an RC lopass filter for the signals that come from the outside world, at the entrances of your board. Spec the time constants so the rise times are only a bit faster than what you need, e.g. 15 uS for crank signals, because that's half a crank degree at 7500 RPM.
Even output signals should be bandlimited. For example, my Arduino board generates signals for my factory ECU crank input. The Arduino will put out pulses with rise times of only a few uS. Because the wire that carries this signal runs in parallel to the input from my crank sensor, a fast rise time on this wire will couple noise into my crank input. So I bandlimited it to ~20 us with an RC lopass. |
Originally Posted by neogenesis2004
(Post 633542)
I agree with Joe on the lack of interrupts. To me it sounds like they are saying, "since you have 8 cores, there is no need for interrupts because you have so much more resources to waste polling inputs!"
To wit: the problem with multiple interrupts is: - it's hard to determine how many clock cycles are used up getting in and out of the interrupt routine - while in the interrupt, what if another interrupt occurs? This is another layer of complication It is far easier to architect the system where you have a core dedicated for each time critical operation. It is also more predictable. For example, ignition timing needs 10 us accuracy. That's not a lot of clock cycles for a midrange uC. You guys are used to, and wedded to, the idea of interrupts. I am now re-entering the world of uC's, so I have less bias than seasoned uC programmers, one may say. |
Originally Posted by JasonC SBB
(Post 633963)
It is de rigeur in system design to bandlimit signals using analog lopass filters, to only the bandwidth you need. Translation: put an RC lopass filter for the signals that come from the outside world, at the entrances of your board. Spec the time constants so the rise times are only a bit faster than what you need, e.g. 15 uS for crank signals, because that's half a crank degree at 7500 RPM.
Even output signals should be bandlimited. For example, my Arduino board generates signals for my factory ECU crank input. The Arduino will put out pulses with rise times of only a few uS. Because the wire that carries this signal runs in parallel to the input from my crank sensor, a fast rise time on this wire will couple noise into my crank input. So I bandlimited it to ~20 us with an RC lopass. |
Originally Posted by bloodline
(Post 633920)
Hmmm, ok, these uneven pulse rates on the CAS seem to be an effort to compensate for slow micro-controllers...
Without the two CMPs, you'd have to wait up to a maximum of two full crank rotations before a CMP pulse came around in order to start firing the ignition. The speed of the CPU has no bearing at all on any of this. A quad-core i7 would still have to wait up to two full crank rotations before it could begin operating the ignition if there were only one CMP pulse per cam rotation. If I take the hardware side of this further, I would have to replace the CAS with something more useful, also the injector wiring would have to be replaced to get sequential injection. Now, I do recommend replacing the CAS with a crank-triggered pickup, but only because the flex of the timing belt causes a lot of spark scatter. Nothing at all to do with batch vs. sequential. Ok, I guess what I want now is a diagram showing the piston no.1 position vs the CAS pulses for the NA (pre '93)... that way I can adjust my model to get it's timing from the original CAS. |
Originally Posted by Joe Perez
(Post 633971)
I don't see why you think this. The uneven-pulse design allows you to have fully sequential injection while reducing the time it takes for the ECU to sync up while starting. You fire the injectors in full-batch mode while cranking (every injector on every CKP pulse) and then you only have to wait a maximum of one crank rotation to get a CMP reference so you can start firing the ignition.
Without the two CMPs, you'd have to wait up to a maximum of two full crank rotations before a CMP pulse came around in order to start firing the ignition. The speed of the CPU has no bearing at all on any of this. A quad-core i7 would still have to wait up to two full crank rotations before it could begin operating the ignition if there were only one CMP pulse per cam rotation. for 0 degrees rotation, Signal A and Signal B would be HIGH. For 90 degrees, Signal A would be LOW and Signal B would be HIGH. For 180 degrees, Signal A would be HIGH and Signal B would be LOW. for 240 degrees, Signal A would be LOW and Signal B would be HIGH. This way you would only need a single interrupt on Signal A (testing the B signal in the interrupt service routine, if B is HIGH then we are at 0, if it is LOW we are at 180), to establish where you are in the cycle, i.e. only one crank rotation. Wouldn't this work? Nope. '94 to '97 MX5s have full sequential injection and they use this same CAS. Read what I wrote in my last post more carefully. Also, I'm stuck with my '91 engine... so unless I replace the injector control hardware/relay board I'm stuck with batch injection. Now, I do recommend replacing the CAS with a crank-triggered pickup, but only because the flex of the timing belt causes a lot of spark scatter. Nothing at all to do with batch vs. sequential. http://i264.photobucket.com/albums/i...ild/timing.jpg |
Originally Posted by bloodline
(Post 633975)
I would, instinctively, do it slightly differently...
My perspective on what you've described relative to the 4G63 design: 1: Assuming you are speaking of degrees at the camshaft, your design treats both the rising and falling edges of "Signal A" as triggers. Bear in mind that many (if not most) microprocessors can only see one side of a transition on their IRQ input- IOW, they can only see a falling edge or a rising edge, but not both. 2: If you were speaking of degrees at the crank, then your solution doesn't allow fully sequential injection. 3: It is desirable to have both a rising and a falling edge on the primary trigger for every ignition event. In the 4G63 design, the rising edge occurs at 75° BTDC, and the falling edge at 5° BTDC. The 75° BTDC edge is the primary trigger during normal operation, giving the timer plenty of room to achieve full ignition advance plus dwell. The 5° BTDC edge is used as an absolute reference for the spark event while cranking over on the starter, when RPM is too low and crankshaft angular velocity too unstable to accurately compute an ignition angle from 75° away. (Note that in #3, I am speaking of degrees at the crankshaft.) Also, I'm stuck with my '91 engine... so unless I replace the injector control hardware/relay board I'm stuck with batch injection. |
1 Attachment(s)
See my Arduino interface schematic.
Opamp circuit is a lopass filter to convert PWM output into a DC voltage for the AFM input of the factory ECU. The Schmitt inverter circuit is the input filter for the incoming 12-1 CKP signal. The RCRC circuit is the input filter for the MAP sensor signal. The 330 ohm / 33 nF filter is to filter the Arduino output which goes to the CKP input of the factory ECU. |
Originally Posted by JasonC SBB
(Post 633968)
To wit: the problem with multiple interrupts is:
- it's hard to determine how many clock cycles are used up getting in and out of the interrupt routine If you mean how long it takes to actually run the interrupt routine, that's important regardless of architecture. Let's look at how a Prop might be configured to do the job of an MS. We dedicate one cog to be the interrupt handler. Whatever time-critical activity the interrupt routine is doing must be executed on the same cog that's detecting the interrupt. There's no way for one cog to "interrupt" another, so you have to perform the whole interrupt routine on the interrupt cog, which, as you said, means you have to be certain that the whole interrupt routine "fits" into the window between interrupts, including the time it takes for the interrupt cog to write data into main memory so that the other cogs can read it. (Even the non-time-critical cogs need to know what the engine RPM is and what phase the crank is in.) - while in the interrupt, what if another interrupt occurs? This is another layer of complication Unless, of course, you are referring to a system with multiple interrupts, like a general-purpose PC. In that case, you handle the high-priority interrupt first, then service the lower-priority ones. But for an ECU, one IRQ is all you need. (Assuming your engine only has one crankshaft, which I think is a fair assumption.) You guys are used to, and wedded to, the idea of interrupts. |
No, you dedicate one cog to do crank angle prediction / ignition. It continually polls the CKP and CMP, calculates crank position, and outputs the coil signals. It reads the desired timing from a shared mem location, which is updated by another cog. This way this cog does one task, and does not need to be interrupted by any, more important tasks.
Another cog does the same for injection. And so on. No interrupts necessary with this architecture. |
Originally Posted by Joe Perez
(Post 617443)
Just wish they'd fucking let us see the fucking schematics for the fucking MS3 and the fucking MS3X that they've been keeping so fucking secretive on fear that some fucker will clone the fucking thing, with no regard for all the fucking people out there who don't give a fuck about copycats and just want to be able to properly optimize their fucking I/O circuits.
Fuckers... Ken |
Originally Posted by neogenesis2004
(Post 617645)
The MS3 is 32bit so the comparable Atmel chip would be from the AVR32 family.
For those who care, its the MC9S12XEP100, has 1M of program flash, 32k of data flash, and 64K of RAM. We use the data flash for all our tuning data currently. Ken |
Originally Posted by muythaibxr
(Post 634014)
Regardless of F-bombs, B&G seemed open to NDA for those who really need to see the schems. It's not really up to James and I though.
Just needed to get a few things off my chest. I'm sure that when the time comes for my next ECU, the MS3 I/O circuits won't be terribly difficult to reverse-engineer. I just hate having to spend the time to do it. |
The 32bit thing was just a shot in the dark guess. I didn't actually Google it back when I posted that.
|
After studying the Timing diagrams provided by Joe, I found it quite easy to rewrite my synchroniser code and timing interrupt to work using the output of the standard CAS.
I was then able to run a simulation, using the following Ignition timing table: RPM BTDC 500 10 1000 10 1500 12 2000 17 2500 22 3000 24 3500 28 4000 28 4500 31 5000 34 5500 36 6000 36 6500 36 7000 36 Which I believe is the stock timings... Are these any good? I would appreciate better ones. Anyway during my simulation, I hit a big snag with the Arduino. The analog acquisition time is 100microseconds per analog pin (using the standard library), which at 8000rpm is about 5 degrees of crank rotation. There simply isn't enough "dead time" in the cycle, in order to acquire the TPS and the Air flow. I think I will have to write my own analog code that will read asynchronously, any better ideas? -Edit- Actually, after playing around with it a bit, I think blinding the code for 10 degrees once per 2 crank revolutions isn't too bad, and that only happens at the VERY top of the engine's running speed... I don't think I've ever taken mine over 6000RPM... maybe once... -Edit 2- Here is the output of my current simulation; In this simulation the ignition fires at 10d BTDC and the injector open time is 90d of crank. I currently only check the cam position signal once, during startup to determine which CKP pulse is next, after that, all timings are derived from the CKP via an interrupt... http://www.cutiemish.com/OneCycle.jpg Changes made to this model mean that that the crank angle now determines the position in the cycle, the units on the x axis are 10ths of a degree. At 1000RPM, there are 170 microseconds per degree of crank rotation. |
I like where this thread is going, gonna keep an eye on it
|
Ok, to solve the Analog acquisition time problem, I decided to start the acquisition just after TDC of cylinder one then waiting to continue execution until the Cam signal goes low, that gives me at least 490micro seconds (at 8000RPM) to acquire my analog readings (plenty of time) :) and also I know that the crank angle is 49deg at that point so I remain synchronized.
I know that overlaps with my injector timing, but frankly they are just junk at the moment until I get more info on how injectors work. Note, I'm only timing from the falling edge of the CKP... I might time from both the rising edge and falling edge if I need more accuracy :) |
Originally Posted by bloodline
(Post 634154)
The analog acquisition time is 100microseconds per analog pin
A few things to consider... What are you planning to use TPS for? In a forced-induction application, MAP (or airflow) are considered be some to be a more useful predictor of load for the purposes of accel enrichment. So if you're only going to sample it for things live overrun or idle threshold, it's not necessary to sample it every single cycle. You could probably do a round-robin scheme with the analog inputs, one per cycle, such as: 1: Airflow 2: TPS 3: Airlow 4: CLT 5: Airflow 6: IAT 7: Airflow 8: O2 9: Airflow 10: TPS 11: (...)
Originally Posted by bloodline
(Post 634175)
I know that overlaps with my injector timing, but frankly they are just junk at the moment until I get more info on how injectors work.
If you're going for full sequential, the injectors should be timed such that the end of the fuel spray always occurs at the same point in the cycle, some distance before BDC on the intake cycle for a given cylinder. Note, I'm only timing from the falling edge of the CKP... |
Originally Posted by Joe Perez
(Post 634203)
Does this mean that the processor is essentially stalled for that entire time?
A few things to consider... What are you planning to use TPS for? In a forced-induction application, MAP (or airflow) are considered be some to be a more useful predictor of load for the purposes of accel enrichment. So if you're only going to sample it for things live overrun or idle threshold, it's not necessary to sample it every single cycle. You could probably do a round-robin scheme with the analog inputs, one per cycle, such as: 1: Airflow 2: TPS 3: Airlow 4: CLT 5: Airflow 6: IAT 7: Airflow 8: O2 9: Airflow 10: TPS 11: (...) If I still want a throttle servo, I'll need to serve it at least every 40milliseconds :) They contain a coil of wire which forms an electromagnet. You pass current through them, and some period of time later they start flowing fuel. You remove the current, and some period of time later they stop flowing fuel. If you're going for full sequential, the injectors should be timed such that the end of the fuel spray always occurs at the same point in the cycle, some distance before BDC on the intake cycle for a given cylinder. For spark prediction? This means that, on average, you will have nearly half a full crank revolution elapse while the timer is running. |
Originally Posted by Joe Perez
(Post 634203)
Does this mean that the processor is essentially stalled for that entire time?
|
All times are GMT -4. The time now is 05:17 AM. |
© 2024 MH Sub I, LLC dba Internet Brands