I'm trying to implement PID controller to my first robot car. To do so I've installed 2 lm393 optical speed sensor to read the rpm and consequently the speed of the wheels.
The problem is that the value that I read is the double of correct value. After checking the code I've tried to move manually one disk lot and it return a value of 2 instead of 1. It's like in the interrupt I use CHANGE instead of RISING. The last attempt was to copy a guy's code on Youtube and in my case it return the double of his value of rpm.
Now I'm suspecting the problem is in my sensor:
even if when i try to block the light with a simple paper seem to work well.
Someone else had the same problem???
This is my code:
Thank u Mark for your reply.
I tried declaring pinMode as INPUT_PULLUP but nothing.
As i wrote, the strange thing is that even copying another sketch only to verify the comparator returns a double value.
I read of a guy somewhere on internet that has the same problem. He solved by using a small capacitor but there weren't much details.
The board in your link, if it's what I think it is, uses a H 2010 photo-transistor in conjunction with a LM 393 comparator IC. It should be counting pulses from a slotted wheel or whatever you have. When powered with 5.0 volts the LM 393 reference level is set at about 2.5 volts and it gets triggered by the photo-transistor. The output of the LM 393 is open collector but a 10K pull up should be on your board. The board should have a LED power on and a LED for pulses out. Blocking the slot of the sensor should trigger the latter LED.
If you want to try a quick and simple diagnostic try the following simple tachometer code sample:
int encoder_pin = 2; // pulse output from the module
unsigned int rpm; // rpm reading
volatile byte pulses; // number of pulses
unsigned long timeold;
// number of pulses per revolution
// based on your encoder disc
unsigned int pulsesperturn = 12;
void counter()
{
//Update count
pulses++;
}
void setup()
{
Serial.begin(9600);
pinMode(encoder_pin, INPUT);
//Interrupt 0 is digital pin 2
//Triggers on Falling Edge (change from HIGH to LOW)
attachInterrupt(0, counter, FALLING);
// Initialize
pulses = 0;
rpm = 0;
timeold = 0;
}
void loop()
{
if (millis() - timeold >= 1000) {
//Don't process interrupts during calculations
detachInterrupt(0);
rpm = (60 * 1000 / pulsesperturn )/ (millis() - timeold)* pulses;
timeold = millis();
pulses = 0;
Serial.print("RPM = ");
Serial.println(rpm,DEC);
//Restart the interrupt processing
attachInterrupt(0, counter, FALLING);
}
}
In this sample modify the number 12 to fit your pulses per turn or revolution. Running that code right now and applying a 1.0 KHz symmetrical square wave to pin 2 I am seeing 1200 RPM. If you are seeing double the correct speed it leads me to believe based on pulses per revolution something is wrong in the code.
Ron I dont't have an oscilloscope but i used your piece of code and it however returns the double of correct value.
I also tried the RC filter of Mark the values changed a little, but are still incorrect.
Somehow this thing is triggering twice as much as it should. Two different codes and the same symptom. I mean you could just /2 in your code but that really does not address the actual problem. What are you using? Slotted wheel or similar? Maybe it is seeing a glint off of it. Just plain strange. The schematics of the board itself pretty much show the LM393 comparator has a two 10K resistor divider for the Vref making Vref 2.5 volts. I have seen a few versions with a pot allowing the user to set sensitivity. I don't know what to suggest as a solution.
I suspect the comparator simply doesn't have nearly enough hysteresis for this use - I'd expect at least 10 to 20% hysteresis is needed for an optical sensor to deal with noise and reflection artifacts, and even 50% is reasonable.
Its a cheap sensor, maybe they've not even considered this?
Hysteresis? The circuit of these modules looks just like this but uses a slightly different photo transistor. The LM 393 reference is set using a pair of 10K resistors in series. So powered with 5 volts Vref is about 2.5 volts. The slightly improved module uses a pot so the user can set sensitivity, not that it matters much.
Probably the easiest thing is to simply divide by 2 in the code making sure that it's good for all range of speed.
The strange thing is that manually using a paper to block the light stream it works well.
Probably when connected to motor shaft the frequency is too high and cause problems.
But however sounds so strange.