Log in

View Full Version : Encoders not changing...


paulcd2000
03-02-2007, 18:12
i implemented the encoder file from Kevin's site... but it doesn't work. I plugged it in to what it said, and i update it with:

LeftWheelCount = Get_Encoder_1_Count();
RightWheelCount = Get_Encoder_2_Count();
what could my problem be?

Joohoo
03-02-2007, 20:32
what other code is being implemented are you using the camera?...GTS?...timers?...other sensors?

make sure the encoder outputs are plugged into the correct inputs.

make sure you are using the right type of encoder, I believe that kevin watson has his code set up for a quadrature encoder.

also make sure that you call all the right functions in the right places ie. encoder_counter() in Interrupt_Vector_low(), encoder1_init() in user_init().

another problem that happened to me was overlapping interrupts. If you do a "find in project" for a bit in the register to see if they are used anywhere else, you may eliminate this problem.

bear24rw
04-02-2007, 00:03
Did you follow the steps in the readme that came with the encode code.. such as adding the initialization call?

paulcd2000
04-02-2007, 10:33
i did follow the steps in the initialization. i am also using the camera. I'll check the encoder type. Where do i find what kind they are exactly? I do call Initialize_encoders() in initialization, and i call interupt handler low from Default routine.

Alan Anderson
04-02-2007, 11:56
...i call interupt handler low from Default routine.

Don't do that.

The interrupt handler is "called" by a hardware feature of the processor. You don't have to do anything more than define it as the interrupt handler.

paulcd2000
04-02-2007, 12:02
k thanks... still haven't gotten a chance to test again

EDIT: nope, still doesn't work...

Manoel
04-02-2007, 16:01
How do you know the encoders are not changing? Are you simply trying to print your xxxxWheelCount variables to a terminal and noticed they don't change?
If so, then that's likely the only problem and your encoders are just fine. Your variables are probably declared long int and, as such, you need to typecast them before printing. Try the following:


printf("Left encoder = %d", (int)LeftWheelCount\r\n);


and see if it works. Sometimes the simple things really get on your way!

paulcd2000
05-02-2007, 17:01
actually, they're not longs. they're ints. a long can hold up to 2147483648, which is about a mile. i just used ints. they're printed using
printf("Left Encoder: %d\t Right Encoder: %d\r", LeftWheelCnt, RightWheelCnt);

But it's a good point. i'll try printing the values directly from the method...

paulcd2000
05-02-2007, 19:16
did anyone have to change their encoder code to get it working? what did you do? cuz ours still isn't working

Alan Anderson
05-02-2007, 20:45
did anyone have to change their encoder code to get it working? what did you do?

I tossed a USB flash drive containing Kevin Watson's frc_encoder.zip file to the lead student programmer and told him to follow the directions in encoder_readme.txt. He did the nine required steps and compiled it. I added a tiny bit of code in Process_Data_From_Local_IO() to turn the raw encoder counts into odometer and heading information, and put a printf statement in Process_Data_From_Master_uP() to verify the proper operation of the encoders.

That's it. It was painless.

paulcd2000
05-02-2007, 21:26
does the type of encoder affect the code? where did you guys get your encoders?

Alan Anderson
05-02-2007, 21:44
The code is designed to work with any encoder having a quadrature output. That means there are two signals, each producing a square wave signal as the shaft turns, but the A and B signals are a quarter-cycle out of phase with each other.

We're using US Digital's E4P encoders. http://www.usdigital.com/products/e4p/index.shtml
I believe we bought them from Newark Electronics, but I'm not the one who purchased them, and I'm not certain.

paulcd2000
05-02-2007, 22:04
would the number of clicks per revolution make it more or less likely to work? because ours runs at 128 clicks per revolution, and some are concerned that that's too fast for the RC to detect

Jared Russell
05-02-2007, 22:44
Make sure the encoders are wired right. You can leave the power pins plugged in and look at the signal wires with an oscilloscope or multimeter. If they change as you rotate the wheel, the problem is in the program. If not, there's an electrical problem.

paulcd2000
05-02-2007, 22:50
k thanks, we'll try that

Alan Anderson
05-02-2007, 23:30
...ours runs at 128 clicks per revolution, and some are concerned that that's too fast for the RC to detect

How many revolutions per second?

We've chosen 256 counts per revolution of the drive wheel. Moving at high speed will give a couple thousand interrupts per second. Our 2005 robot didn't seem to have a problem keeping up with that kind of rate.

radicalnerd
06-02-2007, 01:21
There might be a problem with storing a long to an int without typecasting... Kevin's Get_Encoder_n_Count() functions return a long. If you want to store them as ints you should typecast them:
LeftWheelCount = (int)Get_Encoder_1_Count();
RightWheelCount = (int)Get_Encoder_2_Count();

Otherwise you might get only the most significant bits of the long, which make the int variables 0. In other words, it's counting, but you're not printing them correctly. We had a similar problem with printf displaying longs without typecasting:

