It seems that I can't add elements of an array using 18F26k22 chip here the snippet:
Inc bIndex
Continuous_Deriv[bIndex] = New_Derivative
Total_deriv = Continuous_Deriv[0] + Continuous_Deriv[1] + Continuous_Deriv[2]
If bIndex = 3 Then bIndex = 0
Average = Total_deriv /3
How to add elements of an array?
Yves
I also tried
Total_deriv = Continuous_Deriv[1] + Continuous_Deriv[2] + Continuous_Deriv[3]
still come with an error.
my variables are:
Dim Continuous_Deriv[3] As Word
Dim Total_deriv As Dword
Dim Average As Word
Dim bIndex As Byte ' Create a Byte variable
Yves
You beat me too it 8100xt2. :-)
Incrementing bIndex there, will make the array always being loaded starting at element 1, not element 0. Also, you are accumulating and averaging elements of the array that have not been filled yet. That simple type of averageing does not like extremes in the samples take because it uses a simple division. So any of the elements that hold a value that is too far from the required value, and e spacially a value of 0, will cause the division to be incorrect.
Ok the following works:
Dim bIndex As Byte
Dim Total_deriv As Float
Dim average As Float
Dim New_Derivative As Word
Dim Continuous_Deriv[4] As Word
Inc bIndex
Continuous_Deriv[bIndex] = New_Derivative
Total_deriv = Continuous_Deriv[1] + Continuous_Deriv[2] + Continuous_Deriv[3]
If bIndex = 3 Then bIndex = 1
average = Total_deriv /3
My question is why do I have to declare 4 elements in "Continuous_Deriv[4] As Word" when I use only 3? If I dim like:
Dim Continuous_Deriv[3] As Word
I get a "not enough array elements for an index of 3". That is not very intuitive.
Yves
Below is a very simple method of averaging, but it does show the principle of accumulation and division for averaging:
'
' /\\\\\\\\\
' /\\\///////\\\
' \/\\\ \/\\\ /\\\ /\\\
' \/\\\\\\\\\\\/ /\\\\\ /\\\\\\\\\\ /\\\\\\\\ /\\\\\\\\\\\ /\\\\\\\\\\\ /\\\\\\\\\
' \/\\\//////\\\ /\\\///\\\ \/\\\////// /\\\/////\\\ \////\\\//// \////\\\//// \////////\\\
' \/\\\ \//\\\ /\\\ \//\\\ \/\\\\\\\\\\ /\\\\\\\\\\\ \/\\\ \/\\\ /\\\\\\\\\\
' \/\\\ \//\\\ \//\\\ /\\\ \////////\\\ \//\\/////// \/\\\ /\\ \/\\\ /\\ /\\\/////\\\
' \/\\\ \//\\\ \///\\\\\/ /\\\\\\\\\\ \//\\\\\\\\\\ \//\\\\\ \//\\\\\ \//\\\\\\\\/\\
' \/// \/// \///// \////////// \////////// \///// \///// \////////\//
' Let's find out together what makes a PIC Tick!
'
' Demonstrate a simple average method using accumulation and division
'
' Written for the Positron8 compiler by Les Johnson.
'
Device = 18F25K20 ' Tell the compiler what device to compile for
Declare Xtal = 16 ' Tell the compiler what frequency the device will be operating at (in MHz)
'
' Setup USART1
'
Declare Hserial1_Baud = 9600 ' Set the Baud rate to 9600
Declare HRSOut1_Pin = PORTC.6 ' Set the TX pin
'
' Create any variables for the demo here
'
Dim DemoData As Flash16 = 20000, 10000, 40000, 30000, 50000, 60000 ' A table of data to simulate values being loaded into the array to be averaged
Dim Global_wMyArray[6] As Word ' Create an array to holds the values to be averaged
Dim Global_wAverage As Word ' Holds the average of the array elements sampled
Dim bSamples As Byte ' Holds the samples index
'-------------------------------------------------------------------------
' The main program starts here
' Take some samples and average them.
'
Main:
For bSamples = 0 to 4 ' Create a loop for the values to be sampled
Global_wMyArray[bSamples] = Cread16 DemoData[bSamples] ' Place the demo samples into the array for averaging
If Get_Average() = 1 Then ' Get an average, and is an average ready?
HRsoutLn Dec Global_wAverage ' Yes. So display the average, which is 30000 using array elements, 0, 1, 2, 3 and 4 of the above array
EndIf
Next ' Close the loop
'-------------------------------------------------------------------------
' Accumulate the elements of an array and take a simple average value from them
' Input : Array: Global_wMyArray holds the samples to average
' Output : Will return 1 when an average value is ready
' : Global variable: Global_wAverage will hold the averaged value
' Notes : None
'
Proc Get_Average(), Bit
Static Dim dAccum As Dword = 0 ' Holds the accumulated value
Static Dim bIndex As Byte = 0 ' Holds the index of the array to be averaged
Static Dim tReady As Bit = 0 ' Holds 1 when the average is available
dAccum = dAccum + Global_wMyArray[bIndex] ' Accumulate the elements of the array
Inc bIndex ' Increment the element index
If bIndex = 5 Then ' Have enough accumulations taken place?
dAccum = dAccum / 5 ' Yes. So divide the accumulated value by the amount of array elements sampled
Global_wAverage = dAccum ' Load the global variable with the average value
bIndex = 0 ' Reset the element index
tReady = 1 ' Make the return value 1
EndIf
Result = tReady ' Return the state of tReady
EndProc
Once the averaging array is pre-filled, the Get_Average() procedure will always return 1 and the average will be ready, but in the demo program, it just fills the array with the flash memory table's data then gets an average then stops.
well 8100xt2 that the issue I had if I declare the array with 3 elements I get that error: "Not enough array elements for an index of 3".
Looking at the manual it looks that when you dim an array like "Dim MyWordArray[10] as Word ' Create a 10 element unsigned word array" I get an array of 10 elements and not 11. My understanding is MyWordArray[0] is not allowed.
Yves
I have ran some tests and cannot see a problem. For example:
Dim wMyArray[3] As Word ' Create an unsigned 16-bit array that contains 3 elements
wMyArray[0] = 100 ' Load the first element of the array with the value 100
wMyArray[1] = 200 ' Load the second element of the array with the value 200
wMyArray[2] = 300 ' Load the third element of the array with the value 300
Remember, an array's elements start at 0. So element indexes of 0 to 2 fill an array that has been created with 3 elements.
Les,
Thank you for the clarification. Now it works fine. I was confuse on the manual where it is stated Dim MyWordArray[10] as Word ' Create a 10 element unsigned word array" So in fact it is 11 elements,11 elements if you include the 0
Regards,
Yves
ok