|
|
View previous topic :: View next topic |
Author |
Message |
js.l
Joined: 02 Jun 2010 Posts: 7
|
interrupts work good only on debugger |
Posted: Tue Aug 24, 2010 8:56 pm |
|
|
I am experiencing a weird behavior from my PIC dem2 board. I am using a 18f8722.
My pic is hooked up to an encoder and it controls a PWM output for an electric motor.
My problem is with the calculation of the speed by the encoder, whenever I run my program with the debugger (Pickit3) everything works perfectly. If I go in programing mode, and leave the debugger plugged, the program still works perfectly BUT when ever I unplug the debugger the speed is completely off and gives me random values, even when the speed of the motor is stable.
Here is how I do my speed calculation (my real code is at work, this is a copy paste from my head so might be some syntax mistake, but the logic is there).
Code: |
#int timer0
{
rpm=pulse*6; // 6 is a constant I calculated based on the timer speed
pulse=0;
set_timer0(....);
}
#int_CCP2
{
pulse++; // every rising edge on the encoder increments the pulse count
}
|
Is this a good way of calculating speed? Could the debugger slow down the clock and cause it to be accurate only in debug mode? But then it would not explain why it still works fine in program with the pickit3 plugged...
Is there any command that might be delaying my interrupts, like a set_pwm, delay_ms, fgets, strtod. Or is there anything else I would need to disable my interrupt before calling?
Any ideas? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Aug 24, 2010 11:40 pm |
|
|
Related to the shown snippets: There won't be a need to rewrite a periodical timer on every timer tick normally. But the real problem is most likely not visible here. |
|
|
js.l
Joined: 02 Jun 2010 Posts: 7
|
|
Posted: Wed Aug 25, 2010 10:08 pm |
|
|
Here is all the code, if anyone has any idea about what could cause my problem feel free to share. Sorry it's in french, demarrer=start, poids= weight from a scale, v is for vitesse=speed.
Code: |
#include <18f8722.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
#use delay( clock=10000000)
#byte PORTA=0xF80
#byte PORTB=0xF81
#byte PORTC=0xF82
#byte PORTD=0xF83
#byte PORTE=0xF84
#byte PORTF=0xF85
#byte PORTG=0xF86
#use rs232 (BAUD=9600, XMIT=PIN_G1, RCV=PIN_G2, BITS=8, PARITY=N, STREAM=ORDI, RESTART_WDT,ERRORS)
#use rs232 (BAUD=9600, XMIT=PIN_C6 ,RCV=PIN_C7, BITS=8, PARITY=N, STREAM=BLC, RESTART_WDT,ERRORS)
#include <input.c>
CCP_USE_TIMER1();
unsigned long int rpm_c=0;
int32 pulse=0;
char ratio[4];
float ratio_num;
char demarrer=0;
char poubelle;
int flag=0;
void main (void)
{
char v_nom[5];
char poids[20];
char poids_seul[15];
char mode;
char *ptr;
long int rpm_hp_max=0;
long int rpm_nom=0;
float hp=0;
float hp_max=0;
float hp_nom=0;
double poids_num=0;
unsigned long int seuil_decroche=0;
unsigned long int rpm_m=0;
int duty=0;
unsigned long int v_nom_int=0;
int i=0;
int j=0;
int k=0;
int inc=2;
PORTD=0x00;
output_low(PIN_C2);
setup_ccp1(CCP_PWM);
SET_PWM1_DUTY(duty);
//setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_16);
setup_timer_2(T2_DIV_BY_1,0xFA,1);
setup_ccp2(CCP_CAPTURE_RE);
while(1)
{
demarrer=0;
duty=0;
hp_max=0;
rpm_m=0;
flag=0;
k=0;
inc=1;
duty=6;
fprintf(BLC,"KZERO");
fprintf(ORDI,"\r\nEntrer M pour mode manuel ou A pour automatique\r\n");
delay_ms(200);
mode=fgetc(ORDI);
fprintf(ORDI,"\r\nEntrer la vitesse nominale \r\n");
delay_ms(200);
fgets(v_nom,ORDI);
v_nom_int=strtoul(v_nom,NULL,0);
seuil_decroche=(v_nom_int*4)/5;
fprintf(ORDI,"\r\nEntrer le ratio des poulies (clutch/moteur) \r\n");
delay_ms(200);
fgets(ratio,ORDI);
ratio_num=atof(ratio);
fprintf(ORDI,"\r\nAppuyer sur ENTER pour demarrer \r\n");
poubelle=fgetc(ORDI);
demarrer=1;
PORT_B_PULLUPS(0b00000001);
output_b(0x01);
SET_TRIS_D(0);
SET_TRIS_C(0b10000011);
SET_TRIS_B(0b00000001);
ext_int_edge(H_TO_L);
enable_interrupts(INT_EXT);
enable_interrupts(int_TIMER1);
enable_interrupts(int_CCP2);
set_timer0(0x0BDB);
enable_interrupts(GLOBAL);
delay_ms(250);
rpm_m=ratio_num*rpm_c;
if(mode=='A' || mode=='a')
{
while(duty<120 && demarrer==1 && rpm_m>seuil_decroche)
{
delay_ms(250);
delay_ms(250);
delay_ms(250);
fgets(poids,BLC);
enable_interrupts(GLOBAL);
i=0;
while(poids[i]<='-')
{
i++;
}
for(j=0 ; poids[i]>='-' && poids[i]<='9'; j++)
{
poids_seul[j]=poids[i];
i++;
}
poids_seul[j]='\0';
poids_num=strtod(poids_seul,&ptr);
hp=(poids_num*rpm_m)/5252;
rpm_m=ratio_num*rpm_c;
if(rpm_m<=(v_nom_int+8) && rpm_m>=(v_nom_int-8))
{
hp_nom=hp_nom+hp;
k++;
flag=1;
inc=2;
}
if(hp>hp_max)
{
hp_max=hp;
rpm_hp_max=rpm_m;
}
fprintf(ORDI,"%lf %lu %f \r\n",poids_num,rpm_m,hp);
SET_PWM1_DUTY(duty);
duty=duty+inc;
}
}
else if(mode=='M' || mode=='m')
{
while(demarrer==1 )
{
fgets(poids,BLC);
i=0;
while(poids[i]<='-')
{
i++;
}
for(j=0 ; poids[i]>='-' && poids[i]<='9'; j++)
{
poids_seul[j]=poids[i];
i++;
}
poids_seul[j]='\0';
poids_num=strtod(poids_seul,&ptr);
rpm_m=ratio_num*rpm_c;
hp=(poids_num*rpm_m)/5252;
fprintf(ORDI,"%lf %lu %f \r\n",poids_num,rpm_m,hp);
}
}
duty=0;
flag=0;
SET_PWM1_DUTY(duty);
hp_nom=hp_nom/k;
fprintf(ORDI,"\r\nHP NOMINAL=%f A %lu RPM \r\n",hp_nom,v_nom_int);
fprintf(ORDI,"\r\nHP MAXIMUM=%f A %lu RPM \r\n",hp_max,rpm_hp_max);
}
}
#int_TIMER1
void TIMER1_isr()
{
disable_interrupts(GLOBAL);
rpm_c=6*pulse;
pulse=0;
set_timer0(0x0BDB);
enable_interrupts(GLOBAL);
}
#int_CCP2
void CCP2_isr()
{
pulse++;
}
#int_EXT
void INTRB_isr()
{
disable_interrupts(INT_EXT);
demarrer=0;
SET_PWM1_DUTY(0);
//poubelle=fgetc(ORDI);
enable_interrupts(INT_EXT);
return;
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Aug 25, 2010 10:58 pm |
|
|
Quote: | #int_TIMER1
void TIMER1_isr()
{
disable_interrupts(GLOBAL);
rpm_c=6*pulse;
pulse=0;
set_timer0(0x0BDB);
enable_interrupts(GLOBAL);
}
|
This is wrong. It's not necessary. The compiler and the PIC handle it.
If you do it, your program will crash. Delete the lines in bold. More info:
http://www.ccsinfo.com/forum/viewtopic.php?t=43352&start=1
Quote: |
#int_EXT
void INTRB_isr()
{
disable_interrupts(INT_EXT);
demarrer=0;
SET_PWM1_DUTY(0);
//poubelle=fgetc(ORDI);
enable_interrupts(INT_EXT);
return;
}
|
This is not necessary. Delete the lines shown in bold shown above
Look at examples before you write interrupt code.
Quote: |
double poids_num=0;
|
The PCH compiler considers 'double' to be the same as 'float'.
You don't gain anything by declaring it as 'double'.
Post your #fuses. If you have the XINST fuse set, that is certain to
cause erratic behavior in the program's operation.
Also post your compiler version. |
|
|
js.l
Joined: 02 Jun 2010 Posts: 7
|
|
Posted: Thu Aug 26, 2010 8:24 am |
|
|
I have not used the #fuses, other than the ones that might be set automatically in the configuration bits of MPlab. Could this be my problem? |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Thu Aug 26, 2010 8:50 am |
|
|
js.l wrote: | I have not used the #fuses , other than the ones that might be set automaticaly in the configuration bits of MPlab , could this be my problem? |
Could be.
You should list them for us.
Also, you could consider taking a screen shot in MPLAB of the "Configuration Bits" window to make sure that everything you haven't declared with #FUSES is being set to something you expect.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
js.l
Joined: 02 Jun 2010 Posts: 7
|
|
Posted: Thu Aug 26, 2010 9:05 am |
|
|
Here are my configuration bits
OSC=HS
FCMEN=DISABLE
IESO=DISABLE
PUT=DISABLE
BODEN=ENABLE HARDWARE,SBOREN DISABLE
BODENV=2.0v
WDT=DISABLE CONTROLED BY SWDTEN
WDTPS=1:32768
PMODE=MICROCONTROLLER
ABW=20 BITS
BW=16BIT EXTERNAL BUS
WAIT=DISABLE
CCP2MUX=RC1
LPT1OSC=DISABLE
STVR=ENABLE
XINST=DISABLE
AND ALL THE PROTECT ARE DISABLE |
|
|
js.l
Joined: 02 Jun 2010 Posts: 7
|
|
Posted: Thu Aug 26, 2010 10:38 am |
|
|
problem solved!
it seems like my data aquisition time was a bit too short and by multiplying the pulse count by 6 I multiplyed my error by 6.
I change my timer1 interrupt and added a timer overflow counter. After 6 overflow I recalculate my rpm and it works good in either debugger or programed mode pickit plugged or unplugged
I also took off all the disable and enable interrupts
Thanks |
|
|
|
|
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
|