printf("Left encoder count = %d", Get_Encoder_1_Count() ); //incorrect
printf("Left encoder count = %d", (int)Get_Encoder_1_Count() ); //correct
I believe the first one tripped us up because it only printed the highest 16 bits of the long, making it appear like it's not counting.

This might be something you already know, in which case I'm sorry I can't help. But if you have a problem with encoders generating too many counts, BaneBots has an encoder divider board (http://www.banebots.com/p/EN-A0001-KT) that we're using this year. They have jumpers to select divide by factor: 1, 4, 8, or 16. We have one 128/revolution encoder coupled 2:1 to each CIM motor shaft (that's ~5000 counts/sec at no load speed), divided by 4 so we don't overwhelm the processor with counts.

Jared Russell
06-02-2007, 13:35
You can also try leaving things as longs and printing using "%ld" instead of "%d"

paulcd2000
06-02-2007, 18:38
i'm not sure which motors we're using but i think they're the chalupas. i'll try typecasting the method's returns as ints. I use ints because i get paranoid about the amount of space the robot really has...:)

Thanks to everyone for all of their help! It hasn't yet been fixed, but i have great confidence it will be, thanks to this huge outpouring of help!

Uberbots
07-02-2007, 00:19
Dont be paranoid... unless you are doing some crazy coding then you should be fine.

either way, the proper replacement macro in printf for a long is %li

Jared Russell
07-02-2007, 00:22
%ld works just fine too ;)

http://www.cplusplus.com/reference/clibrary/cstdio/printf.html

Astronouth7303
07-02-2007, 16:57
Are you sure the RC is reading the sensors correctly?

What I did to test our GTS's last year was put the last 4 PWMs in User_CCP mode (digital outputs should work equally well) and have the interrupt handler toggle that. I then hooked an oscilloscope to both the GTS and the CCP pin. The wave forms matched nearly perfectly.

In terms of software, the GTS and encoders should be very similar, ignoring direction. Even just putting an LED on the output pin and watching its apparent brightness should be helpful. (You probably won't see flickering, as it goes too fast.)

If that works, you may need to post your code so that we can look at it.

paulcd2000
08-02-2007, 17:10
i've got one last test to determine if the problem is programming or electrical/mechanical at the root. In interrupt handler low:

else if (INTCON3bits.INT2IF && INTCON3bits.INT2IE) // encoder 1 interrupt?
{
INTCON3bits.INT2IF = 0; // clear the interrupt flag
#ifdef ENABLE_ENCODER_1
--> puts("1");
Encoder_1_Int_Handler(); // call the left encoder interrupt handler (in encoder.c)
#endif
}
else if (INTCON3bits.INT3IF && INTCON3bits.INT3IE) // encoder 2 interrupt?
{
INTCON3bits.INT3IF = 0; // clear the interrupt flag
#ifdef ENABLE_ENCODER_2
--> puts("2");
Encoder_2_Int_Handler(); // call right encoder interrupt handler (in encoder.c)
#endif
}

The "puts" will output to my screen every time the interupt is called. if it never gets called, then the problem in electrical/mechanical in origin. Does anyone see a problem with my logic? (I'll test it friday at 3:00)

paulcd2000
10-02-2007, 12:52
I finally fixed it!!!! yES!! But i have no idea why it didn't work. Oh well... Thank you, everyone, for your help!

JHale
15-02-2007, 18:50
I finally fixed it!!!! yES!! But i have no idea why it didn't work. Oh well... Thank you, everyone, for your help!

Any chance in sharing what you did (I know the post is late). We are having problems with the code as well, and have ruled out the possibility of a problem with the encoders with an oscilloscope.

paulcd2000
15-02-2007, 21:47
Sure. Well i got sick of trying stuff, so i tested the encoders stuff from kevin's stuff. It worked! So i did every step from the installation, and all of a sudden it worked. The testing steps we took were to check to see if the voltage was changing when the motors turn. If it does, check to see if the interrupt fires. If it does, check the interrupt handling routine. If that checks out, then either it's the print statements or i'm stumped :D

paulcd2000
17-02-2007, 21:29
NEW PROBLEM: i now have one good encoder. The other one doesn't count. I've looked at the code, and everything is executed the same as the one that does work. Have yet to test the electrical portion, but my guess is that this is a brand new problem. Anyone have this or know how to fix it?

benhulett
18-02-2007, 00:09
When you say it doesn't work, do you mean it get's stuck on a certain value? Or does it just stay at 0 while you turn it...

In Kevin's encoder_readme.txt, Step 4 states the following:

4) Disable encoders not needed for your design by following
the instructions in encoder.h. By default, all six encoders
are enabled.

Did you disable the rest of the encoders? Make sure you have the two your using enabled.

Are you using correct Digital I/O ports? (2 and 12 I think for the second encoder)

Other than that, I'm not sure why both won't work.....we had 2 working at one point by just following the readme.

paulcd2000
18-02-2007, 08:34
yeah, i have disabled 4-6, but 2 is still active. Today when i get in, i'll check whether they're all plugged in right, and whether they even return a signal. I suspect they do, but i can't be sure.