Ashkan Ziabakhshdeylami

Floating point division problems

Discussion created by Ashkan Ziabakhshdeylami on May 27, 2010
Latest reply on Jun 9, 2010 by bigmac


In the following code, the simple division creat problems with the counter. It seems there is a spill over of the division into other parts of memory.  In other terms, there is a memory leak, and memory spill over.


I have had this problem many other times with the Codewarrior for HCS08 compiler. If you are lucky you can see the other non related variables change when a division is executed. (Spill over to other parts of memory)

In the following specific example, the line of    filteredI = 0.996*(lastFilteredI+sampleI-lastSampleI);  , changes the counter  n to zero ) So the loop never ends


I played with the code a bit, and increased the stack size. There is no spill over anymore, however the following line reset the MCU:  Vrms = VCAL*sqrt(sumV / numberOfSamples);


The code is a  good sample for ADC conversions...


Let me know if you guys have any insight to the problem....

//Calibration coeficients
//These need to be set in order to obtain accurate results
double VCAL = 1.0;
double ICAL = 1.0;
double PHASECAL = 2.3;

//Sample variables
int lastSampleV,lastSampleI,sampleV,sampleI;

//Filter variables
double lastFilteredV, lastFilteredI, filteredV, filteredI;
double filterTemp;

//Stores the phase calibrated instantaneous voltage.
double calibratedV;

//Power calculation variables
double sqI,sqV,instP,sumI,sumV,sumP;

//Useful value variables
double realPower,
int n;

//Setup variables
#define numberOfSamples  3000
void main(void)
  /* Write your local variable definition here */
  unsigned char i;
  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
  /*** End of Processor Expert internal initialization.                    ***/

  /* Write your code here */
  /* For example: for( ; ; ) { } */
  if ( xbee_SetCommandMode() != false )
    xbeeResponse = xbee_SendCommand("ATPL4\r");
    for (n=0; n<numberOfSamples; n++)

       //Used for offset removal
       //Read in voltage and current samples.   
        while ( AD1_Measure(TRUE) !=ERR_OK )
        if (  AD1_GetValue16((unsigned int *) &ADC_Values) != ERR_OK )  
       sampleV = ADC_Values[VAC_ADC];
       sampleI = ADC_Values[I1AC_ADC];
       //Used for offset removal
       lastFilteredV = filteredV;
       lastFilteredI = filteredI;
       //Digital high pass filters to remove 2.5V DC offset.
       filteredV = 0.996*(lastFilteredV+sampleV-lastSampleV);
       filteredI = 0.996*(lastFilteredI+sampleI-lastSampleI);
       //Phase calibration goes here.
       calibratedV = lastFilteredV + PHASECAL * (filteredV - lastFilteredV);
       //Root-mean-square method voltage
       //1) square voltage values
       sqV= calibratedV * calibratedV;
       //2) sum
       sumV += sqV;
       //Root-mean-square method current
       //1) square current values
       sqI = filteredI * filteredI;
       //2) sum
       sumI += sqI;

       //Instantaneous Power
       instP = calibratedV * filteredI;
       sumP +=instP;

    //Calculation of the root of the mean of the voltage and current squared (rms)
    //Calibration coeficients applied.
    Vrms = VCAL*sqrt(sumV / numberOfSamples);
    Irms = ICAL*sqrt(sumI / numberOfSamples);

    //Calculation power values
    realPower = VCAL*ICAL*sumP / numberOfSamples;
    apparentPower = Vrms * Irms;
    powerFactor = realPower / apparentPower;
    sendStr("\r\n realPower:");
    SendWordValue(realPower );

  /*** Don't write any code pass this line, or it will be deleted during code generation. ***/
  /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
  for(; ; ){}
  /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODI