I am working on a project in which I am controlling large size BLDC motors (very cheap infact manufacturer has no datasheet and model name) controlled by a motor controller. For feedback to PID I am using optical encoders (increment type) giving the number of ticks as input and provided a set point and calculating PID for every 10ms by updating the variable. But the Output observed was very much weird, So when I have observed in the serial monitor the number of ticks the encoder gives I found that many numbers in between are missing because of this input given for every 10 ms some times the input goes as (For ex: 3,5,9 even 14 sometimes observed in the serial plotter).
This input is calculated as current_ticks - previous ticks; PID is done using arduino PID library.
Details:
The screenshots for left and right encoder reading have been attached. The attachment with less ticks missing is right and the left shows very much weird count( like has to produce 225 ticks it shows 600 because of wrong counts displayed).
My optical encoder schematic is also attached below.
Regarding the code and board, I am using arduino Mega 2560, and what the code does is just prints the tick count and uses an interrupt on pin2. The repeated value in the serial monitor is just because the loop prints only the tick counts. (sorry for bad english)
Have you written a test program just to detect the encoder pulses? If so, please post it.
Post a link to the datasheet for the encoder you are using.
A photo of the encoder in situ would probably also be useful.
I have a project in which I am using a QRE1113 optical detector to detect the speed and count the revs of a small DC motor. It seems similar electrically to your diagram. It seems to me that the QRE1113 works reliably with an Atmega 328 or an Attiny 1634 on a breadboard but not when connected to my Uno. I have not tried in on my Mega. I wonder (from the depths of ignorance) if there might be extra capacitance or inductance on the Uno board which affects the small signal from the encoder.
Thanks robin for your kind reply( even I didn't provide sufficient information).
I have solved my problem. I expect there was some debounce in the encoder as i don't have access to a scope i couldn't observe the misbehaviour. But however i have suspected that, and I put a schmidt trigger from the encoder output, for the schmidt trigger i added a de-coupling capacitor and added a pull-up resistor of 330k on the encoder output pin. Form the schmidt trigger output I connected it to arduino mega and read that in the serial monitor the output was impressive. No value was missing.
If any of the members feels that there was something wrong or i got the right answer by chance, please let me know I don't to face this error again once i proceed to some other part.
A 330k pullup is way too high, 1k-10k were a more practical resistance with open collector outputs.
Signal recovery at the receiver side indicates a poor overall design. The signal should be formed properly at the sensor side. The contrast between bright and dark segments must be high enough to form a rectangle on the output. Then this information has to be transferred by reliable means, which are sufficiently insensitive to interference. This includes the choice of the right cables and line drivers, where twisted pair cables and sufficiently low pullup resistors should be sufficient for short distances, or differential line drivers and receivers with long lines.
Similarly power lines have to be routed in a way that minimizes crosstalk to sensor lines. A breadboard with Schmitt triggers on it introduces chances for additional interference, such trouble makers should be eliminated in the first place.
I know very very little about electronics and the sort of things that @DrDiettrich mentions in Reply #9.
My QRE1113 device is wired the same as the SparkFun analog breakout board (I don't have space for a breakout board) and the interrupt pin on my Atmega 328 and Attiny1634 uses pinMode(INPUT_PULLUP). However I have not checked whether the attachInterrupt() function might negate the PULLUP.
Anyway, it seems to work very reliably recording the value of micros() for every revolution. But, as I said before it did not work reliably on my Uno.