Infrared Speed Measurement

Hello,

I would like to add a simple speed measurement to my milling machine. I hope to be able to use a Atmel328P-PU but I'm not sure.
Parameters:

  • speed to be measured: 5000 - 25000rpm
  • two events per turn to be captured for the speed measurement
    Questions:
  • do I need an IR sensor which can receive continuous signals or is IR sensor receiving burst signal only ok?
    (e.g. TSOP4038 for continuous signals, TSOP4838 receiving burst signals)
  • what is special wit a burst signal?
  • is the Atmel328P-PU sufficient for measuring 25000rpm with two events per turn?
  • Can I use "pulseIn()" to read the pulses if the sensor activated using the time to calculate the speed for two pulses?

Thanks a lot!

Where would you sense the rotation on your machine? Is it susceptible to flying debris? Is the motor geared up to produce the final speed? How is your motor powered and is the current to the motor directly proportional to the rotation speed, so you could measure the current?
Paul

The built in sensor on my mill uses a Hall sensor and magnets attached to the top of the spindle.
I guess that ready moduls are available.

If you do the math, 25000rpm with two events per revolution means those "events" will be 1.2 msec apart. Very easily done on an Atmel328P. I would not go down the route of pulseIn() since it blocks for the entire pulse. Much better to attach your input signal to an interrupt and then track elapsed microseconds between pulses and do a little math.

DogWatch:

  • do I need an IR sensor which can receive continuous signals or is IR sensor receiving burst signal only ok?
    (e.g. TSOP4038 for continuous signals, TSOP4838 receiving burst signals)

Neither.

All you need is an IR LED and a photo transistor to detect a beam-break or a reflection.

If you have something to cause a beam break you could uses a slotted optical sensor like this

And if you want to detect using a reflective sensor (for example detect a black spot on a white surface) you can use a reflective optical sensor. I have used the QRE1113 with a small DC motor but you may prefer something a bit larger.

...R

Why not use a reflexive one?

Railroader:
Why not use a reflexive one?

I suggested both types.

...R

Yes, You did. My mistake.

These encoder modules are available as an add on.

Thank you all very much for the help!
I will check the QRE1113 breakout sensing directly on the turning shaft. The shaft will get coated black with an reflexive (white) stripe for sensing the rotation.
I will let you know in case I succeed or failure...

DogWatch:
Thank you all very much for the help!
I will check the QRE1113 breakout sensing directly on the turning shaft. The shaft will get coated black with an reflexive (white) stripe for sensing the rotation.
I will let you know in case I succeed or failure...

Be sure to test the "black" to be sure it is not reflective with IR.
Paul

DogWatch:
The shaft will get coated black with an reflexive (white) stripe for sensing the rotation.

Use matte paints for both white and black.

Sparkfun make a QRE1113 module but, while small, the QRE1113 is not difficult for hand soldering. Sparkfun also has a circuit diagram which I have used for digital detection (even though they refer to it as analog).

...R

I bought the Sparkfun breakout and it seems to work good.
As mentioned the color is very important to detect surface changes. It must be mate.
blh64 said something about using interrupt instead of "pulseIn()". Why is that? I have no idea about using interrupts to measure the time between two pulses.

This program is derived from the code I used to control the speed of my DC motor.

const byte fwdPin = 9;
const byte revPin = 10;
const byte potPin = A1;

int potVal;
int pwmVal;

unsigned long revMicros;
unsigned long prevRevMicros;
unsigned long revDuration;
unsigned long revCount;

unsigned long prevDisplayMillis;
unsigned long  displayInterval = 1000;

    // variables for the ISR
volatile unsigned long isrMicros;
volatile unsigned long isrCount;
volatile bool newIsrMicros = false;



void setup() {
    Serial.begin(115200);
    Serial.println("SimpleISRdemo.ino");
    pinMode (fwdPin, OUTPUT);
    pinMode (revPin, OUTPUT);

    isrCount = 0;
    attachInterrupt(0, revDetectorISR, RISING);
}

//==========

void loop() {
    getIsrData();
    if (millis() - prevDisplayMillis >= displayInterval) {
        prevDisplayMillis += displayInterval;
        showData();
        readPot();
        updateMotorSpeed();
    }
}

//===========

 void readPot() {
    potVal = analogRead(potPin);
}

//===========

void updateMotorSpeed() {
    pwmVal = potVal >> 2;

    digitalWrite(revPin,LOW);
    analogWrite(fwdPin, pwmVal);
 }

//===========

void getIsrData() {
    if (newIsrMicros == true) {
        prevRevMicros = revMicros; // save the previous value
        noInterrupts();
            revMicros = isrMicros;
            revCount = isrCount;
            newIsrMicros = false;
        interrupts();
        revDuration = revMicros - prevRevMicros;
    }
}

//===========

void showData() {
    Serial.println();
    Serial.println("===============");
    Serial.print("PWM Val "); Serial.println(pwmVal);
    Serial.print("  Rev Duration ");
    Serial.print(revDuration);
    Serial.print("  Rev Count ");
    Serial.print(revCount);
    Serial.println();
}

//===========

void revDetectorISR() {
    isrMicros = micros();
    isrCount ++;
    newIsrMicros = true;

}

...R

@Robin2: awesome, thanks!
I will try to use your snippet to get wise on Interrupts…

Mhm, is something attached to the interrupt pin 0 means do I need to attach the QRE1113 output to that digital pin2?
Am I right that the interrupt pin 0 is the digital pin 2 on a Atmega328P?.
Is the function “revDetectorISR” called on rising edge of the signal at pin 2 and how does it work together with “getIsrData()” called in every new loop?

DogWatch:
Am I right that the interrupt pin 0 is the digital pin 2 on a Atmega328P?.

No. You attach the same pin number to ISR as the electrical pin.

You may be confused about interrupt pins vs. interrupt numbers. The solution is to use the function digitalPinToInterrupt() as explained in the Arduino documentation on interrupts.

Example

    attachInterrupt(digitalPinToInterrupt(2), revDetectorISR, RISING);

to attach an interrupt to Arduino I/O pin 2.

DogWatch:
Am I right that the interrupt pin 0 is the digital pin 2 on a Atmega328P?.

Yes. But strictly it is interrupt 0 that works on digital pin 2 (not "interrupt pin 0")

Reply #16 is a bit confused.

The style recommended in Reply #17 is the best way.

...R

Robin2:
Yes. But strictly it is interrupt 0 that works on digital pin 2 (not "interrupt pin 0")

Got it, later I found the new recommended style in the arduino docs.
But could you give me another hint to my further question. Is the sensor output with raising/falling signal connecte with pin 2 (interrupt 0!)? My QRE1113 is an analog type. I manage to get a digital type High/Low signal using a analog input port for the sensor output. Can I use the digital pin 2 with the QRE1113 sensor output as well?