get rotation deggres based on time

hello guys im trying to read a wheel spinning up to 13000 rpm. the wheel got 11 teeth with one missing teeth 12-1 witch i count em with an variable reluctance sensor

my idea for this is

if we do 1/360 = 0.0027777777777778
lets say time for a full rotation is 12345 micros

so if we do 12345 * 0.0027777777777778 = 34.29166666666694 micros for 1 deggre
and then lets say that 15555 micros passed that means

15555 / 34.29166666666694 = 453.6087484811628 deggrees after 15555 micros passed

but when i code this into arduino i always missing 3-4 deggrees example :171,175,179,183,186 etc
also when rpms start to rise arduio take so much time to slove that division 15555 / 34.29166666666694
and its startig to missing things

also im using a led to check if im at desired angle

is there any better method for this ? i just want 1 deggre acuracy plus to be able to work at 13k rpm

bump now one can help ????

lets say time for a full rotation is 12345 micros

Why?
60/130000 = 4.615 milliseconds (4615 microseconds)

12345 micros is about 405rpm it was just for example.rpm range varries from 500 to 13000 rpm

motoGuyDIY:
is there any better method for this ?

Did I miss where you actually post the code for your method?

You don’t need to use division to count so there are signs your method could use improvement.

At 13000 rpm, one degree is 1.282 microseconds.
That's just twenty instruction cycles.

At 13000 rpm, one degree is 12.82 microseconds, not 1.282......

leongjerland:
At 13000 rpm, one degree is 12.82 microseconds, not 1.282......

correct - apologies - problems counting the zeroes on a phone app calculator with no scientific format key.

correct forgot to add the code this is my interrupt function

//interrupt ISR
void InteruptPulse() {
	pulseTrigerTime = micros(); //teeth Now time

	previusPulseDurationTime = pulseDurationTime; //previus pulse durration
	pulseDurationTime = pulseTrigerTime - previusPulseTrigerTime; //no pulse duration
	//if pulseDurationTime > max RPM return ;
	teethCounter++; //teeth counter

	if (pulseDurationTime > ((previusTimeAtGap - currentTimeAtGap) + ((previusTimeAtGap - currentTimeAtGap) >> 1))  || teethCounter > actualWheelTeeth) { //missing teeth
		if ( (teethCounter < actualWheelTeeth) && crankWheelSynced) {
			crankWheelSynced = false;
			return;
		}
		else {
			crankWheelSynced = true;
			previusTimeAtGap = currentTimeAtGap; //toothOneMinusOneTime
			currentTimeAtGap = pulseTrigerTime; //toothOneTime
			//get how much time for a 360 rot
			totalRevolutionTime = pulseDurationTime * 12;
			rotatedWheel = !rotatedWheel;
			teethCounter = 1;
		}
	}else {
		//crankWheelSynced = true;
		//totalRevolutionTime = pulseDurationTime * 12;
	}
	previusPreviusTrigerTime = previusPulseTrigerTime;
	previusPulseTrigerTime = pulseTrigerTime;
}

and this is my calculate function

int getCrankAngle() {
	unsigned long toothLastTime = 0;
	int teethCount= 0;
	bool isNextStroke = false;
	unsigned long totalRevTime = 0;
	unsigned long teethDuration = 0;

	noInterrupts();
	teethDuration = pulseDurationTime; //30 degree time

	teethCount = teethCounter; //from ISR
	isNextStroke = rotatedWheel; //check in witch stroke we are

	toothLastTime = pulseTrigerTime;//pulseTrigerTime;//pulseTrigerTime;//currentTimeAtGap;
	totalRevTime = totalRevolutionTime;//totalRevolutionTime;//totalRevolutionTime; //previusPulseDurationTime
	interrupts();

	int crankAngle = ((teethCount -1) * triggerToothAngle) + 270; //eeth -1 * 30 deggres + 270 witch is the offset

	unsigned long elapsedTime = (micros() - toothLastTime);
	
	crankAngle += elapsedTime / (teethDuration * 0.03333333333333333333333333333333);

	if (isNextStroke) { crankAngle += 360; }
	if (crankAngle >= 720) { crankAngle -= 720; };
	if (crankAngle < 0) { crankAngle += 360; }
	return crankAngle ;
}

So by Robin's updated calculation there's about 200 instruction cycles in one degree. Your getCrankAngle() function is about that long, probably longer. So when you ask it to tell you the crank angle, do you want to know what the angle was when you called it or what it's going to be when it returns the number to you?

Just arbitrarily asking for the crank angle "now" doesn't seem very useful. Isn't it more useful to know when it is at a specific position, like degrees BTDC? Maybe there is another way to do what you want.

Is this system supposed to work under acceleration? In one revolution, the crank may accelerate significantly. Your code will think that it's at 320 degrees when the missing tooth comes past to say that you are actually at 360 degrees. To improve the situation, I would have getCrankAngle() work its calculations from the last tooth that was observed. Even if you only update the speed once per revolution, that will keep you closer to the actual position.

hey yes this is going to work under acceleration/decceleration.I want to see if the wheel is for example 32 deggres before TDC and by doing 360 - 32 we got 328 deg so i want to check if im at that potision.

another methond i tried was
for example we are at the 10 tooth so that gives us 300deg

if ( 328 > 300(current_teeth * 30){
if(328 - 300 < 30){
//do the calculations here }
}

this saved me some time i have to say but i dont like this method verry much

crankAngle = ((teethCounter)* triggerToothAngle);

if (teethPassedCounter < actualWheelTeeth) {
			if (crankAngle <= targetAngle && (teethPassedCounter + 1) * 30 > targetAngle) {
				int var = targetAngle - crankAngle;
				int modulus = var % triggerToothAngle; //here we get the rest of the teeth lets say if wee need teeth 11.5 we get the .5 here
				
				if (modulus > 0) {
					offset = (((modulus * 100) / 30) * toothDuration) / 100;
				}else { //if its the angle just on a teeth 
					offset = (microsNow - timeNow) * 2; //fire now
				}
			}

		}

motoGuyDIY:
we got 328 deg so i want to check if im at that potision.

I still don't see the point. By the time you've answered the question, the crank has moved a significant (to you) distance past the point it was at when you asked the question. Even if you ask "am I at 327 yet?" to allow for a one-degree lag, that lag changes depending on the speed that you're doing so maybe you are still at 327 when the answer comes back or maybe you have reached the target 328.

It sounds like you're making an Arduino ECU. That can work for small (eg. single cylinder) engines at low speeds (not 13,000rpm.) For serious ECU work, it's better to start from a chip that's purpose-built for the task.

A better way to trigger a spark at a specific position BTDC is to calculate in advance which tooth it comes after and then, when you see that tooth, delayMicroseconds() for the correct number of microseconds to get the exact degrees after the tooth.

hey you are correct im trying to make an ecu for a single cylinder bike but for now im just doing tests with leds.i think it can work for example speeduino is working on 2560 mega and its more complicated that my simple for now project and it controls much more things so it needs more time to control things read a ton of sensors and calculate the angles.but anyway an arduino due could be a better option ? but its only 3.3v on the pins and i need 5v max from sensors

Then you answered your own question. A Due would not be a better option because of the 5V sensors.

Not really true , a simple two resistor potential divider could allow 5v signals to be dropped to 3v3 for use with a due.
For analog a opamp would be a better option still