Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Programming (http://www.chiefdelphi.com/forums/forumdisplay.php?f=51)
-   -   Issues with encoder code (http://www.chiefdelphi.com/forums/showthread.php?t=45859)

jgannon 26-03-2006 12:01

Issues with encoder code
 
My team has been using Kevin Watson's encoder code in conjunction with the KOP gear tooth sensors, to great success. Unfortunately, during one of our last matches, the wires got yanked off of the RC, and broke the signal pin on digital IO 1. Fortunately, this is not a huge deal, so we got the broken pin out of the cable, and moved the encoders over to digital IO 3 and 4. Now, when I run the code, encoders 3 and 4 start out at 0. If I spin one side of the drivetrain, the count for that side increases to 1, and no more. I have the same problem if I try IO 5 or 6. I know that the sensors are still working fine, because if I move one back to IO 2, then I get the expected counts. Has anyone else run into trouble with using encoders on 3-6? Any suggestions? I'm hoping we'll be able to have a working autonomous mode again in Atlanta.

The Lucas 26-03-2006 12:12

Re: Issues with encoder code
 
Could you post your InterruptHandlerLow code? As I remember it took a little work to get those "Port B" interrupts working.

jgannon 26-03-2006 12:18

Re: Issues with encoder code
 
Quote:

Originally Posted by The Lucas
Could you post your InterruptHandlerLow code? As I remember it took a little work to get those "Port B" interrupts working.

I'm not sure if it is in violation of Kevin's license agreement to post this, so let me know if it is, and I'll take it down post haste. Anyway, this is what I've got:
Code:

void InterruptHandlerLow ()   
{
        unsigned char Port_B;
        unsigned char Port_B_Delta;

        if (PIR1bits.RC1IF && PIE1bits.RC1IE) // rx1 interrupt?
        {
                #ifdef ENABLE_SERIAL_PORT_ONE_RX
                Rx_1_Int_Handler(); // call the rx1 interrupt handler (in serial_ports.c)
                #endif
        }                             
        else if (PIR3bits.RC2IF && PIE3bits.RC2IE) // rx2 interrupt?
        {
                #ifdef ENABLE_SERIAL_PORT_TWO_RX
                Rx_2_Int_Handler(); // call the rx2 interrupt handler (in serial_ports.c)
                #endif
        }
        else if (PIR1bits.TX1IF && PIE1bits.TX1IE) // tx1 interrupt?
        {
                #ifdef ENABLE_SERIAL_PORT_ONE_TX
                Tx_1_Int_Handler(); // call the tx1 interrupt handler (in serial_ports.c)
                #endif
        }                             
        else if (PIR3bits.TX2IF && PIE3bits.TX2IE) // tx2 interrupt?
        {
                #ifdef ENABLE_SERIAL_PORT_TWO_TX
                Tx_2_Int_Handler(); // call the tx2 interrupt handler (in serial_ports.c)
                #endif
        }
        else if (INTCON3bits.INT2IF && INTCON3bits.INT2IE) // encoder 1 interrupt?
        {
                INTCON3bits.INT2IF = 0; // clear the interrupt flag
                #ifdef ENABLE_ENCODER_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
                Encoder_2_Int_Handler(); // call right encoder interrupt handler (in encoder.c)
                #endif
        }
        else if (INTCONbits.RBIF && INTCONbits.RBIE) // encoder 3-6 interrupt?
        {
                Port_B = PORTB; // remove the "mismatch condition" by reading port b           
                INTCONbits.RBIF = 0; // clear the interrupt flag
                Port_B_Delta = Port_B ^ Old_Port_B; // determine which bits have changed
                Old_Port_B = Port_B; // save a copy of port b for next time around
       
                if(Port_B_Delta & 0x10) // did external interrupt 3 change state?
                {
                        #ifdef ENABLE_ENCODER_3
                        Encoder_3_Int_Handler(Port_B & 0x10 ? 1 : 0); // call the encoder 3 interrupt handler (in encoder.c)
                        #endif
                }
                if(Port_B_Delta & 0x20) // did external interrupt 4 change state?
                {
                        #ifdef ENABLE_ENCODER_4
                        Encoder_4_Int_Handler(Port_B & 0x20 ? 1 : 0); // call the encoder 4 interrupt handler (in encoder.c)
                        #endif
                }
                if(Port_B_Delta & 0x40) // did external interrupt 5 change state?
                {
                        #ifdef ENABLE_ENCODER_5
                        Encoder_5_Int_Handler(Port_B & 0x40 ? 1 : 0); // call the encoder 5 interrupt handler (in encoder.c)
                        #endif
                }
                if(Port_B_Delta & 0x80) // did external interrupt 6 change state?
                {
                        #ifdef ENABLE_ENCODER_6
                        Encoder_6_Int_Handler(Port_B & 0x80 ? 1 : 0); // call the encoder 6 interrupt handler (in encoder.c)
                        #endif
                }
        }


//  ***  IFI Code Starts Here***
//                             
//  unsigned char int_byte;     
//  if (INTCON3bits.INT2IF && INTCON3bits.INT2IE)      /* The INT2 pin is RB2/DIG I/O 1. */
//  {
//    INTCON3bits.INT2IF = 0;
//  }
//  else if (INTCON3bits.INT3IF && INTCON3bits.INT3IE)  /* The INT3 pin is RB3/DIG I/O 2. */
//  {
//    INTCON3bits.INT3IF = 0;
//  }
//  else if (INTCONbits.RBIF && INTCONbits.RBIE)  /* DIG I/O 3-6 (RB4, RB5, RB6, or RB7) changed. */
//  {
//    int_byte = PORTB;          /* You must read or write to PORTB */
//    INTCONbits.RBIF = 0;    /*    and clear the interrupt flag        */
//  }                                        /*    to clear the interrupt condition.  */
//  else
//  {
//    CheckUartInts();    /* For Dynamic Debug Tool or buffered printf features. */
//  }
}


The Lucas 26-03-2006 13:46

Re: Issues with encoder code
 
Here are a couple things (differences with my code) to try :

Try declaring Old_Port_B like this:
Code:

        unsigned char Port_B;
        unsigned char Port_B_Delta;
        static unsigned Old_Port_B = 0xFF;

Try spliting your handler into separate rise and fall handlers like so:
Code:

                if (Port_B & 0x10) Int_3Rise_Handler();
                else Int_3Fall_Handler();

Double check that you set INTCONbits.RBIE in initialization
Those are the only differences between my handler (2 encoders & 3 GTS) and your handler. We changed it last year and I don't remember exactly what fixed what.

jgannon 26-03-2006 13:59

Re: Issues with encoder code
 
Quote:

Originally Posted by The Lucas
Try declaring Old_Port_B like this:
Code:

        unsigned char Port_B;
        unsigned char Port_B_Delta;
        static unsigned Old_Port_B = 0xFF;


Hm... looking at the code, that seems to be a really important thing to do. I'll give it a try in Atlanta, and let you know what happens. Thanks!

Mike 26-03-2006 14:32

Re: Issues with encoder code
 
I also remember that his code is defaultly optimized for velocity readings on ports 1 and 2 and optimized for position control on ports 3 and 4. I might be wrong with the numbers, but different ports are optimized for different purposes. Check if your new ports were optimized for a purpose other than your old ports where.

Kevin Sevcik 26-03-2006 14:53

Re: Issues with encoder code
 
Mike,
It occurs to me that you've hit the nail on the head. 3 and 4 are opitmized for positions, so they're expecting a quadrature encoder. They look for the B channel on another set of pins (can't remember which) and they will only increment properly if the cycle goes A rise, B rise, A fall, B fall. If B stays high or low, then the code thinks the encoder is fiddling back and forth and not actually turning. There should be a way to fix this in the code, but I don't have it in front of me. That's exactly what the problem is, however.

JG,
Check Kevin's readme and code comments. They should tell you how to use those inputs for velocity instead of position.

Kevin Watson 26-03-2006 15:12

Re: Issues with encoder code
 
Quote:

Originally Posted by jgannon
I'm not sure if it is in violation of Kevin's license agreement to post this, so let me know if it is, and I'll take it down post haste.

I guess I should explain why I don't want entire copies of my code available elsewhere on the 'net. Two years ago, I posted some code that was later modified and posted on a team's website (team A). Another team (Team B) used the modified version of the code on their robot, but had problems because the modified code had a bug introduced by team A. Team B e-mailed me and said that my code didn't work for them and asked if could I help find the bug. Well, this was during the 2004 six week build period and I was at work when I got the e-mail. Not seeing how the bug could possibly happen and worried that many teams were having the same problem, I left work early so that I could go home and try to reproduce the bug on a real controller. Well, after a few frustrating hours trying to reproduce the bug, I found out that Team B used Team A's modified code, where the bug was found. The point I'm trying to make is that it's much easier for me (and others here on CD) to help diagnose problems if I know that the team started with a build that I know works on my hardware.

-Kevin


All times are GMT -5. The time now is 17:29.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi