Go to Post Enlighten a man who sometimes has difficulty understanding why others stray outside the box, when the box appears to be an optimized and elegant solution. - JVN [more]
Home
Go Back   Chief Delphi > Other > FIRST Tech Challenge
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
 
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 22-08-2006, 14:19
foobert foobert is offline
Registered User
no team
 
Join Date: May 2005
Location: oakland, ca
Posts: 87
foobert is a jewel in the roughfoobert is a jewel in the roughfoobert is a jewel in the rough
Re: Reading an encoder with interrupts

Quote:
Originally Posted by GlennGraham
Would you mind explaining how the encoder interrupt handler works with the timer2 interrupt handler?
the timer is used to determine the amount of time between encoder interrupts so you can determine the speed at which your bot is progressing.

the timer interrupt occurs when the timer overflows, so that you will know if and how many times that has occurred between encoder interrupts.

can't look at the code right now, but will if i have a minute later.
Reply With Quote
  #2   Spotlight this post!  
Unread 25-08-2006, 12:44
GlennGraham's Avatar
GlennGraham GlennGraham is offline
Registered User
AKA: Glenn Graham
FLL #0006 (Shark Bait!)
Team Role: Coach
 
Join Date: Jan 2006
Rookie Year: 2003
Location: Beaverton, Oregon
Posts: 20
GlennGraham is an unknown quantity at this point
Re: Reading an encoder with interrupts

Thanks, yes, it does look like the timer is used to measure the interval between interrupts.

I made some good progress last night working with the white paper on using timer interrupts as well as the data sheet for the controller. I first got the timer working and then was able to hook up a switch to the #2 interrupt port and react to it. The switch was REALLY noisy so I ended up coding an example that disables the switch interrupt for a short time after it triggers to let it settle by using the timer interrupt. Tonight I will replace the switch with the encoder. I might hook up the scope to see how noisy the transitions from low/high/low are.

In the hopes that this thread might be helpful to someone later doing a search on this subject, here are snippets of my code (use the whitepaper and data sheet mentioned above for context):

Add to User_Initialization() in user_routines.c
Code:
  // Example of how to set up a timer to be handled through interrupt
  T1CON = 0;
  T1CONbits.T1CKPS1 = 0;       // Prescale 11=1:8, 10=1:4, 01=1:2, 00=1:1
  T1CONbits.T1CKPS0 = 0;
  TMR1H = 0x85;                // Pre-load TMR1
  TMR1L = 0xED;                //   - Done to remove time from total to get correct period.
  T1CONbits.TMR1ON = 0;        // Turn timer off
  IPR1bits.TMR1IP = 0;          // Set Timer1 Interrupt to low priority
  PIE1bits.TMR1IE = 1;          // Interrupt when Timer1 overflows
  INTCONbits.GIEL = 1;          // Enable Global Low Priority Interrupts

  // Example of how to set up a peripheral interrupt
  INTCON2bits.INTEDG3 = 0;     // Set INT3/rc_dig_int2/Interrupt port #2 - falling edge triggered
  INTCON2bits.INT3IP = 0;      // set rc_dig_int2 low priority
  INTCON3bits.INT3IF = 0;      // clear int flag for rc_dig_int2
  INTCON3bits.INT3IE = 1;      // Enable rc_dig_int2
In user_routines_fast.c
Code:
/*** DEFINE MY ROUTINES AND VARIABLES ***/
void Handle_Timer1_Interrupt(void);
void Handle_Encoder_Interrupt(void);
unsigned char UpdateDisplay;
unsigned int EncoderTickCount;
Code:
void InterruptHandlerLow ()     
{                               
  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;      // Clear the flag
    Handle_Encoder_Interrupt();
  }
  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 if (PIR1bits.TMR1IF )
  {
    PIR1bits.TMR1IF = 0;        // Clear the Timer1 Interrupt Flag
    Handle_Timer1_Interrupt();
  }
}
Code:
/*
* Interrupt Handlers: Set up the handlers so that if an interrupt occurs on
* the Interrupt #2 port we:
*  1) Disable the interrupt so that noise does not re-trigger it
*  2) Increment the counter
*  3) Turn on timer2 which, when overflow occurs will re-enable interrupt #2 after noise has passed
*
* Works well with a noisy switch connected to interrupt 2. The timer allows the switch to settle
* before re-enabling the interrupt. 
*/

void Handle_Encoder_Interrupt(void)
{
  INTCON3bits.INT3IE = 0;      // Disable encoder interrupt
  EncoderTickCount++;          // Increment counter
  T1CONbits.TMR1ON = 1;        // Start timer to wait until noise settles
  UpdateDisplay = 1;           // Set flag to output current count in
                               // Process_Data_From_Local_IO()
}

void Handle_Timer1_Interrupt(void)
{

    T1CONbits.TMR1ON = 0;            // Stop 10MHz Timer
    TMR1H = 0xBF;                    // Reset Timer. Pick value based on switch characheristics 
    TMR1L = 0xFF;                    // BFFF works, EFFF too short (lets bounces through).
    INTCON3bits.INT3IF = 0;          // Re-clear any pending interrupts that may have occured.
    INTCON3bits.INT3IE = 1;          // Enable encoder interrupt
}
Code:
void Process_Data_From_Local_IO(void)
{
  /* Add code here that you want to be executed every program loop. */
  if (UpdateDisplay) {
    INTCONbits.GIEL = 0;               // Disable low priority interrupts
    UpdateDisplay = 0;
    INTCONbits.GIEL = 1;               // Enable low priority interrupts
    printf("Ticks %d\n",(int)EncoderTickCount);
  }
}
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem with reading and writing EEPROM DKolberg Programming 4 16-03-2004 19:29
Help with pots/interrupts mtrawls Programming 10 24-02-2004 17:01
EDU Demo Code: Encoder Interfacing Using Interrupts Kevin Watson Programming 4 08-01-2004 23:14
help with Interrupts thoughtful Programming 5 08-01-2004 16:07
Problem with interrupts on the PIC Mike Betts Programming 7 16-12-2003 21:26


All times are GMT -5. The time now is 00:59.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


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