Nou,een quick search levert genoeg stof tot inspiratie op.
Wel weer een project an sich maar daar zijn we niet vies van
hier iets compleet met vervroeging bij verschillende toerentallen,valt ook wel iets van te maken lijkt me zo.
#include <Avr/interrupt.h>
#include <Avr/io.h>
//Pin definitions:
const byte HallPin1 = 2; // Pin nr 2 to Hall sensor
const byte HallPin2 = 3; // Pin nr 3 is also to Hall sensor
const byte IgnOnPin = 4; // Ignition switch
const byte Ign1Pin = 8; // (PORTB,0)
const byte Ign2Pin = 12; // (PORTB,4)
volatile unsigned int cranktime; // Time from 3 degrees to where the coil should start to load.
volatile unsigned int crankingDwellTime; // The time the coil should charge during cranking
volatile long int microseconds; // The microsecondcounter value.
volatile long int half_revolution_time; // The time it takes for the crank to turn 1/2 revolution.
volatile int runningDwellTime; // The time the coil should charge during running
volatile int dwellTime; // The time the coil should charge.
volatile int IgnSystem; // Statusword for active ign system.
volatile byte IgnOn;
/***********************************************************************/
void setup() {
pinMode(Ign1Pin, OUTPUT); // Initialize the Ignition 1 pin as an output.
pinMode(Ign2Pin, OUTPUT); // -“-
pinMode(HallPin1, INPUT_PULLUP); // To get rid of RFI interference
pinMode(HallPin2, INPUT_PULLUP); // -“-
pinMode(IgnOnPin, INPUT_PULLUP); // -“-
bitClear(PORTB, 0); //digitalWrite(Ign2Pin, LOW); //Turn the ignition off in case it’s on
bitClear(PORTB, 4); //digitalWrite(Ign1Pin, LOW); // -“-
attachInterrupt(digitalPinToInterrupt(HallPin1), SensorOn, RISING); //Hall sensor DI for Ignition 1
attachInterrupt(digitalPinToInterrupt(HallPin2), SensorOff, FALLING); //-“- 2
crankingDwellTime = 4000; //in uS
runningDwellTime = 3000; //in uS
half_revolution_time = 0;
IgnSystem = 0; // No ignition system is active (cranking mode).
IgnOn=LOW;
IgnOn = digitalRead(IgnOnPin);
/********** Setup timer2*************/
noInterrupts();
TCCR2A = 0; // Turn off Control register for waveform generation
TCCR2B = 0; // Turn off noise cancelling, turn off edge select, waveform gen mode 0,
TCCR2A |= (1 << WGM21); // Turn on CTC mode (so it will start again) automatically
TIMSK2 |= (1 << OCIE2A); // Set interrupt on compare match.
OCR2A = 8; // Prescaler of 64 gives 4uS per tick, 4uS * 8 = 32uS (32uS = 1 degree at ~5100rpm).
TCNT2 = 0; // Reset timer counter to 0
microseconds = 0; // Preset the us counter variable.
interrupts();
}
//========================================================================
/* The interrupt action for magnet 1: The Timer starts to count up 32 uS at a time.
**********************/
void SensorOff () {
if (IgnOn == HIGH){
half_revolution_time = microseconds; // For engine speed measurement
TCNT2 = 0; // Reset the timer count to 0
microseconds = 0; // reset the uS counter variable
TCCR2B |= (1 << CS22); // Load 64 prescaler, and this starts the timer2!
// While cranking (rpm < 300), the coil nr 2 will start to charge at once.
if ((half_revolution_time>100000)||(half_revolution_time==0)) {
IgnSystem = 2;
bitSet(PORTB,4); //digitalWrite(Ign2Pin, HIGH); // (Turn on coil 2 charging immediately.)
dwellTime = crankingDwellTime; //Setting the dwelltime for cranking.
cranktime = 0; //Setting the cranktime to 0 for immediate coil charging.
}
// While running (rpm >= 300), coil nr 2 will be used at next ignition.
if ((half_revolution_time<=100000)&&(half_revolution_time!=0)){
IgnSystem = 1; //start using coil nr1 instead.
dwellTime = runningDwellTime; //setting the dwelltime for running
}
}
}
/*========================================================================
The interrupt action for magnet 2: The Timer starts to count up 32uS at a time.
********************************/
void SensorOn () {
if (IgnOn == HIGH){
half_revolution_time = microseconds; // For engine speed measurement
TCNT2 = 0; // Reset the timer count to 0
microseconds = 0; // reset the uS counter variable
TCCR2B |= (1 << CS22); // Load 64 prescaler, and this starts the timer2!
// While cranking (rpm < 300), the coil nr 1 will start to charge at once.
if ((half_revolution_time>100000)||(half_revolution_time==0)) {
IgnSystem = 1;
bitSet(PORTB,0); //digitalWrite(Ign1Pin, HIGH); // (Turn on coil 1 charging immediately,)
dwellTime = crankingDwellTime; //setting the dwelltime for cranking.
cranktime = 0; //Setting the cranktime to 0 for immediate coil charging.
}
// While running (rpm >= 300), coil nr 2 will be used at next ignition.
if ((half_revolution_time<=100000)&&(half_revolution_time!=0)){
IgnSystem = 2; //start using coil nr2 instead.
dwellTime = runningDwellTime; //setting the dwelltime for running
}
}
}
/*=============================================================================
The Interrupt Service Routine for Timer2 that will be executed each time the timer reach the compare match register (32uS)*/
ISR(TIMER2_COMPA_vect) {
microseconds=microseconds+32; // Increases the variable “microseconds” by 32 every time the ISR is executed).
/************ coil charging*****************************/
if ((microseconds >= cranktime) && (microseconds < (cranktime+dwellTime))) {
if (IgnSystem == 1) { //If ignitionsystem 1 is selected, then:
bitSet(PORTB,0); //(Turn on coil 1 charging.) //digitalWrite(Ign1Pin, HIGH);
} if (IgnSystem == 2) { //If ignitionsystem 2 is selected, then:
bitSet(PORTB,4); //(Turn on coil 2 charging.) //digitalWrite(Ign2Pin, HIGH);
}
}
/***********Discharge coilspark*******************************************/
// When the microseconds has reached the cranktime and dwelltime, then:
if (microseconds >=(cranktime + dwellTime)) {
bitClear(PORTB, 0); //digitalWrite(Ign1Pin, LOW); //( Stop charging coil 1. (Gives spark))
bitClear(PORTB, 4); // digitalWrite(Ign2Pin, LOW); // As above.
// _________________________________________________________________________________________________________
if (microseconds > 100000) { // If the engine has stopped or still cranking, stop and reset the timer.
TCCR2B &= ~(1 << CS22); // Clear the prescaler, and this stops the timer2!
TCCR2B = 0;
microseconds = 0;
}
}
}
/***********************************************************/
void loop() {
IgnOn = digitalRead(IgnOnPin); // Check the status of the ignition switch
// Ignition advance curve.
//Following numbers are based on a excell sheet with the advance curve attached.
if (half_revolution_time> 6208 ){ ///Advance 0 @ >4100 rpm (rev limitation)
cranktime=7195-dwellTime;}
if ((half_revolution_time<= 7500 ) && (half_revolution_time> 7317 )){ ///Advance 28 @ 4000-4100 rpm (rev limitation)
cranktime=6208-dwellTime;}
if ((half_revolution_time<= 9091 ) && (half_revolution_time> 7500 )){ ///Advance 28 @ 4000-3300 rpm
cranktime=7525-dwellTime;}
if ((half_revolution_time<= 10000 ) && (half_revolution_time> 9091 )){ ///Advance 27,5 @ 3300-3000 rpm
cranktime=8306-dwellTime;}
if ((half_revolution_time<= 10714 ) && (half_revolution_time> 10000 )){ ///Advance 27 @ 3000-2800 rpm
cranktime=8929-dwellTime;}
if ((half_revolution_time<= 11111 ) && (half_revolution_time> 10714 )){ ///Advance 26 @ 2800-2700 rpm
cranktime=9321-dwellTime;}
if ((half_revolution_time<= 12500 ) && (half_revolution_time> 11111 )){ ///Advance 24 @ 2700-2400 rpm
cranktime=10625-dwellTime;}
if ((half_revolution_time<= 15000 ) && (half_revolution_time> 12500 )){ ///Advance 22 @ 2400-2000 rpm
cranktime=12917-dwellTime;}
if ((half_revolution_time<= 15789 ) && (half_revolution_time> 15000 )){ ///Advance 20 @ 2000-1900 rpm
cranktime=13772-dwellTime;}
if ((half_revolution_time<= 16667 ) && (half_revolution_time> 15789 )){ ///Advance 18 1900-1800 rpm
cranktime=14722-dwellTime;}
if ((half_revolution_time<= 18750 ) && (half_revolution_time>= 16667 )){ //Advance 16 @ 1800-1600 rpm
cranktime=16771-dwellTime;}
if ((half_revolution_time<= 20000 ) && (half_revolution_time>= 18750 )){ //Advance 14 @ 1600-1500 rpm
cranktime=18111-dwellTime;}
if ((half_revolution_time<= 21429 ) && (half_revolution_time>=20000 )){ //Advance 12 @ 1500-1400 rpm
cranktime=19643-dwellTime;}
if ((half_revolution_time<=25000 ) && (half_revolution_time>= 21429 )){ //Advance 10 @ 1400-1200 rpm
cranktime=23194-dwellTime;}
if ((half_revolution_time<=27273 ) && (half_revolution_time>=25000 )){ //Advance 9 @ 1200-1100 rpm
cranktime=25455-dwellTime;}
if ((half_revolution_time<= 30000) && (half_revolution_time>=27273 )){ //Advance 8 @ 1100-1000 rpm
cranktime=28167-dwellTime;}
if ((half_revolution_time<= 33333) && (half_revolution_time>= 30000 )){ //Advance 7,5 @ 1000-900 rpm
cranktime=31389-dwellTime;}
if ((half_revolution_time<=42857 ) && (half_revolution_time>= 33333 )){ //Advance 7 @ 900-700 rpm
cranktime=40476-dwellTime;}
if ((half_revolution_time<=50000 ) && (half_revolution_time>= 42857)){ //Advance 7 @ 700-600 rpm
cranktime=47222-dwellTime;}
if ((half_revolution_time<= 75000 ) && (half_revolution_time>= 50000 )){ //Advance 9 @ 600-400 rpm
cranktime=70000-dwellTime;}
if ((half_revolution_time<= 85714) && (half_revolution_time>= 75000 )){ //Advance 2 @ 400-350 rpm
cranktime=83333-dwellTime;}
if ((half_revolution_time<= 100000 ) && (half_revolution_time>= 85714 )){ //Advance -2,5 @ 350-300 rpm
cranktime=99722-dwellTime;}