Page 199 - Build Your Own Quadcopter_ Power Up Your Designs with the Parallax Elev-8
P. 199
178 Bu il d Y o ur O w n Q u a d c o p t e r
these variable locations. Also, note that it was declared in a VAR block. The memory location
variable reference is simply the name pulsewidth prepended with the “@” symbol. So
using @pulsewidth tells the program to either store or read data beginning at that location.
It is important to state that you should never use an actual physical memory address but
simply use the logical reference name or pointer.
The next reference, named pins, also has four “LONG” word elements. Notice that the
word "LONG" was capitalized in this declaration. This was a purely optional choice and was
done to indicate that the pins array is constant and cannot be overwritten. The pins array
was declared in a DAT block, meaning that it is data. It is a read-only data array. You certainly
would not want to dynamically change the pin designations for your input channels.
However, it can be referred to as pins, just as the pulsewidth array may be referred to as
pulsewidth.
The following method call in the RX_demo tells the start method in the RX object where
to find the data regarding the input pins and also where to store the pulse-width data
corresponding to those pins. Note the indirection used in the arguments.
RX.start(@pins,@pulsewidth)
The Spin compiler is quite elegant and advanced, since it will automatically create the
appropriate reference type based upon the contextual use. The start method signature is
shown below:
PUB start(pins_array_address, pulsewidth_array_address)
The RX.start method call in RX_demo uses @pins and @pulsewidth to pass the
starting array addresses. These are copied into the pins_address and the pulsewidth_
address arguments respectively, making them pointers, since they contain addresses not
real data. In C and C++, these arguments would have to be separately declared as pointers;
however, Spin does it for you as needed. This is a very nice feature.
One more point before I get off my tangent regarding data indirection and pointers.
Pointers can be treated as normal data; for example, assigned to other pointer variables or
having simple arithmetic operations applied to them. The key point to remember is if you
add 1 to a pointer, you are not incrementing the physical address but instead are instructing
the compiler to use the next logical element in the memory storage area. Using the start
method as an example:
pins_array_address = start of the pins array
= address of pins[0]
= actual value of 14
Now add 1 to pins_array_address and we get:
pins_array_address + 1 = address of pins[1]
= actual value of 15
From my teaching experience, I have learned that pointers and indirection have often
been difficult concepts for beginners to understand. This is the reason why I presented such
a detailed discussion regarding this somewhat complex topic. You really should understand
this material in order to get the most from the software development whether you are using
Spin, C/C++, or any other language that uses these concepts.