Issues with photodiode in tachometer

Hi!

Sorry for the long post - I tried to give as much information as possible. I hope someone can help me.

I have got a quite difficult problem on my hands: I want to build a simple tachometer to measure RPM of motors used in RC cars. The basic priciple I am using for this is an LED shining on a disk with a slit with a photodiode behind it. I have made a basic prototyping setup:

Since time is of the essence here I used the integrated comparator to trigger an interrupt. I followed these write-ups: gammon and tardate.

My code is

#include <Servo.h>
#define ESC_PWM_PIN 3

Servo ESC1;

volatile long lastTime = micros();
volatile long timeTaken;

ISR (ANALOG_COMP_vect) {
  long currentTime = micros();

  if(currentTime - lastTime > 5000) {     //debouncing
    timeTaken = currentTime - lastTime;
    lastTime = currentTime;
  }
}
  
void setup() {
  // put your setup code here, to run once:
  ESC1.attach(ESC_PWM_PIN);
  ESC1.write(70);

    Serial.begin (115200);
  Serial.println ("Started.");
  ADCSRB = 0;           // (Disable) ACME: Analog Comparator Multiplexer Enable
  ACSR =  bit (ACI)     // (Clear) Analog Comparator Interrupt Flag
        | bit (ACIE)    // Analog Comparator Interrupt Enable
        | bit (ACIS1)
        | bit (ACIS0);  // ACIS1, ACIS0: Analog Comparator Interrupt Mode Select (trigger on rising edge)
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println((float)60000000/timeTaken);
  Serial.println(timeTaken);
  delay(50);
}

as you can see I implemented some debouncing since I had more than one interrupt call when rotating the disk per hand over the sensor. I am aware that this limits my RPM read-out to 12.000 rpm but with the motor I am currently using I don’t even come close to that.

The problem I am faced with now is the results I am getting from my setup:

This is with the motor running at the lowest speed so I am expecting a couple of hundreds, maybe 1-2 thousand rpm but certainly not 8.000. Also the output is extremly noisy. Furthermore, I am somehow getting readings of 20.000 rpm which imo should be impossible due the debouncing method I use. I mean when there is a minimum of 5ms between interrupts the max rpm readout I should get is 60.000/5 which is 12.000 right?

But my main problem is that the interrupt fires when it shouldn’t: As part of my trouble shooting I removed the disk witch blocks the light from hitting the sensor and unpluged the LED. I then ran a programm that just prints “Triggered” when the interrupt routine is called and ran a test. Unfortunatelly the interrupt was triggered countless times with nothing there to trigger it. Next I completely seperated the motor from the sensor curicuit by controlling the ESC with a remote control (as was originally intended). Still wrong interrupt calls left and right.

Then I thought that maybe the vibration caused some problems so removed the photo diode from my setup and had it just near-by but STILL no improvement…

I now believe that the magnetic field of the motor might cause some induction charge which triggers the interupt. Is this possible? And if so how do I check for it and how do I prevent it?

ANY help or suggestions are highly appreciated! (=

For some reason the pictures don't load. So here they are as links: First pic

second pic

How about a diagram of the whole circuit? It could prove useful in finding the issue.

Stray light is a problem.

tinman13kup: How about a diagram of the whole circuit? It could prove useful in finding the issue.

Sure thing. But I don't know how to use any software to generate one - I hope a hand drawn one is okay.

jremington: Stray light is a problem.

I thought about that but in the end I had the diode laying on the table with the disc removed from the motor, the LED turned off and I still got interrupts - but only if the motor was running.

The brushes on that motor won't help either. Perhaps a schmitt trigger could be helpful.

Looks like you might swap the resistor and photodiode around. What value potentiometer are you using?

tinman13kup: Looks like you might swap the resistor and photodiode around. What value potentiometer are you using?

but that doesn't make it wrong or does it? I mean I get different voltages from the voltage divider but if I set my compare voltage accordingly I should be fine. The potentionmeter has a range from 0 to ~11k.

I did some further testing and pretty much confirmed that the magnetic field of the motor is the ause of all my trouble. If I remove my setup ~50cm from the motor I get no interrupts - nada but when I move it closer (~10cm) I get loads of them. Any idea what I can do about that?

tinman13kup: The brushes on that motor won't help either. Perhaps a schmitt trigger could be helpful.

Would a schmitt trigger help if my problems are in fact due to induced current from the magnetic field of the motor?

A schmitt trigger is used to clean up dirty signals, turning them into a clean digital signal through hysteresis. The output would go to a digital pin and be counted.

It's not a end-all for EMI, but would help. De-coupling on power supplies, wire management, and power supply isolation also help, along with filters.

Is that an old motor that the brushes spark a lot? Any idea how many poles it has?

If you're using a brushed motor they will generate a large amount of noise.

Try a capacitor ( 100nF?) across the motor , with perhaps some series inductors as well (10uH?) to suppress the racket.

Allan

It also wouldn't hurt to route the opto wiring as far as possible from the commutator of the motor. If it's feasible, place the light source and receiver beside each other and mount a mirror, on the motor side of the disc, in front of the pair that's only visible when the slot passes by. This will move the wiring even further away from the motor. Avoid putting sensor wires and motor wires close to each other and parallel.

xmit            rcv
   \             /
    \           /
     \         /
-------------------- disc
       \     / 
        \   /
         \ /
        ==========  mirror

tinman13kup: Is that an old motor that the brushes spark a lot? Any idea how many poles it has?

It is a couple of years old - 3 to 4 years I would say. And yes it sparks a fair bit. It is 7,2V 35 turn DC motor. I am not sure what you mean with 'how many poles'.

allanhurst: If you're using a brushed motor they will generate a large amount of noise.

I will try a brushless motor and see if it makes a difference.

dougp: It also wouldn't hurt to route the opto wiring as far as possible from the commutator of the motor. If it's feasible, place the light source and receiver beside each other and mount a mirror, on the motor side of the disc, in front of the pair that's only visible when the slot passes by. This will move the wiring even further away from the motor. Avoid putting sensor wires and motor wires close to each other and parallel.

That is a great idea but since the LED is on its own power supply atm and the photo diode is on the far side of the disk I doubt that it would improve things.

I will have to order some things to try your suggestions such as capacitors and the parts for the schmitt trigger.

MarkGoingToSpace: I now believe that the magnetic field of the motor might cause some induction charge which triggers the interupt. Is this possible? And if so how do I check for it and how do I prevent it?

This is highly likely - especially with a high current brushed motor.

You need suppression across the motor terminals - 10nF to 100nF ceramic capacitor right on the terminals, shortest leads you can make them.

Then shielding all your sensor cables to reduce pick-up is good.

Never run sensor cabling alongside motor wires, that's guaranteed to inject a lot of noise.

And lastly you require low-pass filter and schmitt-trigger conditioning on the photo diode signal to reduce the effect of induced and coupled short spikes.