  | 
	  | 
		 
	 
	
		| View previous topic :: View next topic   | 
	 
	
	
		| Author | 
		Message | 
	 
	
		
			ze.vana
 
 
  Joined: 11 Jun 2011 Posts: 15
  
			
			 
			 
			 
			
			
			
			
			
			
  
		  | 
		
			
				| Rotary Encoder final | 
			 
			
				 Posted: Sun Sep 04, 2011 8:14 am     | 
				     | 
			 
			
				
  | 
			 
			
				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
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Feb 09, 2012 7:43 am     | 
				     | 
			 
			
				
  | 
			 
			
				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
  
			
			 
			 
			 
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Feb 09, 2012 3:00 pm     | 
				     | 
			 
			
				
  | 
			 
			
				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();
 
 }
 
} | 	 
  | 
			 
		  | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
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
  
		 |