I have all the hardware worked out, and working together on the Arduino. What I need help with is a general idea of how to control the advance. The input will be the hall effect sensor from the distributor which has two pulse per revolution, however right now, I'm using a computer fan that works exactly the same. The output will be to a MSD 6AL ignition thingy, but right now it's triggering my home made timing light. The original author of this code did not solve the problem of the 4ms dwell time being constant through the rpm range and throwing off the timing. The timing will be from 12 degrees to 36 degrees total advance. Now for my questions.
Should I try to advance the distributor to 36 degrees (may not be mechanically plausible) and retard the ignition to 12, or should I set the distributor to 12 and advance to 36? Because if I decide to advance to 36, I'll need a time machine, or I'll have to wait for the next spark.
What is the best way to interpolate the values from the table?
) I am now calculating every revolution of the crank How should I calculate RPM, and how often. The original author calculates it ever 40 revolutions. That's bound to blow something up. I was thinking EVERY revolution.
) See vid, I convinced myself it can work A question of plausibility: Redline is 8,000 RPM roughly; 133ish revolutions per second; 48,000 degrees per second; 48 degrees per millisecond; and I think 1 degree in 20 microseconds. This is the important bit. If I use millis() for calculating rpm, doesn't that mean at 8,000 rpm. I'll only be able to spark with a 48 degree margin of error? That won't work at all.
So, would I google "thingy" to see what you are talking about?
How should I calculate RPM, and how often. The original author calculates it ever 40 revolutions. That's bound to blow something up. I was thinking EVERY revolution.
The input will be the hall effect sensor from the distributor which has two pulse per revolution,
So, every other pulse? How significant a change in RPM do you expect between the two pulses?
If I use millis() for calculating rpm, doesn't that mean at 8,000 rpm. I'll only be able to spark with a 48 degree margin of error? That won't work at all.
You're using a calendar, when a watch with second hand (micros()) would probably be more appropriate.
If you have an engine that revs to 8000 RPM that implies that it's quite a precious engine and IMO you're nuts to try running the ignition with a home-made controller. If anything goes wrong with your controller, the chances are quite high that you will detonate the engine to bits.
That said, if you decide to press on anyway ...
What you're trying to do is hard to do well.
You say you have two pulses per revolution. I assume you mean you have a 4-stroke 4-cylinder engine and your input signal comes from the original points in the distributor. This will already have vacuum advance and mechanical advance built in. Are these suited to your engine? If not, what's wrong with the current characteristics and are you proposing to disable the existing advance mechanisms? Even if you do that, dizzy backlash will limit your ability to get accurate timing. You would be much better off to put a trigger wheel on the crank. It is usually quite easy to do and you can even get the bits you need from places like triggerwheels.com.
Calculating the RPM based on a single firing interval (half crank revolution) is not fine enough, but is the best you can hope for from that sensor. You absolutely need to calculate it every pulse, but the problem is at low RPM the engine speed will vary substantially from cycle to cycle and the measured RPM for the last cycle is not going to be very accurate for the next cycle.
You will need to position your sensor so that your signal arrives in time for your controller to notice it, calculate the required timing based on RPM and load, power the coil for the required dwell time and finally spark at the required timing angle. So you will need to have your input signal arrive at least your dwell time (at worst case rpm) before the most advanced spark angle that you need to support.
You also need to have a scheme to get this going during cranking, where you will get huge variations in cranking speed combined with huge firing intervals making it impossible to guess the crank angle with any accuracy. Probably, your best bet would be to hard-code a fixed timing delay during cranking, and work out empirically what sort of timing gives you roughly zero advance at typical cranking speeds. This side of things gets much easier when you have a proper trigger wheel, though, and you really should aim to fit one. If you do fit one, consider using an NDIS module which will take care of the real-time timing and dwell timing for you and just leave your controller to set the required advance. That solution would be far easier to get going, and also means that the engine will still run if you blow up the controller.
This car was modified in and old school way. The original distributor was replaced with one that had weights and vacuum advance. The fuel injection and computer were all removed and replaced with individual weber carbs. The car drives ok, but the distributor we have came from a saab 900 turbo, so it only has maybe 10ish degrees of advance, where we need 25. The distributor has a hall effect sensor that puts out a square wave that cycles twice per revolution of the crank. I assume this is how the original computer got it's ignition reference. What I am making is for use with the original distributor, no weights, no vacuum advance, just a hall sender. I made some sudden progress this morning when I realized the interrupt function had to do the calculations. I used map() to map 200-4000 rpm (computer fan) to advance 0-microseconds. I also figured out why all my math was so random when i read about integer constants, and I now suffix big number with ul to make them unsigned longs.
dizzy backlash will limit your ability to get accurate timing
how did the original computer account for this?
You also need to have a scheme to get this going during cranking
Roger that. Maybe if RPMs are < xRPM, it would default to 12 degrees advance.
A small clip of what I've got so far.
int coilOut = 7; //Coil output on pin 7
int led = 13; //arduino led
volatile byte rpmcount;
unsigned long rpm;
unsigned long timeold;
volatile int advance = 0; //testing stuff
void setup()
{
attachInterrupt(0, fire, FALLING); //Pin 2 tach input
pinMode(coilOut, OUTPUT); //Coil output
Serial.begin(9600); //Initialize serial port
digitalWrite(2,HIGH); //pull up resistor on hall input
}
void loop()
{
if (rpmcount >= 50) //Serial print RPM loop (don't want it blowin up the serial port)
{
rpmcount = 0;
Serial.print(advance,DEC);
Serial.println(" RPM");
}
}
void fire() //Interrupt routine run when tach pulse goes high
{
delayMicroseconds(advance);
digitalWrite (coilOut, HIGH); //Charge coil (turn on flashlight)
delayMicroseconds(20);//4ms dwell time (really just runs my flashlight)
digitalWrite (coilOut, LOW); //Fire coil (turn off flashlight)
rpm = 15*1000ul*1000ul/(micros() - timeold); //seems to work, not sure if it's right, will come back to this
timeold = micros(); //save current since-on microseconds
advance = map(rpm,200,4000,0,1000); //for testing only - maps rpm range to degrees of advance
rpmcount++;
}
Maynard:
This car was modified in and old school way. The original distributor was replaced with one that had weights and vacuum advance. The fuel injection and computer were all removed and replaced with individual weber carbs. The car drives ok, but the distributor we have came from a saab 900 turbo, so it only has maybe 10ish degrees of advance, where we need 25. The distributor has a hall effect sensor that puts out a square wave that cycles twice per revolution of the crank. I assume this is how the original computer got it's ignition reference. What I am making is for use with the original distributor, no weights, no vacuum advance, just a hall sender.
I think you'll find that the original setup was digitally controlled fuel injection and mechanically controlled ignition, with batch fired injectors controlled by the ECU triggered by a signal from the coil. This was a very common setup for early EFI systems. Essentially, on any car with a distributor you are safe to assume that the distributor controlled the ignition timing. On any car with no distributor and with each plug wired directly to a coil, you can assume that the ignition was controlled digitally.
Since you are going away from EFI and back towards an 'old school' engine management system I would have thought you would want to go for a nice simple mechanical ignition timing system. Most mechanical advance systems can be adjusted by moving the advance end stops and changing the spring weights. But I'd be surprised if the original dizzy for that engine was very far from what you needed. How far have you modified the engine?
I think you'll find that the original setup was digitally controlled fuel injection and mechanically controlled ignition
As I said, the original distributor does not have weights and does not have vacuum advance. In what way is that mechanical ignition?
Essentially, on any car with a distributor you are safe to assume that the distributor controlled the ignition timing
This is incorrect. There are lots of cars that have distributors and crank triggers. Even if they have a sensor in the distributor, it can be a cam position sensor, and not used for timing.
I'm surprised to learn that. One of the big motivations for going to a digitally controlled ignition system was to eliminate all the expensive hardware associated with the distributor. It seems strange to put in all the electronics, sensors, mapping logic and sort out all the timing, and then plonk a mechanical HT distribution system on it too. But if you say that's what you have, I can only believe you.
The distributor becomes extremely simple with electronic control. You lose the vacuum diaphragm and the weights and springs, and you're basically left with a spinny thing. You also get the advantage of modifying advance for load, engine temp, boost. The reason you still need a cam angle sensor is the computer needs to know what's stroke it's on (unless it's wasted spark like EDIS). Hell, one car I used to have had mechanical fuel injection and electronic ignition.
Yeah, I get that it's simple, but it's still a lot of unnecessary fabrication and assembly. I imagine it might have made sense to keep it if the designers couldn't afford to redesign the engine to eliminate the distributor but needed to go to mapped ignition. Still, it doesn't seem like a good design. Anyway, if that's what you've got then it can't be helped.
If you have the possibility of going to a standard distributor (maybe adjusting the mechanical advance if necessary) that would probably be your simplest solution.
Barring that, your next best bet I suggest would be trigger wheel + EDIS + coil packs.
The last option of static distributor + single coil + mapped ignition I would still time from a trigger wheel + EDIS if possible.
I've no doubt you could get something working by timing the ignition of the dizzy, but I think it's going to be tricky to get it working well because the crank position sensing is so course. If you aren't set on using Arduino for that, something like Megajolt would probably get you running sooner.