Gear encoder code

How do you program the gear tooth encoder? The PDFthat discusses the electrical hookup (power mainly and pin descriptions) of these modules is very in-specific about programming. Which port do you hook the encoders up to, and how do you get the uP to process data from them?


I would recommend that you download and look at Kevin Watson’s code.

I looked there! It is for the wrong encoder!!! The code there is for an optical sensor that looks like a potentiometer(there are pictures), and the one that first gives out (the one I have) uses a field effect transistor to sense the teeth on the gears.

Oh. I always thought he has GTS code on his website. You might want to PM him and see, I think I remember him posting a GTS beta once. Maybe not. Do you have experience using interupts?

You can use Kevin Watson’s encoder code for the GTS, just remove the Phase B stuff. It’s also a pretty simple to write your own code for the GTS, but it is easier to just modify Kevin’s.

Perhaps you should be asking for the theory so you can write your own code and learn more. But Since I am a nice guy who has some time on his hands I will spoon feed it to you.

Basically what you want to do with the GTS is either sense your speed or your relative movement.

Go look at the data sheet for the robot controller and see which pin is the external interrupt, you will hook the signal pin of the GTS to that. Now what happens with the GTS is any time the gear tooth comes within range of the GTS the magnetic field changes and the sensors lets you read that change as a binary 1 or 0. ( I don’t know all the specifics, I have never actually used one). The interrupt pin of the robot controller when triggered litterally interrupts the code to enter into a interupt service routine. Inside the interrupt service routine you need to have as little code as possible so not to bog down your processor. When I code something like this all I put in the ISR (interupt service routine) is an increment statement. Then in the main loop I put the code to manipulate the incremented variable. By manipulate I mean measure time between increments, # of increments, distance calculations, etc. This is the exact same process I use for an encoder. The 2 are basically the same when it comes to programming.

Just tell me if I left anything out.


**Thanks teams. Now, I looked at the code and “phase b” is all over the place in “encoder.c” (And maybe elsewhere). What do I comment out? I have a feeling that just taking out all lines that have “phase b” anywhere in them is going to give me syntax errors that I haven’t even heard of!


PS just for curiosity sake, how would you go about programming your own encoder code? How do you get the uP to recognize the signals coming from the GTS when plugged into the Digital Input?

Most encoders I know like the vex encoder plug into an interrupt port or are like the new magnetic absolute encoders we just got and plug into an analog input and act like a continuous spin pot

A lot of this will probably sound like what anon96464947 said, but here goes. Basically you can envision the GTS as a little switch that triggers when it is ‘hit’ by a gear/sprocket tooth. Now, on the software side you have to be able to detect this ‘hit’ and count them. Unfortunately, so many teeth ‘hit’ the GTS per second that you can’t just check for a 1 or a 0 on their port in the normal program loop. Here is where interrupts come in.

Whenever a certain type of event occurs (encoder ticks, serial port data, and timer overflows are some common ones) something called an Interrupt Flag is set. The controller then stops whatever its doing and goes to call the ISR (Interrupt Service Routine) associated with that flag. (ISRs are called from the InterruptHandlerLow() function in user_routines_fast.c in the default code) In the ISR, you do whatever you need to do with that data, (in this case increment a counter) however, the ISR should be very short and fast executing, otherwise the controller will spend all its time servicing interrupts. The interrupt flag is then cleared, and the controller resumes its usual programming.

So, on to the actual issue at hand. To write your own code, you first have to decide which digital IOs you want to use. IOs 1-6 all can interrupt, but 1 & 2 are easiest to use. So what you’d do first is enable the interrupts in the User_Initialization() function. For exactly what that entails, look at Kevin Watson’s initialization code for encoders 1&2. Then you’d write your ISR, lets say these are functions called something like GTS_1_ISR() and GTS_2_ISR(). In these functions, you increment a very large variable. Then you’d call them in the appropriate place in InterruptHandlerLow. In this case the appropriate places are where it checks for the “INTCON3bits.INT2IF && INTCON3bits.INT2IE” flags for digital IO 1 and “INTCON3bits.INT3IF && INTCON3bits.INT3IE” for digital IO 2. Check to make sure the interrupt flag is reset somewhere (either in your ISR or in InterruptHandlerLow()). Then it is time to use the counter.

To access the count, you should probably so something like Kevin Watson does and disable the interrupt before you read the count. (Check out his code for how to do this)

Now, for the easy solution, modifying Levin Watson’s encoder code. Go to the ISR for encoders 1 & 2 (Encoder_1_Int_Handler, and Encoder_2_Int_Handler, respectively), and replace the if statement with Encoder_X_Count++; where X is the number of the encoder.