|
|
View previous topic :: View next topic |
Author |
Message |
Maverick Guest
|
Problem calculating floats |
Posted: Wed Feb 18, 2004 9:50 am |
|
|
Hi,
I have a problem when calculating floats in my program.
I have a part of code that calculates a quadratic formula:
fCourant = COEF_QUAD_A * (fCourant*fCourant)); ( ax˛ +
fCourant += COEF_QUAD_B*fCourant; bx +
fCourant += COEF_QUAD_C; c )
This part of code cause my PIC to reset...
This is the constant in the formula:
#define COEF_QUAD_A 0.000003
#define COEF_QUAD_B 0.030526
#define COEF_QUAD_C -0.008745
I tried to isolate each part of the formula and when it comes to add COEF_QUAD_B * fCourant, the PIC crash here.
Can it be a problem with too many calculs at the same time?
Or it is a float issue?
Im using version 3.129 of CCS and the PIC16F877 at 20MHz. |
|
|
Ttelmah Guest
|
Re: Problem calculating floats |
Posted: Wed Feb 18, 2004 10:58 am |
|
|
Maverick wrote: | Hi,
I have a problem when calculating floats in my program.
I have a part of code that calculates a quadratic formula:
fCourant = COEF_QUAD_A * (fCourant*fCourant)); ( ax˛ +
fCourant += COEF_QUAD_B*fCourant; bx +
fCourant += COEF_QUAD_C; c )
This part of code cause my PIC to reset...
This is the constant in the formula:
#define COEF_QUAD_A 0.000003
#define COEF_QUAD_B 0.030526
#define COEF_QUAD_C -0.008745
I tried to isolate each part of the formula and when it comes to add COEF_QUAD_B * fCourant, the PIC crash here.
Can it be a problem with too many calculs at the same time?
Or it is a float issue?
Im using version 3.129 of CCS and the PIC16F877 at 20MHz. |
One obvious question. Have you got the watchdog enabled?. If so, remember that floating calculations take a (relatively) long time. There is nothing in your code itself that should cause a crash, and though 3.129, is a pretty 'old' version, I do not remember having too many arithmetic problems at this time. I have a program using the 16F876, which does significantly more arithmetic than this (including powers, log, sqrt etc.), and now gives no problem (in the early 3.x compilers, there was a major arithmetic problem with the log function), and this was OK from the late 3.0xx compilers onwards.
Consider adding a 'restart_cause' test to the start of the program, and see if you can find out what the restart is reported as.
Best Wishes |
|
|
Maverick Guest
|
|
Posted: Wed Feb 18, 2004 11:04 am |
|
|
The watch dog was disabled. |
|
|
rwyoung
Joined: 12 Nov 2003 Posts: 563 Location: Lawrence, KS USA
|
|
Posted: Wed Feb 18, 2004 11:16 am |
|
|
I hope you were re-typing and not cut-and-pasting from your code because as your code appears it would not even compile. It looks like you are leaving out the "//" comment after the trailing semicolon.
If that is not the case, do you know the value of "fCourant"?
Also, describe "crash" further.
Are you refering to a compiler error, or does the PIC seem to reset or go off into an unexpected area of code?
Try and post the smallest possible COMPLETE version of your code that exhibits this problem and I'll try it on my compiler (3.184) and a PIC16F877A. _________________ Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month! |
|
|
Maverick Guest
|
|
Posted: Wed Feb 18, 2004 11:31 am |
|
|
My code is as follow, this is a routine I call to read a current measure on the ADC and put the measure in an array of sample. After 16 sample I do the average and use a quadractic formula for the linearity.
Code: |
void MesurerCourant()
{ float fTemp;
lDelaiMesure++;
if (lDelaiMesure >= DELAI_MESURE - DUREE_PERIODE)
{
if (lDelaiMesure >= DELAI_MESURE)
{
lDelaiMesure = 0;
iCompteurEchantillons = 0;
}
set_adc_channel(0); .
delay_us(DELAI_CONVERSION_AN);
lMesuresCourant[iCompteurEchantillons] = (long)read_adc();
iCompteurEchantillons++;
if ( iCompteurEchantillons == NOMBRE_ECHANTILLONS )
{
iCompteurEchantillons = 0;
for (i=0; i < NOMBRE_ECHANTILLONS; i++)
{
fCourant += (float)lMesuresCourant[i];
}
fCourant /= NOMBRE_ECHANTILLONS;
fTemp = fCourant * fCourant;
fCourant = ((float)COEF_QUAD_A*fTemp)
//*** THE PROBLEM START HERE ***
fCourant += ((float)COEF_QUAD_B*fCourant); // <--
fCourant += (float)(COEF_QUAD_C); // <--
AfficherTexte();
}
}
delay_ms(1);
}
|
When the PIC reached the problematic line it reset itself. If I remove the pointed lines the program run correctly... |
|
|
rwyoung
Joined: 12 Nov 2003 Posts: 563 Location: Lawrence, KS USA
|
|
Posted: Wed Feb 18, 2004 11:53 am |
|
|
Again I need to ask if you are cut-and-pasting or retyping because there is a missing semicolon on your line
Code: |
fCourant = ((float)COEF_QUAD_A*fTemp)
|
_________________ Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month! |
|
|
Guest
|
|
Posted: Wed Feb 18, 2004 12:03 pm |
|
|
Dont worry, ¸the program is compiling good.
I just copy-paste the code and remove some comments to light the text. |
|
|
Maverick Guest
|
|
Posted: Wed Feb 18, 2004 12:05 pm |
|
|
Maybe I accidently removed a semi-colon when I removed some comments. |
|
|
rwyoung
Joined: 12 Nov 2003 Posts: 563 Location: Lawrence, KS USA
|
|
Posted: Wed Feb 18, 2004 12:17 pm |
|
|
I ran a simple test with V3.184 of PCM and a PIC16F877A running at 20MHz.
This is my test code:
Code: | #device ICD=TRUE
#device adc=8
#use delay(clock=20000000,RESTART_WDT)
#fuses NOWDT,HS, PUT, NOPROTECT, DEBUG, BROWNOUT, NOCPD, NOWRT
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#include <float.h>
#define COEF_QUAD_A 0.000003
#define COEF_QUAD_B 0.030526
#define COEF_QUAD_C -0.008745
void main()
{
float fCourant;
int8 i;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_counters(RTCC_INTERNAL,RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
for(i=0;i<255;i++)
{
fCourant = 1.0 * i; // generate a new number for testing
printf("%e\r\n", fCourant);
fCourant = COEF_QUAD_A * (fCourant*fCourant); // ( ax˛ +
printf("%e\r\n", fCourant);
fCourant += COEF_QUAD_B*fCourant; // bx +
printf("%e\r\n", fCourant);
fCourant += COEF_QUAD_C; // c )
printf("%e\r\n\r\n", fCourant);
}
}
|
Two notes about the code.
1) I cut-and-pasted from your original post
2) I found two issues in the original post that prevented the code from compiling. The first was the missing "//" after the semicolons and the second was an extra ")" in your X^2 term.
This is by no means an exhaustive test but I'm attaching some of the output as captured. I haven't checked the output with a calculator but the program did run without stopping or re-setting the PIC.
So at this point I would suspect one of the following:
#fuse statment is somehow enabling your watchdog and you don't realize it
Issue with compiler bug and #fuse statment. This seems to be pretty common when reading the release notes associated with compiler revisions.
Issue with floating point routines.
Can you say at exactly what value for fCourant the problem occurs or is it any value? Try a small program like mine above to test your #fuse statement and floating point code.
Partial sample results below...
0.000000E00
0.000000E00
0.000000E00
8.744999E-03
1.000000E+00
3.000000E-06
3.091578E-06
8.741908E-03
2.000000E+00
1.200000E-05
1.236631E-05
8.732633E-03
3.000000E+00
2.700000E-05
2.782420E-05
8.717175E-03
4.000000E+00
4.800000E-05
4.946524E-05
8.695535E-03
5.000000E+00
7.500000E-05
7.728945E-05
8.667711E-03
6.000000E+00
1.080000E-04
1.112968E-04
8.633702E-03
7.000000E+00
1.469999E-04
1.514873E-04
8.593512E-03
8.000000E+00
1.920000E-04
1.978609E-04
8.547139E-03
9.000000E+00
2.430000E-04
2.504178E-04
8.494581E-03
1.000000E+01
3.000000E-04
3.091578E-04
8.435842E-03
... snip ...
2.409999E+02
1.742430E-01
1.795619E-01
1.708169E-01
2.419999E+02
1.756920E-01
1.810551E-01
1.723101E-01
2.429999E+02
1.771470E-01
1.825545E-01
1.738095E-01
2.439999E+02
1.786080E-01
1.840601E-01
1.753151E-01
2.449999E+02
1.800750E-01
1.855719E-01
1.768269E-01
2.459999E+02
1.815479E-01
1.870899E-01
1.783449E-01
2.469999E+02
1.830269E-01
1.886140E-01
1.798690E-01
2.479999E+02
1.845120E-01
1.901444E-01
1.813994E-01
2.489999E+02
1.860029E-01
1.916809E-01
1.829359E-01
2.499999E+02
1.875000E-01
1.932236E-01
1.844786E-01
2.509999E+02
1.890030E-01
1.947725E-01
1.860275E-01
2.519999E+02
1.905120E-01
1.963275E-01
1.875825E-01
2.529999E+02
1.920270E-01
1.978888E-01
1.891438E-01
2.539999E+02
1.935480E-01
1.994562E-01
1.907112E-01 _________________ Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month! |
|
|
|
|
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
|