Atmega 8 ignition filtering

Go To Last Post
23 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,
I'm trying to build a variable ignition controller for my motorcycle, but in the beginning appeared a problem with voltage filtering.The uC cannot measure the engine speed is jumping between 1200 to 4000rpm, but the engine speed simulator is running at 1200rpm.
The ignition coil comes from Opel Astra F(16NZ engine) fuel injection and is shielded, low impedance coil 0.4 ohm.
Because the low impedance of coil, i need to vary the dwell angle.
The signal pickup is a hall sensor TLE4905(power comes from the uC 5v stabilizer)and the power output schematic is below.
My concern is about peak voltage coming from ignition coil when the secondary coil collapse(spark).
The power for uC comes from a 5V stabilizer and a 3300uF capacitor, the test power supply is a laboratory supply so there isn't any noise that perturb the uC.Same supply is for the ignition coil, only have 12V.
I've try to connect a capacitor 100nF...220nF and 1N4007 diode between coil input and the ground but unfortunately without success.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

do you have a LPF on the uC'sinput ?
I sugest to use a separate PSU for the uC part, i suppose that your laboratory PSU goes on constant current mode when Q1 is open

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mz,

Circuits like these are a snakepit of noise, ground bounce, EMI and wiring dress problems and headaches.

You can shotgun the "noise" issues forever and never get a reliable solution. You really need to go at this thing with a good differential scope probe on the cycle itself to make sure every premise of your circuit design is true to your intents. For example, that the micro is getting "noise-free" 5 VDC and that when the ignition coil fires your grounds are not adversely affected.

Not much fun, but definetly a good learning expreince, if you've got the stomach for it and the right equipment.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@vstana, yes is a lab PSU,on my PSU i probably can separate but on the bike how can i separate? I don't use low-pass filter only one capacitor(100nF) before the stab and after 3300uF.what RC should use?

@Chuck-Rowst, i agree with you100%, but if with a lab PSU doesn't work properly, how should expect to work on the bike, where the voltage regulator/alternator will do more noise...
to testing i use 2 power resistor in array with ignition coil to get the 2.8ohm for keeping alive the mosfet transistor till i figure out the time to charge properly the coil and do not overheat the mosfet.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There are specific devices for driving ignition coils. I'd suggest you use them or a commercial coil driver. Have a look at the megasquirt website for tried and tested solutions. Some of the commercial drivers I've seen have current limiting and active clamps to limit the primary voltage. Many years ago I repaired a ignitor box for a Yamaha FZR600. It used specific transistors which were difficult to obtain so I substituted a ST BU931 part that was similar except for the larger package. No external snubbing was used.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

most modern bikes are working at high rpm ~10000 and use CDI, my bike is an old one with low rpm range and TCI is better.
I'm planing to use this coil drive IRGS14C40LPBF
Take a look on the schematic(HGTP14n40fvl).is used other uC but the supply could be use on my project.
I use the original pickup module, only the hall sensor was damaged and it needed to be change. the dwell angle is enormous: ~140degree with the engine off(i rotate manual the crankshaft), with engine on i didn't measured because i'm afraid to not damage the PC scope.The original coil have 3 ohm and this dwell angle is good, but the coil wasn't shielded and other electrical module drive by uC was out of service.
Here is another:
http://www.sportdevices.com/ignition/ignition.htm

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have done automotive ignition work for years, with good success. I do like Kartman suggests, and used an ignition drivers without output snubbers. I use a 1000 Ohm smd ferrite at the uC output to driver. Ground return location for driver is important. Avoid ground path in AVR supply circuit.

Dwell is timer controlled, and is predictive to yield specified dwell over rpm range. Dwell is extended only when starting. It is important to do stall detection, with ignition and fuel timeout. 11K RPM is not a problem.

Working with a simulator on the bench speeds development. A scope is essential. A drill can be used to spin sensor. An Ohm or two of series resistance in coil circuit, will save drivers and coil while software is developed. Remove when complete.

