I was curious how frequently the encoders can be sampled, so I wrote some test code and found that I can’t sample much faster than 10Hz for just 1 encoder and not doing anything else. Does this surprise anyone? Is there a discussion of the microcontroller timing, or do I need to get these metrics by running my own tests?
I will assume that you are using C (not easyC or some other obfuscation)
In order to sample an encoder at high resolution you need to use interrupts. You may also configure (if supported by the encoder) a quadrature input to effectively double the resolution of the encoder.
By using an interrupt driven scheme, anytime the encoder changes, this information is stored to a register (or to a count variable, etc) so that when you poll this, you can find out exactly how much encoder movement has occurred.
Unlike CJO, I presume that you are using EasyC and that you are trying to poll the encoder count (the count of interrupts) that EasyC stores for you. I am interested in hearing what you learn.
My forays into using the encoders and unltrasonics have been infrequent; but they have also been filled with questions like yours (how many of each sensor type can be used at once, how long does it take to run the start, read and stop routines, how long is my user code put to sleep each time the master code runs, how can I tell if my desired polling time coincided with a period when the master runs (every 18.5 mSec (I think)) and is consequently delayed, etc.).
I am currently using easyC, since my rookie team may find it easier to stick with it for a while. I have not found the source code for default routines, so I can only guess as to what they do.
What I am trying to figure out now is if there is any documentation that describes the master code and the timing contraints of the default routines. E.g., can I force the encoders to update at 1000Hz? What if I connect a gyro to an input, can I choose the rate the data is sampled? These kind of questions need to be answered if closed-loop control is employed on the processor.
I cannot quickly find the link on this forum, but I remember reading that the user code runs about every 17.5milliseconds. A more effective trick would be to increment an integer value every time your code runs. Then make a real small printf statement to send this value to the terminal window. Time (with a clock or watch) the counter for 180 seconds (3 minutes). If the count at the end of 100 seconds is 10,286 bigger than when you started, the code cycle time is about once every 17.5milliseconds. If the count is closer to 10,000 then the code cycle time is 18milliseconds.
Basically, take the total count increase over 180 seconds, divide by 180 to get counts per second and then take the inverse of it (1/x) to get seconds per count. (Say the count is 9,735 in 3 minutes. 9,735/180 = 54.083. 1/54.083 = 0.01849 which is pretty close to 18.5milliseconds per program cycle.
I am very sure that the code you write (user code) is executed according to a master processor. The amount of code you write will not slow down how often the code is executed.
The maximum rate at which any sensor can change and still provide usable information for your user code is 1/2 (half) the rate at which the user code executes. If you find the code runs every 18.5milliseconds, then your sensor input must change slower than 2*18.5milli or 37milliseconds (the inverse of which is 27 Hz).
Limit switches are usually pretty slow inputs so user code is fast enough. An optical sensor has 90 slots per revolutions. At 27Hz maximum, the shaft could not turn faster than 27/90 or 0.3 revolutions per second. Or, 60*0.3 is 18 revolutions per minute (rpm). That is pretty darn slow. (The old vinyl LP records spun at 33 1/3 rpms.) Spinning the optical shaft any faster will require using interrupt ports and interrupt routines.
Check out the ChiefDelphi forums for a lot of discussion about how the Master Code operates.
I would also provide a warning about printf . . . it is slow, really slow. If you must log data, write it into an array in memory and then copy the array over to EEPROM or printf once your main code has run. Running printf in every iteration will change your results significantly.
I haven’t actually tried it in EasyC. I haven’t noticed it in MPLAB but to be honest - I haven’t looked that closely.
My other, super simple approach - which I will be doing when I make the official game clock (out of VEX) for a local competition - is to simply toggle a digital output between 1 and 0 and feed the output into a frequency counter. I will set the counter up to count pulses and I will stop the counter in 1,000 seconds and do the math by hand.
One could also use an oscilloscope to check the period of the toggling pulse too. I don’t know how much equipment some of the readers might have.
I will take special note of the printf statement timing to see how much of an effect it has on the user routine cycle time.