I am trying to get DT's 16-bit averaging subroutine to work correctly. I created the attached code as a way to test it. As you can see from the code, it writes values at various locations in the code to EEPROM so that after each execution I can read the data from the EEPROM as a way to see what values are being created.
What I don't undestand and am asking for help from anyone on this forum is why the variable VALUE is always showing up as zero (EEPROM addresses 19 and 36). By the way I set up this test routine, starting with a decimal value of 35260 and incrementing it 6 times, the average stored in VALUE should be 35263...not zero.
Any help is appreciated on this.
Code:'***************************************************************** '* Name : TEST_AVERAGE2.BAS * '* Author : John R. Ellis * '* Notes : Adapted from code by Darrel Taylor * '* "This routine will keep a "Running Average. * '* Instead of adding a bunch of values together and then dividing* '* by the number of samples, it averages each sample into the * '* final result immediately. This eliminates the need for 32 bit * '* math. * '* To allow it to "Catch up" to large changes, set the FAspread * '* to an acceptable range. Simply place the new number in VALUE * '* and GoSub AVERAGE The Average will be returned into the same * '* variable VALUE." * '* Memory : 546 Words of program memory required * '***************************************************************** ADavg VAR WORD AvgCount CON 16 ' = Number of samples to average FAspread CON 1000 ' = Fast Average threshold +/- i VAR Byte ' Index for measurment loop pw VAR WORD ' Stores each pw measurment pw0 Var pw.BYTE0 ' LSB of pw value PW1 var PW.BYTE1 ' MSB of pw value range VAR WORD ' Stores calculated range value range0 VAR range.Byte0 ' LSB of range value range1 VAR range.Byte1 ' MSB of range value us_inch con 147 ' Scale factor converts sensor 147 microsecs to inches VALUE VAR WORD ' Stores average of measurements value0 VAR value.byte0 ' LSB of value value1 VAR value.byte1 ' MSB of value GOTO Main ' Jump over Subroutines ' -----------------{ Subroutines }---------------------------------------- Average_Single: 'Embedded use of Darrel Taylor's 16 bit averaging routine ' USE INTRUCTIONS: First, Select the sensor. ie. Sensor = Temperature ' then place the new number in VALUE and then GoSub AVERAGE_SINGLE. ' The Average will be returned into the same variable VALUE. IF Value = ADavg Then NoChange IF ABS (Value - ADavg) > FAspread OR Value < AvgCount Then FastAvg IF ABS (Value - ADavg) < AvgCount Then RealClose ADavg = ADavg - (ADavg/AvgCount) ADavg = ADavg + (Value/AvgCount) GoTo AVGok FastAvg: ADavg = Value GoTo AVGok RealClose: 'If averaging less than 8 samples, change AvgCount/4 to AvgCount/2. ADavg = ADavg - (ADavg/(AvgCount/2)) ADavg = ADavg + (Value/(AvgCount/2)) AVGok: Value = ADavg ' Put Average back into Value NoChange: Return '-------------------------------------- Main: 'DEFINE WRITE_USED 1 'Required if only writing WORD variables in version 2.6 pw = 35260 WRITE 32,pw ' Comment out for test only For i = 0 to 5 'PULSIN PORTA.4,1,pw ' Make 5 measurements from PW pin ' of transceiver into array pw(i) ' with running average in value pw = pw +1 ' Simulates pw measurement WRITE 34,pw ' Comment out for test only Value = pw WRITE 36,VALUE ' Comment out for test only 'Running average in value...Max pw = 20' = 240" = 35280 usec. Therefore 'pw, value, & range are 16 bit WORDs. GOSUB Average_Single NEXT WRITE 17,i ' Comment out for test only WRITE 19,VALUE ' Comment out for test only range = (Value / us_inch) +1 ' Convert value to range in inches (max 240) ' add 1 to account for division rounding. WRITE 21,range ' Store day's range in EEPROM location END




Bookmarks