Programmable Ignition

Float seems a bit over the top - you won't need very much precision and could easily get away with just using fixed point numbers i.e. scaling the advance value up and storing as an integer value.

A soft rev limiter is usually a rev limiter that comes in progressively as the revs increase rather than going straight from 0% cut to 100% cut.

A 'hard cut' causes the engine revs to cycle up and down with violent changes in power whereas a soft cut progressively reduces the power as the revs approach the threshold.

Yes thats what I did this morning, after reading hows floats are time/processor intensive. so Ive multiplied advance values by 10. I figure that 0.1 degree is enough resolution. (also had to shift some arithmetic around to avoid the need for floats)

A soft limiter is definetly needed. What about having it missfire 1 in 9 at the soft limit, and then ramping up the frequency of missfires as the hard rev limit is reached?

Having your soft cut based on a cut pattern which is not an integer multiple of factor of the number of cylinders is a good idea - it means that the soft cut will affect all cylinders equally rather than preferentially hitting specific cylinders. A 9-cylinder pattern is a good choice for a V8.

The scheme would be the the number of cut cylinders in your pattern will increase as the revs increase. E.g 1 cyl cut at the soft limit, 2 cyls cut at soft limit + 50 rpm, 3 cyls cut at soft limit + 100 rpm and so on.

How are you with electronics? I'm planning my first car electronics project, so I've been doing some research on how to build a proper PSU to power a 5v device. It's definitely not as simple as slapping a 7805 in front of the chip. At least, not if you want it to live more than a week. (So I'm told.) If the point is a permanently installed device, I'm inclined to over-build a little.

So far, I've come up with some ideas based on a combination of forum posts and app notes that covered specific parts, but never an entire 12v-input to 5v-output schematic. This seems like a relevant place to put it. Hope it helps. Ideas appreciated.

12v in goes through a fuse, then a 10-ohm, 1-watt resistor, then a diode. This will protect against reverse connection, and limit current in case something in the protection circuitry fails open. A short to ground in the PSU would pull around 20W, so the fuse would have to be fast-action. I'm still not sure if the resistor would survive, though that's potentially better than other modes of failure.

From there, a TVS to ground. I'm thinking 20v cutoff would make sense. This gives the PSU protection against high-voltage load dumps from the alternator, up to 1.5kW for a few ms. Connection to a 24v jump-start battery would likely blow the fuse, so it might be worth considering a higher value, though there are arguments against that as well. Maybe the best advice is "don't do that." I might do some destructive mock-ups to find out what else would fail, just to know.

I've seen some designs that use a zener in the input stage to protect against reverse polarity from downstream -- like if there were any connections from I/O pins that could see negative transients. I don't know if this would be necessary or not. I/O protection might be better off using the standard diode-to-each-rail method.

Next up, a switching regulator to drop 7-20v to 5v. I found a TI part last night (MC33063) that looks easy enough. Just needs a couple caps, couple output setting resistors, and a 220uH and (optional) 1uH inductor. 1A-capable inductors look cheap (less than $2), and with the optional filter, the output is quoted at less than 40mV ripple.

I hear the MegaSquirt project releases their schematics as open-source, so I might try to find their PSU and see what they came up with. If there's one thing you don't want to fail, it's the ECU. I would imagine they engineered their PSU accordingly.

Well I got my Arduino Uno today. It does 2760 loops a second. not fast enough to even idle.

Calculated that wrong 2760 loops a second is good up to 41000rpm

As for the power supply circuit, I hadnt put much thought into it yet, other than a 7805 and a snubbing diode because that work the last time i put an embedded pc in a car. But it dose definetly need to be engineer o handle everything. When I was installing car alarms Ive seen the back emf from the cars horn kock out the alarm module, and imobilise the car.

I started a thread for a community PSU design:

http://arduino.cc/forum/index.php/topic,106068.0.html

If I don't any more input on this soon, I'm just going to order the parts, build it, and strap it to my Ninja. The bike has a pulsed DC system that has got to be the worst electrical system one could ever find. So, if an AVR can survive that, a car should be cake.

Cool. Will be keeping an eye on that.

Have been contemplating using my laptops sound card as a pulse generator. Cant find any thing on what circuit is needed, everything ive found about using it as an audio input. what is the voltage level needed to switch a digital input? 5V? Im thinking I need a DC offset circuit too. Or is it easier just to buy a signal generator off ebay?

Well, if you happened to have a spare microcontroller lying around I suppose you could use that as a programmable signal generator. :wink:

Haha yes, that was my first thought. but I dont have one so, I thought how could I improvise till I get one

