Advice needed on reading 30,000+ RPM

I am testing 3d printed propellers, the sensor I am using is the TCRT5000. The problem is the propeller seems to not reflect enough IR light back to the sensor to trigger at >10,000 rpm.

I know hall effect sensors are better for this purpose, but sticking a magnet to the propeller would cause a lot of vibration and change its aerodynamic characteristics.

Ideally, the sensor should not need any modification to the propellers. I am thinking of using a pair of laser and detector modules, but they might face the same problem the IR sensors did.

The propellers I am testing have 2 blades and a cord of about 1cm for the sensor to detect when it passes.

Attached is the code I used to test the sensor, credit to InterlinkKnight on youtube

I would greatly appreciate help on this, thanks.

Tachometer_Using_micros.ino (11.7 KB)

How about an opto interrupter to sense the propeller tips passing through the gap?

I'll look into that,

At this point, I'm not even sure what's the bottleneck. Is it the sensor, something in the code, or the Arduino

The readings vary wildly on even lower RPMs

sadlad:
The problem is the propeller seems to not reflect enough IR light back to the sensor to trigger at >10,000 rpm.

How many blades? If three, that's 500 sensor hits per second. Is is possible to move the sensor closer to the axis of rotation? This might give the sensor time to react.

It might be helpful to do some math and figure out how long the blade is in the sensor's sweet spot.

dougp:
How many blades? If three, that's 500 sensor hits per second. Is is possible to move the sensor closer to the axis of rotation? This might give the sensor time to react.

It might be helpful to do some math and figure out how long the blade is in the sensor's sweet spot.

2 bladed prop, at 30,000 RPM, 500 RPS, 2 hits per rev, that means 1000 hits per second or once per millisecond.

The sensor is pretty close to the axis of rotation, about 25mm

v=rω
v=(25x10-3m)(30000RPM)(0.10472)
v=78.54 m/s

the cord of the blade is about 1 cm at the sensor
so..

d=vt
t=d/v
t=(1x10-2m)/(78.54ms-1)
t=1.2732x10-4 seconds , or 127 microseconds

So the sensor has 127 microseconds to trigger, and will have to do so 1000 times per second, or once per millisecond at 30,000RPM if my calculations are correct

I forgot to attach a picture of the setup, so here you go.
As you can see, I've even attached a thing with aluminum foil on the back of it to extend the time for the sensor to trigger, the problem still persists

I'd write some simpler code. Use interrupts, but just count signals from the sensor for ten seconds and then calculate. Then you can see whether the issue is code issues or sensor response time.

sadlad:
I'll look into that,

At this point, I'm not even sure what's the bottleneck. Is it the sensor, something in the code, or the Arduino

The readings vary wildly on even lower RPMs

That sounds like the reflection is not consistent.

The datasheet has no mention of the response time for the reflectance sensor either. Its a photo-transistor
detector though, which are slower than photo-diodes by a considerable margin.

wildbill:
I'd write some simpler code. Use interrupts, but just count signals from the sensor for ten seconds and then calculate. Then you can see whether the issue is code issues or sensor response time.

MarkT:
That sounds like the reflection is not consistent.

The datasheet has no mention of the response time for the reflectance sensor either. Its a photo-transistor
detector though, which are slower than photo-diodes by a considerable margin.

Ok, I made a simpler code (attached). The sensor only picks up the blades during the initial acceleration and deceleration, when the blades are relatively slow-moving.

Even then, I doubt the accuracy of the sensor's reading. When I pass a single finger in front of the sensor, it says that it counted anywhere from tens to hundreds of passes. This inaccuracy gets worse when I increase the sensor's sensitivity.

Maybe my sensor is bad???? I have no idea. What sensor do you suggest, Mark?

Tacho.ino (1.32 KB)

30,000 RPM is over 300 uS, and should be plenty of time even with 2 propellers cutting that time to 150 uS. If you took the IR LED off and mounted it so it’s now shining from the other side of the propeller you would now have a photo interrupter. I can’t see your code on my iPad so perhaps you can post it using the code tags in your reply screen. Are you using interrupts? I’m sure folks have gotten way more than 30,000 RPM using Arduino.

wolframore:
30,000 RPM is over 300 uS, and should be plenty of time even with 2 propellers cutting that time to 150 uS. If you took the IR LED off and mounted it so it’s now shining from the other side of the propeller you would now have a photo interrupter. I can’t see your code on my iPad so perhaps you can post it using the code tags in your reply screen. Are you using interrupts? I’m sure folks have gotten way more than 30,000 RPM using Arduino.

Here's my code, probably not a very good one, I'm new to this.
I think having the IR emitter on the other side of the prop as a photo interrupter is a very good idea. It's easier to detect a block rather than the reflection of the IR

#include<Chrono.h>

int passcount;
int ledstate = 0;
const int bladecount = 2;
const int irpin = 2;
const int ledpin = 6;
const int sample = 100;
unsigned long rpm;
unsigned long freq;
unsigned long period;
volatile unsigned long firstpass;
volatile unsigned long lastpass;
unsigned long t;

Chrono sampletimer;

void passdetect(){
  passcount++;
  if(passcount==1){
    firstpass = micros();
  }
  lastpass = micros();
}

void setup() {
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(irpin), passdetect, RISING);
  pinMode(irpin, INPUT);
  pinMode(ledpin, OUTPUT);
  passcount = 0;
  delay(1000);
}

void loop() {
  if(sampletimer.hasPassed(sample) && passcount > 0){
    t = lastpass - firstpass;
    firstpass = 0;
    lastpass = 0;
    period = (t/passcount)*bladecount;
    freq = 1000000/period;
    rpm = freq*60; 
    
    Serial.print("Δt = ");
    Serial.print(t);
    Serial.print(" µs | ");
    Serial.print(passcount);
    passcount = 0;
    Serial.print(" passes | ");
    Serial.print("period = ");
    Serial.print(period);
    Serial.print(" µs | ");  
    Serial.print(freq);
    Serial.print(" Hz | ");
    Serial.print(rpm);
    Serial.println(" RPM");
    digitalWrite(ledpin, ledstate);
    ledstate = !ledstate;
    sampletimer.restart();
  }
}