Infrared Speed Measurement

DogWatch:
My QRE1113 is an analog type

Please post a link to the datasheet for the exact device you have.

I used my QRE1113 devices as digital devices with the Sparkfun "analog" wiring diagram. How close is your senor to the rotating part - it should be about 1 mm IIIRC.

...R

Hello all,

first, thanks to all of you for the quick and detailed help. Today I was able to check the function of the QRE1113 and the interrupt-logic using the code-guidance from Robin2. I used a mill with speed rated up to 24.000 rpm. I used the Sparkfunk QRE1113 breakout on a black (matt) painted mill tool (50% of the shaft was painted the other 50% was unpainted steel). Using the adapted interrupt code from Ronin2 (Thanks!) I was able to measure the shaft speed right away up to 23.000 rpm. Awesome!
I finally connected the QRE1113 (analog version) output to the digital pin 2 (INT0). Important is to use black matt paint in order have a good High/Low signal at the QRE1113 output. The distance between sensor and shaft should be between 1 to 2mm. The QRE1113 doc is talking about 3mm distance for best performance which ist not the case obviously.
Anyway, I'm happy to have a good and simple way to measure the rotational speed in my project.
Thank you all very much.

Regards,
Joerg

//##################################### HEADER #############################################################
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width,  in pixels
#define SCREEN_HEIGHT 32                                         // OLED display height, in pixels


// declare an SSD1306 display object connected to I2C
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

//int QRE1113_Pin = A0;
const byte interruptPin = 2;                                 // QRE1113 output connected to use "INTERRUPT.0"

unsigned long revMicros;
unsigned long prevRevMicros;
unsigned long revDuration;                                   // calculated duration between two IR pulses by turning shaft
//unsigned long revCount;                                    // to count number of revolutions
double shaftSpeed;

// variables for the ISR (Interrupt Service Routine)
volatile unsigned long isrMicros;
volatile unsigned long isrCount;
volatile bool newIsrMicros = false;


int waitTime = 200;
unsigned long previousTime;


//##################################### SETUP ##############################################################
void setup() {

  Serial.begin(115200);
  pinMode(interruptPin, INPUT_PULLUP);
  //pinMode(A0, INPUT);
  
  // define interrupt to dectect rising singnal when black (no reflexion) detected by IR sensor
  isrCount = 0;
  attachInterrupt(digitalPinToInterrupt(interruptPin), revDetectorISR, RISING);
  

  // initialize OLED display with address 0x3C for 128x64
  if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    while (true);
  }
  oled.display();                                            // start screen on oled
  delay(1000);

  oled.clearDisplay();
  oled.setTextSize(3);
  oled.setTextColor(WHITE);
  oled.setCursor(20, 8);
  oled.println(F("READY"));
  oled.display();
  
  delay(1000);
  previousTime = millis();
}


//##################################### LOOP ###############################################################
void loop() {
  getIsrData();
  if(millis() - previousTime > waitTime) {
    previousTime = millis();
    shaftSpeed = 1 / (float)revDuration * 60000000.0;       // shaft speed converted from microsecond per turn to rpm
    if (shaftSpeed < 1000000.0 && shaftSpeed > 100.0) {     // no data to oled screen outside speed limits
      writeToOLED(String(shaftSpeed,0));
    }else{
      writeToOLED("0");
    }
    //showDataToMonitor();
  }
}


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


// called within interrupt handler (see setup())
void revDetectorISR() {
    isrMicros = micros();
    //isrCount ++;
    newIsrMicros = true;

}


void writeToOLED(String val) {
  oled.clearDisplay();                                        // clear display

  oled.setTextSize(3.5);
  oled.setTextColor(SSD1306_WHITE);
  oled.setCursor(20, 0);
  oled.println(val);
  
  oled.setTextSize(1);
  //oled.setTextColor(SSD1306_WHITE);
  oled.setCursor(100, 25);
  oled.print(F("rpm"));
  oled.display();
}

/*
void showDataToMonitor() {
    Serial.println("===============");
    Serial.print("  Rev Duration ");
    Serial.print(revDuration);
    Serial.print("  ShaftSpeed ");
    Serial.print(String(shaftSpeed,0));
    Serial.println();
}
*/

DogWatch:
Hello all,
guidance from Robin2.
Anyway, I'm happy to have a good and simple way to measure the rotational speed in my project.
Thank you all very much.

Regards,
Joerg

Nice You got up and running. Have You seen the Karma word below Robins title, in the replies from Robin2 and used it?

Railroader:

DogWatch:
Nice You got up and running. Have You seen the Karma word below Robins title, in the replies from Robin2 and used it?

now I have, thanks,

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.