It all starts with a mental vision.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Name a modern high performance bike that uses CDI. Apart from the rf interference it generates it also has a small firing time. TCI has a much longer spark duration whichis good for ensuring the mixture burns. CDI is mainly used on two strokes and they're dying off at a rapid pace. Last year of 125s in moto GP. Latest bikes are coil on plug and have individual coil drivers as do most cars. Sheilded coils are for rf interference supression, 90 s model bikes didn't worry about such things and used unshielded coils. Get yourself an ignitor box from a later model bike and see howvthey do things. The FZR600 box was easy to work on. Just replace the micro and you're off.

The circuit you posted sucks for many reasons.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

noise:
In looking at the PIC circuit I wonder if it is set up for a VR (varible reluctance sensor) not hall. The attenuation, clip and ac coupling suggests that. It is not correct for a hall device.

The sensors do not control dwell, they provide a timing reference. The dwell needs to be calculated as a time in mS preceding the ignition event. Desired timing is calculated from the reference.

Hall sensors typically provide nice outputs. Often they are open collector output and require a stiff pull-up resistor to Vcc. The internal pull-up in the AVR will not work. The noise cancel can be enabled on the input capture. I have not had problems even with open spark plug nearby. The coil and ignition shielding may result in high peak currents due to the parasitic capacitance to ground.

timing table:
For timing in addition to RPM, MAP and engine temperature help for optimized tuning.

firmware:
Timer interrupts using input capture for sensor input, and output compare for coil drive signal may be the heart of the firmware. There are advantages in using the same free running timer. Calculations for control updates are best done from main(), enabled by flags set in ISRs. A typical update time is < 1mS, enough time for each combustion event.

development:
You are starting in the right place. Get good input signal first. Get reliable RPM for the whole range, then work on timer for ignition event and dwell. An RPM simulator with another AVR with serial or pot RPM control also helps. This step will insure the firmware is correct. Then move to real sensor. Then get plug to fire.

It all starts with a mental vision.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A 0.4 Ohm coil is typical of a CD Ignition. You do not control dwell on these coils but rather charge a high voltage capacitor and dump the charge through an SCR into the coil. A Kettering ignition uses a high inductance coil, typically 3 Ohm, that is charged by dwell time and turned off to develop the spark. You will quickly heat up a CD coil trying to saturate it through dwell time.
Your 3300uF is good for brown outs but you also need a nF capacitor to bypass high frequency spikes.
Your huge dwell angle when manually rotating the crankshaft is because of where the pickup is oriented in relation to the firing angle, probably around 180 degrees before TDC. Dwell is angle measured on a mechanical advance ignition. On an electronic system it is time measured. A 3 Ohm coil typically needs 4 ms to charge. The time from the trigger to the coil discharge is calculated from RPM and then the dwell time subtracted from that to determine when to start powering the coil.
Check your original pickup with a piece of steel. The Yamaha pickup has a magnetic core with a coil. The end is placed next to a toothed wheel which changes the inductance as each tooth approaches and recedes.
My programmable ignition uses a mega88 with IGBTs to fire the coils. No snubber, just the freewheeling body diode. No problems with noise even with the circuit unshielded, the three coils and open spark plugs 30cm away.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for your help

I measured the original pickup module dwell time.

First: 22.22hz => 1333.2rpm => 21ms dwell time => 167 degree.

Another test:
27hz => 1620rpm => 17ms dwell time => 165 degree

The measurements are not 100% accurate because the simulator(i used a drill machine to spin the magnet of the original pickup).

Here are the log files, use EasyLogger to open them:

http://www.easysync-ltd.com/userfiles/editor/file/support/software/DDL1M12_Setup.zip

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It appears that pick-up output is measuring a constant crank angle? Try rotating the crank until the pick-up changes output, stop turning and see if the output changes again at a fixed time. So you can use the pick-up open/close to calculate the RPM rather than waiting for an entire revolution.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The pick-up is fixed output, not variable(advanced ignition).
The engine is 250cc, 2stroke, 1 cylinder.

Here is the code what i test:

// Avrstudio 4.17.666
// Winavr 20100110
// Mega8, 8MHz

#include 
#include          
#include              
#include      
#include "lcd.h"


