diff options
Diffstat (limited to 'source/lang')
100 files changed, 6891 insertions, 0 deletions
diff --git a/source/lang/abs.rst b/source/lang/abs.rst new file mode 100644 index 0000000..ed95e6f --- /dev/null +++ b/source/lang/abs.rst @@ -0,0 +1,42 @@ +.. _lang-abs: + +abs(x) +====== + +Description +----------- + +(Macro) computes the absolute value of a number. + +Parameters +---------- + +**x**: the number. + +Returns +------- + +**x**: if **x** is greater than or equal to 0. + +**-x**: if **x** is less than 0. + +Warning +------- + +Because of the way ``abs()`` is implemented, avoid using other +functions or causing side effects inside the parentheses, as it may +lead to incorrect results:: + + abs(a++); // avoid this - yields incorrect results + + abs(a); // use this instead - + a++; // keep other operations outside abs() + + +Arduino Compatibility +--------------------- + +Maple's implementation of ``abs()`` is compatible with Arduino. + + +.. include:: cc-attribution.txt diff --git a/source/lang/analogread.rst b/source/lang/analogread.rst new file mode 100644 index 0000000..0c93650 --- /dev/null +++ b/source/lang/analogread.rst @@ -0,0 +1,152 @@ +.. highlight:: cpp + +.. _lang-analogread: + +analogRead() +============ + +Used to perform ADC conversion. + +.. contents:: Contents + :local: + +Library Documentation +--------------------- + +.. doxygenfunction:: analogRead + +Discussion +---------- + +Reads the value from the specified analog pin. The Maple board +contains a 16-channel, 12-bit analog to digital converter. This means +that it will map input voltages between 0 and 3.3 volts into integer +values between 0 and 4095. This yields a resolution between readings +of 3.3V / 4096 units, or 0.8 millivolts. However, a number of factors +interfere with getting full accuracy and precision. For more +information, see :ref:`adc`. + +Before calling analogRead() on a pin, that pin must first be +configured for analog input, using :ref:`lang-pinMode` (you only +have to do this once, so it's usually done in :ref:`lang-setup`\ ). + +It takes about 0.8 microseconds (.0000008 seconds) to read an analog +input, so the maximum sample rate using this function is approximately +1.3 million samples per second\ [#fsamp]_. + + +Parameter Discussion +-------------------- + +The pin parameter is the number of the analog input pin to read from. +Header pins on the Maple with ADC functionality (marked as "AIN" on +the silkscreen) are: + + 0, 1, 2, 3, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 27, 28 + +Note that pins 3, 27, and 28 are not marked AIN on the silkscreen +for Maple revisions through Rev 5, however, they **do work** as +analog input pins. + +Note +---- + +If the analog input pin is not connected to anything, the value +returned by analogRead() will fluctuate based on a number of factors +(e.g. the values of the other analog inputs, how close your hand is to +the board, etc.) in a seemingly random way. + + +Example +------- + + :: + + + int analogPin = 3; // potentiometer wiper (middle terminal) connected + // to analog pin 3. outside leads to ground and +3.3V + int val = 0; // variable to store the value read + + void setup() { + pinMode(analogPin, INPUT_ANALOG); // set up pin for analog input + SerialUSB.begin(); // set up usb virtual COM port + } + + void loop() { + val = analogRead(analogPin); // read the input pin + SerialUSB.println(val); // print the value, for debugging with + // a serial monitor + } + + +Arduino Compatibility +--------------------- + +The Arduino board contains a 6 channel (8 channels on the Mini and +Nano, 16 on the Mega), 10-bit analog to digital converter with an +input voltage range of 0V--5V. This means that it will map input +voltages between 0 and 5 volts (which is **larger** than Maple's range +of 0V-3.3V) into integer values between 0 and 1023 (which is +**smaller** than the Maple's range of 0--4095). + +This yields a theoretical resolution between readings of: 5 volts / +1024 units or .0049 volts (4.9 mV) per unit on Arduino boards, which +is larger, and thus less precise, than Maple's 0.0008 volts (0.8 mV). + +If your program expects Arduino-style 10-bit ADC, you can :ref:`right +shift <lang-bitshift>` the value of a Maple readout by 2, like so:: + + // right shift means that the result will be between 0 and 1023; + // be aware that you're losing a lot of precision if you do this + int adc_reading = analogRead(pin) >> 2; + +On the Arduino, the input range and resolution can be changed using +their implementation of `analogReference() +<http://arduino.cc/en/Reference/AnalogReference>`_\ . Because of the +way its hardware (as of Rev 5) was designed, it's not possible to +implement analogReference on the Maple, so this function doesn't +exist. If your inputs lie in a different voltage range than 0V--3.3V, +you'll need to bring them into that range before using analogRead. +Some basic tools to accomplish this are `resistor dividers +<http://en.wikipedia.org/wiki/Voltage_divider>`_ and `Zener diodes +<http://en.wikipedia.org/wiki/Voltage_source#Zener_voltage_source>`_\ +. However, opamps and other powered components can also be used if +greater precision is required. + +Finally, On the Arduino, it takes significantly longer to read analog +input: about 100 microseconds (0.0001 s), so the maximum reading rate +is 10,000 times a second. + + +See also +-------- + +- :ref:`ADC note <adc>` +- `(Arduino) Tutorial: Analog Input Pins <http://arduino.cc/en/Tutorial/AnalogInputPins>`_ + + +.. rubric:: Footnotes + +.. [#fsamp] This is based on the current configuration of a 55.5 cycle + sample time, at 72 MHz. However, the minimum sample time *possible* + is 1.5 cycles, leading to a theoretical maximum of approximately 48 + million samples per second (of course, doing anything with the + readings also consumes cycles, so this maximum can't be reached in + practice). + + See the `STM32 Reference Manual <full-manual>`_, §§11.12.4--5 + (pp. 225--226), for more information on the low-level bit twiddling + currently necessary to change the sample time. For examples of how + the ADCs are configured in libmaple, see `adc.h + <http://github.com/leaflabs/libmaple/blob/master/libmaple/adc.h>`_ + and `adc.c + <http://github.com/leaflabs/libmaple/blob/master/libmaple/adc.c>`_\ + . Be aware that changing the sample time has important + consequences related to the impedance of the device connected to + the input pin. If you want to make changes, as a minimum, you + should first read ST's application notes on `ADC modes + <stm32-adc-modes>`_ and `ADC oversampling + <stm32-adc-oversampling>`_. + + +.. include:: cc-attribution.txt diff --git a/source/lang/analogwrite.rst b/source/lang/analogwrite.rst new file mode 100644 index 0000000..d30d4d9 --- /dev/null +++ b/source/lang/analogwrite.rst @@ -0,0 +1,164 @@ +.. highlight:: cpp + +.. _lang-analogwrite: + +analogWrite() +============= + +.. note:: + + On the Maple, calling analogWrite() is the same as calling + :ref:`lang-pwmwrite`\ ; see that function's documentation for more + information. + + This is because PWM is not true analog output (i.e., is not the + output of a `DAC + <http://en.wikipedia.org/wiki/Digital-to-analog_converter>`_\ ), so + the function is badly named. For instance, **analogWrite() has + absolutely nothing to do with** :ref:`lang-analogread`\ , which is + potentially confusing. + + The alias of analogWrite() to pwmWrite() is provided (sigh) for the + sake of compatibility with Arduino, but we recommend using + :ref:`lang-pwmwrite` when writing new software, for clarity. + +.. contents:: Contents + :local: + +Arduino Compatibility +--------------------- + +There are a few important differences between Arduino's `analogWrite() +<http://arduino.cc/en/Reference/AnalogWrite>`_ and Maple's +:ref:`lang-pwmwrite` that you should keep in mind. In each case, we +have some recommendations you can use to help converting from Arduino +to Maple. + +Difference 1: Duty cycle range is different +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The first and most important difference is that the largest possible +value for the duty cycle is much bigger on the Maple. Using Arduino's +analogWrite(), the duty cycle ranges between 0--255 (always off -- +always on)\ [#fbytemax]_\ . Using Maple's pwmWrite(), the duty cycle +ranges from 0--65,535 by default\ [#fuint16max]_\ . + +This is a good thing! The greater range of values on the Maple gives +you much more precise control over the duty cycle of your PWM output. + +If you're porting code from the Arduino and want a quick-and-dirty +fix, one solution is to :ref:`map <lang-map>` the argument to +analogWrite into the right range:: + + // Arduino code: + analogWrite(pin, duty); + + // Becomes Maple code: + analogWrite(pin, map(duty, 0, 255, 0, 65535)); + +This will convert values in the range 0-255 to values in the range +0--65,635, which is the correct default range for all of the timers +which control PWM output. See the :ref:`timers reference <timers>` +for more information. + +Another fix is to consult the :ref:`pin mapping mega table +<pin-mapping-mega table>` to find the timer which controls PWM on the +pin you're using, then set that Timer's overflow to 255. Subsequent +calls to analogWrite() should work as on the Arduino (with the same +loss of precision). Note, however, that that affects the overflow for +the **entire timer**, so other code relying on that timer (such as any +:ref:`interrupts <lang-attachinterrupt>` the timer controls) will +likely need to be modified as well. + +Difference 2: You must use pinMode() to set up PWM +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The second difference is that on the Maple, you **must** set up the pin +for PWM output using :ref:`lang-pinmode`\ , with argument ``PWM``. +This should just be one extra line of code in your +:ref:`lang-setup` function. Example:: + + void setup() { + // set up pin 9 for PWM + pinMode(9, PWM); + } + +This also means that you can't later call :ref:`lang-digitalread` +or :ref:`lang-digitalwrite` on that pin (unless some time in +between, you use pinMode() to reconfigure that pin for ``INPUT`` or +``OUTPUT``; see the :ref:`lang-pinmode` page for more information). + +Difference 3: No PWM on pin 10 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +On the Maple, the pins which support PWM are: 0, 1, 2, 3, 5, 6, 7, 8, +9, 11, 12, and 14, or twelve pins in total. That is at least as +*many* PWM pins as any Arduino board, but there are differences in +*which* pins support it. + +* On **most Arduino boards** (those with the ATmega168 or ATmega328; + this includes the **Arduino Uno**), this function works on pins 3, + 5, 6, 9, 10, and 11, or six pins total. Note that these boards + support PWM on pin 10, while Maple does not. + +* On the **Arduino Mega**, PWM works on pins 2 through 13, or twelve pins + total. Note that this board supports PWM on pins 4, 10, and 13, + while the Maple does not. Maple supports PWM on pins 0, 1, and 14, + which the Mega does not, making the total number of pins supporting + PWM equal on these boards. + +* **Older Arduino boards** with an ATmega8 only support analogWrite() on + pins 9, 10, and 11. Maple does not support PWM on pin 10. + +In all cases, Arduino boards support PWM on pin 10, unlike Maple. We +did our best to make PWM as pin-compatible as possible; however, +circuit layout constraints prevented us from achieving perfect +compatibility. + +The "safest" pins to use for PWM output are pins 9 and 11. These pins +work on any Arduino board and on Maple. The "safe" pins, which work +on most recent Arduino boards, the Arduino Mega and the Maple, are +pins 3, 5, 6, 9, and 11. Thus, if you want your project to be as +portable as possible between Maple and Arduino, we recommend using the +"safest" pins first, then the "safe" pins, as necessary. + +Difference 4: PWM frequency +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The frequency of the PWM signal (i.e., the frequency of a complete +on/off cycle) on the Arduino is approximately 490 Hz. + +On the Maple, the frequency is configurable, defaulting to about 1100 +Hz, or 1.1 KHz. This is because the PWM frequency is the frequency of +the timer which controls PWM output on the particular pin (\ +:ref:`the PWM tutorial has the details <pwm>`\ ). + +If your application absolutely requires Arduino's PWM frequency (it +probably doesn't), then the steps are: + +1. Figure out which timer controls PWM output on your pin (\ :ref:`this table <pwm-timer-table>` is your friend here). Let's say it's ``Timern``\ , where ``n`` is some number 1, 2, 3, or 4. + +2. Call ``Timern.setPeriod(2041)``\ . This will set the timer's period to approximately 2041 microseconds, which is a frequency of approximately 490 Hz. + +Be aware that this will change the period for the **entire timer**\ , +and will affect anything else in your program that depends on that +timer. One example is :ref:`interrupts <timers-attachinterrupt>`\ . +You've been :ref:`warned <timers-pwm-conflicts>`\ . + +See also +-------- + +- :ref:`Maple PWM tutorial <pwm>` + +.. rubric:: Footnotes + +.. [#fbytemax] This is because the value for the duty cycle on Arduino + must fit in 1 byte of memory, and an unsigned (i.e., nonnegative) + integer with size 1 byte can hold the values between 0 and 255. + +.. [#fuint16max] This is because the value for the duty cycle on the + Maple uses 2 bytes of memory, and an unsigned (i.e., nonnegative) + integer with size 2 bytes can hold the values between 0 and 65,535. + + +.. include:: cc-attribution.txt diff --git a/source/lang/arithmetic.rst b/source/lang/arithmetic.rst new file mode 100644 index 0000000..9f21627 --- /dev/null +++ b/source/lang/arithmetic.rst @@ -0,0 +1,129 @@ +.. highlight:: cpp + +.. _lang-arithmetic: + +Addition, Subtraction, Multiplication, & Division +================================================= + +.. contents:: Contents + :local: + +Description +----------- + +These operators return the sum, difference, product, or quotient +(respectively) of the two operands. The operation is conducted using +the data type of the operands, so, for example, ``9 / 4`` gives ``2`` +since 9 and 4 are :ref:`int variables <lang-int>`. + +This also means that the operation can overflow if the result is +larger than that which can be stored in the data type (e.g. adding 1 +to an :ref:`lang-int` with the value 2147483647 gives +-2147483648). If the operands are of different types, the "larger" +type is used for the calculation. + +.. _lang-arithmetic-typeconversion: + +.. note:: The specifics of these rules are beyond the scope of this + documentation; for more information, see `The C++ Programming + Language <http://www2.research.att.com/~bs/3rd.html>`_\ , by Bjarne + Stroustroup, Appendix C, especially §§C.4-C.6, or `this WikiBooks + entry on C++ type conversion + <http://en.wikibooks.org/wiki/C%2B%2B_Programming/Programming_Languages/C%2B%2B/Code/Statements/Variables/Type_Casting#Automatic_type_conversion>`_. + +.. note:: For more information on how computers represent integers, + see the Wikipedia page on `two's complement + <http://en.wikipedia.org/wiki/Two's_complement>`_. + +If one of the numbers (operands) are of the type **float** or of type +**double**, floating point math will be used for the +calculation. + +Examples +-------- + + :: + + y = y + 3; + x = x - 7; + i = j * 6; + r = r / 5; + + +Syntax +------ + + :: + + result = value1 + value2; + result = value1 - value2; + result = value1 * value2; + result = value1 / value2; + + +Parameters +---------- + +**value1**: any numeric variable or constant + +**value2**: any numeric variable or constant + +Programming Tips +---------------- + +- Know that :ref:`integer constants <lang-constants-integers>` + default to :ref:`int <lang-int>`, so some constant calculations + may overflow (e.g., 200000 * 5000000 will yield a negative result). + +- Choose variable sizes that are large enough to hold the largest + results from your calculations. + +- Know at what point your variable will "roll over" and also what + happens in the other direction e.g. (0 - 1) for unsigned arithmetic, + or (0 - -2,147,483,648) for signed arithmetic. + +- For math that requires fractions, float variables may be used, but + be aware of their drawbacks: large size and slow computation speeds + (the STM32 has no floating point hardware, so all floating point + calculations have to be done in software). + +- Use cast operator, e.g. ``(int)myFloat`` to convert one variable type + to another on the fly. + +Arduino Compatibility +--------------------- + +Since the STM32 processor on the Maple is a 32-bit machine, the int +type overflows at a much higher value on Maple than on Arduino. In +particular, on Maple, ints do not overflow (become negative) until +they reach 2,147,483,648; on the Arduino, they overflow at 32,767. +Because of this, programs running on Maple are much less likely to run +into overflow issues. The following table summarizes the sizes and +ranges of integer datatypes on the Maple (the ranges of long long +types are approximate): + +.. _lang-arithmetic-int-sizes: + +.. csv-table:: + :header: Datatype, Unsigned range, Signed range, Size (bytes) + :widths: 8, 12, 17, 8 + + ``char``, 0 --- 255, -128 --- 127, 1 + ``short``, "0 --- 65,535", "-32,768 --- 32,767", 2 + ``int``, "0 --- 4,294,967,295", "-2,147,483,648 --- 2,147,483,647", 4 + ``long``, "0 --- 4,294,967,295", "-2,147,483,648 --- 2,147,483,647", 4 + ``long long``, "0 --- 1.8*10\ :sup:`19`\ " (approx.), "-9.2*10\ :sup:`18` --- 9.2*10\ :sup:`18` (approx.)", 8 + + +See Also +-------- + +- The individual sizes (in bits) of various available types are + defined in `libmaple_types.h + <http://github.com/leaflabs/libmaple/blob/master/libmaple/libmaple_types.h>`_\ + . + +- :ref:`sizeof <lang-sizeof>`\ () + + +.. include:: cc-attribution.txt diff --git a/source/lang/arithmeticcompound.rst b/source/lang/arithmeticcompound.rst new file mode 100644 index 0000000..aa0dc18 --- /dev/null +++ b/source/lang/arithmeticcompound.rst @@ -0,0 +1,46 @@ +.. highlight:: cpp + +.. _lang-arithmeticcompound: + +Compound Arithmetic Operators (``+=`` , ``-=``, ``*=``, ``/=``) +=============================================================== + +Description +----------- + +Perform a mathematical operation on a variable with another constant +or variable. These operators are just a convenient shorthand:: + + x += y; // equivalent to the expression x = x + y; + x -= y; // equivalent to the expression x = x - y; + x *= y; // equivalent to the expression x = x * y; + x /= y; // equivalent to the expression x = x / y; + +Here is an example:: + + int x = 2; + int y = 10; + + x += 4; // x now contains 6 + x -= 3; // x now contains 3 + x *= y; // x now contains 30 + x /= 2; // x now contains 15 + x += max(20, 6); // x now contains 35 + x -= sq(5); // x now contains 15 + +Parameters +---------- + +**x**: a numeric variable + +**y**: a numeric variable, number constant, or any other expression +that evaluates to a number (e.g. call to a function that returns a +number). + +See Also +-------- + +- :ref:`Arithmetic operators <lang-arithmetic>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/array.rst b/source/lang/array.rst new file mode 100644 index 0000000..30a818f --- /dev/null +++ b/source/lang/array.rst @@ -0,0 +1,123 @@ +.. highlight:: cpp + +.. _lang-array: + +Arrays +====== + +An array is a collection of variables that are accessed with an index +number. Arrays in the C++ programming language, in which the Maple is +programmed, can be complicated, but using simple arrays is relatively +straightforward. + +.. contents:: Contents + :local: + +Creating (Declaring) an Array +----------------------------- + +All of the methods below are valid ways to create (declare) an +array. :: + + int myInts[6]; + int myPins[] = {2, 4, 8, 3, 6}; + int mySensVals[6] = {2, 4, -8, 3, 2}; + char message[6] = "hello"; + +You can declare an array without initializing it, as with myInts. In +the line referring to myPins, we declare an array without explicitly +choosing a size. The compiler counts the elements and creates an +array of the appropriate size. + +Finally, you can both initialize and size your array, as in +mySensVals. Note that when declaring an array with elements of type +char, one more element than your initialization is required, to hold +the required `null character <http://en.wikipedia.org/wiki/Null-terminated_string>`_. + + +Accessing an Array +------------------ + + +.. compound:: + + Arrays are **zero indexed**; that is, referring to the array + initialization above, the first element of the array is at index 0, + hence :: + + mySensVals[0] == 2; + mySensVals[1] == 4 + + and so forth. + +It also means that in an array with ten elements, index nine is the +last element. Hence:: + + int myArray[10]={9,3,2,4,3,2,7,8,9,11}; + // myArray[9] contains 11 + // myArray[10] is invalid and contains random information (other memory address) + +For this reason, you should be careful in accessing arrays. Accessing +past the end of an array (using an index number greater than your +declared array size - 1) is reading from memory that is in use for +other purposes. Reading from these locations is probably not going to +do much except yield invalid data. Writing to random memory locations +is definitely a bad idea, and can often lead to unhappy results such +as crashes or program malfunction. This can also be a difficult bug to +track down. + +Unlike Basic or Java, the C compiler does no checking to see if array +access is within legal bounds of the array size that you have +declared. + + +To assign a value to an array +----------------------------- + :: + + mySensVals[0] = 10; + + +To retrieve a value from an array +--------------------------------- + + :: + + x = mySensVals[4]; + + +Arrays and ``for`` Loops +------------------------ + +Arrays are often manipulated inside :ref:`for loops <lang-for>`, where +the loop counter is used as the index for each array element. For +example, to print the elements of an array over the serial port, you +could do something like this:: + + int i; + for (i = 0; i < 5; i = i + 1) { + SerialUSB.println(myPins[i]); + } + + +Example +------- + +For a complete program that demonstrates the use of arrays, see the +Arduino `Knight Rider example +<http://www.arduino.cc/en/Tutorial/KnightRider>`_\ (which will run +unmodified on the Maple). + +Arduino Compatibility +--------------------- + +Arrays on Maple are identical those on Arduino. + +See also +-------- + +- :ref:`Storing arrays in FLASH memory <arm-gcc-attribute-flash>` + + + +.. include:: cc-attribution.txt diff --git a/source/lang/assignment.rst b/source/lang/assignment.rst new file mode 100644 index 0000000..16f0bf4 --- /dev/null +++ b/source/lang/assignment.rst @@ -0,0 +1,70 @@ +.. highlight:: cpp + +.. _lang-assignment: + += assignment operator (single equal sign) +========================================= + +Stores the value to the right of the equal sign in the variable to +the left of the equal sign. + +The single equal sign in the C++ programming language is called the +assignment operator. It has a different meaning than in algebra +class, where it indicated an equation or equality. The assignment +operator tells the microcontroller to evaluate whatever value or +expression is on the right side of the equal sign, and store it in +the variable to the left of the equal sign [#fgross]_. + + + +Example +------- + +:: + + int sensVal; // declare an integer variable named sensVal + senVal = analogRead(0); // store the (digitized) input voltage at analog pin 0 in SensVal + + + +Programming Tips +---------------- + +The variable on the left side of the assignment operator ( = sign ) +needs to be able to hold the value stored in it. If it is not large +enough to hold a value, the value stored in the variable will be +incorrect. + +Don't confuse the assignment operator [ = ] (single equal sign) +with the comparison operator [ == ] (double equal signs), which +evaluates whether two expressions are equal. + + +Arduino Compatibility +--------------------- + +Assignments on the Maple are identical to those on Arduino. + + + +See Also +-------- + + +- `if (comparison operators) <http://arduino.cc/en/Reference/If>`_ +- `char <http://arduino.cc/en/Reference/Char>`_ +- `int <http://arduino.cc/en/Reference/Int>`_ +- `long <http://arduino.cc/en/Reference/Long>`_ + + +.. rubric:: Footnotes + +.. [#fgross] Experienced C++ programmers know this to be an + oversimplification of what happens when the variable on the left + hand side is an object. See Richard Gillam's wonderful and scary + `The Anatomy of the Assignment Operator + <http://icu-project.org/docs/papers/cpp_report/the_anatomy_of_the_assignment_operator.html>`_ + for more information. + + +.. include:: cc-attribution.txt diff --git a/source/lang/attachinterrupt.rst b/source/lang/attachinterrupt.rst new file mode 100644 index 0000000..0b8907f --- /dev/null +++ b/source/lang/attachinterrupt.rst @@ -0,0 +1,102 @@ +.. highlight:: cpp + +.. _lang-attachinterrupt: + +attachInterrupt() +================= + +Used to specify a function to call when an external interrupt (like an +GPIO changing from LOW to HIGH, a button getting pressed, etc.) +occurs. + +.. contents:: Contents + :local: + +Library Documentation +--------------------- + +.. doxygenfunction:: attachInterrupt + +.. doxygenenum:: ExtIntTriggerMode + +.. doxygentypedef:: voidFuncPtr + +Discussion +---------- + +Because the function will run in interrupt context, inside of it, +:ref:`lang-delay` won't work, and the value returned by +:ref:`lang-millis` will not increment. Serial data received while +in the function may be lost. You should declare as ``volatile`` any +global variables that you modify within the attached function. + +There are a few constraints you should be aware of if you're using +more than one interrupt at a time; the :ref:`external-interrupts` page +has the details. + + +Using Interrupts +---------------- + +Interrupts are useful for making things happen automatically in +microcontroller programs, and can help solve timing problems. A +good task for using an interrupt might be reading a rotary encoder, +or monitoring user input. + + +If you wanted to insure that a program always caught the pulses +from a rotary encoder, never missing a pulse, it would make it very +tricky to write a program to do anything else, because the program +would need to constantly poll the sensor lines for the encoder, in +order to catch pulses when they occurred. Other sensors have a +similar interface dynamic too, such as trying to read a sound +sensor that is trying to catch a click, or an infrared slot sensor +(photo-interrupter) trying to catch a coin drop. In all of these +situations, using an interrupt can free the microcontroller to get +some other work done while not missing the doorbell. + + +Example +------- + +:: + + int maple_led_pin = 13; + volatile int state = LOW; // must declare volatile, since it's + // modified within the blink handler + + void setup() { + pinMode(maple_led_pin, OUTPUT); + attachInterrupt(0, blink, CHANGE); + } + + void loop() { + digitalWrite(maple_led_pin, state); + } + + void blink() { + state = !state; + } + + +Arduino Compatibility +--------------------- + +Most Arduino boards have two external interrupts: numbers 0 (on +digital pin 2) and 1 (on digital pin 3). The Arduino Mega has an +additional four: numbers 2 (pin 21), 3 (pin 20), 4 (pin 19), and 5 +(pin 18). On the Maple, you don't have to remember which interrupt +number goes with which pin -- just tell ``attachInterrupt()`` the pin +you want. + + +See also +-------- + + +- :ref:`detachInterrupt <lang-detachinterrupt>` +- :ref:`external-interrupts` + + + +.. include:: cc-attribution.txt diff --git a/source/lang/bit.rst b/source/lang/bit.rst new file mode 100644 index 0000000..c342fdd --- /dev/null +++ b/source/lang/bit.rst @@ -0,0 +1,48 @@ +.. _lang-bit: + +bit() +===== + +Description +----------- + +(Macro) Computes the value of an (unsigned) integer with the specified +bit set (``bit(0)`` is 1, ``bit(1)`` is 2, ``bit(2)`` is 4, then 8, +16, 32, etc.). + + +Syntax +------ + +``bit(n)`` + + +Parameters +---------- + +* **n** the bit to set. + + +Value +----- + +The value of an integer with the given bit set. + + +Arduino Compatibility +--------------------- + +The Maple implementation of bit is compatible with Arduino. + + +See also +-------- + + +- :ref:`lang-bitread` +- :ref:`lang-bitwrite` +- :ref:`lang-bitset` +- :ref:`lang-bitclear` + + +.. include:: cc-attribution.txt diff --git a/source/lang/bitclear.rst b/source/lang/bitclear.rst new file mode 100644 index 0000000..5d1eb95 --- /dev/null +++ b/source/lang/bitclear.rst @@ -0,0 +1,47 @@ +.. _lang-bitclear: + +bitClear() +========== + +Description +----------- + +(Macro) Clears (writes a 0 to) a bit of a numeric variable. + +Syntax +------ + +``bitClear(x, n)`` + + +Parameters +---------- + +* **x** the numeric variable whose bit to clear + +* **n** which bit to clear, starting at 0 for the least-significant + (rightmost) bit + + +Returns +------- + +None. + + +Arduino Compatibility +--------------------- + +This implementation is compatible with that of Arduino. + + +See also +-------- + +- :ref:`bit <lang-bit>`\ () +- :ref:`bitRead <lang-bitread>`\ () +- :ref:`bitWrite <lang-bitwrite>`\ () +- :ref:`bitSet <lang-bitset>`\ () + + +.. include:: cc-attribution.txt diff --git a/source/lang/bitread.rst b/source/lang/bitread.rst new file mode 100644 index 0000000..9f885cf --- /dev/null +++ b/source/lang/bitread.rst @@ -0,0 +1,49 @@ +.. _lang-bitread: + +bitRead() +========= + +Description +----------- + +(Macro) Gets the value of a bit in a number. + + +Syntax +------ + +``bitRead(x, n)`` + + +Parameters +---------- + +* **x** the number from which to read the bit. + +* **n** which bit to read, starting at 0 for the least-significant + (rightmost) bit + + +Value +----- + +The value of the bit (0 or 1). + + +Arduino Compatibility +--------------------- + +The Maple implementation of ``bitRead`` is compatible with Arduino. + + +See also +-------- + + +- :ref:`lang-bit` +- :ref:`lang-bitwrite` +- :ref:`lang-bitset` +- :ref:`lang-bitclear` + + +.. include:: cc-attribution.txt diff --git a/source/lang/bitset.rst b/source/lang/bitset.rst new file mode 100644 index 0000000..502c1b6 --- /dev/null +++ b/source/lang/bitset.rst @@ -0,0 +1,49 @@ +.. _lang-bitset: + +bitSet() +======== + +Description +----------- + +(Macro) Sets (writes a 1 to) a bit of a numeric variable. + + +Syntax +------ + +``bitSet(x, n)`` + + +Parameters +---------- + +* **x** the numeric variable whose bit to set + +* **n** which bit to set, starting at 0 for the least-significant + (rightmost) bit + + +Value +----- + +None. + + +Arduino Compatibility +--------------------- + +The Maple implementation of bitSet is compatible with Arduino. + + +See Also +-------- + +- :ref:`lang-bit` +- :ref:`lang-bitread` +- :ref:`lang-bitwrite` +- :ref:`lang-bitclear` + + + +.. include:: cc-attribution.txt diff --git a/source/lang/bitshift.rst b/source/lang/bitshift.rst new file mode 100644 index 0000000..f05d49e --- /dev/null +++ b/source/lang/bitshift.rst @@ -0,0 +1,148 @@ +.. highlight:: cpp + +.. _lang-bitshift: + +Bit shift left (``<<``), bit shift right (``>>``) +================================================= + +Description +----------- + +(Adapted from `The Bit Math Tutorial +<http://www.arduino.cc/playground/Code/BitMath>`_ in `The Arduino +Playground <http://www.arduino.cc/playground/Main/HomePage>`_\ ) + + +There are two bit shift operators in C++: the left shift operator +``<<`` and the right shift operator ``>>``. These operators cause the +bits in the left operand to be shifted left or right by the number of +positions specified by the right operand. + +More information on bitwise math can be obtained in the Wikipedia +article on `bitwise operations +<http://en.wikipedia.org/wiki/Bitwise_operation>`_\ , especially the +section on shifts in `C, C++, and Java +<http://en.wikipedia.org/wiki/Bitwise_operation#Shifts_in_C.2C_C.2B.2B.2C_C.23_and_Java>`_\ . + + +Syntax +------ + +``some_int << number_of_bits`` + +``some_int >> number_of_bits`` + + +Parameters +---------- + +* **some_int** An integer value or variable. + +* **number_of_bits** integer whose value is at most ``8 * + sizeof(variable)`` (so ``number_of_bits`` can be at most 32 for + ``int`` values, at most ``8`` for ``char`` values, etc.; the various + integer sizes are summarized :ref:`in this table + <lang-arithmetic-int-sizes>`\ ). + + + +Example: +-------- + +Here are some examples of bit shifting, with the binary representation of the number in comments:: + + int a = 5; // binary: 101 + int b = a << 3; // binary: 101000, or 40 in decimal + int c = b >> 3; // binary: 101, or back to 5 like we started with + + +When you left shift a value x by y bits (x << y), the leftmost y bits +in x are lost, literally shifted out of existence. We'll do this +example with ``char`` values (which are integers in the range 0-255, +and take up 8 bits of memory):: + + char a = 5; // binary (all 8 bits): 00000101 + char b = a << 7; // binary: 10000000 - the first 1 in 101 was discarded + + +If you are certain that none of the ones in a value are being shifted +into oblivion, a simple way to think of the left-shift operator is +that it multiplies the left operand by 2 raised to the right operand +power (in math notation, ``x << y`` equals x * 2\ :sup:`y`\ , as long +as none of the bits of x get shifted out). For example, to generate +powers of 2, the following expressions can be employed:: + + 1 << 0 == 1 + 1 << 1 == 2 + 1 << 2 == 4 + 1 << 3 == 8 + ... + 1 << 8 == 256 + 1 << 9 == 512 + 1 << 10 == 1024 + ... + +.. _lang-bitshift-signbit-gotcha: + +When you shift x right by y bits (``x >> y``), and the highest bit in +x is a 1, the behavior depends on the exact data type of x. If x is of +type ``int``, the highest bit is special, and determines whether x is +negative or not; the details are too complicated to explain here, but +they are thoroughly explained in the Wikipedia article on `two's +complement arithmetic +<http://en.wikipedia.org/wiki/Two%27s_complement>`_\ , which the +system most computers use to store integers. In that case, the sign +bit is copied into lower bits, for esoteric historical reasons:: + + int x = -16; // binary (all 32 bits): 11111111111111111111111111110000 + int y = x >> 3; // binary: 11111111111111111111111111111110 + + + +This behavior, called "sign extension", is often not what you +want. You probably wish zeros to be shifted in from the left. It +turns out that the right shift rules are different for ``unsigned +int`` values, so you can use a type cast to suppress ones being copied +from the left:: + + int x = -16; // binary: 11111111111111111111111111110000 + int y = (unsigned int)x >> 3; // binary: 00011111111111111111111111111110 + + + +If you are careful to avoid sign extension, you can use the +right-shift operator, ``>>``, as a way to divide by powers of 2. For +example:: + + int x = 1000; + int y = x >> 3; // integer division of 1000 by 8, causing y = 125. + + +Arduino Compatibility +--------------------- + +Since it's part of the C++ language, bit shifting on the Maple is +compatible with the Arduino; however, you should keep in mind that the +Maple has bigger integer types (as in, more bits) than the Arduino. + +Since the STM32 is a 32-bit processor, the ``int`` type takes up 32 +bits instead of 16, like on Arduino's 16-bit microcontroller. This +means that you can shift left, like ``x << y``, with bigger values of +``y`` on the Maple before ones in ``x`` start to get shifted out. + +To calculate the number of bits of an integer type on the Maple, +multiply its size in bytes (see :ref:`this table +<lang-arithmetic-int-sizes>` for these) by 8, since there are 8 +bits in 1 byte. For example, a ``short`` takes up 2 bytes of memory, +or 2 * 8 = 16 bits. + +See Also +-------- + +- :ref:`lang-bit` +- :ref:`lang-bitread` +- :ref:`lang-bitwrite` +- :ref:`lang-bitclear` + + +.. include:: cc-attribution.txt diff --git a/source/lang/bitwisecompound.rst b/source/lang/bitwisecompound.rst new file mode 100644 index 0000000..2b0fe2f --- /dev/null +++ b/source/lang/bitwisecompound.rst @@ -0,0 +1,231 @@ +.. highlight:: cpp + +.. _lang-bitwisecompound: + +Compound bitwise and (&=), or (\|=), XOR (^=) +============================================= + +The compound bitwise operators perform their calculations at the +bit level of variables. They are often used to clear and set +specific bits of a variable. + +See the :ref:`bitwise math tutorial <lang-bitwisemath>` for more +information on bitwise operators. + +.. contents:: Contents + :local: + +.. _lang-bitwisecompound-and: + +Compound bitwise AND (&=) +------------------------- + +The compound bitwise AND operator ``&=`` is often used with a variable +and a constant to force particular bits in a variable to be zero. This +is often referred to in programming guides as "clearing" or +"resetting" bits. In a program, writing the line ``x &= y;`` is +equivalent to writing ``x = x & y;``. That is, the value of ``x`` +after the line will be equal to its old value bitwise ANDed with the +value of ``y``:: + + x &= y; // equivalent to x = x & y; + +You can use any integer variable for ``x`` (i.e., any variable of type +``int``, ``long``, ``char``, ``byte``, etc.). You can use either an +integer variable or any :ref:`integer value +<lang-constants-integers>` (like ``3`` or ``0x20``) for ``y``. + +Before doing an example of ``&=``, let's first review the Bitwise AND +(``&``) operator:: + + 0 0 1 1 operand1 + 0 1 0 1 operand2 + ---------- + 0 0 0 1 (operand1 & operand2) = result + +As shown above, bits that are "bitwise ANDed" with 0 become 0, while +bits that are "bitwise ANDed" with 1 are left unchanged. So, if ``b`` +is a ``byte`` variable, then ``b & B00000000`` equals zero, and ``b & +B11111111`` equals ``b``. + +.. _lang-bitwisecompound-binconst: + +.. note:: The above uses :ref:`binary constants + <lang-constants-integers-bin>`\ . The numbers are still the same + value in other representations, they just might not be as easy to + understand. + + Normally, in C and C++ code, :ref:`hexadecimal + <lang-constants-integers-hex>` or :ref:`octal + <lang-constants-integers-oct>` are used when we're interested in + an integer's bits, rather than its value as a number. + + While hexadecimal and octal literals might be harder to understand + at first, you should really take the time to learn them. They're + part of C, C++, and many other programming languages, while binary + constants are available only for compatibility with Arduino. + + Also, ``B00000000`` is shown for clarity, but zero in any number + format is zero. + +So, to clear (set to zero) bits 0 and 1 of a one-byte variable, while +leaving the rest of the variable's bits unchanged, use the compound +bitwise AND operator ``&=`` with the constant ``B11111100`` +(hexadecimal ``0xFC``\ ):: + + 1 0 1 0 1 0 1 0 variable + 1 1 1 1 1 1 0 0 mask + ---------------------- + 1 0 1 0 1 0 0 0 + ^^^^^^^^^^^^^^^^ ^^^^ + unchanged cleared + + +Here is the same representation with the variable's bits replaced +with the symbol ``x``\ :: + + x x x x x x x x variable + 1 1 1 1 1 1 0 0 mask + ---------------------- + x x x x x x 0 0 + ^^^^^^^^^^^^^^^^ ^^^^ + unchanged cleared + + +So, using a byte variable ``b``\ , if we say:: + + b = B10101010; // B10101010 == 0xAA + b &= B11111100; // B11111100 == 0xFC + +then we will have :: + + b == B10101000; // B10101000 == 0xA8 + +.. _lang-bitwisecompound-or: + +Compound bitwise OR (\|=) +------------------------- + +The compound bitwise OR operator ``|=`` is often used with a variable +and a constant to "set" (set to 1) particular bits in a variable. In +a program, writing the line ``x |= y;`` is equivalent to writing ``x = +x | y;``. That is, the value of ``x`` after the line will be equal to +its old value bitwise ORed with the value of ``y``:: + + x |= y; // equivalent to x = x | y; + +You can use any integer variable for ``x`` (i.e., any variable of type +``int``, ``long``, ``char``, ``byte``, etc.). You can use either an +integer variable or any integer value (like ``3`` or ``0x20``) for +``y``. (This works the same way as :ref:`compound bitwise AND +<lang-bitwisecompound-and>`\ , ``&=``). + +Before doing an example of ``|=``, let's first review the Bitwise OR +(``|``) operator:: + + 0 0 1 1 operand1 + 0 1 0 1 operand2 + ---------- + 0 1 1 1 (operand1 | operand2) = result + +Bits that are "bitwise ORed" with 0 are unchanged, while bits that are +"bitwise ORed" with 1 are set to 1. So if ``b`` is a ``byte`` +variable, then ``b | B00000000`` equals ``b``, and ``b & B11111111`` +equals ``B11111111`` (here we've used binary constants; see the +:ref:`note <lang-bitwisecompound-binconst>` above). + +So, to set bits 0 and 1 of a one-byte variable, while leaving the rest +of the variable unchanged, use the compound bitwise OR operator +(``|=``) with the constant ``B00000011`` (hexadecimal ``0x3``):: + + 1 0 1 0 1 0 1 0 variable + 0 0 0 0 0 0 1 1 mask + ---------------------- + 1 0 1 0 1 0 1 1 + ^^^^^^^^^^^^^^^^ ^^^^ + unchanged set + +Here is the same representation with the variable's bits replaced with +the symbol ``x``:: + + x x x x x x x x variable + 0 0 0 0 0 0 1 1 mask + ---------------------- + x x x x x x 1 1 + ^^^^^^^^^^^^^^^^ ^^^^ + unchanged set + +So, using a byte variable ``b``, if we say:: + + b = B10101010; // B10101010 == 0xAA + b |= B00000011; // B00000011 == 0x3 + +then we will have :: + + b == B10101011; // B10101011 == 0xAB + +.. _lang-bitwisecompound-xor: + +Compound bitwise XOR (\^=) +-------------------------- + +The compound bitwise XOR operator ``^=`` is used with a variable and a +constant to "toggle" (change 0 to 1, and 1 to 0) particular bits in a +variable. In a program, writing the line ``x ^= y;`` is equivalent to +writing ``x = x ^ y;``. That is, the value of ``x`` after the line +will be equal to its old value bitwise XORed with the value of ``y``:: + + x ^= y; // equivalent to x = x ^ y; + +You can use any integer variable for ``x`` (i.e., any variable of type +``int``, ``long``, ``char``, ``byte``, etc.). You can use either an +integer variable or any integer value (like ``3`` or ``0x20``) for +``y``. (This works the same way as :ref:`&= +<lang-bitwisecompound-and>` and :ref:`\|= +<lang-bitwisecompound-or>`; in fact, these three operators all +work the same in this way). + +Before doing an example of ``^=``, let's first review the Bitwise +XOR operator, ``^``:: + + 0 0 1 1 operand1 + 0 1 0 1 operand2 + ---------- + 0 1 1 0 (operand1 ^ operand2) = result + +One way to look at bitwise XOR is that each bit in the result is a 1 +if the input bits are different, or 0 if they are the same. Another +way to think about it is that the result bit will be 1 when *exactly* +one (no more, no less) of the input bits is 1; otherwise, it will be +zero. This means that if you XOR a bit with 1, it will change (or +toggle) its value, while if you XOR a bit with 0, it stays the same. + +So, to toggle bits 0 and 1 of a one-byte variable, while leaving the +rest of the variable unchanged, use the compound bitwise XOR operator +``^=`` with the constant ``B00000011`` (hexadecimal ``0x3``\ ; see +:ref:`note <lang-bitwisecompound-binconst>` above):: + + 1 0 1 0 1 0 1 0 variable + 0 0 0 0 0 0 1 1 mask + ---------------------- + 1 0 1 0 1 0 1 1 + ^^^^^^^^^^^^^^^^ ^^^^ + unchanged toggled + +So, using a byte variable ``b``, if we say:: + + b = B10101010; // B10101010 == 0xAA + b ^= B00000011; // B00000011 == 0x3 + +then we will have :: + + b == B10101001; // B10101001 == 0xA9 + +See Also +-------- + +- :ref:`Boolean operations <lang-boolean>` (``&&``, ``||``) +- :ref:`Bitwise operators <lang-bitwisemath>` (``&``, ``|``, ``^``, ``~``) + + +.. include:: cc-attribution.txt diff --git a/source/lang/bitwisemath.rst b/source/lang/bitwisemath.rst new file mode 100644 index 0000000..30e8873 --- /dev/null +++ b/source/lang/bitwisemath.rst @@ -0,0 +1,186 @@ +.. highlight:: cpp + +.. _lang-bitwisemath: + +Bitwise AND (&), OR (\|), XOR (^), NOT (~) +========================================== + +The bitwise operators perform their calculations at the bit level of +variables. They help solve a wide range of common programming +problems. + +Much of the material here is adapted for Maple from an (Arduino) +`tutorial on bitwise math +<http://www.arduino.cc/playground/Code/BitMath>`_\ . Another great +resource is the Wikipedia article on `bitwise operations +<http://en.wikipedia.org/wiki/Bitwise_operation>`_\ . + +Below are descriptions and syntax for all of the operators. + +.. contents:: Contents + :local: + +.. _lang-bitwisemath-and: + +Bitwise AND (&) +--------------- + +The bitwise AND operator in C++ is a single ampersand, ``&``, used +between two other integer expressions. Bitwise AND operates on each +bit position of the surrounding expressions independently, according +to this rule: if both input bits are 1, the resulting output is 1, +otherwise the output is 0. Another way of expressing this is:: + + 0 0 1 1 operand1 + 0 1 0 1 operand2 + ---------- + 0 0 0 1 (operand1 & operand2) = result + + +On the Maple, the type ``int`` is a 32-bit value, so using ``&`` +between two ``int`` expressions causes 32 simultaneous AND operations +to occur. In a code fragment like:: + + int a = 92; // in binary: 00000000000000000000000001011100 + int b = 101; // in binary: 00000000000000000000000001100101 + int c = a & b; // result: 00000000000000000000000001000100, + // (or 68 in decimal). + + +Each of the 32 bits in ``a`` and ``b`` are processed using bitwise +AND, and all 32 resulting bits are stored in ``c``, resulting in the +value 1000100 in binary, which is 68 in decimal. + + +.. _lang-bitwisemath-or: + +Bitwise OR (\|) +--------------- + +The bitwise OR operator in C++ is the vertical bar symbol, ``|``. Like +the ``&`` operator, ``|`` operates independently on each bit in its +two surrounding integer expressions, but what it does is +different. The bitwise OR of two bits is 1 if either or both of the +input bits is 1, otherwise it is 0. For example:: + + 0 0 1 1 operand1 + 0 1 0 1 operand2 + ---------- + 0 1 1 1 (operand1 | operand2) = result + +Here is an example of bitwise OR used in a snippet of C++ code (using +``char``, which takes up 8 bits of memory, instead of ``int``, which +uses 32):: + + char a = 92; // in binary: 01011100 + char b = 101; // in binary: 01100101 + char c = a | b; // result: 01111101, or 125 in decimal. + +.. _lang-bitwisemath-xor: + +Bitwise XOR (^) +--------------- + +There is a somewhat unusual operator in C++ called bitwise EXCLUSIVE +OR, also known as bitwise XOR. (In English, this is usually pronounced +"zor" or "ex-or"). The bitwise XOR operator is written using the caret +symbol, ``^``. This operator is very similar to the bitwise OR +operator ``|``, except it evaluates to 0 for a given bit position when +both of the input bits for that position are 1:: + + 0 0 1 1 operand1 + 0 1 0 1 operand2 + ---------- + 0 1 1 0 (operand1 ^ operand2) = result + + +Another way to look at bitwise XOR is that each bit in the result +is a 1 if the input bits are different, or 0 if they are the same. + +Here is a simple example:: + + int x = 12; // binary (ignoring extra bits): 1100 + int y = 10; // binary: 1010 + int z = x ^ y; // binary: 0110, or decimal 6 + + + +The ^ operator is often used to toggle (i.e. change from 0 to 1, or 1 +to 0) some of the bits in an integer expression. In a bitwise OR +operation if there is a 1 in the mask bit, that bit is inverted; if +there is a 0, the bit is not inverted and stays the same. Below is a +program to blink digital pin 13 (the LED pin on Maple):: + + // Blink Maple LED pin + + int led_pin = 13; + int toggle = 0; + + // demo for Exclusive OR + void setup(){ + pinMode(led_pin, OUTPUT); + } + + void loop(){ + toggle = toggle ^ 1; + digitalWrite(led_pin, toggle); + delay(100); + } + +.. _lang-bitwisemath-not: + +Bitwise NOT (~) +--------------- + +The bitwise NOT operator in C++ is the tilde character ``~``. Unlike +``&`` and ``|``, the bitwise NOT operator is applied to a single +operand to its right. Bitwise NOT changes each bit to its opposite: 0 +becomes 1, and 1 becomes 0. For example:: + + 0 1 operand1 + ---- + 1 0 ~operand1 = result + +Another example:: + + char a = 103; // binary: 01100111 + char b = ~a; // binary: 10011000 = -104 + +You might be surprised to see a negative number like -104 as the +result of this operation. This is because the highest bit in an int +variable is the so-called "sign bit". If the highest bit is 1, the +number is interpreted as negative. This encoding of positive and +negative numbers is referred to as *two's complement*. For more +information, see the Wikipedia article on `two's +complement. <http://en.wikipedia.org/wiki/Twos_complement>`_ + +As an aside, it is interesting to note that (under two's complement +arithmetic) for any integer ``x``, ``~x`` is the same as ``-x-1``. + +At times, the sign bit in a signed integer expression can cause +some unwanted surprises. + + +Uses +---- + +One of the most common uses of bitwise operations is to select or +manipulate a particular bit (or bits) from an integer value, often +called `bit masking +<http://en.wikipedia.org/wiki/Mask_%28computing%29>`_\ . See the +linked Wikipedia article for more information and examples. + +If you really want to see bit-twiddling techniques in their full +glory, you could do much worse than to get yourself a copy of +`Hacker's Delight <http://www.hackersdelight.org/>`_\ . + + +See Also +-------- + +- :ref:`Boolean operations <lang-boolean>` (``&&``, ``||``) +- :ref:`Compound bitwise operations <lang-bitwisecompound>` (``&=``, + ``|=``, ``^=``). + + +.. include:: cc-attribution.txt diff --git a/source/lang/bitwrite.rst b/source/lang/bitwrite.rst new file mode 100644 index 0000000..86df26e --- /dev/null +++ b/source/lang/bitwrite.rst @@ -0,0 +1,40 @@ +.. _lang-bitwrite: + +bitWrite(x, n, b) +================= + +Description +----------- + +(Macro) Writes a bit of a numeric variable. + +Parameters +---------- + +**x**: the numeric variable whose bit to write. + +**n**: which bit of the number to write, starting at 0 for the +least-significant (rightmost) bit. + +**b**: the value to write to the bit (0 or 1). + +Returns +------- + +Nothing. + +Arduino Compatibility +--------------------- + +Maple's version of ``bitWrite()`` is compatible with Arduino. + +See also +-------- + +- :ref:`bit() <lang-bit>` +- :ref:`bitRead() <lang-bitRead>` +- :ref:`bitSet() <lang-bitSet>` +- :ref:`bitClear() <lang-bitClear>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/boolean.rst b/source/lang/boolean.rst new file mode 100644 index 0000000..6ff4097 --- /dev/null +++ b/source/lang/boolean.rst @@ -0,0 +1,91 @@ +.. highlight:: cpp + +.. _lang-boolean: + +Boolean Operators +================= + +These can be used inside the condition of an :ref:`if <lang-if>` +statement. Evaluate to :ref:`true <lang-constants-true>` or +:ref:`false <lang-constants-false>`. + +.. contents:: Contents + :local: + +.. _lang-boolean-and: + +&& (logical and) +---------------- + +True only if both operands are true. For example:: + + if (digitalRead(2) == HIGH && digitalRead(3) == HIGH) { // read two switches + // ... + } + +is true only if both inputs are high. Another example:: + + if (a >= 10 && a <= 20){} // true if a is between 10 and 20 + +**Be careful** not to say ``10 <= a <= 20``! This won't work the way +you want. You have to separately test whether ``a`` is at least 10 +using ``a >= 10``, then test whether ``a`` is at most 20 using ``a <= +20``, then combine the results using ``&&``. + + +.. _lang-boolean-or: + +\|\| (logical or) +----------------- + +True if either operand is true. For example:: + + if (x > 0 || y > 0) { + // ... + } + +is true if either ``x`` or ``y`` is greater than 0. + +.. _lang-boolean-not: + +! (logical not) +--------------- + +True if the operand is false. For example:: + + if (!x) { + // ... + } + +is true if ``x`` is false (i.e. if ``x`` is zero). + +Some Advice +----------- + +.. warning:: + + Make sure you don't mistake the boolean AND operator ``&&`` + (double ampersand) for the :ref:`bitwise AND operator + <lang-bitwisemath-and>` ``&`` (single ampersand). They are + entirely different beasts. + + Similarly, do not confuse the boolean OR operator ``||`` (double + pipe) with the :ref:`bitwise OR operator <lang-bitwisemath-or>` + ``|`` (single pipe). + + The :ref:`bitwise NOT operator <lang-bitwisemath-not>` ``~`` + (tilde) looks much different than the boolean not operator ``!`` + (exclamation point, or "bang", as some programmers say), but you + still have to be sure which one you want. + + +See Also +-------- + +- :ref:`Bitwise operators <lang-bitwisemath>` (``&``, ``|``, ``^``, ``~``) +- :ref:`Compound bitwise operators <lang-bitwisecompound>` (``&=``, + ``|=``, ``^=``). +- :ref:`if statement <lang-if>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/booleanvariables.rst b/source/lang/booleanvariables.rst new file mode 100644 index 0000000..9d0e992 --- /dev/null +++ b/source/lang/booleanvariables.rst @@ -0,0 +1,55 @@ +.. highlight:: cpp + +.. _lang-booleanvariables: + +Booleans +======== + +A **boolean** holds one of two values, :ref:`true +<lang-constants-true>` or :ref:`false <lang-constants-false>`. +On a Maple, each boolean variable occupies one byte of memory, and has +type ``bool``. + +.. warning:: + + On an Arduino, the type ``boolean`` is also provided. While the + Maple also has this type for compatibility, **its use is strongly + discouraged**. The ``bool`` type is a standard part of C++, while + ``boolean`` is a non-standard extension that serves no purpose. + +Example +------- + +:: + + int ledPin = 13; // LED on pin 13 + int switchPin = 12; // momentary switch on 12, other side connected to ground + + // running is a boolean variable: + bool running = false; + + void setup() { + pinMode(ledPin, OUTPUT); + pinMode(switchPin, INPUT); + digitalWrite(switchPin, HIGH); // turn on pullup resistor + } + + void loop() { + if (digitalRead(switchPin) == LOW) { + // switch is pressed - pullup keeps pin high normally + delay(100); // delay to debounce switch + running = !running; // toggle running variable + digitalWrite(ledPin, running) // indicate via LED + } + } + +See also +-------- + + +- :ref:`Boolean constants <lang-constants-bool>` +- :ref:`Boolean operators <lang-boolean>` +- :ref:`Variables <lang-variables>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/braces.rst b/source/lang/braces.rst new file mode 100644 index 0000000..229ad8c --- /dev/null +++ b/source/lang/braces.rst @@ -0,0 +1,109 @@ +.. highlight:: cpp + +.. _lang-braces: + +Curly Braces ({}) +================= + +.. contents:: Contents + :local: + +Introduction +------------ + +Curly braces (also referred to as just "braces" or as "curly +brackets") are a major part of the C and C++ programming +languages. They are used in several different constructs, outlined +below, and this can sometimes be confusing for beginners. + +An opening curly brace, ``{`` must always be followed by a closing +curly brace ``}``. This is a condition that is often referred to as +the braces being *balanced*. The Maple IDE (integrated development +environment) includes a convenient feature to check the balance of +curly braces. Just select a brace, or even click the insertion point +immediately following a brace, and its companion will be highlighted\ +[#fbug]_\ . + +Beginning programmers, and programmers coming to C++ from languages +without braces, often find using them confusing or daunting. + +Because the use of the curly brace is so varied, it is good +programming practice to type the closing brace immediately after +typing the opening brace when inserting a construct which requires +curly braces. Then insert some blank lines between your braces and +begin inserting statements. Your braces, and your attitude, will never +become unbalanced. + +Unbalanced braces can often lead to cryptic, impenetrable compiler +errors that can sometimes be hard to track down in a large program. +Because of their varied usages, braces are also incredibly important +to the syntax of a program and moving a brace one or two lines will +usually dramatically affect the meaning of a program. + +The main uses of curly braces +----------------------------- + +**Functions**:: + + // a function body needs braces around it + void myFunction(datatype argument) { + // ... function body goes in here ... + } + +**Loops** (see the :ref:`while <lang-while>`\ , :ref:`for +<lang-for>`\ , and :ref:`do/while <lang-dowhile>` loop reference +pages for more information):: + + // you should put braces around the body of a loop: + + while (boolean expression) { + // code inside the loop goes here + } + + for (initialisation; termination condition; incrementing expr) { + // code inside the loop goes here + } + + do { + // code inside the loop goes here + } while (boolean expression); + + +**Conditional statements** (see the :ref:`if statement <lang-if>` +reference page for more information):: + + // you should put braces around the body of an "if", "else if", + // or "else": + + if (boolean expression) { + // code inside the "if" + } + else if (boolean expression) { + // code inside the "else if" + } + else { + // code inside the "else" + } + +**Switch statements** (see the :ref:`switch statement +<lang-switchcase>` reference page for more information):: + + switch (var) { + case 1: + doThing1(); + break; + case 2: + doThing2(); + break; + } + +.. rubric:: Footnotes + +.. TODO remove this once IDE 0.1.0 released + +.. [#fbug] At present this feature is slightly buggy as the IDE will + often find (incorrectly) a brace in text that has been commented + out. + + +.. include:: cc-attribution.txt diff --git a/source/lang/break.rst b/source/lang/break.rst new file mode 100644 index 0000000..dc50b5f --- /dev/null +++ b/source/lang/break.rst @@ -0,0 +1,35 @@ +.. highlight:: cpp + +.. _lang-break: + +break +===== + +``break`` is used to exit from a :ref:`while <lang-while>`\ , +:ref:`for <lang-for>`\ , or :ref:`do/while <lang-dowhile>` loop, +bypassing the normal loop condition. It is also used to exit from a +:ref:`switch <lang-switchcase>` statement. + + +Example +------- + +:: + + for (x = 0; x < 255; x ++) + { + digitalWrite(PWMpin, x); + sens = analogRead(sensorPin); + if (sens > threshold){ // bail out on sensor detect + x = 0; + // this line of code means that we'll immediately exit + // from the "for" loop: + break; + } + delay(50); + } + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/byte.rst b/source/lang/byte.rst new file mode 100644 index 0000000..45c9d5f --- /dev/null +++ b/source/lang/byte.rst @@ -0,0 +1,34 @@ +.. highlight:: cpp + +.. _lang-byte: + +byte +==== + +The ``byte`` type stores a 1-byte (8-bit) unsigned integer number, +from 0 to 255. + +.. warning:: + + The ``byte`` type is provided for compatibility with Arduino. + However, it is a non-standard extension. The standard C++ type for + storing an 8-bit unsigned integer is ``unsigned char``; we + recommend using that instead. (Your code will still work on an + Arduino). + + +Example +------- + +:: + + byte b = 134; + +See Also +-------- + +- :ref:`byte() <lang-bytecast>` (casting a value to a byte) +- :ref:`Variables <lang-variables>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/bytecast.rst b/source/lang/bytecast.rst new file mode 100644 index 0000000..4ad2a89 --- /dev/null +++ b/source/lang/bytecast.rst @@ -0,0 +1,53 @@ +.. highlight:: cpp + +.. _lang-bytecast: + +byte() (cast) +============= + +Description +----------- + +Converts a value to the :ref:`byte <lang-byte>` data type. + +.. note:: + + Casting to the byte type is provided for compatibility with + Arduino. However, the recommended Maple type for storing an 8-bit + unsigned integer is ``uint8``. (C and C++ programmers: ``stdint.h`` + is also available). + + In order to cast a variable ``x`` to a ``uint8``, the + following syntax can be used:: + + uint8(x); + +Syntax +------ + +``byte(x)`` + + +Parameters +---------- + +**x**: a value of any integer type + + +Returns +------- + +The value, converted to a ``byte``. Note, however, that if the value +is larger than the maximum value you can store in a byte (255), then +the results might be strange and unexpected. + + +See Also +-------- + +- :ref:`lang-byte` + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/cc-attribution.txt b/source/lang/cc-attribution.txt new file mode 100644 index 0000000..e100140 --- /dev/null +++ b/source/lang/cc-attribution.txt @@ -0,0 +1,9 @@ +.. Included in all this directory's files in order to satisfy the +.. Arduino CC Attribution-ShareAlike 3.0 License + +.. admonition:: License and Attribution + + This documentation page was adapted from the `Arduino Reference + Documentation <http://arduino.cc/en/Reference/HomePage>`_\ , which + is released under a `Creative Commons Attribution-ShareAlike 3.0 + License <http://creativecommons.org/licenses/by-sa/3.0/>`_. diff --git a/source/lang/char.rst b/source/lang/char.rst new file mode 100644 index 0000000..8c6dadf --- /dev/null +++ b/source/lang/char.rst @@ -0,0 +1,53 @@ +.. highlight:: cpp + +.. _lang-char: + +char +==== + +Description +----------- + +The ``char`` type stores a 1-byte character value (or integer with +value from -128 to 127). Character literals are written in single +quotes, like this: ``'A'`` (for multiple characters - strings - use +double quotes: ``"ABC"``). + + +Just like everything else on a computer, characters are stored as +numbers. You can see the specific encoding in the `ASCII chart +<http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters>`_\ +. This means that it is possible to do arithmetic on characters, in +which the ASCII value of the character is used (e.g. ``'A' + 1`` has the +decimal value 66, since the ASCII value of the capital letter A in +decimal is 65). See the :ref:`Serial.println() +<lang-serial-println>` documentation for more information about how +characters are converted into numbers. + +The ``char`` datatype is a signed type, meaning that it encodes +numbers from -128 to 127. For an unsigned type, which stores values +from 0 to 255, just use the type ``unsigned char`` (two words). + + +Example +------- + +:: + + // the following two lines are equivalent, using the ASCII + // character encoding: + char c = 'A'; + char c = 65; + + +See also +-------- + + +- :ref:`lang-int` +- :ref:`lang-array` (a string is just an array of ``char``\ s) +- :ref:`Serial.println() <lang-serial-println>` + + + +.. include:: cc-attribution.txt diff --git a/source/lang/charcast.rst b/source/lang/charcast.rst new file mode 100644 index 0000000..844dd58 --- /dev/null +++ b/source/lang/charcast.rst @@ -0,0 +1,39 @@ +.. highlight:: cpp + +.. _lang-charcast: + +char() (cast) +============= + +Description +----------- + +Converts a value to the :ref:`char <lang-char>` data type. + +Syntax +------ + +``char(x)`` + + +Parameters +---------- + +**x**: a value of any type + + +Returns +------- + +The value, converted to a ``char``. Note, however, that if the value +is outside the range of a ``char`` (-128 to 127), then the results +might be strange and unexpected. + + +See Also +-------- + +- :ref:`char <lang-char>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/comments.rst b/source/lang/comments.rst new file mode 100644 index 0000000..c5f118a --- /dev/null +++ b/source/lang/comments.rst @@ -0,0 +1,67 @@ +.. highlight:: cpp + +.. _lang-comments: + +Comments +======== + +Comments are lines in the program that are used to inform yourself or +others about the way the program works. They are ignored by the +compiler, and not exported to the processor, so they don't take up any +space in RAM or Flash. + +One use for comments is to help you understand (or remember) how your +program works, or to inform others how your program works. There are +two different ways of making comments. + +.. _lang-comments-singleline: + +**Single line comment**: Anything following two slashes, ``//``, until +the end of the line, is a comment:: + + x = 5; // the rest of this line is a comment + +.. _lang-comments-multiline: + +**Multi-line comment**: Anything in between a pair of ``/*`` and ``*/`` +is a comment:: + + /* <-- a slash-star begins a multi-line comment + + all of this in the multi-line comment - you can use it to comment + out whole blocks of code + + if (gwb == 0){ // single line comment is OK inside a multi-line comment + x = 3; + } + + // don't forget the "closing" star-slash - they have to be balanced: + */ + +Note that it's okay to use single-line comments within a multi-line +comment, but you can't use multi-line comments within a multi-line +comment. Here's an example:: + + /* ok, i started a multi-line comment + + x = 3; /* this next star-slash ENDS the multi-line comment: */ + + x = 4; // this line is outside of the multi-line comment + + // next line is also outside of the comment, and causes a compile error: + */ + +Programming Tip +--------------- + +When experimenting with code, "commenting out" parts of your program +is a convenient way to remove lines that may be buggy. This leaves +the lines in the code, but turns them into comments, so the compiler +just ignores them. This can be especially useful when trying to locate +a problem, or when a program refuses to compile and the compiler error +is cryptic or unhelpful. + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/comparison.rst b/source/lang/comparison.rst new file mode 100644 index 0000000..8873256 --- /dev/null +++ b/source/lang/comparison.rst @@ -0,0 +1,87 @@ +.. highlight:: cpp + +.. _lang-comparison: + +Comparison Operators +==================== + +The comparison operators ``==``, ``!=``, ``<``, ``>``, ``<=``, and +``>=`` are used to compare two numbers. They are :ref:`true +<lang-constants-true>` when the comparison is true, and :ref:`false +<lang-constants-false>` otherwise. They are based on the symbols +=, ≠, <, >, ≤, and ≥ from mathematics. + +Here are some examples, with their meaning in comments:: + + // "eq" is true when x is equal to y + bool eq = (x == y); + + // "neq" is true when x is different than y + bool neq = (x != y); + + // "lt" is true when x is less than, but NOT equal to, y + bool lt = (x < y); + + // "gt" is true when x is greater than, but NOT equal to, y + bool gt = (x > y); + + // "lte" is true when x is less than or equal to y + bool lte = (x <= y); + + // "gte" is true when x is greater than or equal to y + bool gte = (x >= y); + +The parentheses are optional; they are present only for clarity. For +example, the following two lines are the same:: + + bool eq = x == y; + + bool eq = (x == y); + +Uses +---- + +Comparison operators, along with :ref:`boolean operators +<lang-boolean>`, are useful inside the conditionals of :ref:`if +<lang-if>` statements. Here's one example:: + + if (x < 50) { + // only execute these lines if x is less than 50 + SerialUSB.println("delaying:"); + SerialUSB.println(x); + delay(x); + } + +.. warning:: + Beware of accidentally using the single equal sign (``=``) when you + meant to test if two numbers are equal (``==``). This is a common + mistake inside of ``if`` statement conditionals, e.g.:: + + // DON'T MAKE THIS MISTAKE + if (x = 10) { + // body + } + + The single equal sign is the assignment operator, and sets x to 10 + (puts the value 10 into the variable x). Instead use the double equal + sign (e.g. ``if (x == 10)``), which is the comparison operator, and + tests *whether* x is equal to 10 or not. The latter statement is only + true if x equals 10, but the former statement will always be true. + + This is because C evaluates the statement ``if (x=10)`` as follows: 10 + is assigned to x (remember that the single equal sign is the + :ref:`assignment operator <lang-assignment>`), so x now + contains 10. Then the 'if' conditional evaluates 10, which evaluates + to :ref:`true <lang-constants-true>`, since any non-zero number + evaluates to ``true``. + + Consequently, the conditional of an ``if`` statement like ``if (x = + 10) {...}`` will always evaluate to ``true``, and the variable x + will be set to 10, which is probably not what you meant. + + (This sometimes has uses, though, so just because an assignment + appears within a conditional doesn't mean it's automatically wrong. + Be careful to know what you mean.) + + +.. include:: cc-attribution.txt diff --git a/source/lang/const.rst b/source/lang/const.rst new file mode 100644 index 0000000..1658e6d --- /dev/null +++ b/source/lang/const.rst @@ -0,0 +1,52 @@ +.. highlight:: cpp + +.. _lang-const: + +const Keyword +============= + +The ``const`` keyword stands for "constant". It is a variable +*qualifier* that modifies the behavior of the variable, making a +variable "*read-only*". This means that the variable can be used just +as any other variable of its type, but its value cannot be +changed. You will get a compiler error if you try to assign a value to +a ``const`` variable. + +Constants defined with the ``const`` keyword obey the same rules of +:ref:`variable scoping <lang-scope>` that govern other +variables. This, and the pitfalls of using :ref:`#define +<lang-define>`, often makes using the ``const`` keyword a superior +method for defining constants than ``#define``. + +Example +------- + +:: + + // this defines a variable called "pi", which cannot be changed: + const float pi = 3.14; + float x; + + // .... + + x = pi * 2; // it's fine to find the value of a const variable + + pi = 7; // illegal - you can't write to (modify) a constant + + +**#define** or **const** +------------------------ + +You can use either ``const`` or ``#define`` for creating numeric or +string constants. For :ref:`arrays <lang-array>`\ , you will need +to use ``const``. In general, ``const`` is preferred over ``#define`` +for defining constants. + +See Also +-------- + +- :ref:`#define <lang-define>` +- :ref:`volatile <lang-volatile>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/constants.rst b/source/lang/constants.rst new file mode 100644 index 0000000..b7521ed --- /dev/null +++ b/source/lang/constants.rst @@ -0,0 +1,302 @@ +.. _lang-constants: + +constants +========= + +Constants are predefined variables in the Arduino language. They +are used to make the programs easier to read. We classify constants +in groups. + +.. contents:: Contents + :local: + +.. _lang-constants-bool: + +Boolean Constants +----------------- + +There are two constants used to represent truth and falsity in the +Arduino language: **true**, and **false**. + +.. _lang-constants-false: + +false +^^^^^ + +false is the easier of the two to define. false is defined as 0 +(zero). + +.. _lang-constants-true: + +true +^^^^ + +true is often said to be defined as 1, which is correct, but true +has a wider definition. Any integer which is *non-zero* is TRUE, in +a Boolean sense. So -1, 2 and -200 are all defined as true, too, in +a Boolean sense. + + +Note that the *true* and *false* constants are typed in lowercase +unlike HIGH, LOW, INPUT, & OUTPUT. + + +Defining Pin Levels, HIGH and LOW +--------------------------------- + +When reading or writing to a digital pin there are only two +possible values a pin can take/be-set-to: **HIGH** and **LOW**. + +.. _lang-constants-high: + +**HIGH** + + + +The meaning of HIGH (in reference to a pin) is somewhat different +depending on whether a pin is set to an INPUT or OUTPUT. When a pin +is configured as an INPUT with pinMode, and read with digitalRead, +the microcontroller will report HIGH if a voltage of 3 volts or +more is present at the pin. + + + +A pin may also be configured as an INPUT with pinMode, and +subsequently made HIGH with digitalWrite, this will set the +internal 20K pullup resistors, which will *steer* the input pin to +a HIGH reading unless it is pulled LOW by external circuitry. + + + +When a pin is configured to OUTPUT with pinMode, and set to HIGH +with digitalWrite, the pin is at 5 volts. In this state it can +*source* current, e.g. light an LED that is connected through a +series resistor to ground, or to another pin configured as an +output, and set to LOW. + +.. _lang-constants-low: + +**LOW** + + + +The meaning of LOW also has a different meaning depending on +whether a pin is set to INPUT or OUTPUT. When a pin is configured +as an INPUT with pinMode, and read with digitalRead, the +microcontroller will report LOW if a voltage of 2 volts or less is +present at the pin. + + + +When a pin is configured to OUTPUT with pinMode, and set to LOW +with digitalWrite, the pin is at 0 volts. In this state it can +*sink* current, e.g. light an LED that is connected through a +series resistor to, +5 volts, or to another pin configured as an +output, and set to HIGH. + + + +Defining Digital Pins, INPUT and OUTPUT +--------------------------------------- + +Digital pins can be used either as **INPUT** or **OUTPUT**. +Changing a pin from INPUT TO OUTPUT with pinMode() drastically +changes the electrical behavior of the pin. + +.. _lang-constants-input: + +Pins Configured as Inputs +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Arduino (Atmega) pins configured as **INPUT** with pinMode() are +said to be in a high-impedance state. One way of explaining this is +that pins configured as INPUT make extremely small demands on the +circuit that they are sampling, say equivalent to a series resistor +of 100 Megohms in front of the pin. This makes them useful for +reading a sensor, but not powering an LED. + +.. _lang-constants-output: + +Pins Configured as Outputs +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Pins configured as **OUTPUT** with pinMode() are said to be in a +low-impedance state. This means that they can provide a substantial +amount of current to other circuits. Atmega pins can source +(provide positive current) or sink (provide negative current) up to +40 mA (milliamps) of current to other devices/circuits. This makes +them useful for powering LED's but useless for reading sensors. +Pins configured as outputs can also be damaged or destroyed if +short circuited to either ground or 5 volt power rails. The amount +of current provided by an Atmega pin is also not enough to power +most relays or motors, and some interface circuitry will be +required. + +.. _lang-constants-fp: + +Floating-Point Constants +------------------------ + +Similar to integer constants, floating point constants are used to +make code more readable. Floating point constants are swapped at +compile time for the value to which the expression evaluates. + +.. TODO explain that floating point literals are doubles + +.. _lang-constants-fp-f: + +.. TODO f modifiers + +Examples: + +``n = .005;`` + +Floating point constants can also be expressed in a variety of +scientific notation. 'E' and 'e' are both accepted as valid +exponent indicators. + +:: + + + floating-point evaluates to: also evaluates to: + constant + + 10.0 10 + 2.34E5 2.34 * 10^5 234000 + 67e-12 67.0 * 10^-12 .000000000067 + +.. _lang-constants-integers: + +Integer Constants +----------------- + +Integer constants are numbers used directly in a sketch, like +``123``. By default, these numbers are treated as +`int <http://arduino.cc/en/Reference/Int>`_'s but you can change +this with the U and L modifiers (see below). + + + +Normally, integer constants are treated as base 10 (decimal) +integers, but special notation (formatters) may be used to enter +numbers in other bases. + + + +:: + + Base Example Formatter Comment + + 10 (decimal) 123 none + + 2 (binary) B1111011 leading 'B' only works with 8 bit values (0 to 255) + characters 0-1 valid + + 8 (octal) 0173 leading "0" characters 0-7 valid + + 16 (hexadecimal) 0x7B leading "0x" characters 0-9, A-F, a-f valid + +.. _lang-constants-integers-dec: + +**Decimal** is base 10. This is the common-sense math with which +you are acquainted. Constants without other prefixes are assumed to +be in decimal format. + + + +Example: +:: + + 101 // same as 101 decimal ((1 * 10^2) + (0 * 10^1) + 1) + +.. _lang-constants-integers-bin: + +**Binary** is base two. Only characters 0 and 1 are valid. + + + +Example: +:: + + B101 // same as 5 decimal ((1 * 2^2) + (0 * 2^1) + 1) + +The binary formatter only works on bytes (8 bits) between 0 (B0) +and 255 (B11111111). If it is convenient to input an int (16 bits) +in binary form you can do it a two-step procedure such as: + + + +:: + + myInt = (B11001100 * 256) + B10101010; // B11001100 is the high byte + +.. _lang-constants-integers-oct: + +**Octal** is base eight. Only characters 0 through 7 are valid. Octal +values are indicated by the prefix "0". + +Example: + +:: + + 0101 // same as 65 decimal ((1 * 8^2) + (0 * 8^1) + 1) + +Warning +It is possible to generate a hard-to-find bug by (unintentionally) +including a leading zero before a constant and having the compiler +unintentionally interpret your constant as octal. + +.. _lang-constants-integers-hex: + +**Hexadecimal (or hex)** is base sixteen. Valid characters are 0 +through 9 and letters A through F; A has the value 10, B is 11, up +to F, which is 15. Hex values are indicated by the prefix "0x". +Note that A-F may be syted in upper or lower case (a-f). + + + +Example: + +:: + + 0x101 // same as 257 decimal ((1 * 16^2) + (0 * 16^1) + 1) + +.. _lang-constants-integers-u-l: + +U & L formatters +^^^^^^^^^^^^^^^^ + +By default, an integer constant is treated as an +`int <http://arduino.cc/en/Reference/Int>`_ with the attendant +limitations in values. To specify an integer constant with another +data type, follow it with: + + + + +- a 'u' or 'U' to force the constant into an unsigned data format. + Example: ``33u`` +- a 'l' or 'L' to force the constant into a long data format. + Example: ``100000L`` +- a 'ul' or 'UL' to force the constant into an unsigned long + constant. Example: ``32767ul`` + + + + +See also +-------- + + +- `pinMode() <http://arduino.cc/en/Reference/PinMode>`_ +- `Integer Constants <http://arduino.cc/en/Reference/IntegerConstants>`_ +- `boolean variables <http://arduino.cc/en/Reference/BooleanVariables>`_ +- `#define <http://arduino.cc/en/Reference/Define>`_ +- `byte <http://arduino.cc/en/Reference/Byte>`_ +- `int <http://arduino.cc/en/Reference/Int>`_ +- `unsigned int <http://arduino.cc/en/Reference/UnsignedInt>`_ +- `long <http://arduino.cc/en/Reference/Long>`_ +- `unsigned long <http://arduino.cc/en/Reference/UnsignedLong>`_ + + +.. include:: cc-attribution.txt diff --git a/source/lang/constrain.rst b/source/lang/constrain.rst new file mode 100644 index 0000000..297a2d4 --- /dev/null +++ b/source/lang/constrain.rst @@ -0,0 +1,65 @@ +.. highlight:: cpp + +.. _lang-constrain: + +constrain(x, a, b) +================== + +Description +----------- + +(Macro) Constrains a number to be within a range. + + +Parameters +---------- + +**x**: the number to constrain + +**a**: the lower end of the range + +**b**: the upper end of the range + +Returns +------- + +**x**: if **x** is between **a** and **b** + +**a**: if **x** is less than **a** + +**b**: if **x** is greater than **b** + +Example +------- + +:: + + // limits range of sensor values to between 10 and 150: + sensVal = constrain(sensVal, 10, 150); + + +Warning +------- + +Because of the way ``constrain()`` is implemented, avoid using other +functions or causing side effects inside the parentheses, as it may +lead to incorrect results:: + + constrain(x,a++,b); // avoid this - yields incorrect results + + constrain(x,a,b); // use this instead- + a++; // keep other math outside constrain() + +Arduino Compatibility +--------------------- + +Maple's implementation of ``constrain()`` is compatible with Arduino. + +See also +-------- + +- :ref:`min() <lang-min>` +- :ref:`max() <lang-max>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/continue.rst b/source/lang/continue.rst new file mode 100644 index 0000000..21b3984 --- /dev/null +++ b/source/lang/continue.rst @@ -0,0 +1,34 @@ +.. highlight:: cpp + +.. _lang-continue: + +========== + continue +========== + +The ``continue`` keyword skips the rest of the current iteration of a +:ref:`while <lang-while>`\ , :ref:`for <lang-for>`\ , or +:ref:`do/while <lang-dowhile>` loop. It continues by checking the +conditional expression of the loop, and proceeding with any subsequent +iterations. + + +Example +======= + +:: + + + for (x = 0; x < 255; x ++) { + if (x > 40 && x < 120) { // create jump in values + continue; // skips the next two lines and goes to the + // beginning of the loop, with the next value of x + } + + digitalWrite(PWMpin, x); + delay(50); + } + + + +.. include:: cc-attribution.txt diff --git a/source/lang/cos.rst b/source/lang/cos.rst new file mode 100644 index 0000000..3fbb0af --- /dev/null +++ b/source/lang/cos.rst @@ -0,0 +1,32 @@ +.. _lang-cos: + +cos() +===== + +Calculates the cosine of an angle. + +Library Documentation +--------------------- + +.. doxygenfunction:: cos + +Arduino Compatibility +--------------------- + +The Maple ``cos()`` implementation is compatible with Arduino. + +Note that the Maple implementation comes from `newlib +<http://sourceware.org/newlib/>`_\ , while Arduino's is that of +`avr-libc <http://avr-libc.nongnu.org/>`_\ . + +See also +-------- + + +- :ref:`sin() <lang-sin>` +- :ref:`tan() <lang-tan>` +- :ref:`float <lang-float>` +- :ref:`double <lang-double>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/define.rst b/source/lang/define.rst new file mode 100644 index 0000000..30738ec --- /dev/null +++ b/source/lang/define.rst @@ -0,0 +1,56 @@ +.. highlight:: cpp + +.. _lang-define: + +#define +======= + +``#define`` is a useful C and C++ feature that allows the programmer +to give a name to a constant value before the program is compiled. +The compiler will replace references to these constants with the +defined value at compile time. + +This can have some unwanted side effects. In general, the :ref:`const +<lang-const>` keyword is preferred for defining constants. + + +Syntax +------ + +The following line would define the name ``MY_CONSTANT`` to have value +``value``:: + + #define MY_CONSTANT value + +Note that the ``#`` is necessary. It is usually good style for the +name to be capitalized, although this is not required. + +There is no semicolon after the #define statement. If you include one, +the compiler will likely throw cryptic errors in unrelated places. +That is, **don't do this**:: + + // DON'T DO THIS! THE SEMICOLON SHOULDN'T BE THERE! + #define NAME value; + +Similarly, including an equal sign after the ``#define`` line will +also generate a cryptic compiler error further down the page. That +is, **don't do this, either**:: + + // DON'T DO THIS, EITHER! THE EQUALS SIGN SHOULDN'T BE THERE! + #define NAME = value + +Example +------- + +:: + + #define LED_PIN 13 + // The compiler will replace any mention of LED_PIN with + // the value 3 at compile time. + +See Also +-------- +- :ref:`const <lang-const>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/delay.rst b/source/lang/delay.rst new file mode 100644 index 0000000..90ca268 --- /dev/null +++ b/source/lang/delay.rst @@ -0,0 +1,72 @@ +.. highlight:: cpp + +.. _lang-delay: + +delay() +======= + +Pauses the program for at least a given number of milliseconds. (There +are 1000 milliseconds in a second.) + +Library Documentation +--------------------- + +.. doxygenfunction:: delay + + +Discussion +---------- + +While it is easy to create a blinking LED with the ``delay()`` +function, and many sketches use short delays for such tasks as switch +debouncing, the use of ``delay()`` in a sketch has significant +drawbacks. No other reading of sensors, mathematical calculations, or +pin manipulation can go on during the delay function, so in effect, it +brings most other activity to a halt. For alternative approaches to +controlling timing see the :ref:`millis() <lang-millis>` function +and the "Blink Without Delay" sketch cited :ref:`below +<lang-delay-seealso>`\ . More knowledgeable programmers usually +avoid the use of ``delay()`` for timing of events longer than tens of +milliseconds, unless the sketch is very simple. + +Certain things *do* go on while the ``delay()`` function is +controlling the STM32 chip, however, because the delay function does +not disable interrupts. Serial communication that appears at the RX +pin is recorded, PWM (see :ref:`pwmWrite() <lang-pwmwrite>`\ ) values +and pin states are maintained, and :ref:`interrupts +<lang-attachinterrupt>` will work as they should. + + +Example +------- + +:: + + int ledPin = 13; // LED connected to pin 13 + + void setup() { + pinMode(ledPin, OUTPUT); // sets the digital pin as output + } + + void loop() { + digitalWrite(ledPin, HIGH); // sets the LED on + delay(1000); // waits for a second + digitalWrite(ledPin, LOW); // sets the LED off + delay(1000); // waits for a second + } + +.. _lang-delay-seealso: + +See also +-------- + + +- :ref:`millis() <lang-millis>` +- :ref:`micros() <lang-micros>` +- :ref:`delayMicroseconds() <lang-delayMicroseconds>` +- (Arduino) `Blink Without Delay + <http://arduino.cc/en/Tutorial/BlinkWithoutDelay>`_ example (works + unmodified on Maple) + + +.. include:: cc-attribution.txt diff --git a/source/lang/delaymicroseconds.rst b/source/lang/delaymicroseconds.rst new file mode 100644 index 0000000..24a8286 --- /dev/null +++ b/source/lang/delaymicroseconds.rst @@ -0,0 +1,65 @@ +.. highlight:: cpp + +.. _lang-delaymicroseconds: + +delayMicroseconds() +=================== + +Pauses the program for the amount of time (in microseconds) +specified as parameter. There are a thousand microseconds in a +millisecond, and a million microseconds in a second. + +Library Documentation +--------------------- + +.. doxygenfunction:: delayMicroseconds + + +Example +------- + +The following example configures pin number 8 to work as an output +pin, and sends a train of pulses with a period of roughly 100 +microseconds:: + + int outPin = 8; + + void setup() { + pinMode(outPin, OUTPUT); // sets the digital pin as output + } + + void loop() { + digitalWrite(outPin, HIGH); // sets the pin on + delayMicroseconds(50); // pauses for 50 microseconds + digitalWrite(outPin, LOW); // sets the pin off + delayMicroseconds(50); // pauses for 50 microseconds + } + + +Caveats and Known Issues +------------------------ + +The longest time ``delayMicroseconds()`` can delay is bounded by its +argument type and the STM32 clock rate to be (2^32 - 1) / 12 +microseconds, or less than 6 minutes. For longer pauses, use of +:ref:`lang-delay` is possible. + +Arduino Compatibility +--------------------- + +While we have made every effort we could to ensure that the timing of +delayMicroseconds is as accurate as possible, we cannot guarantee it +will behave as the Arduino implementation down to the microsecond, +especially for smaller values of ``us``. + +See Also +-------- + +- :ref:`millis <lang-millis>` +- :ref:`micros <lang-micros>` +- :ref:`delay <lang-delay>` + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/detachinterrupt.rst b/source/lang/detachinterrupt.rst new file mode 100644 index 0000000..adb2439 --- /dev/null +++ b/source/lang/detachinterrupt.rst @@ -0,0 +1,37 @@ +.. _lang-detachinterrupt: + +detachInterrupt() +================= + +Used to disable an interrupt specified with +:ref:`lang-attachinterrupt`\ . + + +Library Documentation +--------------------- + +.. doxygenfunction:: detachInterrupt + +Arduino Compatibility +--------------------- + +There is one important difference between the Maple version of +detachInterrupt and the Arduino version. On the Maple, the argument +to ``detachInterrupt()`` is the *pin* on which the interrupt is +attached, while on the Arduino, the argument is the *interrupt +number*, which is different from the pin the interrupt is enabled on. + +If you're calling this function, you've already called +:ref:`lang-attachinterrupt` to set up your interrupt handler, so +just call ``detachInterrupt()`` with the same pin argument you gave to +``attachInterrupt()``. + +See Also +-------- + +- :ref:`attachInterrupt() <lang-attachInterrupt>` + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/digitalread.rst b/source/lang/digitalread.rst new file mode 100644 index 0000000..71583ca --- /dev/null +++ b/source/lang/digitalread.rst @@ -0,0 +1,61 @@ +.. highlight:: cpp + +.. _lang-digitalread: + +digitalRead() +============= + +Description +----------- + +Reads the value from a specified digital pin, either :ref:`HIGH +<lang-constants-high>` or :ref:`LOW <lang-constants-low>`. + + +Library Documentation +--------------------- + +.. doxygenfunction:: digitalRead + + +Example +------- + +The following example turns the LED on when the button is pressed:: + + int ledPin = 13; // LED connected to Maple pin 13 + int buttonPin = 38; // BUT connected to Maple pin 38 + + void setup() { + pinMode(ledPin, OUTPUT); + pinMode(buttonPin, INPUT); + } + + void loop() { + int val = digitalRead(buttonPin); // reads the input pin + digitalWrite(ledPin, val); + } + +Note +---- + +If the pin isn't connected to anything, ``digitalRead()`` can return +either HIGH or LOW (and this can change in a way that seems random). + +Arduino Compatibility +--------------------- + +The Maple version of ``digitalRead()`` is compatible with Arduino. + + +See Also +-------- + +- :ref:`pinMode <lang-pinMode>` +- :ref:`digitalWrite <lang-digitalWrite>` + + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/digitalwrite.rst b/source/lang/digitalwrite.rst new file mode 100644 index 0000000..419ef3a --- /dev/null +++ b/source/lang/digitalwrite.rst @@ -0,0 +1,116 @@ +.. _lang-digitalwrite: + +digitalWrite() +============== + +Description +----------- + +Write a `HIGH <http://arduino.cc/en/Reference/Constants>`_ or a +`LOW <http://arduino.cc/en/Reference/Constants>`_ value to a +digital pin. + + + +If the pin has been configured as an OUTPUT with +`pinMode <http://arduino.cc/en/Reference/PinMode>`_\ (), its voltage +will be set to the corresponding value: 5V (or 3.3V on 3.3V boards) +for HIGH, 0V (ground) for LOW. + + + +If the pin is configured as an INPUT, writing a HIGH value with +digitalWrite() will enable an internal 20K pullup resistor (see the +`tutorial on digital pins <http://arduino.cc/en/Tutorial/DigitalPins>`_). +Writing LOW will disable the pullup. The pullup resistor is enough +to light an LED dimly, so if LEDs appear to work, but very dimly, +this is a likely cause. The remedy is to set the pin to an output +with the pinMode() function. + + + +**NOTE:** Digital pin 13 is harder to use as a digital input than +the other digital pins because it has an LED and resistor attached +to it that's soldered to the board on most boards. If you enable +its internal 20k pull-up resistor, it will hang at around 1.7 V +instead of the expected 5V because the onboard LED and series +resistor pull the voltage level down, meaning it always returns +LOW. If you must use pin 13 as a digital input, use an external +pull down resistor. + + + +Syntax +------ + +digitalWrite(pin, value) + + + +Parameters +---------- + +pin: the pin number + + + +value: `HIGH <http://arduino.cc/en/Reference/Constants>`_ or +`LOW <http://arduino.cc/en/Reference/Constants>`_ + + + +Returns +------- + +none + + + +Example +------- + +:: + + + int ledPin = 13; // LED connected to digital pin 13 + + void setup() + { + pinMode(ledPin, OUTPUT); // sets the digital pin as output + } + + void loop() + { + digitalWrite(ledPin, HIGH); // sets the LED on + delay(1000); // waits for a second + digitalWrite(ledPin, LOW); // sets the LED off + delay(1000); // waits for a second + } + + + +Sets pin 13 to HIGH, makes a one-second-long delay, and sets the +pin back to LOW. + + + +Note +---- + +The analog input pins can be used as digital pins, referred to as +A0, A1, etc. + + + +See also +-------- + + +- `pinMode <http://arduino.cc/en/Reference/PinMode>`_\ () +- `digitalRead <http://arduino.cc/en/Reference/DigitalRead>`_\ () +- `Tutorial: Digital Pins <http://arduino.cc/en/Tutorial/DigitalPins>`_ + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/double.rst b/source/lang/double.rst new file mode 100644 index 0000000..b4a1219 --- /dev/null +++ b/source/lang/double.rst @@ -0,0 +1,51 @@ +.. _lang-double: + +double +====== + +Description +----------- + +Double precision floating point number. Occupies 8 bytes. On Maple, +the ``double`` type has a range of approximately -1.79769×10^308 to +1.79769×10^308; the ``double`` type subject to the same :ref:`overflow +issues <lang-variables-rollover>` as any numeric data type. + +Floating point numbers are not exact, and may yield strange results +when compared. For example ``6.0 / 3.0`` may not equal ``2.0``. You +should instead check that the absolute value of the difference between +the numbers is less than some small number. + +Floating point math is also much slower than integer math in +performing calculations, so should be avoided if, for example, a loop +has to run at top speed for a critical timing function. Programmers +often go to some lengths to convert floating point calculations to +integer math to increase speed. + +For more information, see the `Wikipedia article on floating point +math <http://en.wikipedia.org/wiki/Floating_point>`_\ . + +Floating-point numbers represent numbers with "decimal point", unlike +integral types, which always represent whole numbers. Floating-point +numbers are often used to approximate analog and continuous values +because they have greater resolution than integers. + +The double implementation on the Maple uses twice the number of bytes +as a :ref:`float <lang-float>`, with the corresponding gains in +precision. + +Tip +--- + +Users who borrow code from other sources that includes ``double`` +variables may wish to examine the code to see if the implied range and +precision are different from that actually achieved on the Maple. + +See Also +-------- + +- :ref:`float <lang-float>` + + + +.. include:: cc-attribution.txt diff --git a/source/lang/doublecast.rst b/source/lang/doublecast.rst new file mode 100644 index 0000000..4ea1776 --- /dev/null +++ b/source/lang/doublecast.rst @@ -0,0 +1,30 @@ +.. highlight:: cpp + +.. _lang-doublecast: + +double() (cast) +=============== + +Description +----------- + +Converts a value to the :ref:`double <lang-double>` floating point +data type. Here is an example:: + + int x = 2; + double d = double(x); // d now holds 2.0, a double value + +The value ``x`` can be of any type. However, if ``x`` is not a number +(like an ``int`` or ``long``), you will get strange results. + +See the :ref:`double <lang-double>` reference for details about the +precision and limitations of ``double`` values on the Maple. + +See Also +-------- + +- :ref:`double <lang-double>` +- :ref:`float <lang-float>` +- :ref:`float() <lang-floatcast>` + +.. include:: cc-attribution.txt diff --git a/source/lang/dowhile.rst b/source/lang/dowhile.rst new file mode 100644 index 0000000..77e02a3 --- /dev/null +++ b/source/lang/dowhile.rst @@ -0,0 +1,27 @@ +.. highlight:: cpp + +.. _lang-dowhile: + +do/while Loop +============= + +A ``do`` loop works in the same manner as a :ref:`while +<lang-while>` loop, with the exception that the condition is tested +at the end of the loop, so the ``do`` loop will *always* run at least +once. + +This is the basic syntax:: + + do { + // statement block + } while (test condition); + +Example:: + + do { + delay(50); // wait for sensors to stabilize + x = readSensors(); // check the sensors + } while (x < 100); + + +.. include:: cc-attribution.txt diff --git a/source/lang/else.rst b/source/lang/else.rst new file mode 100644 index 0000000..863f21b --- /dev/null +++ b/source/lang/else.rst @@ -0,0 +1,54 @@ +.. highlight:: cpp + +.. _lang-else: + +if/else +======= + +``if``/\ ``else`` allows greater control over the flow of code than +the basic :ref:`if <lang-if>` statement, by allowing multiple tests +to be grouped together. For example, an :ref:`analog input +<lang-analogread>` could be tested, with one action taken if the +input was less than 500, and another action taken if the input was 500 +or greater. The code would look like this:: + + if (pinFiveInput < 500) { + // action A + } else { + // action B + } + +``else`` can precede another ``if`` test, so that multiple, mutually +exclusive tests can be run at the same time. + +Each test will proceed to the next one until a true test is +encountered. When a true test is found, its associated block of code +is run, and the program then skips to the line following the entire +if/else construction. If no test proves to be true, the default +``else`` block is executed, if one is present, and sets the default +behavior. + + +Note that an ``else if`` block may be used with or without a +terminating ``else`` block, and vice-versa. An unlimited number of +such ``else if`` branches is allowed. Here is a code example:: + + if (pinFiveInput < 500) { + // do Thing A + } else if (pinFiveInput >= 1000) { + // do Thing B + } else { + // do Thing C + } + +Another way to express branching, mutually exclusive tests, is with a +:ref:`switch/case <lang-switchcase>` statement. + +See Also +-------- + +- :ref:`if <lang-if>` +- :ref:`switch/case <lang-switchcase>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/enum.rst b/source/lang/enum.rst new file mode 100644 index 0000000..5ecd99c --- /dev/null +++ b/source/lang/enum.rst @@ -0,0 +1,8 @@ +.. _lang-enum: + +enum +==== + +Stub. + +Reference this from language.rst diff --git a/source/lang/float.rst b/source/lang/float.rst new file mode 100644 index 0000000..ef1a339 --- /dev/null +++ b/source/lang/float.rst @@ -0,0 +1,53 @@ +.. highlight:: cpp + +.. _lang-float: + +float +===== + +Description +----------- + +Single-precision floating point number. Occupies 4 bytes. On Maple, +the ``float`` type has a range of approximately -3.40282×10^38 to +3.40282×10^38; the ``float`` type is subject to the same +:ref:`overflow issues <lang-variables-rollover>` as any numeric data +type. + +``float``\ s have only 6-7 decimal digits of precision. That means the +total number of digits, not the number to the right of the decimal +point. You can get more precision by using a :ref:`double +<lang-double>` (which has a precision of about 16 decimal digits). + +The following example declares a ``float`` value named ``myfloat``:: + + float myfloat; + +This example declares a ``float`` value named ``sensorCalibrate``, +with value 1.117:: + + float sensorCalibrate = 1.117; + +The general syntax for declaring a float named ``var`` with value +``val`` is:: + + float var = val; + +Here is a more extended example involving a :ref:`float cast +<lang-floatcast>`:: + + int x; + int y; + float z; + + x = 1; + y = x / 2; // y now contains 0, ints can't hold fractions + z = float(x) / 2; // z now contains .5 + +See Also +-------- + +- :ref:`double <lang-double>` +- :ref:`Variables <lang-variables>` + +.. include:: cc-attribution.txt diff --git a/source/lang/floatcast.rst b/source/lang/floatcast.rst new file mode 100644 index 0000000..7476188 --- /dev/null +++ b/source/lang/floatcast.rst @@ -0,0 +1,31 @@ +.. highlight:: cpp + +.. _lang-floatcast: + +float() (cast) +============== + +Description +----------- + +Converts a value to the :ref:`float <lang-float>` data type. Here +is an example (see the :ref:`constants reference +<lang-constants-fp-f>` for an explanation of the "2.0f"):: + + int x = 2; + float f = float(x); // f now holds 2.0f, a float value + +The value ``x`` can be of any type. However, if ``x`` is not a number +(like an ``int``), you will get strange results. + +See the :ref:`float <lang-float>` reference for details about the +precision and limitations of ``float`` values on the Maple. + +See Also +-------- + +- :ref:`float <lang-float>` +- :ref:`double <lang-double>` +- :ref:`double() <lang-doublecast>` + +.. include:: cc-attribution.txt diff --git a/source/lang/for.rst b/source/lang/for.rst new file mode 100644 index 0000000..6b00d7a --- /dev/null +++ b/source/lang/for.rst @@ -0,0 +1,142 @@ +.. highlight:: cpp + +.. _lang-for: + +for Loops +========= + +.. contents:: Contents + :local: + +Description +----------- + +A ``for`` loop is used to repeat a block of statements enclosed in +curly braces. ``for`` loops are useful for performing repetitive +operations, and are often used in combination with :ref:`arrays +<lang-array>` to operate on collections of data or multiple +:ref:`pins <gpio>`. A ``for`` loop is composed of two parts: first, a +*header*, which sets up the for loop, and then a *body*, which is made +up of lines of code enclosed in curly braces. + +There are three parts to the ``for`` loop header: an *initialization* +expression, *loop condition* expression, and a *post-loop* +expression. The general syntax looks like this:: + + for (initialization; condition; post-loop) { + // all of these lines inside the curly braces are part + // of the loop body. + statement 1; + statement 2; + ... + } + +(Note that there is no semicolon after the post-loop). The +initialization happens first and exactly once, before the loop begins. +Each time through the loop, the condition is tested. The condition is +a :ref:`boolean <lang-boolean>` expression. If it is true, then the +list of statements inside the curly braces are executed. Next, the +post-loop is executed. The loop then begins again by evaluating the +condition again, entering the loop body if it is true. This proceeds +until the condition becomes false. + +Examples +-------- + +Here's an example:: + + // Dim an LED using a PWM pin + int pwmPin = 9; // LED in series with 470 ohm resistor on pin 9 + + void setup() { + pinMode(pwmPin, PWM); + } + + void loop() { + for (int i=0; i <= 65535; i++) { + pwmWrite(pwmPin, i); + delay(1); + } + } + +There is a ``for`` loop In the :ref:`loop() <lang-loop>` function of +the above example. This loop starts by declaring an ``int`` variable +named ``i``, whose value starts out at zero. The loop proceeds by +checking if ``i`` is less than or equal to 65535. Since ``i`` is +zero, this is true, and so the calls to :ref:`pwmWrite() +<lang-pwmwrite>` and :ref:`delay() <lang-delay>` happen next. At this +point, the post-loop expression ``i++`` is evaluated, which +:ref:`increments <lang-increment>` ``i``, so that ``i`` becomes one. +That concludes the first time through the loop. Each "time through +the loop" is referred to as an *iteration*. + +The loop then jumps back to the beginning, checking the condition as +the beginning of its second iteration (initialization is skipped, +since this only happens once, before the first iteration). One is +less than 65535, so the loop statements are executed again. This +proceeds over and over until the iteration when ``i`` finally +reaches 65536. At that point, the condition is no longer true, so the +loop stops executing, and the ``loop()`` function returns. + +Here's another example, using a ``for`` loop to brighten and fade an +LED (see the :ref:`pwmWrite() <lang-pwmwrite>` reference for more +information):: + + int pwmPin = 9; // hook up the LED to pin 9 + void loop() { + int x = 1; + for (int i = 0; i >= 0; i += x) { + analogWrite(pwmPin, i); // controls the brightness of the LED + if (i == 65535) { + x = -1; // switch direction, so i starts decreasing + } + delay(1); + } + } + +Coding Tips +----------- + +The C ``for`` loop is more flexible than ``for`` loops found in some +other computer languages, including BASIC. Any or all of the three +header elements may be left blank, although the semicolons are +required. Also the statements for initialization, condition, and +post-loop can be any valid C statements, and use any C datatypes, +including :ref:`floating point numbers <lang-double>`. These types +of unusual ``for`` loops sometimes provide solutions to less-common +programming problems. + +For example, using a multiplication in the post-loop line will +generate a `geometric progression +<http://en.wikipedia.org/wiki/Geometric_progression>`_:: + + for(int x = 1; x <= 100; x = x * 2) { + SerialUSB.println(x); + } + + +This loop prints out the numbers 1, 2, 4, 8, ..., 64. Check +your understanding of ``for`` loops by answering the following two +questions (answers are in footnote [#fanswers]_\ ): + +1. How many iterations occur before the loop finishes? + +2. Why does it stop at 64? + +See also +-------- + +- :ref:`while <lang-while>` loops +- :ref:`do <lang-dowhile>` loops + +.. rubric:: Footnotes + +.. [#fanswers] + 1. Seven. + + 2. After the seventh iteration, the post-loop causes ``x`` to + equal 128. This is larger than 100, so the loop condition is + false, and the loop stops. + + +.. include:: cc-attribution.txt diff --git a/source/lang/goto.rst b/source/lang/goto.rst new file mode 100644 index 0000000..96a6262 --- /dev/null +++ b/source/lang/goto.rst @@ -0,0 +1,130 @@ +.. highlight:: cpp + +.. _lang-goto: + +Labels and goto +=============== + +A *label* gives a name to a line of code within a function. You can +label a line by writing a name for it, then a colon (``:``), before +the line starts. The ``goto`` keyword allows program flow to transfer +to a labeled line from anywhere within the same function. + +.. warning:: The use of ``goto`` is discouraged in C and C++ + programming. It is *never necessary* to use ``goto`` to write a + program. + + Unless you know what you're doing, using ``goto`` tends to + encourage code which is harder to debug and understand than + programs without ``goto`` that do the same thing. That said, + however, it's sometimes useful; :ref:`see below <goto-when-to-use>` + for a concrete example. + +Using Labels and goto +--------------------- + +Labels and ``goto`` are probably best explained through example. +Let's start with an example of how to label lines. The first line +(``int x = analogRead(some_pin);``) in the :ref:`loop <lang-loop>` +function below has label ``readpin``. The third line (``delay(x);``) +has label ``startdelay``. The second line (``SerialUSB.println(x);``) +does not have a label:: + + void loop() { + readpin: + int x = analogRead(some_pin); + SerialUSB.println(x); // for debugging + startdelay: + delay(x); + // ... more code ... + } + +Anything which can be a :ref:`variable <lang-variables>` name can +be a label. + +Let's say that we wanted to print ``x`` only if it was very large, say +at least 2000. We might want to do this just so anybody watching on a +:ref:`serial monitor <ide-serial-monitor>` would know they were in for +a longer wait than usual. We can accomplish this through the use of a +``goto`` statement that skips the printing if ``x`` is less than +2000:: + + void loop() { + readpin: + int x = analogRead(some_pin); + if (x < 2000) { + goto startdelay; + } + SerialUSB.println(x); // for debugging + startdelay: + delay(x); + // ... more code ... + } + +In this modified program, whenever ``x`` is less than 2000, the body +of the :ref:`if <lang-if>` statement in the second line is +executed. The ``goto`` statement inside the ``if`` body skips +straight to the line labeled ``startdelay``, passing over the line +doing the printing. + +A ``goto`` does not have to "move forwards"; it can go "backwards", +too. For example, the following program prints "5" forever (why?):: + + void loop() { + printfive: + SerialUSB.println(5); + goto printfive; + SerialUSB.println(6); + } + +.. _goto-when-to-use: + +When to Use goto +---------------- + +As mentioned above, use of ``goto`` is `generally discouraged +<http://en.wikipedia.org/wiki/Goto#Criticism_and_decline>`_. However, +when used with care, ``goto`` can simplify certain programs. One +important use case for ``goto`` is breaking out of deeply nested +:ref:`for <lang-for>` loops or :ref:`if <lang-if>` logic blocks. +Here's an example:: + + for(int r = 0; r < 255; r++) { + for(int g = 255; g > -1; g--) { + for(int b = 0; b < 255; b++) { + if (analogRead(0) > 250) { + goto bailout; + } + // more statements ... + } + // innermost loop ends here + } + } + bailout: + // more code here + +In the above example, whenever the :ref:`analog reading +<lang-analogread>` on pin 0 was greater than 250, the program would +jump to the line labeled ``bailout``, exiting all three loops at once. + +While there is already a :ref:`break <lang-break>` keyword for +breaking out of a loop, it will only break out of the *innermost* +loop. So, if instead of saying "``goto bailout;``", there was a +"``break;``" instead, the program would only exit from the loop with +header "``for(int b = 0; b < 255; b++)``". The program would continue +at the line which reads "``// innermost loop ends here``", which is +clearly undesirable if you wanted to leave all three loops at once. + +More examples of when ``goto`` is a good choice are given in Donald +Knuth's paper, "Structured Programming with go to Statements"; see +below for a link. + +See Also +-------- + +- Dijkstra, Edsger W. `Go To Statement Considered Harmful <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.92.4846&rep=rep1&type=pdf>`_ (PDF) + +- Knuth, Donald. `Structured Programming with go to Statements <http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf>`_ (PDF) + + +.. include:: cc-attribution.txt diff --git a/source/lang/highbyte.rst b/source/lang/highbyte.rst new file mode 100644 index 0000000..af0bfcd --- /dev/null +++ b/source/lang/highbyte.rst @@ -0,0 +1,53 @@ +.. _lang-highbyte: + +highByte(x) +=========== + +.. warning:: This macro is provided for compatibility with Arduino + only. It returns the second-least significant byte in an integral + value. It makes sense to call this the "high" byte on a 16-bit + ``int`` microcontroller like the Atmel chips on Arduinos, but it + makes no sense at all on a 32-bit microcontroller like the STM32s + in the Maple line. + + In short: we provide this so that existing Arduino code works as + expected, but **strongly discourage its use** in new programs. + +Description +----------- + +(Macro) Extracts the second lowest byte of an integral data type. + +Parameters +---------- + +**x**: a value of any integral type. + +Returns +------- + +Second lowest byte in **x**. + +Example +------- + +:: + + int x = 0xDEADBEEF; + SerialUSB.println(x, HEX); // prints "BE" + +Arduino Compatibility +--------------------- + +The Maple version of ``highByte()`` is compatible with Arduino. + +See Also +-------- + +- :ref:`lowByte() <lang-lowbyte>` + + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/if.rst b/source/lang/if.rst new file mode 100644 index 0000000..02ba1e7 --- /dev/null +++ b/source/lang/if.rst @@ -0,0 +1,81 @@ +.. highlight:: cpp + +.. _lang-if: + +if Statements +============= + +An ``if`` statement is used to execute code when certain conditions +are met. The general syntax for an ``if`` statement is:: + + if (condition) { + body + } + +An ``if`` statement first tests whether its *condition* is true (such +as an input being above a certain number). If the condition is true, +the ``if`` statement executes its *body*, which is made up of lines of +code inside :ref:`curly braces <lang-braces>`. If the condition is +false, the body is not executed. Here's a more concrete example:: + + if (someVariable > 50) { + // do something here + } + +The program tests to see if ``someVariable`` is greater than 50. If it +is, the program executes every line in the curly braces (which in the +above example does nothing, since the body is just the :ref:`comment +<lang-comments>` line "``// do something here``"). + +Put another way, if the statement in parentheses is true, the +statements inside the braces are run. If not, the program skips over +the code. + +An ``if`` statement's condition (which is inside the parentheses after +``if``) often uses one or more :ref:`boolean <lang-boolean>` or +:ref:`comparison <lang-comparison>` operators. + +Writing the if Body +------------------- + +The brackets may be omitted after an ``if`` statement's +conditional. If this is done, the next line (which ends in a +semicolon) becomes the only line in the body. The following three +``if`` statements all do the same thing:: + + if (x > 120) digitalWrite(ledPin, HIGH); + + if (x > 120) + digitalWrite(ledPin, HIGH); + + if (x > 120) { + digitalWrite(ledPin, HIGH); + } + +However, the following two examples are different:: + + // example 1: two lines of code in the if body + if (x > 120) { + digitalWrite(ledPin1, HIGH); + digitalWrite(ledPin2, HIGH); + } + + // example 2: one line of code in the if body, and + // another line of code after the if statement + if (x > 120) + digitalWrite(ledPin1, HIGH); // this is in the if body + digitalWrite(ledPin2, HIGH); // this is NOT in the if body + +In the first example, since the body is enclosed in curly braces, both +lines are included. In the second example, since the curly braces are +missing, only the first line is in the ``if`` body. + +See Also +-------- + +- :ref:`boolean operators <lang-boolean>` +- :ref:`comparison operators <lang-comparison>` +- :ref:`else <lang-else>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/include.rst b/source/lang/include.rst new file mode 100644 index 0000000..a8bc74c --- /dev/null +++ b/source/lang/include.rst @@ -0,0 +1,71 @@ +.. highlight:: cpp + +.. _lang-include: + +#include +======== + +``#include`` is used to include outside libraries in your sketch. +This gives the programmer access to a large group of standard C +libraries (groups of pre-made functions and data types), and also +libraries written especially for Maple. + +Example +------- + +This example (from the `Arduino LiquidCrystal Tutorial +<http://arduino.cc/en/Tutorial/LiquidCrystal>`_) includes a library +that is used to control :ref:`LCD displays <liquid-crystal>`:: + + // include the library code: + #include <LiquidCrystal.h> + + // initialize the library with the numbers of the interface pins + LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + + void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // Print a message to the LCD. + lcd.print("hello, world!"); + } + + void loop() { + // set the cursor to column 0, line 1 + // (note: line 1 is the second row, since counting begins with 0): + lcd.setCursor(0, 1); + // print the number of seconds since reset: + lcd.print(millis()/1000); + } + +Note that a ``#include`` line, like :ref:`#define <lang-define>`, +has **no semicolon**. The compiler will print strange error messages +if you add one. + +C Standard Library +------------------ + +The standard C library that comes with Maple is called `newlib +<http://sourceware.org/newlib/>`_. Its main sources of documentation +are its `main reference <http://sourceware.org/newlib/libc.html>`_ +page and its `math functions +<http://sourceware.org/newlib/libm.html>`_ reference page. Here's an +example that imports the math.h library in order to take the `cube +root <http://en.wikipedia.org/wiki/Cube_root>`_ of a number:: + + #include <math.h> + + void setup() { + // no setup necessary + } + + void loop() { + // "cbrt" stands for "cube root" + double cubeRootOf3 = cbrt(3.0); + // prints a number that is approximately the cube root of 3: + SerialUSB.println(cubeRootOf3); + } + + + +.. include:: cc-attribution.txt diff --git a/source/lang/increment.rst b/source/lang/increment.rst new file mode 100644 index 0000000..5536a0a --- /dev/null +++ b/source/lang/increment.rst @@ -0,0 +1,44 @@ +.. highlight:: cpp + +.. _lang-increment: + +Increment (``++``) and Decrement (``--``) +========================================= + +These operators increment (add one to) or decrement (subtract one +from) a variable. If they come before the variable, they return its +new value; otherwise, they return its old value. + +Some quick examples:: + + x++; // adds one to x, and returns the old value of x + ++x; // adds one to x, and returns the new value of x + + x--; // decrement x by one and returns the old value of x + --x; // decrement x by one and returns the new value of x + +A more extended example:: + + x = 2; + y = ++x; // x now contains 3, y contains 3 + y = x--; // x contains 2 again, y still contains 3 + +.. warning:: Be careful! You cannot put a space in between the two + ``+`` or ``-`` signs. This example is broken:: + + // this line won't compile (notice the extra space): + int y = x+ +; + +Parameters +---------- + +**x**: an integer value (like an ``int``, ``long``, ``unsigned int``, +etc.). + +See also +-------- + +- :ref:`Compound arithmetic operators <lang-arithmeticcompound>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/int.rst b/source/lang/int.rst new file mode 100644 index 0000000..ac2f16a --- /dev/null +++ b/source/lang/int.rst @@ -0,0 +1,67 @@ +.. highlight:: cpp + +.. _lang-int: + +int +=== + +Description +----------- + +The ``int`` data type represents integers. Integers are your primary +data type for number storage, and store a 4 byte value. This yields a +range of -2,147,483,648 to 2,147,483,647 (minimum value of -2^31 and a +maximum value of (2^31) - 1; that's about negative 2 billion to +positive 2 billion). + +An ``int`` stores a negative number with a technique called `two's +complement math +<http://en.wikipedia.org/wiki/Two%27s_complement#Explanation>`_\ . +The highest bit in an ``int``, sometimes refered to as the "sign" bit, +flags the number as a negative number. (See the linked article on +two's complement for more information). + +The Maple takes care of dealing with negative numbers for you, so that +arithmetic operations work mostly as you'd expect. There can be an +:ref:`unexpected complication <lang-bitshift-signbit-gotcha>` in +dealing with the :ref:`bitshift right operator (>>) +<lang-bitshift>`, however. + +Here is an example of declaring an ``int`` variable named ``ledPin``, +then giving it value 13:: + + int ledPin = 13; + +The general syntax for declaring an ``int`` variable named ``var``, +then giving it value ``val``, looks like:: + + int var = val; + +.. _lang-int-overflow: + +Integer Overflow +---------------- + +When ``int`` variables leave the range specified above, they +:ref:`roll over <lang-variable-rollover>` in the other direction. +Here are some examples:: + + int x; + x = -2,147,483,648; + x--; // x now contains 2,147,483,647; rolled over "left to right" + + x = 2,147,483,647; + x++; // x now contains -2,147,483,648; rolled over "right to left" + +See Also +-------- + +- :ref:`unsigned int <lang-unsignedint>` +- :ref:`char <lang-char>` +- :ref:`unsigned char <lang-unsignedchar>` +- :ref:`long <lang-long>` +- :ref:`unsigned long <lang-unsignedlong>` +- :ref:`Integer Constants <lang-constants-integers>` +- :ref:`Variables <lang-variables>` + +.. include:: cc-attribution.txt diff --git a/source/lang/intcast.rst b/source/lang/intcast.rst new file mode 100644 index 0000000..03c0c07 --- /dev/null +++ b/source/lang/intcast.rst @@ -0,0 +1,32 @@ +.. highlight:: cpp + +.. _lang-intcast: + +int() +===== + +Description +----------- + +Converts a value to the :ref:`int <lang-int>` data type. Here is +an example:: + + double d = 2.5; + int i = int(d); // i holds "2", an int value + +The value inside of the parentheses (``int(...)``) can be of any type. +However, if it is not a numeric type (like ``double``, ``char``, +etc.), you will get strange results. + +See the :ref:`int <lang-int>` reference for details about the +precision and limitations of ``int`` variables on the Maple. + +See Also +-------- + +- :ref:`int <lang-int>` + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/interrupts.rst b/source/lang/interrupts.rst new file mode 100644 index 0000000..5ca7041 --- /dev/null +++ b/source/lang/interrupts.rst @@ -0,0 +1,62 @@ +.. _lang-interrupts: + +interrupts() +============ + +Description +----------- + +Re-enables interrupts (after they've been disabled by +`noInterrupts <http://arduino.cc/en/Reference/NoInterrupts>`_\ ()). +Interrupts allow certain important tasks to happen in the +background and are enabled by default. Some functions will not work +while interrupts are disabled, and incoming communication may be +ignored. Interrupts can slightly disrupt the timing of code, +however, and may be disabled for particularly critical sections of +code. + + + +Parameters +---------- + +None + + + +Returns +------- + +None + + + +Example +------- + +:: + + void setup() {} + + void loop() + { + noInterrupts(); + // critical, time-sensitive code here + interrupts(); + // other code here + } + + + +See Also +-------- + + +- `noInterrupts <http://arduino.cc/en/Reference/NoInterrupts>`_\ () +- `attachInterrupt <http://arduino.cc/en/Reference/AttachInterrupt>`_\ () +- `detachInterrupt <http://arduino.cc/en/Reference/DetachInterrupt>`_\ () + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/keywords.rst b/source/lang/keywords.rst new file mode 100644 index 0000000..451701e --- /dev/null +++ b/source/lang/keywords.rst @@ -0,0 +1,11 @@ +.. _lang-keywords: + +Keywords +======== + +Stub. + +Include list of all C++ keywords, with links to internal documentation +as appropriate. + +Reference this page from language.rst diff --git a/source/lang/long.rst b/source/lang/long.rst new file mode 100644 index 0000000..8a19b2b --- /dev/null +++ b/source/lang/long.rst @@ -0,0 +1,55 @@ +.. highlight:: cpp + +.. _lang-long: + +long +==== + +Description +----------- + +The ``long`` data type stores extended size integer values. You can +use a ``long`` when your values are too large to fit into an :ref:`int +<lang-int>`. A ``long`` occupies 8 bytes of memory. This yields a +range of approximately -9.2×10^18 to 9.2×10^18 (that's 9.2 billion +billion, or about 92 million times the number of stars in the Milky +Way galaxy). The exact range of a ``long`` on the Maple is from +-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807, or -2^63 to +(2^63-1). A ``long`` it is subject to the same :ref:`overflow issues +<lang-variables-rollover>` as any numeric data type. + +Here's an example of declaring a long (see :ref:`integer constants +<lang-constants-u-l>` for an explanation of the "L" at the end of the +number):: + + // Speed of light in nanometers per second (approximate). + long c = 299792458000000000L; + +The general syntax for declaring an ``long`` variable named ``var``, +then giving it value ``val``, looks like:: + + long var = val; + +This is identical to the ``int`` syntax, with ``long`` replacing +``int``. + +Note that ``long`` values will still :ref:`overflow +<lang-int-overflow>`, just like ``int`` values, but their much +larger range makes this less likely to happen. + +The downside to using a ``long`` instead of an ``int`` (besides the +extra storage) is that :ref:`arithmetic <lang-arithmetic>` operations +on ``long``\ s will take slightly longer than on ``int``\ s. + +See Also +-------- + +- :ref:`char <lang-char>` +- :ref:`unsigned char <lang-unsignedchar>` +- :ref:`int <lang-int>` +- :ref:`unsigned int <lang-unsignedint>` +- :ref:`unsigned long <lang-unsignedlong>` +- :ref:`Integer Constants <lang-constants-integers>` +- :ref:`Variables <lang-variables>` + +.. include:: cc-attribution.txt diff --git a/source/lang/longcast.rst b/source/lang/longcast.rst new file mode 100644 index 0000000..16d7582 --- /dev/null +++ b/source/lang/longcast.rst @@ -0,0 +1,30 @@ +.. highlight:: cpp + +.. _lang-longcast: + +long() +====== + +Description +----------- + +Converts a value to the :ref:`long <lang-long>` data type. Here is +an example:: + + double d = 2.5; + long i = long(d); // i holds "2L", an long value + +The value inside of the parentheses (``long(...)``) can be of any type. +However, if it is not a numeric type (like ``double``, ``char``, +etc.), you will get strange results. + +See the :ref:`long <lang-long>` reference for details about the +precision and limitations of ``long`` variables on the Maple. + +See Also +-------- + +- :ref:`long <lang-long>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/loop.rst b/source/lang/loop.rst new file mode 100644 index 0000000..d8f6183 --- /dev/null +++ b/source/lang/loop.rst @@ -0,0 +1,45 @@ +.. highlight:: cpp + +.. _lang-loop: + +loop() +====== + +After creating a :ref:`setup() <lang-setup>` function, which +initializes your sketch, the ``loop()`` function gets called +repeatedly, allowing your program to change and respond. Use it to +actively control your Maple board. + +Example +------- + +:: + + + int buttonPin = 38; + + // setup initializes serial and the button pin + void setup() { + SerialUSB.begin(); + pinMode(buttonPin, INPUT); + } + + // loop() checks the button pin each time it executes, + // and will print 'H' if it is pressed, 'L' otherwise + void loop() { + if (digitalRead(buttonPin) == HIGH) { + SerialUSB.println('H'); + } else { + SerialUSB.println('L'); + } + + delay(1000); + } + +See Also +-------- + +- :ref:`setup() <lang-setup>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/lowbyte.rst b/source/lang/lowbyte.rst new file mode 100644 index 0000000..f9fb711 --- /dev/null +++ b/source/lang/lowbyte.rst @@ -0,0 +1,45 @@ +.. _lang-lowbyte: + +lowByte() +========= + +Description +----------- + +Extracts the low-order (rightmost) byte of a variable (e.g. a +word). + + + +Syntax +------ + +lowByte(x) + + + +Parameters +---------- + +x: a value of any type + + + +Returns +------- + +byte + + + +See also +-------- + + +- `highByte <http://arduino.cc/en/Reference/HighByte>`_\ () +- `word <http://arduino.cc/en/Reference/WordCast>`_\ () + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/map.rst b/source/lang/map.rst new file mode 100644 index 0000000..40b12a8 --- /dev/null +++ b/source/lang/map.rst @@ -0,0 +1,122 @@ +.. _lang-map: + +map(value, fromLow, fromHigh, toLow, toHigh) +============================================ + +Description +----------- + +Re-maps a number from one range to another. That is, a **value** of +**fromLow** would get mapped to **toLow**, a value of **fromHigh** +to **toHigh**, values in-between to values in-between, etc. + + + +Does not constrain values to within the range, because out-of-range +values are sometimes intended and useful. The constrain() function +may be used either before or after this function, if limits to the +ranges are desired. + + + +Note that the "lower bounds" of either range may be larger or +smaller than the "upper bounds" so the map() function may be used +to reverse a range of numbers, for example + + + +``y = map(x, 1, 50, 50, 1);`` + + + +The function also handles negative numbers well, so that this +example + + + +``y = map(x, 1, 50, 50, -100);`` + + + +is also valid and works well. + + + +The map() function uses integer math so will not generate +fractions, when the math might indicate that it should do so. +Fractional remainders are truncated, and are not rounded or +averaged. + + + +Parameters +---------- + +value: the number to map + + + +fromLow: the lower bound of the value's current range + + + +fromHigh: the upper bound of the value's current range + + + +toLow: the lower bound of the value's target range + + + +toHigh: the upper bound of the value's target range + + + +Returns +------- + +The mapped value. + + + +Example +------- + +:: + + /* Map an analog value to 8 bits (0 to 255) */ + void setup() {} + + void loop() + { + int val = analogRead(0); + val = map(val, 0, 1023, 0, 255); + analogWrite(9, val); + } + + + +Appendix +~~~~~~~~ + +For the mathematically inclined, here's the whole function + + + +:: + + long map(long x, long in_min, long in_max, long out_min, long out_max) + { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + } + + + +See Also +-------- + + +- `constrain <http://arduino.cc/en/Reference/Constrain>`_\ () + + +.. include:: cc-attribution.txt diff --git a/source/lang/max.rst b/source/lang/max.rst new file mode 100644 index 0000000..7dbf6a7 --- /dev/null +++ b/source/lang/max.rst @@ -0,0 +1,63 @@ +.. highlight:: cpp + +.. _lang-max: + +max(x, y) +========= + +Description +----------- + +(Macro) Calculates the maximum of two numbers. + + + +Parameters +---------- + +**x**: the first number; may be any number or numeric expression. + +**y**: the second number; may be any number or numeric expression. + + +Returns +------- + +The larger of the two parameter values. + +Example +------- + +:: + + sensVal = max(senVal, 20); // assigns sensVal to the larger of sensVal or 20 + // (effectively ensuring that it is at least 20) + +.. note:: Perhaps counter-intuitively, max() is often used to + constrain the lower end of a variable's range, while :ref:`min() + <lang-min>` is used to constrain the upper end of the range. + +Warning +------- + +Because of the way ``max()`` is implemented, avoid using other +functions inside the parentheses. It may lead to incorrect results:: + + max(a--, 0); // avoid this - yields incorrect results + + a--; // use this instead - + max(a, 0); // keep other operations outside max() + +Arduino Compatibility +--------------------- + +The Maple version of ``max()`` is compatible with Arduino. + +See Also +-------- + +- :ref:`min() <lang-min>` +- :ref:`constrain() <lang-constrain>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/micros.rst b/source/lang/micros.rst new file mode 100644 index 0000000..711c013 --- /dev/null +++ b/source/lang/micros.rst @@ -0,0 +1,69 @@ +.. _lang-micros: + +micros() +======== + +Description +----------- + +Returns the number of microseconds since the Arduino board began +running the current program. This number will overflow (go back to +zero), after approximately 70 minutes. On 16 MHz Arduino boards +(e.g. Duemilanove and Nano), this function has a resolution of four +microseconds (i.e. the value returned is always a multiple of +four). On 8 MHz Arduino boards (e.g. the LilyPad), this function +has a resolution of eight microseconds. + + + +*Note*: there are 1,000 microseconds in a millisecond and 1,000,000 +microseconds in a second. + + + +Parameters +---------- + +None + + + +Returns +------- + +Number of microseconds since the program started (*unsigned long*) + + + +Example +------- + +:: + + unsigned long time; + + void setup(){ + Serial.begin(9600); + } + void loop(){ + Serial.print("Time: "); + time = micros(); + //prints time since program started + Serial.println(time); + // wait a second so as not to send massive amounts of data + delay(1000); + } + + + +See also +-------- + + +- `millis <http://arduino.cc/en/Reference/Millis>`_\ () +- `delay <http://arduino.cc/en/Reference/Delay>`_\ () +- `delayMicroseconds <http://arduino.cc/en/Reference/DelayMicroseconds>`_\ () + + + +.. include:: cc-attribution.txt diff --git a/source/lang/millis.rst b/source/lang/millis.rst new file mode 100644 index 0000000..6ebfff5 --- /dev/null +++ b/source/lang/millis.rst @@ -0,0 +1,70 @@ +.. _lang-millis: + +millis() +======== + +Description +----------- + +Returns the number of milliseconds since the Arduino board began +running the current program. This number will overflow (go back to +zero), after approximately 50 days. + + + +Parameters +---------- + +None + + + +Returns +------- + +Number of milliseconds since the program started (*unsigned long*) + + + +Example +------- + +:: + + unsigned long time; + + void setup(){ + Serial.begin(9600); + } + void loop(){ + Serial.print("Time: "); + time = millis(); + //prints time since program started + Serial.println(time); + // wait a second so as not to send massive amounts of data + delay(1000); + } + + + +Tip: +---- + +Note that the parameter for millis is an unsigned long, errors may +be generated if a programmer tries to do math with other datatypes +such as ints. + + + +See also +-------- + + +- `micros <http://arduino.cc/en/Reference/Micros>`_\ () +- `delay <http://arduino.cc/en/Reference/Delay>`_\ () +- `delayMicroseconds <http://arduino.cc/en/Reference/DelayMicroseconds>`_\ () +- `Tutorial: Blink Without Delay <http://arduino.cc/en/Tutorial/BlinkWithoutDelay>`_ + + + +.. include:: cc-attribution.txt diff --git a/source/lang/min.rst b/source/lang/min.rst new file mode 100644 index 0000000..ffbf1ee --- /dev/null +++ b/source/lang/min.rst @@ -0,0 +1,66 @@ +.. highlight:: cpp + +.. _lang-min: + +min(x, y) +========= + +Description +----------- + +(Macro) Calculates the minimum of two numbers. + + + +Parameters +---------- + +**x**: the first number; may be any number or numeric expression. + +**y**: the second number; may be any number or numeric expression. + + +Returns +------- + +The smaller of the two numbers. + + +Example +------- + +:: + + sensVal = min(sensVal, 100); // assigns sensVal to the smaller of sensVal or 100 + // ensuring that it never gets above 100. + + +.. note:: Perhaps counter-intuitively, max() is often used to + constrain the lower end of a variable's range, while min() is used + to constrain the upper end of the range. + + +Warning +------- + +Because of the way ``min()`` is implemented, avoid using other +functions inside the parentheses. It may lead to incorrect results:: + + min(a++, 100); // avoid this - yields incorrect results + + a++; // use this instead - + min(a, 100); // keep other operations outside min() + +Arduino Compatibility +--------------------- + +The Maple version of ``min()`` is compatible with Arduino. + +See Also +-------- + +- :ref:`max() <lang-max>` +- :ref:`constrain() <lang-constrain>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/modulo.rst b/source/lang/modulo.rst new file mode 100644 index 0000000..9e0dabd --- /dev/null +++ b/source/lang/modulo.rst @@ -0,0 +1,77 @@ +.. highlight:: cpp + +.. _lang-modulo: + +% (modulo) +========== + +Description +----------- + +Calculates the `remainder <http://en.wikipedia.org/wiki/Remainder>`_ +when one integer is divided by another. It is useful for keeping a +variable within a particular range (e.g. the size of an array). + +Syntax +------ + +:: + + result = dividend % divisor + + + +Parameters +---------- + +**dividend**: the number to be divided + +**divisor**: the number to divide by + +Returns +------- + +The remainder of **dividend**\ /\ **divisor**\ . + +Examples +-------- + +:: + + int x; + x = 7 % 5; // x now contains 2 + x = 9 % 5; // x now contains 4 + x = 5 % 5; // x now contains 0 + x = 4 % 5; // x now contains 4 + +:: + + /* update one value in an array each time through a loop */ + + int values[10]; + int i = 0; + + void setup() { + // no setup necessary + } + + void loop() { + values[i] = analogRead(0); + i = (i + 1) % 10; // modulo operator makes sure i stays between 0 and 9 + } + +Tip +--- + +The modulo operator does not work on floats. For that, you can use +the C standard library function `fmod() +<http://sourceware.org/newlib/libm.html#fmod>`_. + + +See Also +-------- + +- :ref:`Arithmetic <lang-arithmetic>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/nointerrupts.rst b/source/lang/nointerrupts.rst new file mode 100644 index 0000000..2043c91 --- /dev/null +++ b/source/lang/nointerrupts.rst @@ -0,0 +1,59 @@ +.. _lang-nointerrupts: + +noInterrupts() +============== + +Description +----------- + +Disables interrupts (you can re-enable them with interrupts()). +Interrupts allow certain important tasks to happen in the +background and are enabled by default. Some functions will not work +while interrupts are disabled, and incoming communication may be +ignored. Interrupts can slightly disrupt the timing of code, +however, and may be disabled for particularly critical sections of +code. + + + +Parameters +---------- + +None. + + + +Returns +------- + +None. + + + +Example +------- + +:: + + void setup() {} + + void loop() + { + noInterrupts(); + // critical, time-sensitive code here + interrupts(); + // other code here + } + + + +See Also +-------- + + +- `interrupts <http://arduino.cc/en/Reference/Interrupts>`_\ () + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/notone.rst b/source/lang/notone.rst new file mode 100644 index 0000000..22432e2 --- /dev/null +++ b/source/lang/notone.rst @@ -0,0 +1,50 @@ +.. _lang-notone: + +noTone() +======== + +Description +----------- + +Stops the generation of a square wave triggered by +`tone <http://arduino.cc/en/Reference/Tone>`_\ (). Has no effect if +no tone is being generated. + + + +**NOTE:** if you want to play different pitches on multiple pins, +you need to call noTone() on one pin before calling tone() on the +next pin. + + + +Syntax +------ + +noTone(pin) + + + +Parameters +---------- + +pin: the pin on which to stop generating the tone + + + +Returns +------- + +nothing + + + +See also +-------- + + +- `tone <http://arduino.cc/en/Reference/Tone>`_ () + + + +.. include:: cc-attribution.txt diff --git a/source/lang/pinmode.rst b/source/lang/pinmode.rst new file mode 100644 index 0000000..aed23d6 --- /dev/null +++ b/source/lang/pinmode.rst @@ -0,0 +1,76 @@ +.. highlight:: cpp + +.. _lang-pinmode: + +pinMode() +========= + +.. contents:: Contents + :local: + +Library Documentation +--------------------- + +.. doxygenfunction:: pinMode + +.. doxygenenum:: WiringPinMode + +Discussion +---------- + +pinMode() is usually called within :ref:`lang-setup` in order to +configure a pin for a certain usage (although it may be called +anywhere). + + +Example +------- + + :: + + + int ledPin = 13; // LED connected to digital pin 13 + + void setup() + { + pinMode(ledPin, OUTPUT); // sets the digital pin as output + } + + void loop() + { + digitalWrite(ledPin, HIGH); // sets the LED on + delay(1000); // waits for a second + digitalWrite(ledPin, LOW); // sets the LED off + delay(1000); // waits for a second + } + + + +Arduino Compatibility +--------------------- + +The libmaple implementation of pinMode() supports OUTPUT and INPUT +modes with a meaning identical to that of the Arduino function. + +INPUT_ANALOG and PWM modes were added because the Maple does not +distinguish between analog and digital pins the same way the Arduino +does. Unlike the Arduino, you **must call pinMode**\ () to set up a pin +for these purposes before a call to, e.g., :ref:`lang-analogRead`. +In practice, this should only add a few lines of pinMode() calls to +your :ref:`lang-setup` function. + +OUTPUT_OPEN_DRAIN, INPUT_PULLUP, INPUT_PULLDOWN, and PWM_OPEN_DRAIN +modes represent functionality not currently available on Arduino +boards. + +See also +-------- + +- :ref:`lang-constants` +- :ref:`lang-digitalwrite` +- :ref:`lang-digitalread` +- Maple :ref:`GPIO <gpio>` reference page + + + +.. include:: cc-attribution.txt diff --git a/source/lang/pointer.rst b/source/lang/pointer.rst new file mode 100644 index 0000000..bc48d7d --- /dev/null +++ b/source/lang/pointer.rst @@ -0,0 +1,28 @@ +.. _lang-pointer: + +The pointer operators: & (reference) and \* (dereference) +========================================================= + + +Pointers are one of the more complicated subjects for beginners in +learning C, and it is possible to write the vast majority of +Arduino sketches without ever encountering pointers. However for +manipulating certain data structures, the use of pointers can +simplify the code, and and knowledge of manipulating pointers is +handy to have in one's toolkit. + +Introducing pointers is somewhat outside the scope of this +documentation. However, a good `pointer tutorial +<http://www.cplusplus.com/doc/tutorial/pointers/>`_ is available. +Also see the `Wikipedia article on pointers +<http://en.wikipedia.org/wiki/Pointer_%28computing%29>`_, especially +the section on `pointers in C +<http://en.wikipedia.org/wiki/Pointer_%28computing%29#C_pointers>`_. + +See Also +======== + +- http://xkcd.com/138/ + + +.. include:: cc-attribution.txt diff --git a/source/lang/pow.rst b/source/lang/pow.rst new file mode 100644 index 0000000..dbe89b6 --- /dev/null +++ b/source/lang/pow.rst @@ -0,0 +1,29 @@ +.. _lang-pow: + +pow(base, exponent) +=================== + +Calculates the value of a number raised to a power. + +Library Documentation +--------------------- + +.. doxygenfunction:: pow + +Example +------- + +``pow()`` can be used to raise a number to a fractional power. This +is useful for e.g. generating exponential mapping of values or +curves. See the `fscale <http://arduino.cc/playground/main/fscale>`_ +function in the Arduino playground for more on this. + +See Also +-------- + +- :ref:`sqrt() <lang-sqrt>` +- :ref:`float <lang-float>` +- :ref:`double <lang-double>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/pulsein.rst b/source/lang/pulsein.rst new file mode 100644 index 0000000..7bbe84c --- /dev/null +++ b/source/lang/pulsein.rst @@ -0,0 +1,82 @@ +.. _lang-pulsein: + +pulseIn() +========= + +Description +----------- + +Reads a pulse (either HIGH or LOW) on a pin. For example, if +**value** is **HIGH**, **pulseIn()** waits for the pin to go +**HIGH**, starts timing, then waits for the pin to go **LOW** and +stops timing. Returns the length of the pulse in microseconds. +Gives up and returns 0 if no pulse starts within a specified time +out. + + + +The timing of this function has been determined empirically and +will probably show errors in longer pulses. Works on pulses from 10 +microseconds to 3 minutes in length. + + + +Syntax +------ + +pulseIn(pin, value) +pulseIn(pin, value, timeout) + + + +Parameters +---------- + +pin: the number of the pin on which you want to read the pulse. +(*int*) + + + +value: type of pulse to read: either +`HIGH <http://arduino.cc/en/Reference/Constants>`_ or +`LOW <http://arduino.cc/en/Reference/Constants>`_. (*int*) + + + +timeout (optional): the number of microseconds to wait for the +pulse to start; default is one second (*unsigned long*) + + + +Returns +------- + +the length of the pulse (in microseconds) or 0 if no pulse started +before the timeout (*unsigned long*) + + + +Example +------- + +:: + + + + int pin = 7; + unsigned long duration; + + void setup() + { + pinMode(pin, INPUT); + } + + void loop() + { + duration = pulseIn(pin, HIGH); + } + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/pwmwrite.rst b/source/lang/pwmwrite.rst new file mode 100644 index 0000000..acc0240 --- /dev/null +++ b/source/lang/pwmwrite.rst @@ -0,0 +1,51 @@ +.. highlight:: cpp + +.. _lang-pwmwrite: + +pwmWrite() +========== + +Writes a :ref:`PWM wave <pwm>` to a pin. You can use this to make an +LED get brighter or dimmer, control a servomotor, etc. After a call to +pwmWrite(), the pin will output a steady square wave with the given +duty cycle. You can change the duty cycle later by calling pwmWrite() +again with the same pin and a different duty. + +.. contents:: Contents + :local: + +Library Documentation +--------------------- + +.. doxygenfunction:: pwmWrite + +Example +------- + +Sets the output to the LED proportional to the value read from the +potentiometer (adapted for Maple from the Arduino `analogWrite() +reference <http://www.arduino.cc/en/Reference/AnalogWrite>`_):: + + + int ledPin = 13; // LED connected to pin 13 (Maple) + int analogPin = 3; // potentiometer connected to analog pin 3 + int val = 0; // variable to store the read value + + void setup() { + pinMode(ledPin, OUTPUT); // sets the LED pin as output + + pinMode(analogPin, PWM); // sets the potentiometer pin as PWM + // output + } + + void loop() { + val = analogRead(analogPin); // read the input pin + + analogWrite(ledPin, val / 16); // analogRead values go from 0 to 4095, + // analogWrite values from 0 to 65535 + } + +See Also +-------- + +- :ref:`Maple PWM tutorial <pwm>` diff --git a/source/lang/random.rst b/source/lang/random.rst new file mode 100644 index 0000000..51bee67 --- /dev/null +++ b/source/lang/random.rst @@ -0,0 +1,95 @@ +.. _lang-random: + +random() +======== + +Description +----------- + +The random function generates pseudo-random numbers. + + + +Syntax +------ + +random(max) +random(min, max) + + + +Parameters +---------- + +min - lower bound of the random value, inclusive *(optional)* + + + +max - upper bound of the random value, exclusive + + + +Returns +------- + +a random number between min and max-1 (*long*) + + + +Note: +----- + +If it is important for a sequence of values generated by random() +to differ, on subsequent executions of a sketch, use randomSeed() +to initialize the random number generator with a fairly random +input, such as analogRead() on an unconnected pin. + + + +Conversely, it can occasionally be useful to use pseudo-random +sequences that repeat exactly. This can be accomplished by calling +randomSeed() with a fixed number, before starting the random +sequence. + + + +Example +------- + +:: + + long randNumber; + + void setup(){ + Serial.begin(9600); + + // if analog input pin 0 is unconnected, random analog + // noise will cause the call to randomSeed() to generate + // different seed numbers each time the sketch runs. + // randomSeed() will then shuffle the random function. + randomSeed(analogRead(0)); + } + + void loop() { + // print a random number from 0 to 299 + randNumber = random(300); + Serial.println(randNumber); + + // print a random number from 10 to 19 + randNumber = random(10, 20); + Serial.println(randNumber); + + delay(50); + } + + + +See also +-------- + + +- `randomSeed <http://arduino.cc/en/Reference/RandomSeed>`_\ () + + + +.. include:: cc-attribution.txt diff --git a/source/lang/randomseed.rst b/source/lang/randomseed.rst new file mode 100644 index 0000000..3dcf4db --- /dev/null +++ b/source/lang/randomseed.rst @@ -0,0 +1,73 @@ +.. _lang-randomseed: + +randomSeed(seed) +================ + +Description +----------- + +randomSeed() initializes the pseudo-random number generator, +causing it to start at an arbitrary point in its random sequence. +This sequence, while very long, and random, is always the same. + + + +If it is important for a sequence of values generated by random() +to differ, on subsequent executions of a sketch, use randomSeed() +to initialize the random number generator with a fairly random +input, such as analogRead() on an unconnected pin. + + + +Conversely, it can occasionally be useful to use pseudo-random +sequences that repeat exactly. This can be accomplished by calling +randomSeed() with a fixed number, before starting the random +sequence. + + + +Parameters +---------- + +long, int - pass a number to generate the seed. + + + +Returns +------- + +no returns + + + +Example +------- + +:: + + long randNumber; + + void setup(){ + Serial.begin(9600); + randomSeed(analogRead(0)); + } + + void loop(){ + randNumber = random(300); + Serial.println(randNumber); + + delay(50); + } + + + +See also +-------- + + +- `random <http://arduino.cc/en/Reference/Random>`_ + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/return.rst b/source/lang/return.rst new file mode 100644 index 0000000..e1b2924 --- /dev/null +++ b/source/lang/return.rst @@ -0,0 +1,61 @@ +.. highlight:: cpp + +.. _lang-return: + +return +====== + +(Keyword) Terminates a function and return a value from a function to +the calling function, if the function has non-``void`` return type. + +Syntax: +------- + +:: + + // from within a "void" function: + return; + + // from within a non-"void" function: + return value; + +In the second case, ``value`` should have a type which is the same as +the return type of the function, or be convertible to it (like an +``int`` to a ``long``, etc.; see :ref:`this note +<lang-arithmetic-typeconversion>` for some references). + +Examples: +--------- + +A function to compare a sensor input to a threshold:: + + // converts analog readings between 0 and 400 to 0, and 400 up to 1. + int checkSensor() { + if (analogRead(0) > 400) { + return 1; + else { + return 0; + } + } + +An early ``return`` is also useful when testing a section of code +without having to "comment out" large sections of possibly buggy code, +like so:: + + void loop() { + + // brilliant code idea to test here + + return; + + // the rest of a dysfunctional sketch here + // this code will never be executed + } + +See Also +-------- + +- :ref:`comments <lang-comments>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/scope.rst b/source/lang/scope.rst new file mode 100644 index 0000000..8e8bb13 --- /dev/null +++ b/source/lang/scope.rst @@ -0,0 +1,120 @@ +.. highlight:: cpp + +.. _lang-scope: + +Variable Scope +============== + +Variables in the C++ programming language, which Maple uses (all of +your sketches are C++ programs in disguise), have a property called +*scope*. Simply put, a variable's scope is made up of all of the +lines where the variable can be used. + +Scope in C++ is a fairly complex topic, so we won't try to describe it +in full here. Instead, we present a simplified view, describing two +different kinds of scopes, *global* and *local*. For more detailed +information, consult a C++ reference. + +Global and Local Variables +-------------------------- + +A global variable is one that can be "seen" by every function in a +program. In the :ref:`Maple IDE <ide>`, any variable declared outside +of a function (like :ref:`setup() <lang-setup>` and :ref:`loop() +<lang-loop>`) is a global variable. + +A local variable can only be "seen" inside of a particular function. +You can declare a variable to be local to a function by declaring it +inside of the :ref:`curly braces <lang-braces>` which enclose that +function. + +When programs start to get larger and more complex, local variables +are a useful way to ensure that a function has exclusive access to its +own variables. This prevents programming errors when one function +mistakenly modifies variables used by another function. + +It is also sometimes useful to declare and initialize a variable +inside a :ref:`for <lang-for>` loop. This creates a variable that +can only be accessed from inside the loop body. + +Example +------- + +Here is an example sketch (which you can copy into the Maple IDE and +run on your Maple) that illustrates the use of global and local +variables, as well as declaring variables inside of a ``for`` loop. +Be sure to open a :ref:`serial monitor <ide-serial-monitor>` after you +:ref:`verify <ide-verify>` and :ref:`upload <ide-upload>` the sketch:: + + int globalVar; // any function will see this variable + + void setup() { + // since "globalVar" is declared outside of any function, + // every function can "see" and use it: + globalVar = 50; + + // the variables "i" and "d" declared inside the "loop" function + // can't be seen here. see what happens when you uncomment the + // following lines, and try to Verify (compile) the sketch: + // + // i = 16; + // SerialUSB.print("i = "); + // SerialUSB.println(i); + // d = 26.5; + // SerialUSB.print("d = "); + // SerialUSB.println(d); + } + + void loop() { + // since "i" and "d" are declared inside of the "loop" function, + // they can only be seen and used from inside of it: + int i; + double d; + + for (int j = 0; j < 5; j++) { + // variable i can be used anywhere inside the "loop" function; + // variable j can only be accessed inside the for-loop brackets: + i = j * j; + SerialUSB.print("i = "); + SerialUSB.println(i); + } + + // globalVar can be accessed from anywhere. note how even + // though we set globalVar = 50 in the "setup" function, we can + // see that value here: + SerialUSB.print("globalVar = "); + SerialUSB.println(globalVar); + + // d can be accessed from anywhere inside the "loop" function: + d = 26.5; + SerialUSB.print("d = "); + SerialUSB.print(d); + SerialUSB.println(" (before separateFunction())"); + + separateFunction(); + + // notice how even though separateFunction() has a variable + // named "d", it didn't touch our (local) variable which has + // the same name: + SerialUSB.print("d = "); + SerialUSB.print(d); + SerialUSB.println(" (after separateFunction())"); + } + + void separateFunction() { + // variable "d" here has the same name as variable "d" inside of + // the "loop" function, but since they're both _local_ + // variables, they don't affect each other: + double d = 30.5; + SerialUSB.print("d = "); + SerialUSB.print(d); + SerialUSB.println(" (inside of separateFunction())"); + } + +See Also +-------- + +- `C++ programming Wikibook <http://en.wikibooks.org/wiki/C%2B%2B_Programming/Programming_Languages/C%2B%2B/Code/Statements/Scope>`_. +- Wikipedia article on `scope <http://en.wikipedia.org/wiki/Scope_%28programming%29>`_ + +.. include:: cc-attribution.txt diff --git a/source/lang/semicolon.rst b/source/lang/semicolon.rst new file mode 100644 index 0000000..4cf7b9f --- /dev/null +++ b/source/lang/semicolon.rst @@ -0,0 +1,25 @@ +.. highlight:: cpp + +.. _lang-semicolon: + +Semicolon (;) +============= + +Used to end a line of code. Example:: + + int a = 13; + +Tip +--- + +Forgetting to end a line in a semicolon will result in a compiler +error. The error text may be obvious, and refer to a missing +semicolon, or it may not. If an impenetrable or seemingly illogical +compiler error comes up, one of the first things to check is a +missing semicolon, in the immediate vicinity, preceding the line at +which the compiler complained. + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/serial.rst b/source/lang/serial.rst new file mode 100644 index 0000000..743f921 --- /dev/null +++ b/source/lang/serial.rst @@ -0,0 +1,68 @@ +.. _lang-serial: + +Serial +====== + +Used for communication between the Arduino board and a computer or +other devices. All Arduino boards have at least one serial port +(also known as a UART or USART): **Serial**. It communicates on +digital pins 0 (RX) and 1 (TX) as well as with the computer via +USB. Thus, if you use these functions, you cannot also use pins 0 +and 1 for digital input or output. + + + +You can use the Arduino environment's built-in serial monitor to +communicate with an Arduino board. Click the serial monitor button +in the toolbar and select the same baud rate used in the call to +begin(). + + + +The Arduino Mega has three additional serial ports: **Serial1** on +pins 19 (RX) and 18 (TX), **Serial2** on pins 17 (RX) and 16 (TX), +**Serial3** on pins 15 (RX) and 14 (TX). To use these pins to +communicate with your personal computer, you will need an +additional USB-to-serial adaptor, as they are not connected to the +Mega's USB-to-serial adaptor. To use them to communicate with an +external TTL serial device, connect the TX pin to your device's RX +pin, the RX to your device's TX pin, and the ground of your Mega to +your device's ground. (Don't connect these pins directly to an +RS232 serial port; they operate at +/- 12V and can damage your +Arduino board.) + + + +Functions +--------- + + +- `begin <http://arduino.cc/en/Serial/Begin>`_\ () +- `end <http://arduino.cc/en/Serial/End>`_\ () +- `available <http://arduino.cc/en/Serial/Available>`_\ () +- `read <http://arduino.cc/en/Serial/Read>`_\ () +- `flush <http://arduino.cc/en/Serial/Flush>`_\ () +- `print <http://arduino.cc/en/Serial/Print>`_\ () + +.. _lang-serial-println: + +- `println <http://arduino.cc/en/Serial/Println>`_\ () +- `write <http://arduino.cc/en/Serial/Write>`_\ () + + + +Examples +-------- + + +- `ASCII Table <http://arduino.cc/en/Tutorial/ASCIITable>`_ +- `Dimmer <http://arduino.cc/en/Tutorial/Dimmer>`_ +- `Graph <http://arduino.cc/en/Tutorial/Graph>`_ +- `Physical Pixel <http://arduino.cc/en/Tutorial/PhysicalPixel>`_ +- `Virtual Color Mixer <http://arduino.cc/en/Tutorial/VirtualColorMixer>`_ +- `Serial Call Response <http://arduino.cc/en/Tutorial/SerialCallResponse>`_ +- `Serial Call Response ASCII <http://arduino.cc/en/Tutorial/SerialCallResponseASCII>`_ + + + +.. include:: cc-attribution.txt diff --git a/source/lang/serialusb.rst b/source/lang/serialusb.rst new file mode 100644 index 0000000..730fb07 --- /dev/null +++ b/source/lang/serialusb.rst @@ -0,0 +1,8 @@ +.. _lang-serialusb: + +Serial over USB Communications +============================== + +.. _lang-serialusb-println: + +Stub. diff --git a/source/lang/setup.rst b/source/lang/setup.rst new file mode 100644 index 0000000..6b142d2 --- /dev/null +++ b/source/lang/setup.rst @@ -0,0 +1,34 @@ +.. _lang-setup: + +setup() +======= + +The setup() function is called when a sketch starts. Use it to +initialize variables, pin modes, start using libraries, etc. The +setup function will only run once, after each powerup or reset of +the Arduino board. + + + +Example +~~~~~~~ + +:: + + + int buttonPin = 3; + + void setup() + { + Serial.begin(9600); + pinMode(buttonPin, INPUT); + } + + void loop() + { + // ... + } + + + +.. include:: cc-attribution.txt diff --git a/source/lang/shiftout.rst b/source/lang/shiftout.rst new file mode 100644 index 0000000..e76cc01 --- /dev/null +++ b/source/lang/shiftout.rst @@ -0,0 +1,136 @@ +.. _lang-shiftout: + +shiftOut() +========== + +Description +----------- + +Shifts out a byte of data one bit at a time. Starts from either the +most (i.e. the leftmost) or least (rightmost) significant bit. Each +bit is written in turn to a data pin, after which a clock pin is +pulsed to indicate that the bit is available. + + + +This is a software implementation; Arduino (as of 0019) also +provides an `SPI library <http://arduino.cc/en/Reference/SPI>`_ +that uses the hardware implementation. + + + +Syntax +------ + +shiftOut(dataPin, clockPin, bitOrder, value) + + + +Parameters +---------- + +dataPin: the pin on which to output each bit (*int*) + + + +clockPin: the pin to toggle once the **dataPin** has been set to +the correct value (*int*) + + + +bitOrder: which order to shift out the bits; either **MSBFIRST** or +**LSBFIRST**. +(Most Significant Bit First, or, Least Significant Bit First) + + + +value: the data to shift out. (*byte*) + + + +Returns +------- + +None + + + +Note +---- + +The **dataPin** and **clockPin** must already be configured as +outputs by a call to +`pinMode <http://arduino.cc/en/Reference/PinMode>`_\ (). + + + +**shiftOut** is currently written to output 1 byte (8 bits) so it +requires a two step operation to output values larger than 255. + +:: + + // Do this for MSBFIRST serial + int data = 500; + // shift out highbyte + shiftOut(dataPin, clock, MSBFIRST, (data >> 8)); + // shift out lowbyte + shiftOut(data, clock, MSBFIRST, data); + + // Or do this for LSBFIRST serial + data = 500; + // shift out lowbyte + shiftOut(dataPin, clock, LSBFIRST, data); + // shift out highbyte + shiftOut(dataPin, clock, LSBFIRST, (data >> 8)); + + + +Example +------- + +*For accompanying circuit, see the `tutorial on controlling a 74HC595 shift register <http://arduino.cc/en/Tutorial/ShiftOut>`_.* + + + +:: + + //**************************************************************// + // Name : shiftOutCode, Hello World // + // Author : Carlyn Maw,Tom Igoe // + // Date : 25 Oct, 2006 // + // Version : 1.0 // + // Notes : Code for using a 74HC595 Shift Register // + // : to count from 0 to 255 // + //**************************************************************** + + //Pin connected to ST_CP of 74HC595 + int latchPin = 8; + //Pin connected to SH_CP of 74HC595 + int clockPin = 12; + ////Pin connected to DS of 74HC595 + int dataPin = 11; + + void setup() { + //set pins to output because they are addressed in the main loop + pinMode(latchPin, OUTPUT); + pinMode(clockPin, OUTPUT); + pinMode(dataPin, OUTPUT); + } + + void loop() { + //count up routine + for (int j = 0; j < 256; j++) { + //ground latchPin and hold low for as long as you are transmitting + digitalWrite(latchPin, LOW); + shiftOut(dataPin, clockPin, LSBFIRST, j); + //return the latch pin high to signal chip that it + //no longer needs to listen for information + digitalWrite(latchPin, HIGH); + delay(1000); + } + } + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/sin.rst b/source/lang/sin.rst new file mode 100644 index 0000000..398b8f3 --- /dev/null +++ b/source/lang/sin.rst @@ -0,0 +1,32 @@ +.. _lang-sin: + +sin() +===== + +Calculates the `sine <http://en.wikipedia.org/wiki/Sine>`_ of an +angle. + +Library Documentation +--------------------- + +.. doxygenfunction:: sin + +Arduino Compatibility +--------------------- + +The Maple version of ``sin()`` is compatible with Arduino. + +Note that the Maple implementation comes from `newlib +<http://sourceware.org/newlib/>`_\ , while Arduino's is that of +`avr-libc <http://avr-libc.nongnu.org/>`_\ . + +See Also +-------- + +- :ref:`cos <lang-cos>` +- :ref:`tan <lang-tan>` +- :ref:`float <lang-float>` +- :ref:`double <lang-double>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/sizeof.rst b/source/lang/sizeof.rst new file mode 100644 index 0000000..409a6d7 --- /dev/null +++ b/source/lang/sizeof.rst @@ -0,0 +1,64 @@ +.. highlight:: cpp + +.. _lang-sizeof: + +sizeof() +======== + +The ``sizeof`` operator on the Maple returns the number of bytes +needed to store a value of a given type\ [#fcharsize]_. This can be +an ordinary numeric type, like ``int``. It can be something more +complicated, like a ``struct`` or ``union``. If the argument to +``sizeof`` is an array, it returns the total number of bytes occupied +by the array. + +The general syntax looks like this:: + + sizeof(type) + sizeof(var) + +Example +------- + +The ``sizeof`` operator is useful for dealing with arrays (such as +strings) where it is convenient to be able to change the size of the +array without breaking other parts of the program. + +This program prints out a text string one character at a time. Try +changing the text phrase:: + + char myStr[] = "this is a test"; + int i; + + void setup() { + Serial.begin(9600); + } + + void loop() { + for (i = 0; i < sizeof(myStr) - 1; i++) { + Serial.print(i, DEC); + Serial.print(" = "); + Serial.println(myStr[i], BYTE); + } + } + + +Note that ``sizeof`` returns the total number of bytes. So for larger +variable types such as ``int``, the :ref:`for loop <lang-for>` +would look something like this:: + + for (i = 0; i < (sizeof(myInts)/sizeof(int)) - 1; i++) { + // do something with myInts[i] + } + +.. rubric:: Footnotes + +.. [#fcharsize] Technically (and pedantically) speaking, ``sizeof`` + returns a multiple of the number of bits a ``char`` occupies in + memory. However, on the Maple (this goes for most C++ + implementations), a ``char`` occupies 8 bits = 1 byte. All the C++ + standard guarantees, however, is that a ``char`` occupies at + *least* 8 bits. + +.. include:: cc-attribution.txt + diff --git a/source/lang/sq.rst b/source/lang/sq.rst new file mode 100644 index 0000000..a14817f --- /dev/null +++ b/source/lang/sq.rst @@ -0,0 +1,42 @@ +.. highlight:: cpp + +.. _lang-sq: + +sq(a) +===== + +Description +----------- + +(Macro) computes the square of a number. + +Parameters +---------- + +**a**: the number. + +Returns +------- + +**a** squared (**a** × **a**). + +Warning +------- + +Because of the way ``sq()`` is implemented, avoid using other +functions or causing side effects inside the parentheses, as it may +lead to incorrect results:: + + b = sq(a++); // avoid this - yields incorrect results + + b = sq(a); // use this instead - + a++; // keep other operations outside sq() + + +Arduino Compatibility +--------------------- + +Maple's implementation of ``sq()`` is compatible with Arduino. + + +.. include:: cc-attribution.txt diff --git a/source/lang/sqrt.rst b/source/lang/sqrt.rst new file mode 100644 index 0000000..956a754 --- /dev/null +++ b/source/lang/sqrt.rst @@ -0,0 +1,25 @@ +.. _lang-sqrt: + +sqrt() +====== + +Calculates the square root of a number. + +Library Documentation +--------------------- + +.. doxygenfunction:: sqrt + +Arduino Compatibility +--------------------- + +The Maple versino of ``sqrt()`` is compatible with Arduino. + +See Also +-------- + +- :ref:`pow <lang-pow>` +- :ref:`sq <lang-sq>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/static.rst b/source/lang/static.rst new file mode 100644 index 0000000..4646db1 --- /dev/null +++ b/source/lang/static.rst @@ -0,0 +1,57 @@ +.. highlight:: cpp + +.. _lang-static: + +Static +====== + +The ``static`` keyword can be used to create variables that are +visible to only one function. However, unlike local variables that get +created and destroyed every time a function is called, ``static`` +variables persist beyond the function call, preserving their data +between function calls. + +Variables declared as ``static`` will only be created and initialized +the first time a function is called. + +.. note:: This is only one use of the ``static`` keyword in C++. It + has some other important uses that are not documented here; consult + a reliable C++ reference for details. + +Example +------- + +One use case for ``static`` variables is implementing counters that +last longer than the functions which need them, but shouldn't be +shared to other functions. Here's an example:: + + void setup() { + SerialUSB.begin(); + } + + void loop() { + int reading; + if (timeToReadSensors()) { + reading = readSensors(); + } + // do something with reading + } + + int readSensors() { + static int numSensorReadings = 0; + numSensorReadings++; + if (numSensorReadings % 100 == 0) { + SerialUSB.print("just got to another 100 sensor readings"); + } + return analogRead(...); + } + +In this example, the static variable ``numSensorReadings`` is +initialized to zero the first time ``readSensors()`` is called, and +then incremented, so it starts out at one. Subsequent calls to +``readSensors()`` won't reset ``numSensorReadings`` to zero, because +it was declared ``static``. Thus, ``numSensorReadings`` is a count of +the number of times that ``readSensors()`` has been called. + + +.. include:: cc-attribution.txt diff --git a/source/lang/string.rst b/source/lang/string.rst new file mode 100644 index 0000000..92c3f69 --- /dev/null +++ b/source/lang/string.rst @@ -0,0 +1,131 @@ +.. highlight:: cpp + +.. _lang-string: + +Strings +======= + +Description +----------- + +Text strings can be represented in two ways. You can + +1. Use the :ref:`String <lang-stringclass>` data type, which is +part of the core as of version 0.0.9, or + +2. You can make a string out of an array of type :ref:`char +<lang-char>` and null-terminate it. + +This page describes the second method. + +Examples +-------- + +All of the following are valid declarations for strings:: + + char str1[15]; + char str2[6] = {'m', 'a', 'p', 'l', 'e'}; + char str3[6] = {'m', 'a', 'p', 'l', 'e', '\0'}; + char str4[ ] = "maple"; + char str5[6] = "maple"; + char str6[15] = "maple"; + +As you can see, there are several methods available for declaring and +initializing strings: + +- Declare an array of ``char`` without initializing it, as with ``str1``. + +- Declare an array of ``char`` (with one extra ``char``) and the + compiler will add the required null character, as with ``str2``. + +- Explicitly add the null character (``'\0'``), as with ``str3``. + +- Initialize with a string constant in quotation marks (``"..."``); + the compiler will size the array to fit the string constant and a + terminating null character (``str4``). + +- Initialize the array with an explicit size and string constant, + (``str5``). + +- Initialize the array, leaving extra space for a larger string + (``str6``). + +Null Termination +---------------- + +Generally, strings are terminated with a null character (`ASCII +<http://en.wikipedia.org/wiki/ASCII>`_ code 0). This allows functions +(like ``SerialUSB.print()``) to tell where the end of a string is. +Otherwise, they would continue reading subsequent bytes of memory that +aren't actually part of the string. + +This means that your string needs to have space for one more character +than the text you want it to contain. That is why ``str2`` and +``str5`` need to be six characters, even though "maple" is only five +-- the last position is automatically filled with a NULL +character. ``str4`` will be automatically sized to six characters, one +for the extra null. In the case of ``str3``, we've explicitly included +the null character (written ``'\0'``) ourselves. + +Note that it's possible to have a string without a final null +character (e.g. if you had specified the length of ``str2`` as five +instead of six). This will break most functions that use strings, so +you shouldn't do it intentionally. If you notice something behaving +strangely (operating on characters not in the string), however, this +could be the problem. + +Single quotes or double quotes? +------------------------------- + +Strings are always defined inside double quotes (``"Abc"``) and +characters are always defined inside single quotes (``'A'``). + +Wrapping long strings +--------------------- + +You can wrap long strings like this:: + + char myString[] = "This is the first line" + " this is the second line" + " etcetera"; + +Arrays of Strings +----------------- + +It is often convenient, when working with large amounts of text, +such as a project with an LCD display, to setup an array of +strings. Because strings themselves are arrays, this is in actually +an example of a two-dimensional array. + +In the code below, the asterisk after the datatype char ``char *`` +indicates that this is an array of "pointers". All array names are +actually pointers, so this is required to make an array of arrays. +Pointers are one of the more esoteric parts of C for beginners to +understand, but it isn't necessary to understand pointers in detail to +use them effectively here:: + + char* myStrings[] = {"This is string 1", "This is string 2", + "This is string 3", "This is string 4", + "This is string 5", "This is string 6"}; + + void setup() { + SerialUSB.begin(); + } + + void loop() { + for (int i = 0; i < 6; i++) { + SerialUSB.println(myStrings[i]); + delay(500); + } + } + + +See Also +-------- + +- :ref:`array <lang-array>` +- :ref:`__attribute__ <arm-gcc-attribute-flash>` +- :ref:`Variables <lang-variables>` + + +.. include:: cc-attribution.txt diff --git a/source/lang/stringclass.rst b/source/lang/stringclass.rst new file mode 100644 index 0000000..5e53f08 --- /dev/null +++ b/source/lang/stringclass.rst @@ -0,0 +1,9 @@ +.. _lang-stringclass: + +String Class +============ + +Stub. + + +.. include:: cc-attribution.txt diff --git a/source/lang/stringobject.rst b/source/lang/stringobject.rst new file mode 100644 index 0000000..d7f287c --- /dev/null +++ b/source/lang/stringobject.rst @@ -0,0 +1,91 @@ +.. _lang-stringobject: + +String +====== + +Description +----------- + +The String class, part of the core as of version 0019, allows you +to use and manipulate strings of text in more complex ways than +`character arrays <http://arduino.cc/en/Reference/String>`_ do. You +can concatenate Strings, append to them, search for and replace +substrings, and more. It takes more memory than a simple character +array, but it is also more useful. + + + +For reference, character arrays are referred to as strings with a +small s, and instances of the String class are referred to as +Strings with a capital S. Note that constant strings, specified in +"double quotes" are treated as char arrays, not instances of the +String class. + + + +Functions +--------- + + +- `String <http://arduino.cc/en/Reference/StringConstructor>`_\ () +- `charAt <http://arduino.cc/en/Reference/StringCharAt>`_\ () +- `compareTo <http://arduino.cc/en/Reference/StringCompareTo>`_\ () +- `concat <http://arduino.cc/en/Reference/StringConcat>`_\ () +- `endsWith <http://arduino.cc/en/Reference/StringEndsWith>`_\ () +- `equals <http://arduino.cc/en/Reference/StringEquals>`_\ () +- `equalsIgnoreCase <http://arduino.cc/en/Reference/StringEqualsIgnoreCase>`_\ () +- `getBytes <http://arduino.cc/en/Reference/StringGetBytes>`_\ () +- `indexOf <http://arduino.cc/en/Reference/StringIndexOf>`_\ () +- `lastIndexOf <http://arduino.cc/en/Reference/StringLastIndexOf>`_\ () +- `length <http://arduino.cc/en/Reference/StringLength>`_\ () +- `replace <http://arduino.cc/en/Reference/StringReplace>`_\ () +- `setCharAt <http://arduino.cc/en/Reference/StringSetCharAt>`_\ () +- `startsWith <http://arduino.cc/en/Reference/StringStartsWith>`_\ () +- `substring <http://arduino.cc/en/Reference/StringSubstring>`_\ () +- `toCharArray <http://arduino.cc/en/Reference/StringToCharArray>`_\ () +- `toLowerCase <http://arduino.cc/en/Reference/StringToLowerCase>`_\ () +- `toUpperCase <http://arduino.cc/en/Reference/StringToUpperCase>`_\ () +- `trim <http://arduino.cc/en/Reference/StringTrim>`_\ () + + + +Operators +--------- + + +- `[] (element access) <http://arduino.cc/en/Reference/StringBrackets>`_ +- `+ (concatenation) <http://arduino.cc/en/Reference/StringPlus>`_ +- `== (comparison) <http://arduino.cc/en/Reference/StringComparison>`_ + + + +Examples +-------- + + +- `StringConstructors <http://arduino.cc/en/Tutorial/StringConstructors>`_ +- `StringAdditionOperator <http://arduino.cc/en/Tutorial/StringAdditionOperator>`_ +- `StringIndexOf <http://arduino.cc/en/Tutorial/StringIndexOf>`_ +- `StringAppendOperator <http://arduino.cc/en/Tutorial/StringAppendOperator>`_ +- `StringLengthTrim <http://arduino.cc/en/Tutorial/StringLengthTrim>`_ +- `StringCaseChanges <http://arduino.cc/en/Tutorial/StringCaseChanges>`_ +- `StringReplace <http://arduino.cc/en/Tutorial/StringReplace>`_ +- `StringCharacters <http://arduino.cc/en/Tutorial/StringCharacters>`_ +- `StringStartsWithEndsWith <http://arduino.cc/en/Tutorial/StringStartsWithEndsWith>`_ +- `StringComparisonOperators <http://arduino.cc/en/Tutorial/StringComparisonOperators>`_ +- `StringSubstring <http://arduino.cc/en/Tutorial/StringSubstring>`_ + + + +See Also +-------- + + +- `string <http://arduino.cc/en/Reference/String>`_: character + arrays +- `Variable Declaration <http://arduino.cc/en/Reference/VariableDeclaration>`_ + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/switchcase.rst b/source/lang/switchcase.rst new file mode 100644 index 0000000..46c47d8 --- /dev/null +++ b/source/lang/switchcase.rst @@ -0,0 +1,117 @@ +.. highlight:: cpp + +.. _lang-switchcase: + +switch / case statements +======================== + +Like :ref:`if/else <lang-else>` blocks, A ``switch`` statement +controls program flow by allowing you to specify different code that +should be executed under various cases. + +The general syntax looks like this:: + + switch (var) { + case val1: + // statements + break; + case val2: + // statements + break; + ... + default: + // statements + } + +Where ``var`` is a variable whose value to investigate, and the +``val1``, ``val2`` after each ``case`` are constant values that +``var`` might be. + + +Description +----------- + +A ``switch`` statement compares the value of a variable to the values +specified in ``case`` statements. When a ``case`` statement is found +whose value matches that of the variable, the code in that case +statement is run. + +Here's a more concrete example:: + + switch (var) { + case 1: + doThing1(); + break; + case 2: + doThing2(); + break; + } + afterTheSwitch(); + +In the above example, if ``var == 1``, then the code beginning on the +line after ``case 1`` gets executed. That is, if ``var`` is one, +``doThing1()`` gets called first, and then the ``break`` statement is +executed. + +The ``break`` keyword exits the ``switch`` statement, and is typically +used at the end of each ``case``. Since there is a ``break`` at the +end of ``case 1``, the ``switch`` statement exits, and the next line +to be run is the one which calls ``afterTheSwitch()``. + +Without a ``break``, the ``switch`` statement will continue executing +the following ``case`` expressions ("falling-through") until a +``break`` (or the end of the switch statement) is reached. Let's +pretend the ``switch`` looked like this instead:: + + switch (var) { + case 1: + doThing1(); + // no break statement anymore + case 2: + doThing2(); + break; + } + afterTheSwitch(); + +Now, if ``var`` is one, ``doThing1()`` gets executed like before. +However, without a ``break``, the code would continue to be executed +line-by-line, so ``doThing2()`` would be called next. At this point, +a ``break`` has been reached, so the program continues by calling +``afterTheSwitch()``. This is usually not what you want, which is why +each ``case`` usually has a ``break`` at the end. + +Writing "``default:``" instead of a ``case`` statement allows you to +specify what to do if none of the ``case`` statements matches. Having +a ``default`` is optional (you can leave it out), but if you have one, +it must appear after all of the ``case`` statements. Let's add a +``default`` to the ``switch`` we've been discussing:: + + switch (var) { + case 1: + doThing1(); + break; + case 2: + doThing2(); + break; + default: + doSomethingElse(); + } + afterTheSwitch(); + +If ``var`` is one, then ``doThing1()`` gets called. If ``var`` is +two, ``doThing2()`` gets called. If ``var`` is anything else, +``doSomethingElse()`` gets called. As stated above, a ``default`` is +optional. If you're missing one and none of the ``case`` statements +match, the ``switch`` does nothing at all, as if it weren't there. + +``switch`` statements are often used with an ``enum`` value as the +variable to compare. In this case, you can write down all of the +values the ``enum`` takes as ``case`` statements, and be sure you've +covered all the possibilities. + +See also: +--------- + +- :ref:`if...else <lang-else>` + +.. include:: cc-attribution.txt diff --git a/source/lang/tan.rst b/source/lang/tan.rst new file mode 100644 index 0000000..4bbe0db --- /dev/null +++ b/source/lang/tan.rst @@ -0,0 +1,31 @@ +.. _lang-tan: + +tan() +===== + +Calculates the tangent of an angle. + +Library Documentation +--------------------- + +.. doxygenfunction:: tan + +Arduino Compatibility +--------------------- + +The Maple version of ``tan()`` is compatible with Arduino. + +Note that the Maple implementation comes from `newlib +<http://sourceware.org/newlib/>`_\ , while Arduino's is that of +`avr-libc <http://avr-libc.nongnu.org/>`_\ . + +See Also +-------- + + +- :ref:`sin <lang-sin>` +- :ref:`cos <lang-cos>` +- :ref:`float <lang-float>` +- :ref:`double <lang-double>` + +.. include:: cc-attribution.txt diff --git a/source/lang/tone.rst b/source/lang/tone.rst new file mode 100644 index 0000000..96f0a7c --- /dev/null +++ b/source/lang/tone.rst @@ -0,0 +1,81 @@ +.. _lang-tone: + +tone() +====== + +Description +----------- + +Generates a square wave of the specified frequency (and 50% duty +cycle) on a pin. A duration can be specified, otherwise the wave +continues until a call to +`noTone <http://arduino.cc/en/Reference/NoTone>`_\ (). The pin can be +connected to a piezo buzzer or other speaker to play tones. + + + +Only one tone can be generated at a time. If a tone is already +playing on a different pin, the call to tone() will have no effect. +If the tone is playing on the same pin, the call will set its +frequency. + + + +Use of the tone() function will interfere with PWM output on pins 3 +and 11 (on boards other than the Mega). + + + +**NOTE:** if you want to play different pitches on multiple pins, +you need to call noTone() on one pin before calling tone() on the +next pin. + + + +Syntax +------ + +tone(pin, frequency) +tone(pin, frequency, duration) + + + +Parameters +---------- + +pin: the pin on which to generate the tone + + + +frequency: the frequency of the tone in hertz + + + +duration: the duration of the tone in milliseconds (optional) + + + +Returns +------- + +nothing + + + +See also +-------- + + +- `noTone <http://arduino.cc/en/Reference/NoTone>`_\ () +- `analogWrite <http://arduino.cc/en/Reference/AnalogWrite>`_\ () +- `Tutorial:Tone <http://arduino.cc/en/Tutorial/Tone>`_ +- `Tutorial:Pitch follower <http://arduino.cc/en/Tutorial/Tone2>`_ +- `Tutorial:Simple Keyboard <http://arduino.cc/en/Tutorial/Tone3>`_ +- `Tutorial: multiple tones <http://arduino.cc/en/Tutorial/Tone4>`_ + + +- `Tutorial: PWM <http://arduino.cc/en/Tutorial/PWM>`_ + + + +.. include:: cc-attribution.txt diff --git a/source/lang/types.rst b/source/lang/types.rst new file mode 100644 index 0000000..d095da1 --- /dev/null +++ b/source/lang/types.rst @@ -0,0 +1,7 @@ +.. _lang-types: + +Built-in types +============== + +Stub. (explain all built-in integral and floating-point types, +including ``uint8`` style ones). diff --git a/source/lang/unsignedchar.rst b/source/lang/unsignedchar.rst new file mode 100644 index 0000000..c49690d --- /dev/null +++ b/source/lang/unsignedchar.rst @@ -0,0 +1,36 @@ +.. highlight:: cpp + +.. _lang-unsignedchar: + +unsigned char +============= + +Description +----------- + +An unsigned version of the :ref:`char <lang-char>` data type. An +``unsigned char`` occupies 1 byte of memory; it stores an integer from +0 to 255. + +Like an :ref:`unsigned int <lang-unsignedint>`, an ``unsigned char`` +won't store negative numbers; it is also subject to the same +:ref:`overflow issues <lang-int-overflow>` as any integral data type. + +Example +------- + +:: + + unsigned char c = 240; + +See Also +-------- + + +- :ref:`byte <lang-byte>` +- :ref:`int <lang-int>` +- :ref:`array <lang-array>` +- :ref:`SerialUSB.println() <lang-serialusb-println>` +- :ref:`Serial.println() <lang-serial-println>` + +.. include:: cc-attribution.txt diff --git a/source/lang/unsignedint.rst b/source/lang/unsignedint.rst new file mode 100644 index 0000000..aa5cc1b --- /dev/null +++ b/source/lang/unsignedint.rst @@ -0,0 +1,58 @@ +.. highlight:: cpp + +.. _lang-unsignedint: + +unsigned int +============ + +Description +----------- + +An ``unsigned int`` (unsigned integer) is the same as an :ref:`int +<lang-int>` in that it stores a 4 byte integer value. However, +Instead of storing both negative and positive numbers, an ``unsigned +int`` can only store nonnegative values, yielding a range of 0 to +4,294,967,295 (the positive value is 2^32 - 1). + +The difference between an ``unsigned int`` and a (signed) ``int`` lies +in the way the highest bit, sometimes referred to as the "sign" bit, +is interpreted. In the case of the Maple ``int`` type (which is +signed), if the high bit is a "1", the number is interpreted as a +negative number, using a technique known as `two's complement math +<http://en.wikipedia.org/wiki/Two%27s_complement#Explanation>`_. The +bits in an an ``unsigned int`` are interpreted according to the usual +rules for converting `binary to decimal +<http://en.wikipedia.org/wiki/Binary_numeral_system#Counting_in_binary>`_. + +An ``unsigned int`` is subject to the same :ref:`overflow issues +<lang-int-overflow>` as a regular ``int``; the only difference is +that an ``unsigned int`` will "underflow" at 0, and "overflow" at +4,294,967,295. Here is some example code which illustrates this:: + + unsigned int x; + x = 0; + x--; // x now contains 4,294,967,295; rolled over "left to right" + x++; // x now contains 0; rolled over "right to left" + +Here is an example of declaring an ``unsigned int`` variable named +``ledPin``, then giving it value 13:: + + unsigned int ledPin = 13; + +The general syntax for declaring an ``unsigned int`` variable named +``var``, then giving it value ``val``, looks like:: + + unsigned int var = val; + +See Also +-------- + +- :ref:`int <lang-int>` +- :ref:`char <lang-char>` +- :ref:`unsigned char <lang-unsignedchar>` +- :ref:`long <lang-long>` +- :ref:`unsigned long <lang-unsignedlong>` +- :ref:`Integer Constants <lang-constants-integers>` +- :ref:`Variables <lang-variables>` + +.. include:: cc-attribution.txt diff --git a/source/lang/unsignedlong.rst b/source/lang/unsignedlong.rst new file mode 100644 index 0000000..2ca49f8 --- /dev/null +++ b/source/lang/unsignedlong.rst @@ -0,0 +1,44 @@ +.. highlight:: cpp + +.. _lang-unsignedlong: + +unsigned long +============= + +Description +----------- + +An unsigned version of the :ref:`long <lang-long>` data type. An +``unsigned long`` occupies 8 bytes of memory; it stores an integer +from 0 to 2^64-1, which is approximately 1.8×10^19 (18 quintillion, or +18 billion billion). + +Like an :ref:`unsigned int <lang-unsignedint>`, an ``unsigned long`` +won't store negative numbers; it is also subject to the same +:ref:`overflow issues <lang-int-overflow>` as any integral data type. + +Here is an example of declaring an ``unsigned long`` variable named +``c``, then giving it value 299,792,458,000,000,000 (see :ref:`integer +constants <lang-constants-u-l>` for an explanation of the "L" at the +end of the number):: + + // Speed of light in nanometers per second (approximate). + unsigned long c = 299792458000000000L; + +The general syntax for declaring an ``unsigned long`` variable named +``var``, then giving it value ``val``, looks like:: + + unsigned long var = val; + +See Also +-------- + +- :ref:`long <lang-long>` +- :ref:`int <lang-int>` +- :ref:`unsigned <lang-unsignedint>` +- :ref:`char <lang-char>` +- :ref:`unsigned char <lang-unsignedchar>` +- :ref:`Integer Constants <lang-constants-integers>` +- :ref:`Variables <lang-variables>` + +.. include:: cc-attribution.txt diff --git a/source/lang/variables.rst b/source/lang/variables.rst new file mode 100644 index 0000000..05a4f96 --- /dev/null +++ b/source/lang/variables.rst @@ -0,0 +1,170 @@ +.. highlight:: cpp + +.. _lang-variables: + +Variables +========= + +A variable is a way of naming and storing a value for later use by +the program, such as data from a sensor or an intermediate value +used in a calculation. + +.. contents:: Contents + :local: + +.. _lang-variables-declaring: + +Declaring Variables +------------------- + +Before they are used, all variables have to be *declared*. Declaring a +variable means defining its type, giving it a name, and (optionally) +giving it an initial value (this is often referred to as +*initializing* the variable). Variables do not have to be initialized +(given a value) when they are declared, but it is good style to give +them an initial value whenever possible. + +Here is an example of declaring a variable named ``inputVariable1`` +with type :ref:`int <lang-int>` (the ``int`` type is used to store +integers, like -2, -1, 0, 1, etc.):: + + int inputVariable1; + +In the above declaration, we did not give the variable an initial +value. Here is another example, where we declare an ``int`` variable +named ``inputVariable2``, with an initial value of ``0``:: + + int inputVariable2 = 0; + +The Maple environment comes ready to use with many useful types of +variables. See the :ref:`built-in types <lang-types>` page for more +information. + +Here are a few examples of declaring variables of different types:: + + int lightSensVal; + char currentLetter; + unsigned long speedOfLight = 186000UL; + char errorMessage = {"choose another option"}; // see string + +Naming Variables +---------------- + +The rules for naming a variable are simple. Names for variables can +contain letters, numbers, and underscores (the underscore is the +:kbd:`_` character), and cannot begin with a number. So +``temperature_reading``, ``tempReading``, ``tempReading1``, and +``tempReading2`` are all valid variable names, but ``4_temp_readings`` +is not, because it begins with a number. + +You cannot choose a name for a variable that is one of the C++ +:ref:`keywords <lang-keywords>`. + +Variable names are case-sensitive, so "tempreading" and "tempReading" +are different variables. However, it is very bad style to write code +that chooses variables which are the same up to case. + +You should give your variables descriptive names, so as to make your +code more readable. Variable names like ``tiltSensor`` or +``pushButton`` help you (and anyone else reading your code) understand +what the variable represents. Variable names like ``var`` or +``value``, on the other hand, do little to make your code readable. + +.. _lang-variables-scope: + +Variable Scope +-------------- + +An important choice that programmers face is where (in the program +text) to declare variables. The specific place that variables are +declared influences how various functions in a program will "see" the +variable. This is called variable *scope*. See the :ref:`scope +reference <lang-scope>` for more information. + +.. _lang-variables-initializing: + +Initializing Variables +---------------------- + +Variables may be *initialized* (assigned a starting value) when they +are declared or not. It is always good programming practice however to +double check that a variable has valid data in it before it is used. +Using a variable before you give it a value is a common source of +bugs. + +.. _lang-variables-rollover: + +Variable Rollover +----------------- + +Every (numeric) type has a valid *range*. The range of a type is the +smallest and largest value that a variable of that type can store. +For example, the :ref:`int <lang-int>` type has a range of +-2,147,483,648 to 2,147,483,647 [#frange]_. + +When variables are made to exceed their range's maximum value, they +"roll over" back to their minimum value. Note that this happens in +both directions. It's like in the game *Pac-Man* -- when Pac-Man goes +past the right edge of the screen, he reappears on the left, and when +he goes past the left side of the screen, he reappears on the right:: + + int x; + x = -2,147,483,648; + x = x - 1; // x now contains -2,147,483,647; rolled over "left to right" + + x = 2,147,483,647; + x = x + 1; // x now contains -2,147,483,648; rolled over "right to left" + +Each numeric type's reference page includes its range. See the +:ref:`built-in types <lang-types>` reference for links to each type's +reference page. + +Using Variables +--------------- + +Once variables have been declared, they are given values using the +:ref:`assignment operator <lang-assignment>`, which is a single equals +sign, ``=``. The assignment operator tells the program to store the +value on the right side of the equals sign into the variable on the +left side:: + + inputVariable1 = 7; // sets variable named inputVariable1 to 7 + inputVariable2 = analogRead(2); // sets variable named inputVariable2 to + // the (digitized) input voltage read from + // analog pin #2 + +Once a variable has been set (assigned a value), you can test its +value to see if it meets certain conditions, or you can use its value +directly. For instance, the following code tests whether the +inputVariable2 is less than 100, then sets a delay based on +inputVariable2 (which, at that point, is at least 100):: + + if (inputVariable2 < 100) { + inputVariable2 = 100; + } + + delay(inputVariable2); + +See Also +-------- + +- :ref:`lang-scope` +- :ref:`lang-types` + +.. rubric:: Footnotes + +.. [#frange] This range might seem a little weird at first. The + reasons for this range of values have to do with the fact that an + ``int`` occupies 32 bits of memory, and the facts :: + + 2^31 = -2,147,483,648 + 2^31 - 1 = 2,147,483,647 + + + Why 2^31 instead of 2^32? Well, that has to do with `how ints are + (usually) stored + <http://en.wikipedia.org/wiki/Two%27s_complement>`_ on computers. + + +.. include:: cc-attribution.txt + diff --git a/source/lang/void.rst b/source/lang/void.rst new file mode 100644 index 0000000..bc7a3dc --- /dev/null +++ b/source/lang/void.rst @@ -0,0 +1,40 @@ +.. _lang-void: + +void +==== + +The void keyword is used only in function declarations. It +indicates that the function is expected to return no information to +the function from which it was called. + + + +Example: +-------- + +:: + + // actions are performed in the functions "setup" and "loop" + // but no information is reported to the larger program + + void setup() + { + // ... + } + + void loop() + { + // ... + } + + + + +See also +-------- + +`function declaration <http://arduino.cc/en/Reference/FunctionDeclaration>`_ + + + +.. include:: cc-attribution.txt diff --git a/source/lang/volatile.rst b/source/lang/volatile.rst new file mode 100644 index 0000000..a0ef671 --- /dev/null +++ b/source/lang/volatile.rst @@ -0,0 +1,73 @@ +.. _lang-volatile: + +volatile keyword +================ + +volatile is a keyword known as a variable *qualifier*, it is +usually used before the datatype of a variable, to modify the way +in which the compiler and subsequent program treats the variable. + + + +Declaring a variable volatile is a directive to the compiler. The +compiler is software which translates your C/C++ code into the +machine code, which are the real instructions for the Atmega chip +in the Arduino. + + + +Specifically, it directs the compiler to load the variable from RAM +and not from a storage register, which is a temporary memory +location where program variables are stored and manipulated. Under +certain conditions, the value for a variable stored in registers +can be inaccurate. + + + +A variable should be declared volatile whenever its value can be +changed by something beyond the control of the code section in +which it appears, such as a concurrently executing thread. In the +Arduino, the only place that this is likely to occur is in sections +of code associated with interrupts, called an interrupt service +routine. + + + +Example +------- + +:: + + // toggles LED when interrupt pin changes state + + int pin = 13; + volatile int state = LOW; + + void setup() + { + pinMode(pin, OUTPUT); + attachInterrupt(0, blink, CHANGE); + } + + void loop() + { + digitalWrite(pin, state); + } + + void blink() + { + state = !state; + } + + + +See also +-------- + + +- `AttachInterrupt <http://arduino.cc/en/Reference/AttachInterrupt>`_ + + + + +.. include:: cc-attribution.txt diff --git a/source/lang/while.rst b/source/lang/while.rst new file mode 100644 index 0000000..be1ea14 --- /dev/null +++ b/source/lang/while.rst @@ -0,0 +1,49 @@ +.. _lang-while: + +while Loops +=========== + +Description +----------- + +**while** loops will loop continuously, and infinitely, until the +expression inside the parenthesis, () becomes false. Something must +change the tested variable, or the **while** loop will never exit. +This could be in your code, such as an incremented variable, or an +external condition, such as testing a sensor. + + + +Syntax +------ + +:: + + while(expression){ + // statement(s) + } + + + +Parameters +---------- + +expression - a (boolean) C statement that evaluates to true or +false + + + +Example +------- + +:: + + var = 0; + while(var < 200){ + // do something repetitive 200 times + var++; + } + + + +.. include:: cc-attribution.txt |