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

QEI code for 18f4431

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







QEI code for 18f4431
PostPosted: Thu Jun 30, 2005 11:10 pm     Reply with quote

hi,
I try to use someone's code for optical encoder with f4431.
phase A connected to RA3(QEA)pin 5 and phase B to RA4(QEB)pin 6.

but lcd only show "count = 3345" or any number after i reset the MCU.


Can anyone help?

Code:
#include <18F4431.h>
#DEVICE ICD=TRUE
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600,  parity=N, Bits=8, xmit=PIN_C6, rcv=PIN_C7,stream=COM_1)

#BYTE QEICON=0xFB6  // quadrature configure
#bit QEICONDIR=0xFB6.5
#BYTE DFLTCON=0xF60  // quadrature noise filter configure
#BYTE CAP2BUFL=0xF66 // position counter
#BYTE CAP2BUFH=0xF67
#BYTE CAP3BUFL=0xF64  //max count
#BYTE CAP3BUFH=0xF65
#include <lcd.c>
unsigned int16 quadhigh=0; 


#int_IC2QEI

QuadRollover()
{
// increment high bytes if + direction on interrupt, decrement if -
QEICONDIR?quadhigh++:quadhigh--;
// to see when this happens,
// I find it helpful to toggle a digital out here
}



void main()
{
   signed int32 position=0;
   signed int32 old_pos=0;

   QEICON=24; // quad in x4 mode, resettable by maxcount
   DFLTCON=49; // noise filter on QEA, QEB,, 1:2 clock
   CAP3BUFL=0xFF;  // set max count
   CAP3BUFH=0xFF;
   
   lcd_init();
    lcd_putc("\n\rready\n\r");

   enable_interrupts(INT_IC2QEI); // interrupt on maxcount or underflow
   enable_interrupts(GLOBAL);


  while (1)
{  //of course, in real life, this is RTCC driven!!
        position=(((int32)(quadhigh))<<16)+(CAP2BUFL+((int16)CAP2BUFH<<8));
      if(old_pos!=position)
      {
         old_pos=position;
         printf(lcd_putc,"\fcount = %6ld",old_pos);
      }
      
}
}
sseidman



Joined: 14 Mar 2005
Posts: 159

View user's profile Send private message

Re: QEI code for 18f4431
PostPosted: Fri Jul 01, 2005 6:45 am     Reply with quote

williamho wrote:
hi,
I try to use someone's code for optical encoder with f4431.
phase A connected to RA3(QEA)pin 5 and phase B to RA4(QEB)pin 6.

but lcd only show "count = 3345" or any number after i reset the MCU.


Can anyone help?



It's my code.

First, add

Code:
CAP2BUFL=0;
CAP2BUFH=0;

somewhere after you define these registers. This will help you determine whether you're counting at all!

Slow down that last loop a lot. You really don't want to do this print of every iteration through the loop-- maybe every 100 iterations or so. I don't think this is your problem, but all that serial output is going to wreak havoc. The original snippet for the loop in main is just a placeholder-- I used a timer to drive the loop at a kHz for control purposes, and I used a counter to update the display at something like every 100 iterations.

Then, try running the code simply tying both QE inputs low, or one low and one high, and make sure that your count stays at 0 (or maybe one or two LSB's to either side of zero, allowing for startup glitches.

Next, with the type of behavior you're seeing, I'd consider a watchdog timer. How do you know that the lcd is actually updating?? I'd recommend using an RS232 out-- at least in a terminal, you can see whether the output is scrolling or not. At the very least, toggle a bit every once in a while to help you try and figure things out. Depending on your output rate, maybe you could send the 4th or 5th LSB of your count out to a digital out and an LED. If you can look at this output on an oscilloscope, just look at the LSB. With an LED, you need to pick a bit that will change slow enough to see the blinking.

You may or may not need QuadRollover. I needed this because I had a high resolution encoder, running on the motor side of a big gear reducer at high speed. If you're not expecting your count to exceed 16 bits, don't enable the interrupt, change all the position types to signed16, and get rid of the math that marries the count high 16 to the count low 16. Even if you need 32 bits, this would be a good debugging step to help you figure out if the interrupt is killing you.

Get rid of the "6" in your %6ld format. Maybe things die if you need more than 6 digits right now. I don't know much about lcd_putc, so I don't know if it would screw up here, and how the screwup would manifest on the screen.

Bottom line, slow down your output rate to something reasonable, and try to figure out if the count is working through a means more verifiable than an lcd write.

Scott Seidman
Code:
pswanson
Guest







Small detail
PostPosted: Thu Jul 07, 2005 12:37 pm     Reply with quote

Note that you declared quadhigh as an unsigned int16. You can potentially and perhaps very easily underflow this term.
sseidman



Joined: 14 Mar 2005
Posts: 159

View user's profile Send private message

Re: Small detail
PostPosted: Thu Jul 07, 2005 12:54 pm     Reply with quote

pswanson wrote:
Note that you declared quadhigh as an unsigned int16. You can potentially and perhaps very easily underflow this term.


Thanks for pointing it out. I'm pretty sure I tested it, and found that when you decrement an unsigned 0x00, it rolls over to 0xFF. Math done with the result will of course be wrong, but I'm just shifting it up to the high byte of an i32, so it doesn't make a difference. I'll check again, just to make sure.

In my actual app, I don't check the encoder until a hit a switch going in the negative direction. when I hit it, I zero the count, and move in the positive direction toward center.

Scott
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