#define OutON  PORTB |= (1<<2)
#define  OutOFF PORTB &= ~(1<<2) 

// input switch
#define sw_on  ~PINB & (1 << 0)
#define sw_off   PINB & (1 << 0)


char     tempstr[9];
uint8_t pulse_width2;
uint32_t rpm;
volatile uint16_t pulse_width, delay_time;


unsigned char LedState = 0;   // Keeps track of the LED on/off state 
volatile unsigned char LcdDelay;   
volatile unsigned char PulseDelay;  

//-------------------------------------------------------------------
ISR (TIMER0_OVF_vect) 
{
// timer
 static unsigned char Count1mS = 0;
   
   TCNT0 += 6; // Adjust count so we get 250 uS rollover period
   
   if (++Count1mS == 2)
   {
      // Set a flag to indicate 1mS has elapsed
      Count1mS = 0;
	PulseDelay++;
 
	if (++Count10mS == 200) // 200ms
	{
	Count10mS = 0;
	LcdDelay = 1;
	}
	
}
	}
//-------------------------------------------------------------------

ISR(TIMER1_CAPT_vect)
{
static uint16_t new_edge, prev_edge;

   new_edge = ICR1;
   pulse_width = new_edge - prev_edge;
   prev_edge = new_edge;   

}

// -------------------------------------------------------------------
void Timer_0_setup(void)
{
// setup timer 0
 TCCR0 |= (1 << CS01); // 8 divider
TCNT0 = 0;            // Initial value 
TIMSK |= (1<<TOIE0); //Timer/Counter0 Overflow Interrupt Enable

}

//-------------------------------------------------------------------
int main(void)
{
DDRB |= (1 << 2); // Set led as output
   DDRB   &= ~(1 << PB0);           // set ICP pin as input
   PORTB  |=  (1<<PB0);             // pull-up
   TCCR1B  =  (1<<CS12);            // prescaler = 256
   TIMSK  |=  (1<<TICIE1);          // enable Input Capture Interrupt
Timer_0_setup();
   lcd_init(LCD_DISP_ON); /* initialize display, cursor off */
lcd_clrscr(); /* clear the screen*/
                                                     
   for(;;)
   {
      cli();

	  //rpm
	  pulse_width2 = pulse_width * 256UL / (F_CPU / 1000); // 256 is prescaler 
	  sei();
	//rpm
	rpm = 60000 / pulse_width2; 

//-----------------------------------------------
if ((rpm > 1250) && (rpm <= 1500))
{
delay_time = 8;
}

else if ((rpm > 1000) && (rpm <= 1250))
{
delay_time = 12;
}

else if ((rpm > 750) && (rpm <= 1000))
{
delay_time = 14;
}

else if ((rpm > 500) && (rpm <= 750))
{
delay_time = 18;
}

else if (rpm <= 500)
{
delay_time = 30;
}

//-------------------------------------------------------------

if (sw_off)
{
LedState=0;
OutOFF;
}

if ((sw_on) && (LedState==0))
{
//OutON;
PulseDelay = 0;
LedState=1;
}

  if (PulseDelay == delay_time)
{
if (sw_on)
{
OutON;
}
}

//------------------------------------------------------------ 

   if (LcdDelay==1)
{
lcd_clrscr();  
	// time
      utoa(pulse_width2,tempstr,10);  
	  lcd_gotoxy( 0, 0 );
      lcd_puts(tempstr);

	// rpm display
	   utoa(rpm,tempstr,10);
	  lcd_gotoxy( 7, 0 );
      lcd_puts(tempstr);
    


LcdDelay = 0;
}
   }
} 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A two stroke engine really wants a CDI system due to plug oiling. CDI can punch through this better. Also note that the advance angle decreases with RPM with a two stroke as the scavenging improves and the burn speed increases.

I'd suggest you look at using the timer1 compare function for the coil trigger.

