Hello guys this is my first project with uno and its going very well.
I am trying to make a parallel ecu for my small 150 cc efi bike that i will use to tune it my self
so far i can read all the sensors, read rpm, calculate the injector pulse width but i do miss one part
to make my bike run with my fuel map.
i want to know how to get the angle of the crankshaft so i can time the injector correctly, i already read the crankshaft sensor using interrupts by using this code
|
int ReadCrankTimes(){
int maxAngle = 360, math = 0,angle = 0;
noInterrupts();
Serial.println(timeoldHigh);
Serial.println(timeoldLow);
math = timeoldHigh + timeoldLow ; //360
interrupts();
}
void InteruptPulse(){
unsigned long TimeNow = micros();
state = digitalRead(CrankInputPin);
//divide by 2 later on GetRpm
++crankRevolutions;
if(state == LOW){
timeoldLow= TimeNow - lastTime;
}else{
timeoldHigh = TimeNow - lastTime;
}
lastTime = TimeNow;
}
my idea was to calculate how many angles is the missing tooth from the total 360 rotation and start from there
by using timeoldLow / (timeoldHigh + timeoldLow) * 360 but i dont think this is the correct way to do it
so timeoldHigh + timeoldLow its a 360 turn
4 strokes are 2 360 crankshaft turns
here you can use some data from my logs if you want
Don't do that! Serial printing uses interrupts. Grab "safe" copies while interrupts are disabled, turn the interrupts back on, THEN do your calculation or printing.
The Arduino is not the ideal platform to make an ECU. There are specialized processors that basically run the entire program synchronized with the crank rotation. However it can be done for simple control of small numbers of cylinders.
Once you have a complete revolution, then you can estimate that the next one will take the same amount of time. So a fraction of a revolution is a fraction of that time.
How many pulses per crank revolution? You talk about a "missing tooth" which usually means many pulses per revolution but you also talk about having only two pulses per revolution. Which is it?
If you measure the time between tooth pulses the pulse that arrives after a much longer interval will be the tooth after the missing tooth. And if you know where, relative to the crankshaft, the missing tooth is you can identify the crank position.
Keep in mind that you will need to know the angle much more accurately than +/- 30 degrees so you must use time. You can use successive pulses to update the timing as the speed varies.
motoGuyDIY:
my wheel got 12 teeth with 1 missing so its 11 actual teeth
360 / 12 = 30deg
Is the long pulse a HIGH pulse or a LOW pulse? I'm going to guess that RISING edges signal the signal the start of a tooth and FALLING edges signal the end of a tooth, so the long pulse would be LOW. You don't need both edges so I would look only at RISING edges.
If you keep an average of the last few tooth times (RISING to RISING) you should be able to easily detect the RISING edge of the First Tooth (the one after the gap). It will have a tooth considerably longer than the average. I would try 1.5 times the average as a threshold to detect the long gap.
The average tooth time, times 12, will give you an approximation of the time per rotation. You can use the rotation rate, last edge number, and last edge time to calculate the degrees since the First Tooth. If the First Tooth is not a TDC then you would add an offset to get degrees from TDC.
I like that ISR. I would add a count of which pulse last passed so the time-based calculation is only within a 30° or 60° interval:
volatile unsigned long PulseInterval; // Microseconds between the last two pulses
volatile unsigned long PulseTime; // Time (micros()) of the rising edge of the latest pulse
volatile byte PulseNumber = 0; // Which pulse was the latest pulse
volatile boolean PulseIsNew = false; // Flag set by the ISR
void myPulseIsr()
{
static unsigned long prevPulseTime; // Needed for detecting the new pulse interval
static unsigned long prevPulseInterval; // Needed for detecting the long pulse
PulseTime = micros();
prevPulseInterval = PulseInterval; // save the preceding value
PulseInterval = PulseTime - prevPulseTime;
prevPulseTime = PulseTime;
PulseNumber++;
// A pulse longer than 1.5 times the previous pulse indicates the index pulse (#0).
if (PulseInterval > (prevPulseInterval + (prevPulseInterval >> 1))) // compare to prev * 1.5
{
PulseNumber = 0;
}
PulseIsNew = true; // Let loop() know that new data is available
}
void setup()
{
attachInterrupt(digitalPinToInterrupt(2), myPulseIsr, RISING);
}
void loop()
{
static unsigned long localPulseTime = 0;
static byte localPulseNumber = 0;
static unsigned long microsecondsPerRevolution = 999;
if (PulseIsNew)
{
// Grab the volatile variables.
noInterrupts();
unsigned long localPulseInterval = PulseInterval; // Should work down to 152 RPM
localPulseTime = PulseTime;
byte localPulseNumber = PulseNumber;
PulseIsNew = false;
interrupts();
microsecondsPerRevolution = localPulseInterval * 12;
if (localPulseNumber == 0)
{
microsecondsPerRevolution = localPulseInterval * 6; // Long Pulse
}
}
unsigned long microsecondsSincePulse = micros() - localPulseTime;
long int degreesSinceIndex = 30 * localPulseNumber; // First 11 pulses are at 30° intervals
// Equivalent to (microsecondsPerRevolution / microsecondsSincePulse) * 360 but less subject to truncation
degreesSinceIndex += (microsecondsPerRevolution * 360UL) / microsecondsSincePulse;
// THIS IS WHERE YOU ADJUST 'degreesSinceIndex' FOR OFFSET FROM TDC
// This is where you use the new crank position
}
thnx a lot for your code i will study it right now. btw i went to my bike and used a socket to turn the crank
while i was turn the crank there was a spot where the fuel pump worked so that was the trigger point for ecu
then i turn the crank counter clockwise and the pump worked again so i said it must be the ecu count the teeth .so i turned the key off and then on and tried the same thing fuel pump worked so it must be a static trigger
i need to remove the stator case to see at what point the efi gets triggered
hey guys i got a small update i cant read the sensor correct yet but i do know that from teeth number 1
till the sensor location at TDC its 4.5 teeth that means 135deg so the triger point is 360 - 135 = 225 deg
sensor got 2 cables can it possible be an inductive sensor instead of hall sensor ?if so how you read an inductive sensor because i only get only 2 pulses per rotation
as far i know a hall effect sensor got 3 cables.I attached my sensor btw i read somewhere that if sensor is inductive i need a converter from analog to digital to read it.if so is there any fast converter? what do you recommend for this job
Why don't you write a short program that does nothing except try to detect a pulse from the sensor. That way you can easily try different circuit configurations.
motoGuyDIY:
i will try tomorrow with an ADC converter what do you recommend i want something fast for this job
At this stage I don't even know that an ADC is needed. That's why I suggested a simple test program. If it was my project I would be hoping to be able to detect it with a digital HIGH or LOW.
yea i know i tried everything but its not working. take a look at my readings with analogRead conerted to voltage. this looks like an analog signal so i need to convert it to understand it