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

How can I improve this code?

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



Joined: 05 Jun 2013
Posts: 15

View user's profile Send private message

How can I improve this code?
PostPosted: Sun Jun 05, 2016 12:21 am     Reply with quote

Hi, I'm not very new to CCS C but I have a problem that I can't seem to get my head around.

I have a rotary encoder, which is 4000 CPR and can work till 6000 RPM, I'm using PIC18F26K22 working at 4PLL at 16MHz, but when I move the encoder even to speed on 60 RPM my code starts missing the points.

I thought maybe it's the problem of printf so I removed all the printf from my code but still nothing. If someone could improve the code or give me a tip as to how to make it check input points faster or what is slowing it down, it'll be really helpful.

Code:

signed int16 En2Code()
{
   Code = Input_a() & 0x7;
   
   if (Code != PCode)
   {
      if (Code >= 4)
      {
         Index = 0;
         output_high(INT_LED);
         return Index;
      }
      else
         output_low(INT_LED);
     
      if ((Code == 0 && PCode == 2) || (Code == 1 && PCode == 0) || (Code == 2 && PCode == 3) || (Code == 3 && PCode == 1))
         Index++;
      else
         Index--;
     
      PCode = Code;
   }
   return Index;
}


Here is the .h file but it has lots of other points that aren't used in this routine but I am not using any other functions, this is the only function used in while loop.

Code:

#include <18F26K22.h>
#device ADC=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#use delay(internal=64MHz)
#use rs232(baud=230400,parity=N,xmit=PIN_B2,rcv=PIN_B3,bits=8,stream=TTL, FORCE_SW)

#define INP1 PIN_A0
#define INP2 PIN_A1
#define INP3 PIN_A2

#define INT_LED PIN_C1

int1 IN1X = false;
int1 IN2X = false;
int1 IN3X = false;
int PCode = 0;

int1 print = true;
int Code = 0;
int Codes[10];
int CodeAdd = 0;
signed int16 Index = 0;


signed int16 Encode(void);
signed int16 En2Code(void);
Ttelmah



Joined: 11 Mar 2010
Posts: 19338

View user's profile Send private message

PostPosted: Sun Jun 05, 2016 12:41 am     Reply with quote

Honestly, either get a PIC that has a rotary encoder module, or use an external encoder.

With 'quadrature' encoders, the signal has to be sampled at least four times for every cycle of the encoder output. Either by using interrupts, or by just sampling fast enough.

If your encoder is 4000PPR, and it goes to 6000RPM, then this implies sampling at 1.6 million times per second.

(4000*4*6000)/60 = 1600000

Not even remotely possible, especially if the PIC is wanting to do anything else.....

The software approach, either using interrupts, timers, or just calling a routine, is perfectly acceptable for something like a 16 line encoder moving at a few hundred RPM max, but for anything as fast as you are talking about, and with the number of lines your encoder involves, you need hardware. If you are only driving one encoder, then it is quite easy (just a couple of logic gates), to drive the internal PIC timers to give counts (Microchip have an AN on this).

You need hardware to do this. US Digital do some nice SPI encoder chips, or a few PIC's do have quadrature modules 'built in'.

As a further comment, are you sure your approach is sound?. Normally if using an encoder directly on the motor shaft, it'll be a low accuracy encoder (perhaps only 16PPR). High accuracy encoders are normally used 'after' the gearbox. Part of this is that the finer the encoder, the more accurately the bearing has to hold the shaft. The high accuracy bearings are often not rated for motor speeds, and the vibration of the motor can make the encoder useless.
temtronic



Joined: 01 Jul 2010
Posts: 9164
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jun 05, 2016 6:22 am     Reply with quote

MR T is right again ! I've used US Digital's encoder chips for decades, sigh I'm getting old. Used them first on the 'new' 16F877 to control helicopters. While I've never used a PIC with QEI, it would be interesting to see the price/perfomance breakdown vs. a USD device.

Jay
greeniemax



Joined: 05 Jun 2013
Posts: 15

View user's profile Send private message

PostPosted: Sun Jun 05, 2016 10:04 am     Reply with quote

Thank you Ttelmah for your great informative response.

I think I know why is it happening though, please guide me if you think I'm wrong.

I have PC817 Photocoupler on the line, I used it to reduce noise, though the board I'm using is for something else.

But the response time for these are slow like 18us up and 18us down, I think this could be causing the problem.

I'll try it with a board with open connection to the processor.

What do you think, might this be the problem? Because 4000 RPM is a lot, it's not even going beyond 100 RPM without giving errors.
Ttelmah



Joined: 11 Mar 2010
Posts: 19338

View user's profile Send private message

PostPosted: Sun Jun 05, 2016 1:05 pm     Reply with quote

Yes, that is probably your current problem, but there is little point in wasting time on your current approach, since it is not going to work at the speed you want. An oscilloscope will tell you in an instant what is happening on your inputs. Basic test equipment is a 'must' if you want to do designs at even a basic level. I built my first scope, when I was at school.

Understand that proper encoder chips will have input circuits designed to reduce noise already built in....
Ttelmah



Joined: 11 Mar 2010
Posts: 19338

View user's profile Send private message

PostPosted: Mon Jun 06, 2016 12:40 am     Reply with quote

Just to give a 'follow up' on this.

Cost. On chips that have the MFM module (motion feedback), the price is zero. Basically these chips cost the same as their brethren without the module, and (of course) also zero real estate on the PCB. Question is whether there is a chip with this module that fits the other requirements. The PIC18F2431 for example, is $3.22, while similar chips with the same amount of ROM and RAM all come around $3 to $4.
Downside is that except for a few much larger DSPIC's, there is generally only one MFM module in any PIC. If more than one encoder is needed, then external counting is the way to go.
The module has Schmitt inputs and a programmable digital noise filter.

Then there is the question of what the rated speed of the encoder actually 'is'. As I've already said, most high line count encoders (1000PPR+), are not rated to go to 6000RPM. If you look at a fairly normal encoder like the OMRON E6C3 family, these have a maximum output frequency specification of 125KHz. With the comment:

"The maximum electrical response revolution is determined by the resolution and maximum response frequency as follows:
Maximum electrical response frequency (rpm) = Maximum response frequency/resolution × 60
This means that the E6C3 will not operate electrically if its revolution exceeds the maximum electrical response revolution."

So the 3600PPR version is limited to 2083RPM.

It is very unlikely indeed that a 4000PPR encoder will operate to 6000RPM.

I think though his encoders are only 1000PPR, so the *4 is already included in the figure. Then makes sense of the numbers. His maximum frequency then is 'only' 400KHz.
Still though much to fast to handle with software.

He needs to understand, that everything depends on what 'else' is happening outside the routine. Even one calculation, one putc, etc., each costs time, and delays the routine being called again. At 16MHz, with a encoder at this sort of rate, you don't have time to do _anything_....

If he is doing any code outside the routine, then edges _will_ be missed. How long this code takes, will determine the limiting speed. I'd guess he has something that is taking quite a few tens of uSec, hence edges are missed....
greeniemax



Joined: 05 Jun 2013
Posts: 15

View user's profile Send private message

PostPosted: Mon Jun 06, 2016 9:45 am     Reply with quote

Thanks for your help guys, I'll surely go with an encoding IC, but I tried it without PC817 and trust me it works great.

I get to about 200 RPM without any problem, I don't need it to work beyond 120 RPM anyways but it's working perfectly now.

Thanks for your support, I'll get the encoding IC for my actual project.
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