|
|
View previous topic :: View next topic |
Author |
Message |
mi Guest
|
problem to read position from encoder |
Posted: Mon Nov 21, 2005 6:30 am |
|
|
Hi every body,
I have problem to read the postion from encoder when the motor is turn more than 1000RPM.(pic is not work)
Any body can help me to make this program to read the position more than 3500RPM.
Thank you very much for your help.
#include <18f2431.h>
#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)
#use fast_io(B)
/*
RB4,RB5=quadrature inputs
*/
signed int32 position=0;
//Note using int32, otherwise routine will run off the end very quickly.
//Also 'signed', so the unit can handle the shaft rotating backwards at
//the start...
#byte portb=0xF81
#bit bchanged=0xFF2.0
#int_global
void myint(void) {
static int old;
static int new;
static int value;
//Here I have an edge on one of the quadrature inputs
new=portb;
/*Now I have to decode the quadrature changes. There are four
possibilities:
I can have a rising or falling edge, on each of the two inputs. I have to
look at the state of the other bit, and increment/decrement according to
this. */
value=new^old;
//'value', now has the bit set, which has changed
if (value & 0x10) {
//Here the low bit has changed
if (new & 0x10) {
//Here a rising edge on A
if (new & 0x20) --position;
else ++position;
}
else {
//Here a falling edge on A
if (new & 0x20) ++position;
else --position;
}
}
else {
//Here the high bit (B) must have changed
if (new & 0x20) {
//Here a rising edge on B
if (new & 0x10) ++position;
else --position;
}
else {
//Here a falling edge on B
if (new & 0x10) --position;
else ++position;
}
}
old=new;
bchanged=0;
#asm
//Here the 'fast' exit.
RETFIE 1
#ENDASM
}
//Main code loop
void main(void) {
signed int32 lastpos=0;
position=0;
port_b_pullups(true);
//Note that many of the quadrature encoders _require_ pull-ups on
//their lines, having open collector outputs.
setup_adc_ports(NO_ANALOGS);
setup_spi(FALSE);
set_tris_B(0x30); //Input on bit 4,5 for quad
enable_interrupts(INT_RB);
enable_interrupts(global);
lastpos=position;
while (true) {
if(lastpos!=position){
lastpos=position;
printf("%ld \n\r",lastpos*360/4/1024/23);
//I would recommend a delay here. The interrupt will still keep
//counting edges, but without a delay, the string will be 'non stop'
//for any reasonable movement rate.
}
}
} |
|
|
sseidman
Joined: 14 Mar 2005 Posts: 159
|
|
Posted: Mon Nov 21, 2005 7:37 am |
|
|
Using the 2431, you shouldn't have to do any edge detection by yourself-- use the QE inputs, and take advantage of the hardware quadrature handling. It will be much faster. |
|
|
MikeValencia
Joined: 04 Aug 2004 Posts: 238 Location: Chicago
|
|
Posted: Mon Nov 21, 2005 8:50 am |
|
|
What filtering capacitors do you have? If you look on a scope and find that the rise time doesn't even get a chance to get up all the way, then you'll have to change your hardware.
This would be the first step in troubleshooting your problem, because if the hardware is the problem, then no software changes will fix it. |
|
|
Mi Guest
|
|
Posted: Mon Nov 21, 2005 9:40 pm |
|
|
Hi sseidman and MikeValencia
I use 2 encoders input, one encoder i use QE input with no problem but an other one i use interrupt port b to capture position from encoder and i have problem when motor turn fast.
I don't have filtering capacitor, my encoder is HEDS5500. i connected my encoder directly to the pic in port B4 and B5.
how to speed up the program?
where i can i put the filtering capacitor?
thank you very much. |
|
|
sseidman
Joined: 14 Mar 2005 Posts: 159
|
|
Posted: Tue Nov 22, 2005 7:31 am |
|
|
Personally, I'd throw one uC at each. |
|
|
Ttelmah Guest
|
|
Posted: Tue Nov 22, 2005 8:02 am |
|
|
First comment. Which HEDS5500?. For the -A version, 3500RPM, is faster than the encoder itself is rated.
Even with the -A version, you need to be checking that the signals are switching to the levels needed by the port inputs at full speed. Remember the RB4:7 pins, have schmitt trigger inputs, and must therefore go from 0.2Vdd to 0.8Vdd, for an edge to be seen. Many TTL outputs, will not guarantee this, only going up to perhaps 0.6Vdd, when switching quickly. The output timings for the decoder you are using, are for it reaching 2.4v, not the 4v needed by the PIC's inputs. I'd suspect this is actually the core of your problem, and adding a buffer with better input sensitivity might make it all work.
For full quadrature decoding, you have to count four 'edges' for every line on the encoder. At 3500RPM, on the -C version (100 lines), you would have edges at (3500*100*4)/60 times per second. This corresponds to about every 85 instruction cycles. The code you have posted is a version I developed some time ago, and should handle this rate (though I'd run the chip at 40MHz, to give more margin).
Best Wishes |
|
|
MikeValencia
Joined: 04 Aug 2004 Posts: 238 Location: Chicago
|
|
Posted: Tue Nov 22, 2005 8:04 am |
|
|
I only have one pair of encoders connected to rb0 and another pin. I have a tmr1, rb0, and tmr3 isr running. What i do before leaving the tmr1 and tmr3 isr is:
Code: |
#int_timer1
void tmr_isr(void)
{
...
if (rb0 interrupt flag is set)
{
rb0_isr_routine();
}
}
#int_ext
{
rb0_isr_routine();
}
|
No fast interrupt routines are used, and i seem to get away with it. Remember, with a rb0 interrupt, all you have to do is to do a 'dummy read' of rb0, and it automatically clears the flag.
If 20Mhz isn't enough, have you considered using 40MHz? or even 10MHz with PLLx4 speedup enabled to give you 40MHz?
If i had to start from the beginning, I would do as sseidman says and use two 18f4431 chips.
As an alternative, isn't it possible to feed one pair of encoders into your QEI, and another pair to go thru some flipflop logic and go to either tmr1 or tmr3 as external timer inputs? |
|
|
Mi Guest
|
|
Posted: Tue Nov 22, 2005 9:24 pm |
|
|
hi Ttelmah,
Thank you very much for your reply and your answer.
Sorry my encoder is HEDM5500J.
if I use crystal 10Mhz and PLL x 4 i can capture position with the speed increase two time.
I try to see the signal output with full speed from encoder is 0 - 4.8V and frequancy 100khz , i think is not problem with hardware.
do you have an other method to capture the position with int_Rb?
Thank you. |
|
|
Ttelmah Guest
|
|
Posted: Wed Nov 23, 2005 5:19 am |
|
|
So you have switched to using the HEDM, rather than the HEDS you originally referred to?.
Frequency, should not be 100KHz. At 3500RPM, the frequency should be (3500*1024)/60 = 59733Hz. If you are reading 100KHz, then it implies you are either well over 3500RPM, or have a lot of innacuracy somewhere in your test setup...
Now if the signal is at 100KHz, this implies quadrature decoding at 400000 times per second (remember the quadrature signals are both the rising, and falling edges of _both_clocks). Even at 40Mhz, this gives only 25 instruction times between the edges. This is beyond the capabilty of a PIC to manage. In fact if you are getting to even half this rate (50 instruction times), you are pretty much flat out, and would not have time to do anything much else.
Other posters have mentioned the possibility of using a PIC, with hardware quadrature decoders built in, another possibility is the LS7166, which is designed for this sort of job.
Do you really need this level of resolution?. Potentially you are reading the position in 0.088 degree steps. Unless you shaft is held very rigidly, with high quality bearings, you are unlikely to get repeatable operation at this sort of accuracy level, and the whole problem becomes a lot easier if you reduce the encoder accuracy. With a 100 line encoder, you still get better than 1 degree step size, and the data rate is only 1/10th of what you are using. Alternatively, switching to using single edge detection (a rising or falling interrupt on just one of the signals), reduces the data rae to just 1/4 the current level.
Realistically, you are trying to do something, that is beyond the abilities of the hardware you are using, and need to 'think again'.
Best Wishes |
|
|
|
|
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
|