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

Encoder error checking

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



Joined: 05 May 2006
Posts: 25

View user's profile Send private message AIM Address

Encoder error checking
PostPosted: Fri May 05, 2006 9:43 pm     Reply with quote

Good Day Folks!
I have an encoder issue with what I believe to be noise. The current feedback circuit input only utilizes A and B channels of the encoder but all the typical signals are available. I want to make a quick fix and all I have to work with is a few PIC12F629's, resistors and connectors. The encoder is a line driver 5000PPR capable of 300KHz operating at TTL levels. I certainly don't come close to that speed. I never actually never even complete one revolution in this application. I basically made a comparator from two of the processors. One to handle channel A and one for channel B. I know I could use one PIC but I am slightly concerned with speed. and since I had two, I used them. How can I determine how fast this code is processed? Both PICs are running the same code, one for each channel.

while (TRUE)
{
if (input(ENC))
{
if (!input(ENCN))
{
output_toggle(ENCO);
output_toggle(LED);
}
}
}
Any help is appreciated.

Thanks
Ttelmah
Guest







PostPosted: Sat May 06, 2006 2:56 am     Reply with quote

You talk about 'other signals'. The A, and B channels are all that most encoders offer. Some will offer an extra 'index' output, but this is rarer...
Now the first question, is what mode does the decoder use?. There are three different ways that the quadrature signals can be decoded. The first (simplest), is 'single sampling'. With this, the decoder circuit looks for one edge of one of the signals, and looks at the other signal on this edge. This gives 5000 locations/rev, from a 5000 'line' encoder. The second, is to sample both edges of one of the signals. Gives 10000 locations/rev, from a 5000 line decoder. The third is to use full quadrature decoding. On this, you look at the level of both signals, on each edge of each signal. This gives 20000 locations/rev, from a 5000 line decoder.
Now what you are doing, will destroy the data needed for all but the single sampling mode. If you do not know what mode the decoder is working in, then you would be better off assuming that it does need both edges of each waveform accurately decoded.
Now 'time wise', the answer is to count instructions in the assembler listing, or run the code in MPLAB, and use the 'stopwatch' function. How long it'll take, will depend on some parts you don't show (the key one, being the 'I/O mode selected on the chip).
If (for instance), you use 'standard_IO', then each time you perform a output on a port, it'll be translated into two instructions, one setting the TRIS register, and the other doing the actual IO. The same applies for each input. If instead you use 'FAST_IO', these instructions become just single machine operations. Seperately, the 'output_toggle' instruction, would be probably better replaced with having an internal flag that is toggled, and then copied out to the port. The reason here is that if there is significant loading on the line, you may well run into the 'read modify write' problem on this line. I'd also suggest that you use GP2 as the input pin for this, since this pin has a schmitt trigger input, which should help to supress noise. There is also a final problem, in that in the code as shown, you do not ensure that the output pin starts with the same polarity as the input. If this is wrong when the code starts, the encoder will be seen as rotating in the wrong direction...
I'd suggest a somewhat different approach:
Code:

#include <12F629.h>
#use delay(clock=4000000)
#fuses INTRC,NOWDT,NOPROTECT,NOMCLR

#use fast_io(A)
#byte GPIO=5
#bit IP=GPIO.2
#bit OP=GPIO.0

void main() {

   int8 last;
   int8 val;
   setup_counters(RTCC_INTERNAL,WDT_2304MS);
   set_TRIS_A(0x4);
   //Make the output match the input
   GPIO=0;
   val=GPIO;
   OP=bit_test(val,2);
   clear_interrupt(INT_RA);
   enable_interrupts(INT_RA); //Using port change to wake from sleep
   while (true) {
      sleep();
      val=GPIO;
      OP=bit_test(val,2);
      clear_interrupt(INT_RA);
   }
}

This does seem to be a 'sledgehammer/nut' solution, a simple schmitt trigger input buffer would be a lot easier, but this ought to support pulse rates up to about 100KHz. This uses the hardware 'interrupt on change' feature, to detect an edge on the incoming signal, and then makes the output copy this.

Best Wishes
dsaari



Joined: 05 May 2006
Posts: 25

View user's profile Send private message AIM Address

PostPosted: Sat May 06, 2006 6:08 am     Reply with quote

When I spoke of other signals from the encoder I was describing the compliments of the A and B channels. I want to use these signals along with their compliments to help eliminate possible errors on the encoder lines due to noise. Basically I take channel A into an input and it's compliment into another input and if they are at different states I want to toggle an output bit which will then become my new, and hopefully noiseless encoder signal. The exisiting circuitry only utilizes the A and B channels and not the compliments. This way I figure I can make it more robust by placing my circuit ahead of the exsisting circuit. I calculated that my encoder only turns 120 degrees in about 20 seconds, that 1390pulses or about 70Hz. So I really need to be sure I can loop through my code in about 14ms to be sure I don't miss counts. I'm pretty much looking for a down and dirty solution with simple code as this is all the pic will be used for. I think I actually have it working, but I wanted to verify speed to assure I wasn't on the edge of missing counts.

Thank you
Ttelmah
Guest







PostPosted: Sat May 06, 2006 8:13 am     Reply with quote

14mSec!. You could perform several dozen floating point operations in this time. The loop will only take a few tens of uSec.
However the question about how the decoder works remains.
Seperately though, if the encoder has differential outputs (which is what you are describing), it should be fed to a differential input, not directly into any simple logic. It sounds as though the decoder was built for an encoder offering logic outputs, and is being used with one giving differential signals. Using logic inputs (whether in the existing ones in the decoder, or on a PIC), leaves any common mode noise still present. Get rid of the PC, and use a proper differential receiver. the results will be magnitudes better.

Best Wishes
dsaari



Joined: 05 May 2006
Posts: 25

View user's profile Send private message AIM Address

PostPosted: Sat May 06, 2006 9:55 am     Reply with quote

The decoder is within a pic18F2331, I have no source for what it is doing, but the datasheet specified quadrature encoder inputs, so I'd imagine the that must be the decoding scheme being utilized. I do understand that a true differential receiver is what I need, but it is not what I have available right now. I did pulldown the differential inputs prior to bringing them into the PIC logic as they float when not on. It does by all appearances seem to be functioning. My biggest concern would have been speed, which sounds like it's not going to be an issue. I do intent to resolve this with a differential reciever long term but my bandaide will need to suffice for now. Thanks for your input.
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