The default encoder code from Kevin is great for seeing the interrupts
work. I would run that code (unmodified) on a test system and look at
the way it responds to interrupts generated by hand using a switch.
The default encoder code will print out the counts for the enabled interrupts
on a regular interval.
We wired up a bunch of switches and put them on digital I/O 1-6 to see
how they worked.
What digital I/O pins do you have the GTS wired to?
Your printf seems to say that the switch is on rc_dig_in06 and
you are expecting encoder_1_count to increment. That will not work.
You should not be trying to print from the interrupt handler. Printing takes
way too long to be done in the interrupt context.
We also used a switch to simulate the GTS input when we were developing
code on a test bed, so you should be able to get it to work.
You need to remember that all the interrupts are on the digital I/O pins 1-6.
encoder_1_count in Kevin’s code refers to the count of interrupts on pin 1.
I encourage you to use digital I/O 1 and 2 for your GTS. For reasons why,
search the forum for posts on the difference between edge triggered and
level triggered interrupts.
I had the encoder to rc_dig_in06 aswell. I defined it in encoder.h. Where should I print from? Because it’s printing, just it’s only printing 0, not counting like it should.
And how do you see how the interrupts trigger on the test code if you don’t have printfs? My code is not really modified, I just removed Encoder_3-6 because I wont be using them. I kept Encoder_1 and_2 and have them to rc_dig_in06 and 07. I defined it properly in encoder.h, but maybe I’ll swithc them back to rc_dig_in01 and 02.
Thanks! Anything else I’m missing?
Two big problems. First, the Encoder_1_Int_Handler() interrupt service routine will only be triggered by a transition on digital input 1. Move your gear tooth sensor to rc_dig_in_01. There’s no interrupt connection to rc_dig_in06.
Second, you won’t be incrementing the counter unless the code manages to execute quickly enough to read the value of the pin before it goes back high. Take out the if statement. The interrupt will occur only once per pulse of the input signal.
There’s a small problem as well – using printf() inside an interrupt routine is risky, as it can be a time-consuming function.
Oh man, this just doesn’t seem to want to work! I’ve been working on it since friday! Ummm, ok I changed some things, now I’m getting a code error. (the red light of doom). I don’t know what to do! I guess I’ll start from scratch again! We need more programmers on my team! lol
EDIT: Ok, no more red light of death, but sitll not working, would it help if I posted my code?
It would help if you posted your code, and it would help even more if you clarified exactly what “not working” means. What are you expecting it to do, and what is it doing instead?
Looking at your code, I see a couple of small issues with a printf(). The encoder counts are defined as long, and you’re not casting them to an int when printing their value. That could give unexpected results, as the %d format specifier expects a regular integer and might show you just the high two bytes of the value (which will be zero until you’ve counted a lot of teeth).
Also, if you’re trying to read the value of the counter outside the interrupt service routine, you should not be accessing the variable directly. Instead, use the function provided to do it. That way you won’t find your code being interrupted and changing the value in the middle of reading it, leaving you with an inconsistent result.
I want the GTS to count everytime it senses a tooth. So it can count rotations of the wheels (say 90 teeth per rev). As of now, when I print the value, it stays at 0. That is what I mean by not working.
I uploaded a new version of encoder.c, it still doesn’t count however. I made all the changes you suggested.
Your software looks like it should work. Do you trust your hardware?
Is the gear tooth sensor mounted as specified, in the correct orientation and at the correct distance from a ferrous gear? Does the board have 12v power on the proper pin? Does it have 5v and ground? Have you looked at the output with an oscilloscope to verify that it’s providing pulses?
My current setup is using a push switch to simulate the gear tooth sensor. I have it hooked up to rc_dig_in11. I have it printing to screen, and when pushed it shows up as 0, otherwise as 1, so looks like the hardware is working. I’m not sure what to do. The counter is still not counting, it just stays at 0. Thanks again for all the help, it is very much appreciated :)!
You misunderstood the part of the code that deals with configuring quadrature encoders.
Phase A of encoder 1 has always been documented as rc_dig_in_01, and phase A of encoder 2 has always been documented as rc_dig_in_02. The “B” phases for a quadrature encoder can be connected to any other digital inputs, but there is no phase B on a gear tooth sensor, which is why that part of the interrupt code is simply removed to handle a GTS.
Digital input 1 on the RC goes to one hardware interrupt on the PIC. Digital input 2 on the RC goes to another hardware interrupt. Changes on digital inputs 3-6 can be configured to cause a third hardware interrupt. If you want to use interrupts, you must use the input pins that support interrupts. (Now why am I suddenly having deja vu?)
Well, I guess you learn something new everyday (or maybe sometimes it takes a couple of days to understand it) but anyways, this is my first year programming anything, and I was in charge or programming the robot. I had alot on my plate I guess so I’m sorry if some of my questions seemed stupid. I really appreciate all the help, our team didn’t have any mentors who knew programming, so I’m really glad I could find an e-mentor! Thanks again, now I just have to finish the rest of the autonomous before Rochester!