Problems measuring shaft rotating speed with optical sensor

Hi Everyone,

I'm attempting to measure the rotating speed of a 1" diameter motor shaft. I only have access to the end of the shaft, so I am attempting to use this sensor, along with a small reflective strip on the end of the shaft to sense the rotating speed. The sensor data sheet says it can detect reflective objects almost half an inch away, but I haven't been having any luck with the sensor. At the moment it seems as though I've entirely fried the sensor actually. I'm relatively new to wiring things up myself, and I thinking it's very possible I hooked the diode up wrong at some point and burnt it out (Would the diode have burnt out this quickly? I definitely exceeded the reverse breakdown voltage, which is only 3 volts. In the future I will be more careful to step my voltage down as well...)

At this point, since it looks like I'll need a new sensor anyways, I though I'd as if anyone had any advice on a different method (hall effect sensor?) or any tips on how to manage to get something like this to work properly.

Thanks,

Graham

There are four different types of output available for that sensor, and depending on which type you have and how you have wired it, you may not detect a signal using an Arduino.

You also must have a current limiting resistor in series with the emitter LED (150 Ohm minimum) or you could burn out the Arduino output pin, the LED or both.

Which exact type of sensor do you have, (totem pole or open collector output) and how, exactly, have you wired it?

Please post a hand drawn diagram, showing all connections, with pin numbers labeled, and post your code, using code tags.

Hi JRemington,

I attached a sketch showing how I plan to hook up the sensor up once I get a new once, since I’ve confirmed that mine is dead (No current flow through the LED). When I originally hooked it up, I did not have the resistor on the LED side of the sensor, but otherwise that is exactly how I had it wired, and how I plan to wire the new one up unless you see any issues.

I have the OPB770, which is the “Buffered Totem-Pole” sensor logic.

The code I eventually want to use for the sensor is to use pulseIn to calculate the frequency in RPM of the rotating shaft:

void setup(){
Serial.begin(9600);
pinMode(5,INPUT)
long n;
}

void loop(){
n=60000000/pulseIn(5,HIGH);
Serial.println(n);
}

But for the time being, I’m just trying to get it to read, so I was using this code to let me know whenever I get a high signal and how often I get the high signal:

void setup(){
Serial.begin(9600);
pinMode(5,INPUT);
}
void loop(){
if (digitalRead(5)==HIGH){
Serial.println("HIGH");
Serial.Println(millis());
}
}

On a side note, I’m not sure if I need to specify pin 5 with INPUT_PULLUP, or if INPUT is fine. I tried it once with the pullup setting and I got a constant high voltage on the output signal, which is the opposite of what I though that setting was suppose to do.

Thanks for you help, and thanks in advance for any additional help you or anyone else can give me,

Graham

The buffered totem pole output is the best choice, and the circuit diagram looks fine. You do not need INPUT_PULLUP with a totem pole output.

This:

n=60000000/pulseIn(5,HIGH);

should be written as:

n=60000000UL/pulseIn(5,HIGH);

to make it clear that you are using unsigned long integer division.

However, that expression probably won't give you the correct RPM value. You should time one or more complete revolutions of the shaft, rather than passage of part of a reflective strip. In other words, measure the time between two successive rising or falling edges from the sensor (for one revolution of the shaft).

You also don't need microsecond resolution. The built in millis() timer usually fine for RPM measurements.

I use code similar to the following for RPM measurements, in the particular case that the Arduino has nothing else to do but make that measurement (blocking code):

while(digitalRead(sensor_pin)==LOW); //wait till high
unsigned long start = millis();
while(digitalRead(sensor_pin)==HIGH); //wait until low
while(digitalRead(sensor_pin)==LOW); //wait till high again
unsigned long rotation_period=millis()-start;
unsigned int rpm = 60000UL/rotation_period; //calculate RPM.