![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
vietlongIPD
Joined: 16 Mar 2010 Posts: 1
|
help- impulse noise encoder - pic 18f4331 - use int ext |
Posted: Tue Mar 16, 2010 8:50 am |
|
|
Hi everybody
I have a strange problem. I control my motor (servo with encoder 200 slot - 2 sign A B) with module ccp1 and I use int_ext1 (PIN_C4) to receive signA of encoder. But if I don't connect supply power for motor (one pole connect with +12v, other pwm1 = ccp1) program recognize correct number of pulse encoder and if have motor run program is wrong, same have noise. PIC auto count pulse and perform program although I don't rotate encoder (I take apart the motor & encoder).
Here is my circuit, assured that there is no virus ( orcad 10.5)
http://www.mediafire.com/?mjmjm5w3myv
My program
Code: |
#include <18f4331.h>
#FUSES HS //High speed Osc (> 4mhz)
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOCPD //No EE protection
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOWDT
#use delay(clock=20000000)
#use fast_io(b)
#use fast_io(c)
#use fast_io(a)
#use fast_io(d)
#use fast_io(e)
int1 flag_ngat1=0,flag_ngat2=0,ngat1=0,ngat2=0;
int16 signA,signB,en_t,en_p;
int8 en;
/**************************************/
#int_ext1 //count encoder left
void ngat_int1()
{
disable_interrupts(int_ext1);
signA++;
if ((signA >= en_t)&&(flag_ngat1 == 0))
{
ngat1 = 1;
flag_ngat1 = 1;
signA = 0;
}
enable_interrupts(int_ext1) ;
}
#int_ext2 //count encoder right
void ngat_int2()
{
disable_interrupts(int_ext2);
signB ++;
if ((signB >= en_p)&&(flag_ngat2 == 0))
{
ngat2 = 1;
flag_ngat2 = 1;
signB = 0;
}
enable_interrupts(int_ext2) ;
}
/**************************************/
void main(){
set_tris_A(0xB1); // pin A7 -> pin A0 1011 0001
set_tris_B(0xC0); // pin B7 -> pin B0 1100 0000
set_tris_C(0x39); // pin C7 -> pin C0 0011 1001
set_tris_D(0x03); // pin D7 -> pin D0 0000 0011
set_tris_E(111);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
setup_timer_0( RTCC_INTERNAL| RTCC_DIV_256 | RTCC_8_BIT);
setup_timer_2(T2_DIV_BY_16, 255, 1);
/* setup_power_pwm_pins(PWM_BOTH_ON,PWM_BOTH_ON,PWM_O FF,PWM_OFF);
setup_power_pwm(PWM_CLOCK_DIV_128|PWM_FREE_RUN,
1, //postscale, not used
0, //initial PTMR
63, //**************PTPER9 //
0, //compare special event, not used
1, //postscale compare special event, not used
0); //dead_time
set_power_pwm_override(1, false, 0);
set_power_pwm_override(3, false, 0);
set_power_pwm_override(5, false, 0);
set_power_pwm_override(7, false, 0);*/ // use mode PWM cua 18f4331
enable_interrupts(int_ext1);
enable_interrupts(int_ext2);
ext_int_edge(1, L_TO_H );
ext_int_edge(2, L_TO_H );
enable_interrupts(GLOBAL);
output_high(PIN_B0);
output_high(PIN_B1);
output_high(PIN_B2);
output_high(PIN_B3);
output_high(PIN_B4);
output_high(PIN_B5);
output_high(PIN_D2);
output_high(PIN_D3);
output_high(PIN_D4);
output_high(PIN_D5);
output_high(PIN_D6);
output_high(PIN_D7);
output_high(PIN_C6);
output_high(PIN_C7);
set_pwm1_duty(255); //high V on CCP1
set_pwm2_duty(255); //high V on CCP2
signA=0
while(true){
if(signA>100) output_low(PIN_B0); //if encoder rotate 1 round then indicator light of Pin B0 lighted
if(signA>200) output_low(PIN_B1); //if encoder rotate 2 round then indicator light of Pin B2 lighted
if(signA>300) output_low(PIN_B2); //if encoder rotate 3 round then indicator light of Pin B0 lighted
if(signA>400) output_low(PIN_B3); //if encoder rotate 4 round then indicator light of Pin B0 lighted
if(signA>500) output_low(PIN_B4); //if encoder rotate 5 round then indicator light of Pin B0 lighted
}
}
|
This is simple program for test encoder but as I said, if I connect motor with CCP1 and run it -> my program auto light lamp although I don't rotate encoder. I don't know why (of course pin 17 ccp1 connect - octo - uln2803 - bjtb562 // d468 - mosfet irf540 - 1pole of motor) .
My friend advise me to use module QEi for filter noise but I don't know how to config module QEI - somebody can help me - I fabricate one robot and I need use encoder --> for control the motor and calculate distance of the robot correctly.
Sorry for my English level is not very good, but I hope that you can understand a little piece and help me.
Best regards. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Mar 16, 2010 4:15 pm |
|
|
Quote: |
PIC auto count pulse and perform program although I don't rotate encoder
enable_interrupts(int_ext1);
enable_interrupts(int_ext2);
ext_int_edge(1, L_TO_H );
ext_int_edge(2, L_TO_H );
enable_interrupts(GLOBAL);
|
Does the encoder have open-collector outputs ? (or open-drain)
If it does, then the PIC interrupt pins will be "floating" inputs.
This means an interrupt could be triggered by noise at any time.
To fix this, you need to use pull-up resistors on the INT0 and INT1 pins
on the PIC. You can use 4.7K ohms. This will hold the INT0 and INT1
pins at a logic '1' level, and prevent interrupts due to noise.
Quote: |
set_tris_A(0xB1); // pin A7 -> pin A0 1011 0001
set_tris_B(0xC0); // pin B7 -> pin B0 1100 0000
set_tris_C(0x39); // pin C7 -> pin C0 0011 1001
set_tris_D(0x03); // pin D7 -> pin D0 0000 0011
set_tris_E(111);
|
Also, the '111' value is probably not intended. You probably mean 0b111
or 0x07. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|