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

Rotary Encoder final

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
ze.vana



Joined: 11 Jun 2011
Posts: 15

View user's profile Send private message Send e-mail

Rotary Encoder final
PostPosted: Sun Sep 04, 2011 8:14 am     Reply with quote

Here in my Country there are not dsPIC or PICs with QEI MODULATE ,then I decided to do
that project. This is ROTARY ENCODER'S final version with 32 bits, he measures counterclockwise
and anti-counterclockwise rotations. I've tested it with industrial TTL encoders (Heidenhein and Sick
2500 pulse/revolution , both from Germany) used in CNC machines, and I can guarantee, it makes
measurements super fast, without losing position.
First project:
http://www.ccsinfo.com/forum/viewtopic.php?. I’ve copied the flex_lcd from this Forum, I hope the author does not mind, this Forum has helped me a lot, thanks all you guys!
Email ze.vana@hotmail.com

Code:

#include <18F4520.h>         
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=40M)
#use  RS232(baud=9600, parity=N, bits=8,xmit=pin_c6, rcv=pin_c7)
#include <flex_lcd.c>
#define tog1 (pin_d6)
#define led (pin_d0)//#define led (pin_d7)em casa é o d0
//#define DIR_1 (pin_d0)
//#define ZERO_2 input(pin_C3)//REFERENC input
#define DIR_2 (pin_d1)
#define ZERO input(pin_d2)
#define MENOS input(pin_d3)

  int1 referen=0;
  char signal;
 
  int16 tmr0;
  int16 tmr0xn=0;
  int32 result0=0,real;
  #bit pir0=0x0ff2.2 //timer0 overflow

  int16 tmr1;
  int16 tmr1xn=0;
  int32 result1=0;
  #bit pir1=0x0f9e.0 //timer1 overflow
 
  int1 stopped;
  int8 zerado = 0;
  int16 tmr1H,tmr1L,tmr0H,tmr0L;//see line 129
  int32 MAX=0,MIN=200,MEDIA,differen;//see line 122
 
#INT_TIMER2
void intt2_isr()
  {
  set_timer2(0);
  tmr1=GET_TIMER1();   //get counter UP value
  tmr0=GET_TIMER0();  //get counter DOWN value 
 // differen= result1 - real;

 if(pir1==1)
{
tmr1xn++;
pir1=0;
   }
if(pir0==1)
   {
tmr0xn++;
pir0=0;
   }
 //--auto zero--------------------------             //positive
if(differen > 200000 && stopped==1 && zerado != 1 && signal== 43 && real < 65000)//zerar 1
   { //see line 131
  result1= media;
  set_timer1(media);
  set_timer0(0);
  tmr0xn=0;
  tmr1xn=0;
  zerado=1;
   }                                                 //positive
if(differen > 200000 && stopped==1 && zerado != 2 && signal== 43 && real < 65000)//zerar 2
   { //see line 150
  result1= media;
  set_timer1(media);
  set_timer0(0);
  tmr0xn=0;
  tmr1xn=0;
  zerado=2;
  }
 //----auto zero--end--------------------
/*
if(referen==0 && zero_2==1)
{
  result1= 0;
  set_timer1(0);
  set_timer0(0);
  tmr0xn=0;
  tmr1xn=0;
  referen=1;
   }
 */
  }
#INT_TIMER3
  void ext3_isr()
  {
  SET_TIMER3(0);
min=max;
if(real < min)
  {
  min= real;
  }
if(real > max )
  {
  MAX =real;
  }
if(max  > min )
  {
  media = min;
  }
else
  {
  media= max;
  }
 }
