CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

18f4685 encoder problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Lemosek



Joined: 15 Oct 2011
Posts: 36

View user's profile Send private message

18f4685 encoder problem
PostPosted: Wed Feb 15, 2012 8:32 am     Reply with quote

Hello,
I found on this forum code from Mr. Ttelmah to read encoder position.
I try using this, but I have some problems.
My code:
Code:

//*****************************************************
//obsługa enkodera
//
//*****************************************************
#int_ext
void int_rb_isr(void) {
   static int8 old;
   static int8 new;
   static int8 value;

   new=PORTB; //You don't need a separate function for this....
   //Assuming the encoder is on B1, and B2
   //Now I have to decode the quadrature changes. There are four   
   //possibilities:
   //I can have a rising or falling edge, on each of the two inputs. I have to
   //look at the state of the other bit, and increment/decrement according to
   //this.
   value=new^old;
   //'value', now has the bit set, which has changed
   if (value & 0x2) {
      //Here the low bit has changed
      if (new & 0x2) {
         //Here a rising edge on A
         if (new & 0x4) --position;
         else ++position;
      }
      else {
         //Here a falling edge on A
         if (new & 0x4) ++position;
         else --position;
      }
   }
   else {
      //Here the high bit (B) must have changed
      if (new & 0x4) {
         //Here a rising edge on B
         if (new & 0x2) ++position;
         else --position;
      }
      else {
         //Here a falling edge on B
         if (new & 0x2) --position;
         else ++position;
      }
   }
   old=new;
}

main
{
clear_interrupt(INT_RB);
clear_interrupt(INT_EXT);
enable_interrupts(INT_EXT);
enable_interrupts(INT_EXT1);
enable_interrupts(GLOBAL);

while(1)
  {
  printf(lcd_putc, "%u", position);
  }

}

My problem is when I turn left I have for example 10 9 10 11. Other side is 11 12 11 10.
Why does this happen ??

My compiler version 4.120

Encoder is connected to RB0 and RB1 pins.

Best regards
R.L.
Ttelmah



Joined: 11 Mar 2010
Posts: 19329

View user's profile Send private message

PostPosted: Wed Feb 15, 2012 10:53 am     Reply with quote

That is not the code I posted, but something 'bodged' from it.
My code uses INT_RB only. As posted the code will only respond to changes on one bit and miss two of the four states.
You also have INT_EXT1 enabled without a handler, which will cause indeterminate behaviour.
What chip are you using (affects what pins can be used).

Best Wishes
Lemosek



Joined: 15 Oct 2011
Posts: 36

View user's profile Send private message

PostPosted: Wed Feb 15, 2012 11:02 am     Reply with quote

Hello,
My chip is 18f4685. Maybe my code is wrong.
So how this code I must use. I use RB0(INT0) and RB1(INT1) pins.
I use INT_EXT because this chip don't have INT_RB1 and INT_RB0.

Best regards
R.L.
temtronic



Joined: 01 Jul 2010
Posts: 9162
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Feb 15, 2012 12:47 pm     Reply with quote

Get familiar to using the 'search' function on this forum. You'll soon find a zillion answers to encoder. It's up to you to decide which best suits your project.
If your PIC has INT_RB, it's a simple matter to get 2 encoders to work with the B7...4 pins.
you could also look at the examples in the examples folder......
Lemosek



Joined: 15 Oct 2011
Posts: 36

View user's profile Send private message

PostPosted: Wed Feb 15, 2012 1:13 pm     Reply with quote

Hello, In example folder, example don't use the interrupt. I can't change pcb to connect encoder to RB7..4. I need to use INT0(RB0) and INT1(RB1).
Can someone help me ??

Best regards
R.L.
Lemosek



Joined: 15 Oct 2011
Posts: 36

View user's profile Send private message

PostPosted: Thu Feb 16, 2012 4:20 am     Reply with quote

Hello, I solve My problem code below
Code:

#int_ext high
void int_rb_isr(void) {
   static int8 old;
   static int8 new;
   static int8 value;

   new=PORTB;   
   value=new^old;
   //'value', now has the bit set, which has changed
   if (value & 0x1) {
      //Here the low bit has changed
      if (new & 0x1) {
         //Here a rising edge on A
         if (new & 0x2) position--;
         else position++;
      }
      else {
         //Here a falling edge on A
         if (new & 0x2) position++;
         else position--;
      }
   }
   else {
      //Here the high bit (B) must have changed
      if (new & 0x2) {
         //Here a rising edge on B
         if (new & 0x1) position++;
         else position--;
      }
      else {
         //Here a falling edge on B
         if (new & 0x1) position--;
         else position++;
      }
   }
   old=new;

   clear_interrupt(INT_EXT);

}


main
{

clear_interrupt(INT_EXT);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);

while(1)
  {
  printf(lcd_putc, "%u", position);
  }

}

 


I don't known why I must add clear_interrupt at interrupt subroutine ??

Best regards
R.L.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group