Prev: Need C source for 64 bit integer math (have 32bit limit on my compiler)
Next: 24 Bit, dual channelADC, SPI Slave, 85 DegC (or more)
From: vibz86 on 24 Sep 2009 09:56 Hi folks, Im having great trouble in pic programming and hope someone can help me.Im designing a motor controller circuit using pic 16f877a. Iv got a single ended quadrature encoder (It has 5 outputs - a channel, b channel, z channel, 5v, ground). Iv finished the coding for the motor controller part in mikroc. NowI dont know how to do the programming for this encoder. Have to get the feedback(Pulses) from this encoder compare it with the expected pulses and make adjestments. Can someone show me a sample coding for this in mikroc. Iv googled this for last several days and read so many articles but I still couldnt do the coding. This is the coding in mikroc iv written so far. This works. If possible can someone integrate the encoder components in this void m1(int forward) { if(forward) { PORTC.F4=1; PORTC.F5=0; } else { PORTC.F4=0; PORTC.F5=1; } } void m2(int forward) { if(forward) { PORTC.F6=1; PORTC.F7=0; } else { PORTC.F6=0; PORTC.F7=1; } } void setup_timer0() //for encoder 1 { //should be called after configuring the ports(coresponding tris) TRISA.F4=1; //encoder signal input bit OPTION_REG=0x80; OPTION_REG.T0CS=1; //timer0 counter mode } void setup_timer1() { TRISC.F0=1;//encorder signal input bit T1CON=0;//configure prescale of timer1 T1CON.TMR1CS=1;//To set RC0 as input source for timer1 T1CON.T1OSCEN=0;//internal oscillator disabled T1CON.T1SYNC=1;//disable synchronization T1CON.TMR1ON=1;//start timer1 } void main() { PORTC=0; TRISC=0; setup_timer0(); setup_timer1(); PWM1_INIT(5000);//Both pwm generators share one pulse width value. So one //initializing is enough PWM1_change_duty(80); pwm2_change_duty(200); pwm1_start(); pwm2_start(); m1(1); //m1 forward m2(0); //m2 backward while(1) { delay_ms(1000); PORTB=TMR0; //Encorder1 value PORTD=TMR1L; //Encorder2 value } } --------------------------------------- This message was sent using the comp.arch.embedded web interface on http://www.EmbeddedRelated.com
From: Tim Wescott on 24 Sep 2009 10:35 On Thu, 24 Sep 2009 08:56:26 -0500, vibz86 wrote: > Hi folks, > Im having great trouble in pic programming and hope someone can help > me.Im designing a motor controller circuit using pic 16f877a. Iv got a > single ended quadrature encoder (It has 5 outputs - a channel, b > channel, z channel, 5v, ground). Iv finished the coding for the motor > controller part in mikroc. NowI dont know how to do the programming for > this encoder. Have to get the feedback(Pulses) from this encoder compare > it with the expected pulses and make adjestments. Can someone show me a > sample coding for this in mikroc. Iv googled this for last several days > and read so many articles but I still couldnt do the coding. > > This is the coding in mikroc iv written so far. This works. If possible > can someone integrate the encoder components in this I can _help_ you, but if you want me to do your work you may contact me professionally and I'll charge for it. An encoder produces a 2-bit gray code that counts up or down depending on the direction of the encoder. The algorithm that has always worked best for me is to take that gray code, translate it into 2 bits of straight binary, then have a nice wide position register that follows those two bits. To translate into straight binary you just need to xor the least significant bit by the most significant bit (just arbitrarily choose whether A or B is most significant, then if the position doesn't 'go' in the right direction reverse them). So do something like this. This code must be called either every time an encoder input changes (which would require that you set up the encoder inputs to interrupt on change) or often enough that you're guaranteed to catch every encoder change (which requires that you figure out the maximum possible speed of the encoder and make sure you call this code at least once for each encoder output state -- I'd aim for twice). Don't just copy this code in and expect it to work. In fact, don't _touch_ this until you've worked out the operation on paper and understand _why_ it works. Working with encoders is easy, once you've turned your brain upside down. static int position; int x, diff; x = (port capture such that x.0 = A and x.1 = B, and all higher bits are zero); x ^= x >> 1; // xor x.0 with x.1 diff = (position - x) & 0x0003; // get the difference in the LSB switch (diff) { case 1: --position; // encoder has decremented, follow it break; case 2: // encoder has incremented or decremented twice, // we're lost (insert your error recovery here) break; case 3: ++position; // encoder has incremented, follow it break; case 0: // encoder hasn't moved break; } -- www.wescottdesign.com
From: Chris Stratton on 24 Sep 2009 10:48 On Sep 24, 10:35 am, Tim Wescott <t...(a)seemywebsite.com> wrote: > So do something like this. This code must be called either every time an > encoder input changes (which would require that you set up the encoder > inputs to interrupt on change) or often enough that you're guaranteed to > catch every encoder change The fun of course being that it requires either interrupts that can be set to trigger on either edge, or keeping the interrupt configuration register up to date with which edge should be expected next, or running each signal into two pins one set to trigger on rising and the other on falling...
From: TTman on 24 Sep 2009 11:11 "Chris Stratton" <cs07024(a)gmail.com> wrote in message news:60d9f920-22f1-45d2-98d9-6e25eb46165f(a)e18g2000vbe.googlegroups.com... On Sep 24, 10:35 am, Tim Wescott <t...(a)seemywebsite.com> wrote: > So do something like this. This code must be called either every time an > encoder input changes (which would require that you set up the encoder > inputs to interrupt on change) or often enough that you're guaranteed to > catch every encoder change The fun of course being that it requires either interrupts that can be set to trigger on either edge, or keeping the interrupt configuration register up to date with which edge should be expected next, or running each signal into two pins one set to trigger on rising and the other on falling... Isn't it just as effective to do it in hardware with flipflops.... giving step and direction ?
From: Rich Webb on 24 Sep 2009 11:11
On Thu, 24 Sep 2009 08:56:26 -0500, "vibz86" <vibz86(a)gmail.com> wrote: >Hi folks, >Im having great trouble in pic programming and hope someone can help me.Im >designing a motor controller circuit using pic 16f877a. Iv got a single >ended quadrature encoder (It has 5 outputs - a channel, b channel, z >channel, 5v, ground). Iv finished the coding for the motor controller part >in mikroc. NowI dont know how to do the programming for this encoder. Unless I'm extremely constrained by cost or board space or whatever, I've found that life is simpler by letting an external chip handle reading quadrature encoders. Nowadays it's usually this guy: <http://www.usdigital.com/products/interfaces/ics/lfls7366r-s/> -- Rich Webb Norfolk, VA |