Just as a heads up, you are accessing variables in your ISR and main loop without any regard for their volatile nature. Yes, you have them declared volatile, but you have a race condition. Technically, the 'pulseTimex' variables can change midway through their use in the loop. This is especially true since these are long values and not likely to be anywhere near atomic operations.

I would suggest you create a new variable which signals the ISR has run. In the main loop, test if the variable indicates the ISR has fired. If so, do the calculations there and then. That way, your ISR only looks something like:

volatile bool fired = false ;
volatile unsigned long errorCount = 0UL ;
.
.
.
void halltrigger()
{
  HallTimeOld = HallTimeNew;
  HallTimeNew = micros(); 
   if( !fired )
   {
      fired = true ;
   } else {
      errorCount++ ;
   }
}

Then the loop can have the following, whereby 'pulseTimex' no longer needs to be volatile.

void loop()
{
.
.
.
   if( fired )
   {
        pulseTime4 = pulseTime3; //keeping track of last 4 signal times
        pulseTime3 = pulseTime2;
        pulseTime2 = pulseTime1;

        // Make sure we don't have a race condition - disable interrupts while
        // accessing our shared variables.
        cli() ;
        pulseTime1 = HallTimeNew - HallTimeOld;
        fired = false ;
        sei() ;
   }
.
.
.
}

Also, since you're CPU constrained right now, you're obviously going to need some serious optimization. For starters, add to your loop:

void loop()
{
   while( true )
   {
      // Place your existing loop here
   }
}

As for the pulseTime value shifts, you might consider using an array and using memcpy. I've been meaning to test performance to see which is faster. As such, I'm not sure it will be faster but it would be worth a try. The code would look something like this:

volatile unsigned long pulseTime[4] ;
.
.
.
if( fired )
{
   memcpy( &pulseTime[0], &pulseTime[1], 3*sizeof(unsigned long) ) ;
   // Make sure we don't have a race condition - disable interrupts while
   .
   .
   .
}

Now that you have an 'errorCount' variable, wouldn't hurt to periodically test to see if any errors have occurred. If you're seeing a lot of them, meaning past some threshold, to shut things down because time is off and undefined. Having any type of delay in your main loop should give you pause. But at least you can now detect some timing errors.

Lastly, as for a signal generator, would this be a good use for something like a 555 tied to a pot?

Edits: Fixed potential race condition. Optimized ISR. Realized much later I used memcpy to shift the wrong direction. Fixed.

Thanks for the tips! I didnt think about variables changing half way through. and testing for it is a bloody good idea too :slight_smile:

Keep in mind the errorCount detects a timing issue, not that the values were changed half way through. In fact, that race condition should never happen now. If it does, its a bug. Please note the use of the sei() and cli() functions. Those respectively enable and disable interrupts, thereby avoiding the race condition.

What it attempts to detect is that an interrupt has been missed/serviced, meaning its taking longer to service an interrupt than the rate at which they are occurring. Which is why, should you begin to detect errors, more than likely something has gone horribly wrong with the timing.

Meant to post this here but it went to another thread accidentally, this file has pickup and driver circuits + a whole pic biased controller for a distributor type ignition. You might be interested in the coil drivers unless you intend to drive CDI coils. Vespa Labs

LoL 3rd time the charm.

I thought about buying that kit from Jaycar years ago, but have never been able to find this info. I'll definetly be using this coil driver circuit. Thanks a lot!!!

Look at the Silicon Chip site they have the files for the circuit boards in the downloads. The also have the early version of the software but they do not have the software for the more advanced unit for some reason. Possibly so you buy the jaycar kits?

Just thought thought I would share I put together a hall pickup and coil driver from the plans I linked to and it works just great. Next I guess is to figure out the programming for my application.
I am doing a test here dropping the ground to the light.

http://www.flickr.com/photos/novegetablesnodessert/7550236592/in/photostream

Just want to give you a heads up to an issue I ran into with the electronics. It seems that in bench testing I was getting enough self induced noise in the circuit "Rx Tx LEDs would start flashing and zap" was crashing the arduino. This was at higher RPM 5000rpm to 10000rpm. I decided that I should have the system mounted to a larger ground chassis "Motorcycle Frame" to dissipate the negative flow of electrons "dump them into the big pool of the frame", this seems to have resolved my issue. Now to producing the hall pickup mount + mag-rotor for the motor before I attempt to program.

Update/Correction
Set up an RPM readout and thought the code was wrong than looked closer at the dremel rpm range 3500rpm to 28000rpm and the code is correct, so no proto-board crashes unless I over-rev the bike by at least 10000rpm. Hopefully this will be good.

Hi!

I could not saw any picture of wip, sorry.

I am onto CDI with VR input sensor, but I will be watching this project too.