With the racing two strokes I've worked on, the flywheel has pole pieces and a reluctor pickup. The pole piece is the angle width of min advance to max advance so the electronics can detect the start and end of the pole piece and interpolate the ignition time between these two points.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are mixing variable sizes in your equations which could cause problems. 'pulse_width2' is calculated from variables and constants that are all larger than uint8. I think the compiler will take all the constants and replace them with a single value (250UL/F_CPU/1000) = ? Possibly zero. (250000/8000000 = 0.03125 float, 0 unit8.
You are setting constant ignition advance within certain RPM ranges?
Instead of "if ((rpm > X) && (rpm <= Y))" you could use if-elseif statements:
if (rpm < x)
delay = A;
elseif (rpm < y)
delay = B;
elseif (rpm < Z)
delay = C;
else delay = D;

Where x, y, z, ... are all increasing rpms.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks, i will correct the code.

volatile uint16_t pulse_width, pulse_width2, delay_time; 

My delay method will be good?
First i read the RPM value than at specific value of it i make the delay than when on pick-up i have signal(ground), i delay the coil charge, after delay time is over the coil is charged until the pick-up i don't have (ground) signal and the spark is produced.

For the moment i wan to make the dwell time constant (~1ms) for all RPM ranges.After i will try to make advanced ignition.
Every 30 RPM should sample for adjusting the dwell time?i've try every 100..200rpm but is far to much i need to lower it, but what is the optimal sample value?

I don't have the advance MAP only the torque chart.

As you see the maximum torque is reached between 5000 and 5200 RPM. The pick-up is fixed at 22.15degree BTDC.

I want to increase maximum torque RPM ranges.
From the chart result 709us to 738us is the optimal timing from producing the spark till the TDC(0 degree), please correct me if i'm wrong.
Another problem is the coil driver schematic.
For filtering the driver(IRGS14C40LPBF) output what are the values for them (Capacitor and diode..Schottky or Rectifier diode).

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is this engine a MZ ETZ motorbike? 'Bout the only thing that produces so little power from Germany. If it were a Rotax the power would look a lot healthier!
With the ignition think in terms of degrees - it only becomes time when you know the rpm. Since it is a two stroke - use CDI. Go to a bike wreckers and get a ignitor box for a Suzuki RGV250 - there's two electronics boxes on this bike - one does the advance and power valve control and the other has an inverter and CDI system in it. Another option is a CDI box that was featured in the ETI magazine many years ago. Jaycar used to sell the kit. Most of the other two strokes I've worked on generated the high voltage via the alternator.

If you want to persist with the transistor assisted route, just buy a driver module from a car application. Have a look at the megasquirt site as they have a run down of the stuff available for popular cars. You'll either be able to buy one new or get one from a wrecker for an 80's car. Bosch have a nice little module that takes care of the driving of the coil - current limiting etc. You just tell it when to fire.

You want more torque spread - put an expansion chamber exhaust on it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes it is an MZ ETZ 250L(17KW) from 1988.I don't want to put a CDI because is larger and don't have place to put.
I prefer to build, rather than bay one.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Being a MZ owner, you should know about plug oiling problems. I had these issues years ago with a Suzuki GT250 that was points ignition. Going to CDI cures a lot of this problem. Being kick-start, I dare say you've cursed the bike when it doesnt start. You don't have the space? How big do you think a CDI unit is?

You can persist with your dodgy circuit and fiddle with the snubber, but as I and others have said, with the proper device, you don't need snubbers. Your noise issue is probably more due to circuit layout and large current pulses due to the coil saturating. Investigate if you can use commercial coil drivers from cars.
You want the primary circuit to reach 300-400V then be actively clamped in order to get a good spark voltage. Ignition coils, whilst a transformer, work by using the flyback voltage. You charge up the inductance (dwell time) and either time the start of the dwell period or current limit the primary until it is time to spark. Depending on the RPM and various other parameters the spark duration in terms of crank angle will vary. The spark is just to initiate the burn, the burn may well continue way past TDC.

Be aware if you get the timing wrong you'll burn a hole in your piston. Be sure your advance never goes too far. I speak from experience here.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't have oiling problem, with the old point ignition the same .... no problems(maybe because i use synthetic oil for mixture and i keep the REV high enough to not be underpowered)But when i forget the choke on, with some spark plugs model i have problems and doesn't matter what i'm doing but the engine don't want to start,the only hope to start is to change the spark plug.My carb is Mikuni VM36SS.

