cancel
Showing results for 
Search instead for 
Did you mean: 

PSoC 5, 3 & 1 MCU

New Contributor II
    I'm trying to calculate the average of all values in an array. The array values get loaded from a Measure() function (not shown) and array values are constantly updated to create a running average.   
   
        
   
    There is a for loop that sums the array values. Then I'm dividing the sum by the number of array values and printing result on LCD. My problem is when i place the division directly after the summing "for" loop, the division never takes place and I end up with FlightTimeAvg = FlightTimeSum. When i moved the division line after a couple of LCD instructions I get the proper answer.   
   
        
   
    Does anyone have any ideas what could be going on?    
   
        
   
    Thanks   
   
    Aaron   
   
        
   
        
   
        
   
        
   
        
   
        
   
    while(1)        
   
     {   
   
     // Clear LCD screen   
   
     LCD_Position(0,0);          
   
     LCD_PrCString ("                ");   
   
     LCD_Position(1,0);   
   
     LCD_PrCString ("                ");   
   
        
   
     // Print "Calculating" on row 1   
   
     LCD_Position(0,0);     
   
     LCD_PrCString ("Calculating...");   
   
               
   
     // Reset Tick counter   
   
     Tick = 0;        
   
        
   
     // Delay   
   
     while(Tick < 40);   
   
        
   
     // Call Measure function   
   
     FlightTime = Measure();   
   
        
   
        
   
     // Calculate sum of FlightTime array   
   
     FlightTimeSum = 0;   
   
        
   
     for (j = 0; j < Samples; j++)   
   
     {   
   
     FlightTimeSum += FlightTime;   
   
     }   
   
        
   
     //Calculate average of array, when placed immediatelyhere   
   
     //after summing routine, the division does not   
   
     //take place and I end up with FlightTimeAvg = FlightTimeSum   
   
     //FlightTimeAvg = FlightTimeSum / Samples;   
   
        
   
     // Clear LCD row 1   
   
     LCD_Position(0,0);          
   
     LCD_PrCString ("                ");   
   
        
   
     // Print "Done" on row 1   
   
     LCD_Position(0,0);   
   
     LCD_PrCString ("Done");        
   
        
   
     //Calculate average of array, when placed here division takes    
   
     //place and get expected result   
   
     FlightTimeAvg = FlightTimeSum / Samples;   
   
        
   
        
   
     // Print FlightTime on row 2   
   
     LCD_Position(1,0);                  
   
     csprintf(LCDBuffer, "%u    ", FlightTimeAvg);   
   
     LCD_PrString(LCDBuffer);   
   
        
   
        
   
        
   
     // Reset Tick counter   
   
     Tick = 0;   
   
        
   
     // Delay   
   
     while(Tick < 40);   
   
        
   
     i++;   
   
     if (i == Samples)   
   
     {   
   
     i = 0;   
   
     }   
   
        }   
   
    }   
0 Likes
Reply
10 Replies
Esteemed Contributor

Not being able to see the entire code -

   

 

   

1)  FlightTimeAvg large enough it never overflows ?

   

 

   

2) Samples is a variable, not a def, so that it does not get optimized out ?

   

 

   

3) The avg right after for() should be ok.....not sure why its behaving sensitive

   

to position.....

   

 

   

4) Measure() incing i for the array reference ? Then is i global, therefore subject

   

to other f()'s modification ?

   

 

   

5) All globals used in ISRs declared volatile ?

   

 

   

6) Samples ever == 1 ? Or flightime all samples equal, such that avg = sum of al

   

flight times....?

   

 

   

    

   

         

   

http://www.barrgroup.com/Embedded-Systems/How-To/C-Volatile-Keyword    Volatile

   

 

   

 

   

 

   

Regards, Dana.

0 Likes
Reply
New Contributor II

Dana

   

 

   

1)  FlightTimeAvg large enough it never overflows ?

   

FlightTime array gets filled with values around 500. So FlightTimeSum ends up around 5000 and FlightTimeAvg around 500. These three variables are defined as unsigned int (WORD)

   

 2) Samples is a variable, not a def, so that it does not get optimized out ?

   

 I've tried Samples as both a variable and constant. Same result

   

3) The avg right after for() should be ok.....not sure why its behaving sensitive

   

to position..... odd indeed

   

4) Measure() incing i for the array reference ? Then is i global, therefore subject

   

to other f()'s modification ?

   

"i" is only used by main function, Measure function doesn't reference array

   

 

   

5) All globals used in ISRs declared volatile ?

   

 The variables Pulses, Tick, and CompleteFlag are volatile and are just incremented by Timer1, Timer2, and Comparator ISR's relatively

   

6) Samples ever == 1 ? Or flightime all samples equal, such that avg = sum of al

   

flight times....? I loaded the array intially with non zero values, samples is never 1 and avg should never equal sum

   

   

I've attached the full code minus ISR's. I'm using C29466 with CY3210 development board.

   

I can actually just use the sum value to represent a running average and just eliminate the division altogether. But I wanted to try and understand why I'm seeing these issues.

   

Thanks

   

Aaron

0 Likes
Reply
Anonymous
Not applicable

Does it work if you use a magic-number 10 instead of the Samples variable?

0 Likes
Reply
New Contributor II

 Using number 10 doesn't work either. If I make sample size 4 or less it works which is strange. But if I multiple by .1 instead of dividing by 10 it works fine. 

0 Likes
Reply
Esteemed Contributor

I do not see the interrupt code I assume you are using for delays.

   

 

   

Best to post the project archive.

   

 

   

    

   

          

   

“File”                                                           Designer

   

“Archive Project”

   

 

   

Regards, Dana.

0 Likes
Reply
Moderator
Moderator

 I have tried to reproduce this issue, but am unable to do so. You can try by increasing the size of LCDBuffer to 16. If that does not work, you have the option of creating a Technical Support case. To do so:

   

www.cypress.com

   

“Support & Community”

   

“Technical Support”

   

“Create a MyCase”

   

 

   

Also attach a minimal project which can reproduce this issue.

   

 

   

Thanks,

   

Sampath

0 Likes
Reply
New Contributor II

Here's the full archive Dana asked for. I'll see if i can replicate with a simplified program.

0 Likes
Reply
New Contributor II

In my Measure() function I was trying to read the timer1 count using below command. I initially removed the line altogether and my calculations were working as expected.

   

readTimer = Timer1_bReadTimerSaveCV();

   

Then I added the line back in but changed it to Timer1_bReadTimer(); and still working fine.

   

Is there any reason the bReadTimerSaveCV() api could cause issues vs bReadTimer()?

   

Aaron

0 Likes
Reply
Esteemed Contributor

I am at remote site, so w/o ice cube. But I noticed following -

   

 

   

1) Set up global properties with high analog power. I do not know

   

what your input signal looks like but start here. Analog power, opamp

   

bias, column buffer.....

   

 

   

   

 

   

2) Your comparator not configed with hysteresis, generally a good idea

   

to do that, especially in light of your using it to generate an isr.

   

 

   

Regards, Dana.

0 Likes
Reply
Esteemed Contributor

With regard to your read timer f()'s, when a read is done that is

   

captured into the compare register, and then read. The Save CV

   

f() restores the compare value.

   

 

   

Would this affect you ? It could produce a compare out to the pin

   

that is always high, is that what you want ? This is if a read of the

   

time always produced a full scale (period) value, as if timer was not

   

getting clocked between isr firings.

   

 

   

Regards, Dana.

0 Likes
Reply