I have been looking for ways to offload counting encoder clicks from the microprocessor to another chip so that i can get as high a click rate as i want (8,000+) There are thosands of dedicated counting ICs that cost only a few dollars and could easily handle the rate i want to use, but controlling them looks to be a problem when i want to have 4 encoders. I have only begun to look, but from what i have seen, counters designed for encoders have a relatively complicated scheme just for reading the counter, more than i’d like to implement in software and wire. Does your team use a counter or some other sort of electronics to reduce the number of interrupts on the RC from encoders or other sensors?
Last year we used an up/down counter (actually 2 8 bit counters cascaded into a 16 bit counter) plus a 16 bit parallel in/serial out latch to get the data in and out to an auxilary CPU then I sent the data via RS232 into the user CPU. It was pretty straight forward electronics 101 type project.
With this year’s CPU we totally did away with the counter, etc. If you really want to keep them, I think I would drive the latch & serial in and out directly from the user CPU without the auxilary CPU.
BUT… …I really question whether you need this at all. There are a lot of lackings in the CPU we are using but it DOES have some pretty useful features as well.
On very useful feature is that you can dynamically set the number of edges between interrupts. With this system you can basically keep your interrupt load constant over time. When the encoders are going slow, you can simply get interrupted every rising edge, then inc or dec your counter by 1 (based on the state of your other quadrature channel). If the time between interrupts is too short, you can then set the next interrupt to happen every 2 rising edges (you have to then inc or dec your counter by 2 each interrupt). Now you check the time between interrupts and see if you need to increase or decrease your scaling for the next interrupt. It is pretty straight forward. I think you can get a scale of up to 16 edges between interrupts. With this scaling and the speed of the CPU we have, I suppose you can handle the 4 encoders you want to handle at the speeds you want.
Do whatever you like, but as I jokingly say to the CS guys around here, “Software is free!”
Joe J.
P.S. Of course I know that software is NOT free, but it is a fairly famous idea round here that management often treats it as if it is.
There are some combined quadrature encoder interpreter/counter’s with a 24 bit counter. If i was going to use 4, i’d have to use the same 8 digital i/o pins for all of them and then i think use an additional 4 pins to run them independtly. There are some that come with a rs232 adapter, but im not sure if i can get 4 to run through one, easily.
I do in fact need the resolution that i was saying. It is maximum rate of input that actually matters, not just having a high rate throughout the whole range of motor speeds.
You are right, if you do the scheme I discussed you end up losing resolution at the higher RPM’s. This is typically not an issue when you are using the encoders for wheel position (it is rare that a robot needs to know to the 1/8 of an inch where it is when it is going 10 feet per second.), but for other applications, you can sometimes need constant resolution, even at high speeds (cranks shaft position for spark timing for example).
If you are in this case, additional circuitry is often a good solution.
I think that you can use the up/down timer scheme from our robot last year with 64 bit parallel in/serial out latch (made from 8 8-bit shift resisters). This would let you read all the counters at one time with only 1 “shift in” command. You can buy pretty fast shift registers that would allow you to scream the data into the user CPU on the RC.
This would only take 2 or (at most) 3 pins on your RC (depending on if you want your counters to be able to be zeroed or not – you can get by without zeroing them with a little software)
I think using the RS-232 solution would be a significant bother and complexity that you do not have to go through. The interface would be a cinch with the shift register & up/down counter solution.
Joe J.
I thought that there was probably hardware that could send the data through very few pins without much trouble, but i have no idea where to even get started. There are dozens of types of counters and thousands of models. If you have some resources you could point me to to get started, that would be good. Software, whitepapers, anything.
Btw, you were at the NJ regional, right? I think me and a few of my team members talked to you while at the practice field.
I know that most PIC processors have internal counters that can count transistions on input pins - I dont know if they are available on the one in the RC - if so it would be much easier to use than an external device - and the counters dont need interrupts for each count - only when they have reached their terminal count.
if they are present on the PIC chip, they can count at 1/4 the clock frequency - what is the clock in the RC? is it 20 or 40 MHz? (I forget)
counting at 8kHz would be a breeze for the PIC
terminal count? Is this in reference to using an external counter? I know i don’t need an interrupt for one, i was talking about using the RC to do the encoder counting. If a terminal count is the last one before counter overflow, than i dont think that’s a problem either because i was planning on using a 24 bit counter and i highly doubt the robot will drive that far before reset…
I’m almost sure that the RC doesnt have any sort of built in counter that would allow up/down counting.
It is 40 mhz but from what i have heard, 10k counts is pushing it. I also will be having a user code loop that will be pretty significant, im not solely doing counting.
10kHz is pushing it if each count causes an interrupt - if the internal counters are on an I/O pin then it can count at 10Mhz with a 40MHz clock on the uP
terminal count is when you preload the counter everytime it overflows - so with an 8 bit counter you can have it overflow everytime it counts to 1, or to 256 and everything in between, depending on what you set it up to preload with.
I just spent some time looking at data sheet on the 18fxx20 chip that the RC uses. There are 5 counters that i think i can use (as long as their inputs are in fact one of the digital inputs, i think im gonna need to ask IFI about this) there are 3 that can be used as 16 bit and 2 that can only go up to 8 bit. Because i don’t see anyway of counting down, the only option is two have two counter’s per wheel and use an encoder enterpreter chip that can output two streams, one for up clicks and one for down clicks. This means that at best, i can have one encoder on two 16 bit counters, one on two 8 bit counters, and the other two on interrupts. I think this maybe pointless anyway because the interrupt digital I/O pins and the counter pins are most likely the same (again, i have to ask IFI).
I want to say right away that I am not a EE (though I sometimes play one on TV ;-).
If you want specific chips, I have found the following from Digi-key. I believe they will work, but it is possible you may need an inverter here or a NOR gate there to get things to work exactly as you want.
As to the 8 bit up/down counter:
SN74ALS867ADW
http://focus.ti.com/lit/ds/sdas115c/sdas115c.pdf
As to an 8 bit parallel load shift register:
74F676
http://www.fairchildsemi.com/ds/74/74F676.pdf
You can have the clock for the counter be driven by one channel of the encoder, the other channel of the encoder is tied to the up/dn pin of the counter.
The CPU drives the “parallel load” mode of the shift register and then shift in the bits to the its input pins.
You can daisy chain the 676’s to have the data look like one long register.
You can also cascade the counters if you need to have more counts than an 8 bit number can hold.
Alternatively, you can also reset the counters after you read them so that you can just accumulate the total count inside your CPU. You run the risk potential of missing a count when you reset the counters if you are not careful, but depending on your application, this may or may not be a big deal. With some clever circuitry and/or software you can avoid this problem but this is more than I want to get into here.
I don’t know if this helps, but it should be a good start.
Joe J.
P.S. I have used the 676 before so I can vouch for it with first hand knowledge. However, I have not used the 867 before – I have always had some other 4 bit counters hanging around the office that I could cascaded into whatever size counter I needed. From what you are talking about, I suppose you will need more than 8 bits perhaps 16 bits. This gets tedious with 4 bit counters so I suggested an 8 bit version. Looking at the data sheets though I am pretty sure that it will work out for your application – perhaps others have favorites they are used to using that they can vouch for from personal experience.
Digital inputs 1 through 6 are already tied to the low priority interrupt handler in the default IFI code. Transitions from 0 to 1 are detected. This is actually how we’re doing our encoding – we just detect beam breaks. At every break, the interrupt triggers and increments a counter.
Everyone seems to love talking about quadrature encoders, but in this particular type of application where you usually have some gear reduction between the motors and the wheels, it just seems silly. If I’m driving the motors forward and the wheels are moving backwards despite the gearing connecting the motors to the wheels, I have a BIG PROBLEM. Thus, just use one bit for encoding and keep track of what direction you’re driving your motor to tell you which direction you’re going in.
And because I gazed ahead and noticed a question about terminal count… When the external counter reaches the highest number it can count to, it will have to raise a flag indicating it has reached it’s “terminal count.” This can be done internally in the PIC to keep track of time. If counters external raise a terminal count every, for example, 1024 ticks, then the PIC will be able to increment a counter internally indicating that the counter has moved another 1024 ticks.
Ted has a good point - if you end up hitting something, or another bot is pushing you backwards, you wheels will either be slipping (spinning) or turning backwards or both
but either way, you are already lost - so you might as well assume you are going in the direction you set your motors to. once your wheels slip your position based on wheel turns is useless.
and if you are using wheel rotation to close the loop on motor speed, buy the time your wheels end up being pushed backwards your PID loop would have them at full power forwards anyway
Well, and what I was trying to also say was that depending on your robot’s gearing, it’s probably very difficult to push the robots backwards any significant amount, ESPECIALLY if their motors are driving. I’d be more willing to believe wheels slip or spin rather than run backwards. When a motor wants to drive forwards and you drive it backwards instead, it’s not good for the motor nor the source of power to the motor.
Well, even if your position is useless, the rate of change is still useful. In fact, sometimes the thing to do when your wheels slip is to reduce your speed until you start catching on carpet again. Sometimes having some feedback control controlling your speed is a good way to do that.
And again, motors in full power forward while wheels are going backwards is no good for anyone. “back EMF” becomes “forward EMF”… or something.
So, yeah, to reiterate, I don’t think quadrature encoders really provide much advantage. Get your ticks, fudge your direction, and you’ll do just as good as any.
Now, if you have other mechanisms besides drive train that might be driven backwards (perhaps you’re using something as input that is fairly free to rotate… etc.) then the quadrature makes a lot of sense. But for drive train for most of these robots, it’s probably not all that helpful.
The drive train should be just barely traction limited so slipping will be rare. There are many cases where the drive trains will backdrive in my application, often the motors will not be on and the wheels will spin, it is not always that they will be spinning in the opposite direction. I defenitley do need a direction sensor. Regardless, it isn’t too hard at all to check direction with the quadrature encoders, every counter i have looked at has the capability to, and it probably doesnt add too much time to my interrupt code to do a single if on a digital i/o pin. One possible solution might be to use current sensors to see if the motors are being backdriven, but if im going to be counting encoder clicks, i might as well count them up and down.
So basically, the parrallel outputs of the counter are connected to the parrallel inputs of the shift register. The shift register is put permanantly into parallel load mode (Mode is high) Then, to read the shift register, the CPU has a digital IO pin connected to the CP (clock pulse) pin which it pulses, then checks serial output, and repeats to get all 8/16 bits of the counter? I’m not sure if the proper way to do this is to actually have a common clock or something like that, but this seems to be correct, too.
I wrote up some code to do what i think you’re saying:
char encVel()
{
char encVel;
for(int i = 1; i<9; i++)
{
/*set clock to shift register high*/
shiftClkA = 1;
/*read the current bit of the shift register encVel*/
encVel |= serialInput<<i
/*set clock back*/
shiftClkA=0;
}
/*reset counter*/
counterResetA = 1;
counterResetA = 0;
return encVel;
}