I've ordered the parts for the ignition: IRGS14C40LPBF and IRG4BC40UPBF.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm back with the same problem only now is better. My coil driver doesn't collapse anymore but is oscillating.
I think the coil/driver transistor/filtering should be the problem because the uC driver is working well without the coil.

#ifndef F_CPU
#define F_CPU 8000000UL
#endif

#include 
#include "lcd.h"
#include         
#include             
#include  

#define OutON  PORTB |= (1<<1)
#define  OutOFF PORTB &= ~(1<<1)

// input switch
#define sw_on  ~PINB & (1 << 0)
#define sw_off   PINB & (1 << 0)


char tempstr[9];
uint32_t rpm;
volatile uint16_t pulse_width, pulse_width2, delay_time;

volatile unsigned char LcdDelay;  
volatile unsigned char PulseDelay;

//-------------------------------------------------------------------
ISR (TIMER0_OVF_vect)
{
// timer
 static unsigned char Count1mS = 0;
 static unsigned char Count10mS = 0;
  
   TCNT0 += 6; // Adjust count so we get 250 uS rollover period
  
   if (++Count1mS == 2)
   {
      // Set a flag to indicate 1mS has elapsed
      Count1mS = 0;
   PulseDelay++;
 
   if (++Count10mS == 200) // 200ms
   {
   Count10mS = 0;
   LcdDelay = 1;
   }
  
}
   }
  
   //-------------------------------------------------------------------

ISR(TIMER1_CAPT_vect)
{
static uint16_t new_edge, prev_edge;

   new_edge = ICR1;
   pulse_width = new_edge - prev_edge;
   prev_edge = new_edge;  

}
  
   // -------------------------------------------------------------------
void Timer_0_setup(void)
{
// setup timer 0
 TCCR0 |= (1 << CS01); // 8 divider
TCNT0 = 0;            // Initial value
TIMSK |= (1<<TOIE0); //Timer/Counter0 Overflow Interrupt Enable

}

//-------------------------------------------------------------------
int main(void)
{
DDRB |= (1 << 1); // Set led as output
   DDRB   &= ~(1 << PB0);           // set ICP pin as input
   PORTB  |=  (1<<PB0);             // pull-up
   TCCR1B  =  (1<<CS12);            // prescaler = 256
   TIMSK  |=  (1<<TICIE1);          // enable Input Capture Interrupt
Timer_0_setup();
   lcd_init(LCD_DISP_ON); /* initialize display, cursor off */
lcd_clrscr(); /* clear the screen*/
                                                    
  while (1)
   {
      cli();

     //rpm
     pulse_width2 = pulse_width * 256UL / (F_CPU / 1000); // 256 is prescaler
     sei();
   //rpm
   rpm = 60000 / pulse_width2;

//-----------------------------------------------
if ((rpm > 1250) && (rpm <= 1500))
{
delay_time = 8;
}

else if ((rpm > 1000) && (rpm <= 1250))
{
delay_time = 12;
}

else if ((rpm > 750) && (rpm <= 1000))
{
delay_time = 14;
}

else if ((rpm > 500) && (rpm <= 750))
{
delay_time = 18;
}

else if (rpm <= 500)
{
delay_time = 30;
}

//-------------------------------------------------------------

if (sw_off)
{
OutOFF;
PulseDelay = 0;
}

  if (PulseDelay == delay_time)
{
if (sw_on)
{
OutON;

}
}

//------------------------------------------------------------

   if (LcdDelay==1)
{
lcd_clrscr();
   // time
      utoa(pulse_width2,tempstr,10);
     lcd_gotoxy( 0, 0 );
      lcd_puts(tempstr);

   // rpm display
      utoa(rpm,tempstr,10);
     lcd_gotoxy( 7, 0 );
      lcd_puts(tempstr);
  


LcdDelay = 0;
}
   }
} 

Here is my schematic:

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

good evening, interested in your ignition for MZ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

after 6 years ... ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...