void main(){
  set_tris_a(0xff);
  set_tris_b(0xff);
  set_tris_c(0xff);
  SET_TRIS_D(0x00);
  output_d(0x00);
 //TIMER0 16 bits as counter /DOWN
  SETUP_TIMER_0(RTCC_EXT_H_TO_L|RTCC_DIV_1);
      SET_TIMER0(0);
      DISABLE_INTERRUPTS ( GLOBAL );
  // TIMER1 16 bits as counter /UP
  SETUP_TIMER_1(T1_EXTERNAL | T1_DIV_BY_1 );
      ext_int_edge(H_TO_L);
      set_timer1(0);
 //TIMER2 INTERNAL
  SETUP_TIMER_2( T2_DIV_BY_1,0xc0,2);
      set_timer2(0);
      enable_interrupts(int_timer2);
      enable_interrupts(global);
 //TIMER3 INTERNAL
  SETUP_TIMER_3(T3_INTERNAL |T3_DIV_BY_4); // TIMER3 INTERNAL
     SET_TIMER3(1000);
     enable_interrupts(INT_TIMER3 );
     enable_interrupts(global);
  lcd_init();//It must be here or else you got instability.
   stopped=1;
   tmr1L=0; tmr1H=100;tmr0L=0;tmr0H=100;
 while(true)
  {
  tmr1L=GET_TIMER1();  //get timer0/1 initial value
  tmr0L=GET_TIMER0(); //see line 150
  differen= result1 + result0;//value to zero encoder
  result0=(65536 * tmr0xn) + tmr0;//gets 32 bits timer0/1
  result1=(65536 * tmr1xn) + tmr1;
 if(result1 >= result0)
    {
 real= result1 -result0;// get plus real value
    signal='+';
    }
 else
   {
 real= result0 -result1;// get minus real value
   signal='-';
   }
  printf(LCD_PUTC"\f\%c%Lu %Lu\n",signal,real,differen );
  printf(LCD_PUTC "\n1:%Lu 0:%Lu",result1,result0 );     
  //printf("\f r:%lu t1:%lutmr1xn:%lu", result0 ,tmr0,tmr0xn);tests
 //printf("\f %u",signal );
 delay_ms(100);

 tmr1H=GET_TIMER1();  // get timer0/1 final  value
 tmr0H=GET_TIMER0(); //see line 119
 
 if(tmr1H == tmr1L && tmr0H == tmr0L)// if all equal, encoder is stopped
    {                               //see line 129
delay_ms(700);
 stopped=1;//flag
 output_high led;
    }
else
    {
stopped=0;
output_low led;
    }
  }
 }
quadro



Joined: 09 Feb 2012
Posts: 4

View user's profile Send private message

PostPosted: Thu Feb 09, 2012 7:43 am     Reply with quote

Thanks for very useful code.
I'm working on position and speed reading, but I'm using 18f4431.
18f4431 has some disadvantages (program memory low, price high...).
I have a lot of 18f46k20. Your code is a big advantage for me. Thanks.
ze.vana



Joined: 11 Jun 2011
Posts: 15

View user's profile Send private message Send e-mail

PostPosted: Thu Feb 09, 2012 3:00 pm     Reply with quote

Thanks for appreciating.
Well I have received some questions on how it works, then as my english is not so good. And I think this code could be a little difficult to understand, I am putting the basic code.
The used additional Hardware I can send by email for who want.
BASIC CODE:
Code:

//BASIC CODE
#include <18F4520.h>         //<18F452colt.h> or  coltbootloader
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=40M)

#include <flex_lcd.c>

//encoder--------------------------------------------encoder-----
 int16  T0,T1,R; //float R; //R is the result from T1-T0
//--------------------------
 void print_lcd(void){
   T1= GET_TIMER1(); //get counter UP value
   T0= GET_TIMER0(); //get counter DOWN value
   R= T1-T0;         //R is the result from Timer1-Timer0

   printf(LCD_PUTC"\f\REAL:%Lu \n",R); 
   printf(LCD_PUTC"\nR=T1:%Lu-T0:%Lu",t1,t0 );
   delay_ms(200);

   if(t0 > t1){    //Tmr0 never can be grater than  Tmr1,
   SET_TIMER0(0); //if so reset Timers
   SET_TIMER1(0);
    }
  }

//#int_timer2
void timer_t2()
  {
  set_timer2(250);
 // lcd_init();
 // delay_ms(100);
 // print_lcd();
  }
 
//encoder------------end--------------------------encoder--------
void main (void)
{
 set_tris_a(0xff);
 set_tris_b(0x00);
 set_tris_c(0xff);
 set_tris_d(0xff);

//TIMER0 16 bits as counter /DOWN
SETUP_TIMER_0(RTCC_EXT_H_TO_L|RTCC_DIV_1);
SET_TIMER0(0);
   
// TIMER1 16 bits as counter /UP
 SETUP_TIMER_1(T1_EXTERNAL | T1_DIV_BY_1 );

 set_timer1(0);
  lcd_init();
  delay_ms(500);

  while(true)
  {
 print_lcd();
 }
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library 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