Vous êtes sur la page 1sur 300

Solti Imre:

Arduino eljrsgyjtemny
Ajnls:
Ez egy aurdino s egyb szabadon msolhat oldalakrl sszeollzott lers
Tudom, hogy semmi j nincs benne az aurdino.cc-hez kpest, de egyrszt bele-
vettem pr library lerst, ami nem szerepelt az eredetiben, msrszt ez gy egy-
ben van, nem kell tokenenknt tnylazni...:-)
Publiklsra kerlt: 2012. november
(TavIR-AVR; www.tavir.hu)
Arduino Language Reference
Arduino programs can be divided in three main parts: structure, values (variables and constants),
and functions.
Structure
setup()
loop()

Control Structures
if
if...else
for
switch case
while
do... while
break
continue
return
goto

Further Syntax
; (semicolon)
{} (curl braces)
!! (single line comment)
!" "! (multi#line comment)
$define
$include
Arithmetic Operators
% (assignment operator)
&'nbsp; (addition)
# (subtraction)
" (multiplication)
! (division)
( (modulo)
Comparison Operators
%% (e)ual to)
*% (not e)ual to)
'lt; (less than)
'gt; (greater than)
'lt;% (less than or e)ual to)
'gt;% (greaterthanor e)ual to)
+
Boolean Operators
'amp;'amp; (and)
,, (or)
* (not)
Bitwise Operators
'amp; (bitwise and)
, (bitwise or)
- (bitwise .or)
/ (bitwise not)
'lt;'lt; (bitshift left)
'gt;'gt; (bitshift right)
Compound Operators
&& (increment)
0 (decrement)
&% (compound addition)
#% (compound subtraction)
"% (compound multiplication)
!% (compound division)
'amp;% (compound bitwise and)
,% (compound bitwise or)
Variables
Constants
1231 , 456
2789: , 59:89:, 2789:;894498
true , false
integer constants
floating point constants
Data Types
void
boolean
char
unsigned char
bte
int
unsigned int
word
long
unsigned long
float
<
double
string # char arra
=tring # ob>ect
arra
Conversion
char()
bte()
int()
word()
long()
float()
Variable Scope & uali!iers
variable scope
static
volatile
const
"tilities
si?eof()
Functions
Digital I/O
pin@ode()
digital6rite()
digitalAead()
Analog I/O
analogAeference()
analogAead()
analog6rite() # 86@
Advanced I/O
tone()
no:one()
shift5ut()
shift2n()
pulse2n()
Time
millis()
micros()
B
dela()
dela@icroseconds()
Math
min()
ma.()
abs()
constrain()
map()
pow()
s)rt()
Trigonometry
sin()
cos()
tan()
Random Numbers
random=eed()
random()
its and ytes
lowCte()
highCte()
bitAead()
bit6rite()
bit=et()
bitDlear()
bit()
Interru!ts
attach2nterrupt()
detach2nterrupt()
interrupts()
no2nterrupts()
"ommunication
=erial
=tream
Leonardo #!ecific
Eeboard
@ouse
F
abs#x$
Domputes the absolute value of a number.
%arameters: .: the number
&eturns' .: if . is greater than or e)ual to G.
#.: if . is less than G.
(arnin)
Cecause of the wa the abs() function is implemented, avoid using other functions inside the
brackets, it ma lead to incorrect results.
abs(a&&); !! avoid this # ields incorrect results
a&&; !! use this instead #
abs(a); !! keep other math outside the function
analo)&ead#$
Aeads the value from the specified analog pin. :he Arduino board contains a H channel (I channels
on the @ini and 7ano, +H on the @ega), +G#bit analog to digital converter. :his means that it will
map input voltages between G and J volts into integer values between G and +G<B. :his ields a
resolution between readings of: J volts ! +G<F units or, .GGFK volts (F.K mL) per unit. :he input
range and resolution can be changed using analogAeference().
2t takes about +GG microseconds (G.GGG+ s) to read an analog input, so the ma.imum reading rate is
about +G,GGG times a second.
Syntax' analogAead(pin)
%arameters' pin: the number of the analog input pin to read from (G to J on most boards, G to M on
the @ini and 7ano, G to +J on the @ega)
&eturns' int (G to +G<B)
*ote
2f the analog input pin is not connected to anthing, the value returned b analogAead() will
fluctuate based on a number of factors (e.g. the values of the other analog inputs, how close our
hand is to the board, etc.).
+xample
int analog8in % B; !! potentiometer wiper (middle terminal) connected to analog pin B
!! outside leads to ground and &JL
int val % G; !! variable to store the value read
void setup()
{
=erial.begin(KHGG); !! setup serial
}
J
void loop()
{
val % analogAead(analog8in); !! read the input pin
=erial.println(val); !! debug value
}
analo)&e!erence#type$
Donfigures the reference voltage used for analog input (i.e. the value used as the top of the input
range). :he options are:
" NOPA94:: the default analog reference of J volts (on JL Arduino boards) or B.B volts (on B.BL
Arduino boards)
" 27:OA7A4: an built#in reference, e)ual to +.+ volts on the A:mega+HI or A:megaB<I and <.JH
volts on the A:megaI (not available on the Arduino @ega)
" 27:OA7A4+L+: a built#in +.+L reference (Arduino @ega onl)
" 27:OA7A4<LJH: a built#in <.JHL reference (Arduino @ega onl)
" OQ:OA7A4: the voltage applied to the AAOP pin (G to JL onl) is used as the reference.
%arameters tpe: which tpe of reference to use (NOPA94:, 27:OA7A4, 27:OA7A4+L+,
27:OA7A4<LJH, or OQ:OA7A4).
&eturns 7one.
*ote After changing the analog reference, the first few readings from analogAead() ma not be
accurate.
(arnin)
NonRt use anthing less than GL or more than JL for e.ternal reference voltage on the AAOP pin* 2f
ouRre using an e.ternal reference on the AAOP pin, ou must set the analog reference to
OQ:OA7A4 before calling analogAead(). 5therwise, ou will short together the active reference
voltage (internall generated) and the AAOP pin, possibl damaging the microcontroller on our
Arduino board.
Alternativel, ou can connect the e.ternal reference voltage to the AAOP pin through a JE
resistor, allowing ou to switch between e.ternal and internal reference voltages. 7ote that the
resistor will alter the voltage that gets used as the reference because there is an internal B<E resistor
on the AAOP pin. :he two act as a voltage divider, so, for e.ample, <.JL applied through the
resistor will ield <.J " B< ! (B< & J) % /<.<L at the AAOP pin.
analo)(rite#$
6rites an analog value (86@ wave) to a pin. Dan be used to light a 4ON at varing brightnesses or
drive a motor at various speeds. After a call to analog6rite(), the pin will generate a stead s)uare
wave of the specified dut ccle until the ne.t call to analog6rite() (or a call to digitalAead() or
digital6rite() on the same pin). :he fre)uenc of the 86@ signal is appro.imatel FKG 1?.
H
5n most Arduino boards (those with the A:mega+HI or A:megaB<I), this function works on pins
B, J, H, K, +G, and ++. 5n the Arduino @ega, it works on pins < through +B. 5lder Arduino boards
with an A:megaI onl support analog6rite() on pins K, +G, and ++. Sou do not need to call
pin@ode() to set the pin as an output before calling analog6rite().
:he analog6rite function has nothing whatsoever to do with the analog pins or the analogAead
function.
Syntax' analog6rite(pin, value)
%arameters' pin: the pin to write to.
value: the dut ccle: between G (alwas off) and <JJ (alwas on).
&eturns' nothing
7otes and Enown 2ssues
:he 86@ outputs generated on pins J and H will have higher#than#e.pected dut ccles. :his is
because of interactions with the millis() and dela() functions, which share the same internal timer
used to generate those 86@ outputs. :his will be noticed mostl on low dut#ccle settings (e.g G #
+G) and ma result in a value of G not full turning off the output on pins J and H.
+xample
=ets the output to the 4ON proportional to the value read from the potentiometer.

int led8in % K; !! 4ON connected to digital pin K
int analog8in % B; !! potentiometer connected to analog pin B
int val % G; !! variable to store the read value
void setup()
{
pin@ode(led8in, 59:89:); !! sets the pin as output
}
void loop()
{
val % analogAead(analog8in); !! read the input pin
analog6rite(led8in, val ! F); !! analogAead values go from G to +G<B, analog6rite values
from G to <JJ
}
Addition, Subtraction, -ultiplication, & Division
:hese operators return the sum, difference, product, or )uotient (respectivel) of the two operands.
:he operation is conducted using the data tpe of the operands, so, for e.ample, K ! F gives < since
K and F are ints. :his also means that the operation can overflow if the result is larger than that
which can be stored in the data tpe (e.g. adding + to an int with the value B<,MHM gives #B<,MHI). 2f
the operands are of different tpes, the TlargerT tpe is used for the calculation.
M
2f one of the numbers (operands) are of the tpe float or of tpe double, floating point math will be
used for the calculation.
+xamples
% & B;
. % . # M;
i % > " H;
r % r ! J;
Syntax result % value+ & value<;
result % value+ # value<;
result % value+ " value<;
result % value+ ! value<;
%arameters' value+: an variable or constant
value<: an variable or constant
%ro)rammin) Tips'
" Enow that integer constants default to int, so some constant calculations ma overflow (e.g. HG "
+GGG will ield a negative result).
" Dhoose variable si?es that are large enough to hold the largest results from our calculations "
Enow at what point our variable will Troll overT and also what happens in the other direction e.g.
(G # +) 5A (G # # B<MHI)
" Por math that re)uires fractions, use float variables, but be aware of their drawbacks: large si?e,
slow computation speeds
" 9se the cast operator e.g. (int)mPloat to convert one variable tpe to another on the fl.
Arrays
An arra is a collection of variables that are accessed with an inde. number. Arras in the D
programming language, on which Arduino is based, can be complicated, but using simple arras is
relativel straightforward.
Creatin) #Declarin)$ an Array
All of the methods below are valid was to create (declare) an arra.
int m2ntsUHV;
int m8insUV % {<, F, I, B, H};
int m=ensLalsUHV % {<, F, #I, B, <};
char messageUHV % ThelloT;
Sou can declare an arra without initiali?ing it as in m2nts.
2n m8ins we declare an arra without e.plicitl choosing a si?e. :he compiler counts the elements
I
and creates an arra of the appropriate si?e.
Pinall ou can both initiali?e and si?e our arra, as in m=ensLals. 7ote that when declaring an
arra of tpe char, one more element than our initiali?ation is re)uired, to hold the re)uired
null character.
Accessin) an Array
Arras are ?ero inde.ed, that is, referring to the arra initiali?ation above, the first element of the
arra is at inde. G, hence
m=ensLalsUGV %% <, m=ensLalsU+V %% F, and so forth.
2t also means that in an arra with ten elements, inde. nine is the last element. 1ence:
int mArraU+GV%{K,B,<,F,B,<,M,I,K,++};
!! mArraUKV contains ++
!! mArraU+GV is invalid and contains random information (other memor address)
Por this reason ou should be careful in accessing arras. Accessing past the end of an arra (using
an inde. number greater than our declared arra si?e # +) is reading from memor that is in use for
other purposes. Aeading from these locations is probabl not going to do much e.cept ield invalid
data. 6riting to random memor locations is definitel a bad idea and can often lead to unhapp
results such as crashes or program malfunction. :his can also be a difficult bug to track down.
9nlike CA=2D or WALA, the D compiler does no checking to see if arra access is within legal
bounds of the arra si?e that ou have declared.
To assi)n a value to an array'
m=ensLalsUGV % +G;
To retrieve a value !rom an array'
. % m=ensLalsUFV;
Arrays and FO& .oops
Arras are often manipulated inside for loops, where the loop counter is used as the inde. for each
arra element. Por e.ample, to print the elements of an arra over the serial port, ou could do
something like this:
int i;
for (i % G; i X J; i % i & +) {
=erial.println(m8insUiV);
}
/ assi)nment operator #sin)le e0ual si)n$
=tores the value to the right of the e)ual sign in the variable to the left of the e)ual sign.
K
:he single e)ual sign in the D programming language is called the assignment operator. 2t has a
different meaning than in algebra class where it indicated an e)uation or e)ualit. :he assignment
operator tells the microcontroller to evaluate whatever value or e.pression is on the right side of the
e)ual sign, and store it in the variable to the left of the e)ual sign.
+xample
int sensLal; !! declare an integer variable named sensLal
senLal % analogAead(G); !! store the (digiti?ed) input voltage at analog pin G in =ensLal
%ro)rammin) Tips
:he variable on the left side of the assignment operator ( % sign ) needs to be able to hold the value
stored in it. 2f it is not large enough to hold a value, the value stored in the variable will be incorrect.
NonRt confuse the assignment operator U % V (single e)ual sign) with the comparison operator U %% V
(double e)ual signs), which evaluates whether two e.pressions are e)ual.
attach1nterrupt#$
=pecifies a function to call when an e.ternal interrupt occurs. Aeplaces an previous function that
was attached to the interrupt. @ost Arduino boards have two e.ternal interrupts: numbers G (on
digital pin <) and + (on digital pin B). :he Arduino @ega has an additional four: numbers < (pin <+),
B (pin <G), F (pin +K), and J (pin +I).
Syntax' attach2nterrupt(interrupt, function, mode)
%arameters' interrupt: the number of the interrupt (int)
function: the function to call when the interrupt occurs; this function must take no
parameters and return nothing. :his function is sometimes referred to as an interrupt
service routine.
mode defines when the interrupt should be triggered. Pour contstants are predefined
as valid
values' " 456 to trigger the interrupt whenever the pin is low,
" D1A73O to trigger the interrupt whenever the pin changes value
" A2=273 to trigger when the pin goes from low to high,
" PA44273 for when the pin goes from high to low.
&eturns' none
*ote' 2nside the attached function, dela() wonRt work and the value returned b millis() will
not increment. =erial data received while in the function ma be lost. Sou should
declare as volatile an variables that ou modif within the attached function.
Interru!ts using
2nterrupts are useful for making things happen automaticall in microcontroller programs, and can
help solve timing problems. A good task for using an interrupt might be reading a rotar encoder,
monitoring user input.
+G
2f ou wanted to insure that a program alwas caught the pulses from a rotar encoder, never
missing a pulse, it would make it ver trick to write a program to do anthing else, because the
program would need to constantl poll the sensor lines for the encoder, in order to catch pulses
when the occurred. 5ther sensors have a similar interface dnamic too, such as tring to read a
sound sensor that is tring to catch a click, or an infrared slot sensor (photo#interrupter) tring to
catch a coin drop. 2n all of these situations, using an interrupt can free the microcontroller to get
some other work done while not missing the doorbell.
+xample
int pin % +B;
volatile int state % 456;
void setup()
{
pin@ode(pin, 59:89:);
attach2nterrupt(G, blink, D1A73O);
}
void loop()
{
digital6rite(pin, state);
}
void blink()
{
state % *state;
}
be)in#$
=ets the data rate in bits per second (baud) for serial data transmission. Por communicating with the
computer, use one of these rates: BGG, +<GG, <FGG, FIGG, KHGG, +FFGG, +K<GG, <IIGG, BIFGG, JMHGG,
or ++J<GG. Sou can, however, specif other rates # for e.ample, to communicate over pins G and +
with a component that re)uires a particular baud rate.
Syntax' =erial.begin(speed)
Arduino -e)a only' =erial+.begin(speed)
=erial<.begin(speed)
=erialB.begin(speed)
%arameters' speed: in bits per second (baud) 0 long
&eturns' nothing
+xample
void setup() {
=erial.begin(KHGG); !! opens serial port, sets data rate to KHGG bps
++
}
void loop() {}
Arduino -e)a +xample
!! Arduino @ega using all four of its =erial ports
!! (=erial, =erial+, =erial<, =erialB),
!! with different baud rates:
void setup(){
=erial.begin(KHGG);
=erial+.begin(BIFGG);
=erial<.begin(+K<GG);
=erialB.begin(FIGG);
=erial.println(T1ello DomputerT);
=erial+.println(T1ello =erial +T);
=erial<.println(T1ello =erial <T);
=erialB.println(T1ello =erial BT);
}
void loop() {}
bitClear#$
Dlears (writes a G to) a bit of a numeric variable.
Syntax' bitDlear(., n)
%arameters .: the numeric variable whose bit to clear
n: which bit to clear, starting at G for the least#significant (rightmost) bit
&eturns' none
bit#$
Domputes the value of the specified bit (bit G is +, bit + is <, bit < is F, etc.).
Syntax' bit(n)
%arameters n: the bit whose value to compute
&eturns' the value of the bit
bit&ead#$
Description' Aeads a bit of a number.
Syntax' bitAead(., n)
%arameters' .: the number from which to read
n: which bit to read, starting at G for the least#significant (rightmost) bit
&eturns' the value of the bit (G or +).
+<
bitSet#$
=ets (writes a + to) a bit of a numeric variable.
Syntax' bit=et(., n)
%arameters' .: the numeric variable whose bit to set
n: which bit to set, starting at G for the least#significant (rightmost) bit
&eturns' none
bitshi!t le!t #22$, bitshi!t ri)ht #33$
Prom :he Citmath :utorial in :he 8laground
:here are two bit shift operators in D&&: the left shift operator XX and the right shift operator
YY. :hese operators cause the bits in the left operand to be shifted left or right b the number
of positions specified b the right operand.
Syntax' variable XX number;of;bits
variable YY number;of;bits
%arameters' variable # (bte, int, long) number;of;bits integer X% B<
+xample
int a % J; !! binar: GGGGGGGGGGGGG+G+
int b % a XX B; !! binar: GGGGGGGGGG+G+GGG, or FG in decimal
int c % b YY B; !! binar: GGGGGGGGGGGGG+G+, or back to J like we started with
6hen ou shift a value . b bits (. XX ), the leftmost bits in . are lost, literall shifted
out of e.istence:
int a % J; !! binar: GGGGGGGGGGGGG+G+
int b % a XX +F; !! binar: G+GGGGGGGGGGGGGG # the first + in +G+ was discarded
2f ou are certain that none of the ones in a value are being shifted into oblivion, a simple wa to
think of the left#shift operator is that it multiplies the left operand b < raised to the right operand
power. Por e.ample, to generate powers of <, the following e.pressions can be emploed:
+ XX G %% +
+ XX + %% <
+ XX < %% F
+ XX B %% I
...
+ XX I %% <JH
+ XX K %% J+<
+ XX +G %% +G<F
...
6hen ou shift . right b bits (. YY ), and the highest bit in . is a +, the behavior depends on the
+B
e.act data tpe of .. 2f . is of tpe int, the highest bit is the sign bit, determining whether . is
negative or not, as we have discussed above. 2n that case, the sign bit is copied into lower bits, for
esoteric historical reasons:
int . % #+H; !! binar: ++++++++++++GGGG
int % . YY B; !! binar: +++++++++++++++G
:his behavior, called sign e.tension, is often not the behavior ou want. 2nstead, ou ma wish
?eros to be shifted in from the left. 2t turns out that the right shift rules are different for unsigned int
e.pressions, so ou can use a tpecast to suppress ones being copied from the left:
int . % #+H; !! binar: ++++++++++++GGGG
int % (unsigned int). YY B; !! binar: GGG++++++++++++G
2f ou are careful to avoid sign e.tension, ou can use the right#shift operator YY as a wa to divide
b powers of <. Por O.ample
int . % +GGG;
int % . YY B; !! integer division of +GGG b I, causing % +<J.
Bitwise A*D #&$, Bitwise O& #4$, Bitwise 5O& #6$
:he bitwise operators perform their calculations at the bit level of variables. :he help solve a wide
range of common programming problems. @uch of the material below is from an e.cellent tutorial
on bitwise math wihch ma be found here.
Bitwise A*D #&$
:he bitwise A7N operator in D&& is a single ampersand, ', used between two other integer
e.pressions. Citwise A7N operates on each bit position of the surrounding e.pressions
independentl, according to this rule: if both input bits are +, the resulting output is +, otherwise the
output is G. Another wa of e.pressing this is:
G G + + operand+
G + G + operand<
##########
G G G + (operand+ ' operand<) # returned result
2n Arduino, the tpe int is a +H#bit value, so using ' between two int e.pressions causes +H
simultaneous A7N operations to occur. 2n a code fragment like:
int a % K<; !! in binar: GGGGGGGGG+G+++GG
int b % +G+; !! in binar: GGGGGGGGG++GG+G+
int c % a ' b; !! result: GGGGGGGGG+GGG+GG, or HI in decimal.
Oach of the +H bits in a and b are processed b using the bitwise A7N, and all +H resulting bits are
stored in c, resulting in the value G+GGG+GG in binar, which is HI in decimal.
5ne of the most common uses of bitwise A7N is to select a particular bit (or bits) from an integer
value, often called masking. =ee below for an e.ample
+F
Bitwise O& #4$
:he bitwise 5A operator in D&& is the vertical bar smbol, ,. 4ike the ' operator, , operates
independentl each bit in its two surrounding integer e.pressions, but what it does is different (of
course). :he bitwise 5A of two bits is + if either or both of the input bits is +, otherwise it is G. 2n
other words:
G G + + operand+
G + G + operand<
##########
G + + + (operand+ , operand<) # returned result
1ere is an e.ample of the bitwise 5A used in a snippet of D&& code:
int a % K<; !! in binar: GGGGGGGGG+G+++GG
int b % +G+; !! in binar: GGGGGGGGG++GG+G+
int c % a , b; !! result: GGGGGGGGG+++++G+, or +<J in decimal.
+xample %ro)ram
A common >ob for the bitwise A7N and 5A operators is what programmers call Aead#@odif#
6rite on a port. 5n microcontrollers, a port is an I bit number that represents something about the
condition of the pins. 6riting to a port controls all of the pins at once.
85A:N is a built#in constant that refers to the output states of digital pins G,+,<,B,F,J,H,M. 2f there is
+ in an bit position, then that pin is 1231. (:he pins alread need to be set to outputs with the
pin@ode() command.) =o if we write 85A:N % CGG++GGG+; we have made pins <,B ' M 1231.
5ne slight hitch here is that we ma also have changeed the state of 8ins G ' +, which are used b
the Arduino for serial communications so we ma have interfered with serial communication.
5ur algorithm for the program is:
" 3et 85A:N and clear out onl the bits corresponding to the pins we wish to control (with
bitwise A7N).
" Dombine the modified 85A:N value with the new value for the pins under control (with
biwise 5A).
int i; !! counter variable
int >;
void setup(){
NNAN % NNAN , C++++++GG; !! set direction bits for pins < to M, leave G and + untouched (.. , GG
%% ..)
!! same as pin@ode(pin, 59:89:) for pins < to M
=erial.begin(KHGG);
}
void loop(){
for (i%G; iXHF; i&&){
85A:N % 85A:N ' CGGGGGG++; !! clear out bits < # M, leave pins G and + untouched (.. ' ++ %%
..)
+J
> % (i XX <); !! shift variable up to pins < # M # to avoid pins G and +
85A:N % 85A:N , >; !! combine the port information with the new information for 4ON pins
=erial.println(85A:N, C27); !! debug to show masking
dela(+GG);
}
}
Bitwise 5O& #6$
:here is a somewhat unusual operator in D&& called bitwise OQD49=2LO 5A, also known as
bitwise Q5A. (2n Onglish this is usuall pronounced Teks#orT.) :he bitwise Q5A operator is written
using the caret smbol -. :his operator is ver similar to the bitwise 5A operator ,, onl it evaluates
to G for a given bit position when both of the input bits for that position are +:
G G + + operand+
G + G + operand<
##########
G + + G (operand+ - operand<) # returned result
Another wa to look at bitwise Q5A is that each bit in the result is a + if the input bits are different,
or G if the are the same.
7ere is a simple code +xample
int . % +<; !! binar: ++GG
int % +G; !! binar: +G+G
int ? % . - ; !! binar: G++G, or decimal H
:he - operator is often used to toggle (i.e. change from G to +, or + to G) some of the bits in an
integer e.pression. 2n a bitwise 5A operation if there is a + in the mask bit, that bit is inverted; if
there is a G, the bit is not inverted and stas the same. Celow is a program to blink digital pin J.
!! Clink;8in;J
!! demo for O.clusive 5A
void setup(){
NNAN % NNAN , CGG+GGGGG; !! set digital pin five as 59:89:
=erial.begin(KHGG);
}
void loop(){
85A:N % 85A:N - CGG+GGGGG; !! invert bit J (digital pin J), leave others untouched
dela(+GG);
}
compound bitwise A*D #&/$
:he compound bitwise A7N operator ('%) is often used with a variable and a constant to force
particular bits in a variable to the 456 state (to G). :his is often referred to in programming guides
as TclearingT or TresettingT bits.
+H
Syntax' . '% ; !! e)uivalent to . % . ' ;
%arameters' .: a char, int or long variable
: an integer constant or char, int, or long
+xample
Pirst, a review of the Citwise A7N (') operator
G G + + operand+
G + G + operand<
##########
G G G + (operand+ ' operand<) # returned result
Cits that are Tbitwise A7NedT with G are cleared to G so, if mCte is a bte variable, mCte '
CGGGGGGGG % G;
Cits that are Tbitwise A7NedT with + are unchanged so,
mCte ' C++++++++ % mCte;
*ote' because we are dealing with bits in a bitwise operator # it is convenient to use the binar
formatter with constants. :he numbers are still the same value in other representations, the
are >ust not as eas to understand. Also, CGGGGGGGG is shown for clarit, but ?ero in an
number format is ?ero (hmmm something philosophical thereZ)
Donse)uentl # to clear (set to ?ero) bits G ' + of a variable, while leaving the rest of the variable
unchanged, use the compound bitwise A7N operator ('%) with the constant C++++++GG
+ G + G + G + G variable
+ + + + + + G G mask
######################
+ G + G + G G G variable unchanged bits cleared
1ere is the same representation with the variableRs bits replaced with the smbol .
. . . . . . . . variable
+ + + + + + G G mask
######################
. . . . . . G G variable unchanged bits cleared

=o if:
mCte % +G+G+G+G;
mCte '% C+++++GG %% C+G+G+GGG;
compound bitwise O& #4/$
:he compound bitwise 5A operator (,%) is often used with a variable and a constant to TsetT (set to
+) particular bits in a variable.
Syntax' . ,% ; !! e)uivalent to . % . , ;
+M
%arameters' .: a char, int or long variable
: an integer constant or char, int, or long
+xample
Pirst, a review of the Citwise 5A (,) operator
G G + + operand+
G + G + operand<
##########
G + + + (operand+ , operand<) # returned result
Cits that are Tbitwise 5AedT with G are unchanged, so if mCte is a bte variable,
mCte , CGGGGGGGG % mCte;
Cits that are Tbitwise 5AedT with + are set to + so: mCte , C++++++++ % C++++++++;
Donse)uentl # to set bits G ' + of a variable, while leaving the rest of the variable unchanged, use
the compound bitwise 5A operator (,%) with the constant CGGGGGG++
+ G + G + G + G variable
G G G G G G + + mask
######################
+ G + G + G + + variable unchanged bits set
1ere is the same representation with the variables bits replaced with the smbol .
. . . . . . . . variable
G G G G G G + + mask
######################
. . . . . . + +
variable unchanged bits set
=o if: mCte % C+G+G+G+G;
mCte ,% CGGGGGG++ %% C+G+G+G++;
Bitwise *OT #8$
:he bitwise 75: operator in D&& is the tilde character /. 9nlike ' and ,, the bitwise 75: operator
is applied to a single operand to its right. Citwise 75: changes each bit to its opposite: G becomes
+, and + becomes G. Por O.ample
G + operand+
##########
+ G / operand+
int a % +GB; !! binar: GGGGGGGGG++GG+++
int b % /a; !! binar: +++++++++GG++GGG % #+GF
Sou might be surprised to see a negative number like #+GF as the result of this operation. :his is
because the highest bit in an int variable is the so#called sign bit. 2f the highest bit is +, the number
is interpreted as negative. :his encoding of positive and negative numbers is referred to as twoRs
+I
complement. Por more information, see the 6ikipedia article on twoRs complement.
As an aside, it is interesting to note that for an integer ., /. is the same as #.#+.
At times, the sign bit in a signed integer e.pression can cause some unwanted surprises.
bit(rite#$
6rites a bit of a numeric variable.
Syntax' bit6rite(., n, b)
%arameters' .: the numeric variable to which to write
n: which bit of the number to write, starting at G for the least#significant (rightmost)
bit
b: the value to write to the bit (G or +)
&eturns' none
Boolean Operators
:hese can be used inside the condition of an if statement.
&& #lo)ical and$
:rue onl if both operands are true, e.g.
if (digitalAead(<) %% 1231 '' digitalAead(B) %% 1231) { !! read two switches
!! ...
}
is true onl if both inputs are high.
44 #lo)ical or$
:rue if either operand is true, e.g.
if (. Y G ,, Y G) {
!! ...
}
is true if either . or is greater than G.
9 #not$
:rue if the operand is false, e.g.
+K
if (*.) {
!! ...
}
is true if . is false (i.e. if . e)uals G).
(arnin)99 @ake sure ou donRt mistake the boolean A7N operator, '' (double ampersand) for
the bitwise A7N operator ' (single ampersand). :he are entirel different beasts.
=imilarl, do not confuse the boolean ,, (double pipe) operator with the bitwise 5A
operator , (single pipe). :he bitwise not / (tilde) looks much different than the
boolean not * (e.clamation point or TbangT as the programmers sa) but ou still
have to be sure which one ou want where.
+xamples
if (a Y% +G '' a X% <G){} !! true if a is between +G and <G
boolean
A boolean holds one of two values, true or false. (Oach boolean variable occupies one bte of
memor.)
+xample
int 4ONpin % J; !! 4ON on pin J
int switch8in % +B; !! momentar switch on +B, other side connected to ground
boolean running % false;
void setup()
{
pin@ode(4ONpin, 59:89:);
pin@ode(switch8in, 2789:);
digital6rite(switch8in, 1231); !! turn on pullup resistor
}
void loop()
{
if (digitalAead(switch8in) %% 456)
{ !! switch is pressed # pullup keeps pin high normall
dela(+GG); !! dela to debounce switch
running % *running; !! toggle running variable
digital6rite(4ONpin, running) !! indicate via 4ON
}
}
:; Curly Braces
Durl braces (also referred to as >ust TbracesT or as Tcurl bracketsT) are a ma>or part of the D
programming language. :he are used in several different constructs, outlined below, and this can
sometimes be confusing for beginners.
<G
An opening curl brace T{T must alwas be followed b a closing curl brace T}T. :his is a
condition that is often referred to as the braces being balanced. :he Arduino 2NO (integrated
development environment) includes a convenient feature to check the balance of curl braces. Wust
select a brace, or even click the insertion point immediatel following a brace, and its logical
companion will be highlighted.
At present this feature is slightl bugg as the 2NO will often find (incorrectl) a brace in te.t that
has been Tcommented out.T
Ceginning programmers, and programmers coming to D from the CA=2D language often find using
braces confusing or daunting. After all, the same curl braces replace the AO:9A7 statement in a
subroutine (function), the O7N2P statement in a conditional and the 7OQ: statement in a P5A
loop.
Cecause the use of the curl brace is so varied, it is good programming practice to tpe the closing
brace immediatel after tping the opening brace when inserting a construct which re)uires curl
braces. :hen insert some carriage returns between our braces and begin inserting statements. Sour
braces, and our attitude, will never become unbalanced.
9nbalanced braces can often lead to crptic, impenetrable compiler errors that can sometimes be
hard to track down in a large program. Cecause of their varied usages, braces are also incredibl
important to the snta. of a program and moving a brace one or two lines will often dramaticall
affect the meaning of a program.
The main uses o! curly braces
Functions
void mfunction(datatpe argument){
statements(s)
}
.oops
while (boolean e.pression)
{
statement(s)
}
do
{
statement(s)
} while (boolean e.pression);
!or (initialisation; termination condition; incrementing e.pr)
{
statement(s)
}
Conditional statements
<+
if (boolean e.pression)
{
statement(s)
}
else if (boolean e.pression)
{
statement(s)
}
else
{
statement(s)
}
brea<
break is used to e.it from a do, for, or while loop, bpassing the normal loop condition. 2t is also
used to e.it from a switch statement.
+xample
for (. % G; . X <JJ; . &&)
{
digital6rite(86@pin, .);
sens % analogAead(sensor8in);
if (sens Y threshold){ !! bail out on sensor detect
. % G;
break;
}
dela(JG);
}
byte#$
Donverts a value to the bte data tpe.
Syntax' bte(.)
%arameters' .: a value of an tpe
&eturns' bte
byte
A bte stores an I#bit unsigned number, from G to <JJ.
+xample
bte b % C+GG+G; !! TCT is the binar formatter (C+GG+G % +I decimal)
<<
char#$
Donverts a value to the char data tpe.
Syntax' char(.)
%arameters' .: a value of an tpe
&eturns' char
char
A data tpe that takes up + bte of memor that stores a character value. Dharacter literals are
written in single )uotes, like this: RAR (for multiple characters # strings # use double )uotes: TACDT).
Dharacters are stored as numbers however. Sou can see the specific encoding in the A=D22 chart.
:his means that it is possible to do arithmetic on characters, in which the A=D22 value of the
character is used (e.g. RAR & + has the value HH, since the A=D22 value of the capital letter A is HJ).
=ee =erial.println reference for more on how characters are translated to numbers.
:he char datatpe is a signed tpe, meaning that it encodes numbers from #+<I to +<M. Por an
unsigned, one#bte (I bit) data tpe, use the bte data tpe.
+xample
char mDhar % RAR;
char mDhar % HJ; !! both are e)uivalent
Comments
Domments are lines in the program that are used to inform ourself or others about the wa the
program works. :he are ignored b the compiler, and not e.ported to the processor, so the donRt
take up an space on the Atmega chip.
Domments onl purpose are to help ou understand (or remember) how our program works or to
inform others how our program works. :here are two different was of marking a line as a
comment:
+xample
. % J; !! :his is a single line comment. Anthing after the slashes is a comment
!! to the end of the line
!" this is multiline comment # use it to comment out whole blocks of code
if (gwb %% G){ !! single line comment is 5E inside a multiline comment
. % B; !" but not another multiline comment # this is invalid "!
}
!! donRt forget the TclosingT comment # the have to be balanced*
"!
Tip' 6hen e.perimenting with code, Tcommenting outT parts of our program is a convenient wa
to remove lines that ma be bugg. :his leaves the lines in the code, but turns them into
comments, so the compiler >ust ignores them. :his can be especiall useful when tring to
<B
locate a problem, or when a program refuses to compile and the compiler error is crptic or
unhelpful.
Arduino=%rocessin) .an)ua)e Comparison
:he Arduino language (based on 6iring) is implemented in D!D&&, and therefore has some
differences from the 8rocessing language, which is based on Wava.
Arrays
Arduino 8rocessing
int barUIV;
barUGV % +; intUV bar % new intUIV;
barUGV % +;
int fooUV % { G, +, < }; int fooUV % { G, +, < };
or
intUV foo % { G, +, < };
.oops
Arduino 8rocessing
int i;
for (i % G; i X J; i&&) { ... } for (int i % G; i X J; i&&) { ... }
%rintin)
Arduino 8rocessing
=erial.println(Thello worldT); println(Thello worldT);
int i % J;
=erial.println(i); int i % J;
println(i);
int i % J;
=erial.print(Ti % T);
=erial.print(i);
=erial.println(); int i % J;
println(Ti % T & i);
constants
Donstants are predefined variables in the Arduino language. :he are used to make the programs
easier to read. 6e classif constants in groups.
De!inin) .o)ical .evels, true and !alse #Boolean Constants$
:here are two constants used to represent truth and falsit in the Arduino language: true, and false.
!alse false is the easier of the two to define. false is defined as G (?ero).
true true is often said to be defined as +, which is correct, but true has a wider definition.
An integer which is non#?ero is true, in a Coolean sense. =o #+, < and #<GG are all
defined as true, too, in a Coolean sense.
<F
7ote that the true and false constants are tped in lowercase unlike 1231, 456, 2789:, '
59:89:.
De!inin) %in .evels, 71>7 and .O(
6hen reading or writing to a digital pin there are onl two possible values a pin can take!be#set#to:
1231 and 456.
71>7
:he meaning of 1231 (in reference to a pin) is somewhat different depending on whether a pin is
set to an 2789: or 59:89:. 6hen a pin is configured as an 2789: with pin@ode, and read with
digitalAead, the microcontroller will report 1231 if a voltage of B volts or more is present at the
pin.
A pin ma also be configured as an 2789: with pin@ode, and subse)uentl made 1231 with
digital6rite, this will set the internal <GE pullup resistors, which will steer the input pin to a 1231
reading unless it is pulled 456 b e.ternal circuitr. :his is how 2789:;894498 works as well
6hen a pin is configured to 59:89: with pin@ode, and set to 1231 with digital6rite, the pin is
at J volts. 2n this state it can source current, e.g. light an 4ON that is connected through a series
resistor to ground, or to another pin configured as an output, and set to 456.
.O(
:he meaning of 456 also has a different meaning depending on whether a pin is set to 2789: or
59:89:. 6hen a pin is configured as an 2789: with pin@ode, and read with digitalAead, the
microcontroller will report 456 if a voltage of < volts or less is present at the pin.
6hen a pin is configured to 59:89: with pin@ode, and set to 456 with digital6rite, the pin is
at G volts. 2n this state it can sink current, e.g. light an 4ON that is connected through a series
resistor to, &J volts, or to another pin configured as an output, and set to 1231.
De!inin) Di)ital %ins, 1*%"T, 1*%"T?%".."%, and O"T%"T
Nigital pins can be used as 2789:, 2789:;894498, or 59:89:. Dhanging a pin with
pin@ode() changes the electrical behavior of the pin.
%ins Con!i)ured as 1*%"T
Arduino (Atmega) pins configured as 2789: with pin@ode() are said to be in a high#impedance
state. 8ins configured as 2789: make e.tremel small demands on the circuit that the are
sampling, e)uivalent to a series resistor of +GG @egohms in front of the pin. :his makes them
useful for reading a sensor, but not powering an 4ON.
2f ou have our pin configured as an 2789:, ou will want the pin to have a reference to ground,
often accomplished with a pull#down resistor (a resistor going to ground) as described in the Nigital
Aead =erial tutorial.
%ins Con!i)ured as 1*%"T?%".."%
:he Atmega chip on the Arduino has internal pull#up resistors (resistors that connect to power
<J
internall) that ou can access. 2f ou prefer to use these instead of e.ternal pull#down resistors, ou
can use the 2789:;894498 argument in pin@ode(). :his effectivel inverts the behavior, where
1231 means the sensor is off, and 456 means the sensor is on. =ee the 2nput 8ullup =erial tutorial
for an e.ample of this in use.
%ins Con!i)ured as Outputs
8ins configured as 59:89: with pin@ode() are said to be in a low#impedance state. :his means
that the can provide a substantial amount of current to other circuits. Atmega pins can source
(provide positive current) or sink (provide negative current) up to FG mA (milliamps) of current to
other devices!circuits. :his makes them useful for powering 4ONRs but useless for reading sensors.
8ins configured as outputs can also be damaged or destroed if short circuited to either ground or J
volt power rails. :he amount of current provided b an Atmega pin is also not enough to power
most relas or motors, and some interface circuitr will be re)uired.
const <eyword
:he const keword stands for constant. 2t is a variable )ualifier that modifies the behavior of the
variable, making a variable Tread#onlT. :his means that the variable can be used >ust as an other
variable of its tpe, but its value cannot be changed. Sou will get a compiler error if ou tr to
assign a value to a const variable.
Donstants defined with the const keword obe the rules of variable scoping that govern other
variables. :his, and the pitfalls of using$define, makes the const keword a superior method for
defining constants and is preferred over using $define.
+xample
const float pi % B.+F;
float .;
!! ....
. % pi " <; !! itRs fine to use constRs in math
pi % M; !! illegal # ou canRt write to (modif) a constant
@de!ine or const
Sou can use either const or $define for creating numeric or string constants. Por arras, ou will
need to use const. 2n general const is preferred over $define for defining constants.
constrain#x, a, b$
Donstrains a number to be within a range.
%arameters .: the number to constrain, all data tpes
a: the lower end of the range, all data tpes
b: the upper end of the range, all data tpes
&eturns .: if . is between a and b
<H
a: if . is less than a
b: if . is greater than b
+xample
sensLal % constrain(sensLal, +G, +JG); !! limits range of sensor values to between +G and +JG
continue
:he continue statement skips the rest of the current iteration of a loop (do, for, or while). 2t
continues b checking the conditional e.pression of the loop, and proceeding with an subse)uent
iterations.
O.ample
for (. % G; . X <JJ; . &&)
{
if (. Y FG '' . X +<G){ !! create >ump in values
continue;
}
digital6rite(86@pin, .);
dela(JG);
}
cos#rad$
Dalculates the cos of an angle (in radians). :he result will be between #+ and +.
%arameters' rad: the angle in radians (float)
&eturns' :he cos of the angle (TdoubleT)
<M
DCFAA .ibrary
:he NDPMM librar adds the abilit to read and decode the atomic time broadcasted b the NDPMM
radiostation. 2t has been designed to work in con>unction with the Arduino :ime librar and allows
a sketch to get the precise DO: time and date as a standard D time;t.
:he NDPMM 4ibrar download. O.ample sketches have been added to +) illustrate and debug the
incoming signal <) use the librar, using the set=nc8rovider callback and converting to different
time ?ones. 2n order to e.ploit all features in the librar, Coth the :ime and :ime[one librar are
included.
Functional Overview
NDPMM(NDPMM8in, NDPinterrupt, 5nAisingPlank); !! 2nitiali?e
time;t get:ime(); !! Aeturns the current time in DO:
time;t get9:D:ime(); !! Aeturns the current time in 9:D
=tart(); !! =tart listening to NDPMM signal
=top(); !! =top listening to NDPMM sign
+xample
:he sketch below implements the most NDPMM basic functionalit. 2t reads the signal from pin <,
and <#B minutes it will update the internal clock.
$include TNDPMM.hT
$include T:ime.hT
$define NDP;827 < !! Donnection pin to NDP MM device
$define NDP;27:OAA98: G !! 2nterrupt number associated with pin
time;t time;
!! 7on#inverted input on pin NDP;827
NDPMM NDP % NDPMM(NDP;827,NDP;27:OAA98:, true);
void setup() {
=erial.begin(KHGG);
NDP.=tart();
=erial.println(T6aiting for NDPMM time ... T);
=erial.println(T2t will take at least < minutes before a first time update.T);
}
void loop() {
dela(+GGG);
time;t NDPtime % NDP.get:ime(); !! Dheck if new NDPMM time is available
if (NDPtime*%G)
{
=erial.println(T:ime is updatedT);
set:ime(NDPtime);
}
digitalDlockNispla();
}
void digitalDlockNispla(){
<I
!! digital clock displa of the time
=erial.print(hour());
printNigits(minute());
printNigits(second());
=erial.print(T T);
=erial.print(da());
=erial.print(T T);
=erial.print(month());
=erial.print(T T);
=erial.print(ear());
=erial.println();
}
void printNigits(int digits){
!! utilit function for digital clock displa: prints preceding colon and leading G
=erial.print(T:T);
if(digits X +G)
=erial.print(RGR);
=erial.print(digits);
}
@de!ine
$define is a useful D component that allows the programmer to give a name to a constant value
before the program is compiled. Nefined constants in arduino donRt take up an program memor
space on the chip. :he compiler will replace references to these constants with the defined value at
compile time.
:his can have some unwanted side effects though, if for e.ample, a constant name that had been
$defined is included in some other constant or variable name. 2n that case the te.t would be
replaced b the $defined number (or te.t). 2n general, the const keword is preferred for defining
constants and should be used instead of $define.
Syntax' $define constant7ame value (7ote that the $ is necessar.)
+xample
$define led8in B
!! :he compiler will replace an mention of led8in with the value B at compile time.
Tip' :here is no semicolon after the $define statement. 2f ou include one, the compiler will
throw crptic errors further down the page.
$define led8in B; !! this is an error
=imilarl, including an e)ual sign after the $define statement will also generate a crptic compiler
error further down the page.
$define led8in % B !! this is also an error
<K
delay#$
8auses the program for the amount of time (in miliseconds) specified as parameter. (:here are +GGG
milliseconds in a second.)
Syntax' dela(ms)
%arameters' ms: the number of milliseconds to pause (unsigned long)
&eturns' nothing
+xample
int led8in % +B; !! 4ON connected to digital pin +B
void setup()
{
pin@ode(led8in, 59:89:); !! sets the digital pin as output
}
void loop()
{
digital6rite(led8in, 1231); !! sets the 4ON on
dela(+GGG); !! waits for a second
digital6rite(led8in, 456); !! sets the 4ON off
dela(+GGG); !! waits for a second
}
Caveat
6hile it is eas to create a blinking 4ON with the dela() function, and man sketches use short
delas for such tasks as switch debouncing, the use of dela() in a sketch has significant drawbacks.
7o other reading of sensors, mathematical calculations, or pin manipulation can go on during the
dela function, so in effect, it brings most other activit to a halt. Por alternative approaches to
controlling timing see the millis() function and the sketch sited below. @ore knowledgeable
programmers usuall avoid the use of dela() for timing of events longer than +GRs of milliseconds
unless the Arduino sketch is ver simple.
Dertain things do go on while the dela() function is controlling the Atmega chip however, because
the dela function does not disable interrupts. =erial communication that appears at the AQ pin is
recorded, 86@ (analog6rite) values and pin states are maintained, and interrupts will work as the
should.
delay-icroseconds#$
8auses the program for the amount of time (in microseconds) specified as parameter. :here are a
thousand microseconds in a millisecond, and a million microseconds in a second.
Durrentl, the largest value that will produce an accurate dela is +HBIB. :his could change in
future Arduino releases. Por delas longer than a few thousand microseconds, ou should use
dela() instead.
Syntax' dela@icroseconds(us)
BG
%arameters' us: the number of microseconds to pause (unsigned int)
&eturns' none
+xample
int out8in % I; !! digital pin I
void setup()
{
pin@ode(out8in, 59:89:); !! sets the digital pin as output
}
void loop()
{
digital6rite(out8in, 1231); !! sets the pin on
dela@icroseconds(JG); !! pauses for JG microseconds
digital6rite(out8in, 456); !! sets the pin off
dela@icroseconds(JG); !! pauses for JG microseconds
}
configures pin number I to work as an output pin. 2t sends a train of pulses with +GG microseconds
period.
Caveats and Known Issues
:his function works ver accuratel in the range B microseconds and up. 6e cannot assure that
dela@icroseconds will perform precisel for smaller dela#times.
As of Arduino GG+I, dela@icroseconds() no longer disables interrupts.
detach1nterrupt#$
:urns off the given interrupt.
Syntax' detach2nterrupt(interrupt)
%arameters' interrupt: the number of interrupt to disable (G or +).
di)ital&ead#$
Aeads the value from a specified digital pin, either 1231 or 456.
Syntax' digitalAead(pin)
%arameters' pin: the number of the digital pin ou want to read (int)
&eturns' 1231 or 456
+xample

int led8in % +B; !! 4ON connected to digital pin +B
int in8in % M; !! pushbutton connected to digital pin M
int val % G; !! variable to store the read value
void setup()
B+
{
pin@ode(led8in, 59:89:); !! sets the digital pin +B as output
pin@ode(in8in, 2789:); !! sets the digital pin M as input
}
void loop()
{
val % digitalAead(in8in); !! read the input pin
digital6rite(led8in, val); !! sets the 4ON to the buttonRs value
}
=ets pin +B to the same value as the pin M, which is an input.
*ote' 2f the pin isnRt connected to anthing, digitalAead() can return either 1231 or 456 (and
this can change randoml).
:he analog input pins can be used as digital pins, referred to as AG, A+, etc.
di)ital(rite#$
6rite a 1231 or a 456 value to a digital pin.
2f the pin has been configured as an 59:89: with pin@ode(), its voltage will be set to the
corresponding value: JL (or B.BL on B.BL boards) for 1231, GL (ground) for 456.
2f the pin is configured as an 2789:, writing a 1231 value with digital6rite() will enable an
internal <GE pullup resistor (see the tutorial on digital pins). 6riting 456 will disable the pullup.
:he pullup resistor is enough to light an 4ON diml, so if 4ONs appear to work, but ver diml, this
is a likel cause. :he remed is to set the pin to an output with the pin@ode() function.
*OT+' Nigital pin +B is harder to use as a digital input than the other digital pins because it has an
4ON and resistor attached to it thatRs soldered to the board on most boards. 2f ou enable its
internal <Gk pull#up resistor, it will hang at around +.M L instead of the e.pected JL
because the onboard 4ON and series resistor pull the voltage level down, meaning it alwas
returns 456. 2f ou must use pin +B as a digital input, use an e.ternal pull down resistor.
Syntax' digital6rite(pin, value)
%arameters' pin: the pin number
value: 1231 or 456
&eturns' none
+xample

int led8in % +B; !! 4ON connected to digital pin +B
void setup()
{
pin@ode(led8in, 59:89:); !! sets the digital pin as output
}
B<
void loop()
{
digital6rite(led8in, 1231); !! sets the 4ON on
dela(+GGG); !! waits for a second
digital6rite(led8in, 456); !! sets the 4ON off
dela(+GGG); !! waits for a second
}
=ets pin +B to 1231, makes a one#second#long dela, and sets the pin back to 456.
*ote' :he analog input pins can be used as digital pins, referred to as AG, A+, etc.
double
Nouble precision floating point number. 5ccupies F btes.
:he double implementation on the Arduino is currentl e.actl the same as the float, with no gain
in precision.
Tip' 9sers who borrow code from other sources that includes double variables ma wish to
e.amine the code to see if the implied precision is different from that actuall achieved on the
Arduino.
do B while
:he do loop works in the same manner as the while loop, with the e.ception that the condition is
tested at the end of the loop, so the do loop will alwas run at least once.
do
{
!! statement block
} while (test condition);
+xample
do
{
dela(JG); !! wait for sensors to stabili?e
. % read=ensors(); !! check the sensors
} while (. X +GG);
++%&O- .ibrary
:he microcontroller on the Arduino board has OO8A5@: memor whose values are kept when the
board is turned off (like a tin hard drive). :his librar enables ou to read and write those btes.
:he microcontrollers on the various Arduino boards have different amounts of OO8A5@: +G<F
btes on the A:megaB<I, J+< btes on the A:mega+HI and A:megaI, F EC (FGKH btes) on the
A:mega+<IG and A:mega<JHG.
BB
++%&O-Cread#$
Aeads a bte from the OO8A5@. 4ocations that have never been written to have the value of <JJ.
Syntax' OO8A5@.read(address)
%arameters' address: the location to read from, starting from G (int)
&eturns' the value stored in that location (bte)
+xample
$include XOO8A5@.hY
int a % G;
int value;
void setup()
{
=erial.begin(KHGG);
}
void loop()
{
value % OO8A5@.read(a);
=erial.print(a);
=erial.print(T\tT);
=erial.print(value);
=erial.println();
a % a & +;
if (a %% J+<)
a % G;
dela(JGG);
}
++%&O-Cwrite#$
6rite a bte to the OO8A5@.
Syntax' OO8A5@.write(address, value)
%arameters' address: the location to write to, starting from G (int)
value: the value to write, from G to <JJ (bte)
&eturns' none
*ote' An OO8A5@ write takes B.B ms to complete. :he OO8A5@ memor has a specified life of
+GG,GGG write!erase ccles, so ou ma need to be careful about how often ou write to it.
BF
+xample
$include XOO8A5@.hY
void setup()
{
for (int i % G; i X J+<; i&&)
OO8A5@.write(i, i);
}
void loop()
{
}
+thernet library
6ith the Arduino Othernet =hield, this librar allows an Arduino board to connect to the internet. 2t
can serve as either a server accepting incoming connections or a client making outgoing ones. :he
librar supports up to four concurrent connection (incoming or outgoing or a combination).
Arduino communicates with the shield using the =82 bus. :his is on digital pins ++, +<, and +B on
the 9no and pins JG, J+, and J< on the @ega. 5n both boards, pin +G is used as ==. 5n the @ega,
the hardware == pin, JB, is not used to select the 6J+GG, but it must be kept as an output or the =82
interface wonRt work.
+thernet class
:he Othernet class initiali?es the ethernet librar and network settings.
" begin()
" local28()
" maintain()
1%Address class
:he 28Address class works with local and remote 28 addressing.
" 28Address()
Server class
:he =erver class creates servers which can send data to and receive data from connected clients
(programs running on other computers or devices).
" =erver
" Othernet=erver()
" begin()
" available()
" write()
BJ
" print()
" println()
Client class
:he client class creates clients that can connect to servers and send and receive data.
" Dlient
" OthernetDlient()
" if (OthernetDlient)
" connected()
" connect()
" write()
" print()
" println()
" available()
" read()
" flush()
" stop()
+thernet"D% class
:he Othernet9N8 class enables 9N8 message to be sent and received.
" begin()
" read()
" write()
" begin8acket()
" end8acket()
" parse8acket()
" available()
" remote28()
" remote8ort()
+thernetCbe)in#$
2nitiali?es the ethernet librar and network settings.
6ith version +.G, the librar supports N1D8. 9sing Othernet.begin(mac) with the proper network
setup, the Othernet shield will automaticall obtain an 28 address. :his increases the sketch si?e
significantl.
Syntax' Othernet.begin(mac);
Othernet.begin(mac, ip);
Othernet.begin(mac, ip, dns);
Othernet.begin(mac, ip, dns, gatewa);
Othernet.begin(mac, ip, dns, gatewa, subnet);
%arameters' mac' the @AD (@edia access control) address for the device (arra of H btes). this
is the Othernet hardware address of our shield. 7ewer Arduino Othernet =hields
include a sticker with the deviceRs @AD address. Por older shields, choose our own.
BH
ip' the 28 address of the device (arra of F btes)
dns' the address for a N7= server.
)ateway' the 28 address of the network gatewa (arra of F btes). optional: defaults
to the device 28 address with the last octet set to +
subnet' the subnet mask of the network (arra of F btes). optional: defaults to
<JJ.<JJ.<JJ.G
&eturns' :he N1D8 version of this function, Othernet.begin(mac), returns an int: + on a
successful N1D8 connection, G on failure. :he other versions donRt return anthing.
+xample
$include XOthernet.hY
!! the media access control (ethernet hardware) address for the shield:
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
!!the 28 address for the shield:
bte ipUV % { +G, G, G, +MM };
void setup()
{
Othernet.begin(mac, ip);
}
void loop () {}
+thernetClient#$
Dreates a client which can connect to a specified internet 28 address and port (defined in the
client.connect() function).
Syntax' OthernetDlient()
%arameters' 7one
+xample
$include XOthernet.hY
$include X=82.hY
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
bte ipUV % { +G, G, G, +MM };
bte serverUV % { HF, <BB, +IM, KK }; !! 3oogle
OthernetDlient client;
void setup()
{
Othernet.begin(mac, ip);
=erial.begin(KHGG);
dela(+GGG);
=erial.println(Tconnecting...T);
BM
if (client.connect(server, IG)) {
=erial.println(TconnectedT);
client.println(T3O: !searchZ)%arduino 1::8!+.GT);
client.println();
} else {
=erial.println(Tconnection failedT);
}
}
void loop()
{
if (client.available()) {
char c % client.read();
=erial.print(c);
}
if (*client.connected()) {
=erial.println();
=erial.println(Tdisconnecting.T);
client.stop();
for(;;)
;
}
}
$thernet

clientCavailable#$
Aeturns the number of btes available for reading (that is, the amount of data that has been written
to the client b the server it is connected to). available() inherits from the =tream utilit class.
Syntax' client.available()
%arameters' none
&eturns' :he number of btes available.
+xample
$include XOthernet.hY
$include X=82.hY
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
bte ipUV % { +G, G, G, +MM };
bte serverUV % { HF, <BB, +IM, KK }; !! 3oogle
OthernetDlient client;
void setup()
{
Othernet.begin(mac, ip);
=erial.begin(KHGG);
BI
dela(+GGG);
=erial.println(Tconnecting...T);
if (client.connect(server, IG)) {
=erial.println(TconnectedT);
client.println(T3O: !searchZ)%arduino 1::8!+.GT);
client.println();
} else {
=erial.println(Tconnection failedT);
}
}
void loop()
{
if (client.available()) {
char c % client.read();
=erial.print(c);
}
if (*client.connected()) {
=erial.println();
=erial.println(Tdisconnecting.T);
client.stop();
for(;;)
;
}
$thernet

clientCconnected#$
6hether or not the client is connected. 7ote that a client is considered connected if the connection
has been closed but there is still unread data.
Syntax' client.connected()
%arameters' none
&eturns' Aeturns true if the client is connected, false if not.
+xample
$include XOthernet.hY
$include X=82.hY
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
bte ipUV % { +G, G, G, +MM };
bte serverUV % { HF, <BB, +IM, KK }; !! 3oogle
OthernetDlient client;
void setup()
{
BK
Othernet.begin(mac, ip);
=erial.begin(KHGG);
dela(+GGG);
=erial.println(Tconnecting...T);
if (client.connect(server, IG)) {
=erial.println(TconnectedT);
client.println(T3O: !searchZ)%arduino 1::8!+.GT);
client.println();
} else {
=erial.println(Tconnection failedT);
}
}
void loop()
{
if (client.available()) {
char c % client.read();
=erial.print(c);
}
if (*client.connected()) {
=erial.println();
=erial.println(Tdisconnecting.T);
client.stop();
for(;;)
;
$thernet
clientCconnect#$
Donnect to the 28 address and port specified in the constructor. :he return value indicates success or
failure.
Syntax' client.connect()
%arameters' none
&eturns' Aeturns true if the connection succeeds, false if not.
+xample
$include XOthernet.hY
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
bte ipUV % { +G, G, G, +MM };
bte serverUV % { HF, <BB, +IM, KK }; !! 3oogle
Dlient client(server, IG);
void setup()
{
FG
Othernet.begin(mac, ip);
=erial.begin(KHGG);
dela(+GGG);
=erial.println(Tconnecting...T);
if (client.connect()) {
=erial.println(TconnectedT);
client.println(T3O: !searchZ)%arduino 1::8!+.GT);
client.println();
} else {
=erial.println(Tconnection failedT);
}
}
void loop()
{
if (client.available()) {
char c % client.read();
=erial.print(c);
}
if (*client.connected()) {
=erial.println();
=erial.println(Tdisconnecting.T);
client.stop();
for(;;)
;
}
}
$thernet

Client#$
Dreates a client which can connect to the specified internet 28 address and port.
Syntax' Dlient(ip, port)
%arameters' ip: the 28 address that the client will connect to (arra of F btes)
port: the port that the client will connect to (int)
+xample
$include XOthernet.hY
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
bte ipUV % { +G, G, G, +MM };
bte serverUV % { HF, <BB, +IM, KK }; !! 3oogle
Dlient client(server, IG);
void setup()
{
F+
Othernet.begin(mac, ip);
=erial.begin(KHGG);
dela(+GGG);
=erial.println(Tconnecting...T);
if (client.connect()) {
=erial.println(TconnectedT);
client.println(T3O: !searchZ)%arduino 1::8!+.GT);
client.println();
} else {
=erial.println(Tconnection failedT);
}
}
void loop()
{
if (client.available()) {
char c % client.read();
=erial.print(c);
}
if (*client.connected()) {
=erial.println();
=erial.println(Tdisconnecting.T);
client.stop();
for(;;)
;
}
}
$thernet

clientC!lush#$
Niscard an btes that have been written to the client but not et read. flush() inherits from the
=tream utilit class.
Syntax' client.flush()
%arameters' none
&eturns' none
$thernet

clientCprint#$
8rint data to the server that a client is connected to. 8rints numbers as a se)uence of digits, each an
A=D22 character (e.g. the number +<B is sent as the three characters R+R, R<R, RBR).
F<
Syntax' client.print(data)
client.print(data, CA=O)
%arameters' data: the data to print (char, bte, int, long, or string)
CA=O (optional): the base in which to print numbers: NOD for decimal (base +G),
5D: for octal (base I), 1OQ for he.adecimal (base +H).
&eturns' bte: returns the number of btes written, though reading that number is optional
$thernet

clientCprintln#$
8rint data, followed b a carriage return and newline, to the server a client is connected to. 8rints
numbers as a se)uence of digits, each an A=D22 character (e.g. the number +<B is sent as the three
characters R+R, R<R, RBR).
Syntax client.println()
client.println(data)
client.print(data, CA=O)
%arameters data (optional): the data to print (char, bte, int, long, or string)
CA=O (optional): the base in which to print numbers: C27 for binar (base <), NOD
for decimal (base +G), 5D: for octal (base I), 1OQ for he.adecimal (base +H).
$thernet

clientCread#$
Aead the ne.t bte received from the server the client is connected to (after the last call to read()).
read() inherits from the =tream utilit class.
Syntax' client.read()
%arameters' none
&eturns' :he ne.t bte (or character), or #+ if none is available.
$thernet

clientCstop#$
Nisconnect from the server.
Syntax' client.stop()
%arameters' none
&eturns' none
FB
$thernet

clientCwrite#$
6rite data to the server the client is connected to.
Syntax' client.write(data)
%arameters' data: the bte or char to write
$thernet
1%Address#$
Nefines an 28 address. 2t can be used to declare both local and remote addresses.
Syntax' 28Address(address);
%arameters' address: a comma delimited list representing the address (F btes, e.. +K<, +HI, +, +)
&eturns' 7one
+xample
$include XOthernet.hY
!! network configuration. gatewa and subnet are optional.
!! the media access control (ethernet hardware) address for the shield:
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
!! the routerRs gatewa address:
bte gatewaUV % { +G, G, G, + };
!! the subnet:
bte subnetUV % { <JJ, <JJ, G, G };
Othernet=erver server % Othernet=erver(<B);
!!the 28 address is dependent on our network
28Address ip(+K<,+HI,+,+);
void setup()
{
!! initiali?e the ethernet device
Othernet.begin(mac, ip, gatewa, subnet);
!! start listening for clients
server.begin();
}
void loop()
{
!!print out the 28 address
FF
=erial.println(m28address);
}
$thernet
+thernetClocal1%#$
5btains the 28 address of the Othernet shield. 9seful when the address is auto assigned through
N1D8.
Syntax: Othernet.local28();
%arameters' none
&eturns' the 28 address
+xample
$include X=82.hY
$include XOthernet.hY
!! Onter a @AD address for our controller below.
!! 7ewer Othernet shields have a @AD address printed on a sticker on the shield
bte macUV % {G.GG, G.AA, G.CC, G.DD, G.NO, G.G< };
!! 2nitiali?e the Othernet client librar
!! with the 28 address and port of the server
!! that ou want to connect to (port IG is default for 1::8):
OthernetDlient client;
void setup() {
!! start the serial librar:
=erial.begin(KHGG);
!! start the Othernet connection:
if (Othernet.begin(mac) %% G) {
=erial.println(TPailed to configure Othernet using N1D8T);
!! no point in carring on, so do nothing forevermore:
for(;;)
;
}
!! print our local 28 address:
=erial.println(Othernet.local28());
}
void loop() {
!!
}
FJ
$thernet
+thernetCmaintain#$
Allows for the renewal of N1D8 leases. 6hen assigned an 28 address via N1D8, ethernet devices
are given a lease on the address for an amount of time. 6ith Othernet.maintain(), it is possible to
re)uest a renewal from the N1D8 server. Nepending on the serverRs configuration, ou ma receive
the same address, a new one, or none at all.
Othernet.maintain() was added to Arduino +.G.+.
Syntax' Othernet.maintain();
%arameters' none
&eturns bte:
G: nothing happened
+: renew failed
<: renew success
B: rebind fail
F: rebind success
+thernet ' +thernetServer
+thernetServer#$
Dreate a server that listens for incoming connections on the specified port.
Syntax' =erver(port);
%arameters' port: the port to listen on (int)
&eturns' 7one
+xample
$include X=82.hY
$include XOthernet.hY
!! network configuration. gatewa and subnet are optional.
!! the media access control (ethernet hardware) address for the shield:
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
!!the 28 address for the shield:
bte ipUV % { +G, G, G, +MM };
!! the routerRs gatewa address:
bte gatewaUV % { +G, G, G, + };
!! the subnet:
bte subnetUV % { <JJ, <JJ, G, G };
!! telnet defaults to port <B
FH
Othernet=erver server % Othernet=erver(<B);
void setup()
{
!! initiali?e the ethernet device
Othernet.begin(mac, ip, gatewa, subnet);
!! start listening for clients
server.begin();
}
void loop()
{
!! if an incoming client connects, there will be btes available to read:
OthernetDlient client % server.available();
if (client %% true) {
!! read btes from the incoming client and write them back
!! to an clients connected to the server:
server.write(client.read());
$thernet

"D%Cavailable#$
3et the number of btes (characters) available for reading from the buffer. :his is data thatRs alread
arrived.
:his function can onl be successfull called after 9N8.parse8acket(). available() inherits from the
=tream utilit class.
Syntax' 9N8.available()
%arameters' 7one
&eturns' the number of btes available to read
+xample
$include X=82.hY
$include XOthernet.hY
$include XOthernet9dp.hY
!! Onter a @AD address and 28 address for our controller below.
!! :he 28 address will be dependent on our local network:
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
28Address ip(+K<, +HI, +, +MM);
unsigned int local8ort % IIII; !! local port to listen on
!! An Othernet9N8 instance to let us send and receive packets over 9N8
Othernet9N8 9dp;
FM
char packetCufferU9N8;:Q;8ADEO:;@AQ;=2[OV; !!buffer to hold incoming packet,
void setup() {
!! start the Othernet and 9N8:
Othernet.begin(mac,ip);
9dp.begin(local8ort);
}
void loop() {
int packet=i?e % 9dp.parse8acket();
if(9dp.available())
{
=erial.print(TAeceived packet of si?e T);
=erial.println(packet=i?e);
=erial.print(TProm T);
28Address remote % 9dp.remote28();
for (int i %G; i X F; i&&)
{
=erial.print(remoteUiV, NOD);
if (i X B)
{
=erial.print(T.T);
}
}
=erial.print(T, port T);
=erial.println(9dp.remote8ort());
!! read the packet into packetCufffer
9dp.read(packetCuffer,9N8;:Q;8ADEO:;@AQ;=2[O);
=erial.println(TDontents:T);
=erial.println(packetCuffer);
$thernet

"D%Cbe)in#$
2nitiali?es the ethernet 9N8 librar and network settings.
Syntax' Othernet9N8.begin(local8ort);
%arameters' local8ort: the local port to listen on (int)
&eturns' 7one
+xample

$include X=82.hY
$include XOthernet.hY
$include XOthernet9dp.hY
FI
!! Onter a @AD address and 28 address for our controller below.
!! :he 28 address will be dependent on our local network:
bte macUV % {G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
28Address ip(+K<, +HI, +, +MM);
unsigned int local8ort % IIII; !! local port to listen on
!! An Othernet9N8 instance to let us send and receive packets over 9N8
Othernet9N8 9dp;
void setup() {
!! start the Othernet and 9N8:
Othernet.begin(mac,ip);
9dp.begin(local8ort);
}
void loop() {
}
$thernet

"D%Cbe)in%ac<et#$
=tarts a connection to write 9N8 data to the remote connection
Syntax' 9N8.begin8acket(remote28, remote8ort);
%arameters' remote28: the 28 address of the remote connection (F btes)
remote8ort: the port of the remote connection (int)
&eturns' 7one
+xample
$include X=82.hY
$include XOthernet.hY
$include XOthernet9dp.hY
!! Onter a @AD address and 28 address for our controller below.
!! :he 28 address will be dependent on our local network:
bte macUV % {G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
28Address ip(+K<, +HI, +, +MM);
unsigned int local8ort % IIII; !! local port to listen on
!! An Othernet9N8 instance to let us send and receive packets over 9N8
Othernet9N8 9dp;
void setup() {
!! start the Othernet and 9N8:
Othernet.begin(mac,ip);
FK
9dp.begin(local8ort);
}
void loop() {
9dp.begin8acket(9dp.remote28(), 9dp.remote8ort());
9dp.write(ThelloT);
9dp.end8acket();
}
$thernet
"D%Cend%ac<et#$
Dalled after writing 9N8 data to the remote connection.
Syntax' 9N8.end8acket();
%arameters' 7one
&eturns' 7one
+xample
$include X=82.hY
$include XOthernet.hY
$include XOthernet9dp.hY
!! Onter a @AD address and 28 address for our controller below.
!! :he 28 address will be dependent on our local network:
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
28Address ip(+K<, +HI, +, +MM);
unsigned int local8ort % IIII; !! local port to listen on
!! An Othernet9N8 instance to let us send and receive packets over 9N8
Othernet9N8 9dp;
void setup() {
!! start the Othernet and 9N8:
Othernet.begin(mac,ip);
9dp.begin(local8ort);
}
void loop() {
9dp.begin8acket(9dp.remote28(), 9dp.remote8ort());
9dp.write(ThelloT);
9dp.end8acket();
}
JG
$thernet

"D%Cparse%ac<et#$
Dhecks for the presence of a 9N8 packet, and reports the si?e. parse8acket() must be called before
reading the buffer with 9N8.read().
Syntax' 9N8.parse8acket();
%arameters' 7one
&eturns' int: the si?e of a received 9N8 packet
+xample
$include X=82.hY !! needed for Arduino versions later than GG+I
$include XOthernet.hY
$include XOthernet9dp.hY !! 9N8 librar from: b>oern]cs.stanford.edu +<!BG!<GGI
!! Onter a @AD address and 28 address for our controller below.
!! :he 28 address will be dependent on our local network:
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
28Address ip(+K<, +HI, +, +MM);
unsigned int local8ort % IIII; !! local port to listen on
!! An Othernet9N8 instance to let us send and receive packets over 9N8
Othernet9N8 9dp;
void setup() {
!! start the Othernet and 9N8:
Othernet.begin(mac,ip);
9dp.begin(local8ort);
=erial.begin(KHGG);
}
void loop() {
!! if thereRs data available, read a packet
int packet=i?e % 9dp.parse8acket();
if(packet=i?e)
{
=erial.print(TAeceived packet of si?e T);
=erial.println(packet=i?e);
}
dela(+G);
J+
$thernet
"D%Cread#$
Aeads 9N8 data from the specified buffer. 2f no arguments are given, it will return the ne.t
character in the buffer.
:his function can onl be successfull called after 9N8.parse8acket().
Syntax' 9N8.read();
9N8.read(packetCuffer, @a.=i?e);
%arameters' packetCuffer: buffer to hold incoming packets (char)
@a.=i?e: ma.imum si?e of the buffer (int)
&eturns' char : returns the characters in the buffer
+xample
$include X=82.hY
$include XOthernet.hY
$include XOthernet9dp.hY
!! Onter a @AD address and 28 address for our controller below.
!! :he 28 address will be dependent on our local network:
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
28Address ip(+K<, +HI, +, +MM);
unsigned int local8ort % IIII; !! local port to listen on
!! An Othernet9N8 instance to let us send and receive packets over 9N8
Othernet9N8 9dp;
char packetCufferU9N8;:Q;8ADEO:;@AQ;=2[OV; !!buffer to hold incoming packet,
void setup() {
!! start the Othernet and 9N8:
Othernet.begin(mac,ip);
9dp.begin(local8ort);
}
void loop() {
int packet=i?e % 9dp.parse8acket();
if(packet=i?e)
{
=erial.print(TAeceived packet of si?e T);
=erial.println(packet=i?e);
=erial.print(TProm T);
28Address remote % 9dp.remote28();
for (int i %G; i X F; i&&)
{
=erial.print(remoteUiV, NOD);
if (i X B)
{
J<
=erial.print(T.T);
}
}
=erial.print(T, port T);
=erial.println(9dp.remote8ort());
!! read the packet into packetCufffer
9dp.read(packetCuffer,9N8;:Q;8ADEO:;@AQ;=2[O);
=erial.println(TDontents:T);
=erial.println(packetCuffer);
}
}
$thernet

"D%Cremote1%#$
3ets the 28 address of the remote connection.
This function must be called after %D&'!arse&ac(et)*'
Syntax' 9N8.remote28();
%arameters' 7one
&eturns' F btes : the 28 address of the remote connection
+xample
$include X=82.hY
$include XOthernet.hY
$include XOthernet9dp.hY
!! Onter a @AD address and 28 address for our controller below.
!! :he 28 address will be dependent on our local network:
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
28Address ip(+K<, +HI, +, +MM);
unsigned int local8ort % IIII; !! local port to listen on
!! An Othernet9N8 instance to let us send and receive packets over 9N8
Othernet9N8 9dp;
void setup() {
!! start the Othernet and 9N8:
Othernet.begin(mac,ip);
9dp.begin(local8ort);
}
void loop() {
int packet=i?e % 9dp.parse8acket();
if(packet=i?e)
JB
{
=erial.print(TAeceived packet of si?e T);
=erial.println(packet=i?e);
=erial.print(TProm 28 : T);
28Address remote % 9dp.remote28();
!!print out the remote connectionRs 28 address
=erial.print(remote);
=erial.print(T on port : T);
!!print out the remote connectionRs port
=erial.println(9dp.remote8ort());
}
}
$thernet
"D%Cremote%ort#$
3ets the port of the remote 9N8 connection.
This function must be called after %D&'!arse&ac(et)*'
Syntax' 9N8.remote8ort();
%arameters' 7one
&eturns' int : the port of the 9N8 connection to a remote host
+xample
$include X=82.hY
$include XOthernet.hY
$include XOthernet9dp.hY
!! Onter a @AD address and 28 address for our controller below.
!! :he 28 address will be dependent on our local network:
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
28Address ip(+K<, +HI, +, +MM);
unsigned int local8ort % IIII; !! local port to listen on
!! An Othernet9N8 instance to let us send and receive packets over 9N8
Othernet9N8 9dp;
char packetCufferU9N8;:Q;8ADEO:;@AQ;=2[OV; !!buffer to hold incoming packet,
void setup() {
!! start the Othernet and 9N8:
Othernet.begin(mac,ip);
9dp.begin(local8ort);
}
void loop() {
int packet=i?e % 9dp.parse8acket();
JF
if(packet=i?e)
{
=erial.print(TAeceived packet of si?e T);
=erial.println(packet=i?e);
=erial.print(TProm T);
28Address remote % 9dp.remote28();
for (int i %G; i X F; i&&)
{
=erial.print(remoteUiV, NOD);
if (i X B)
{
=erial.print(T.T);
}
}
=erial.print(T, port T);
=erial.println(9dp.remote8ort());
!! read the packet into packetCufffer
9dp.read(packetCuffer,9N8;:Q;8ADEO:;@AQ;=2[O);
=erial.println(TDontents:T);
=erial.println(packetCuffer);
}
}
$thernet
"D%Cwrite#$
6rites 9N8 data to the remote connection. @ust be wrapped between begin8acket() and
end8acket(). begin8acket() initiali?es the packet of data, it is not sent until end8acket() is called.
Syntax' 9N8.write(message);
%arameters' message: the outgoing message (char)
&eturns' bte : returns the number of characters sent. :his does not have to be read
+xample
$include X=82.hY
$include XOthernet.hY
$include XOthernet9dp.hY
!! Onter a @AD address and 28 address for our controller below.
!! :he 28 address will be dependent on our local network:
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
28Address ip(+K<, +HI, +, +MM);
unsigned int local8ort % IIII; !! local port to listen on
!! An Othernet9N8 instance to let us send and receive packets over 9N8
Othernet9N8 9dp;
JJ
void setup() {
!! start the Othernet and 9N8:
Othernet.begin(mac,ip);
9dp.begin(local8ort);
}
void loop() {
9dp.begin8acket(9dp.remote28(), 9dp.remote8ort());
9dp.write(ThelloT);
9dp.end8acket();
}
$thernet
i! #+thernetClient$
2ndicates if the specified Othernet client is read.
Syntax' if (client)
%arameters' none
&eturns' boolean : returns true if the specified client is available.
+xample
$include XOthernet.hY
$include X=82.hY
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
bte ipUV % { +G, G, G, +MM };
bte serverUV % { HF, <BB, +IM, KK }; !! 3oogle
OthernetDlient client;
void setup()
{
Othernet.begin(mac, ip);
=erial.begin(KHGG);
dela(+GGG);
=erial.println(Tconnecting...T);
while(*client){
; !! wait until there is a client connected to proceed
}
if (client.connect(server, IG)) {
=erial.println(TconnectedT);
client.println(T3O: !searchZ)%arduino 1::8!+.GT);
client.println();
} else {
=erial.println(Tconnection failedT);
}
}
JH
void loop()
{
if (client.available()) {
char c % client.read();
=erial.print(c);
}
if (*client.connected()) {
=erial.println();
=erial.println(Tdisconnecting.T);
client.stop();
for(;;)
;
}
}
$thernet #erver class
serverCavailable#$
3ets a client that is connected to the server and has data available for reading. :he connection
persists when the returned client ob>ect goes out of scope; ou can close it b calling client.stop().
available() inherits from the =tream utilit class.
Syntax' server.available()
%arameters' 7one
&eturns' a Dlient ob>ect; if no Dlient has data available for reading, this ob>ect will evaluate to
false in an if#statement (see the e.ample below)
+xample
$include XOthernet.hY
$include X=82.hY
!! the media access control (ethernet hardware) address for the shield:
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
!!the 28 address for the shield:
bte ipUV % { +G, G, G, +MM };
!! the routerRs gatewa address:
bte gatewaUV % { +G, G, G, + };
!! the subnet:
bte subnetUV % { <JJ, <JJ, G, G };
!! telnet defaults to port <B
Othernet=erver server % Othernet=erver(<B);
void setup()
{
!! initiali?e the ethernet device
Othernet.begin(mac, ip, gatewa, subnet);
JM
!! start listening for clients
server.begin();
}
void loop()
{
!! if an incoming client connects, there will be btes available to read:
OthernetDlient client % server.available();
if (client %% true) {
!! read btes from the incoming client and write them back
!! to an clients connected to the server:
server.write(client.read());
}
}
$thernet + #erver class
serverCbe)in#$
:ells the server to begin listening for incoming connections.
Syntax' server.begin()
%arameters' 7one
&eturns' 7one
+xample
$include X=82.hY
$include XOthernet.hY
!! the media access control (ethernet hardware) address for the shield:
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
!!the 28 address for the shield:
bte ipUV % { +G, G, G, +MM };
!! the routerRs gatewa address:
bte gatewaUV % { +G, G, G, + };
!! the subnet:
bte subnetUV % { <JJ, <JJ, G, G };
!! telnet defaults to port <B
Othernet=erver server % Othernet=erver(<B);
void setup()
{
!! initiali?e the ethernet device
Othernet.begin(mac, ip, gatewa, subnet);
!! start listening for clients
server.begin();
JI
}
void loop()
{
!! if an incoming client connects, there will be btes available to read:
OthernetDlient client % server.available();
if (client %% true) {
!! read btes from the incoming client and write them back
!! to an clients connected to the server:
server.write(client.read());
}
}
$thernet + #erver class
Server#$
Dreate a server that listens for incoming connections on the specified port.
Syntax' =erver(port);
%arameters' port: the port to listen on (int)
&eturns' 7one
+xample
$include XOthernet.hY
!! network configuration. gatewa and subnet are optional.
!! the media access control (ethernet hardware) address for the shield:
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
!!the 28 address for the shield:
bte ipUV % { +G, G, G, +MM };
!! the routerRs gatewa address:
bte gatewaUV % { +G, G, G, + };
!! the subnet:
bte subnetUV % { <JJ, <JJ, G, G };
!! telnet defaults to port <B
=erver server % =erver(<B);
void setup()
{
!! initiali?e the ethernet device
Othernet.begin(mac, ip, gatewa, subnet);
!! start listening for clients
server.begin();
}
JK
void loop()
{
!! if an incoming client connects, there will be btes available to read:
Dlient client % server.available();
if (client %% true) {
!! read btes from the incoming client and write them back
!! to an clients connected to the server:
server.write(client.read());
}
}
$thernet + #erver class
serverCprint#$
8rint data to all the clients connected to a server. 8rints numbers as a se)uence of digits, each an
A=D22 character (e.g. the number +<B is sent as the three characters R+R, R<R, RBR).
Syntax' server.print(data)
server.print(data, CA=O)
%arameters' data: the data to print (char, bte, int, long, or string)
CA=O (optional): the base in which to print numbers: C27 for binar (base <), NOD
for decimal (base +G), 5D: for octal (base I), 1OQ for he.adecimal (base +H).
&eturns' bte
print() will return the number of btes written, though reading that number is
optional
$thernet + #erver class
serverCprintln#$
8rint data, followed b a newline, to all the clients connected to a server. 8rints numbers as a
se)uence of digits, each an A=D22 character (e.g. the number +<B is sent as the three characters R+R,
R<R, RBR).
Syntax' server.println()
server.println(data)
server.println(data, CA=O)
%arameters' data (optional): the data to print (char, bte, int, long, or string)
CA=O (optional): the base in which to print numbers: C27 for binar (base <), NOD
for decimal (base +G), 5D: for octal (base I), 1OQ for he.adecimal (base +H).
$thernet + #erver class
HG
serverCwrite#$
6rite data to all the clients connected to a server.
Syntax' server.write(data)
%arameters' data: the value to write (bte or char)
&eturns' 7one
+xample
$include XOthernet.hY
!! network configuration. gatewa and subnet are optional.
!! the media access control (ethernet hardware) address for the shield:
bte macUV % { G.NO, G.AN, G.CO, G.OP, G.PO, G.ON };
!!the 28 address for the shield:
bte ipUV % { +G, G, G, +MM };
!! the routerRs gatewa address:
bte gatewaUV % { +G, G, G, + };
!! the subnet:
bte subnetUV % { <JJ, <JJ, G, G };
!! telnet defaults to port <B
=erver server % =erver(<B);
void setup()
{
!! initiali?e the ethernet device
Othernet.begin(mac, ip, gatewa, subnet);
!! start listening for clients
server.begin();
}
void loop()
{
!! if an incoming client connects, there will be btes available to read:
Dlient client % server.available();
if (client %% true) {
!! read btes from the incoming client and write them back
!! to an clients connected to the server:
server.write(client.read());
}
}
H+
Firmata .ibrary
:he Pirmata librar implements the Pirmata protocol for communicating with software on the host
computer. :his allows ou to write custom firmware without having to create our own protocol
and ob>ects for the programming environment that ou are using.
-ethods
be)in#$
start the librar
be)in#lon)$
start the librar and override the default baud rate
printVersion#$
send the protocol version to the host computer
blin<Version#$
blink the protocol version on pin +B
printFirmwareVersion#$
send the firmware name and version to the host computer
setFirmwareVersion#byte maDor, byte minor$
set the firmware name and version, using the sketchRs filename, minus the .pde
Sendin) -essa)es
sendAnalo)#byte pin, int value$
send an analog message
sendDi)ital%orts#byte pin, byte !irst%ort, byte second%ort$
send digital ports as individual btes
sendDi)ital%ort%air#byte pin, int value$
send digital ports as one int
sendSysex#byte command, byte bytec, byteE bytev$
send a command with an arbitrar arra of btes
sendStrin)#const charE strin)$
send a string to the host computer
sendStrin)#byte command, const charE strin)$
send a string to the host computer using a custom command tpe
&eceivin) -essa)es
available#$
check to see if there are an incoming messages in the buffer
H<
process1nput#$
process incoming messages from the buffer, sending the data to an registered callback functions
attach#byte command, callbac<Function myFunction$
attach a function to an incoming message tpe
detach#byte command$
detach a function from an incoming message tpe
Callbac< Functions
2n order to attach our function to a message tpe, our function must match the standard callback
function. :here are currentl three tpes of callback functions in Pirmata: generic, string, and
sse..
)eneric
void callbackPunction(bte pin, int value);
system?reset
void sstemAesetDallbackPunction(void);
strin)
void stringDallbackPunction(char "m=tring);
sysex
void sse.DallbackPunction(bte pin, bte bteDount, bte "arra8ointer);
-essa)e Types
:hese are the various message tpes that ou can attach functions to.
A*A.O>?-+SSA>+
the analog value for a single pin
D1>1TA.?-+SSA>+
I#bits of digital pin data (one port)
&+%O&T?A*A.O>
enable!disable the reporting of analog pin
&+%O&T?D1>1TA.
enable!disable the reporting of a digital port
S+T?%1*?-OD+
change the pin mode between 2789:!59:89:!86@!etc.
F1&-ATA?ST&1*>
D#stle strings, uses stringDallbackPunction for the function tpe
SFS+5?STA&T
generic, arbitrar length messages (via @2N2 =sO. protocol), uses sse.DallbackPunction for the
function tpe
HB
SFST+-?&+S+T
message to reset firmware to its default state, uses sstemAesetDallbackPunction for the function
tpe
+xample
:his e.ample shows how to send and receive analog messages using Pirmata.
$include XPirmata.hY
bte analog8in;
void analog6riteDallback(bte pin, int value)
{
pin@ode(pin,59:89:);
analog6rite(pin, value);
}
void setup()
{
Pirmata.setPirmwareLersion(G, +);
Pirmata.attach(A7A453;@O==A3O, analog6riteDallback);
Pirmata.begin();
}
void loop()
{
while(Pirmata.available()) {
Pirmata.process2nput();
}
for(analog8in % G; analog8in X :5:A4;A7A453;827=; analog8in&&) {
Pirmata.sendAnalog(analog8in, analogAead(analog8in));
}
}
!loat#$
Donverts a value to the float data tpe.
Syntax' float(.)
%arameters' .: a value of an tpe
&eturns' float
*otes' =ee the reference for float for details about the precision and limitations of floating
point numbers on Arduino.
HF
!loat
Natatpe for floating#point numbers, a number that has a decimal point. Ploating#point numbers are
often used to appro.imate analog and continuous values because the have greater resolution than
integers. Ploating#point numbers can be as large as B.FG<I<BJO&BI and as low as #B.FG<I<BJO&BI.
:he are stored as B< bits (F btes) of information.
Ploats have onl H#M decimal digits of precision. :hat means the total number of digits, not the
number to the right of the decimal point. 9nlike other platforms, where ou can get more precision
b using a double (e.g. up to +J digits), on the Arduino, double is the same si?e as float.
Ploating point numbers are not e.act, and ma ield strange results when compared. Por e.ample
H.G ! B.G ma not e)ual <.G. Sou should instead check that the absolute value of the difference
between the numbers is less than some small number.
Ploating point math is also much slower than integer math in performing calculations, so should be
avoided if, for e.ample, a loop has to run at top speed for a critical timing function. 8rogrammers
often go to some lengths to convert floating point calculations to integer math to increase speed.
+xamples
float mfloat;
float sensorDalbrate % +.++M;
Syntax' float var % val;
" var # our float variable name
" val # the value ou assign to that variable
+xample Code
int .;
int ;
float ?;
. % +;
% . ! <; !! now contains G, ints canRt hold fractions
? % (float). ! <.G; !! ? now contains .J (ou have to use <.G, not <)
!or statements
:he for statement is used to repeat a block of statements enclosed in curl braces. An increment
counter is usuall used to increment and terminate the loop. :he for statement is useful for an
repetitive operation, and is often used in combination with arras to operate on collections of
data!pins.
There are three parts to the !or loop header'
for (initiali?ation; condition; increment) {
!!statement(s);
}
HJ
:he initiali?ation happens first and e.actl once. Oach time through the loop, the condition is tested;
if itRs true, the statement block, and the increment is e.ecuted, then the condition is tested again.
6hen the condition becomes false, the loop ends.
+xample
!! Nim an 4ON using a 86@ pin
int 86@pin % +G; !! 4ON in series with FMG ohm resistor on pin +G
void setup()
{
!! no setup needed
}
void loop()
{
for (int i%G; i X% <JJ; i&&){
analog6rite(86@pin, i);
dela(+G);
}
}
"oding Ti!s
:he D for loop is much more fle.ible than for loops found in some other computer languages,
including CA=2D. An or all of the three header elements ma be omitted, although the semicolons
are re)uired. Also the statements for initiali?ation, condition, and increment can be an valid D
statements with unrelated variables, and use an D datatpes including floats. :hese tpes of
unusual for statements ma provide solutions to some rare programming problems.
Por e.ample, using a multiplication in the increment line will generate a logarithmic progression:
for(int . % <; . X +GG; . % . " +.J){
println(.);
}
3enerates: <,B,F,H,K,+B,+K,<I,F<,HB,KF
Another e.ample, fade an 4ON up and down with one for loop:
void loop()
{
int . % +;
for (int i % G; i Y #+; i % i & .){
analog6rite(86@pin, i);
if (i %% <JJ) . % #+; !! switch direction at peak
dela(+G);
}
}
!loatin) point constants
HH
=imilar to integer constants, floating point constants are used to make code more readable. Ploating
point constants are swapped at compile time for the value to which the e.pression evaluates.
+xamples'
n % .GGJ;
Ploating point constants can also be e.pressed in a variet of scientific notation. ROR and ReR are both
accepted as valid e.ponent indicators.
floating#point constant evaluates to: also evaluates to:
+G.G +G
<.BFOJ <.BF " +G-J <BFGGG
HMe#+< HM.G " +G-#+< .GGGGGGGGGGHM
Functions
=egmenting code into functions allows a programmer to create modular pieces of code that perform
a defined task and then return to the area of code from which the function was TcalledT. :he tpical
case for creating a function is when one needs to perform the same action multiple times in a
program.
Por programmers accustomed to using CA=2D, functions in Arduino provide (and e.tend) the utilit
of using subroutines (35=9C in CA=2D).
=tandardi?ing code fragments into functions has several advantages:
" Punctions help the programmer sta organi?ed. 5ften this helps to conceptuali?e the program.
" Punctions codif one action in one place so that the function onl has to be thought out and
debugged once.
" :his also reduces chances for errors in modification, if the code needs to be changed.
" Punctions make the whole sketch smaller and more compact because sections of code are reused
man times.
" :he make it easier to reuse code in other programs b making it more modular, and as a nice
side effect, using functions also often makes the code more readable.
:here are two re)uired functions in an Arduino sketch, setup() and loop(). 5ther functions must be
created outside the brackets of those two functions. As an e.ample, we will create a simple function
to multipl two numbers.
+xample
:o TcallT our simple multipl function, we pass it parameters of the datatpe that it is e.pecting:
void loop{
int i % <;
int > % B;
HM
int k;
k % m@ultiplPunction(i, >); !! k now contains H
}
5ur function needs to be declared outside an other function, so Tm@ultiplPunction()T can go
either above or below the Tloop()T function.
:he entire sketch would then look like this:
void setup(){
=erial.begin(KHGG);
}
void loop() {
int i % <;
int > % B;
int k;
k % m@ultiplPunction(i, >); !! k now contains H
=erial.println(k);
dela(JGG);
}
int m@ultiplPunction(int ., int ){
int result;
result % . " ;
return result;
}
Another example
:his function will read a sensor five times with analogAead() and calculate the average of five
readings. 2t then scales the data to I bits (G#<JJ), and inverts it, returning the inverted result.
int Aead=ens;and;Dondition(){
int i;
int sval % G;
for (i % G; i X J; i&&){
sval % sval & analogAead(G); !! sensor on analog pin G
}
sval % sval ! J; !! average
sval % sval ! F; !! scale to I bits (G # <JJ)
sval % <JJ # sval; !! invert output
return sval;
}
:o call our function we >ust assign it to a variable.
int sens;
sens % Aead=ens;and;Dondition();
HI
>.CD .ibrary
:he librar is based on the e.cellent ksG+GI graphics routines written and copright b Pabian
@a.imilian :hiele. :he site link in his code does not respond but ou can obtain a cop of his
original work in the download section at the end of this article.
:he code here has been converted to an Arduino librar, has more fle.ibilit in port addressing and
improvements in 2!5 speed. :he interface has been made more Arduino friendl and some
convenience functions added. :he method naming is mostl unchanged to facilitate porting of code
written for the original version. =ome methods now have default arguments to make them easer to
use.
:he test sketch included in the download demonstrates man of the capabilities of the librar and if
ou start with this and use the default Arduino pin assignments, it is a good wa to make sure that
everthing is working before ou customi?e our configuration. 1ere is a simplified version of the
e.ample sketch in the download:
>.CD example s<etch
$include XksG+GI.hY !! librar header
$include XArial+F.hY !! font definition for +F point Arial font.
$include T=stemPontJ.M.hT !! sstem font
$include TArduino2con.hT !! bitmap
unsigned long start@illis;
unsigned int iter % G;
void setup() {
34DN.2nit(757;27LOA:ON); !! initialise the librar
34DN.Dlear=creen();
34DN.NrawCitmap(Arduino2con, B<,G, C4ADE); !!draw the bitmap at the ., position
dela(BGGG);
34DN.Dlear=creen();
34DN.=electPont(=stemJ.M); !! select fi.ed width sstem font
}
void loop() { !! run over and over again
start@illis % millis();
while( millis() # start@illis X +GGG) { !! loop for one second
34DN.NrawAect(G, G, HF, H+, C4ADE); !! rectangle in left side of screen
34DN.NrawAoundAect(HI, G, JI, H+, J, C4ADE); !! rounded rectangle around te.t area
for(int i%G; i X H<; i &% F)
34DN.Nraw4ine(+,+,HB,i, C4ADE); !! draw lines from upper left down right side of rectangle
34DN.NrawDircle(B<,B+,BG,C4ADE); !! draw circle centered in the left side of screen
34DN.PillAect(K<,FG,+H,+H, 612:O); !! clear previous spinner position
34DN.Dursor:o(J,J); !! locate curser for printing te.t
34DN.8rint7umber(&&iter); !! print current iteration at the current cursor position
}
!! displa number of iterations in one second
34DN.Dlear=creen(); !! clear the screen
34DN.Dursor:o(+B,<); !! positon cursor
34DN.8uts(TP8=% T); !! print a te.t string
34DN.8rint7umber(iter); !! print a number
HK
}
}
>.CD Functions'
:his is a list of functions supported b the librar. (Aefer to the included 1:@4 librar
documentation for the latest and most complete documentation)
34DN.2nit(invert) initiali?e the librar for normal or inverted drawing. 2f
invert is false, drawing sets pi.els, if true pi.els are
cleared when drawn (see also =et2nverted method)
34DN.3otoQS(.,) locate the graphic cursor at positions . and , G,G is
upper left corner
34DN.Dlear=creen() clear the 4DN screen
!! 3raphic Nrawing Punctions (color 612:O clears pi.els, C4ADE sets pi.els)
34DN.NrawDircle(., , radius, color) draw circle with center at .,
34DN.Nraw4ine(.+,+,.<,<,color) draw line from .+,+ to .<,<
34DN.NrawLert4ine(., , length, color) draw vertical line
34DN.Nraw1ori4ine(., , length, color) draw hori?ontal line
34DN.NrawAect(., , width, height, color) draw rectangle
34DN.NrawAoundAect(., , width, height, radius, color) as above with rounded edges
34DN.PillAect(., , width, height, color) draw filled rectangle
34DN.2nvertAect(., , width, height) invert pi.els within given rectangle
34DN.=et2nverted(invert) set drawing mode to inverted
34DN.=etNot(., , color); draw a dot in the given color at the given location
34DN.NrawCitmap(bitmap, ., , color); draw the bitmap at the given ., position
!! Pont Punctions
34DN.=electPont(font, color ) select font, defaults color to black if not specified
34DN.8utDhar(character) print given character to screen at current cursor
location
34DN.8uts(string) print given string to screen at current cursor location
34DN.8uts;8(string) print string from program memor to screen at current
cursor location
34DN.8rint7umber(number) print the decimal value of the given number at current
cursor location
34DN.Dursor:o(., ); !! G based coordinates for fi.ed width fonts (i.e. the
supplied sstem font)
7ote: valid colors are C4ADE (sets pi.els) or 612:O (clears pi.els)
(irin) and Con!i)uration'
2n vB there are B tpes of configuration:
.ibrary

%anel
%in
MG
Oach tpe of configuration is handled b separate configuration files.
:he librar configuration is handled b glcd!glcd;Donfig.h :he librar configuration determines
things like panel tpe, as well as a few other options. 2t is the master configuration file.
:he panel configuration is used to configure things that are specific to a particular glcd panel like
the geometr of the displa, the chip select lines, and the low level timing for the panel. :he
glcd;Donfig.h librar configuration file specifies which panel configuration file to use.
:he pin configuration is used to assign pins. A given panel configuration will automaticall
determine which pin configuration file to use based on which board tpe is being used in the 2NO.
8in assignments are contained in the appropriate pin configuration header file in glcd!config for the
supported controller chips. :hese controller tpes are supported in the current version:
ksG+GI;arduino.h X# this is for A:mega+HI and A:megaB<I boards
ksG+GI;mega.h X# for the Arduino @ega (A:mega+<IG!<JHG)
ksG+GI;=anguino.h X# for =anguino (A:megaHFF)
ksG+GI;:eens.h X# for :eens!:eens&&
=ee the readme file, glcd!glcd;Donfig.h and included 1:@4 documentation supplied with the
download for more details on configuration.
2t is suggested that ou wire up the panel using the default pin assignments. :his diagram shows
how panels should be connected using the default pin assignments in the distributed librar.
Donnections for common 34DN panels:
34DN 8anel 8inouts
Arduino
GHI
-e)a Function
%inout
A
%inout
B
%inout
C
%inout
D
Comments
JL JL &J volts + *<* *<* F
3nd 3nd 37N < *+* *+* B
e.ternal e.ternal
Lo (Dontrast
in)
B B B J
Donnect to 6iper of
contrast pot (@iddle pin)
I << NG F M M K
K <B N+ J I I +G
+G <F N< H K K ++
++ <J NB M +G +G +<
F <H NF I ++ ++ +B
J <M NJ K +< +< +F
H <I NH +G +B +B +J
M <K NM ++ +F +F +H
+F (alogG) BB D=O4+ +< +J +H + Dhip + select
+J (alog+) BF D=O4< +B +H +J < Dhip < select
M+
Aeset Aeset +F +M +M
Donnect to reset pin (see
Aeset pin note below)
+H (alog<) BJ A;6 +J J J M Aead!write
+M (alogB) BH N;2 +H F F H Nata!2nstruction (aka A=)
+I (alogF) BM O7 +M H H I Onable
e.ternal e.ternal
Lee
(Dontrast out
)
+I +I +I
connect to one leg of +Gk
or <Gk pot
e.ternal e.ternal Cacklight &J +K +K +K
+GG to BBG ohm resistor to
&Jv
3nd 3nd
Cacklight
3nd
<G <G <G
3nd n!a n!a n!a n!a n!a n!a
connect other leg of
contrast pot to 3nd
Reset Function Note:
2f the 2NO fails to upload the Arduino when the glcd moduleRs reset line is attached to the Arduino
boardRs reset pin, see the troubleshooting guide below for remedies.
8inout A panels:
1N@HF3=+<4#F
Drstalfont? DPA3+<IHFC (tested b biomed)
=parkfun 4DN#GGM+GD@ (tested b biomed)
7ED Olectronics 4DN#GG<< (tested b 7ED Olectronics)
8inout C panels:
1N@HF3=+<4#J
4ume. 4D@#=+<IHF3=P (tested b >owan)
Puturlec C49O+<IQHF4DN (tested b tgger>ai)
A[ Nisplas A3@+<HFP (tested b sant)
Nisplatech HF+<IA CD (tested b 9do Elein)
Adafruit 34DN (4eave AO=O: pin disconnected or ou ma e.perience upload problems)
(tested b :hings)
NataLision N3+<IHF#II (tested b wglover)
:opwa 4@+<IHF4N6 (tested b ?andaa)
=atistronics A:+<IHFW#+ (tested b doublet)
Nigitron =3+<IHFWF (also appears to need AO=O: disconnected for uploads)
9nknown manufacturer ^S#+<IHFP (tested b =phi7.)
9nknown manufacturer :@+<IHF4#< (tested b frantorres)
9nknown manufacturer +<IHFW#+ (tested b pi.elk)
1uahong :echnolog 4td 4@3+<IHF (4@3#==D+<AHFNAS(#1) variant, ellow green
backlight, black on green) (tested b .skaft)
=ure Olectronics NO#4@+GJ (tested b imode)
6ide.hk T4DN =hield 8ro & 34DN +<I.HF 4DNT (tested b universam) H#wa Eepad
shortens D=+ (AG) to ground*
M<
8inout D panels:
=hen?hen Winghua Nisplas Do 4td. W@+<IHF (tested b macpod)
Lee (pin B) should be left disconnected. :he pot on the displa controls contrast
Cacklight 4ON ma alread have resistors added.
8inout N panels:
Larious +K< . HF displas:
Crand @odel Dhip Dontrast
6intek# Dascades 6N#3+KGH3 E=G+GIC #M.J to #+Gv
6intek # 3O7 6N#3+KGH3 E=G+GIC #M.J to #+Gv
6intek 6N#3+KGH3 =HCG+GIA #K.J to #+<v
:ODN2= S+KGH+ 1NH+<G< #M.J to #+Gv
Laritroni. @34=+K<HF 1NH+<G< #I.J to #+G.Jv
:he contrast voltage is negative with respect to ground.
Cacklight is F.Mv re)uiring +G#+< ohm resistor from &Jv.
:he ksG+GI;@anual;Donfig.h needs to be used and modified as below.
+. define N2=84AS;62N:1 +K<
<. define N2=84AS;1O231: HF
and
+. elif glcd;D128;D597: %% B
<. define glcd;D128G glcdD=O4+,456, glcdD=O4<,456
B. define glcd;D128+ glcdD=O4+,456, glcdD=O4<,1231
F. define glcd;D128< glcdD=O4+,1231, glcdD=O4<,456
(Sou are welcome to add other panels to the above lists that are tested and working with this
librar. Cut if ou add a new panel pinout tpe column to the table i.e. O, P, 3, etc... 84OA=O,
84OA=O add them to the end using the ne.t available letter and do not shift e.isting letters around.)
:his diagram shows wiring of the common tpe A panel. Dheck to see how our panel datasheet
matches the connector assignments before wiring up. :ake particular care that the &Jv and ground
connections are correct*
MB
(irin) up the external components'
@ost 34DN panels re)uire an e.ternal preset pot to set the 4DN working voltage (contrast) and a
fi.ed resistor to limit the current in the backlight. :he datasheet for our panel should provide
specific information on the wiring and choice of components. A suggestion for wiring these up is to
use a small piece of strip#board with header pins for JL, ground and Aeset providing connection to
the Arduino. =ee the diagram above for laout.
MF
Contrast %ot *OT+'
8la close attention for how to wire up the contrast pot. ksG+GI modules do not wire up their
contrast pot the same wa as a tpical hdFFMIG lcd. A hdFFMIG tpicall hooks its contrast pot legs
to &Jv and 37N. 5n a ksG+GI, the pot, which is tpicall between +G#<Gk, is used to create a
varing negative voltage from Lee up to 37N that is used to feed to the Lo input signal. 2n order to
do this, one leg of the pot needs to hook to ground, one leg needs to hook to the Lee negative
voltage output pin and then the wiper (middle pin of the pot) will have the variable voltage output
that can be fed to the Lo contrast control input pin.
Chan)in) the Arduino pin assi)nments:
:he E=G+GI chip needs lots of pins. I data pins and J command pins are re)uired in addition to the
power connections. 2deall the command pins should all be on one port and all the data pins
together on another. 2n practice this is not eas to do on a standard arduino.
=tarting with glcd vB, pin assignment is much more fle.ible as an glcd function or data pin can be
assigned to an Arduino pin. 2f ou split data pins across ports the code will run slightl slower, but
for all but the most speed critical graphic applications its not significant. :o change pin assignments
ou must modif the appropriate pin configuration file in the glcd!config director (ksG+GI.h when
using a mB<I based arduino). Pind the section in the file that begins:
Con!i)uration !or assi)nin) .CD bits to Arduino %ins
Sou will see the defines for the data pins and the five control pins with their default pin
assignments:
*ame Arduino pin number
$define glcdNataG8in I
$define glcdNata+8in K
$define glcdNata<8in +G
$define glcdNataB8in ++
$define glcdNataF8in F
$define glcdNataJ8in J
$define glcdNataH8in H
$define glcdNataM8in M
$define glcdD=O4+ +F (Analog pin G)
$define glcdD=O4< +J (Analog pin +)
$define glcdA6 +H (Analog pin <)
$define glcdN2 +M (Analog pin B)
$define glcdO7 +I (Analog pin F)
An of these data pins and glcd functions can be assigned to an pin (as long as its not used b
something else) 1ere are the pin!port mappings for the Arduino mB<I processor:
8ort C I#+B
8ort D +F#+K (the analog pins)
8ort N G#M (note G and + are used b hardware serial)
MJ
6hile an Arduino pin can can be used for an glcd data pin, using Arduino pins that are all in the
same port and that are in consecutive bit order will give slightl higher performance. :he default
pin assignments for the glcd data pins are assigned to take advantage of this optimi?ation.
An e.ample of remapping a pin might be to change glcdO7 to use some other pin rather than +I to
allow using i<c on a mB<I based board.
Troubleshootin)
No !i,els visible on the dis!lay
Dheck &Jv and 3nd connections between Arduino and 34DN panel
Dheck that all data and command pins are wired correctl
Dheck contrast voltage (tpicall between #B and #F volts) on contrast#in pin of 4DN panel. 6hile
the sketch is operating, tr graduall ad>usting the pot through its range. =ome displas are ver
sensitive to this setting.
Dheck sketch has compiled ok and downloaded to the arduino.
Left and right side of image reversed
swap D=O4+ and D=O4< wires (or swap pin assignments in header file)
Dis!lay garbled
check all data and command pins are wired correctl and that these match the setting in the header
file.
#(etch u!load not -or(ing
:r the glcd with nothing connected to its reset line
:r connecting the glcd reset line to vcc
enable the librar software reset functionalit
.L"D reset !in NOT$+
:he Arduino autoreset circuit is )uit fragile. Nepending on the particular Arduino board and glcd
module, connecting the glcd module to the Arduino board reset line ma interfere with the Arduino
boardRs autoreset circuit. @ost glcds will reset on power up so the glcd reset line can be left
unconnected. @ost of the remaining others will work when their reset line is connected to vcc. A
small fraction of the glcds out there will need a reset pulse. Por those that need a reset pulse and
connecting the glcd to the arduino reset line causes the autoreset on the aruduino board to fail, the
librar must be used to reset the glcd which re)uires another Arduino pin. 2n order to enable this
functionalit edit the pin configuration file and uncomment the line that looks like this:
!! Aeset Cit # uncomment the ne.t line if reset is connected to an output pin !!$define glcdAO= +K !!
Aeset Cit
And then connect the Arduino pin specified b glcdAO= to the glcd moduleRs reset pin.
=till having problems, see the forum discussion links below.
MH
Create your own !onts and icons
:here is a free >ava application available that can convert an of our 8D fonts for use with this
librar. :he software is called PontDreator< and it can produce a header file that stores font
definitions in program memor when included in our sketch. =ee the included 1:@4
documentation for more information about this as well as some web site links for obtaining
additional fonts.
+mbedin) ima)es in your !irmware
A 8rocessing sketch is provided in the download that converts bmp images to files that can be used
b the librar to displa the image on the 4DN. =ee the documentation in the download for more
information.
+xample
!"
" Casic test code for the Arduino E=G+GI 34DN librar. :his code e.ercises a range of graphic
" functions supported b the librar and is an e.ample of its use. 2t also gives an indication of
" performance, showing the number of frames drawn per second.
"!
$include XksG+GI.hY
$include TArial+F.hT !! proportional font
$include T=stemPontJ.M.hT !! sstem font
$include TArduino2con.hT !! bitmap
unsigned long start@illis;
unsigned int loops % G;
unsigned int iter % G;
void setup(){
dela(JGG); !! allow time for 4DN to reset
34DN.2nit(757;27LOA:ON); !! initialise the librar, non inverted writes pi.els onto a clear
screen
34DN.Dlear=creen();
34DN.NrawCitmap(Arduino2con, B<,G, C4ADE); !!draw the bitmap at the given ., position
34DN.=electPont(=stemJ.M); !! switch to fi.ed width sstem font
countdown(J);
34DN.Dlear=creen();
intro=creen(); !! show some intro stuff
34DN.Dlear=creen();
}
void intro=creen(){
34DN.=electPont(Arial;+F); !! ou can also make our own fonts, see plaground for details
34DN.3otoQS(<G, <);
34DN.8uts(T34DN version T);
34DN.8rint7umber(34DN;LOA=257);
34DN.NrawAoundAect(+H,G,KK,+I, J, C4ADE); !! rounded rectangle around te.t area
34DN.=electPont(=stemJ.M); !! switch to fi.ed width sstem font
showDharacters();
countdown(J);
}
MM
void showDharacters(){
bte line % B; !! start on the fourth line
for(bte c % B<; c X%+<M; c&&){
if( (c#B<) ( <G %% G)
34DN.Dursor:o(+,line&&); !! Dursor:o is used for fi.ed width sstem font
34DN.8utDhar(c);
}
}
void draw=pinner(bte pos, bte ., bte ) {
!! this draws an ob>ect that appears to spin
switch(pos ( I) {
case G : 34DN.Nraw4ine( ., #I, ., &I, C4ADE); break;
case + : 34DN.Nraw4ine( .&B, #M, .#B, &M, C4ADE); break;
case < : 34DN.Nraw4ine( .&H, #H, .#H, &H, C4ADE); break;
case B : 34DN.Nraw4ine( .&M, #B, .#M, &B, C4ADE); break;
case F : 34DN.Nraw4ine( .&I, , .#I, , C4ADE); break;
case J : 34DN.Nraw4ine( .&M, &B, .#M, #B, C4ADE); break;
case H : 34DN.Nraw4ine( .&H, &H, .#H, #H, C4ADE); break;
case M : 34DN.Nraw4ine( .&B, &M, .#B, #M, C4ADE); break;
}
}
void countdown(int count){
while(count##){ !! do countdown
34DN.Dursor:o(G,+); !! first column, second row (offset is from G)
34DN.8utDhar(count & RGR);
dela(+GGG);
}
}
void loop(){ !! run over and over again
iter % G;
start@illis % millis();
while( millis() # start@illis X +GGG){ !! loop for one second
34DN.NrawAect(G, G, HF, H+, C4ADE); !! rectangle in left side of screen
34DN.NrawAoundAect(HI, G, JI, H+, J, C4ADE); !! rounded rectangle around te.t area
for(int i%G; i X H<; i &% F)
34DN.Nraw4ine(+,+,HB,i, C4ADE); !! draw lines from upper left down right side of rectangle
34DN.NrawDircle(B<,B+,BG,C4ADE); !! draw circle centered in the left side of screen
34DN.PillAect(K<,FG,+H,+H, 612:O); !! clear previous spinner position
draw=pinner(loops&&,+GG,FI); !! draw new spinner position
!!34DN.PillAect(<F,t.t427OB,+F,+F, 612:O); !! clear te.t area that will be drawn below
34DN.Dursor:o(J,J); !! locate curser for printing te.t
34DN.8rint7umber(&&iter); !! print current iteration at the current cursor position
}
!! displa number of iterations in one second
34DN.Dlear=creen(); !! clear the screen
34DN.Dursor:o(+F,<); !! positon cursor
34DN.8uts(TP8=% T); !! print a te.t string
34DN.8rint7umber(iter); !! print a number
}
MI
)oto
:ransfers program flow to a labeled point in the program
Syntax' label:
goto label; !! sends program flow to the label
Tip' :he use of goto is discouraged in D programming, and some authors of D programming
books claim that the goto statement is never necessar, but used >udiciousl, it can simplif
certain programs. :he reason that man programmers frown upon the use of goto is that
with the unrestrained use of goto statements, it is eas to create a program with undefined
program flow, which can never be debugged.
6ith that said, there are instances where a goto statement can come in hand, and simplif
coding. 5ne of these situations is to break out of deepl nested for loops, or if logic blocks,
on a certain condition.
+xample
for(bte r % G; r X <JJ; r&&){
for(bte g % <JJ; g Y #+; g##){
for(bte b % G; b X <JJ; b&&){
if (analogAead(G) Y <JG){ goto bailout;}
!! more statements ...
}
}
}
bailout:
!!
hi)hByte#$
O.tracts the high#order (leftmost) bte of a word (or the second lowest bte of a larger data tpe).
Syntax' highCte(.)
%arameters' .: a value of an tpe
&eturns' bte
i!
if, which is used in con>unction with a comparison operator, tests whether a certain condition has
been reached, such as an input being above a certain number. :he format for an if test is:
if (someLariable Y JG)
{
!! do something here
}
MK
:he program tests to see if someLariable is greater than JG. 2f it is, the program takes a particular
action. 8ut another wa, if the statement in parentheses is true, the statements inside the brackets are
run. 2f not, the program skips over the code.
:he brackets ma be omitted after an if statement. 2f this is done, the ne.t line (defined b the
semicolon) becomes the onl conditional statement.
if (. Y +<G) digital6rite(4ONpin, 1231);
if (. Y +<G)
digital6rite(4ONpin, 1231);
if (. Y +<G){ digital6rite(4ONpin, 1231); }
if (. Y +<G){
digital6rite(4ONpin+, 1231);
digital6rite(4ONpin<, 1231);
} !! all are correct
:he statements being evaluated inside the parentheses re)uire the use of one or more operators:
Comparison Operators'
. %% (. is e)ual to )
. *% (. is not e)ual to )
. X (. is less than )
. Y (. is greater than )
. X% (. is less than or e)ual to )
. Y% (. is greater than or e)ual to )
(arnin)' Ceware of accidentall using the single e)ual sign (e.g. if (. % +G) ). :he single e)ual
sign is the assignment operator, and sets . to +G (puts the value +G into the variable .).
2nstead use the double e)ual sign (e.g. if (. %% +G) ), which is the comparison operator,
and tests whether . is e)ual to +G or not. :he latter statement is onl true if . e)uals +G,
but the former statement will alwas be true. :his is because D evaluates the statement if
(.%+G) as follows: +G is assigned to . (remember that the single e)ual sign is the
assignment operator), so . now contains +G. :hen the RifR conditional
evaluates +G, which alwas evaluates to :A9O, since an non#?ero number evaluates to
:A9O. Donse)uentl, if (. % +G) will alwas evaluate to :A9O, which is not the desired
result when using an RifR statement. Additionall, the variable . will be set to +G, which is
also not a desired action.
if can also be part of a branching control structure using the if...elseV construction.
i! = else
if!else allows greater control over the flow of code than the basic if statement, b allowing multiple
tests to be grouped together. Por e.ample, an analog input could be tested and one action taken if
the input was less than JGG, and another action taken if the input was JGG or greater. :he code
would look like this:
IG
if (pinPive2nput X JGG)
{
!! action A
}
else
{
!! action C
}
else can proceed another if test, so that multiple, mutuall e.clusive tests can be run at the same
time.
Oach test will proceed to the ne.t one until a true test is encountered. 6hen 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. 2f no test proves to be true, the default else block is e.ecuted, if one is present, and
sets the default behavior.
7ote that an else if block ma be used with or without a terminating else block and vice versa. An
unlimited number of such else if branches is allowed.
if (pinPive2nput X JGG)
{
!! do :hing A
}
else if (pinPive2nput Y% +GGG)
{
!! do :hing C
}
else
{
!! do :hing D
}
Another wa to e.press branching, mutuall e.clusive tests, is with the switch case statement.
clude
$include is used to include outside libraries in our sketch. :his gives the programmer access to a
large group of standard D libraries (groups of pre#made functions), and also libraries written
especiall for Arduino.
:he main reference page for ALA D libraries (ALA is a reference to the Atmel chips on which the
Arduino is based) is here.
7ote that $include, similar to $define, has no semicolon terminator, and the compiler will ield
crptic error messages if ou add one.
+xample
:his e.ample includes a librar that is used to put data into the program space flash instead of ram.
:his saves the ram space for dnamic memor needs and makes large lookup tables more practical.
I+
$include Xavr!pgmspace.hY
prog;uint+H;t mDonstantsUV 8A53@O@ % {G, <++FG, MG< , K+<I, G, <JMHF, IFJH,
G,G,G,G,G,G,G,G,<KI+G,IKHI,<KMH<,<KMH<,FJGG};
J/ , B/ , E/ , =/
8erform a mathematical operation on a variable with another constant or variable. :he &% (et al)
operators are >ust a convenient shorthand for the e.panded snta., listed below.
Syntax' . &% ; !! e)uivalent to the e.pression . % . & ;
. #% ; !! e)uivalent to the e.pression . % . # ;
. "% ; !! e)uivalent to the e.pression . % . " ;
. !% ; !! e)uivalent to the e.pression . % . ! ;
%arameters' .: an variable tpe
: an variable tpe or constant
+xamples
. % <;
. &% F; !! . now contains H
. #% B; !! . now contains B
. "% +G; !! . now contains BG
. !% <; !! . now contains +J
JJ #increment$ = BB #decrement$
2ncrement or decrement a variable
Syntax' .&&; !! increment . b one and returns the old value of .
&&.; !! increment . b one and returns the new value of .
.## ; !! decrement . b one and returns the old value of .
##. ; !! decrement . b one and returns the new value of .
%arameters' .: an integer or long (possibl unsigned)
&eturns' :he original or newl incremented ! decremented value of the variable.
+xamples
. % <;
% &&.; !! . now contains B, contains B
% .##; !! . contains < again, still contains B
I<
int#$
Donverts a value to the int data tpe.
Syntax' int(.)
%arameters' .: a value of an tpe
&eturns' int
1nte)er Constants
2nteger constants are numbers used directl in a sketch, like +<B. C default, these numbers are
treated as intRs but ou can change this with the 9 and 4 modifiers (see below).
7ormall, integer constants are treated as base +G (decimal) integers, but special notation
(formatters) ma be used to enter numbers in other bases.
Base +xample Formatter Comment
+G (decimal) +<B none
< (binar) C++++G++ leading RCR onl works with I bit values (G to <JJ)
characters G#+ valid
I (octal) G+MB leading TGT characters G#M valid
+H (he.adecimal) G.MC leading TG.T characters G#K, A#P, a#f valid
:he binar formatter onl works on btes (I bits) between G (CG) and <JJ (C++++++++). 2f it is
convenient to input an int (+H bits) in binar form ou can do it a two#step procedure such as:
m2nt % (C++GG++GG " <JH) & C+G+G+G+G; !! C++GG++GG is the high bte
" & . !ormatters
C default, an integer constant is treated as an int with the attendant limitations in values. :o
specif an integer constant with another data tpe, follow it with:
" a RuR or R9R to force the constant into an unsigned data format. O.ample BBu
" a RlR or R4R to force the constant into a long data format. O.ample +GGGGG4
" a RulR or R94R to force the constant into an unsigned long constant. O.ample B<MHMul
interrupts#$
Ae#enables interrupts (after theRve been disabled b no2nterrupts()). 2nterrupts allow certain
important tasks to happen in the background and are enabled b default. =ome functions will not
work while interrupts are disabled, and incoming communication ma be ignored. 2nterrupts can
slightl disrupt the timing of code, however, and ma be disabled for particularl critical sections of
code.
%arameters' 7one
IB
&eturns' 7one
+xample
void setup() {}
void loop()
{
no2nterrupts();
!! critical, time#sensitive code here
interrupts();
!! other code here
}
int
2ntegers are our primar datatpe for number storage, and store a < bte value. :his ields a range
of #B<,MHI to B<,MHM (minimum value of #<-+J and a ma.imum value of (<-+J) # +).
2ntRs store negative numbers with a techni)ue called <Rs complement math. :he highest bit,
sometimes refered to as the TsignT bit, flags the number as a negative number. :he rest of the bits
are inverted and + is added.
:he Arduino takes care of dealing with negative numbers for ou, so that arithmetic operations
work transparentl in the e.pected manner. :here can be an une.pected complication in dealing
with the bitshift right operator ('gt;'gt;) however.
+xample
int led8in % +B;
Syntax' int var % val;
" var # our int variable name
" val # the value ou assign to that variable
Codin) Tip
6hen variables are made to e.ceed their ma.imum capacit the Troll overT back to their minimum
capaciti, note that this happens in both directions.
int .
. % #B<,MHI;
. % . # +; !! . now contains B<,MHM # rolls over in neg. direction
. % B<,MHM;
. % . & +; !! . now contains #B<,MHI # rolls over
IF
-ouse K Leyboard B Moystic< )Only for Leonardo/*
LeyboardCbe)in#$
6hen used with the 4eonardo board, Eeboard.begin() starts emulating a keboard connected to a
computer. :o end control, use Eeboard.end().
Syntax' Eeboard.begin()
%arameters' none
&eturns' nothing
+xample
void setup() {
!! make pin < an input and turn on the
!! pullup resistor so it goes high unless
!! connected to ground:
pin@ode(<, 2789:;894498);
Eeboard.begin();
}
void loop() {
!!if the button is pressed
if(digitalAead(<)%%456){
!!=end the message
Eeboard.print(T1ello*T);
}
}
Mouse0eyboard
LeyboardCend#$
=tops the 4eonardo emulating a keboard connected to the computer. :o start keboard emulation,
use Eeboard.begin().
Syntax' Eeboard.end()
%arameters' none
&eturns' nothing
+xample
void setup() {
!!start keboard communication
Eeboard.begin();
!!send a kestroke
IJ
Eeboard.print(T1ello*T);
!!end keboard communication
Eeboard.end();
}
void loop() {
!!do nothing
}
Leyboard -odi!iers
:he Eeboard.write() and Eeboard.press() and Eeboard.release() commands don_t work with
ever possible A=D22 character, onl those that correspond to a ke on the keboard. Por e.ample,
backspace works, but man of the other non#printable characters produce unpredictable results. Por
capital letters (and other kes), what_s sent is shift plus the character (i.e. the e)uivalent of pressing
both of those kes on the keboard).
A modifier ke is a special ke on a computer keboard that modifies the normal action of another
ke when the two are pressed in combination.
Por more on A=D22 values and the characters or functions the represent, see asciitable.com
Por multiple ke presses use Eeboard.press()
The .eonardoNs de!initions !or modi!ier <eys are listed below'
Ee 1e. Necimal value
EOS;4OP:;D:A4 G.IG +<I
EOS;4OP:;=12P: G.I+ +<K
EOS;4OP:;A4: G.I< +BG
EOS;4OP:;392 G.IB +B+
EOS;A231:;D:A4 G.IF +B<
EOS;A231:;=12P: G.IJ +BB
EOS;A231:;A4: G.IH +BF
EOS;A231:;392 G.IM +BJ
EOS;98;AAA56 G.NA <+I
EOS;N567;AAA56 G.NK <+M
EOS;4OP:;AAA56 G.NI <+H
EOS;A231:;AAA56 G.NM <+J
EOS;CADE=8ADO G.C< +MI
EOS;:AC G.CB +MK
EOS;AO:9A7 G.CG +MH
EOS;O=D G.C+ +MM
EOS;27=OA: G.N+ <GK
EOS;NO4O:O G.NF <+<
EOS;8A3O;98 G.NB <++
EOS;8A3O;N567 G.NH <+F
EOS;15@O G.N< <+G
EOS;O7N G.NJ <+B
EOS;DA8=;45DE G.D+ +KB
EOS;P+ G.D< +KF
IH
EOS;P< G.DB +KJ
EOS;PB G.DF +KH
EOS;PF G.DJ +KM
EOS;PJ G.DH +KI
EOS;PH G.DM +KK
EOS;PM G.DI <GG
EOS;PI G.DK <G+
EOS;PK G.DA <G<
EOS;P+G G.DC <GB
EOS;P++ G.DD <GF
EOS;P+< G.DN <GJ
0eyboard
LeyboardCpress#$
6hen called, Eeboard.press() functions as if a ke were pressed and held on our keboard.
9seful when using modifier kes. :o end the ke press, use Eeboard.release() or
Eeboard.releaseAll().
2t is necessar to call Eeboard.begin() before using press().
Syntax' Eeboard.press()
%arameters' char : the ke to press
&eturns' 7one
+xample
!! use this option for 5=Q:
char ctrlEe % EOS;4OP:;392;
!! use this option for 6indows and 4inu.:
!! char ctrlEe % EOS;4OP:;D:A4;
void setup() {
!! make pin < an input and turn on the
!! pullup resistor so it goes high unless
!! connected to ground:
pin@ode(<, 2789:;894498);
!! initiali?e control over the keboard:
Eeboard.begin();
}
void loop() {
while (digitalAead(<) %% 1231) {
!! do nothing until pin < goes low
dela(JGG);
}
dela(+GGG);
!! new document:
IM
Eeboard.press(ctrlEe);
Eeboard.press(RnR);
dela(+GG);
Eeboard.releaseAll();
!! wait for new window to open:
dela(+GGG);
}
0eyboard
LeyboardCprint#$
=ends a kestroke to a connected computer.
Eeboard.print() must be called after initiating Eeboard.begin().
(A&*1*>' 6hen ou use the Eeboard.print() command, the Arduino takes over our keboard
@ake sure ou have control before ou use the command. A pushbutton to toggle the
keboard control state is effective.
Syntax' Eeboard.print(character)
Eeboard.print(characters)
%arameters' character : a char or int to be sent to the computer as a kestroke characters : a string
to be sent to the computer as a kestroke
&eturns' int : number of btes sent
+xample
void setup() {
!! make pin < an input and turn on the
!! pullup resistor so it goes high unless
!! connected to ground:
pin@ode(<, 2789:;894498);
Eeboard.begin();
}
void loop() {
!!if the button is pressed
if(digitalAead(<)%%456){
!!=end the message
Eeboard.print(T1ello*T);
}
}
II
0eyboard
LeyboardCprintln#$
=ends a kestroke to a connected computer, followed b a newline and carriage return.
Eeboard.println() must be called after initiating Eeboard.begin().
(A&*1*>' 6hen ou use the Eeboard.println() command, the Arduino takes over our
keboard* @ake sure ou have control before ou use the command. A pushbutton
to toggle the keboard control state is effective.
Syntax' Eeboard.println()
Eeboard.println(character)
Eeboard.println(characters)
%arameters' character : a char or int to be sent to the computer as a kestroke, followed b
newline and carriage return.
characters : a string to be sent to the computer as a kestroke, followed b a
newline and carriage return.
&eturns' int : number of btes sent
+xample
void setup() {
!! make pin < an input and turn on the
!! pullup resistor so it goes high unless
!! connected to ground:
pin@ode(<, 2789:;894498);
Eeboard.begin();
}
void loop() {
!!if the button is pressed
if(digitalAead(<)%%456){
!!=end the message
Eeboard.println(T1ello*T);
}
}
0eyboard
LeyboardCreleaseAll#$
4ets go of all kes currentl pressed. =ee Eeboard.press() for additional information.
Syntax' Eeboard.releaseAll()
IK
%arameters' 7one
&eturns' int : the number of kes released
+xample
!! use this option for 5=Q:
char ctrlEe % EOS;4OP:;392;
!! use this option for 6indows and 4inu.:
!! char ctrlEe % EOS;4OP:;D:A4;
void setup() {
!! make pin < an input and turn on the
!! pullup resistor so it goes high unless
!! connected to ground:
pin@ode(<, 2789:;894498);
!! initiali?e control over the keboard:
Eeboard.begin();
}
void loop() {
while (digitalAead(<) %% 1231) {
!! do nothing until pin < goes low
dela(JGG);
}
dela(+GGG);
!! new document:
Eeboard.press(ctrlEe);
Eeboard.press(RnR);
dela(+GG);
Eeboard.releaseAll();
!! wait for new window to open:
dela(+GGG);
}
0eyboard
LeyboardCrelease#$
4ets go of the specified ke. =ee Eeboard.press() for more information.
Syntax' Eeboard.release(ke)
%arameters' ke : the ke to release. char
&eturns' int : the number of kes released
+xample
!! use this option for 5=Q:
char ctrlEe % EOS;4OP:;392;
KG
!! use this option for 6indows and 4inu.:
!! char ctrlEe % EOS;4OP:;D:A4;
void setup() {
!! make pin < an input and turn on the
!! pullup resistor so it goes high unless
!! connected to ground:
pin@ode(<, 2789:;894498);
!! initiali?e control over the keboard:
Eeboard.begin();
}
void loop() {
while (digitalAead(<) %% 1231) {
!! do nothing until pin < goes low
dela(JGG);
}
dela(+GGG);
!! new document:
Eeboard.press(ctrlEe);
Eeboard.press(RnR);
dela(+GG);
Eeboard.release(ctrlEe);
Eeboard.release(RnR);
!! wait for new window to open:
dela(+GGG);
}
0eyboard
LeyboardCwrite#$
=ends a kestroke to a connected computer. :his is similar to pressing and releasing a ke on our
keboard. Sou can send some A=D22 characters or the additional keboard modifiers and special
kes.
5nl A=D22 characters that are on the keboard are supported. Por e.ample, A=D22 I (backspace)
would work, but A=D22 <J (=ubstitution) would not. 6hen sending capital letters, Eeboard.write()
sends a shift command plus the desired character, >ust as if tping on a keboard. 2f sending a
numeric tpe, it sends it as an A=D22 character (e.. Eeboard.write(KM) will send RaR).
Por a complete list of A=D22 characters, see A=D22:able.com.
(A&*1*>' 6hen ou use the Eeboard.write() command, the Arduino takes over our
keboard* @ake sure ou have control before ou use the command. A pushbutton to
toggle the keboard control state is effective.
Syntax' Eeboard.write(character)
%arameters' character : a char or int to be sent to the computer. Dan be sent in an notation thatRs
acceptable for a char. Por e.ample, all of the below are acceptable and send the same
K+
value, HJ or A=D22 A:
Eeboard.write(HJ); !! sends A=D22 value HJ, or A
Eeboard.write(RAR); !! same thing as a )uoted character
Eeboard.write(G.F+); !! same thing in he.adecimal
Eeboard.write(GbG+GGGGG+); !! same thing in binar (weird choice, but it works)
&eturns' int : number of btes sent
+xample
void setup() {
!! make pin < an input and turn on the
!! pullup resistor so it goes high unless
!! connected to ground:
pin@ode(<, 2789:;894498);
Eeboard.begin();
}
void loop() {
!!if the button is pressed
if(digitalAead(<)%%456){
!!=end an A=D22 RAR,
Eeboard.write(HJ);
}
}
K<
=E
EeboardAnd@ouseDontrol
Dontrols the mouse from five pushbuttons on an Arduino 4eonardo.
1ardware:
" J pushbuttons attached to N<, NB, NF, NJ, NH
:he mouse movement is alwas relative. :his sketch reads four pushbuttons, and uses them to set
the movement of the mouse.
(A&*1*>' 6hen ou use the @ouse.move() command, the Arduino takes over our mouse*
@ake sure ou have control before ou use the mouse commands.
"!
!! set pin numbers for the five buttons:
const int upCutton % <;
const int downCutton % B;
const int leftCutton % F;
const int rightCutton % J;
const int mouseCutton % H;
void setup() { !! initiali?e the buttonsR inputs:
pin@ode(upCutton, 2789:);
pin@ode(downCutton, 2789:);
pin@ode(leftCutton, 2789:);
pin@ode(rightCutton, 2789:);
pin@ode(mouseCutton, 2789:);
=erial.begin(KHGG);
!! initiali?e mouse control:
@ouse.begin();
Eeboard.begin();
}
void loop() {
!! use serial input to control the mouse:
if (=erial.available() Y G) {
char inDhar % =erial.read();
switch (inDhar) {
case RuR:
!! move mouse up
@ouse.move(G, #FG);
break;
case RdR:
!! move mouse down
@ouse.move(G, FG);
break;
case RlR:
!! move mouse left
@ouse.move(#FG, G);
break;
KB
case RrR:
!! move mouse right
@ouse.move(FG, G);
break;
case RmR:
!! move mouse right
@ouse.click(@59=O;4OP:);
break;
}
}
!! use the pushbuttons to control the keboard:
if (digitalAead(upCutton) %% 1231) {
Eeboard.write(RuR);
}
if (digitalAead(downCutton) %% 1231) {
Eeboard.write(RdR);
}
if (digitalAead(leftCutton) %% 1231) {
Eeboard.write(RlR);
}
if (digitalAead(rightCutton) %% 1231) {
Eeboard.write(RrR);
}
if (digitalAead(mouseCutton) %% 1231) {
Eeboard.write(RmR);
}
}
KF
=E
Leyboard Button test
=ends a te.t string when a button is pressed.
:he circuit:
" pushbutton attached from pin < to &JL
" +G#kilohm resistor attached from pin F to ground
"!
const int button8in % <; !! input pin for pushbutton
int previousCutton=tate % 1231; !! for checking the state of a pushCutton
int counter % G; !! button push counter
void setup() {
!! make the pushCutton pin an input:
pin@ode(button8in, 2789:);
!! initiali?e control over the keboard:
Eeboard.begin();
}
void loop() {
!! read the pushbutton:
int button=tate % digitalAead(button8in);
!! if the button state has changed,
if ((button=tate *% previousCutton=tate)
!! and itRs currentl pressed:
'' (button=tate %% 1231)) {
!! increment the button counter
counter&&;
!! tpe out a message
Eeboard.print(TSou pressed the button T);
Eeboard.print(counter);
Eeboard.println(T times.T);
}
!! save the current button state for comparison ne.t time:
previousCutton=tate % button=tate;
}
KJ
=E
-ouseContinousDrawin)
Dontrols the mouse from two potentiometer on an Arduino 4eonardo. 9ses a pushbutton to turn on
and off mouse control, and a second pushbutton to click the left mouse button
1ardware:
" < potentiometers connected to pins AG and A+
" pushbuttons connected to pin N< and NB
:he mouse movement is alwas relative. :his sketch reads two analog inputs that range from G to
+G<B (or less on either end) and translates them into an offset compared to the previous position.
6AA7273: 6hen ou use the @ouse.move() command, the Arduino takes over our mouse*
@ake sure ou have control before ou use the command. :his sketch includes a pushbutton to
toggle the mouse control state, so ou can turn on and off mouse control.
"!
!! set pin numbers for switch, >ostick a.es, and 4ON:
const int switch8in % <; !! switch to turn on and off mouse control
const int mouseCutton % B; !! input pin for the mouse pushCutton
const int .A.is % AG; !! >ostick Q a.is
const int A.is % A+; !! >ostick S a.is
const int led8in % +B; !! @ouse control 4ON
KH
!! parameters for reading the >ostick:
int range % +<; !! output range of Q or S movement
int responseNela % J; !! response dela of the mouse, in ms
int threshold % range!F; !! resting threshold
int center % range!<; !! resting position value
int prev.Lal % G;
int prevLal % G;
int prevQreading % G;
int prevSreading % G;
int toggle % G;
boolean mouse2sActive % false; !! whether or not to control the mouse
int prev=witch=tate % 456; !! previous switch state
int prevCutton=tate % 456;
void setup() {
pin@ode(switch8in, 2789:); !! the switch pin
pin@ode(led8in, 59:89:); !! the 4ON pin
!! take control of the mouse:
@ouse.begin();
}
void loop() {
!! read the switch:
int switch=tate % digitalAead(switch8in);
!! if itRs changed and itRs high, toggle the mouse state:
if (switch=tate *% prev=witch=tate) {
if (switch=tate %% 1231) {
mouse2sActive % *mouse2sActive;
!! turn on 4ON to indicate mouse state:
digital6rite(led8in, mouse2sActive);
}
}
!! save switch state for ne.t comparison:
prev=witch=tate % switch=tate;
!! read and scale the two a.es:
!! int .Aeading % readA.is(AG, .Lal);
!! int Aeading % readA.is(A+, lastLal);
int currQreading % analogAead(.A.is);
int currSreading % analogAead(A.is);
int .Aeading % prevQreading # currQreading;
int Aeading % prevSreading # currSreading;
prevQreading % currQreading;
prevSreading % currSreading;
!! if the mouse control state is active, move the mouse:
KM
if (mouse2sActive) {
@ouse.move(.Aeading, Aeading, G);
}
!! read the mouse button and click or not click:
!! if the mouse button is pressed:
int button=tate % digitalAead(mouseCutton);
if (button=tate %% 1231 '' prevCutton=tate %% 456) {
!! if the mouse is not pressed, press it:
toggle&&;
if(toggle %% +)
if (*@ouse.is8ressed(@59=O;4OP:)) {
@ouse.press(@59=O;4OP:);
}
}
else if(toggle %% <)
{
!! else the mouse button is not pressed:
!! if the mouse is pressed, release it:
if (@ouse.is8ressed(@59=O;4OP:)) {
@ouse.release(@59=O;4OP:);
}
toggle % G;
}
prevCutton=tate % button=tate;
dela(responseNela);
}
The processing application allow you to draw on the grey screen by pressing the mouse left button
and moving the cursor. To let you free to drawing only by moving the two potentiometers, when you
press the pushbutton connected to the D3 input, the Leonardo will hold the left mouse clic for you
until you press the pushbutton another time.
!"
" Dontinuous 4ines.
" Dlick and drag the mouse to draw a line.
"!
void setup() {
si?e(HFG, FIG);
background(+G<);
}
void draw() {
stroke(<JJ);
stroke6eight(+G);
if(mouse8ressed) {
line(mouseQ, mouseS, pmouseQ, pmouseS);
}
}
KI
Moystic< Control
+xample
!"
Wostick@ouseDontrol
Dontrols the mouse from a >ostick on an Arduino 4eonardo. 9ses a pushbutton to turn on and off
mouse control, and a second pushbutton to click the left mouse button
1ardware:
" <#a.is >ostick connected to pins AG and A+
" pushbuttons connected to pin N< and NB
:he mouse movement is alwas relative. :his sketch reads two analog inputs that range from G to
+G<B (or less on either end) and translates them into ranges of #H to H. :he sketch assumes that the
>ostick resting values are around the middle of the range, but that the var within a threshold.
6AA7273: 6hen ou use the @ouse.move() command, the Arduino takes over our mouse*
@ake sure ou have control before ou use the command. :his sketch includes a pushbutton to
toggle the mouse control state, so ou can turn on and off mouse control.
"!
!! set pin numbers for switch, >ostick a.es, and 4ON:
const int switch8in % <; !! switch to turn on and off mouse control
const int mouseCutton % B; !! input pin for the mouse pushCutton
const int .A.is % AG; !! >ostick Q a.is
const int A.is % A+; !! >ostick S a.is
const int led8in % J; !! @ouse control 4ON
!! parameters for reading the >ostick:
int range % +<; !! output range of Q or S movement
int responseNela % J; !! response dela of the mouse, in ms
int threshold % range!F; !! resting threshold
KK
int center % range!<; !! resting position value
boolean mouse2sActive % false; !! whether or not to control the mouse
int last=witch=tate % 456; !! previous switch state
void setup() {
pin@ode(switch8in, 2789:); !! the switch pin
pin@ode(led8in, 59:89:); !! the 4ON pin
!! take control of the mouse:
@ouse.begin();
}
void loop() {
int switch=tate % digitalAead(switch8in); !! read the switch
if (switch=tate *% last=witch=tate) { !! if itRs changed and itRs high, toggle the mouse state
if (switch=tate %% 1231) {
mouse2sActive % *mouse2sActive;
digital6rite(led8in, mouse2sActive); !! turn on 4ON to indicate mouse state
}
}
!! save switch state for ne.t comparison:
last=witch=tate % switch=tate;
!! read and scale the two a.es:
int .Aeading % readA.is(AG);
int Aeading % readA.is(A+);
!! if the mouse control state is active, move the mouse:
if (mouse2sActive) {
@ouse.move(.Aeading, Aeading, G);
}
!! read the mouse button and click or not click:
!! if the mouse button is pressed:
if (digitalAead(mouseCutton) %% 1231) {
!! if the mouse is not pressed, press it:
if (*@ouse.is8ressed(@59=O;4OP:)) {
@ouse.press(@59=O;4OP:);
}
}
!! else the mouse button is not pressed:
else {
!! if the mouse is pressed, release it:
if (@ouse.is8ressed(@59=O;4OP:)) {
@ouse.release(@59=O;4OP:);
}
}
dela(responseNela);
}
!"
+GG
reads an a.is (G or + for . or ) and scales the
analog input range to a range from G to XrangeY
"!
int readA.is(int thisA.is) {
!! read the analog input:
int reading % analogAead(thisA.is);
!! map the reading from the analog input range to the output range:
reading % map(reading, G, +G<B, G, range);
!! if the output reading is outside from the
!! rest position threshold, use it:
int distance % reading # center;
if (abs(distance) X threshold) {
distance % G;
}
!! return the distance for this a.is:
return distance;
}
+G+
.ibraries
4ibraries provide e.tra functionalit for use in sketches, e.g. working with hardware or
manipulating data. :o use a librar in a sketch, select it from =ketch Y 2mport 4ibrar.
Standard .ibraries
" OO8A5@ # reading and writing to TpermanentT storage
" Othernet # for connecting to the internet using the Arduino Othernet =hield
" Pirmata # for communicating with applications on the computer using a standard serial protocol.
" 4i)uidDrstal # for controlling li)uid crstal displas (4DNs)
" =N # for reading and writing =N cards
" =ervo # for controlling servo motors
" =82 # for communicating with devices using the =erial 8eripheral 2nterface (=82) Cus
" =oftware=erial # for serial communication on an digital pins. Lersion +.G and later of
Arduino incorporate @ikal 1artRs 7ew=oft=erial librar as =oftware=erial.
" =tepper # for controlling stepper motors
" 6iPi # for connecting to the internet using the Arduino 6iPi shield
" 6ire # :wo 6ire 2nterface (:62!2<D) for sending and receiving data over a net of devices or
sensors.
:he @atri. and =prite libraries are no longer part of the core distribution.
.eonardo Only .ibraries
" Eeboard # =end kestrokes to an attached computer.
" @ouse # Dontrol cursor movement on a connected computer.
Contributed .ibraries
2f ouRre using one of these libraries, ou need to install it first. :o do so, download the librar and
un?ip it. 2t should be in a folder of its own, and will tpicall contain at least two files, one with a .h
suffi. and one with a .cpp suffi.. 5pen our Arduino sketchbook folder. 2f there is alread a folder
there called libraries, place the librar folder in there. 2f not, create a folder called libraries in the
sketchbook folder, and drop the librar folder in there. :hen re#start the Arduino programming
environment, and ou should see our new librar in the =ketch Y 2mport 4ibrar menu.
Por details, see the page on the Arduino environment.
Communication #networ<in) and protocols$'
" @essenger # for processing te.t#based messages from the computer
" 7ew=oft=erial # an improved version of the =oftware=erial librar
" 5ne6ire # control devices (from Nallas =emiconductor) that use the 5ne 6ire protocol.
" 8=<Eeboard # read characters from a 8=< keboard.
" =imple @essage =stem # send messages between Arduino and the computer
" ==erial<@obile # send te.t messages or emails using a cell phone (via A: commands over
software serial)
" 6ebduino # e.tensible web server librar (for use with the Arduino Othernet =hield)
" Q+G # =ending Q+G signals over AD power lines
" QCee # for communicating with QCees in A82 mode
+G<
" =erialDontrol # Aemote control other Arduinos over a serial connection
Sensin)'
" Dapacitive =ensing # turn two or more pins into capacitive sensors
" Nebounce # for reading nois digital inputs (e.g. from buttons)
Displays and .+Ds'
" 2mproved 4DN librar fi.es 4DN initiali?ation bugs in official Arduino 4DN librar
" 34DN # graphics routines for 4DN based on the E=G+GI or e)uivalent chipset.
" 4edDontrol # for controlling 4ON matrices or seven#segment displas with a @AQM<<+ or
@AQM<+K.
" 4edDontrol # an alternative to the @atri. librar for driving multiple 4ONs with @a.im chips.
" 4edNispla # control of a 1D@=#<K.. scrolling 4ON displa.
:hese libraries are compatible 6iring versions, and the links below point to the (e.cellent)
6iring documentation.
" @atri. # Casic 4ON @atri. displa manipulation librar
" =prite # Casic image sprite manipulation librar for use in animations with an 4ON matri.
Audio and (ave!orms'
" PP: # fre)uenc analsis of audio or other analog signals
" :one # generate audio fre)uenc s)uare waves in the background on an microcontroller pin
-otors and %(-'
" :4DJKFG # +H channel +< bit 86@ controller.
Timin)'
" Nate:ime # a librar for keeping track of the current date and time in software.
" @etro # help ou time actions at regular intervals
" @s:imer< # uses the timer < interrupt to trigger an action ever 7 milliseconds.
"tilities'
" 8=tring # a lightweight class for printing to buffers
" =treaming # a method to simplif print statements
Por a guide to writing our own libraries, see this tutorial. Aeference 1ome
:he te.t of the Arduino reference is licensed under a Dreative Dommons Attribution#=hareAlike B.G
4icense. Dode samples in the reference are released into the public domain.
+GB
.CD .ibrary
:his librar allows an Arduino board to control 4i)uidDrstal displas (4DNs) based on the 1itachi
1NFFMIG (or a compatible) chipset, which is found on most te.t#based 4DNs. :he librar works
with in either F# or I#bit mode (i.e. using F or I data lines in addition to the rs, enable, and,
optionall, the rw control lines).
lcdCautoscroll#$
:urns on automatic scrolling of the 4DN. :his causes each character output to the displa to push
previous characters over b one space. 2f the current te.t direction is left#to#right (the default), the
displa scrolls to the left; if the current direction is right#to#left, the displa scrolls to the right. :his
has the effect of outputting each new character to the same location on the 4DN.
Syntax' lcd.autoscroll()
%arameters' lcd: a variable of tpe 4i)uidDrstal
+xample
Li1uid"rystal Library 2 Autoscroll
+GF
!"
Nemonstrates the use a +H.< 4DN displa. :he 4i)uidDrstal librar works with all 4DN displas
that are compatible with the 1itachi 1NFFMIG driver. :here are man of them out there, and ou
can usuall tell them b the +H#pin interface.

:his sketch demonstrates the use of the autoscroll() and noAutoscroll() functions to make new te.t
scroll or not.

:he circuit:
" 4DN A= pin to digital pin +<
" 4DN Onable pin to digital pin ++
" 4DN NF pin to digital pin J
" 4DN NJ pin to digital pin F
" 4DN NH pin to digital pin B
" 4DN NM pin to digital pin <
" 4DN A!6 pin to ground
" +GE resistor:
" ends to &JL and ground
" wiper to 4DN L5 pin (pin B)
"!
!! include the librar code:
$include X4i)uidDrstal.hY
!! initiali?e the librar with the numbers of the interface pins
4i)uidDrstal lcd(+<, ++, J, F, B, <);
void setup() {
!! set up the 4DNRs number of columns and rows:
lcd.begin(+H,<);
}
void loop() {
!! set the cursor to (G,G):
lcd.setDursor(G, G);
!! print from G to K:
for (int thisDhar % G; thisDhar X +G; thisDhar&&) {
lcd.print(thisDhar);
dela(JGG);
}
!! set the cursor to (+H,+):
lcd.setDursor(+H,+);
!! set the displa to automaticall scroll:
lcd.autoscroll();
!! print from G to K:
for (int thisDhar % G; thisDhar X +G; thisDhar&&) {
lcd.print(thisDhar);
dela(JGG);
}
!! turn off automatic scrolling
+GJ
lcd.noAutoscroll();
!! clear screen for the ne.t loop:
lcd.clear();
}
Li1uid"rystal
lcdCbe)in#$
=pecifies the dimensions (width and height) of the displa.
Syntax' lcd.begin(cols, rows)
%arameters' lcd: a variable of tpe 4i)uidDrstal
cols: the number of columns that the displa has
rows: the number of rows that the displa has
Li1uid"rystal
lcdCblin<#$
Nispla the blinking 4DN cursor. 2f used in combination with the cursor() function, the result
will depend on the particular displa.
Syntax' lcd.blink()
%arameters' lcd: a variable of tpe 4i)uidDrstal
+xample " blink() and noClink()
Li1uid"rystal Library 3 lin(
!"
Nemonstrates the use a +H.< 4DN displa. :he 4i)uidDrstal librar works with all 4DN displas
that are compatible with the 1itachi 1NFFMIG driver. :here are man of them out there, and ou
can usuall tell them b the +H#pin interface.
:his sketch prints T1ello 6orld*T to the 4DN and makes the cursor block blink.

:he circuit:
" 4DN A= pin to digital pin +<
" 4DN Onable pin to digital pin ++
" 4DN NF pin to digital pin J
" 4DN NJ pin to digital pin F
" 4DN NH pin to digital pin B
" 4DN NM pin to digital pin <
" 4DN A!6 pin to ground
" +GE resistor:
" ends to &JL and ground
" wiper to 4DN L5 pin (pin B)
"!
!! include the librar code:
+GH
$include X4i)uidDrstal.hY
!! initiali?e the librar with the numbers of the interface pins
4i)uidDrstal lcd(+<, ++, J, F, B, <);
void setup() {
!! set up the 4DNRs number of columns and rows:
lcd.begin(+H, <);
!! 8rint a message to the 4DN.
lcd.print(Thello, world*T);
}
void loop() {
!! :urn off the blinking cursor:
lcd.noClink();
dela(BGGG);
!! :urn on the blinking cursor:
lcd.blink();
dela(BGGG);
}
Li1uid"rystal
lcdCclear#$
Dlears the 4DN screen and positions the cursor in the upper#left corner.
Syntax' lcd.clear()
%arameters' lcd: a variable of tpe 4i)uidDrstal
Li1uid"rystal
.i0uidCrystal#$
Dreates a variable of tpe 4i)uidDrstal. :he displa can be controlled using F or I data lines. 2f the
former, omit the pin numbers for dG to dB and leave those lines unconnected. :he A6 pin can be
tied to ground instead of connected to a pin on the Arduino; if so, omit it from this functionRs
parameters.
Syntax' 4i)uidDrstal(rs, enable, dF, dJ, dH, dM)
4i)uidDrstal(rs, rw, enable, dF, dJ, dH, dM)
4i)uidDrstal(rs, enable, dG, d+, d<, dB, dF, dJ, dH, dM)
4i)uidDrstal(rs, rw, enable, dG, d+, d<, dB, dF, dJ, dH, dM)
%arameters' rs' the number of the Arduino pin that is connected to the A= pin on the 4DN
rw' the number of the Arduino pin that is connected to the A6 pin on the 4DN
(optional)
+GM
enable' the number of the Arduino pin that is connected to the enable pin on the
4DN
dO, dG, dP, dQ, dR, dS, dH, dA' the numbers of the Arduino pins that are connected to
the corresponding data pins on the 4DN. dG, d+, d<, and dB are optional; if omitted,
the 4DN will be controlled using onl the four data lines (dF, dJ, dH, dM).
+xample
$include X4i)uidDrstal.hY
4i)uidDrstal lcd(+<, ++, +G, J, F, B, <);
void setup()
{
lcd.print(Thello, world*T);
}
void loop() {}
Li1uid"rystal
lcdCcreateChar#$
Dreate a custom character (glph) for use on the 4DN. 9p to eight characters of J.I pi.els are
supported (numbered G to M). :he appearance of each custom character is specified b an arra of
eight btes, one for each row. :he five least significant bits of each bte determine the pi.els in that
row. :o displa a custom character on the screen, write() its number.
Syntax' lcd.createDhar(num, data)
%arameters' lcd: a variable of tpe 4i)uidDrstal
num: which character to create (G to M)
data: the characterRs pi.el data
+xample
$include X4i)uidDrstal.hY
4i)uidDrstal lcd(+<, ++, J, F, B, <);
bte smileUIV % {
CGGGGG,
C+GGG+,
CGGGGG,
CGGGGG,
C+GGG+,
CG+++G,
CGGGGG,
};
void setup() {
lcd.createDhar(G, smile);
lcd.begin(+H, <);
lcd.write(G);
}
void loop() {}
+GI
Li1uid"rystal
lcdCcursor#$
Nispla the 4DN cursor: an underscore (line) at the position to which the ne.t character will be
written.
Syntax' lcd.cursor()
%arameters' lcd: a variable of tpe 4i)uidDrstal
+xample " cursor() and " noDursor()
=E
4i)uidDrstal 4ibrar # Dursor

Nemonstrates the use a +H.< 4DN displa. :he 4i)uidDrstal librar works with all 4DN displas
that are compatible with the 1itachi 1NFFMIG driver. :here are man of them out there, and ou
can usuall tell them b the +H#pin interface.

:his sketch prints T1ello 6orld*T to the 4DN and uses the cursor() and noDursor() methods to turn
on and off the cursor.

:he circuit:
" 4DN A= pin to digital pin +<
" 4DN Onable pin to digital pin ++
" 4DN NF pin to digital pin J
" 4DN NJ pin to digital pin F
" 4DN NH pin to digital pin B
" 4DN NM pin to digital pin <
" 4DN A!6 pin to ground
" +GE resistor:
" ends to &JL and ground
" wiper to 4DN L5 pin (pin B)
"!
$include X4i)uidDrstal.hY
!! initiali?e the librar with the numbers of the interface pins
4i)uidDrstal lcd(+<, ++, J, F, B, <);
void setup() {
!! set up the 4DNRs number of columns and rows:
lcd.begin(+H, <);
lcd.print(Thello, world*T);
}
void loop() {
lcd.noDursor();
dela(JGG);
!! :urn on the cursor:
lcd.cursor();
dela(JGG);
}
+GK
Li1uid"rystal
lcdCdisplay#$
!"
4i)uidDrstal 4ibrar # displa() and noNispla()

Nemonstrates the use a +H.< 4DN displa. :he 4i)uidDrstal librar works with all 4DN displas
that are compatible with the 1itachi 1NFFMIG driver. :here are man of them out there, and ou
can usuall tell them b the +H#pin interface.

:his sketch prints T1ello 6orld*T to the 4DN and uses the displa() and noNispla() functions to
turn on and off the displa.

:he circuit:
" 4DN A= pin to digital pin +<
" 4DN Onable pin to digital pin ++
" 4DN NF pin to digital pin J
" 4DN NJ pin to digital pin F
" 4DN NH pin to digital pin B
" 4DN NM pin to digital pin <
" 4DN A!6 pin to ground
" +GE resistor:
" ends to &JL and ground
" wiper to 4DN L5 pin (pin B)
"!
!! include the librar code:
$include X4i)uidDrstal.hY
!! initiali?e the librar with the numbers of the interface pins
4i)uidDrstal lcd(+<, ++, J, F, B, <);
void setup() {
!! set up the 4DNRs number of columns and rows:
lcd.begin(+H, <);
!! 8rint a message to the 4DN.
lcd.print(Thello, world*T);
}
void loop() {
!! :urn off the displa:
lcd.noNispla();
dela(JGG);
!! :urn on the displa:
lcd.displa();
dela(JGG);
}
++G
Li1uid"rystal
lcdChome#$
8ositions the cursor in the upper#left of the 4DN. :hat is, use that location in outputting subse)uent
te.t to the displa. :o also clear the displa, use the clear() function instead.
Syntax' lcd.home()
%arameters' lcd: a variable of tpe 4i)uidDrstal
Li1uid"rystal
lcdCle!tTo&i)ht#$
=et the direction for te.t written to the 4DN to left#to#right, the default. :his means that subse)uent
characters written to the displa will go from left to right, but does not affect previousl#output te.t.
Syntax' lcd.left:oAight()
%arameters' lcd: a variable of tpe 4i)uidDrstal
Li1uid"rystal
lcdCnoAutoscroll#$
:urns off automatic scrolling of the 4DN.
Syntax' lcd.noAutoscroll()
%arameters' lcd: a variable of tpe 4i)uidDrstal
Li1uid"rystal
lcdCnoBlin<#$
:urns off the blinking 4DN cursor.
Syntax' lcd.noClink()
%arameters' lcd: a variable of tpe 4i)uidDrstal
+xample " blink() and noClink()
Li1uid"rystal
lcdCnoCursor#$
1ides the 4DN cursor.
Syntax' lcd.noDursor()
+++
%arameters lcd: a variable of tpe 4i)uidDrstal
+xample " cursor() and noDursor()
Li1uid"rystal
lcdCnoDisplay#$
:urns off the 4DN displa, without losing the te.t currentl shown on it.
Syntax' lcd.noNispla()
%arameters' lcd: a variable of tpe 4i)uidDrstal
+xample " displa() and noNispla()
Li1uid"rystal
lcdCprint#$
8rints te.t to the 4DN.
Syntax' lcd.print(data)
lcd.print(data, CA=O)
%arameters' lcd: a variable of tpe 4i)uidDrstal
data: the data to print (char, bte, int, long, or string)
CA=O (optional): the base in which to print numbers: C27 for binar (base <), NOD
for decimal (base +G), 5D: for octal (base I), 1OQ for he.adecimal (base +H).
&eturns' bte
print() will return the number of btes written, though reading that number is
optional
+xample
$include X4i)uidDrstal.hY
4i)uidDrstal lcd(+<, ++, +G, J, F, B, <);
void setup()
{
lcd.print(Thello, world*T);
}
void loop() {}
++<
Li1uid"rystal
lcdCri)htTo.e!t#$
=et the direction for te.t written to the 4DN to right#to#left (the default is left#to#right). :his means
that subse)uent characters written to the displa will go from right to left, but does not affect
previousl#output te.t.
Syntax' lcd.right:o4eft()
%arameters' lcd: a variable of tpe 4i)uidDrstal
Li1uid"rystal
lcdCscrollDisplay.e!t#$
=crolls the contents of the displa (te.t and cursor) one space to the left.
Syntax' lcd.scrollNispla4eft()
%arameters' lcd: a variable of tpe 4i)uidDrstal
+xample
!"
4i)uidDrstal 4ibrar # scrollNispla4eft() and scrollNisplaAight()

Nemonstrates the use a +H.< 4DN displa. :he 4i)uidDrstal librar works with all 4DN displas
that are compatible with the 1itachi 1NFFMIG driver. :here are man of them out there, and ou
can usuall tell them b the +H#pin interface.
:his sketch prints T1ello 6orld*T to the 4DN and uses the scrollNispla4eft() and
scrollNisplaAight() methods to scroll the te.t.

:he circuit:
" 4DN A= pin to digital pin +<
" 4DN Onable pin to digital pin ++
" 4DN NF pin to digital pin J
" 4DN NJ pin to digital pin F
" 4DN NH pin to digital pin B
" 4DN NM pin to digital pin <
" 4DN A!6 pin to ground
" +GE resistor:
" ends to &JL and ground
" wiper to 4DN L5 pin (pin B)
"!
!! include the librar code:
$include X4i)uidDrstal.hY
!! initiali?e the librar with the numbers of the interface pins
4i)uidDrstal lcd(+<, ++, J, F, B, <);
void setup() {
!! set up the 4DNRs number of columns and rows:
lcd.begin(+H, <);
++B
!! 8rint a message to the 4DN.
lcd.print(Thello, world*T);
dela(+GGG);
}
void loop() {
!! scroll +B positions (string length) to the left
!! to move it offscreen left:
for (int positionDounter % G; positionDounter X +B; positionDounter&&) {
!! scroll one position left:
lcd.scrollNispla4eft();
!! wait a bit:
dela(+JG);
}
!! scroll <K positions (string length & displa length) to the right
!! to move it offscreen right:
for (int positionDounter % G; positionDounter X <K; positionDounter&&) {
!! scroll one position right:
lcd.scrollNisplaAight();
!! wait a bit:
dela(+JG);
}
!! scroll +H positions (displa length & string length) to the left
!! to move it back to center:
for (int positionDounter % G; positionDounter X +H; positionDounter&&) {
!! scroll one position left:
lcd.scrollNispla4eft();
!! wait a bit:
dela(+JG);
}
!! dela at the end of the full loop:
dela(+GGG);
}
Li1uid"rystal
lcdCscrollDisplay&i)ht#$
=crolls the contents of the displa (te.t and cursor) one space to the right.
Syntax' lcd.scrollNisplaAight()
%arameters' lcd: a variable of tpe 4i)uidDrstal
+xample scrollNispla4eft() and scrollNisplaAight()
++F
Li1uid"rystal
lcdCsetCursor#$
8osition the 4DN cursor; that is, set the location at which subse)uent te.t written to the 4DN will
be displaed.
Syntax' lcd.setDursor(col, row)
%arameters' lcd: a variable of tpe 4i)uidDrstal
col: the column at which to position the cursor (with G being the first column)
row: the row at which to position the cursor (with G being the first row)
+xample
!"
4i)uidDrstal 4ibrar # setDursor

Nemonstrates the use a +H.< 4DN displa. :he 4i)uidDrstal librar works with all 4DN displas
that are compatible with the 1itachi 1NFFMIG driver. :here are man of them out there, and ou
can usuall tell them b the +H#pin interface.

:his sketch prints to all the positions of the 4DN using the setDursor(G method:

:he circuit:
" 4DN A= pin to digital pin +<
" 4DN Onable pin to digital pin ++
" 4DN NF pin to digital pin J
" 4DN NJ pin to digital pin F
" 4DN NH pin to digital pin B
" 4DN NM pin to digital pin <
" 4DN A!6 pin to ground
" +GE resistor:
" ends to &JL and ground
" wiper to 4DN L5 pin (pin B)
"!
!! include the librar code:
$include X4i)uidDrstal.hY
!! these constants wonRt change. Cut ou can change the si?e of
!! our 4DN using them:
const int numAows % <;
const int numDols % +H;
!! initiali?e the librar with the numbers of the interface pins
4i)uidDrstal lcd(+<, ++, J, F, B, <);
void setup() {
!! set up the 4DNRs number of columns and rows:
lcd.begin(numDols,numAows);
}
void loop() {
++J
!! loop from A=D22 RaR to A=D22 R?R:
for (int this4etter % RaR; this4etter X% R?R; this4etter&&) {
!! loop over the columns:
for (int thisDol % G; thisDol X numAows; thisDol&&) {
!! loop over the rows:
for (int thisAow % G; thisAow X numDols; thisAow&&) {
!! set the cursor position:
lcd.setDursor(thisAow,thisDol);
!! print the letter:
lcd.write(this4etter);
dela(<GG);
}
}
}
}
Li1uid"rystal
lcdCwrite#$
6rite a character to the 4DN.
Syntax' lcd.write(data)
%arameters' lcd: a variable of tpe 4i)uidDrstal
data: the character to write to the displa
&eturns' bte
write() will return the number of btes written, though reading that number is
optional
+xample
$include X4i)uidDrstal.hY
4i)uidDrstal lcd(+<, ++, +G, J, F, B, <);
void setup()
{
=erial.begin(KHGG);
}
void loop()
{
if (=erial.available()) {
lcd.write(=erial.read());
}
}
++H
lon)#$
Donverts a value to the long data tpe.
Syntax' long(.)
%arameters' .: a value of an tpe
&eturns' long
lon)
4ong variables are e.tended si?e variables for number storage, and store B< bits (F btes), from
#<,+FM,FIB,HFI to <,+FM,FIB,HFM.
Syntax' long var % val;
o var # the long variable name
o val # the value assigned to the variable
loop#$
After creating a setup() function, which initiali?es and sets the initial values, the loop() function
does precisel what its name suggests, and loops consecutivel, allowing our program to change
and respond. 9se it to activel control the Arduino board.
+xample
int button8in % B;
!! setup initiali?es serial and the button pin
void setup()
{
begin=erial(KHGG);
pin@ode(button8in, 2789:);
}
!! loop checks the button pin each time,
!! and will send serial if it is pressed
void loop()
{
if (digitalAead(button8in) %% 1231)
serial6rite(R1R);
else
serial6rite(R4R);
dela(+GGG);
}
++M
lo-yte)*
O.tracts the low#order (rightmost) bte of a variable (e.g. a word).
Syntax' lowCte(.)
%arameters' .: a value of an tpe
&eturns' bte
map#value, !rom.ow, !rom7i)h, to.ow, to7i)h$
Ae#maps a number from one range to another. :hat is, a value of from4ow would get mapped to
to4ow, a value of from1igh to to1igh, values in#between to values in#between, etc.
Noes not constrain values to within the range, because out#of#range values are sometimes intended
and useful. :he constrain() function ma be used either before or after this function, if limits to the
ranges are desired.
7ote that the Tlower boundsT of either range ma be larger or smaller than the Tupper boundsT so
the map() function ma be used to reverse a range of numbers, for e.ample
% map(., +, JG, JG, +);
:he function also handles negative numbers well, so that this e.ample
% map(., +, JG, JG, #+GG);
is also valid and works well.
:he map() function uses integer math so will not generate fractions, when the math might indicate
that it should do so. Practional remainders are truncated, and are not rounded or averaged.
%arameters' value: the number to map
from4ow: the lower bound of the valueRs current range
from1igh: the upper bound of the valueRs current range
to4ow: the lower bound of the valueRs target range
to1igh: the upper bound of the valueRs target range
&eturns' :he mapped value.
+xample
!" @ap an analog value to I bits (G to <JJ) "!
void setup() {}
void loop()
{
int val % analogAead(G);
val % map(val, G, +G<B, G, <JJ);
analog6rite(K, val);
}
++I
A!!endi,
Por the mathematicall inclined, hereRs the whole function
long map(long ., long in;min, long in;ma., long out;min, long out;ma.)
{
return (. # in;min) " (out;ma. # out;min) ! (in;ma. # in;min) & out;min;
}
max#x, y$
Dalculates the ma.imum of two numbers.
%arameters' .: the first number, an data tpe
: the second number, an data tpe
&eturns' :he larger of the two parameter values.
+xample sensLal % ma.(senLal, <G); !! assigns sensLal to the larger of sensLal or <G
!! (effectivel ensuring that it is at least <G)
*ote' 8erhaps counter#intuitivel, ma.() is often used to constrain the lower end of a
variableRs range, while min() is used to constrain the upper end of the range.
(arnin)99 Cecause of the wa the ma.() function is implemented, avoid using other functions
inside the brackets, it ma lead to incorrect results
ma.(a##, G); !! avoid this # ields incorrect results
a##; !! use this instead #
ma.(a, G); !! keep other math outside the function
micros#$
Aeturns the number of microseconds since the Arduino board began running the current program.
:his number will overflow (go back to ?ero), after appro.imatel MG minutes. 5n +H @1? Arduino
boards (e.g. Nuemilanove and 7ano), this function has a resolution of four microseconds (i.e. the
value returned is alwas a multiple of four). 5n I @1? Arduino boards (e.g. the 4il8ad), this
function has a resolution of eight microseconds.
%arameters' 7one
&eturns' 7umber of microseconds since the program started (unsigned long)
+xample
unsigned long time;
void setup(){
=erial.begin(KHGG);
}
void loop(){
=erial.print(T:ime: T);
++K
time % micros();
!!prints time since program started
=erial.println(time);
!! wait a second so as not to send massive amounts of data
dela(+GGG);
}
millis#$
Aeturns the number of milliseconds since the Arduino board began running the current program.
:his number will overflow (go back to ?ero), after appro.imatel JG das.
%arameters' 7one
&eturns' 7umber of milliseconds since the program started (unsigned long)
+xample
unsigned long time;
void setup(){
=erial.begin(KHGG);
}
void loop(){
=erial.print(T:ime: T);
time % millis();
!!prints time since program started
=erial.println(time);
!! wait a second so as not to send massive amounts of data
dela(+GGG);
}
Tip' 7ote that the parameter for millis is an unsigned long, errors ma be generated if a
programmer tries to do math with other datatpes such as ints.
min#x, y$
Dalculates the minimum of two numbers.
%arameters' .: the first number, an data tpe
: the second number, an data tpe
&eturns' :he smaller of the two numbers.
+xamples
sensLal % min(sensLal, +GG); !! assigns sensLal to the smaller of sensLal or +GG
!! ensuring that it never gets above +GG.
*ote' 8erhaps counter#intuitivel, ma.() is often used to constrain the lower end of a
variableRs range, while min() is used to constrain the upper end of the range.
+<G
(arnin)99 Cecause of the wa the min() function is implemented, avoid using other functions
inside the brackets, it ma lead to incorrect results
min(a&&, +GG); !! avoid this # ields incorrect results
a&&;
min(a, +GG); !! use this instead # keep other math outside the function
T #modulo$
Dalculates the remainder when one integer is divided b another. 2t is useful for keeping a variable
within a particular range (e.g. the si?e of an arra).
Syntax' result % dividend ( divisor
%arameters' dividend: the number to be divided
divisor: the number to divide b
&eturns' the remainder
+xamples
. % M ( J; !! . now contains <
. % K ( J; !! . now contains F
. % J ( J; !! . now contains G
. % F ( J; !! . now contains F
+xample Code
!" update one value in an arra each time through a loop "!
int valuesU+GV;
int i % G;
void setup() {}
void loop()
{
valuesUiV % analogAead(G);
i % (i & +) ( +G; !! modulo operator rolls over variable
}
(arnin)99 :he modulo operator does not work on floats.
+<+
MouseLeyboard
-ouseCbe)in#$
Cegins emulating the mouse connected to a computer. begin() must be called before controlling the
computer. :o end control, use @ouse.end().
Syntax' @ouse.begin()
%arameters' none
&eturns' nothing
+xample
void setup(){
pin@ode(<, 2789:);
}
void loop(){
!!initiate the @ouse librar when button is pressed
if(digitalAead(<) %% 1231){
@ouse.begin();
}
}
Mouse0eyboard
-ouseCclic<#$
=ends a momentar click to the computer at the location of the cursor. :his is the same as pressing
and immediatel releasing the mouse button.
@ouse.click() defaults to the left mouse button.
(A&*1*>' 6hen ou use the @ouse.click() command, the Arduino takes over our mouse*
@ake sure ou have control before ou use the command. A pushbutton to toggle the
mouse control state is effective.
Syntax' @ouse.click();
@ouse.click(button);
%arameters' button: which mouse button to press # char
o @59=O;4OP: (default)
o @59=O;A231:
o @59=O;@2NN4O
&eturns' nothing
+xample
void setup(){
pin@ode(<,2789:);
!!initiate the @ouse librar
+<<
@ouse.begin();
}
void loop(){
!!if the button is pressed, send a Aight mouse click
if(digitalAead(<) %% 1231){
@ouse.click();
}
}
Mouse0eyboard
-ouseCend#$
=tops emulating the mouse connected to a computer. :o start control, use @ouse.begin().
Syntax' @ouse.end()
%arameters' none
&eturns' nothing
+xample
void setup(){
pin@ode(<,2789:);
!!initiate the @ouse librar
@ouse.begin();
}
void loop(){
!!if the button is pressed, send a Aight mouse click
!!then end the @ouse emulation
if(digitalAead(<) %% 1231){
@ouse.click();
@ouse.end();
}
}
Mouse
-ouseCis%ressed#$
Dhecks the current status of all mouse buttons, and reports if an are pressed or not.
Syntax' @ouse.is8ressed();
@ouse.is8ressed(button);
%arameters' 6hen there is no value passed, it checks the status of the left mouse button.
button: which mouse button to check # char
@59=O;4OP: (default)
@59=O;A231:
@59=O;@2NN4O
+<B
&eturns' boolean : reports wether a button is pressed or not
+xample
void setup(){
!!:he switch that will initiate the @ouse press
pin@ode(<,2789:);
!!:he switch that will terminate the @ouse press
pin@ode(B,2789:);
!!=tart serial communication with the computer
=erial+.begin(KHGG);
!!initiate the @ouse librar
@ouse.begin();
}
void loop(){
!!a variable for checking the buttonRs state
int mouse=tate%G;
!!if the switch attached to pin < is closed, press and hold the right mouse button and save
the state ina variable
if(digitalAead(<) %% 1231){
@ouse.press();
mouse=tate%@ouse.is8ressed();
}
!!if the switch attached to pin B is closed, release the right mouse button and save the state
in a variable
if(digitalAead(B) %% 1231){
@ouse.release();
mouse=tate%@ouse.is8ressed();
}
!!print out the current mouse button state
=erial+.println(mouse=tate);
dela(+G);
}
Mouse0eyboard
-ouseCmove#$
@oves the cursor on a connected computer. :he motion onscreen is alwas relative to the cursorRs
current location. Cefore using @ouse.move() ou must call @ouse.begin()
(A&*1*>999 6hen ou use the @ouse.move() command, the Arduino takes over our mouse*
@ake sure ou have control before ou use the command. A pushbutton to toggle
the mouse control state is effective.
Syntax' @ouse.move(.Lal, 8os, wheel);
%arameters' .Lal: amount to move along the .#a.is # int
Lal: amount to move along the #a.is # int
wheel: amount to move scroll wheel # int
+<F
&eturns' nothing
+xample
const int .A.is % A+; !!analog sensor for Q a.is
const int A.is % A<; !! analog sensor for S a.is
int range % +<; !! output range of Q or S movement
int responseNela % <; !! response dela of the mouse, in ms
int threshold % range!F; !! resting threshold
int center % range!<; !! resting position value
int minimaUV % {+G<B, +G<B}; !! actual analogAead minima for {., }
int ma.imaUV % {G,G}; !! actual analogAead ma.ima for {., }
int a.isUV % {.A.is, A.is}; !! pin numbers for {., }
int mouseAeadingU<V; !! final mouse readings for {., }
void setup() {
@ouse.begin();
}
void loop() {
!! read and scale the two a.es:
int .Aeading % readA.is(G);
int Aeading % readA.is(+);
!! move the mouse:
@ouse.move(.Aeading, Aeading, G);
dela(responseNela);
}
!"
reads an a.is (G or + for . or ) and scales the
analog input range to a range from G to XrangeY
"!
int readA.is(int a.is7umber) {
int distance % G; !! distance from center of the output range
!! read the analog input:
int reading % analogAead(a.isUa.is7umberV);
!! of the current reading e.ceeds the ma. or min for this a.is,
!! reset the ma. or min:
if (reading X minimaUa.is7umberV) {
minimaUa.is7umberV % reading;
}
if (reading Y ma.imaUa.is7umberV) {
ma.imaUa.is7umberV % reading;
}
!! map the reading from the analog input range to the output range:
reading % map(reading, minimaUa.is7umberV, ma.imaUa.is7umberV, G, range);
+<J
!! if the output reading is outside from the
!! rest position threshold, use it:
if (abs(reading # center) Y threshold) {
distance % (reading # center);
}
!! the S a.is needs to be inverted in order to
!! map the movemment correctl:
if (a.is7umber %% +) {
distance % #distance;
}
!! return the distance for this a.is:
return distance;
}
Mouse0eyboard
-ouseCpress#$
=ends a button press to a connected computer. A press is the e)uivalent of clicking and
continuousl holding the mouse button. A press is cancelled with @ouse.release().
Cefore using @ouse.press(), ou need to start communication with @ouse.begin().
@ouse.press() defaults to a left button press.
(A&*1*>9 6hen ou use the @ouse.press() command, the Arduino takes over our mouse*
@ake sure ou have control before ou use the command. A pushbutton to toggle the
mouse control state is effective.
Syntax' @ouse.press();
@ouse.press(button)
%arameters' button: which mouse button to press # char
@59=O;4OP: (default)
@59=O;A231:
@59=O;@2NN4O
&eturns' nothing
+xample
void setup(){
!!:he switch that will initiate the @ouse press
pin@ode(<,2789:);
!!:he switch that will terminate the @ouse press
pin@ode(B,2789:);
!!initiate the @ouse librar
@ouse.begin();
}
void loop(){
!!if the switch attached to pin < is closed, press and hold the right mouse button
+<H
if(digitalAead(<) %% 1231){
@ouse.press();
}
!!if the switch attached to pin B is closed, release the right mouse button
if(digitalAead(B) %% 1231){
@ouse.release();
}
}
Mouse0eyboard
-ouseCrelease#$
=ends a message that a previousl pressed button (invoked through @ouse.press()) is released.
@ouse.release() defaults to the left button.
(A&*1*>9 6hen ou use the @ouse.release() command, the Arduino takes over our mouse*
@ake sure ou have control before ou use the command. A pushbutton to toggle the
mouse control state is effective.
Syntax' @ouse.release();
@ouse.release(button);
%arameters' button: which mouse button to press # char
@59=O;4OP: (default)
@59=O;A231:
@59=O;@2NN4O
&eturns' nothing
+xample
void setup(){
!!:he switch that will initiate the @ouse press
pin@ode(<,2789:);
!!:he switch that will terminate the @ouse press
pin@ode(B,2789:);
!!initiate the @ouse librar
@ouse.begin();
}
void loop(){
!!if the switch attached to pin < is closed, press and hold the right mouse button
if(digitalAead(<) %% 1231){
@ouse.press();
}
!!if the switch attached to pin B is closed, release the right mouse button
if(digitalAead(B) %% 1231){
@ouse.release();
}
}
+<M
*ew%in) library
Features
6orks with man different ultrasonic sensor models: =AGF, =APGJ, =APGH, NS8#@OGGM
' 8aralla. 8273)))`.
2nterface with all but the =APGH sensor using onl one Arduino pin.
NoesnRt lag for a full second if no ping!echo is received.
8ing sensors consistentl and reliabl at up to BG times per second.
:imer interrupt method for event#driven sketches.
Cuilt#in digital filter method ping;median() for eas error correction.
9ses port registers when accessing pins for faster e.ecution and smaller code si?e.
Allows setting of a ma.imum distance where pings beond that distance are read as no ping
TclearT.
Oase of using multiple sensors (e.ample sketch with +J sensors).
@ore accurate distance calculation (cm, inches ' u=).
NoesnRt use pulse2n, which is slow and gives incorrect results with some ultrasonic sensor
models.
Activel developed with features being added and bugs!issues addressed.
Constructor
7ew8ing sonar(trigger;pin, echo;pin U, ma.;cm;distanceV);
+xample'
7ew8ing sonar(+<, ++, <GG);
:his initiali?es 7ew8ing to use pin +< for trigger output, pin ++ for echo input, with a ma.imum
ping distance of <GGcm. ma.;cm;distance is optional Udefault % JGGcmV.
-ethods
sonar.ping(); =end a ping, returns the echo time in microseconds or G (?ero) if
no ping echo within set distance limit
sonar.ping;in(); =end a ping, returns the distance in inches or G (?ero) if no ping
echo within set distance limit
sonar.ping;cm(); =end a ping, returns the distance in centimeters or G (?ero) if no
ping echo within set distance limit
sonar.ping;median(iterations); No multiple pings (default%J), discard out of range pings and
return median in microseconds
sonar.convert;in(echo:ime); Donverts microseconds to distance in inches
sonar.convert;cm(echo:ime); Donverts microseconds to distance in centimeters
sonar.ping;timer(function); =end a ping and call function to test if ping is complete.
sonar.check;timer(); Dheck if ping has returned within the set distance limit.
timer;us(fre)uenc, function); Dall function ever fre)uenc microseconds.
timer;ms(fre)uenc, function); Dall function ever fre)uenc milliseconds.
timer;stop(); # =top the timer.
+<I
+xample'
$include X7ew8ing.hY
$define :A233OA;827 +<
$define OD15;827 ++
$define @AQ;N2=:A7DO <GG
7ew8ing sonar(:A233OA;827, OD15;827, @AQ;N2=:A7DO);
void setup() {
=erial.begin(++J<GG);
}
void loop() {
int u= % sonar.ping();
=erial.print(T8ing: T);
=erial.print(u= ! 9=;A597N:A28;D@);
=erial.println(TcmT);
dela(JG);
}
!! ######################################################################################################################
!! :his e.ample code was used to successfull communicate with +J ultrasonic sensors. Sou can
!! ad>ust the number of sensors in our pro>ect b changing =57AA;79@ and the number of
!! 7ew8ing ob>ects in the TsonarT arra. Sou also need to change the pins for each sensor for the
!! 7ew8ing ob>ects. Oach sensor is pinged at BBms intervals. =o, one ccle of all sensors takes
!! FKJms (BB " +J % FKJms). :he results are sent to the Tone=ensorDcleT function which currentl
!! >ust displas the distance data. Sour pro>ekt would normall process the sensor results in this
!! function (for e.ample, decide if a robot needs to turn and call the turn function). Eeep in mind
!! this e.ample is event#driven. Sour complete sketch needs to be written so thereRs no TdelaT
!! commands and the loop() ccles at faster than a BBms rate. 2f other processes take longer than
!! BBms, ouRll need to increase 8273;27:OALA4 so it doesnRt get behind.
!! ######################################################################################################################
$include X7ew8ing.hY
$define =57AA;79@ +J !! 7umber or sensors.
$define @AQ;N2=:A7DO <GG !! @a. distance in cm.
$define 8273;27:OALA4 BB !! @illiseconds between pings.
unsigned long ping:imerU=57AA;79@V; !! 6hen each pings.
unsigned int cmU=57AA;79@V; !! =tore ping distances.
uintI;t current=ensor % G; !! 6hich sensor is active.
7ew8ing sonarU=57AA;79@V % { !! =ensor ob>ect arra.
7ew8ing(F+, F<, @AQ;N2=:A7DO),
7ew8ing(FB, FF, @AQ;N2=:A7DO),
7ew8ing(FJ, <G, @AQ;N2=:A7DO),
7ew8ing(<+, <<, @AQ;N2=:A7DO),
7ew8ing(<B, <F, @AQ;N2=:A7DO),
7ew8ing(<J, <H, @AQ;N2=:A7DO),
+<K
7ew8ing(<M, <I, @AQ;N2=:A7DO),
7ew8ing(<K, BG, @AQ;N2=:A7DO),
7ew8ing(B+, B<, @AQ;N2=:A7DO),
7ew8ing(BF, BB, @AQ;N2=:A7DO),
7ew8ing(BJ, BH, @AQ;N2=:A7DO),
7ew8ing(BM, BI, @AQ;N2=:A7DO),
7ew8ing(BK, FG, @AQ;N2=:A7DO),
7ew8ing(JG, J+, @AQ;N2=:A7DO),
7ew8ing(J<, JB, @AQ;N2=:A7DO)
};
void setup() {
=erial.begin(++J<GG);
ping:imerUGV % millis() & MJ; !! Pirst ping start in ms.
for (uintI;t i % +; i X =57AA;79@; i&&)
ping:imerUiV % ping:imerUi # +V & 8273;27:OALA4;
}
void loop() {
for (uintI;t i % G; i X =57AA;79@; i&&) {
if (millis() Y% ping:imerUiV) {
ping:imerUiV &% 8273;27:OALA4 " =57AA;79@;
if (i %% G '' current=ensor %% =57AA;79@ # +)
one=ensorDcle(); !! No something with results.
sonarUcurrent=ensorV.timer;stop();
current=ensor % i;
cmUcurrent=ensorV % G;
sonarUcurrent=ensorV.ping;timer(echoDheck);
}
}
!! :he rest of our code would go here.
}
void echoDheck() { !! 2f ping echo, set distance to arra.
if (sonarUcurrent=ensorV.check;timer())
cmUcurrent=ensorV % sonarUcurrent=ensorV.ping;result ! 9=;A597N:A28;D@;
}
void one=ensorDcle() { !! No something with the results.
for (uintI;t i % G; i X =57AA;79@; i&&) {
=erial.print(i);
=erial.print(T%T);
=erial.print(cmUiV);
=erial.print(Tcm T);
}
=erial.println();
}
+BG
no1nterrupts#$
Nisables interrupts (ou can re#enable them with interrupts()). 2nterrupts allow certain important
tasks to happen in the background and are enabled b default. =ome functions will not work while
interrupts are disabled, and incoming communication ma be ignored. 2nterrupts can slightl disrupt
the timing of code, however, and ma be disabled for particularl critical sections of code.
%arameters' 7one
&eturns' 7one
+xample
void setup() {}
void loop()
{
no2nterrupts();
!! critical, time#sensitive code here
interrupts();
!! other code here
}
noTone#$
=tops the generation of a s)uare wave triggered b tone(). 1as no effect if no tone is being
generated.
*OT+' if ou want to pla different pitches on multiple pins, ou need to call no:one() on
one pin before calling tone() on the ne.t pin.
Syntax' no:one(pin)
%arameters' pin: the pin on which to stop generating the tone
&eturns' nothing
+B+
OneB(ire %rotocol
(:his page still needs some more generalisation to +#6ire, as some code is specific to Tusing the
N=+I<GT and a specifc 4DN. 2t also needs a cleaning of the librar paragraph that includes
references to older versions of libraries.)
Nallas =emiconductor (now @a.im) produces a famil of devices that are controlled through a
proprietar +#wire protocol. :here are no fees for programmers using the Nallas +#6ire (trademark)
drivers.
5n a +#6ire network, which Nallas has dubbed a T@icro4anT (trademark), a single TmasterT device
communicates with one or more +#6ire TslaveT devices over a single data line, which can also be
used to provide power to the slave devices. (Nevices drawing power from the +#wire bus are said to
be operating in parasitic power mode.) http:!!sheepdogguides.com!arduino!asw+onew+.htm :om
CodRs guide to +#6ire ma tell ou more than ou want to know... but it ma also answer
)uestions and inspire interest.
:he +#wire temperature sensors have become particularl popular, because theRre ine.pensive and
eas to use, providing calibrated digital temperature readings directl. :he are more tolerant of
long wires between sensor and Arduino. :he sample code below demonstrates how to interface with
a +#wire device using Wim =tudtRs 5ne6ire Arduino librar, with the N=+I=<G digital thermometer
as an e.ample. @an +#6ire chips can operate in both parasitic and normal power modes.
@icro4ans can be accessed directl b an Arduino, using the mature Arduino 5ne6ire librar.
Alternativel, the can be accessed through an interface which costs a little mone, but reduces the
workload inside the Arduino. :he interface cost aI in kit form at <!<G+G. :here is a guide to using it
from an independent source.
%owerin) One(ire devices
:he chip can be powered two was. 5ne (the TparasiticT option) means that onl two wires need go
to the chip. :he other ma, in some cases, give more reliable operation (parasitic often works well),
as an e.tra wire carring the power for the chip is involved. Por getting started, especiall if our
chip is within <G feet of our Arduino, the parasitic option is probabl fine. :he code below works
for either option, anwa.
%arasite power mode
6hen operating in parasite power mode, onl two wires are re)uired: one data wire, and ground. At
the master, a F.Mk pull#up resistor must be connected to the +#wire bus. 6hen the line is in a ThighT
state, the device pulls current to charge an internal capacitor.
:his current is usuall ver small, but ma go as high as +.J mA when doing a temperature
conversion or writing OO8A5@. 6hen a slave device is performing one these operations, the bus
master must keep the bus pulled high to provide power until the operation completes; a dela of
MJGms is re)uired for a N=+I=<G temperature conversion. :he master canRt do anthing during this
time, like issuing commands to other devices, or polling for the slaveRs operation to be completed.
:o support this, the 5ne6ire librar makes it possible to have the bus held high after the data is
written.
*ormal #external supply$ mode
+B<
6ith an e.ternal suppl, three wires are re)uired: the bus wire, ground, and power. :he F.Mk pull#
up resistor is still re)uired on the bus wire. As the bus is free for data transfer, the microcontroller
can continuall poll the state of a device doing a conversion. :his wa, a conversion re)uest can
finish as soon as the device reports being done, as opposed to having to wait MJGms in TparasiteT
power mode.
*ote on resistors'
Por larger networks, ou can tr smaller resistors.
:he A:megaB<I!+HI datasheet indicates starting at +kH and a number of users have found smaller
to work better on larger networks.
Addressin) a One(ire device
Oach +#6ire device contains a uni)ue HF#bit RromR code, consisting of an I#bit famil code, a FI#bit
serial number, and an I#bit DAD. :he DAD is used to verif the integrit of the data. Por e.ample,
the sample code, below, checks if the device being addressed is a N=+I=<G temperature sensor b
checking for its famil code, G.+G. :o use the sample code with the newer N=+IC<G sensor, ouRd
check for a famil code of G.<I, instead, and for the N=+I<< ouRd check for G.<<.
Cefore sending a command to a slave device, the master must first select that device using its rom
code. Alternativel, ou can address a command to all slave devices b issuing a Rskip romR
command (G., instead. :his is onl safe if ou are sure there is onl one slave device on the
@icro4A7. for commands that donRt elicit a response from the slave devices # data collision will
occur if data is re)uested from more than one slave.
+xample code
$include X5ne6ire.hY
!! N=+I=<G :emperature chip i!o
5ne6ire ds(+G); !! on pin +G
void setup(void) {
!! initiali?e inputs!outputs
!! start serial port
=erial.begin(KHGG);
}
void loop(void) {
bte i;
bte present % G;
bte dataU+<V;
bte addrUIV;
if ( *ds.search(addr)) {
=erial.print(T7o more addresses.\nT);
ds.reset;search();
return;
}
=erial.print(TA%T);
+BB
for( i % G; i X I; i&&) {
=erial.print(addrUiV, 1OQ);
=erial.print(T T);
}
if ( 5ne6ire::crcI( addr, M) *% addrUMV) {
=erial.print(TDAD is not valid*\nT);
return;
}
if ( addrUGV %% G.+G) {
=erial.print(TNevice is a N=+I=<G famil device.\nT);
}
else if ( addrUGV %% G.<I) {
=erial.print(TNevice is a N=+IC<G famil device.\nT);
}
else {
=erial.print(TNevice famil is not recogni?ed: G.T);
=erial.println(addrUGV,1OQ);
return;
}
ds.reset();
ds.select(addr);
ds.write(G.FF,+); !! start conversion, with parasite power on at the end
dela(+GGG); !! mabe MJGms is enough, mabe not
!! we might do a ds.depower() here, but the reset will take care of it.
present % ds.reset();
ds.select(addr);
ds.write(G.CO); !! Aead =cratchpad
=erial.print(T8%T);
=erial.print(present,1OQ);
=erial.print(T T);
for ( i % G; i X K; i&&) { !! we need K btes
dataUiV % ds.read();
=erial.print(dataUiV, 1OQ);
=erial.print(T T);
}
=erial.print(T DAD%T);
=erial.print( 5ne6ire::crcI( data, I), 1OQ);
=erial.println();
}
Convertin) 7+5 to somethin) meanin)!ul #Temperature$
In order to convert the #$% code to a temperature value, first you need to identify if you are using
a D&'(&)*, or D&'(+)* series sensor. The code to read the temperature needs to be slightly
different for the D&'(+)* ,and D&'())-, because it returns a ').bit temperature value ,*.*/)0 deg
precision-, while the D&'(&)* and D&'()* return 1.bit values ,*.0 deg precision-.
+BF
2irst off, you need to define some variables, ,put right under loop,- above-
int 1ighCte, 4owCte, :Aeading, =ignCit, :c;+GG, 6hole, Pract;
Then for a D&'(+)* series you will add the following code below the &erial.println,-3 above
4owCte % dataUGV;
1ighCte % dataU+V;
:Aeading % (1ighCte XX I) & 4owCte;
=ignCit % :Aeading ' G.IGGG; !! test most sig bit
if (=ignCit) !! negative
{
:Aeading % (:Aeading - G.ffff) & +; !! <Rs comp
}
:c;+GG % (H " :Aeading) & :Aeading ! F; !! multipl b (+GG " G.GH<J) or H.<J
6hole % :c;+GG ! +GG; !! separate off the whole and fractional portions
Pract % :c;+GG ( +GG;
if (=ignCit) !! 2f its negative
{
=erial.print(T#T);
}
=erial.print(6hole);
=erial.print(T.T);
if (Pract X +G)
{
=erial.print(TGT);
}
=erial.print(Pract);
=erial.print(T\nT);
This bloc< o! code converts the temperature to de) C and prints it to the Serial outputC
A Code Snippet !or the DS GIPO with OCS De)ree &esolution
Above e.ample works onl for the C#tpe of the N=+I<G. 1ere is a code e.ample that works with
the lower resolution N=+I<G and with multiple sensors diplaing their values on a 4DN. O.ample is
working with Arduino pin K. Peel free to change that to an appropriate pin for our use. 8in + and B
of the N=+I<G has to be put to ground* 2n the e.ample a Jk resistor is put from pin < of N=+I<G to
Lcc (&JL). =ee 4i)uidDrstal documentation for connecting the 4DN to the Arduino.
$include X5ne6ire.hY
$include X4i)uidDrstal.hY
!! 4DN%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
!!initiali?e the librar with the numbers of the interface pins
4i)uidDrstal lcd(+<, ++, J, F, B, <);
$define 4DN;62N:1 <G
$define 4DN;1O231: <
+BJ
!" N=+I=<G :emperature chip i!o "!
5ne6ire ds(K); !! on pin K
$define @AQ;N=+I<G;=O7=5A= <
bte addrU@AQ;N=+I<G;=O7=5A=VUIV;
void setup(void)
{
lcd.begin(4DN;62N:1, 4DN;1O231:,+);
lcd.setDursor(G,G);
lcd.print(TN=+I<G :estT);
if (*ds.search(addrUGV))
{
lcd.setDursor(G,G);
lcd.print(T7o more addresses.T);
ds.reset;search();
dela(<JG);
return;
}
if ( *ds.search(addrU+V))
{
lcd.setDursor(G,G);
lcd.print(T7o more addresses.T);
ds.reset;search();
dela(<JG);
return;
}
}
int 1ighCte, 4owCte, :Aeading, =ignCit, :c;+GG, 6hole, Pract;
char bufU<GV;
void loop(void)
{
bte i, sensor;
bte present % G;
bte dataU+<V;
for (sensor%G;sensorX@AQ;N=+I<G;=O7=5A=;sensor&&)
{
if ( 5ne6ire::crcI( addrUsensorV, M) *% addrUsensorVUMV)
{
lcd.setDursor(G,G);
lcd.print(TDAD is not validT);
return;
}
if ( addrUsensorVUGV *% G.+G)
{
lcd.setDursor(G,G);
lcd.print(TNevice is not a N=+I=<G famil device.T);
return;
}
+BH
ds.reset();
ds.select(addrUsensorV);
ds.write(G.FF,+); !! start conversion, with parasite power on at the end
dela(+GGG); !! mabe MJGms is enough, mabe not
!! we might do a ds.depower() here, but the reset will take care of it.
present % ds.reset();
ds.select(addrUsensorV);
ds.write(G.CO); !! Aead =cratchpad
for ( i % G; i X K; i&&)
{ !! we need K btes
dataUiV % ds.read();
}
4owCte % dataUGV;
1ighCte % dataU+V;
:Aeading % (1ighCte XX I) & 4owCte;
=ignCit % :Aeading ' G.IGGG; !! test most sig bit
if (=ignCit) !! negative
{
:Aeading % (:Aeading - G.ffff) & +; !! <Rs comp
}
:c;+GG % (:Aeading"+GG!<);
6hole % :c;+GG ! +GG; !! separate off the whole and fractional portions
Pract % :c;+GG ( +GG;
sprintf(buf, T(d:(c(d.(d\BBMD T,sensor,=ignCit Z R#R : R&R, 6hole, Pract X +G Z G : Pract);
lcd.setDursor(G,sensor(4DN;1O231:);
lcd.print(buf);
}
}
+BM
%in)
8ing 9ltrasonic Aange Pinder
:he 8ing))) is an ultrasonic range finder from 8aralla.. 2t detects the distance of the closest ob>ect in
front of the sensor (from < cm up to Bm). 2t works b sending out a burst of ultrasound and listening
for the echo when it bounces off of an ob>ect. :he Arduino board sends a short pulse to trigger the
detection, then listens for a pulse on the same pin using the pulse2n() function. :he duration of this
second pulse is e)ual to the time taken b the ultrasound to travel to the ob>ect and back to the
sensor. 9sing the speed of sound, this time can be converted to distance.
+xample
!" 8ing))) =ensor
:his sketch reads a 8273))) ultrasonic rangefinder and returns the distance to the closest ob>ect in
range. :o do this, it sends a pulse to the sensor to initiate a reading, then listens for a pulse to return.
:he length of the returning pulse is proportional to the distance of the ob>ect from the sensor.
"!
!! this constant wonRt change. 2tRs the pin number of the sensorRs output:
const int ping8in % M;
void setup() {
!! initiali?e serial communication:
=erial.begin(KHGG);
}
+BI
void loop()
{
!! establish variables for duration of the ping, and the distance result in inches and centimeters:
long duration, inches, cm;
!! :he 8273))) is triggered b a 1231 pulse of < or more microseconds.
!! 3ive a short 456 pulse beforehand to ensure a clean 1231 pulse:
pin@ode(ping8in, 59:89:);
digital6rite(ping8in, 456);
dela@icroseconds(<);
digital6rite(ping8in, 1231);
dela@icroseconds(J);
digital6rite(ping8in, 456);
!! :he same pin is used to read the signal from the 8273))): a 1231 pulse whose duration is the
!! time (in microseconds) from the sending of the ping to the reception of its echo off of an ob>ect.
pin@ode(ping8in, 2789:);
duration % pulse2n(ping8in, 1231);
!! convert the time into a distance
inches % microseconds:o2nches(duration);
cm % microseconds:oDentimeters(duration);

=erial.print(inches);
=erial.print(Tin, T);
=erial.print(cm);
=erial.print(TcmT);
=erial.println();

dela(+GG);
}
long microseconds:o2nches(long microseconds)
{
!! According to 8aralla.Rs datasheet for the 8273))), there are MB.MFH microseconds per inch (i.e.
!! sound travels at ++BG feet per second). :his gives the distance travelled b the ping, outbound
!! and return, so we divide b < to get the distance of the obstacle
return microseconds ! MF ! <;
}
long microseconds:oDentimeters(long microseconds)
{
!! :he speed of sound is BFG m!s or <K microseconds per centimeter. :he ping travels out and back,
!! so to find the distance of the ob>ect we take half of the distance travelled.
return microseconds ! <K ! <;
}
+BK
pin-ode#$
Donfigures the specified pin to behave either as an input or an output. =ee the description of digital
pins for details on the functionalit of the pins.
As of Arduino +.G.+, it is possible to enable the internal pullup resistors with the mode
2789:;894498. Additionall, the 2789: mode e.plicitl disables the internal pullups.
Syntax' pin@ode(pin, mode)
%arameters' pin: the number of the pin whose mode ou wish to set
mode: 2789:, 59:89:, or 2789:;894498. (see the digital pins page for a more
complete description of the functionalit.)
&eturns' 7one
+xample
int led8in % +B; !! 4ON connected to digital pin +B
void setup()
{
pin@ode(led8in, 59:89:); !! sets the digital pin as output
}
void loop()
{
digital6rite(led8in, 1231); !! sets the 4ON on
dela(+GGG); !! waits for a second
digital6rite(led8in, 456); !! sets the 4ON off
dela(+GGG); !! waits for a second
}
7ote: :he analog input pins can be used as digital pins, referred to as AG, A+, etc.
%ointer operators
pow#base, exponent$
Dalculates the value of a number raised to a power. 8ow() can be used to raise a number to a
fractional power. :his is useful for generating e.ponential mapping of values or curves.
%arameters' base: the number (float)
e.ponent: the power to which the base is raised (float)
&eturns' :he result of the e.ponentiation (double)
+xample
!" fscale
+FG
Ploating 8oint Autoscale Punction LG.+
:his function will scale one set of floating point numbers (range) to another set of floating point
numbers (range)
2t has a TcurveT parameter so that it can be made to favor either the end of the output. (4ogarithmic
mapping)
It taes / parameters
original@in # the minimum value of the original range # this @9=: be less than origninal@a.
original@a. # the ma.imum value of the original range # this @9=: be greater than orginal@in
newCegin # the end of the new range which maps to orginal@in # it can be smaller, or larger, than
newOnd, to facilitate inverting the ranges
newOnd # the end of the new range which maps to original@a. # it can be larger, or smaller, than
newCegin, to facilitate inverting the ranges
inputLalue # the variable for input that will mapped to the given ranges, this variable is constrained
to origina@in X% inputLalue X% original@a.
curve # curve is the curve which can be made to favor either end of the output scale in the
mapping. 8arameters are from #+G to +G with G being a linear mapping (which
basicall takes curve out of the e)uation)
:o understand the curve parameter do something like this:
void loop(){
for ( >%G; > X <GG; >&&){
scaledAesult % fscale( G, <GG, G, <GG, >, #+.J);
=erial.print(>, NOD);
=erial.print(T T);
=erial.println(scaledAesult, NOD);
}
}
And tr some different values for the curve function # remember G is a neutral, linear mapping
:o understand the inverting ranges, do something like this:
void loop(){
for ( >%G; > X <GG; >&&){
scaledAesult % fscale( G, <GG, <GG, G, >, G);
!! =erial.print lines as above
}
}
"!
$include Xmath.hY
int >;
float scaledAesult;
void setup() {
+F+
=erial.begin(KHGG);
}
void loop(){
for ( >%G; > X <GG; >&&){
scaledAesult % fscale( G, <GG, G, <GG, >, #+.J);
=erial.print(>, NOD);
=erial.print(T T);
=erial.println(scaledAesult , NOD);
}
}
float fscale( float original@in, float original@a., float newCegin, float newOnd, float inputLalue,
float curve){
float 5riginalAange % G;
float 7ewAange % G;
float ?eroAefDurLal % G;
float normali?edDurLal % G;
float rangedLalue % G;
boolean invPlag % G;
!! condition curve parameter
!! limit range
if (curve Y +G) curve % +G;
if (curve X #+G) curve % #+G;
curve % (curve " #.+) ; !! # invert and scale # this seems more intuitive # postive numbers give more
weight to high end on output
curve % pow(+G, curve); !! convert linear scale into lograthimic e.ponent for other pow function
!"
=erial.println(curve " +GG, NOD); !! multpl b +GG to preserve resolution
=erial.println();
"!
!! Dheck for out of range inputLalues
if (inputLalue X original@in) {
inputLalue % original@in;
}
if (inputLalue Y original@a.) {
inputLalue % original@a.;
}
!! [ero Aefference the values
5riginalAange % original@a. # original@in;
if (newOnd Y newCegin){
7ewAange % newOnd # newCegin;
}
+F<
else
{
7ewAange % newCegin # newOnd;
invPlag % +;
}
?eroAefDurLal % inputLalue # original@in;
normali?edDurLal % ?eroAefDurLal ! 5riginalAange; !! normali?e to G # + float
!"
=erial.print(5riginalAange, NOD);
=erial.print(T T);
=erial.print(7ewAange, NOD);
=erial.print(T T);
=erial.println(?eroAefDurLal, NOD);
=erial.println();
"!
!! Dheck for original@in Y original@a. # the math for all other cases i.e. negative numbers seems
to work out fine
if (original@in Y original@a. ) {
return G;
}
if (invPlag %% G){
rangedLalue % (pow(normali?edDurLal, curve) " 7ewAange) & newCegin;
}
else !! invert the ranges
{
rangedLalue % newCegin # (pow(normali?edDurLal, curve) " 7ewAange);
}
return rangedLalue;
}
%&O>-+-
=tore data in flash (program) memor instead of =AA@. :hereRs a description of the various tpes
of memor available on an Arduino board.
:he 8A53@O@ keword is a variable modifier, it should be used onl with the datatpes defined
in pgmspace.h. 2t tells the compiler Tput this information into flash memorT, instead of into
=AA@, where it would normall go.
8A53@O@ is part of the pgmspace.h librar. =o ou first need to include the librar at the top
our sketch, like this:
$include Xavr!pgmspace.hY
+FB
Syntax' data:pe variable7ameUV 8A53@O@ % {data2ntG, data2nt+, data2ntB...};
program memor data:pe # an program memor variable tpe (see below)
variable7ame # the name for our arra of data
7ote that because 8A53@O@ is a variable modifier, there is no hard and fast rule about where it
should go, so the Arduino compiler accepts all of the definitions below, which are also
snonmous. 1owever e.periments have indicated that, in various versions of Arduino (having to
do with 3DD version), 8A53@O@ ma work in one location and not in another. :he Tstring tableT
e.ample below has been tested to work with Arduino +B. Oarlier versions of the 2NO ma work
better if 8A53@O@ is included after the variable name.
data:pe variable7ameUV 8A53@O@ % {}; !! use this form
data:pe 8A53@O@ variable7ameUV % {}; !! not this one
8A53@O@ data:pe variable7ameUV % {}; !! use this form
6hile 8A53@O@ could be used on a single variable, it is reall onl worth the fuss if ou have a
larger block of data that needs to be stored, which is usuall easiest in an arra, (or another D data
structure beond our present discussion).
9sing 8A53@O@ is also a two#step procedure. After getting the data into Plash memor, it
re)uires special methods (functions), also defined in the pgmspace.h librar, to read the data from
program memor back into =AA@, so we can do something useful with it.
As mentioned above, it is important to use the datatpes outlined in pgmspace.h. =ome crptic bugs
are generated b using ordinar datatpes for program memor calls. Celow is a list of variable
tpes to use. Ploating point numbers in program memor do not appear to be supported.
prog;char # a signed char (+ bte) #+<M to +<I
prog;uchar # an unsigned char (+ bte) G to <JJ
prog;int+H;t # a signed int (< btes) #B<,MHM to B<,MHI
prog;uint+H;t # an unsigned int (< btes) G to HJ,JBJ
prog;intB<;t # a signed long (F btes) #<,+FM,FIB,HFI to " <,+FM,FIB,HFM.
prog;uintB<;t # an unsigned long (F btes) G to F,<KF,KHM,<KJ
+xample
:he following code fragments illustrate how to read and write unsigned chars (btes) and ints (<
btes) to 8A53@O@.
$include Xavr!pgmspace.hY
!! save some unsigned ints
8A53@O@ prog;uint+H;t char=etUV % { HJGGG, B<MKH, +HIFB, +G, ++<BF};
!! save some chars
prog;uchar sign@essageUV 8A53@O@ % {T2 A@ 8AONA:5A, 97=OO7 D5@CA:A7:.
DAOA:ON CS :1O 972:ON =:A:O= NO8AA:T};
unsigned int displa2nt;
int k; !! counter variable
char mDhar;
+FF
!! read back a <#bte int
displa2nt % pgm;read;word;near(char=et & k)
!! read back a char
mDhar % pgm;read;bte;near(sign@essage & k);
Arrays of strings
2t is often convenient when working with large amounts of te.t, such as a pro>ect with an 4DN
displa, to setup an arra of strings. Cecause strings themselves are arras, this is in actuall an
e.ample of a two#dimensional arra.
:hese tend to be large structures so putting them into program memor is often desirable. :he code
below illustrates the idea.
!"
8A53@O@ string demo. 1ow to store a table of strings in program memor (flash), and retrieve
them.
2nformation summari?ed from: http:!!www.nongnu.org!avr#libc!user#manual!pgmspace.html
=etting up a table (arra) of strings in program memor is slightl complicated, but here is a good
template to follow.
=etting up the strings is a two#step process. Pirst define the strings.
"!
$include Xavr!pgmspace.hY
prog;char string;GUV 8A53@O@ % T=tring GT; !! T=tring GT etc are strings to store # change to suit.
prog;char string;+UV 8A53@O@ % T=tring +T;
prog;char string;<UV 8A53@O@ % T=tring <T;
prog;char string;BUV 8A53@O@ % T=tring BT;
prog;char string;FUV 8A53@O@ % T=tring FT;
prog;char string;JUV 8A53@O@ % T=tring JT;
!! :hen set up a table to refer to our strings.
8A53@O@ const char "string;tableUV % !! change Tstring;tableT name to suit
{
string;G,
string;+,
string;<,
string;B,
string;F,
string;J };
char bufferUBGV; !! make sure this is large enough for the largest string it must hold
void setup()
{
=erial.begin(KHGG);
+FJ
}
void loop()
{
!" 9sing the string table in program memor re)uires the use of special functions to retrieve the
data. :he strcp;8 function copies a string from program space to a string in AA@ (TbufferT).
@ake sure our receiving string in AA@ is large enough to hold whatever ou are retrieving
from program space. "!
for (int i % G; i X H; i&&)
{
strcp;8(buffer, (char")pgm;read;word('(string;tableUiV))); !! 7ecessar casts and dereferencing,
>ust cop.
=erial.println( buffer );
dela( JGG );
}
}
pulse1n#$
Aeads a pulse (either 1231 or 456) on a pin. Por e.ample, if value is 1231, pulse2n() waits for
the pin to go 1231, starts timing, then waits for the pin to go 456 and stops timing. Aeturns the
length of the pulse in microseconds. 3ives up and returns G if no pulse starts within a specified time
out.
:he timing of this function has been determined empiricall and will probabl show errors in longer
pulses. 6orks on pulses from +G microseconds to B minutes in length.
Syntax' pulse2n(pin, value)
pulse2n(pin, value, timeout)
%arameters' pin: the number of the pin on which ou want to read the pulse. (int)
value: tpe of pulse to read: either 1231 or 456. (int)
timeout (optional): the number of microseconds to wait for the pulse to start; default
is one second (unsigned long)
&eturns' the length of the pulse (in microseconds) or G if no pulse started before the timeout
(unsigned long)
+xample
int pin % M;
unsigned long duration;
void setup()
{
pin@ode(pin, 2789:);
}
void loop()
{
duration % pulse2n(pin, 1231);
}
+FH
random#$
:he random function generates pseudo#random numbers.
Syntax' random(ma.)
random(min, ma.)
%arameters' min # lower bound of the random value, inclusive (optional)
ma. # upper bound of the random value, e.clusive
&eturns' a random number between min and ma.#+ (long)
*ote' 2f it is important for a se)uence of values generated b random() to differ, on
subse)uent e.ecutions of a sketch, use random=eed() to initiali?e the random number
generator with a fairl random input, such as analogAead() on an unconnected pin.
Donversel, it can occasionall be useful to use pseudo#random se)uences that repeat e.actl. :his
can be accomplished b calling random=eed() with a fi.ed number, before starting the random
se)uence.
+xample
long rand7umber;
void setup(){
=erial.begin(KHGG);
!! if analog input pin G is unconnected, random analog noise will cause the call to random=eed() to
!! generate different seed numbers each time the sketch runs. random=eed() will then shuffle the
!! random function.
random=eed(analogAead(G));
}
void loop() {
!! print a random number from G to <KK
rand7umber % random(BGG);
=erial.println(rand7umber);
!! print a random number from +G to +K
rand7umber % random(+G, <G);
=erial.println(rand7umber);
dela(JG);
}
+FM
randomSeed#seed$
random=eed() initiali?es the pseudo#random number generator, causing it to start at an arbitrar
point in its random se)uence. :his se)uence, while ver long, and random, is alwas the same.
2f it is important for a se)uence of values generated b random() to differ, on subse)uent e.ecutions
of a sketch, use random=eed() to initiali?e the random number generator with a fairl random input,
such as analogAead() on an unconnected pin.
Donversel, it can occasionall be useful to use pseudo#random se)uences that repeat e.actl. :his
can be accomplished b calling random=eed() with a fi.ed number, before starting the random
se)uence.
%arameters' long, int # pass a number to generate the seed.
&eturns' no returns
+xample
long rand7umber;
void setup(){
=erial.begin(KHGG);
random=eed(analogAead(G));
}
void loop(){
rand7umber % random(BGG);
=erial.println(rand7umber);
dela(JG);
}
return
:erminate a function and return a value from a function to the calling function, if desired.
Syntax' return;
return value; !! both forms are valid
%arameters' value: an variable or constant tpe
+xamples'
A function to compare a sensor input to a threshold
int check=ensor(){
if (analogAead(G) Y FGG) {
return +;
else{
return G;
}
+FI
}
:he return keword is hand to test a section of code without having to Tcomment outT large
sections of possibl bugg code.
void loop(){
!! brilliant code idea to test here
return;
!! the rest of a dsfunctional sketch here
!! this code will never be e.ecuted
}
Variable Scope
Lariables in the D programming language, which Arduino uses, have a propert called scope. :his
is in contrast to languages such as CA=2D where ever variable is a global variable.
A global variable is one that can be seen b ever function in a program. 4ocal variables are onl
visible to the function in which the are declared. 2n the Arduino environment, an variable
declared outside of a function (e.g. setup(), loop(), etc. ), is a global variable.
6hen programs start to get larger and more comple., local variables are a useful wa to insure that
onl one function has access to its own variables. :his prevents programming errors when one
function inadvertentl modifies variables used b another function.
2t is also sometimes hand to declare and initiali?e a variable inside a for loop. :his creates a
variable that can onl be accessed from inside the for#loop brackets.
+xample
int g86@val; !! an function will see this variable
void setup()
{
!! ...
}
void loop()
{
int i; !! TiT is onl TvisibleT inside of TloopT
float f; !! TfT is onl TvisibleT inside of TloopT
!! ...
for (int > % G; > X+GG; >&&){
!! variable > can onl be accessed inside the for#loop brackets
}
}
+FK
SD
sdCbe)in#$
2nitiali?es the =N librar and card. :his begins use of the =82 bus (digital pins ++, +<, and +B on
most Arduino boards; JG, J+, and J< on the @ega) and the chip select pin, which defaults to the
hardware == pin (pin +G on most Arduino boards, JB on the @ega). 7ote that even if ou use a
different chip select pin, the hardware == pin must be kept as an output or the =N librar functions
will not work.
Syntax' =N.begin()
=N.begin(cspin)
%arameters' cspin (optional): the pin connected to the chip select line of the =N card; defaults to
the hardware == line of the =82 bus
&eturns' true on success; false on failure
=ome things to keep in mind when using the =N 4ibrar
Overvie-
:he communication between the microcontroller and the =N card uses =82, which takes place on
digital pins ++, +<, and +B (on most Arduino boards) or JG, J+, and J< (Arduino @ega).
Additionall, another pin must be used to select the =N card. :his can be the hardware == pin # pin
+G (on most Arduino boards) or pin JB (on the @ega) # or another pin specified in the call to
=N.begin(). 7ote that even if ou donRt use the hardware == pin, it must be left as an output or the
=N librar wonRt work. Nifferent boards use different pins for this functionalit, so be sure ou_ve
selected the correct pin in =N.begin().
7ot all the functions are listed on the main =N librar page, because the are part of the librarRs
utilit functions.
Formattin)=%reparin) the card
(7C : whenever referring to the =N card, it means =N and micro=N si?es, as well as =N and =N1N
formats)
Sou_ll need a =N reader and computer to format our card properl. :he librar supports the
PA:+H and PA:B< filesstems, but use PA:+H when possible. :he process to format is fairl
straightforward.
File *amin)
PA: file sstems have a limitation when it comes to naming conventions. Sou must use the I.B
format, so that file names look like b7A@OGG+.OQ:c, where b7A@OGG+c is an I character or
fewer string, and bOQ:c is a B character e.tension. 8eople commonl use the e.tensions .:Q:
and .453. 2t is possible to have a shorter file name (for e.ample, mdata.t.t, or time.log), but ou
cannot use longer file names. Aead more on the I.B convention.
Openin)=Closin) !iles
+JG
6hen ou use file.write(), it doesnRt write to the card until ou flush() or close(). 6henever ou
open a file, be sure to close it to save our data.
As of version +.G, it is possible to have multiple files open.
Di!!erent Shields=boards
:here are a number of different shields that support =N cards. :his list is not e.clusive, but are
commonl used.
4rduino $thernet &hield
:he Othernet =hield comes with an =N card slot onboard. :he shield fits on top of our Arduino.
Cecause the Othernet module uses pin +G, the D= pin for the =N card has been moved to pin F.
@ake sure ou use =N.begin(F) to use the =N card functionalit.
4dafruit 5icro.&D breaout +oard
:his board supports @icro#=N cards, ans ou_ll need to wire it up before ou can use it. 5n the
board, connect 37N to ground, Jv to Jv, D4E to 8in +B on our Arduino, N5 to pin +<, N2 to pin
++, and D= to pin +G. 2f ou are alread using pin +G, ou can use a different pin, as long as ou
remember to change the pin in =N.begin().
&parfun &D &hield
:he =parkfun shield fits on our Arduino and uses pin I for D=. Sou will need use =N.begin(I) to
use the card.
7C: the =parkfun shield was recentl updated. 5lder versions look similar, but were lacking a
connection to the B.BL bus and did not have the onboard he. inverter.
#D
sdCexists#$
:ests whether a file or director e.ists on the =N card.
Syntax' =N.e.ists(filename)
%arameters' filename: the name of the file to test for e.istence, which can include directories
(delimited b forward#slashes, !)
&eturns' true if the file or director e.ists, false if not
#D
sdCm<dir#$
Dreate a director on the =N card. :his will also create an intermediate directories that donRt
alread e.ists; e.g. =N.mkdir(Ta!b!cT) will create a, b, and c.
+J+
Syntax' =N.mkdir(filename)
%arameters' filename: the name of the director to create, with sub#directories separated b
forward#slashes, !
&eturns' true if the creation of the director succeeded, false if not
#D
sdCopen#$
5pens a file on the =N card. 2f the file is opened for writing, it will be created if it doesnRt alread
e.ist (but the director containing it must alread e.ist).
(A&*1*>9 onl one file can be open at a time.
Syntax' =N.open(filepath)
=N.open(filepath, mode)
%arameters' filename: the name the file to open, which can include directories (delimited b
forward slashes, !) # char "
mode (optional): the mode in which to open the file, defaults to P24O;AOAN # bte.
one of:
P24O;AOAN: open the file for reading, starting at the beginning of the file.
P24O;6A2:O: open the file for reading and writing, starting at the end of the file.
&eturns' a Pile ob>ect referring to the opened file; if the file couldnRt be opened, this ob>ect
will evaluate to false in a boolean conte.t, i.e. ou can test the return value with Tif (f
)T.
#D
sdCremove#$
Aemove a file from the =N card.
Syntax' =N.remove(filename)
%arameters' filename: the name of the file to remove, which can include directories (delimited b
forward#slashes, !)
&eturns' true if the removal of the file succeeded, false if not. (if the file didnRt e.ist, the return
value is unspecified)
#D
sdCrmdir#$
Aemove a director from the =N card. :he director must be empt.
+J<
Syntax' =N.rmdir(filename)
%arameters' filename: the name of the director to remove, with sub#directories separated b
forward#slashes, !
&eturns' true if the removal of the director succeeded, false if not. (if the director didnRt
e.ist, the return value is unspecified)
#D + 4ile class
available#$
Dheck if there are an btes available for reading from the file. available() inherits from the =tream
utilit class.
Syntax' file.available()
%arameters' file: an instance of the Pile class (returned b =N.open())
&eturns' the number of btes available (int)
#D + 4ile class
close#$
Dlose the file, and ensure that an data written to it is phsicall saved to the =N card.
Syntax' file.close()
%arameters' file: an instance of the Pile class (returned b =N.open())
&eturns' none
#D + 4ile class
!lush#$
Onsures that an btes written to the file are phsicall saved to the =N card. :his is done
automaticall when the file is closed.
Syntax' file.flush()
%arameters' file: an instance of the Pile class (returned b =N.open())
&eturns' none
+JB
#D + 4ile class
isDirectory#$
Nirectories (or folders) are special kinds of files, this function reports if the current file is a
director or not.
Syntax' file.isNirector()
%arameters' file: an instance of the Pile class (returned b file.open()
&eturns' boolean
+xample
$include X=N.hY
Pile root;
void setup()
{
=erial.begin(KHGG);
pin@ode(+G, 59:89:);
=N.begin(+G);
root % =N.open(T!T);
printNirector(root, G);
=erial.println(Tdone*T);
}
void loop()
{
!! nothing happens after setup finishes.
}
void printNirector(Pile dir, int num:abs) {
while(true) {
Pile entr % dir.open7e.tPile();
if (* entr) {
!! no more files
!!=erial.println(T""nomorefiles""T);
break;
}
for (uintI;t i%G; iXnum:abs; i&&) {
=erial.print(R\tR);
}
=erial.print(entr.name());
if (entr.isNirector()) {
=erial.println(T!T);
printNirector(entr, num:abs&+);
} else {
+JF
!! files have si?es, directories do not
=erial.print(T\t\tT);
=erial.println(entr.si?e(), NOD);
}
}
}
#D + 4ile class
open*extFile#$
Aeports the ne.t file or folder in a director.
Syntax' file.open7e.tPile()
%arameters' file: an instance of the Pile class that is a director
&eturns' char : the ne.t file or folder in the path
+xample
$include X=N.hY
Pile root;
void setup()
{
=erial.begin(KHGG);
pin@ode(+G, 59:89:);
=N.begin(+G);
root % =N.open(T!T);
printNirector(root, G);
=erial.println(Tdone*T);
}
void loop()
{
!! nothing happens after setup finishes.
}
void printNirector(Pile dir, int num:abs) {
while(true) {
Pile entr % dir.open7e.tPile();
if (* entr) {
!! no more files
=erial.println(T""nomorefiles""T);
}

for (uintI;t i%G; iXnum:abs; i&&) {
=erial.print(R\tR);
+JJ
}

=erial.print(entr.name());
if (entr.isNirector()) {
=erial.println(T!T);
printNirector(entr, num:abs&+);
} else {
!! files have si?es, directories do not
=erial.print(T\t\tT);
=erial.println(entr.si?e(), NOD);
}
}
}
#D + 4ile class
pee<#$
Aead a bte from the file without advancing to the ne.t one. :hat is, successive calls to peek() will
return the same value, as will the ne.t call to read().
peek() inherits from the =tream utilit class.
Syntax' file.peek()
%arameters' file: an instance of the Pile class (returned b =N.open())
&eturns' :he ne.t bte (or character), or #+ if none is available.
#D + 4ile class
position#$
3et the current position within the file (i.e. the location to which the ne.t bte will be read from or
written to).
Syntax' file.position()
%arameters' file: an instance of the Pile class (returned b =N.open())
&eturns' the position within the file (unsigned long)
#D + 4ile class
print#$
8rint data to the file, which must have been opened for writing. 8rints numbers as a se)uence of
digits, each an A=D22 character (e.g. the number +<B is sent as the three characters R+R, R<R, RBR).
+JH
Syntax' file.print(data)
file.print(data, CA=O)
%arameters' file: an instance of the Pile class (returned b =N.open())
data: the data to print (char, bte, int, long, or string)
CA=O (optional): the base in which to print numbers: C27 for binar (base <), NOD
for decimal (base +G), 5D: for octal (base I), 1OQ for he.adecimal (base +H).
&eturns' bte
print() will return the number of btes written, though reading that number is
optional.
#D + 4ile class
println#$
8rint data, followed b a carriage return and newline, to the Pile, which must have been opened for
writing. 8rints numbers as a se)uence of digits, each an A=D22 character (e.g. the number +<B is
sent as the three characters R+R, R<R, RBR).
Syntax' file.println()
file.println(data)
file.print(data, CA=O)
%arameters' file: an instance of the Pile class (returned b =N.open())
data (optional): the data to print (char, bte, int, long, or string)
CA=O (optional): the base in which to print numbers: C27 for binar (base <), NOD
for decimal (base +G), 5D: for octal (base I), 1OQ for he.adecimal (base +H).
&eturns' bte
println() will return the number of btes written, though reading that number is
optional.
#D + 4ile class
read#$
Aead a bte from the file. read() inherits from the =tream utilit class.
Syntax' file.read()
%arameters' file: an instance of the Pile class (returned b =N.open())
&eturns' :he ne.t bte (or character), or #+ if none is available.
+JM
#D + 4ile class
rewindDirectory#$
rewindNirector() will bring ou back to the first file in the director, used in con>unction with
open7e.tPile().
Syntax' file.rewindNirector()
%arameters' file: an instance of the Pile class.
&eturns' 7one
+xample
$include X=N.hY
Pile root;
void setup()
{
=erial.begin(KHGG);
pin@ode(+G, 59:89:);
=N.begin(+G);
root % =N.open(T!T);
printNirector(root, G);
=erial.println(Tdone*T);
}
void loop()
{
!! nothing happens after setup finishes.
}
void printNirector(Pile dir, int num:abs) {
while(true) {
Pile entr % dir.open7e.tPile();
if (* entr) {
!! no more files
!! return to the first file in the director
dir.rewindNirector();
break;
}

for (uintI;t i%G; iXnum:abs; i&&) {
=erial.print(R\tR);
}
=erial.print(entr.name());
if (entr.isNirector()) {
=erial.println(T!T);
+JI
printNirector(entr, num:abs&+);
} else {
!! files have si?es, directories do not
=erial.print(T\t\tT);
=erial.println(entr.si?e(), NOD);
}
}
}
#D + 4ile class
see<#$
=eek to a new position in the file, which must be between G and the si?e of the file (inclusive).
Syntax' file.seek(pos)
%arameters' file: an instance of the Pile class (returned b =N.open())
pos: the position to which to seek (unsigned long)
&eturns' true for success, false for failure (boolean)
#D + 4ile class
siUe#$
3et the si?e of the file.
Syntax' file.si?e()
%arameters' file: an instance of the Pile class (returned b =N.open())
&eturns' the si?e of the file in btes (unsigned long)
#D + 4ile class
write#$
6rite data to the file.
Syntax' file.write(data)
file.write(buf, len)
%arameters' file: an instance of the Pile class (returned b =N.open())
data: the bte, char, or string (char ") to write
buf: an arra of characters or btes
len: the number of elements in buf
&eturns' bte write() will return the number of btes written, though reading that number is
+JK
optional
+xamples'
=E
=N card read!write

:his e.ample shows how to read and write data to and from an =N card fd>l. :he circuit:

"" =N card attached to =82 bus as follows:
"" @5=2 # pin ++
"" @2=5 # pin +<
"" D4E # pin +B
"" D= # pin F
"!

$include X=N.hY
Pile mPile;
void setup()
{
!! 5pen serial communications and wait for port to open:
=erial.begin(KHGG);
while (*=erial) {
; !! wait for serial port to connect. 7eeded for 4eonardo onl
}
=erial.print(T2nitiali?ing =N card...T);
!! 5n the Othernet =hield, D= is pin F. 2tRs set as an output b default.
!! 7ote that even if itRs not used as the D= pin, the hardware == pin
!! (+G on most Arduino boards, JB on the @ega) must be left as an output
!! or the =N librar functions will not work.
pin@ode(+G, 59:89:);

if (*=N.begin(F)) {
=erial.println(Tinitiali?ation failed*T);
return;
}
=erial.println(Tinitiali?ation done.T);

!! open the file. note that onl one file can be open at a time,
!! so ou have to close this one before opening another.
mPile % =N.open(Ttest.t.tT, P24O;6A2:O);

!! if the file opened oka, write to it:
if (mPile) {
=erial.print(T6riting to test.t.t...T);
mPile.println(Ttesting +, <, B.T);
!! close the file:
mPile.close();
=erial.println(Tdone.T);
} else {
!! if the file didnRt open, print an error:
+HG
=erial.println(Terror opening test.t.tT);
}

!! re#open the file for reading:
mPile % =N.open(Ttest.t.tT);
if (mPile) {
=erial.println(Ttest.t.t:T);

!! read from the file until thereRs nothing else in it:
while (mPile.available()) {
=erial.write(mPile.read());
}
!! close the file:
mPile.close();
} else {
!! if the file didnRt open, print an error:
=erial.println(Terror opening test.t.tT);
}
}
void loop()
{
!! nothing happens after setup
}
Datalogger
=E
=N card datalogger

:his e.ample shows how to log data from three analog sensors to an =N card using the =N librar.

:he circuit:
"" analog sensors on analog ins G, +, and <
"" =N card attached to =82 bus as follows:
"" @5=2 # pin ++
"" @2=5 # pin +<
"" D4E # pin +B
"" D= # pin F
"!
$include X=N.hY
!! 5n the Othernet =hield, D= is pin F. 7ote that even if itRs not
!! used as the D= pin, the hardware D= pin (+G on most Arduino boards,
!! JB on the @ega) must be left as an output or the =N librar
!! functions will not work.
const int chip=elect % F;
void setup()
+H+
{
!! 5pen serial communications and wait for port to open:
=erial.begin(KHGG);
while (*=erial) {
; !! wait for serial port to connect. 7eeded for 4eonardo onl
}
=erial.print(T2nitiali?ing =N card...T);
!! make sure that the default chip select pin is set to
!! output, even if ou donRt use it:
pin@ode(+G, 59:89:);

!! see if the card is present and can be initiali?ed:
if (*=N.begin(chip=elect)) {
=erial.println(TDard failed, or not presentT);
!! donRt do anthing more:
return;
}
=erial.println(Tcard initiali?ed.T);
}
void loop()
{
!! make a string for assembling the data to log:
=tring data=tring % TT;
!! read three sensors and append to the string:
for (int analog8in % G; analog8in X B; analog8in&&) {
int sensor % analogAead(analog8in);
data=tring &% =tring(sensor);
if (analog8in X <) {
data=tring &% T,T;
}
}
!! open the file. note that onl one file can be open at a time,
Pile dataPile % =N.open(Tdatalog.t.tT, P24O;6A2:O);
!! if the file is available, write to it:
if (dataPile) {
dataPile.println(data=tring);
dataPile.close();
!! print to the serial port too:
=erial.println(data=tring);
}
!! if the file isnRt open, pop up an error:
else {
=erial.println(Terror opening datalog.t.tT);
}
}
+H<
NumpPile
!"
=N card file dump

:his e.ample shows how to read a file from the =N card using the =N librar and send it over the
serial port.

:he circuit:
"" =N card attached to =82 bus as follows:
"" @5=2 # pin ++
"" @2=5 # pin +<
"" D4E # pin +B
"" D= # pin F
"!
$include X=N.hY
!! 5n the Othernet =hield, D= is pin F. 7ote that even if itRs not
!! used as the D= pin, the hardware D= pin (+G on most Arduino boards,
!! JB on the @ega) must be left as an output or the =N librar
!! functions will not work.
const int chip=elect % F;
void setup()
{
!! 5pen serial communications and wait for port to open:
=erial.begin(KHGG);
while (*=erial) {
; !! wait for serial port to connect. 7eeded for 4eonardo onl
}
=erial.print(T2nitiali?ing =N card...T);
!! make sure that the default chip select pin is set to
!! output, even if ou donRt use it:
pin@ode(+G, 59:89:);

!! see if the card is present and can be initiali?ed:
if (*=N.begin(chip=elect)) {
=erial.println(TDard failed, or not presentT);
!! donRt do anthing more:
return;
}
=erial.println(Tcard initiali?ed.T);

!! open the file. note that onl one file can be open at a time,
!! so ou have to close this one before opening another.
Pile dataPile % =N.open(Tdatalog.t.tT);
!! if the file is available, write to it:
if (dataPile) {
while (dataPile.available()) {
+HB
=erial.write(dataPile.read());
}
dataPile.close();
}
!! if the file isnRt open, pop up an error:
else {
=erial.println(Terror opening datalog.t.tT);
}
}
void loop()
{
}
"ardInfo
!"
=N card test
:his e.ample shows how use the utilit libraries on which the =N librar is based in order to get
info about our =N card. Ler useful for testing a card when ouRre not sure whether its working or
not.

:he circuit:
"" =N card attached to =82 bus as follows:
"" @5=2 # pin ++ on Arduino 9no!Nuemilanove!Niecimila
"" @2=5 # pin +< on Arduino 9no!Nuemilanove!Niecimila
"" D4E # pin +B on Arduino 9no!Nuemilanove!Niecimila
"" D= # depends on our =N card shield or module.
8in F used here for consistenc with other Arduino e.amples
"!
!! include the =N librar:
$include X=N.hY
!! set up variables using the =N utilit librar functions:
=d<Dard card;
=dLolume volume;
=dPile root;
!! change this to match our =N shield or module;
!! Arduino Othernet shield: pin F
!! Adafruit =N shields and modules: pin +G
!! =parkfun =N shield: pin I
const int chip=elect % F;
void setup()
{
!! 5pen serial communications and wait for port to open:
=erial.begin(KHGG);
while (*=erial) {
+HF
; !! wait for serial port to connect. 7eeded for 4eonardo onl
}
=erial.print(T\n2nitiali?ing =N card...T);
!! 5n the Othernet =hield, D= is pin F. 2tRs set as an output b default.
!! 7ote that even if itRs not used as the D= pin, the hardware == pin
!! (+G on most Arduino boards, JB on the @ega) must be left as an output
!! or the =N librar functions will not work.
pin@ode(+G, 59:89:); !! change this to JB on a mega
!! weRll use the initiali?ation code from the utilit libraries
!! since weRre >ust testing if the card is working*
if (*card.init(=82;1A4P;=8OON, chip=elect)) {
=erial.println(Tinitiali?ation failed. :hings to check:T);
=erial.println(T" is a card is insertedZT);
=erial.println(T" 2s our wiring correctZT);
=erial.println(T" did ou change the chip=elect pin to match our shield or moduleZT);
return;
} else {
=erial.println(T6iring is correct and a card is present.T);
}
!! print the tpe of card
=erial.print(T\nDard tpe: T);
switch(card.tpe()) {
case =N;DAAN;:S8O;=N+:
=erial.println(T=N+T);
break;
case =N;DAAN;:S8O;=N<:
=erial.println(T=N<T);
break;
case =N;DAAN;:S8O;=N1D:
=erial.println(T=N1DT);
break;
default:
=erial.println(T9nknownT);
}
!! 7ow we will tr to open the RvolumeR!RpartitionR # it should be PA:+H or PA:B<
if (*volume.init(card)) {
=erial.println(TDould not find PA:+H!PA:B< partition.\n@ake sure ouRve formatted the cardT);
return;
}
!! print the tpe and si?e of the first PA:#tpe volume
uintB<;t volumesi?e;
=erial.print(T\nLolume tpe is PA:T);
=erial.println(volume.fat:pe(), NOD);
=erial.println();

volumesi?e % volume.blocks8erDluster(); !! clusters are collections of blocks
volumesi?e "% volume.clusterDount(); !! weRll have a lot of clusters
volumesi?e "% J+<; !! =N card blocks are alwas J+< btes
+HJ
=erial.print(TLolume si?e (btes): T);
=erial.println(volumesi?e);
=erial.print(TLolume si?e (Ebtes): T);
volumesi?e !% +G<F;
=erial.println(volumesi?e);
=erial.print(TLolume si?e (@btes): T);
volumesi?e !% +G<F;
=erial.println(volumesi?e);
=erial.println(T\nPiles found on the card (name, date and si?e in btes): T);
root.openAoot(volume);

!! list all files in the card with date and si?e
root.ls(4=;A , 4=;NA:O , 4=;=2[O);
}
void loop(void) {
}
V semicolon
9sed to end a statement.
+xample
int a % +B;
Tip' Porgetting to end a line in a semicolon will result in a compiler error. :he error te.t ma be
obvious, and refer to a missing semicolon, or it ma not. 2f an impenetrable or seemingl
illogical compiler error comes up, one of the first things to check is a missing semicolon, in
the immediate vicinit, preceding the line at which the compiler complained.
Serial
9sed 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 9AA: or 9=AA:): =erial. 2t communicates on
digital pins G (AQ) and + (:Q) as well as with the computer via 9=C. :hus, if ou use these
functions, ou cannot also use pins G and + for digital input or output.
Sou can use the Arduino environmentRs built#in serial monitor to communicate with an Arduino
board. Dlick the serial monitor button in the toolbar and select the same baud rate used in the call to
begin().
:he Arduino @ega has three additional serial ports: =erial+ on pins +K (AQ) and +I (:Q), =erial<
on pins +M (AQ) and +H (:Q), =erialB on pins +J (AQ) and +F (:Q). :o use these pins to
communicate with our personal computer, ou will need an additional 9=C#to#serial adaptor, as
the are not connected to the @egaRs 9=C#to#serial adaptor. :o use them to communicate with an
e.ternal ::4 serial device, connect the :Q pin to our deviceRs AQ pin, the AQ to our deviceRs
:Q pin, and the ground of our @ega to our deviceRs ground. (NonRt connect these pins directl to
+HH
an A=<B< serial port; the operate at &!# +<L and can damage our Arduino board.)
:he Arduino 4eonardo board uses =erial+ to communicate via ::4 (JL) serial on pins G (AQ) and
+ (:Q). =erial is reserved for 9=C DND communication. Por more information, refer to the
4eonardo getting started page and hardware page.
Functions
o if (=erial) o available()
o begin() o end()
o find() o find9ntil()
o flush() o parsePloat()
o parse2nt() o peek()
o print() o println()
o read() o readCtes()
o readCtes9ntil() o set:imeout()
o write() o serialOvent()
+xamples
o AeadA=D22=tring
o A=D22 :able
o Nimmer
o 3raph
o 8hsical 8i.el
o Lirtual Dolor @i.er
o =erial Dall Aesponse
o =erial Dall Aesponse A=D22
#erial$vent
serial+vent#$
Dalled when data is available. 9se =erial.read() to capture this data.
Syntax void serialOvent(){
!!statements
}
Arduino -e)a only'
void serialOvent+(){
!!statements
}
void serialOvent<(){
!!statements
}
void serialOventB(){
!!statements
}
+HM
%arameters' statements: an valid statements
+xample
!"
=erial Ovent e.ample
6hen new serial data arrives, this sketch adds it to a =tring.
6hen a newline is received, the loop prints the string and clears it.
A good test for this is to tr it with a 38= receiver that sends out 7@OA G+IB sentences.
"!
=tring input=tring % TT; !! a string to hold incoming data
boolean stringDomplete % false; !! whether the string is complete
void setup() {
!! initiali?e serial:
=erial.begin(KHGG);
!! reserve <GG btes for the input=tring:
input=tring.reserve(<GG);
}
void loop() {
!! print the string when a newline arrives:
if (stringDomplete) {
=erial.println(input=tring);
!! clear the string:
input=tring % TT;
stringDomplete % false;
}
}
!" =erialOvent occurs whenever a new data comes in the hardware serial AQ. :his routine is run
between each time loop() runs, so using dela inside loop can dela response. @ultiple btes of data
ma be available.
"!
void serialOvent() {
while (=erial.available()) {
!! get the new bte:
char inDhar % (char)=erial.read();
!! add it to the input=tring:
input=tring &% inDhar;
!! if the incoming character is a newline, set a flag
!! so the main loop can do something about it:
if (inDhar %% R\nR) {
stringDomplete % true;
}
}
}
+HI
SerialCparse1nt#$
=erial.parse2nt() returns the first valid (long) integer number from the serial buffer. Dharacters that
are not integers (or the minus sign) are skipped. =erial.parse2nt() is terminated b the first character
that is not a digit.
=erial.parse2nt() inherits from the =tream utilit class.
Syntax' =erial.parse2nt()
%arameters' none
&eturns' int
Servo library
:his librar allows an Arduino board to control AD (hobb) servo motors. =ervos have integrated
gears and a shaft that can be precisel controlled. =tandard servos allow the shaft to be positioned at
various angles, usuall between G and +IG degrees. Dontinuous rotation servos allow the rotation of
the shaft to be set to various speeds.
:he =ervo librar supports up to +< motors on most Arduino boards and FI on the Arduino @ega.
5n boards other than the @ega, use of the librar disables analog6rite() (86@) functionalit on
pins K and +G, whether or not there is a =ervo on those pins. 5n the @ega, up to +< servos can be
used without interfering with 86@ functionalit; use of +< to <B motors will disable 86@ on pins
++ and +<.
Circuit
=ervo motors have three wires: power, ground, and signal. :he power wire is tpicall red, and
should be connected to the JL pin on the Arduino board. :he ground wire is tpicall black or
brown and should be connected to a ground pin on the Arduino board. :he signal pin is tpicall
ellow, orange or white and should be connected to a digital pin on the Arduino board. 7ote servos
draw considerable power, so if ou need to drive more than one or two, ouRll probabl need to
power them from a separate suppl (i.e. not the &JL pin on our Arduino). Ce sure to connect the
grounds of the Arduino and e.ternal power suppl together.
Functions
o attached()
o attach()
o detach()
o read()
o write()
o write@icroseconds()
+xamples
!! =weep
+HK
$include X=ervo.hY

=ervo mservo; !! create servo ob>ect to control a servo
!! a ma.imum of eight servo ob>ects can be created

int pos % G; !! variable to store the servo position

void setup()
{
mservo.attach(K); !! attaches the servo on pin K to the servo ob>ect
}

void loop()
{
for(pos % G; pos X +IG; pos &% +) !! goes from G degrees to +IG degrees
{ !! in steps of + degree
mservo.write(pos); !! tell servo to go to position in variable RposR
dela(+J); !! waits +Jms for the servo to reach the position
}
for(pos % +IG; posY%+; pos#%+) !! goes from +IG degrees to G degrees
{
mservo.write(pos); !! tell servo to go to position in variable RposR
dela(+J); !! waits +Jms for the servo to reach the position
}
}
#ervo
attached#$
Dheck whether the =ervo variable is attached to a pin.
Syntax' servo.attached()
%arameters' servo: a variable of tpe =ervo
&eturns' true if the servo is attached to pin; false otherwise.
#ervo
attach#$
Attach the =ervo variable to a pin. 7ote that in Arduino GG+H and earlier, the =ervo librar supports
onl servos on onl two pins: K and +G.
Syntax' servo.attach(pin)
servo.attach(pin, min, ma.)
%arameters' servo: a variable of tpe =ervo
pin: the number of the pin that the servo is attached to
min (optional): the pulse width, in microseconds, corresponding to the minimum (G#
+MG
degree) angle on the servo (defaults to JFF)
ma. (optional): the pulse width, in microseconds, corresponding to the ma.imum
#GIOBde)ree$ an)le on the servo #de!aults to PROO$
+xample
$include X=ervo.hY
=ervo mservo;
void setup()
{
mservo.attach(K);
}
void loop() {}
#ervo
detach#$
Netach the =ervo variable from its pin. 2f all =ervo variables are detached, then pins K and +G can be
used for 86@ output with analog6rite().
Syntax' servo.detach()
%arameters' servo: a variable of tpe =ervo
#ervo
read#$
Aead the current angle of the servo (the value passed to the last call to write()).
Syntax' servo.read()
%arameters' servo: a variable of tpe =ervo
&eturns' :he angle of the servo, from G to +IG degrees.
#ervo
write#$
6rites a value to the servo, controlling the shaft accordingl. 5n a standard servo, this will set the
angle of the shaft (in degrees), moving the shaft to that orientation. 5n a continuous rotation servo,
this will set the speed of the servo (with G being full#speed in one direction, +IG being full speed in
the other, and a value near KG being no movement).
Syntax' servo.write(angle)
%arameters' servo: a variable of tpe =ervo
angle: the value to write to the servo, from G to +IG
+xample
+M+
$include X=ervo.hY
=ervo mservo;
void setup()
{
mservo.attach(K);
mservo.write(KG); !! set servo to mid#point
}
void loop() {}
#ervo
write-icroseconds#$
6rites a value in microseconds (u=) to the servo, controlling the shaft accordingl. 5n a standard
servo, this will set the angle of the shaft. 5n standard servos a parameter value of +GGG is full
counter#clockwise, <GGG is full clockwise, and +JGG is in the middle.
7ote that some manufactures do not follow this standard ver closel so that servos often respond
to values between MGG and <BGG. Peel free to increase these endpoints until the servo no longer
continues to increase its range. 7ote however that attempting to drive a servo past its endpoints
(often indicated b a growling sound) is a high#current state, and should be avoided.
Dontinuous#rotation servos will respond to the write@icrosecond function in an analogous manner
to the write function.
Syntax' servo.write@icroseconds(u=)
%arameters' servo: a variable of tpe =ervo
u=: the value of the parameter in microseconds (int)
+xample
$include X=ervo.hY
=ervo mservo;
void setup()
{
mservo.attach(K);
mservo.write@icroseconds(+JGG); !! set servo to mid#point
}
void loop() {}
+M<
setup#$
:he setup() function is called when a sketch starts. 9se it to initiali?e variables, pin modes, start
using libraries, etc. :he setup function will onl run once, after each powerup or reset of the
Arduino board.
+xample
int button8in % B;
void setup()
{
=erial.begin(KHGG);
pin@ode(button8in, 2789:);
}
void loop()
{
!! ...
}
shi!t1n#$
=hifts in a bte of data one bit at a time. =tarts from either the most (i.e. the leftmost) or least
(rightmost) significant bit. Por each bit, the clock pin is pulled high, the ne.t bit is read from the
data line, and then the clock pin is taken low.
*ote' this is a software implementation; Arduino also provides an =82 librar that uses the
hardware implementation, which is faster but onl works on specific pins.
Syntax' bte incoming % shift2n(data8in, clock8in, bit5rder)
%arameters' data8in: the pin on which to input each bit (int)
clock8in: the pin to toggle to signal a read from data8in
bit5rder: which order to shift in the bits; either @=CP2A=: or 4=CP2A=:.
(@ost =ignificant Cit Pirst, or, 4east =ignificant Cit Pirst)
&eturns' the value read (bte)
shi!tOut#$
=hifts out a bte of data one bit at a time. =tarts from either the most (i.e. the leftmost) or least
(rightmost) significant bit. Oach bit is written in turn to a data pin, after which a clock pin is pulsed
(taken high, then low) to indicate that the bit is available.
*ote' if ouRre interfacing with a device thatRs clocked b rising edges, ouRll need to make
sure that the clock pin is low before the call to shift5ut(), e.g. with a call to
digital6rite(clock8in, 456).
:his is a software implementation; see also the =82 librar, which provides a hardware
+MB
implementation that is faster but works onl on specific pins.
Syntax' shift5ut(data8in, clock8in, bit5rder, value)
%arameters' data8in: the pin on which to output each bit (int)
clock8in: the pin to toggle once the data8in has been set to the correct value (int)
bit5rder: which order to shift out the bits; either @=CP2A=: or 4=CP2A=:.
(@ost =ignificant Cit Pirst, or, 4east =ignificant Cit Pirst)
value: the data to shift out. (bte)
&eturns' 7one
*ote' :he data8in and clock8in must alread be configured as outputs b a call to pin@ode().
shift5ut is currentl written to output + bte (I bits) so it re)uires a two step operation to output
values larger than <JJ.
!! No this for @=CP2A=: serial
int data % JGG;
shift5ut(data8in, clock, @=CP2A=:, (data YY I)); !! shift out highbte
shift5ut(data, clock, @=CP2A=:, data); !! shift out lowbte
data % JGG; !! 5r do this for 4=CP2A=: serial
shift5ut(data8in, clock, 4=CP2A=:, data); !! shift out lowbte
shift5ut(data8in, clock, 4=CP2A=:, (data YY I)); !! shift out highbte
+xample
=E =hift Aegister O.ample for two MF1DJKJ shift registers
:his sketch turns on each of the 4ONs attached to two MF1DJKJ shift registers, in se)uence from
output G to output +J.
1ardware:
" < MF1DJKJ shift register attached to pins <, B, and F of the Arduino, as detailed below.
" 4ONs attached to each of the outputs of the shift register
"!
const int latch8in % I; !!8in connected to latch pin (=:;D8) of MF1DJKJ
const int clock8in % +<; !!8in connected to clock pin (=1;D8) of MF1DJKJ
const int data8in % ++; !!8in connected to Nata in (N=) of MF1DJKJ
char input=tringU<V;
void setup() {
!!set pins to output because the are addressed in the main loop
pin@ode(latch8in, 59:89:);
pin@ode(data8in, 59:89:);
pin@ode(clock8in, 59:89:);
=erial.begin(KHGG);
=erial.println(TresetT);
}
void loop() {
!! iterate over the +H outputs of the two shift registers
for (int this4ed % G; this4ed X +H; this4ed&&) {
+MF
register6rite(this4ed, 1231); !! write data to the shift registers
if (this4ed Y G) { !! if this is not the first 4ON, turn off the previous 4ON
register6rite(this4ed # +, 456);
}
!! if this is the first 4ON, turn off the highest 4ON:
else {
register6rite(+J, 456);
}
dela(<JG); !! pause between 4ONs
}
}
!! :his method sends bits to the shift registers:
void register6rite(int which8in, int which=tate) {
!! the bits ou want to send. 9se an unsigned int, so ou can use all +H bits:
unsigned int bits:o=end % G;
!! turn off the output so the pins donRt light up while ouRre shifting bits:
digital6rite(latch8in, 456);
bit6rite(bits:o=end, which8in, which=tate); !! turn on the ne.t highest bit in bits:o=end
!! break the bits into two btes, one for the first register and one for the second:
bte register5ne % highCte(bits:o=end);
bte register:wo % lowCte(bits:o=end);
!! shift the btes out:
shift5ut(data8in, clock8in, @=CP2A=:, register:wo);
shift5ut(data8in, clock8in, @=CP2A=:, register5ne);
digital6rite(latch8in, 1231); !! turn on the output so the 4ONs can light up
}
!!""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!
!! 7otes : Dode for using a MF1DJKJ =hift Aegister : to count from G to <JJ !!
!!""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
int latch8in % I; !!8in connected to =:;D8 of MF1DJKJ
int clock8in % +<; !!8in connected to =1;D8 of MF1DJKJ
int data8in % ++; !!8in connected to N= of MF1DJKJ
void setup() { !!set pins to output because the are addressed in the main loop
pin@ode(latch8in, 59:89:);
pin@ode(clock8in, 59:89:);
pin@ode(data8in, 59:89:);
}
void loop() {
!!count up routine
for (int > % G; > X <JH; >&&) {
!!ground latch8in and hold low for as long as ou are transmitting
+MJ
digital6rite(latch8in, 456);
shift5ut(data8in, clock8in, 4=CP2A=:, >);
!!return the latch pin high to signal chip that it
!!no longer needs to listen for information
digital6rite(latch8in, 1231);
dela(+GGG);
}
}
SimpleSDAudio
8la audio files with our Arduino in decent )ualit from =N card, onl ver few additional
hardware re)uired.
Features
I#Cit 86@ output # no e.ternal NAD re)uired
H<.JGG k1? (fullrate) ! B+.<JG k1? (halfrate) sampling rate ] +H @1?
B+.<JG k1? (fullrate) ! +J.H<J k1? (halfrate) sampling rate ] I @h?
86@ output is operating alwas at fullrate for easier filtering
@ono, bridge and stereo mode
AA@ usage /+.B kCte
A5@ usage /H.+ kCte
2ntegrated =N librar (minimal PA: onl, optimi?ed for low AA@ usage and high
performance)
6orks with most =N card shields that are hooked to =82 port
Oas to use A82: +. init librar, <. select audio file, B. call pla, F. call worker while audio is
plaing
=upports =N and =N1D cards formated with PA:+H or PA:B<
&estrictions

Audio file must be converted prior use
Audio files must reside in root director of card
Pile name of audio file must be in I.B#format
Audio file must reside completel non#fragmented on card
Dombination of fullrate and stereo actuall leads to buffer underruns
@inimum controller re)uired: A:mega+HI. A:megaI is too low on AA@.
uic<start )uide
2nstall librar: 9n?ip all to our !libraries! folder.
Dop the file !libraries!=imple=NAudio!e.amples!OQA@84O.AP@ to root folder of a
freshl formated =N card (donRt use )uick format*).
Donnect =N card to our Arduino board (using shield or whatever, =N cardRs chip select
should go to pin F, all other to =82 pins).
Donnect a speaker or headphone via +GG ohm resistor in series to audio output pin (pin K on
Arduinos with A:mega+HI!B<I, pin FF on Arduinos with A:mega+<IG!<JHG). Donnect
other end of speaker to 37N.
4aunch Arduino 2NO and tr e.ample TCare@inimum6ithNebugT first.
+MH
Sou should hear the audio (plas >ust a few seconds). Activate serial monitor to find some
information if it does not work. @abe ou have to ad>ust =N cards D= pin in sketch.
%reparation o! SD card and conversion o! audio !iles
:he audio librar uses a ver trimmed =N librar that uses the PA: onl to find the start sector of
the files. :herefore the file must be completel non#fragmented on the =N card. :he best wa to
ensure this is to do a fresh and full format of the card (donRt use )uick format*). After formating the
=N card, onl cop new files on it. NonRt delete files and avoid rename operations that creates file
names that doesnRt fit into I.B format (see http:!!en.wikipedia.org!wiki!I.B;filename ). All files must
placed in root director as folders are not supported b the audio librar.
:o convert audio files 2 suggest the use of =oQ from http:!!so..sourceforge.net .
4inu. users should compile =oQ from source or use their favorite package manager to install =oQ. 2
recommend to use the following line for conversions:
so6 inputfile.wav ..norm7.' .e unsigned.integer .b ( .r 3')0* .c ' .t raw outputfile.raw
Dhange the following according to our needs:
Por stereo change #c + to #c <
Por full rate use #r H<JGG ] +H@1?, #r B+<JG ] I @1?
Por half rate use #r B+<JG ] +H@1?, #r +JH<J ] I @1?
:he option ##norm%#+ is used to avoid bad sounding clipping effects.
File name conventions
Oven ou could choose an filename and an e.tension, 2 suggest using an e.tension that shows
audio rate and stereo or mono mode. 2n the batch#files 2 use the following:
.AP@ # Pullrate, mono
.AP= # Pullrate, stereo
.A1@ # 1alfrate, mono
.A1= # 1alfrate, stereo
1ardware setup
:he =N card should be connected to the =82 port of the controller. :he chip select pin from the card
can be connected to an free digital pin, but if pin F is used on Arduinos ou donRt have to ad>ust the
source code. @an shields with =N card support like Othernet#=hield will work. Sou need pegel
conversion circuits from JL to B.BL for most Arduinos (e.cept those that run nativel on B.BL).
According our mode configuration, one or two pins are used for audio output. :his pins can not be
changed and are different between different Arduino boards. Por A:mega+HI!B<I based plattforms
those are pins K and +G. Por A:mega+<IG!<JHG those are pins FF and FJ. Por other plattforms look
into the file =imple=NAudio.h.
Ce careful that the audio output pins are digital ports that carr a positive voltage between GL and
JL. 2t is not a good idea to have a ND voltage at line#inputs or smaller speakers as there will be a
stead current flow. :herefore at least a resistor and!or a capacitor should be connected in series.
Por a start use at least +GG ohm or a capacitor between +GGnP and +GGuP. Por line inputs use a
voltage divider or poti to reduce the voltage.
+MM
A%1 re!erence
Constants
1ere is an overview of the constants used in the librar.
$define ==NA;LOA=257=:A273 T+.GGT
!! =ound @ode Plags
$define ==NA;@5NO;P944AA:O G.GG !! H<.JGG k1? ] +H @1?, B+.<JG k1? ] I @1?
$define ==NA;@5NO;1A4PAA:O G.+G !! B+.<JG k1? ] +H @1?, +J.H<J k1? ] I @1?
$define ==NA;@5NO;@575 G.GG !! 9se onl +st 86@ pin
$define ==NA;@5NO;=:OAO5 G.G+ !! 9se both 86@ pins for stereo output
$define ==NA;@5NO;@575;CA2N3O G.G< !! 9se both 86@ pins for more power
!! Orror codes from =imple=NAudio, see other sd;l".h for more error codes
$define ==NA;OAA5A;7944 G.IG !! 7ull pointer
$define ==NA;OAA5A;C9P:5=@A44 G.I+ !! Cuffer to small
$define ==NA;OAA5A;75:;272: G.I< !! =stem not initiali?ed properl
Class name and de!ault instance
class =d8laDlass { ... }
e.tern =d8laDlass =d8la;
:he name of the class is =d8laDlass. 5ne instance is alread created for use and is named =d8la.
%ublic class !unctions
init#$
boolean init,uint(8t sound5ode-3
Dall this to initial?e the librar and set sound mode. :his function will also a)uire the needed buffer
(if not alread set manuall using set6orkCuffer), initiali?e =N card and sets up all used pins.
A combination of the following flags must be provided as argument (combine via or#ing):
=ample rate setting flags
==NA;@5NO;P944AA:O # H<.JGG k1? ] +H @1?, B+.<JG k1? ] I @1?
==NA;@5NO;1A4PAA:O # B+.<JG k1? ] +H @1?, +J.H<J k1? ] I @1?
5utput channel configuration flags
==NA;@5NO;@575 # 9se onl +st 86@ pin
==NA;@5NO;=:OAO5 # 9se both 86@ pins for stereo output
==NA;@5NO;@575;CA2N3O # 9se both 86@ pins for more power
:he function return true if successfull, false if an error occured. Sou can use get4astOrror() to
retrieve the error code. :pical reasons for errors are wrong =N card connection or too low AA@
(+k heap re)uired) for internal buffer available.
+MI
setFile#$
boolean set2ile,char "file9ame-3
After init was successfull, call this to select audio file b providing the filename in I.B format.
:he function return true if successfull, false if an error occured. Sou can use get4astOrror() to
retrieve the error code. :pical reasons for errors are that the file was not found.
wor<er#$
void worer,void-3
Dall this continuall at least as long as the audio plaback is running. :his function fills the internal
plaback buffer b reading the ne.t sectors from =N card. Sou canet call this function too often, but
a buffer underrun can occur when the time between two calls are too long.
play#$
void play,void-3
2f audio is not plaing, plaing will be started. 2f it is alread plaing, it will start plaing from ?ero
again.
stop#$
void stop,void-3
=tops plaback if plaing, sets plaposition to ?ero.
pause#$
void pause,void-3
8auses plaing if not plaing, resumes plaing if was paused.
setSDCS%in#$
void set&DC&:in,uint(8t cs:in-3
Dall this before init to set =N#Dards D=#8in to other than default.
set(or<Bu!!er#$
void set;or+uffer,uint(8t "p+uf, uint'/8t buf&i<e-3
Dall this if ou want to use our own buffer (at least +G<F btes, must be multiple of J+<). Dall this
before init and then init will use this buffer instead using malloc to create its own.
de1nit#$
void deInit,void-3
+MK
Dall this to free resources like buffer, release =N card pins, audio interrupts and audio pins.
dir#$
void dir,void ,"callbac-,char "--3
5utput the director of the =N card. A pointer to a callback function must be provided. :he
callback function is called once for ever file found in the root director of the card. :he strings
contain ?ero#termination but no linefeeds.
+xample'
...
!! setup global callback function
void dir;callback(char "buf) {
=erial.println(buf);
}
...
!! somewhere after initiali?ation
=d8la.dir('dir;callback);
isStopped#$, is%layin)#$, is%aused#$
boolean is&topped,void-3
boolean is:laying,void-3
boolean is:aused,void-3
Aeturns the current state of the plaback. :he function is=topped() can be used after issuing pla()
to determine when the plaback has finished.
is"nderrunOccured#$
boolean is=nderrun>ccured,void-3
Aeturns if the internal underrun#flag is set and clears it. 2f audio sounds strange or has dropouts, test
if underruns are the cause.
)et.ast+rror#$
uint(8t getLast$rror,void-3
Aetrieve the last error code and clears it. :o analse the error reason, take a look also at the files
sd;l+.h and sd;l<.h of the librar to find the meaning of the code.

FA
=d8la.init fails
1ave ou selected the correct D= pin for our =N#cardZ 9ncomment the line
!! &d:lay.set&DC&:in,'*-3
in the e.amples and enter correct pin number here.
+IG
Sour =N shield ma be crap and =N communication is onl possible with limited speed. :r
commenting the line
&:&? @7 ,' AA &:I)%-3
in function =N;4G;=pi=et1igh=peed(). 2f this doesnRt help, comment out also the first line and tr
again. 2f then init works ou have a bad =N card shield.
sin#rad$
Dalculates the sine of an angle (in radians). :he result will be between #+ and +.
%arameters' rad: the angle in radians (float)
&eturns' the sine of the angle (double)
siUeo!
:he si?eof operator returns the number of btes in a variable tpe, or the number of btes occupied
b an arra.
Syntax' si?eof(variable)
%arameters' variable: an variable tpe or arra (e.g. int, float, bte)
+xample
:he si?eof operator is useful for dealing with arras (such as strings) where it is convenient to be
able to change the si?e of the arra without breaking other parts of the program.
:his program prints out a te.t string one character at a time. :r changing the te.t phrase.
char m=trUV % Tthis is a testT;
int i;
void setup(){
=erial.begin(KHGG);
}
void loop() {
for (i % G; i X si?eof(m=tr) # +; i&&){
=erial.print(i, NOD);
=erial.print(T % T);
=erial.write(m=trUiV);
=erial.println();
}
dela(JGGG); !! slow down the program
}
7ote that si?eof returns the total number of btes. =o for larger variable tpes such as ints, the for
loop would look something like this. 7ote also that a properl formatted string ends with the 7944
smbol, which has A=D22 value G.
+I+
for (i % G; i X (si?eof(m2nts)!si?eof(int)) # +; i&&) {
!! do something with m2ntsUiV
}
So!twareSerial .ibrary
:he Arduino hardware has built#in support for serial communication on pins G and + (which also
goes to the computer via the 9=C connection). :he native serial support happens via a piece of
hardware (built into the chip) called a 9AA:. :his hardware allows the Atmega chip to receive
serial communication even while working on other tasks, as long as there room in the HF bte serial
buffer.
:he =oftware=erial librar has been developed to allow serial communication on other digital pins
of the Arduino, using software to replicate the functionalit (hence the name T=oftware=erialT). 2t is
possible to have multiple software serial ports with speeds up to ++J<GG bps. A parameter enables
inverted signaling for devices which re)uire that protocol.
:he version of =oftware=erial included in +.G and later is based on the 7ew=oft=erial librar b
@ikal 1art.
.imitations
:he librar has the following known limitations:
o 2f using multiple software serial ports, onl one can receive data at a time.
o 7ot all pins on the @ega and @ega <JHG support change interrupts, so onl the following
can be used for AQ: +G, ++, +<, +B, JG, J+, J<, JB, H<, HB, HF, HJ, HH, HM, HI, HK
o 7ot all pins on the 4eonardo support change interrupts, so onl the following can be used
for AQ: I, K, +G, ++, +F (@2=5), +J (=DE), +H (@5=2).
+xample
!"
=oftware serial multple serial test
Aeceives from the hardware serial, sends to software serial.
Aeceives from software serial, sends to hardware serial.
:he circuit:
" AQ is digital pin +G (connect to :Q of other device)
" :Q is digital pin ++ (connect to AQ of other device)
7ote:
7ot all pins on the @ega and @ega <JHG support change interrupts,
so onl the following can be used for AQ:
+G, ++, +<, +B, JG, J+, J<, JB, H<, HB, HF, HJ, HH, HM, HI, HK
7ot all pins on the 4eonardo support change interrupts,
so onl the following can be used for AQ:
I, K, +G, ++, +F (@2=5), +J (=DE), +H (@5=2).
+I<
created back in the mists of time
modified <J @a <G+<
b :om 2goe
based on @ikal 1artRs e.ample
:his e.ample code is in the public domain.
"!
$include X=oftware=erial.hY
=oftware=erial m=erial(+G, ++); !! AQ, :Q
void setup()
{
!! 5pen serial communications and wait for port to open:
=erial.begin(JMHGG);
while (*=erial) {
; !! wait for serial port to connect. 7eeded for 4eonardo onl
}
=erial.println(T3oodnight moon*T);
!! set the data rate for the =oftware=erial port
m=erial.begin(FIGG);
m=erial.println(T1ello, worldZT);
}
void loop() !! run over and over
{
if (m=erial.available())
=erial.write(m=erial.read());
if (=erial.available())
m=erial.write(=erial.read());
}
Functions
o =oftware=erial()
o available()
o begin()
o is4istening()
o overflow()
o peek()
o read()
o print()
o println()
o listen()
o write()
+IB
So!twareSerial' available#$
3et the number of btes (characters) available for reading from a software serial port. :his is data
thatRs alread arrived and stored in the serial receive buffer.
Syntax' m=erial.available()
%arameters' none
&eturns' the number of btes available to read
+xample
!! include the =oftware=erial librar so ou can use its functions:
$include X=oftware=erial.hY
$define r.8in +G
$define t.8in ++
!! set up a new serial port
=oftware=erial m=erial % =oftware=erial(r.8in, t.8in);
void setup() {
!! define pin modes for t., r.:
pin@ode(r.8in, 2789:);
pin@ode(t.8in, 59:89:);
!! set the data rate for the =oftware=erial port
m=erial.begin(KHGG);
}
void loop() {
if (m=erial.available()YG){
m=erial.read();
}
}
So!twareSerial' be)in#speed$
=ets the speed (baud rate) for the serial communication. =upported baud rates are BGG, +<GG, <FGG,
FIGG, KHGG, +FFGG, +K<GG, <IIGG, B+<JG, BIFGG, JMHGG, and ++J<GG.
%arameters' speed: the baud rate (long)
&eturns' none
+xample
!! include the =oftware=erial librar so ou can use its functions:
$include X=oftware=erial.hY
+IF
$define r.8in +G
$define t.8in ++
!! set up a new serial port
=oftware=erial m=erial % =oftware=erial(r.8in, t.8in);
void setup() {
!! define pin modes for t., r.:
pin@ode(r.8in, 2789:);
pin@ode(t.8in, 59:89:);
!! set the data rate for the =oftware=erial port
m=erial.begin(KHGG);
}
void loop() {
!! ...
}
So!twareSerial#rx%in, tx%in$
A call to =oftware=erial(r.8in, t.8in) creates a new =oftware=erial ob>ect, whose name ou need to
provide as in the e.ample below.
Sou need to call =oftware=erial.begin() to enable communication.
%arameters' r.8in: the pin on which to receive serial data
t.8in: the pin on which to transmit serial data
+xample
$define r.8in <
$define t.8in B
!! set up a new serial port
=oftware=erial m=erial % =oftware=erial(r.8in, t.8in);
So!twareSerial' is.istenin)#$
:ests to see if re)uested software serial port is activel listening.
Syntax' m=erial.is4istening()
%arameters' none
&eturns' boolean
+xample
$include X=oftware=erial.hY
+IJ
!! software serial : :Q % digital pin +G, AQ % digital pin ++
=oftware=erial port5ne(+G,++);
void setup()
{
!! =tart the hardware serial port
=erial.begin(KHGG);
!! =tart software serial port
port5ne.begin(KHGG);
}
void loop()
{
if (port5ne.is4istening()) {
=erial.println(T8ort 5ne is listening*T);
}
So!twareSerial' listen#$
Onables the selected software serial port to listen. 5nl one software serial port can listen at a time;
data that arrives for other ports will be discarded. An data alread received is discarded during the
call to listen() (unless the given instance is alread listening).
Syntax' m=erial.listen()
%arameters: m=erial:the name of the instance to listen
&eturns' 7one
+xample
$include X=oftware=erial.hY
!! software serial : :Q % digital pin +G, AQ % digital pin ++
=oftware=erial port5ne(+G, ++);
!! software serial : :Q % digital pin I, AQ % digital pin K
=oftware=erial port:wo(I, K);
void setup()
{
!! =tart the hardware serial port
=erial.begin(KHGG);
!! =tart both software serial ports
port5ne.begin(KHGG);
port:wo.begin(KHGG);
}
void loop()
{
+IH
port5ne.listen();
if (port5ne.is4istening()) {
=erial.println(T8ort 5ne is listening*T);
}else{
=erial.println(T8ort 5ne is not listening*T);
}
if (port:wo.is4istening()) {
=erial.println(T8ort :wo is listening*T);
}else{
=erial.println(T8ort :wo is not listening*T);
}
}
So!twareSerial' over!low#$
:ests to see if a software serial buffer overflow has occurred. Dalling this function clears the
overflow flag, meaning that subse)uent calls will return false unless another bte of data has been
received and discarded in the meantime.
:he software serial buffer can hold HF btes.
Syntax' m=erial.overflow()
%arameters' none
&eturns' boolean
+xample
$include X=oftware=erial.hY
!! software serial : :Q % digital pin +G, AQ % digital pin ++
=oftware=erial port5ne(+G,++);
void setup()
{
!! =tart the hardware serial port
=erial.begin(KHGG);
!! =tart software serial port
port5ne.begin(KHGG);
}
void loop()
{
if (port5ne.overflow()) {
=erial.println(T=oftware=erial overflow*T);
}
+IM
So!twareSerial' pee<
Aeturn a character that was received on the AQ pin of the software serial port. 9nlike read(),
however, subse)uent calls to this function will return the same character.
7ote that onl one =oftware=erial instance can receive incoming data at a time (select which one
with the listen() function).
%arameters' none
&eturns' the character read, or #+ if none is available
+xample
=oftware=erial m=erial(+G,++);
void setup()
{
m=erial.begin(KHGG);
}
void loop()
{
char c % m=erial.peek();
}
So!twareSerial' print#data$
8rints data to the transmit pin of the software serial port. 6orks the same as the =erial.print()
function.
%arameters' var, see =erial.print() for details
&eturns' bte
print() will return the number of btes written, though reading that number is
optional
+xample
=oftware=erial serial(+G,++);
int analogLalue;
void setup()
{
serial.begin(KHGG);
}
void loop()
{
!! read the analog input on pin G:
analogLalue % analogAead(AG);
+II
!! print it out in man formats:
serial.print(analogLalue); !! print as an A=D22#encoded decimal
serial.print(T\tT); !! print a tab character
serial.print(analogLalue, NOD); !! print as an A=D22#encoded decimal
serial.print(T\tT); !! print a tab character
serial.print(analogLalue, 1OQ); !! print as an A=D22#encoded he.adecimal
serial.print(T\tT); !! print a tab character
serial.print(analogLalue, 5D:); !! print as an A=D22#encoded octal
serial.print(T\tT); !! print a tab character
serial.print(analogLalue, C27); !! print as an A=D22#encoded binar
serial.print(T\tT); !! print a tab character
serial.print(analogLalue!F, CS:O); !! print as a raw bte value (divide the
!! value b F because analogAead() returns numbers
!! from G to +G<B, but a bte can onl hold values
!! up to <JJ)
serial.print(T\tT); !! print a tab character
serial.println(); !! print a linefeed character
!! dela +G milliseconds before the ne.t reading:
dela(+G);
}
So!twareSerial' println#data$
8rints data to the transmit pin of the software serial port, followed b a carriage return and line feed.
6orks the same as the =erial.println() function.
%arameters' var, see =erial.println() for details
&eturns bte
println() will return the number of btes written, though reading that number is
optional
+xample
=oftware=erial serial(+G,++);
int analogLalue;
void setup()
{
serial.begin(KHGG);
}
void loop()
{
!! read the analog input on pin G:
analogLalue % analogAead(AG);
!! print it out in man formats:
serial.print(analogLalue); !! print as an A=D22#encoded decimal
serial.print(T\tT); !! print a tab character
serial.print(analogLalue, NOD); !! print as an A=D22#encoded decimal
+IK
serial.print(T\tT); !! print a tab character
serial.print(analogLalue, 1OQ); !! print as an A=D22#encoded he.adecimal
serial.print(T\tT); !! print a tab character
serial.print(analogLalue, 5D:); !! print as an A=D22#encoded octal
serial.print(T\tT); !! print a tab character
serial.print(analogLalue, C27); !! print as an A=D22#encoded binar
serial.print(T\tT); !! print a tab character
serial.print(analogLalue!F, CS:O); !! print as a raw bte value (divide the
!! value b F because analogAead() returns numbers
!! from G to +G<B, but a bte can onl hold values
!! up to <JJ)
serial.print(T\tT); !! print a tab character
serial.println(); !! print a linefeed character
!! dela +G milliseconds before the ne.t reading:
dela(+G);
}
So!twareSerial' read
Aeturn a character that was received on the AQ pin of the software serial port. 7ote that onl one
=oftware=erial instance can receive incoming data at a time (select which one with the listen()
function).
%arameters' none
&eturns' the character read, or #+ if none is available
+xample
=oftware=erial m=erial(+G,++);
void setup()
{
m=erial.begin(KHGG);
}
void loop()
{
char c % m=erial.read();
}
So!twareSerial' write#data$
8rints data to the transmit pin of the software serial port as raw btes. 6orks the same as the
=erial.write() function.
%arameters' =erial.write() for details
&eturns' bte
+KG
write() will return the num. of btes written, though reading that number is optional
+xample
=oftware=erial m=erial(+G, ++);
void setup()
{
m=erial.begin(KHGG);
}
void loop()
{
m=erial.write(FJ); !! send a bte with the value FJ
int btes=ent % m=erial.write(bhelloc); !!send the string bhelloc and return the
length of the string.
}
S%1 library
:his librar allows ou to communicate with =82 devices, with the Arduino as the master device.
A Crief 2ntroduction to the =erial 8eripheral 2nterface (=82)
=erial 8eripheral 2nterface (=82) is a snchronous serial data protocol used b microcontrollers for
communicating with one or more peripheral devices )uickl over short distances. 2t can also be
used for communication between two microcontrollers.
6ith an =82 connection there is alwas one master device (usuall a microcontroller) which
controls the peripheral devices. :picall there are three lines common to all the devices:
# @aster 2n =lave 5ut (@2=5) # :he =lave line for sending data to the master
# @aster 5ut =lave 2n (@5=2) # :he @aster line for sending data to the peripherals,
# =erial Dlock (=DE) # :he clock pulses which snchroni?e data transmission generated b the
master, and
# =lave =elect pin # the pin on each device that the master can use to enable and disable specific
devices. 6hen a deviceRs =lave =elect pin is low, it communicates with the master. 6hen itRs
high, it ignores the master. :his allows ou to have multiple =82 devices sharing the same
@2=5, @5=2, and D4E lines.
:o write code for a new =82 device ou need to note a few things:
# 2s data shifted in @ost =ignificant Cit (@=C) or 4east =ignificant Cit (4=C) firstZ :his is
controlled b the =82.setCit5rder() function.
# 2s the data clock idle when high or lowZ
+K+
# Are samples on the rising or falling edge of clock pulsesZ :his and the clock idling are
controlled b the =82.setNata@ode() function
# 6hat speed is the =82 running atZ :his is controlled b the =82.setDlockNivider() function.
:he =82 standard is loose and each device implements it a little differentl. :his means ou have to
pa special attention to the deviceRs datasheet when writing our code. 3enerall speaking, there are
three modes of transmission. :hese modes control whether data is shifted in and out on the rising or
falling edge of the data clock signal (called the clock phase, and whether the clock is idle when high
or low (called the clock polarit). :he three modes combine polarit and phase. :he
=82.setNata@ode() function lets ou set the mode to control clock polarit and phase according to
this table:
@ode Dlock 8olarit (D854) Dlock 8hase (D81A)
G G G
+ G +
< + G
B + +
5nce ou have our =82 parameters set correctl ou >ust need to figure which registers in our
device control which functions, and ouRre good to go. :his will be e.plained in the data sheet for
our device.
Connections
5n the Arduino Nuemilanove and other A:mega+HI ! B<I#based boards, the =82 bus uses pins +G
(==), ++ (@5=2), +< (@2=5), and +B (=DE). 5n the Arduino @ega, this is JG (@2=5), J+ (@5=2),
J< (=DE), and JB (==). @2=5, @5=2, and =DE are also available in a consistent phsical location
on the 2D=8 header; this is useful, for e.ample, in designing a shield that works on the 9no and the
@ega.
7ote that even if ouRre not using the == pin, it must remain set as an output; otherwise, the =82
interface can be put into slave mode, rendering the librar inoperative. 2t is, however, possible to
use a pin other than pin +G as the slave select (==) pin. Por e.ample, the Arduino Othernet shield
uses pin F to control the =82 connection to the on#board =N card, and pin +G to control the
connection to the Othernet controller.
Functions
# begin()
# end()
# setCit5rder()
# setDlockNivider()
# setNata@ode()
# transfer()
+K<
+xamples
!"
=D8+GGG Carometric 8ressure =ensor Nispla

=hows the output of a Carometric 8ressure =ensor on a 9ses the =82 librar. Por details on the
sensor, see: http:!!www.sparkfun.com!commerce!product;info.phpZproducts;id%I+H+
http:!!www.vti.fi!en!support!obsolete;products!pressure;sensors!

Dircuit:
=D8+GGG sensor attached to pins H, M, +G # +B:
NANS: pin H
D=C: pin M
@5=2: pin ++
@2=5: pin +<
=DE: pin +B
"!
!! the sensor communicates using =82, so include the librar:
$include X=82.hY
!!=ensorRs memor register addresses:
const int 8AO==9AO % G.+P; !!B most significant bits of pressure
const int 8AO==9AO;4=C % G.<G; !!+H least significant bits of pressure
const int :O@8OAA:9AO % G.<+; !!+H bit temperature reading
const bte AOAN % Gb++++++GG; !! =D8+GGGRs read command
+KB
const bte 6A2:O % GbGGGGGG+G; !! =D8+GGGRs write command
!! pins used for the connection with the sensor
!! the other ou need are controlled b the =82 librar):
const int dataAead8in % H;
const int chip=elect8in % M;
void setup() {
=erial.begin(KHGG);
!! start the =82 librar:
=82.begin();
!! initali?e the data read and chip select pins:
pin@ode(dataAead8in, 2789:);
pin@ode(chip=elect8in, 59:89:);
!!Donfigure =D8+GGG for low noise configuration:
writeAegister(G.G<, G.<N);
writeAegister(G.G+, G.GB);
writeAegister(G.GB, G.G<);
!! give the sensor time to set up:
dela(+GG);
}
void loop() {
!!=elect 1igh Aesolution @ode
writeAegister(G.GB, G.GA);
!! donRt do anthing until the data read pin is high:
if (digitalAead(dataAead8in) %% 1231) {
!!Aead the temperature data
int tempNata % readAegister(G.<+, <);
!! convert the temperature to celsius and displa it:
float real:emp % (float)tempNata ! <G.G;
=erial.print(T:empUDV%T);
=erial.print(real:emp);
!!Aead the pressure data highest B bits:
bte pressure;data;high % readAegister(G.+P, +);
pressure;data;high '% GbGGGGG+++; !!ou onl needs bits < to G
!!Aead the pressure data lower +H bits:
unsigned int pressure;data;low % readAegister(G.<G, <);
!!combine the two parts into one +K#bit number:
long pressure % ((pressure;data;high XX +H) , pressure;data;low)!F;
!! displa the temperature:
=erial.println(T\t8ressure U8aV%T & =tring(pressure));
}
+KF
}
!!Aead from or write to register from the =D8+GGG:
unsigned int readAegister(bte thisAegister, int btes:oAead ) {
bte inCte % G; !! incoming bte from the =82
unsigned int result % G; !! result to return
=erial.print(thisAegister, C27);
=erial.print(T\tT);
!! =D8+GGG e.pects the register name in the upper H bits
!! of the bte. =o shift the bits left b two bits:
thisAegister % thisAegister XX <;
!! now combine the address and the command into one bte
bte data:o=end % thisAegister ' AOAN;
=erial.println(thisAegister, C27);
!! take the chip select low to select the device:
digital6rite(chip=elect8in, 456);
!! send the device the register ou want to read:
=82.transfer(data:o=end);
!! send a value of G to read the first bte returned:
result % =82.transfer(G.GG);
!! decrement the number of btes left to read:
btes:oAead##;
!! if ou still have another bte to read:
if (btes:oAead Y G) {
!! shift the first bte left, then get the second bte:
result % result XX I;
inCte % =82.transfer(G.GG);
!! combine the bte ou >ust got with the previous one:
result % result , inCte;
!! decrement the number of btes left to read:
btes:oAead##;
}
!! take the chip select high to de#select:
digital6rite(chip=elect8in, 1231);
!! return the result:
return(result);
}
!!=ends a write command to =D8+GGG
void writeAegister(bte thisAegister, bte thisLalue) {
!! =D8+GGG e.pects register address in the upper H bits of the bte. =o shift the bits left b two bits:
thisAegister % thisAegister XX <;
!! now combine the register address and the command into one bte:
bte data:o=end % thisAegister , 6A2:O;
!! take the chip select low to select the device:
digital6rite(chip=elect8in, 456);
=82.transfer(data:o=end); !!=end register location
=82.transfer(thisLalue); !!=end value to record into register
+KJ
!! take the chip select high to de#select:
digital6rite(chip=elect8in, 1231);
}
!"
Di)ital %otentiometer Control

:his e.ample controls an Analog Nevices ANJ<GH digital potentiometer. :he ANJ<GH has H
potentiometer channels. Oach channelRs pins are labeled
A # connect this to voltage
6 # this is the potRs wiper, which changes when ou set it
C # connect this to ground.

:he ANJ<GH is =82#compatible,and to command it, ou send two btes, one with the channel
number (G # J) and one with the resistance value for the channel (G # <JJ).

:he circuit:
" All A pins of ANJ<GH connected to &JL
" All C pins of ANJ<GH connected to ground
" An 4ON and a <<G#ohm resisor in series connected from each 6 pin to ground
" D= # to digital pin +G (== pin)
" =N2 # to digital pin ++ (@5=2 pin)
" D4E # to digital pin +B (=DE pin)
"!
!! inslude the =82 librar:
$include X=82.hY
!! set pin +G as the slave select for the digital pot:
const int slave=elect8in % +G;
+KH
void setup() {
!! set the slave=elect8in as an output:
pin@ode (slave=elect8in, 59:89:);
!! initiali?e =82:
=82.begin();
}
void loop() {
!! go through the si. channels of the digital pot:
for (int channel % G; channel X H; channel&&) {
!! change the resistance on this channel from min to ma.:
for (int level % G; level X <JJ; level&&) {
digital8ot6rite(channel, level);
dela(+G);
}
!! wait a second at the top:
dela(+GG);
!! change the resistance on this channel from ma. to min:
for (int level % G; level X <JJ; level&&) {
digital8ot6rite(channel, <JJ # level);
dela(+G);
}
}
}
int digital8ot6rite(int address, int value) {
!! take the == pin low to select the chip:
digital6rite(slave=elect8in,456);
!! send in the address and value via =82:
=82.transfer(address);
=82.transfer(value);
!! take the == pin high to de#select the chip:
digital6rite(slave=elect8in,1231);
}
#&I
be)in#$
2nitiali?es the =82 bus, setting =DE, @5=2, and == to outputs, pulling =DE and @5=2 low and ==
high.
Syntax' =82.begin()
%arameters' 7one
&eturns' 7one
#&I
end#$
Nisables the =82 bus (leaving pin modes unchanged).
+KM
Syntax' =82.end()
%arameters' 7one
&eturns' 7one
#&I
setBitOrder#$
=ets the order of the bits shifted out of and into the =82 bus, either 4=CP2A=: (least#significant bit
first) or @=CP2A=: (most#significant bit first).
Syntax' =82.setCit5rder(order)
%arameters' order: either 4=CP2A=: or @=CP2A=:
&eturns' 7one
#&I
setCloc<Divider#$
=ets the =82 clock divider relative to the sstem clock. :he dividers available are <, F, I, +H, B<, HF,
or +<I. :he default setting is =82;D45DE;N2LF, which sets the =82 clock to one#)uarter the
fre)uenc of the sstem clock.
Syntax' =82.setDlockNivider(divider)
%arameters' divider:
# =82;D45DE;N2L<
# =82;D45DE;N2LF
# =82;D45DE;N2LI
# =82;D45DE;N2L+H
# =82;D45DE;N2LB<
# =82;D45DE;N2LHF or
# =82;D45DE;N2L+<I
&eturns' 7one
#&I
setData-ode#$
=ets the =82 data mode: that is, clock polarit and phase. =ee the 6ikipedia article on =82 for
details.
Syntax' =82.setNata@ode(mode)
%arameters' mode: =82;@5NOG, =82;@5NO+, =82;@5NO<, or =82;@5NOB
&eturns' 7one
+KI
#&I
trans!er#$
:ransfers one bte over the =82 bus, both sending and receiving.
Syntax' =82.transfer(val)
%arameters' val: the bte to send out over the bus
&eturns' the bte read from the bus
s0#x$
Dalculates the s)uare of a number: the number multiplied b itself.
%arameters' .: the number, an data tpe
&eturns' the s)uare of the number
s0rt#x$
Dalculates the s)uare root of a number.
%arameters' .: the number, an data tpe
&eturns double, the numberRs s)uare root.
static
:he static keword is used to create variables that are visible to onl one function. 1owever unlike
local variables that get created and destroed ever time a function is called, static variables persist
beond the function call, preserving their data between function calls.
Lariables declared as static will onl be created and initiali?ed the first time a function is called.
+xample
" Aandom6alk wanders up and down randoml between two endpoints. :he ma.imum move in
" one loop is governed b the parameter Tstepsi?eT.
" A static variable is moved up and down a random amount.
" :his techni)ue is also known as Tpink noiseT and Tdrunken walkT.
"!
$define random6alk4owAange #<G
$define random6alk1ighAange <G
int stepsi?e;
int this:ime;
+KK
int total;
void setup()
{
=erial.begin(KHGG);
}
void loop()
{ !! tetst random6alk function
stepsi?e % J;
this:ime % random6alk(stepsi?e);
=erial.println(this:ime);
dela(+G);
}
int random6alk(int move=i?e){
static int place; !! variable to store value in random walk # declared static so that it stores
!! values in between function calls, but no other functions can change its value
place % place & (random(#move=i?e, move=i?e & +));
if (place X random6alk4owAange){ !! check lower and upper limits
place % place & (random6alk4owAange # place); !! reflect number back in positive direction
}
else if(place Y random6alk1ighAange){
place % place # (place # random6alk1ighAange); !! reflect number back in negative direction
}
return place;
}
Stepper library
Circuit !or "nipolar Stepper -otor B Two %ins
<GG
Circuit !or "nipolar Stepper -otor B Four %ins
<G+
Circuit !or Bipolar Stepper -otor B Two %ins
Circuit !or Bipolar Stepper -otor B Four %ins
<G<
Stepper#steps, pinG, pinP$
Stepper#steps, pinG, pinP, pinQ, pinR$
:his function creates a new instance of the =tepper class that represents a particular stepper motor
attached to our Arduino board. 9se it at the top of our sketch, above setup() and loop(). :he
number of parameters depends on how ouRve wired our motor # either using two or four pins of
the Arduino board.
%arameters steps: the number of steps in one revolution of our motor. 2f our motor gives the
number of degrees per step, divide that number into BHG to get the number of steps
(e.g. BHG ! B.H gives +GG steps). (int)
pin+, pin<: two pins that are attached to the motor (int)
pinB, pinF: optional the last two pins attached to the motor, if itRs connected to four
pins (int)
&eturns' A new instance of the =tepper motor class.
+xample
=tepper m=tepper % =tepper(+GG, J, H);
stepperCsetSpeed#rpms$
=ets the motor speed in rotations per minute (A8@s). :his function doesnRt make the motor turn,
>ust sets the speed at which it will when ou call step().
%arameters' rpms: the speed at which the motor should turn in rotations per minute # a positive
number (long)
&eturns' 7one
stepperCstep#steps$
:urns the motor a specific number of steps, at a speed determined b the most recent call to
set=peed(). :his function is blocking; that is, it will wait until the motor has finished moving to pass
control to the ne.t line in our sketch. Por e.ample, if ou set the speed to, sa, + A8@ and called
step(+GG) on a +GG#step motor, this function would take a full minute to run. Por better control, keep
the speed high and onl go a few steps with each call to step().
%arameters' steps: the number of steps to turn the motor # positive to turn one direction, negative
to turn the other (int)
&eturns' 7one
stepper example
!"
" @otorEnob
<GB
"
" A stepper motor follows the turns of a potentiometer (or other sensor) on analog input G.
"
" http:!!www.arduino.cc!en!Aeference!=tepper. :his e.ample code is in the public domain.
"!
$include X=tepper.hY
!! change this to the number of steps on our motor
$define =:O8= +GG
!! create an instance of the stepper class, specifing the number of steps of the motor and the pins
!! itRs attached to
=tepper stepper(=:O8=, I, K, +G, ++);
!! the previous reading from the analog input
int previous % G;
void setup()
{
!! set the speed of the motor to BG A8@s
stepper.set=peed(BG);
}
void loop()
{
!! get the sensor value
int val % analogAead(G);
!! move a number of steps e)ual to the change in the sensor reading
stepper.step(val # previous);
!! remember the previous value of the sensor
previous % val;
}
stream
=tream is the base class for character and binar based streams. 2t is not called directl, but invoked
whenever ou use a function that relies on it.
=tream defines the reading functions in Arduino. 6hen using an core functionalit that uses a
read() or similar method, ou can safel assume it calls on the =tream class. Por functions like
print(), =tream inherits from the 8rint class.
=ome of the libraries that rel on =tream include :
# =erial
# 6ire
# Othernet Dlient
<GF
# Othernet =erver
# =N
Functions
# available()
# read()
# flush()
# find()
# find9ntil()
# peek()
# readCtes()
# readCtes9ntil()
# parse2nt()
# parsefloat()
# set:imeout()
streamCavailable#$
available() gets the number of btes available in the stream. :his is onl for btes that have alread
arrived.
:his function is part of the =tream class, and is called b an class that inherits from it (6ire,
=erial, etc). =ee the =tream class main page for more information.
Syntax' stream.available()
%arameters' stream : an instance of a class that inherits from =tream.
&eturns' int : the number of btes available to read
streamC!ind#$
find() reads data from the stream until the target string of given length is found :he function returns
true if target string is found, false if timed out.
:his function is part of the =tream class, and is called b an class that inherits from it (6ire,
=erial, etc). =ee the =tream class main page for more information.
Syntax' stream.find(target)
%arameters' stream : an instance of a class that inherits from =tream.
target : the string to search for (char)
&eturns' boolean
streamC!ind"ntil#$
find9ntil() reads data from the stream until the target string of given length or terminator string is
<GJ
found. :he function returns true if target string is found, false if timed out
:his function is part of the =tream class, and is called b an class that inherits from it (6ire,
=erial, etc). =ee the =tream class main page for more information.
Syntax' stream.find9ntil(target, terminal)
%arameters' stream : an instance of a class that inherits from =tream.
target : the string to search for (char)
terminal : the terminal string in the search (char)
&eturns' boolean
streamC!lush#$
flush() clears the buffer once all outgoing characters have been sent.
:his function is part of the =tream class, and is called b an class that inherits from it (6ire,
=erial, etc). =ee the =tream class main page for more information.
Syntax' stream.flush()
%arameters' stream : an instance of a class that inherits from =tream.
&eturns' boolean
streamCparseFloat#$
parsePloat() returns the first valid floating point number from the current position. 2nitial characters
that are not digits (or the minus sign) are skipped. parsePloat() is terminated b the first character
that is not a floating point number.
:his function is part of the =tream class, and is called b an class that inherits from it (6ire,
=erial, etc). =ee the =tream class main page for more information.
Syntax' stream.parsePloat(list)
%arameters' stream : an instance of a class that inherits from =tream.
list : the stream to check for floats (char)
&eturns' float
streamCparse1nt#$
parse2nt() returns the first valid (long) integer number from the current position. 2nitial characters
that are not integers (or the minus sign) are skipped. parse2nt() is terminated b the first character
that is not a digit.
:his function is part of the =tream class, and is called b an class that inherits from it (6ire,
<GH
=erial, etc). =ee the =tream class main page for more information.
Syntax' stream.parse2nt(list)
%arameters' stream : an instance of a class that inherits from =tream.
list : the stream to check for ints (char)
&eturns' int
streamCpee<#$
Aead a bte from the file without advancing to the ne.t one. :hat is, successive calls to peek() will
return the same value, as will the ne.t call to read().
:his function is part of the =tream class, and is called b an class that inherits from it (6ire,
=erial, etc). =ee the =tream class main page for more information.
Syntax' stream.peek()
%arameters' stream : an instance of a class that inherits from =tream.
&eturns' :he ne.t bte (or character), or #+ if none is available.
streamCreadBytes#$
readCtes() read characters from a stream into a buffer. :he function terminates if the determined
length has been read, or it times out (see set:imeout()).
readCtes() returns the number of characters placed in the buffer. A G means no valid data was
found.
:his function is part of the =tream class, and is called b an class that inherits from it (6ire,
=erial, etc). =ee the =tream class main page for more information.
Syntax' stream.readCtes(buffer, length)
%arameters' stream : an instance of a class that inherits from =tream.
buffer: the buffer to store the btes in (charUV or bteUV)
length : the number of btes to read (int)
&eturns' bte
streamCreadBytes"ntil#$
readCtes9ntil() read characters from a stream into a buffer. :he function terminates if the
terminator character is detected, the determined length has been read, or it times out (see
set:imeout()). readCtes9ntil() returns the number of characters placed in the buffer. A G means
no valid data was found.
<GM
:his function is part of the =tream class, and is called b an class that inherits from it (6ire,
=erial, etc). =ee the =tream class main page for more information.
Syntax' stream.readCtes9ntil(character, buffer, length)
%arameters' stream : an instance of a class that inherits from =tream.
character : the character to search for (char)
buffer: the buffer to store the btes in (charUV or bteUV) length : the number of btes
to read (int)
&eturns' bte
streamCread#$
read() reads characters from an incoming stream to the buffer.
:his function is part of the =tream class, and is called b an class that inherits from it (6ire,
=erial, etc). =ee the =tream class main page for more information.
Syntax' stream.read()
%arameters' stream : an instance of a class that inherits from =tream.
&eturns' the first bte of incoming data available (or #+ if no data is available)
streamCsetTimeout#$
set:imeout() sets the ma.imum milliseconds to wait for stream data, it defaults to +GGG
milliseconds. :his function is part of the =tream class, and is called b an class that inherits from it
(6ire, =erial, etc). =ee the =tream class main page for more information.
Syntax' stream.set:imeout(time)
%arameters' stream : an instance of a class that inherits from =tream.
time : timeout duration in milliseconds (long).
&eturns' 7one
strin)
:e.t strings can be represented in two was. ou can use the =tring data tpe, which is part of the
core as of version GG+K, or ou can make a string out of an arra of tpe char and null#terminate it.
:his page described the latter method. Por more details on the =tring ob>ect, which gives ou more
functionalit at the cost of more memor, see the =tring ob>ect page.
+xamples
All of the following are valid declarations for strings.
<GI
char =tr+U+JV;
char =tr<UIV % {RaR, RrR, RdR, RuR, RiR, RnR, RoR};
char =trBUIV % {RaR, RrR, RdR, RuR, RiR, RnR, RoR, R\GR};
char =trFU V % TarduinoT;
char =trJUIV % TarduinoT;
char =trHU+JV % TarduinoT;
%ossibilities !or declarin) strin)s
] Neclare an arra of chars without initiali?ing it as in =tr+
] Neclare an arra of chars (with one e.tra char) and the compiler will add the re)uired null
character, as in =tr<
] O.plicitl add the null character, =trB
] 2nitiali?e with a string constant in )uotation marks; the compiler will si?e the arra to fit the
string constant and a terminating null character, =trF
] 2nitiali?e the arra with an e.plicit si?e and string constant, =trJ
] 2nitiali?e the arra, leaving e.tra space for a larger string, =trH
*ull termination
3enerall, strings are terminated with a null character (A=D22 code G). :his allows functions (like
=erial.print()) to tell where the end of a string is. 5therwise, the would continue reading
subse)uent btes of memor that arenRt actuall part of the string.
:his means that our string needs to have space for one more character than the te.t ou want it to
contain. :hat is wh =tr< and =trJ need to be eight characters, even though TarduinoT is onl seven
# the last position is automaticall filled with a null character. =trF will be automaticall si?ed to
eight characters, one for the e.tra null. 2n =trB, weRve e.plicitl included the null character (written
R\GR) ourselves.
7ote that itRs possible to have a string without a final null character (e.g. if ou had specified the
length of =tr< as seven instead of eight). :his will break most functions that use strings, so ou
shouldnRt do it intentionall. 2f ou notice something behaving strangel (operating on characters
not in the string), however, this could be the problem.
Sin)le 0uotes or double 0uotesW
=trings are alwas defined inside double )uotes (TAbcT) and characters are alwas defined inside
single )uotes(RAR).
(rappin) lon) strin)sC Sou can wrap long strings like this:
char m=tringUV % T:his is the first lineT
T this is the second lineT
T etceteraT;
Arrays o! strin)s
2t is often convenient, when working with large amounts of te.t, such as a pro>ect with an 4DN
displa, to setup an arra of strings. Cecause strings themselves are arras, this is in actuall an
e.ample of a two#dimensional arra.
<GK
2n the code below, the asterisk after the datatpe char Tchar"T indicates that this is an arra of
TpointersT. All arra names are actuall pointers, so this is re)uired to make an arra of arras.
8ointers are one of the more esoteric parts of D for beginners to understand, but it isnRt necessar to
understand pointers in detail to use them effectivel here.
+xample
char" m=tringsUV%{T:his is string +T, T:his is string <T, T:his is string BT,
T:his is string FT, T:his is string JT,T:his is string HT};
void setup(){
=erial.begin(KHGG);
}
void loop(){
for (int i % G; i X H; i&&){
=erial.println(m=tringsUiV);
dela(JGG);
}
}
Strin) class
:he =tring class, part of the core as of version GG+K, allows ou to use and manipulate strings of
te.t in more comple. was than character arras do. Sou can concatenate =trings, append to them,
search for and replace substrings, and more. 2t takes more memor than a simple character arra,
but it is also more useful.
Por reference, character arras are referred to as strings with a small s, and instances of the =tring
class are referred to as =trings with a capital =. 7ote that constant strings, specified in Tdouble
)uotesT are treated as char arras, not instances of the =tring class.
Functions
] =tring()
] charAt()
] compare:o()
] concat()
] ends6ith()
] e)uals()
] e)uals2gnoreDase()
] getCtes()
] inde.5f()
] last2nde.5f()
] length()
] replace()
] setDharAt()
] starts6ith()
] substring()
<+G
] toDharArra()
] to4owerDase()
] to9pperDase()
] trim()
Operators
] UV (element access)
] & (concatenation)
] %% (comparison)
+xamples
5 #tring"onstructors
=tring string5ne % T1ello =tringT; !! using a constant =tring
=tring string5ne % =tring(RaR); !! converting a constant char into a =tring
=tring string:wo % =tring(T:his is a stringT); !! converting a constant string into a =tring ob>ect
=tring string5ne % =tring(string:wo & T with moreT);!! concatenating two strings
=tring string5ne % =tring(+B); !! using a constant integer
=tring string5ne % =tring(analogAead(G), NOD); !! using an int and a base
=tring string5ne % =tring(FJ, 1OQ); !! using an int and a base (he.adecimal)
=tring string5ne % =tring(<JJ, C27); !! using an int and a base (binar)
=tring string5ne % =tring(millis(), NOD); !! using a long and a base
5 #tringAdditionO!erator
Bou can add &trings together in a variety of ways. This is called concatenation and it results in the
original &tring being longer by the length of the &tring or character array with which you
concatenate it. The C operator allows you to combine a &tring with another &tring, with a constant
character array, an 4&CII representation of a constant or variable number, or a constant
character.
!! adding a constant integer to a string:
string:hree % string5ne & +<B;
!! adding a constant long interger to a string:
string:hree % string5ne & +<BFJHMIK;
!! adding a constant character to a string:
string:hree % string5ne & RAR;
!! adding a constant string to a string:
string:hree % string5ne & TabcT;
!! adding two =trings together:
string:hree % string5ne & string:wo;
Bou can also use the C operator to add the results of a function to a &tring, if the function returns
one of the allowed data types mentioned above. 2or e6ample,
string:hree % string5ne & millis();
<++
This is allowable since the millis,- function returns a long integer, which can be added to a &tring.
Bou could also do thisD
string:hree % string5ne & analogAead(AG);
because analog?ead,- returns an integer. &tring concatenation can be very useful when you need to
display a combination of values and the descriptions of those values into one &tring to display via
serial communication, on an LCD display, over an $thernet connection, or anywhere that &trings
are useful.
"aution+ Bou should be careful about concatenating multiple variable types on the same line, as
you may get une6pected results. 2or $6ample
int sensorLalue % analogAead(AG);
=tring string5ne % T=ensor value: T;
=tring string:hree % string5ne & sensorLalue;
=erial.println(string:hree);
results in E&ensor FalueD G*)E or whatever the analog?ead,- result is, but
int sensorLalue % analogAead(AG);
=tring string:hree % T=ensor value: T & sensorLalue;
=erial.println(string:hree);
gives unpredictable results because stringThree never got an initial value before you started
concatenating different data types. #ereHs another e6ample where improper initiali<ation will cause
errorsD
=erial.println(T2 want T & analogAead(AG) & T donutsT);
This wonHt compile because the compiler doesnHt handle the operator precedence correctly. >n the
other hand, the following will compile, but it wonHt run as e6pectedD
int sensorLalue % analogAead(AG);
=tring string:hree % T2 want T & sensorLalue;
=erial.println(string:hree & T donutsT);
It doesnHt run correctly for the same reason as beforeD stringThree never got an initial value before
you started concatenating different data types.
2or best results, initiali<e your &trings before you concatenate them.
5 #tringInde,Of

&tring inde6>f,- and lastInde6>f,-5ethod
The &tring obIect inde6>f,- method gives you the ability to search for the first instance of a
particular character value in a &tring. Bou can also loo for the first instance of the character after
a given offset. The lastInde6>f,- method lets you do the same things from the end of a &tring.
=tring string5ne % TX1:@4YX1OANYXC5NSYT;
int firstDlosingCracket % string5ne.inde.5f(RYR);
<+<
In this case, firstClosing+racet eJuals 0, because the first K character is at position 0 in the &tring
,counting the first character as *-. If you want to get the second closing bracet, you can use the
fact that you now the position of the first one, and search from firstClosing+racet C ' as the
offset, lie soD
string5ne % TX1:@4YX1OANYXC5NSYT;
int secondDlosingCracket % string5ne.inde.5f(RYR, firstDlosingCracket & + );
The result would be '', the position of the closing bracet for the #$4D tag.
If you want to search from the end of the &tring, you can use the lastInde6>f,- method instead. This
function returns the position of the last occurrence of a given character.
string5ne % TX1:@4YX1OANYXC5NSYT;
int last5peningCracket % string5ne.last2nde.5f(RXR);
In this case, last>pening+racet eJuals '), the position of the A for the +>DB tag. If you want the
opening bracet for the #$4D tag, it would be at string>ne.lastInde6>f,HAH, last>pening+racet .'
-, or /.
5 #tringA!!endO!erator
Lust as you can concatenate &trings with other data obIects using the &tring4ddition>perator, you
can also use the C7 operator and the cconcat,- method to append things to &trings. The C7
operator and the concat,- method wor the same way, itHs Iust a matter of which style you prefer.
The two e6amples below illustrate both, and result in the same &tringD
=tring string5ne % TA long integer: T;
!! using &% to add a long variable to a string:
string5ne &% +<BFJHMIK;
or
=tring string5ne % TA long integer: T;
!! using concat() to add a long variable to a string:
string:wo.concat(+<BFJHMIK);
In both cases, string>ne eJuals E4 long integerD ')3G0/M(1E. Lie the C operator, these operators
are handy for assembling longer strings from a combination of data obIects.
5 #tringLengthTrim
length,- returns the length of a &tring. There are many occasions when you need this. 2or
e6ample,if you wanted to mae sure a &tring was less than 'G* characters, to fit it in a te6t
message, you could do thisD
!"
=tring length()

O.amples of how to use length() in a =tring. 5pen the =erial @onitor and start sending characters to
<+B
see the results.
"!
=tring t.t@sg % TT; !! a string for incoming te.t
int last=tring4ength % t.t@sg.length(); !! previous length of the =tring
void setup() {
!! 5pen serial communications and wait for port to open:
=erial.begin(KHGG);
while (*=erial) {
; !! wait for serial port to connect. 7eeded for 4eonardo onl
}
!! send an intro:
=erial.println(T\n\n=tring length():T);
=erial.ptintln();
}
void loop() {
!! add an incoming characters to the =tring:
while (=erial.available() Y G) {
char inDhar % =erial.read();
t.t@sg &% inDhar;
}
!! print the message and a notice if itRs changed:
if (t.t@sg.length() *% last=tring4ength) {
=erial.println(t.t@sg);
=erial.println(t.t@sg.length());
!! if the =tringRs longer than +FG characters, complain:
if (t.t@sg.length() X +FG) {
=erial.println(T:hatRs a perfectl acceptable te.t messageT);
}
else {
=erial.println(T:hatRs too long for a te.t message.T);
}
!! note the length for ne.t time through the loop:
last=tring4ength % t.t@sg.length();
}
}
trim,- is useful for when you now there are e6traneous whitespace characters on the beginning or
the end of a &tring and you want to get rid of them. ;hitespace refers to characters that tae space
but arenHt seen. It includes the single space ,4&CII 3)-, tab ,4&CII 1-, vertical tab ,4&CII ''-, form
feed ,4&CII ')-, carriage return ,4&CII '3-, or newline ,4&CII '*-. The e6ample below shows a
&tring with whitespace, before and after trimmingD
!"
=tring length() and trim()

O.amples of how to use length() and trim() in a =tring
"!
<+F
void setup() {
!! 5pen serial communications and wait for port to open:
=erial.begin(KHGG);
while (*=erial) {
; !! wait for serial port to connect. 7eeded for 4eonardo onl
}
!! send an intro:
=erial.println(T\n\n=tring length() and trim():T);
=erial.println();
}
void loop() {
!! hereRs a =tring with empt spaces at the end (called white space):
=tring string5ne % T1ello* T;
=erial.print(string5ne);
=erial.print(TX### end of string. 4ength: T);
=erial.println(string5ne.length());
!! trim the white space off the string:
string5ne.trim();
=erial.print(string5ne);
=erial.print(TX### end of trimmed string. 4ength: T);
=erial.println(string5ne.length());
!! do nothing while true:
while(true);
}
5 #tring"ase"hanges
!"
=tring Dase changes
O.amples of how to change the case of a string
"!
void setup() {
!! 5pen serial communications and wait for port to open:
=erial.begin(KHGG);
while (*=erial) {
; !! wait for serial port to connect. 7eeded for 4eonardo onl
}
!! send an intro:
=erial.println(T\n\n=tring case changes:T);
=erial.println();
}
void loop() {
!! to9pperDase() changes all letters to upper case:
=tring string5ne % TXhtmlYXheadYXbodYT;
<+J
=erial.println(string5ne);
string5ne.to9pperDase();
=erial.println(string5ne);
!! to4owerDase() changes all letters to lower case:
=tring string:wo % TX!C5NSYX!1:@4YT;
=erial.println(string:wo);
string:wo.to4owerDase();
=erial.println(string:wo);
!! do nothing while true:
while(true);
}
5 #tringRe!lace
"aution+ If you try to replace a substring thatHs more than the whole string itself, nothing will be
replaced. 2or $6ample
=tring string5ne % TXhtmlYXheadYXbodYT;
=tring string:wo % string5ne.replace(TXhtmlYXheadYX!headYXbodYX!bodYX!htmlYT, TClahT);
In this case, the code will compile, but string>ne will remain unchanged, since the replacement
substring is more than the &tring itself.
!"
=tring replace()
O.amples of how to replace characters or substrings of a string
"!
void setup() {
!! 5pen serial communications and wait for port to open:
=erial.begin(KHGG);
while (*=erial) {
; !! wait for serial port to connect. 7eeded for 4eonardo onl
}
!! send an intro:
=erial.println(T\n\n=tring replace:\nT);
=erial.println();
}
void loop() {
=tring string5ne % TXhtmlYXheadYXbodYT;
=erial.println(string5ne);
!! replace() changes all instances of one substring with another:
!! first, make a cop of th original string:
=tring string:wo % string5ne;
!! then perform the replacements:
string:wo.replace(TXT, TX!T);
!! print the original:
=erial.println(T5riginal string: T & string5ne);
<+H
!! and print the modified string:
=erial.println(T@odified string: T & string:wo);
!! ou can also use replace() on single characters:
=tring normal=tring % TbookkeeperT;
=erial.println(Tnormal: T & normal=tring);
=tring leet=tring % normal=tring;
leet=tring.replace(RoR, RGR);
leet=tring.replace(ReR, RBR);
=erial.println(TlBBtspeak: T & leet=tring);
!! do nothing while true:
while(true);
}
5 #tring"haracters
!"
=tring charAt() and setDharAt()

O.amples of how to get and set characters of a =tring
"!
void setup() {
!! 5pen serial communications and wait for port to open:
=erial.begin(KHGG);
while (*=erial) {
; !! wait for serial port to connect. 7eeded for 4eonardo onl
}
=erial.println(T\n\n=tring charAt() and setDharAt():T);
}
void loop() {
!! make a string to report a sensor reading:
=tring report=tring % T=ensorAeading: FJHT;
=erial.println(report=tring);
!! the readingRs most significant digit is at position +J in the report=tring:
char most=ignificantNigit % report=tring.charAt(+J);
=erial.println(T@ost significant digit of the sensor reading is: T & most=ignificantNigit);
!! add blank space:
=erial.println();
!! ou can alo set the character of a string. Dhange the : to a % character
report=tring.setDharAt(+B, R%R);
=erial.println(report=tring);
!! do nothing while true:
while(true);
}
<+M
5 #tring#tarts6ith$nds6ith
starts6ith() and ends6ith() can be used to look for a particular message header, or for a single
character at the end of a =tring. :he can also be used with an offset to look for a substring starting
at a particular position. Por O.ample
string5ne % T1::8!+.+ <GG 5ET;
if (string5ne.starts6ith(T<GG 5ET, K)) {
=erial.println(T3ot an 5E from the serverT);
}
:his is functionall the same as this:
string5ne % T1::8!+.+ <GG 5ET;
if (string5ne.substring(K) %% T<GG 5ET) {
=erial.println(T3ot an 5E from the serverT);
}
Daution: 2f ou look for a position thatRs outside the range of the string,ouRll get unpredictable
results. Por e.ample, in the e.ample above string5ne.starts6ith(T<GG 5ET, +H) wouldnRt check
against the =tring itself, but whatever is in memor >ust beond it. Por best results, make sure the
inde. values ou use for starts6ith and ends6ith are between G and the =tringRs length().
!"
=tring start6ith() and ends6ith()

O.amples of how to use starts6ith() and ends6ith() in a =tring
"!
void setup() {
!! 5pen serial communications and wait for port to open:
=erial.begin(KHGG);
while (*=erial) {
; !! wait for serial port to connect. 7eeded for 4eonardo onl
}
!! send an intro:
=erial.println(T\n\n=tring starts6ith() and ends6ith():T);
=erial.println();
}
void loop() {
!! starts6ith() checks to see if a =tring starts with a particular substring:
=tring string5ne % T1::8!+.+ <GG 5ET;
=erial.println(string5ne);
if (string5ne.starts6ith(T1::8!+.+T)) {
=erial.println(T=erverRs using http version +.+T);
}
!! ou can also look for starts6ith() at an offset position in the string:
string5ne % T1::8!+.+ <GG 5ET;
<+I
if (string5ne.starts6ith(T<GG 5ET, K)) {
=erial.println(T3ot an 5E from the serverT);
}
!! ends6ith() checks to see if a =tring ends with a particular character:
=tring sensorAeading % Tsensor % T;
sensorAeading &% analogAead(AG);
=erial.print (sensorAeading);
if (sensorAeading.ends6ith(G)) {
=erial.println(T. :his reading is divisible b tenT);
}
else {
=erial.println(T. :his reading is not divisible b tenT);
}
!! do nothing while true:
while(true);
}
5 #tring"om!arisonO!erators
starts;ith,- and ends;ith,- can be used to loo for a particular message header, or for a single
character at the end of a &tring. They can also be used with an offset to loo for a substring starting
at a particular position. 2or $6ample
string5ne % T1::8!+.+ <GG 5ET;
if (string5ne.starts6ith(T<GG 5ET, K)) {
=erial.println(T3ot an 5E from the serverT);
}
This is functionally the same as thisD
string5ne % T1::8!+.+ <GG 5ET;
if (string5ne.substring(K) %% T<GG 5ET) {
=erial.println(T3ot an 5E from the serverT);
}
"aution+ If you loo for a position thatHs outside the range of the string,youHll get unpredictable
results. 2or e6ample, in the e6ample above string>ne.starts;ith,E)** >KE, '/- wouldnHt chec
against the &tring itself, but whatever is in memory Iust beyond it. 2or best results, mae sure the
inde6 values you use for starts;ith and ends;ith are between * and the &tringHs length,-.
!"
=tring start6ith() and ends6ith()

O.amples of how to use starts6ith() and ends6ith() in a =tring
"!
void setup() {
!! 5pen serial communications and wait for port to open:
=erial.begin(KHGG);
while (*=erial) {
<+K
; !! wait for serial port to connect. 7eeded for 4eonardo onl
}
!! send an intro:
=erial.println(T\n\n=tring starts6ith() and ends6ith():T);
=erial.println();
}
void loop() {
!! starts6ith() checks to see if a =tring starts with a particular substring:
=tring string5ne % T1::8!+.+ <GG 5ET;
=erial.println(string5ne);
if (string5ne.starts6ith(T1::8!+.+T)) {
=erial.println(T=erverRs using http version +.+T);
}
!! ou can also look for starts6ith() at an offset position in the string:
string5ne % T1::8!+.+ <GG 5ET;
if (string5ne.starts6ith(T<GG 5ET, K)) {
=erial.println(T3ot an 5E from the serverT);
}
!! ends6ith() checks to see if a =tring ends with a particular character:
=tring sensorAeading % Tsensor % T;
sensorAeading &% analogAead(AG);
=erial.print (sensorAeading);
if (sensorAeading.ends6ith(G)) {
=erial.println(T. :his reading is divisible b tenT);
}
else {
=erial.println(T. :his reading is not divisible b tenT);
}
!! do nothing while true:
while(true);
}
5 #tring#ubstring
substring,- with only one parameter loos for a given substring from the position given to the end
of the string. It e6pects that the substring e6tends all the way to the end of the &tring. 2or $6ample
=tring string5ne % TDontent#:pe: te.t!htmlT;
!! substring(inde.) looks for the substring from the inde. position to the end:
if (string5ne.substring(+K) %% ThtmlT) {
}

is true, while
=tring string5ne % TDontent#:pe: te.t!htmlT;
!! substring(inde.) looks for the substring from the inde. position to the end:
if (string5ne.substring(+K) %% ThtmT) {
}
<<G

is not true, because thereHs an l after the htm in the &tring.
substring,- with two parameters loos for a given substring from the first parameter to the second.
2or $6ample
=tring string5ne % TDontent#:pe: te.t!htmlT;
!! ou can also look for a substring in the middle of a string:
if (string5ne.substring(+F,+I) %% Tte.tT) {
}
#tring
X Y #element access$
Allows ou access to the individual characters of a string.
Syntax' char thisDhar % string+UnV
%arameters' char thisDhar # a character variable
string+ # a string variable
int n # a numeric variable
&eturns' the nth char of the string. =ame as charAt().
#tring
charAt#$
Access a particular character of the =tring.
Syntax' string.charAt(n)
%arameters' string: a variable of tpe =tring
n: the character to access
&eturns' the nRth character of the =tring
#tring
compareTo#$
Dompares two =trings, testing whether one comes before or after the other, or whether theRre
e)ual. :he strings are compared character b character, using the A=D22 values of the characters.
:hat means, for e.ample, that RaR comes before RbR but after RAR. 7umbers come before letters.
Syntax' string.compare:o(string<)
<<+
%arameters' string: a variable of tpe =tring
string<: another variable of tpe =tring
&eturns' a negative number: if string comes before string<
G: if string e)uals string<
a positive number: if string comes after string<
#tring
// operator
Dompares two strings for e)ualit. :he comparison is case#sensitive, meaning the =tring ThelloT is
not e)ual to the =tring T1O445T. Punctionall the same as string.e)uals()
Syntax' string+ %% string<
%arameters' string+, string<: variables of tpe =tring
&eturns' true: if string+ e)uals string<
false: otherwise
#tring
concat#$
Dombines, or concatenates two strings into one new =tring. :he second string is appended to the
first, and the result is placed in a new =tring
Syntax' string.concat(string, string<)
%arameters' string, string<: variables of tpe =tring
&eturns' new =tring that is the combination of the original two =trings
<<<
#tring
Strin)#$
Donstructs an instance of the =tring class. :here are multiple versions that construct =trings from
different data tpes (i.e. format them as se)uences of characters), including:
] a constant string of characters, in double )uotes (i.e. a char arra)
] a single constant character, in single )uotes
] another instance of the =tring ob>ect
] a constant integer or long integer
] a constant integer or long integer, using a specified base
] an integer or long integer variable
] an integer or long integer variable, using a specified base
Donstructing a =tring from a number results in a string that contains the A=D22 representation of
that number. :he default is base ten, so
=tring this=tring % =tring(+B)
gives ou the =tring T+BT. Sou can use other bases, however. Por e.ample,
=tring this=tring % =tring(+B, 1OQ)
gives ou the =tring TNT, which is the he.adecimal representation of the decimal value +B.
5r if ou prefer binar,
=tring this=tring % =tring(+B, C27)
gives ou the =tring T+G++T, which is the binar representation of +B.
Syntax' =tring(val)
=tring(val, base)
%arameters' val: a variable to format as a =tring # string, char, bte, int, long, unsigned int,
unsigned long
base (optional) # the base in which to format an integral value
&eturns' an instance of the =tring class
+xamples
All of the following are valid declarations for =trings.
=tring string5ne % T1ello =tringT; !! using a constant =tring
=tring string5ne % =tring(RaR); !! converting a constant char into a =tring
=tring string:wo % =tring(T:his is a stringT); !! converting a constant string into a =tring ob>ect
=tring string5ne % =tring(string:wo & Twith moreT); !! concatenating two strings
=tring string5ne % =tring(+B); !! using a constant integer
=tring string5ne % =tring(analogAead(G), NOD); !! using an int and a base
=tring string5ne % =tring(FJ, 1OQ); !! using an int and a base (he.adecimal)
=tring string5ne % =tring(<JJ, C27); !! using an int and a base (binar)
=tring string5ne % =tring(millis(), NOD); !! using a long and a base
<<B
#tring
ends(ith#$
:ests whether or not a =tring ends with the characters of another =tring.
Syntax' string.ends6ith(string<)
%arameters' string: a variable of tpe =tring
string<: another variable of tpe =tring
&eturns' true: if string ends with the characters of string<
false: otherwise
#tring
e0uals#$
Dompares two strings for e)ualit. :he comparison is case#sensitive, meaning the =tring ThelloT is
not e)ual to the =tring T1O445T.
Syntax' string.e)uals(string<)
%arameters' string, string<: variables of tpe =tring
&eturns' true: if string e)uals string<
false: otherwise
#tring
e0uals1)noreCase#$
Dompares two strings for e)ualit. :he comparison is not case#sensitive, meaning the
=tring(ThelloT) is e)ual to the =tring(T1O445T).
Syntax' string.e)uals2gnoreDase(string<)
%arameters' string, string<: variables of tpe =tring
&eturns' true: if string e)uals string< (ignoring case)
false: otherwise
#tring
)etBytes#$
Dopies the stringRs characters to the supplied buffer.
Syntax' string.getCtes(buf, len)
<<F
%arameters' string: a variable of tpe =tring
buf: the buffer to cop the characters into (bte UV)
len: the si?e of the buffer (unsigned int)
&eturns' 7one
#tring
indexO!#$
4ocates a character or =tring within another =tring. C default, searches from the beginning of the
=tring, but can also start from a given inde., allowing for the locating of all instances of the
character or =tring.
Syntax' string.inde.5f(val)
string.inde.5f(val, from)
%arameters' string: a variable of tpe =tring
val: the value to search for # char or =tring
from: the inde. to start the search from
&eturns' :he inde. of val within the =tring, or #+ if not found.
#tring
last1ndexO!#$
4ocates a character or =tring within another =tring. C default, searches from the end of the =tring,
but can also work backwards from a given inde., allowing for the locating of all instances of the
character or =tring.
Syntax' string.last2nde.5f(val)
string.last2nde.5f(val, from)
%arameters' string: a variable of tpe =tring
val: the value to search for # char or =tring
from: the inde. to work backwards from
&eturns' :he inde. of val within the =tring, or #+ if not found.
#tring
len)th#$
Aeturns the length of the =tring, in characters. (7ote that this doesnRt include a trailing null
character.)
Syntax' string.length()
<<J
%arameters' string: a variable of tpe =tring
&eturns' :he length of the =tring in characters.
#tring
J operator
Dombines, or concatenates two strings into one new =tring. :he second string is appended to the
first, and the result is placed in a new =tring. 6orks the same as string.concat().
Syntax' stringB % string+ & string <; stringB &% string<;
%arameters' string, string<, stringB: variables of tpe =tring
&eturns' new =tring that is the combination of the original two =trings
#tring
replace#$
:he =tring replace() function allows ou to replace all instances of a given character with another
character. Sou can also use replace to replace substrings of a string with a different substring.
Syntax' string.replace(substring+, substring<)
%arameters' string: a variable of tpe =tring
substring+: another variable of tpe =tring
substring<: another variable of tpe =tring
&eturns' another =tring containing the new string with replaced characters.
#tring
setCharAt#$
=ets a character of the =tring. 1as no effect on indices outside the e.isting length of the =tring.
Syntax' string.setDharAt(inde., c)
%arameters' string: a variable of tpe =tring
inde.: the inde. to set the character at
c: the character to store to the given location
&eturns' 7one
<<H
#tring
starts(ith#$
:ests whether or not a =tring starts with the characters of another =tring.
Syntax' string.starts6ith(string<)
%arameters' string, string<: variable< of tpe =tring
&eturns' true: if string starts with the characters of string<
false: otherwise
#tring
substrin)#$
3et a substring of a =tring. :he starting inde. is inclusive (the corresponding character is included
in the substring), but the optional ending inde. is e.clusive (the corresponding character is not
included in the substring). 2f the ending inde. is omitted, the substring continues to the end of the
=tring.
Syntax string.substring(from)
string.substring(from, to)
%arameters' string: a variable of tpe =tring
from: the inde. to start the substring at
to (optional): the inde. to end the substring before
&eturns' the substring
#tring
toCharArray#$
Dopies the stringRs characters to the supplied buffer.
Syntax' string.toDharArra(buf, len)
%arameters' string: a variable of tpe =tring
buf: the buffer to cop the characters into (char UV)
len: the si?e of the buffer (unsigned int)
&eturns' 7one
<<M
#tring
to.owerCase#$
3et a lower#case version of a =tring. As of +.G, to4owerDase() modifies the string in place rather
than returning a new one.
Syntax' string.to4owerDase()
%arameters' string: a variable of tpe =tring
&eturns' none
=tring
to"pperCase#$
3et an upper#case version of a =tring. As of +.G, to9pperDase() modifies the string in place rather
than returning a new one.
Syntax' string.to9pperDase()
%arameters' string: a variable of tpe =tring
&eturns' none
#tring
trim#$
3et a version of the =tring with an leading and trailing whitespace removed. As of +.G, trim()
modifies the string in place rather than returning a new one.
Syntax' string.trim()
%arameters' string: a variable of tpe =tring
&eturns' none
<<I
switch = case statements
4ike if statements, switch...case controls the flow of programs b allowing programmers to specif
different code that should be e.ecuted in various conditions. 2n particular, a switch statement
compares the value of a variable to the values specified in case statements. 6hen a case statement is
found whose value matches that of the variable, the code in that case statement is run.
:he break keword e.its the switch statement, and is tpicall used at the end of each case. 6ithout
a break statement, the switch statement will continue e.ecuting the following e.pressions (Tfalling#
throughT) until a break, or the end of the switch statement is reached.
+xample
switch (var) {
case +:
!!do something when var e)uals +
break;
case <:
!!do something when var e)uals <
break;
default:
!! if nothing else matches, do the default
!! default is optional
}
Syntax switch (var) {
case label:
!! statements
break;
case label:
!! statements
break;
default:
!! statements
}
%arameters' var: the variable whose value to compare to the various cases
label: a value to compare the variable to
tan#rad$
Dalculates the tangent of an angle (in radians). :he result will be between negative infinit and
infinit.
%arameters' rad' the an)le in radians #!loat$
&eturns' :he tangent of the angle (double)
<<K
Time library
:he :ime librar adds timekeeping functionalit to Arduino with or without e.ternal timekeeping
hardware. 2t allows a sketch to get the time and date as: second, minute, hour, da, month and ear.
2t also provides time as a standard D time;t so elapsed times can be easil calculated and time
values shared across different platforms.
:he code is derived from the earlier 8laground Nate:ime librar but is updated to provide an A82
that is more fle.ible and easier to use.
:he download includes e.ample sketches illustrating how similar sketch code can be used with: a
Aeal :ime Dlock,2nternet 7:8 time service, 38= time data, NDPMM radio signal, and =erial time
messages from a computer. :o use all of the features in the librar, ouRll need the 9N8bitewise
librar
Functional Overview
hour(); !! the hour now (G#<B)
minute(); !! the minute now (G#JK)
second(); !! the second now (G#JK)
da(); !! the da now (+#B+)
weekda(); !! da of the week, =unda is da +
month(); !! the month now (+#+<)
ear(); !! the full four digit ear: (<GGK, <G+G etc)
hourPormat+<(); !! the hour now in +< hour format
isA@(); !! returns true if time now is A@
is8@(); !! returns true if time now is 8@
now(); !! returns the current time as seconds since Wan + +KMG
:he time and date functions can take an optional parameter for the time. :his prevents errors if the
time rolls over between elements. Por e.ample, if a new minute begins between getting the minute
and second, the values will be inconsistent. 9sing the following functions eliminates this problem
time;t t % now(); !! store the current time in time variable t
hour(t); !! returns the hour for the given time t
minute(t); !! returns the minute for the given time t
second(t); !! returns the second for the given time t
da(t); !! the da for the given time t
weekda(t); !! da of the week for the given time t
month(t); !! the month for the given time t
ear(t); !! the ear for the given time t
Punctions for managing the timer services are:
set:ime(t); !! set the sstem time to the give time t
set:ime(hr,min,sec,da,month,r); !! another wa to set the time
ad>ust:ime(ad>ustment); !! ad>ust sstem time b adding the ad>ustment value
time=tatus(); !! indicates if time has been set and recentl
!! snchroni?ed. Aeturns one of the following:
time7ot=et !! the time has never been set, the clock started at Wan + +KMG
time7eeds=nc !! the time had been set but a snc attempt did not succeed
time=et !! the time is set and is snced
<BG
:ime and Nate values are not valid if the status is time7ot=et. 5therwise values can be used but the
returned time ma have drifted if the status is time7eeds=nc.
set=nc8rovider(get:imePunction); !! set the e.ternal time provider
set=nc2nterval(interval); !! set the number of seconds between re#snc
=trings for das and months are supported in the librar, see the :ime=erialNate=tring.pde e.ample
in the download
:here are man convenience macros in the time.h file for time constants and conversion of time
units.
9sing the 4ibrar Dop the download to the 4ibrar director. :he :ime director contains the
:ime librar and some e.ample sketches illustrating how the librar can be used with various time
sources:
# :ime=erial.pde shows Arduino as a clock without e.ternal hardware. 2t is snchroni?ed b
time messages sent over the serial port. A companion 8rocessing sketch will automaticall
provide these messages if it is running and connected to the Arduino serial port.
# :imeA:D uses a N=+BGM real time clock to provide time snchroni?ation. A basic A:D
librar named N=+BGMA:D is included in the download. :o run this sketch the N=+BGMA:D
librar must be installed.
# :ime7:8 uses the Arduino Othernet shield to access time using the internet 7:8 time
service.
# :ime38= gets time from a 38=.
+xample
:he test sketch uses a message on the serial port to set the time. A 8rocessing sketch that sends
these messsages is included in the download but ou can test this sketch b sending :+<H<BFM<GG
using the serial monitor (this sets the time to noon on Wan + <G+G). 5n a uni. sstem, ou can set the
time with the shell command:
:[;ad>ust%#I; echo :a((a(date &(s)&HG"HG"a:[;ad>ust)) Y !dev!tt.usbserial#AIGGIpm
4dIust the TN8adIust value to your time<one and the serial port to your 4rduino.
$include X:ime.hY
$define :2@O;@=3;4O7 ++ !! time snc to 8D is 1OANOA followed b 9ni. time;t as ten
A=D22 digits
$define :2@O;1OANOA R:R !! 1eader tag for serial time snc message
$define :2@O;AO^9O=: M !! A=D22 bell character re)uests a time snc message
!! :+<H<BFM<GG !!noon Wan + <G+G
void setup() {
=erial.begin(KHGG);
}
<B+
void loop(){
if(=erial.available() )
{
process=nc@essage();
}
if(time=tatus() %% time7ot=et)
=erial.println(Twaiting for snc messageT);
else
digitalDlockNispla();
dela(+GGG);
}
void digitalDlockNispla(){
!! digital clock displa of the time
=erial.print(hour());
printNigits(minute());
printNigits(second());
=erial.print(T T);
=erial.print(da());
=erial.print(T T);
=erial.print(month());
=erial.print(T T);
=erial.print(ear());
=erial.println();
}
void printNigits(int digits){
!! utilit function for digital clock displa: prints preceding colon and leading G
=erial.print(T:T);
if(digits X +G)
=erial.print(RGR);
=erial.print(digits);
}
void process=nc@essage() {
!! if time snc available from serial port, update time and return true
while(=erial.available() Y% :2@O;@=3;4O7 ){ !! time message consists of header ' +G A=D22
digits
char c % =erial.read() ;
=erial.print(c);
if( c %% :2@O;1OANOA ) {
time;t pctime % G;
for(int i%G; i X :2@O;@=3;4O7 #+; i&&){
c % =erial.read();
if( c Y% RGR '' c X% RKR){
pctime % (+G " pctime) & (c # RGR) ; !! convert digits to a number
}
}
set:ime(pctime); !! =nc Arduino clock to the time received on the serial port
}
}
}
<B<
#ere is a fragment from the Time9T:.pde e6ample setch showing how the sync:rovider
functionality simplifies the setch code. This setch gets time from an Internet time provider ,9T:-
using the 4rduino $thernet shield. 9ote that the loop code does not reJuire any logic to maintain
time sync. The Time library will automatically monitor 9T: and sync the time as necessary.
void setup()
{
=erial.begin(KHGG);
Othernet.begin(mac,ip,gatewa);
=erial.println(Twaiting for sncT);
set=nc8rovider(get7tp:ime);
while(time=tatus()%% time7ot=et)
; !! wait until the time is set b the snc provider
}
void loop()
{
if( now() *% prevNispla) !!update the displa onl if the time has changed
{
prevNispla % now();
digitalDlockNispla();
}
}
void digitalDlockNispla(){
!! digital clock displa of the time
=erial.print(hour());
printNigits(minute());
printNigits(second());
=erial.print(T T);
=erial.print(da());
=erial.print(T T);
=erial.print(month());
=erial.print(T T);
=erial.print(ear());
=erial.println();
}
void printNigits(int digits){
!! utilit function for digital clock displa: prints preceding colon and leading G
=erial.print(T:T);
if(digits X +G)
=erial.print(RGR);
=erial.print(digits);
}
!"######## 7:8 code ##########"!
!! ntp code not shown # see :ime7:8.pde e.ample sketch
<BB
tone#$
3enerates a s)uare wave of the specified fre)uenc (and JG( dut ccle) on a pin. A duration can
be specified, otherwise the wave continues until a call to no:one(). :he pin can be connected to a
pie?o bu??er or other speaker to pla tones.
5nl one tone can be generated at a time. 2f a tone is alread plaing on a different pin, the call to
tone() will have no effect. 2f the tone is plaing on the same pin, the call will set its fre)uenc.
9se of the tone() function will interfere with 86@ output on pins B and ++ (on boards other than
the @ega).
*OT+' if ou want to pla different pitches on multiple pins, ou need to call no:one() on one pin
before calling tone() on the ne.t pin.
Syntax' tone(pin, fre)uenc)
tone(pin, fre)uenc, duration)
%arameters' pin: the pin on which to generate the tone
fre)uenc: the fre)uenc of the tone in hert? # unsigned int
duration: the duration of the tone in milliseconds (optional) # unsigned long
&eturns' nothing
unsi)ned char
An unsigned data tpe that occupies + bte of memor. =ame as the bte datatpe.
:he unsigned char datatpe encodes numbers from G to <JJ.
Por consistenc of Arduino programming stle, the bte data tpe is to be preferred.
+xample
unsigned char mDhar % <FG;
unsi)ned int
9nsigned ints (unsigned integers) are the same as ints in that the store a < bte value. 2nstead of
storing negative numbers however the onl store positive values, ielding a useful range of G to
HJ,JBJ (<-+H) # +).
:he difference between unsigned ints and (signed) ints, lies in the wa the highest bit, sometimes
refered to as the TsignT bit, is interpreted. 2n the Arduino int tpe (which is signed), if the high bit is
a T+T, the number is interpreted as a negative number, and the other +J bits are interpreted with <Rs
complement math.
+xample
9nsigned int led8in % +B;
<BF
=nta.: unsigned int var % val;
$ var # our unsigned int variable name
$ val # the value ou assign to that variable
Codin) Tip
6hen variables are made to e.ceed their ma.imum capacit the Troll overT back to their minimum
capaciti, note that this happens in both directions
unsigned int .
. % G;
. % . # +; !! . now contains HJJBJ # rolls over in neg direction
. % . & +; !! . now contains G # rolls over
unsi)ned lon)
9nsigned long variables are e.tended si?e variables for number storage, and store B< bits (F btes).
9nlike standard longs unsigned longs wonRt store negative numbers, making their range from G to
F,<KF,KHM,<KJ (<-B< # +).
+xample
unsigned long time;
void setup()
{
=erial.begin(KHGG);
}
void loop()
{
=erial.print(T:ime: T);
time % millis();
!!prints time since program started
=erial.println(time);
!! wait a second so as not to send massive amounts of data
dela(+GGG);
}
=nta.: unsigned long var % val;
$ var # our long variable name
$ val # the value ou assign to that variable
<BJ
Variables
A variable is a wa of naming and storing a value for later use b the program, such as data from a
sensor or an intermediate value used in a calculation.
Declarin) Variables
Cefore the are used, all variables have to be declared. Neclaring a variable means defining its tpe,
and optionall, setting an initial value (initiali?ing the variable). Lariables do not have to be
initiali?ed (assigned a value) when the are declared, but it is often useful.
int inputLariable+;
int inputLariable< % G; !! both are correct
8rogrammers should consider the si?e of the numbers the wish to store in choosing variable tpes.
Lariables will roll over when the value stored e.ceeds the space assigned to store it. =ee below for
an e.ample.
Variable Scope
Another important choice that programmers face is where to declare variables. :he specific place
that variables are declared influences how various functions in a program will see the variable. :his
is called variable scope.
1nitialiUin) Variables
Lariables ma be initiali?ed (assigned a starting value) when the are declared or not. 2t is alwas
good programming practice however to double check that a variable has valid data in it, before it is
accessed for some other purpose.
+xample
int calibrationLal % +M; !! declare calibrationLal and set initial value
Variable &ollover
6hen variables are made to e.ceed their ma.imum capacit the Troll overT back to their minimum
capacit, note that this happens in both directions.
int .
. % #B<,MHI;
. % . # +; !! . now contains B<,MHM # rolls over in neg. direction
. % B<,MHM;
. % . & +; !! . now contains #B<,MHI # rolls over
"sin) Variables
5nce variables have been declared, the are used b setting the variable e)ual to the value one
wishes to store with the assignment operator (single e)ual sign). :he assignment operator tells the
program to put whatever is on the right side of the e)ual sign into the variable on the left side.
inputLariable+ % M; !! sets the variable named inputLariable+ to M
<BH
inputLariable< % analogAead(<); !! sets the variable named inputLariable< to the
!! (digiti?ed) input voltage read from analog pin $<
+xamples
int light=ensLal;
char current4etter;
unsigned long speed5f4ight % +IHGGG94;
char error@essage % {Tchoose another optionT}; !! see string
5nce a variable has been set (assigned a value), ou can test its value to see if it meets certain
conditions, or ou can use its value directl. Por instance, the following code tests whether the
inputLariable< is less than +GG, then sets a dela based on inputLariable< which is a minimum of
+GG:
if (inputLariable< X +GG)
{
inputLariable< % +GG;
}
dela(inputLariable<);
:his e.ample shows all three useful operations with variables. 2t tests the variable ( if
(inputLariable< X +GG) ), it sets the variable if it passes the test ( inputLariable< % +GG ), and it uses
the value of the variable as an input parameter to the dela() function ( dela(inputLariable<) )
=tle 7ote: Sou should give our variables descriptive names, so as to make our code more
readable. Lariable names like tilt=ensor or pushCutton help ou (and anone else reading our code
) understand what the variable represents. Lariable names like var or value, on the other hand, do
little to make our code readable.
Sou can name a variable an word that is not alread one of the kewords in Arduino. Avoid
beginning variable names with numeral characters.
=ome variable tpes
$ char
$ bte
$ int
$ unsigned int
$ long
$ unsigned long
$ float
$ double
void
:he void keword is used onl in function declarations. 2t indicates that the function is e.pected to
return no information to the function from which it was called.
<BM
+xample
!! actions are performed in the functions TsetupT and TloopT
!! but no information is reported to the larger program
void setup()
{
!! ...
}
void loop()
{
!! ...
}
volatile <eyword
volatile is a keword known as a variable )ualifier, it is usuall used before the datatpe of a
variable, to modif the wa in which the compiler and subse)uent program treats the variable.
Neclaring a variable volatile is a directive to the compiler. :he compiler is software which
translates our D!D&& code into the machine code, which are the real instructions for the Atmega
chip in the Arduino.
=pecificall, it directs the compiler to load the variable from AA@ and not from a storage register,
which is a temporar memor location where program variables are stored and manipulated. 9nder
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 b something beond the
control of the code section in which it appears, such as a concurrentl e.ecuting thread. 2n the
Arduino, the onl place that this is likel to occur is in sections of code associated with interrupts,
called an interrupt service routine.
+xample
!! toggles 4ON when interrupt pin changes state
int pin % +B;
volatile int state % 456;
void setup()
{
pin@ode(pin, 59:89:);
attach2nterrupt(G, blink, D1A73O);
}
void loop()
{
digital6rite(pin, state);
}
<BI
void blink()
{
state % *state;
}
while loops
while loops will loop continuousl, and infinitel, until the e.pression inside the parenthesis, ()
becomes false. =omething must change the tested variable, or the while loop will never e.it. :his
could be in our code, such as an incremented variable, or an e.ternal condition, such as testing a
sensor.
Syntax' while(e.pression){
!! statement(s)
}
%arameters' e.pression # a (boolean) D statement that evaluates to true or false
+xample
var % G;
while(var X <GG){
!! do something repetitive <GG times
var&&;
}
(iFi library
6ith the Arduino 6iPi =hield, this librar allows an Arduino board to connect to the internet. 2t can
serve as either a server accepting incoming connections or a client making outgoing ones. :he
librar supports 6O8 and 68A< 8ersonal encrption, but not 68A< Onterprise. Also note, if the
==2N is not broadcast, the shield cannot connect.
Arduino communicates with the 6iPi shield using the =82 bus. :his is on digital pins ++, +<, and +B
on the 9no and pins JG, J+, and J< on the @ega. 5n both boards, pin +G is used as ==. 5n the
@ega, the hardware == pin, JB, is not used but it must be kept as an output or the =82 interface
wonRt work. Nigital pin M is used as a handshake pin between the 6ifi shield and the Arduino, and
should not be used.
:he 6iPi librar is ver similar to the Othernet librar, and man of the function calls are the same.
Por additional information on the 6iPi shield, see the 3etting =tarted page and the 6iPi shield
hardware page.
(iFi class
:he 6iPi class initiali?es the ethernet librar and network settings.
<BK
" begin()
" disconnect()
" ==2N()
" C==2N()
" A==2()
" encrption:pe()
" scan7etworks()
" get=ocket()
" macAddress()
1%Address class
:he 28Address class provides information about the network configuration.
" local28()
" subnet@ask()
" gatewa28()
Server class
:he =erver class creates servers which can send data to and receive data from connected clients
(programs running on other computers or devices).
" =erver
" 6iPi=erver()
" begin()
" available()
" write()
" print()
" println()
Client class
:he client class creates clients that can connect to servers and send and receive data.
" Dlient
" 6iPiDlient()
" connected()
" connect()
" write()
" print()
" println()
" available()
" read()
" flush()
" stop()
<FG
+xamples
"onnectNo$ncry!tion
!"
:his e.ample connects to an unencrpted 6ifi network. :hen it prints the @AD address of the
6ifi shield, the 28 address obtained, and other network details.
Dircuit:
" 6iPi shield attached
"!
$include X6iPi.hY
char ssidUV % Tour7etworkT; !! the name of our network
int status % 64;2N4O;=:A:9=; !! the 6ifi radioRs status
void setup() {
!! initiali?e serial:
=erial.begin(KHGG);
!! attempt to connect to an open network:
=erial.print(TAttempting to connect to open network: T);
=erial.println(ssid);
status % 6iPi.begin(ssid);
!! if ouRre not connected, stop here:
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
while(true);
}
!! if ou are connected :
else {
=erial.print(TSouRre connected to the networkT);
printDurrent7et();
print6ifiNata();
}
}
void loop() {
!! check the network connection once ever +G seconds:
dela(+GGGG);
printDurrent7et();
}
void print6ifiNata() {
!! print our 6iPi shieldRs 28 address:
28Address ip % 6iPi.local28();
=erial.print(T28 Address: T);
=erial.println(ip);
=erial.println(ip);
<F+
!! print our @AD address:
bte macUHV;
6iPi.macAddress(mac);
=erial.print(T@AD address: T);
=erial.print(macUJV,1OQ);
=erial.print(T:T);
=erial.print(macUFV,1OQ);
=erial.print(T:T);
=erial.print(macUBV,1OQ);
=erial.print(T:T);
=erial.print(macU<V,1OQ);
=erial.print(T:T);
=erial.print(macU+V,1OQ);
=erial.print(T:T);
=erial.println(macUGV,1OQ);
!! print our subnet mask:
28Address subnet % 6iPi.subnet@ask();
=erial.print(T7et@ask: T);
=erial.println(subnet);
!! print our gatewa address:
28Address gatewa % 6iPi.gatewa28();
=erial.print(T3atewa: T);
=erial.println(gatewa);
}
void printDurrent7et() {
!! print the ==2N of the network ouRre attached to:
=erial.print(T==2N: T);
=erial.println(6iPi.==2N());
!! print the @AD address of the router ouRre attached to:
bte bssidUHV;
6iPi.C==2N(bssid);
=erial.print(TC==2N: T);
=erial.print(bssidUJV,1OQ);
=erial.print(T:T);
=erial.print(bssidUFV,1OQ);
=erial.print(T:T);
=erial.print(bssidUBV,1OQ);
=erial.print(T:T);
=erial.print(bssidU<V,1OQ);
=erial.print(T:T);
=erial.print(bssidU+V,1OQ);
=erial.print(T:T);
=erial.println(bssidUGV,1OQ);
!! print the received signal strength:
long rssi % 6iPi.A==2();
=erial.print(Tsignal strength (A==2):T);
=erial.println(rssi);
<F<
!! print the encrption tpe:
bte encrption % 6iPi.encrption:pe();
=erial.print(TOncrption :pe:T);
=erial.println(encrption,1OQ);
}
"onnect6ith6$&
!"
:his e.ample connects to a 6O8#encrpted 6ifi network. :hen it prints the @AD address of the
6ifi shield, the 28 address obtained, and other network details.
2f ou use FG#bit 6O8, ou need a ke that is +G characters long, and the characters must be
he.adecimal (G#K or A#P). e.g. for FG#bit, ACCANOAPG+ will work, but ACCANOAP wonRt work
(too short) and ACCA2=NOAP wonRt work (2 and = are not he.adecimal characters).
Por +<I#bit, ou need a string that is <H characters long. NGNGNOANPGGNACCANOAPCOANON
will work because itRs <H characters, all in the G#K, A#P range.
Dircuit:
" 6iPi shield attached
"!
$include X6iPi.hY
char ssidUV % Tour7etworkT; !! our network ==2N (name)
char keUV % TNGNGNOANPGGNACCANOAPCOANONT; !! our network ke
int ke2nde. % G; !! our network ke 2nde. number
int status % 64;2N4O;=:A:9=; !! the 6ifi radioRs status
void setup() {
!! initiali?e serial:
=erial.begin(KHGG);
!! attempt to connect to an open network:
=erial.print(TAttempting to connect to 6O8 network: T);
=erial.println(ssid);
status % 6iPi.begin(ssid, ke2nde., ke);
!! if ouRre not connected, stop here:
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
while(true);
}
!! if ou are connected :
else {
=erial.print(TSouRre connected to the networkT);
printDurrent7et();
print6ifiNata();
<FB
}
}
void loop() {
!! check the network connection once ever +G seconds:
dela(+GGGG);
printDurrent7et();
}
void print6ifiNata() {
!! print our 6iPi shieldRs 28 address:
28Address ip % 6iPi.local28();
=erial.print(T28 Address: T);
=erial.println(ip);
=erial.println(ip);
!! print our @AD address:
bte macUHV;
6iPi.macAddress(mac);
=erial.print(T@AD address: T);
=erial.print(macUJV,1OQ);
=erial.print(T:T);
=erial.print(macUFV,1OQ);
=erial.print(T:T);
=erial.print(macUBV,1OQ);
=erial.print(T:T);
=erial.print(macU<V,1OQ);
=erial.print(T:T);
=erial.print(macU+V,1OQ);
=erial.print(T:T);
=erial.println(macUGV,1OQ);
}
void printDurrent7et() {
!! print the ==2N of the network ouRre attached to:
=erial.print(T==2N: T);
=erial.println(6iPi.==2N());
!! print the @AD address of the router ouRre attached to:
bte bssidUHV;
6iPi.C==2N(bssid);
=erial.print(TC==2N: T);
=erial.print(bssidUJV,1OQ);
=erial.print(T:T);
=erial.print(bssidUFV,1OQ);
=erial.print(T:T);
=erial.print(bssidUBV,1OQ);
=erial.print(T:T);
=erial.print(bssidU<V,1OQ);
=erial.print(T:T);
=erial.print(bssidU+V,1OQ);
=erial.print(T:T);
<FF
=erial.println(bssidUGV,1OQ);
!! print the received signal strength:
long rssi % 6iPi.A==2();
=erial.print(Tsignal strength (A==2):T);
=erial.println(rssi);
!! print the encrption tpe:
bte encrption % 6iPi.encrption:pe();
=erial.print(TOncrption :pe:T);
=erial.println(encrption,1OQ);
=erial.println();
}
"onnect6ith6&A
!"
:his e.ample connects to a 68A#encrpted 6ifi network. :hen it prints the @AD address of the
6ifi shield, the 28 address obtained, and other network details.
Dircuit:
" 6iPi shield attached
"!
$include X6iPi.hY
char ssidUV % Tnetwork7ameT; !! our network ==2N (name)
char passUV % Tour8asswordT; !! our network password
int status % 64;2N4O;=:A:9=; !! the 6ifi radioRs status
void setup() {
!! initiali?e serial:
=erial.begin(KHGG);
!! attempt to connect to an open network:
=erial.print(TAttempting to connect to 68A network: T);
=erial.println(ssid);
status % 6iPi.begin(ssid, pass);
!! if ouRre not connected, stop here:
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
while(true);
}
!! if ou are connected :
else {
=erial.print(TSouRre connected to the networkT);
printDurrent7et();
print6ifiNata();
<FJ
}
}
void loop() {
!! check the network connection once ever +G seconds:
dela(+GGGG);
printDurrent7et();
}
void print6ifiNata() {
!! print our 6iPi shieldRs 28 address:
28Address ip % 6iPi.local28();
=erial.print(T28 Address: T);
=erial.println(ip);
=erial.println(ip);
!! print our @AD address:
bte macUHV;
6iPi.macAddress(mac);
=erial.print(T@AD address: T);
=erial.print(macUJV,1OQ);
=erial.print(T:T);
=erial.print(macUFV,1OQ);
=erial.print(T:T);
=erial.print(macUBV,1OQ);
=erial.print(T:T);
=erial.print(macU<V,1OQ);
=erial.print(T:T);
=erial.print(macU+V,1OQ);
=erial.print(T:T);
=erial.println(macUGV,1OQ);
}
void printDurrent7et() {
!! print the ==2N of the network ouRre attached to:
=erial.print(T==2N: T);
=erial.println(6iPi.==2N());
!! print the @AD address of the router ouRre attached to:
bte bssidUHV;
6iPi.C==2N(bssid);
=erial.print(TC==2N: T);
=erial.print(bssidUJV,1OQ);
=erial.print(T:T);
=erial.print(bssidUFV,1OQ);
=erial.print(T:T);
=erial.print(bssidUBV,1OQ);
=erial.print(T:T);
=erial.print(bssidU<V,1OQ);
=erial.print(T:T);
=erial.print(bssidU+V,1OQ);
<FH
=erial.print(T:T);
=erial.println(bssidUGV,1OQ);
!! print the received signal strength:
long rssi % 6iPi.A==2();
=erial.print(Tsignal strength (A==2):T);
=erial.println(rssi);
!! print the encrption tpe:
bte encrption % 6iPi.encrption:pe();
=erial.print(TOncrption :pe:T);
=erial.println(encrption,1OQ);
=erial.println();
}
#canNet-or(s
!"
:his e.ample prints the 6ifi shieldRs @AD address, and scans for available 6ifi networks using
the 6ifi shield. Over ten seconds, it scans again. 2t doesnRt actuall connect to an network, so no
encrption scheme is specified.
Dircuit:
" 6iPi shield attached
"!
$ include X=82.hY
$include X6iPi.hY
void setup() {
!! initiali?e serial and wait for the port to open:
=erial.begin(KHGG);
!! attempt to connect using 6O8 encrption:
=erial.println(T2nitiali?ing 6ifi...T);
print@acAddress();
!! scan for e.isting networks:
=erial.println(T=canning available networks...T);
list7etworks();
}
void loop() {
dela(+GGGG);
!! scan for e.isting networks:
=erial.println(T=canning available networks...T);
<FM
list7etworks();
}
void print@acAddress() {
!! the @AD address of our 6ifi shield
bte macUHV;
!! print our @AD address:
6iPi.macAddress(mac);
=erial.print(T@AD: T);
=erial.print(macUJV,1OQ);
=erial.print(T:T);
=erial.print(macUFV,1OQ);
=erial.print(T:T);
=erial.print(macUBV,1OQ);
=erial.print(T:T);
=erial.print(macU<V,1OQ);
=erial.print(T:T);
=erial.print(macU+V,1OQ);
=erial.print(T:T);
=erial.println(macUGV,1OQ);
}
void list7etworks() {
!! scan for nearb networks:
=erial.println(T"" =can 7etworks ""T);
bte num=sid % 6iPi.scan7etworks();
!! print the list of networks seen:
=erial.print(Tnumber of available networks:T);
=erial.println(num=sid);
!! print the network number and name for each network found:
for (int this7et % G; this7etXnum=sid; this7et&&) {
=erial.print(this7et);
=erial.print(T) T);
=erial.print(6iPi.==2N(this7et));
=erial.print(T\t=ignal: T);
=erial.print(6iPi.A==2(this7et));
=erial.print(T dCmT);
=erial.print(T\tOncrption: T);
=erial.println(6iPi.encrption:pe(this7et));
}
}
<FI
!"
Chat Server
A simple server that distributes an incoming messages to all connected clients. :o use telnet to
our deviceRs 28 address and tpe. Sou can see the clientRs input in the serial monitor as well.
:his e.ample is written for a network using 68A encrption. Por 6O8 or 68A, change the
6ifi.begin() call accordingl.
Dircuit:
" 6iPi shield attached
"!
$include X=82.hY
$include X6iPi.hY
char ssidUV % TSour7etworkT; !! our network ==2N (name)
char passUV % TpasswordT; !! our network password (use for 68A, or use as ke for 6O8)
int ke2nde. % G; !! our network ke 2nde. number (needed onl for 6O8)
int status % 64;2N4O;=:A:9=;
6iPi=erver server(<B);
boolean alreadDonnected % false; !! whether or not the client was connected previousl
void setup() {
!! start serial port:
=erial.begin(KHGG);
!! attempt to connect to 6ifi network:
while ( status *% 64;D577OD:ON) {
=erial.print(TAttempting to connect to ==2N: T);
=erial.println(ssid);
status % 6iPi.begin(ssid, pass);
!! wait +G seconds for connection:
dela(+GGGG);
}
!! start the server:
server.begin();
!! ouRre connected now, so print out the status:
print6ifi=tatus();
}
void loop() {
!! wait for a new client:
6iPiDlient client % server.available();
!! when the client sends the first bte, sa hello:
if (client) {
<FK
if (*alreadDonnected) {
!! clead out the input buffer:
client.flush();
=erial.println(T6e have a new clientT);
client.println(T1ello, client*T);
alreadDonnected % true;
}
if (client.available() Y G) {
!! read the btes incoming from the client:
char thisDhar % client.read();
!! echo the btes back to the client:
server.write(thisDhar);
!! echo the btes to the server as well:
=erial.write(thisDhar);
}
}
}
void print6ifi=tatus() {
!! print the ==2N of the network ouRre attached to:
=erial.print(T==2N: T);
=erial.println(6iPi.==2N());
!! print our 6iPi shieldRs 28 address:
28Address ip % 6iPi.local28();
=erial.print(T28 Address: T);
=erial.println(ip);
!! print the received signal strength:
long rssi % 6iPi.A==2();
=erial.print(Tsignal strength (A==2):T);
=erial.print(rssi);
=erial.println(T dCmT);
}
!"
(i!i %achube sensor client
:his sketch connects an analog sensor to 8achube (http:!!www.pachube.com) using an Arduino
6ifi shield.
:his e.ample is written for a network using 68A encrption. Por 6O8 or 68A, change the
6ifi.begin() call accordingl.
:his e.ample has been updated to use version <.G of the 8achube.com A82. :o make it work, create
a feed with a datastream, and give it the 2N sensor+. 5r change the code below to match our feed.
Dircuit:
<JG
" Analog sensor attached to analog in G
" 6ifi shield attached to pins +G, ++, +<, +B
"!
$include X=82.hY
$include X6iPi.hY
$define A82EOS TS59A A82 EOS 35O= 1OAOT !! replace our pachube api ke here
$define POON2N GGGGG !! replace our feed 2N
$define 9=OAA3O7: T@ Arduino 8ro>ectT !! user agent is the pro>ect name
char ssidUV % Tour7etworkT; !! our network ==2N (name)
char passUV % Tsecret8asswordT; !! our network password
int status % 64;2N4O;=:A:9=;
!! initiali?e the librar instance:
6iPiDlient client;
!! if ou donRt want to use N7= (and reduce our sketch si?e)
!! use the numeric 28 instead of the name for the server:
28Address server(<+H,J<,<BB,+<<); !! numeric 28 for api.pachube.com
!!char serverUV % Tapi.pachube.comT; !! name address for pachube A82
unsigned long lastDonnection:ime % G; !! last time ou connected to the server, in
milliseconds
boolean lastDonnected % false; !! state of the connection last time through the main loop
const unsigned long posting2nterval % +G"+GGG; !!dela between updates to 8achube.com
void setup() {
!! start serial port:
=erial.begin(KHGG);
!! attempt to connect to 6ifi network:
while ( status *% 64;D577OD:ON) {
=erial.print(TAttempting to connect to ==2N: T);
=erial.println(ssid);
status % 6iPi.begin(ssid, pass);
!! wait +G seconds for connection:
dela(+GGGG);
}
!! ouRre connected now, so print out the status:
print6ifi=tatus();
}
void loop() {
!! read the analog sensor:
int sensorAeading % analogAead(AG);
!! if thereRs incoming data from the net connection.
!! send it out the serial port. :his is for debugging
!! purposes onl:
if (client.available()) {
<J+
char c % client.read();
=erial.print(c);
}
!! if thereRs no net connection, but there was one last time
!! through the loop, then stop the client:
if (*client.connected() '' lastDonnected) {
=erial.println();
=erial.println(Tdisconnecting.T);
client.stop();
}
!! if ouRre not connected, and ten seconds have passed since
!! our last connection, then connect again and send data:
if(*client.connected() '' (millis() # lastDonnection:ime Y posting2nterval)) {
sendNata(sensorAeading);
}
!! store the state of the connection for ne.t time through
!! the loop:
lastDonnected % client.connected();
}
!! this method makes a 1::8 connection to the server:
void sendNata(int thisNata) {
!! if thereRs a successful connection:
if (client.connect(server, IG)) {
=erial.println(Tconnecting...T);
!! send the 1::8 89: re)uest:
client.print(T89: !v<!feeds!T);
client.print(POON2N);
client.println(T.csv 1::8!+.+T);
client.println(T1ost: api.pachube.comT);
client.print(TQ#8achubeApiEe: T);
client.println(A82EOS);
client.print(T9ser#Agent: T);
client.println(9=OAA3O7:);
client.print(TDontent#4ength: T);
!! calculate the length of the sensor reading in btes:
!! I btes for Tsensor+,T & number of digits of the data:
int this4ength % I & get4ength(thisNata);
client.println(this4ength);
!! last pieces of the 1::8 89: re)uest:
client.println(TDontent#:pe: te.t!csvT);
client.println(TDonnection: closeT);
client.println();
!! hereRs the actual content of the 89: re)uest:
client.print(Tsensor+,T);
client.println(thisNata);
<J<
}
else {
!! if ou couldnRt make a connection:
=erial.println(Tconnection failedT);
=erial.println();
=erial.println(Tdisconnecting.T);
client.stop();
}
!! note the time that the connection was made or attempted:
lastDonnection:ime % millis();
}
!! :his method calculates the number of digits in the
!! sensor reading. =ince each digit of the A=D22 decimal
!! representation is a bte, the number of digits e)uals
!! the number of btes:
int get4ength(int someLalue) {
!! thereRs at least one bte:
int digits % +;
!! continuall divide the value b ten,
!! adding one to the digit count for each
!! time ou divide, until ouRre at G:
int dividend % someLalue !+G;
while (dividend Y G) {
dividend % dividend !+G;
digits&&;
}
!! return the number of digits:
return digits;
}
void print6ifi=tatus() {
!! print the ==2N of the network ouRre attached to:
=erial.print(T==2N: T);
=erial.println(6iPi.==2N());
!! print our 6iPi shieldRs 28 address:
28Address ip % 6iPi.local28();
=erial.print(T28 Address: T);
=erial.println(ip);
!! print the received signal strength:
long rssi % 6iPi.A==2();
=erial.print(Tsignal strength (A==2):T);
=erial.print(rssi);
=erial.println(T dCmT);
}
<JB
!"
(i!i %achube sensor client with Strin)s
:his sketch connects an analog sensor to 8achube using a Arduino 6ifi shield.
:his e.ample is written for a network using 68A encrption. Por 6O8 or 68A, change the
6ifi.begin() call accordingl.
:his e.ample has been updated to use version <.G of the 8achube.com A82. :o make it work, create
a feed with a datastream, and give it the 2N sensor+. 5r change the code below to match our feed.
:his e.ample uses the =tring librar, which is part of the Arduino core from version GG+K.
Dircuit:
" Analog sensor attached to analog in G
" 6ifi shield attached to pins +G, ++, +<, +B
"!
$include X=82.hY
$include X6iPi.hY
$define A82EOS TS59A A82 EOS 35O= 1OAOT !! replace our pachube api ke here
$define POON2N GGGGG !! replace our feed 2N
$define 9=OAA3O7: T@ Arduino 8ro>ectT !! user agent is the pro>ect name
char ssidUV % Tour7etworkT; !! our network ==2N (name)
char passUV % Tsecret8asswordT; !! our network password
int status % 64;2N4O;=:A:9=;
!! initiali?e the librar instance:
6iPiDlient client;
!! if ou donRt want to use N7= (and reduce our sketch si?e)
!! use the numeric 28 instead of the name for the server:
!!28Address server(<+H,J<,<BB,+<<); !! numeric 28 for api.pachube.com
char serverUV % Tapi.pachube.comT; !! name address for pachube A82
unsigned long lastDonnection:ime % G; !! last time ou connected to the server, in
milliseconds
boolean lastDonnected % false; !! state of the connection last time through the main loop
const unsigned long posting2nterval % +G"+GGG; !!dela between updates to 8achube.com
void setup() {
!! start serial port:
=erial.begin(KHGG);
!! attempt to connect to 6ifi network:
while ( status *% 64;D577OD:ON) {
=erial.print(TAttempting to connect to ==2N: T);
=erial.println(ssid);
status % 6iPi.begin(ssid, pass);
<JF
!! wait +G seconds for connection:
dela(+GGGG);
}
!! ouRre connected now, so print out the status:
print6ifi=tatus();
}
void loop() {
!! read the analog sensor:
int sensorAeading % analogAead(AG);
!! convert the data to a =tring to send it:
=tring data=tring % Tsensor+,T;
data=tring &% sensorAeading;
!! ou can append multiple readings to this =tring if our
!! pachube feed is set up to handle multiple values:
int other=ensorAeading % analogAead(A+);
data=tring &% T\nsensor<,T;
data=tring &% other=ensorAeading;
!! if thereRs incoming data from the net connection.
!! send it out the serial port. :his is for debugging
!! purposes onl:
if (client.available()) {
char c % client.read();
=erial.print(c);
}
!! if thereRs no net connection, but there was one last time
!! through the loop, then stop the client:
if (*client.connected() '' lastDonnected) {
=erial.println();
=erial.println(Tdisconnecting.T);
client.stop();
}
!! if ouRre not connected, and ten seconds have passed since
!! our last connection, then connect again and send data:
if(*client.connected() '' (millis() # lastDonnection:ime Y posting2nterval)) {
sendNata(data=tring);
}
!! store the state of the connection for ne.t time through
!! the loop:
lastDonnected % client.connected();
}
!! this method makes a 1::8 connection to the server:
void sendNata(=tring thisNata) {
!! if thereRs a successful connection:
if (client.connect(server, IG)) {
=erial.println(Tconnecting...T);
<JJ
!! send the 1::8 89: re)uest:
client.print(T89: !v<!feeds!T);
client.print(POON2N);
client.println(T.csv 1::8!+.+T);
client.println(T1ost: api.pachube.comT);
client.print(TQ#8achubeApiEe: T);
client.println(A82EOS);
client.print(T9ser#Agent: T);
client.println(9=OAA3O7:);
client.print(TDontent#4ength: T);
client.println(thisNata.length());
!! last pieces of the 1::8 89: re)uest:
client.println(TDontent#:pe: te.t!csvT);
client.println(TDonnection: closeT);
client.println();
!! hereRs the actual content of the 89: re)uest:
client.println(thisNata);
}
else {
!! if ou couldnRt make a connection:
=erial.println(Tconnection failedT);
=erial.println();
=erial.println(Tdisconnecting.T);
client.stop();
}
!! note the time that the connection was made or attempted:
lastDonnection:ime % millis();
}
void print6ifi=tatus() {
!! print the ==2N of the network ouRre attached to:
=erial.print(T==2N: T);
=erial.println(6iPi.==2N());
!! print our 6iPi shieldRs 28 address:
28Address ip % 6iPi.local28();
=erial.print(T28 Address: T);
=erial.println(ip);
!! print the received signal strength:
long rssi % 6iPi.A==2();
=erial.print(Tsignal strength (A==2):T);
=erial.print(rssi);
=erial.println(T dCmT);
}
<JH
6i4iT-itter"lient
!" 6ifi :witter Dlient with =trings
:his sketch connects to :witter using using an Arduino 6iPi shield. 2t parses the Q@4 returned,
and looks for Xte.tYthis is a tweetX!te.tY
:his e.ample is written for a network using 68A encrption. Por 6O8 or 68A, change the
6ifi.begin() call accordingl.
:his e.ample uses the =tring librar, which is part of the Arduino core from version GG+K.
Dircuit:
" 6iPi shield attached to pins +G, ++, +<, +B
"!
$include X=82.hY
$include X6iPi.hY
char ssidUV % TSour7etworkT; !! our network ==2N (name)
char passUV % TpasswordT; !! our network password (use for 68A, or use as ke for 6O8)
int ke2nde. % G; !! our network ke 2nde. number (needed onl for 6O8)
int status % 64;2N4O;=:A:9=; !! status of the wifi connection
!! initiali?e the librar instance:
6iPiDlient client;
const unsigned long re)uest2nterval % BG"+GGG; !! dela between re)uests; BG seconds
!! if ou donRt want to use N7= (and reduce our sketch si?e)
!! use the numeric 28 instead of the name for the server:
!!28Address server(+KK,JK,+FK,<GG); !! numeric 28 for api.twitter.com
char serverUV % Tapi.twitter.comT; !! name address for twitter A82
boolean re)uested; !! whether ouRve made a re)uest since connecting
unsigned long lastAttempt:ime % G; !! last time ou connected to the server, in milliseconds
=tring current4ine % TT; !! string to hold the te.t from server
=tring tweet % TT; !! string to hold the tweet
boolean reading:weet % false; !! if ouRre currentl reading the tweet
void setup() {
!! reserve space for the strings:
current4ine.reserve(<JH);
tweet.reserve(+JG);
!! start serial port:
=erial.begin(KHGG);
!! attempt to connect to 6ifi network:
while ( status *% 64;D577OD:ON) {
=erial.print(TAttempting to connect to ==2N: T);
<JM
=erial.println(ssid);
status % 6iPi.begin(ssid, pass);
!! wait +G seconds for connection:
dela(+GGGG);
}
!! ouRre connected now, so print out the status:
print6ifi=tatus();
connect:o=erver();
}
void loop()
{
if (client.connected()) {
if (client.available()) {
!! read incoming btes:
char inDhar % client.read();
!! add incoming bte to end of line:
current4ine &% inDhar;
!! if ou get a newline, clear the line:
if (inDhar %% R\nR) {
current4ine % TT;
}
!! if the current line ends with Xte.tY, it will
!! be followed b the tweet:
if ( current4ine.ends6ith(TXte.tYT)) {
!! tweet is beginning. Dlear the tweet string:
reading:weet % true;
tweet % TT;
!! break out of the loop so this character isnRt added to the tweet:
return;
}
!! if ouRre currentl reading the btes of a tweet,
!! add them to the tweet =tring:
if (reading:weet) {
if (inDhar *% RXR) {
tweet &% inDhar;
}
else {
!! if ou got a TXT character,
!! ouRve reached the end of the tweet:
reading:weet % false;
=erial.println(tweet);
!! close the connection to the server:
client.stop();
}
}
}
}
else if (millis() # lastAttempt:ime Y re)uest2nterval) {
!! if ouRre not connected, and two minutes have passed since
<JI
!! our last connection, then attempt to connect again:
connect:o=erver();
}
}
void connect:o=erver() {
!! attempt to connect, and wait a millisecond:
=erial.println(Tconnecting to server...T);
if (client.connect(server, IG)) {
=erial.println(Tmaking 1::8 re)uest...T);
!! make 1::8 3O: re)uest to twitter:
client.println(T3O: !+!statuses!user;timeline..mlZscreen;name%arduino 1::8!+.+T);
client.println(T1ost:api.twitter.comT);
client.println(TDonnection:closeT);
client.println();
}
!! note the time of this connect attempt:
lastAttempt:ime % millis();
}
void print6ifi=tatus() {
!! print the ==2N of the network ouRre attached to:
=erial.print(T==2N: T);
=erial.println(6iPi.==2N());
!! print our 6iPi shieldRs 28 address:
28Address ip % 6iPi.local28();
=erial.print(T28 Address: T);
=erial.println(ip);
!! print the received signal strength:
long rssi % 6iPi.A==2();
=erial.print(Tsignal strength (A==2):T);
=erial.print(rssi);
=erial.println(T dCmT);
}
6eb client
!"
:his sketch connects to a website (http:!!www.google.com) using a 6iPi shield.
:his e.ample is written for a network using 68A encrption. Por 6O8 or 68A, change the
6ifi.begin() call accordingl.
:his e.ample is written for a network using 68A encrption. Por 6O8 or 68A, change the
6ifi.begin() call accordingl.
Dircuit:
" 6iPi shield attached
<JK
"!
$include X=82.hY
$include X6iPi.hY
char ssidUV % TSour7etworkT;!! our network ==2N (name)
char passUV % TpasswordT; !! our network password (use for 68A, or use as ke for 6O8)
int ke2nde. % G; !! our network ke 2nde. number (needed onl for 6O8)
int status % 64;2N4O;=:A:9=;
!! if ou donRt want to use N7= (and reduce our sketch si?e)
!! use the numeric 28 instead of the name for the server:
28Address server(+MB,+KF,MB,+GJ); !! numeric 28 for 3oogle (no N7=)
!!char serverUV % Twww.google.comT; !! name address for 3oogle (using N7=)
!! 2nitiali?e the Othernet client librar with the 28 address and port of the server
!! that ou want to connect to (port IG is default for 1::8):
6iPiDlient client;
void setup() {
=erial.begin(KHGG);
!! attempt to connect to 6ifi network:
while ( status *% 64;D577OD:ON) {
=erial.print(TAttempting to connect to ==2N: T);
=erial.println(ssid);
status % 6iPi.begin(ssid, pass);
!! wait +G seconds for connection:
dela(+GGGG);
}
=erial.println(TDonnected to wifiT);
print6ifi=tatus();
=erial.println(T\n=tarting connection to server...T);
!! if ou get a connection, report back via serial:
if (client.connect(server, IG)) {
=erial.println(Tconnected to serverT);
!! @ake a 1::8 re)uest:
client.println(T3O: !searchZ)%arduino 1::8!+.+T);
client.println(T1ost:www.google.comT);
client.println(TDonnection: closeT);
client.println();
}
}
void loop() {
!! if there are incoming btes available
!! from the server, read them and print them:
while (client.available()) {
char c % client.read();
=erial.write(c);
<HG
}
!! if the serverRs disconnected, stop the client:
if (*client.connected()) {
=erial.println();
=erial.println(Tdisconnecting from server.T);
client.stop();
!! do nothing forevermore:
while(true);
}
}
void print6ifi=tatus() {
!! print the ==2N of the network ouRre attached to:
=erial.print(T==2N: T);
=erial.println(6iPi.==2N());
!! print our 6iPi shieldRs 28 address:
28Address ip % 6iPi.local28();
=erial.print(T28 Address: T);
=erial.println(ip);
!! print the received signal strength:
long rssi % 6iPi.A==2();
=erial.print(Tsignal strength (A==2):T);
=erial.print(rssi);
=erial.println(T dCmT);
}
Re!eating 6ifi 6eb client
!"
:his sketch connects to a a web server and makes a re)uest using an Arduino 6ifi shield.
Dircuit:
" 6ifi shield attached to pins +G, ++, +<, +B
"!
$include X=82.hY
$include X6iPi.hY
char ssidUV % Tour7etworkT; !! our network ==2N (name)
char passUV % Tsecret8asswordT; !! our network password
int ke2nde. % G; !! our network ke 2nde. number (needed onl for 6O8)
int status % 64;2N4O;=:A:9=;
!! 2nitiali?e the 6ifi client librar
6iPiDlient client;
<H+
!! server address:
char serverUV % Twww.arduino.ccT;
!!28Address server(HF,+B+,I<,<F+);
unsigned long lastDonnection:ime % G; !! last time ou connected to the server, in msec
boolean lastDonnected % false; !! state of the connection last time through the main loop
const unsigned long posting2nterval % +G"+GGG; !! dela between updates, in milliseconds
void setup() {
!! start serial port:
=erial.begin(KHGG);
!! attempt to connect to 6ifi network:
while ( status *% 64;D577OD:ON) {
=erial.print(TAttempting to connect to ==2N: T);
=erial.println(ssid);
status % 6iPi.begin(ssid, pass);
!! wait +G seconds for connection:
dela(+GGGG);
}
!! ouRre connected now, so print out the status:
print6ifi=tatus();
}
void loop() {
!! if thereRs incoming data from the net connection.
!! send it out the serial port. :his is for debugging purposes onl:
while (client.available()) {
char c % client.read();
=erial.write(c);
}
!! if thereRs no net connection, but there was one last time
!! through the loop, then stop the client:
if (*client.connected() '' lastDonnected) {
=erial.println();
=erial.println(Tdisconnecting.T);
client.stop();
}
!! if ouRre not connected, and ten seconds have passed since
!! our last connection, then connect again and send data:
if(*client.connected() '' (millis() # lastDonnection:ime Y posting2nterval)) {
httpAe)uest();
}
!! store the state of the connection for ne.t time through
!! the loop:
lastDonnected % client.connected();
}
!! this method makes a 1::8 connection to the server:
void httpAe)uest() {
<H<
!! if thereRs a successful connection:
if (client.connect(server, IG)) {
=erial.println(Tconnecting...T);
!! send the 1::8 89: re)uest:
client.println(T3O: !latest.t.t 1::8!+.+T);
client.println(T1ost: www.arduino.ccT);
client.println(T9ser#Agent: arduino#ethernetT);
client.println(TDonnection: closeT);
client.println();
!! note the time that the connection was made:
lastDonnection:ime % millis();
}
else {
!! if ou couldnRt make a connection:
=erial.println(Tconnection failedT);
=erial.println(Tdisconnecting.T);
client.stop();
}
}
void print6ifi=tatus() {
!! print the ==2N of the network ouRre attached to:
=erial.print(T==2N: T);
=erial.println(6iPi.==2N());
!! print our 6iPi shieldRs 28 address:
28Address ip % 6iPi.local28();
=erial.print(T28 Address: T);
=erial.println(ip);
!! print the received signal strength:
long rssi % 6iPi.A==2();
=erial.print(Tsignal strength (A==2):T);
=erial.print(rssi);
=erial.println(T dCmT);
}
6eb #erver
!"
A simple web server that shows the value of the analog input pins. using a 6iPi shield.
:his e.ample is written for a network using 68A encrption. Por 6O8 or 68A, change the
6ifi.begin() call accordingl.
Dircuit:
" 6iPi shield attached
" Analog inputs attached to pins AG through AJ (optional)
"!
<HB
$include X=82.hY
$include X6iPi.hY
char ssidUV % Tour7etworkT; !! our network ==2N (name)
char passUV % Tsecret8asswordT; !! our network password
int ke2nde. % G; !! our network ke 2nde. number (needed onl for 6O8)
int status % 64;2N4O;=:A:9=;
6iPi=erver server(IG);
void setup() {
!! start serial port:
=erial.begin(KHGG);
!! attempt to connect to 6ifi network:
while ( status *% 64;D577OD:ON) {
=erial.print(TAttempting to connect to ==2N: T);
=erial.println(ssid);
status % 6iPi.begin(ssid, pass);
!! wait +G seconds for connection:
dela(+GGGG);
}
server.begin();
!! ouRre connected now, so print out the status:
print6ifi=tatus();
}
void loop() {
!! listen for incoming clients
6iPiDlient client % server.available();
if (client) {
=erial.println(Tnew clientT);
!! an http re)uest ends with a blank line
boolean current4ine2sClank % true;
while (client.connected()) {
if (client.available()) {
char c % client.read();
=erial.write(c);
!! if ouRve gotten to the end of the line (received a newline
!! character) and the line is blank, the http re)uest has ended,
!! so ou can send a repl
if (c %% R\nR '' current4ine2sClank) {
!! send a standard http response header
client.println(T1::8!+.+ <GG 5ET);
client.println(TDontent#:pe: te.t!htmlT);
client.println(TDonnnection: closeT);
client.println();
client.println(TX*N5D:S8O 1:@4YT);
client.println(TXhtmlYT);
!! add a meta refresh tag, so the browser pulls again ever J seconds:
<HF
client.println(TXmeta http#e)uiv%\Trefresh\T content%\TJ\TYT);
!! output the value of each analog input pin
for (int analogDhannel % G; analogDhannel X H; analogDhannel&&) {
int sensorAeading % analogAead(analogDhannel);
client.print(Tanalog input T);
client.print(analogDhannel);
client.print(T is T);
client.print(sensorAeading);
client.println(TXbr !YT);
}
client.println(TX!htmlYT);
break;
}
if (c %% R\nR) {
!! ouRre starting a new line
current4ine2sClank % true;
}
else if (c *% R\rR) {
!! ouRve gotten a character on the current line
current4ine2sClank % false;
}
}
}
!! give the web browser time to receive the data
dela(+);
!! close the connection:
client.stop();
=erial.println(Tclient disonnectedT);
}
}
void print6ifi=tatus() {
!! print the ==2N of the network ouRre attached to:
=erial.print(T==2N: T);
=erial.println(6iPi.==2N());
!! print our 6iPi shieldRs 28 address:
28Address ip % 6iPi.local28();
=erial.print(T28 Address: T);
=erial.println(ip);
!! print the received signal strength:
long rssi % 6iPi.A==2();
=erial.print(Tsignal strength (A==2):T);
=erial.print(rssi);
=erial.println(T dCmT);
}
<HJ
6i4i
(iFiCbe)in#$
2nitiali?es the 6iPi librarRs network settings and provides the current status.
Syntax' 6iPi.begin();
6iPi.begin(ssid);
6iPi.begin(ssid, pass);
6iPi.begin(ssid, ke2nde., ke);
%arameters' ssid: the ==2N (=ervice =et 2dentifier) is the name of the 6iPi network ou want to
connect to.
ke2nde.: 6O8 encrpted networks can hold up to F different kes. :his identifies
which ke ou are going to use.
ke: a he.adecimal string used as a securit code for 6O8 encrpted networks.
pass: 68A encrpted networks use a password in the form of a string for securit.
&eturns' $ 64;D577OD:ON when connected to a network
$ 64;2N4O;=:A:9= when not connected to a network, but powered on
+xample
$include X6iPi.hY
!!==2N of our network
char ssidUV % Tour7etworkT;
!!password of our 68A 7etwork
char passUV % Tsecret8asswordT;
void setup()
{
6iPi.begin(ssid, pass);
}
void loop () {}
6i4i
(iFiCBSS1D#$
3ets the @AD address of the routher ou are connected to
Syntax' 6iPi.C==2N(bssid);
%arameters' bssid : H bte arra
&eturns' A bte arra containing the @AD address of the router the 6iPi shield is currentl
connected to.
+xample
<HH
$include X6iPi.hY
!!==2N of our network
char ssidUV % Tour7etworkT;
!!password of our 68A 7etwork
char passUV % Tsecret8asswordT;
void setup()
{
6iPi.begin(ssid, pass);
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
while(true);
}
!! if ou are connected, print out info about the connection:
else {
!! print the @AD address of the router ouRre attached to:
bte bssidUHV;
6iPi.C==2N(bssid);
=erial.print(TC==2N: T);
=erial.print(bssidUJV,1OQ);
=erial.print(T:T);
=erial.print(bssidUFV,1OQ);
=erial.print(T:T);
=erial.print(bssidUBV,1OQ);
=erial.print(T:T);
=erial.print(bssidU<V,1OQ);
=erial.print(T:T);
=erial.print(bssidU+V,1OQ);
=erial.print(T:T);
=erial.println(bssidUGV,1OQ);
}
}
void loop () {}
6i4i + "lient class
Client#$
Dlient is the base class for all 6iPi client based calls. 2t is not called directl, but invoked whenever
ou use a function that relies on it.
6i4i + "lient class
clientCavailable#$
Aeturns the number of btes available for reading (that is, the amount of data that has been written
to the client b the server it is connected to).
<HM
available() inherits from the =tream utilit class.
Syntax' client.available()
%arameters' none
&eturns' :he number of btes available.
+xample
$include X=82.hY
$include X6iPi.hY
char ssidUV % Tm7etworkT; !! our network ==2N (name)
char passUV % Tm8asswordT; !! our network password
int status % 64;2N4O;=:A:9=;
char servernameUV%Tgoogle.comT; !! 3oogle
6iPiDlient client;
void setup() {
=erial.begin(KHGG);
=erial.println(TAttempting to connect to 68A network...T);
=erial.print(T==2N: T);
=erial.println(ssid);
status % 6iPi.begin(ssid, pass);
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
!! donRt do anthing else:
while(true);
}
else {
=erial.println(TDonnected to wifiT);
=erial.println(T\n=tarting connection...T);
!! if ou get a connection, report back via serial:
if (client.connect(servername, IG)) {
=erial.println(TconnectedT);
!! @ake a 1::8 re)uest:
client.println(T3O: !searchZ)%arduino 1::8!+.GT);
client.println();
}
}
}
void loop() {
!! if there are incoming btes available
!! from the server, read them and print them:
if (client.available()) {
char c % client.read();
=erial.print(c);
}
<HI
!! if the serverRs disconnected, stop the client:
if (*client.connected()) {
=erial.println();
=erial.println(Tdisconnecting.T);
client.stop();
!! do nothing forevermore:
for(;;)
;
}
}
6i4i + "lient class
connected#$
6hether or not the client is connected. 7ote that a client is considered connected if the connection
has been closed but there is still unread data.
Syntax' client.connected()
%arameters' none
&eturns' Aeturns true if the client is connected, false if not.
+xample
$include X=82.hY
$include X6iPi.hY
char ssidUV % Tm7etworkT; !! our network ==2N (name)
char passUV % Tm8asswordT; !! our network password
int status % 64;2N4O;=:A:9=;
28Address server(MF,+<J,++J,+GJ); !! 3oogle
!! 2nitiali?e the client librar
6iPiDlient client;
void setup() {
=erial.begin(KHGG);
=erial.println(TAttempting to connect to 68A network...T);
=erial.print(T==2N: T);
=erial.println(ssid);
status % 6iPi.begin(ssid, pass);
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
!! donRt do anthing else:
while(true);
}
else {
<HK
=erial.println(TDonnected to wifiT);
=erial.println(T\n=tarting connection...T);
!! if ou get a connection, report back via serial:
if (client.connect(server, IG)) {
=erial.println(TconnectedT);
!! @ake a 1::8 re)uest:
client.println(T3O: !searchZ)%arduino 1::8!+.GT);
client.println();
}
}
}
void loop() {
if (client.available()) {
char c % client.read();
=erial.print(c);
}
if (*client.connected()) {
=erial.println();
=erial.println(Tdisconnecting.T);
client.stop();
for(;;)
;
}
}
6i4i + "lient class
connect#$
Donnect to the 28 address and port specified in the constructor. :he return value indicates success or
failure. connect() also supports N7= lookups when using a domain name (e.:google.com).
Syntax' client.connect(ip, port)
client.connect(9A4, port)
%arameters' ip: the 28 address that the client will connect to (arra of F btes)
9A4: the domain name the client will connect to (string, e..:Tarduino.ccT)
port: the port that the client will connect to (int)
&eturns' Aeturns true if the connection succeeds, false if not.
+xample
$include X=82.hY
$include X6iPi.hY
char ssidUV % Tm7etworkT; !! our network ==2N (name)
char passUV % Tm8asswordT; !! our network password
<MG
int status % 64;2N4O;=:A:9=;
char servernameUV%Tgoogle.comT; !! remote server we will connect to
6iPiDlient client;
void setup() {
=erial.begin(KHGG);
=erial.println(TAttempting to connect to 68A network...T);
=erial.print(T==2N: T);
=erial.println(ssid);
status % 6iPi.begin(ssid, pass);
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
!! donRt do anthing else:
while(true);
}
else {
=erial.println(TDonnected to wifiT);
=erial.println(T\n=tarting connection...T);
!! if ou get a connection, report back via serial:
if (client.connect(servername, IG)) {
=erial.println(TconnectedT);
!! @ake a 1::8 re)uest:
client.println(T3O: !searchZ)%arduino 1::8!+.GT);
client.println();
}
}
}
void loop() { }
6i4i + "lient class
!lush#$
Niscard an btes that have been written to the client but not et read.
flush() inherits from the =tream utilit class.
Syntax' client.flush()
%arameters' none
&eturns' none
6i4i + "lient class
(iFiClient#$
Dreates a client that can connect to to a specified internet 28 address and port as defined in
client.connect().
<M+
Syntax' 6iPiDlient()
%arameters' none
+xample
$include X=82.hY
$include X6iPi.hY
char ssidUV % Tm7etworkT; !! our network ==2N (name)
char passUV % Tm8asswordT; !! our network password
int status % 64;2N4O;=:A:9=;
28Address server(MF,+<J,++J,+GJ); !! 3oogle
!! 2nitiali?e the client librar
6iPiDlient client;
void setup() {
=erial.begin(KHGG);
=erial.println(TAttempting to connect to 68A network...T);
=erial.print(T==2N: T);
=erial.println(ssid);
status % 6iPi.begin(ssid, pass);
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
!! donRt do anthing else:
while(true);
}
else {
=erial.println(TDonnected to wifiT);
=erial.println(T\n=tarting connection...T);
!! if ou get a connection, report back via serial:
if (client.connect(server, IG)) {
=erial.println(TconnectedT);
!! @ake a 1::8 re)uest:
client.println(T3O: !searchZ)%arduino 1::8!+.GT);
client.println();
}
}
}
void loop() {
}
<M<
6i4i + "lient class
print#$
8rint data to the server that a client is connected to. 8rints numbers as a se)uence of digits, each an
A=D22 character (e.g. the number +<B is sent as the three characters R+R, R<R, RBR).
Syntax' client.print(data)
client.print(data, CA=O)
%arameters' data: the data to print (char, bte, int, long, or string)
CA=O (optional): the base in which to print numbers:, NOD for decimal (base +G),
5D: for octal (base I), 1OQ for he.adecimal (base +H).
&eturns' bte : returns the number of btes written, though reading that number is optional
6i4i + "lient class
println#$
8rint data, followed b a carriage return and newline, to the server a client is connected to. 8rints
numbers as a se)uence of digits, each an A=D22 character (e.g. the number +<B is sent as the three
characters R+R, R<R, RBR).
Syntax' client.println()
client.println(data)
client.print(data, CA=O)
%arameters' data (optional): the data to print (char, bte, int, long, or string)
CA=O (optional): the base in which to print numbers: NOD for decimal (base +G),
5D: for octal (base I), 1OQ for he.adecimal (base +H).
&eturns' bte: return the number of btes written, though reading that number is optional
6i4i + "lient class
read#$
Aead the ne.t bte received from the server the client is connected to (after the last call to read()).
read() inherits from the =tream utilit class.
Syntax' client.read()
%arameters' none
&eturns' :he ne.t bte (or character), or #+ if none is available.
<MB
6i4i + "lient class
stop#$
Nisconnect from the server
Syntax' client.stop()
%arameters' none
&eturns' none
6i4i + "lient class
write#$
6rite data to the server the client is connected to.
Syntax' client.write(data)
%arameters' data: the bte or char to write
&eturns' bte: the number of characters written. it is not necessar to read this value.
6i4i
(iFiCdisconnect#$
Nisconnects the 6iPi shield from the current network.
Syntax' 6iPi.disconnect();
%arameters' none
&eturns' nothing
6i4i
(iFiCencryptionType#$
3ets the encrption tpe of the current network
Syntax' 6iPi.encrption:pe();
6iPi.encrption:pe(wifiAccess8oint);
%arameters' wifiAccess8oint: specifies which network to get information from
&eturns' bte : value represents the tpe of encrption
" :E28 (68A) % <
" 6O8 % J
" DD@8 (68A) % F
" 757O % M
" A9:5 % I
+xample
<MF
$include X=82.hY
$include X6iPi.hY
!!==2N of our network
char ssidUV % Tour7etworkT;
!!password of our 68A 7etwork
char passUV % Tsecret8asswordT;
void setup()
{
6iPi.begin(ssid, pass);
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
while(true);
}
!! if ou are connected, print out info about the connection:
else {
!! print the encrption tpe:
bte encrption % 6iPi.encrption:pe();
=erial.print(TOncrption :pe:T);
=erial.println(encrption,1OQ);
}
}
void loop () {}
(iFiC)ateway1%#$
3ets the 6iPi shieldRs gatewa 28 address.
Syntax' 6iPi.gatewa28();
%arameters' none
&eturns' An arra containing the shieldRs gatewa 28 address
+xample
include X=82.hY
include X6iPi.hY
int status % 64;2N4O;=:A:9=; !! the 6ifi radioRs status
!!==2N of our network char ssidUV % Tour7etworkT; !!password of our 68A 7etwork char
passUV % Tsecret8asswordT;
28Address gatewa;
void setup() {
=erial.begin(KHGG);
6iPi.begin(ssid, pass);
<MJ
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
while(true);
}
!! if ou are connected, print out info about the connection:
else {
!! print our gatewa address:
gatewa % 6iPi.gatewa28();
=erial.print(T3A:O6AS: T);
=erial.println(gatewa);
}
}
void loop () {}
(iFiC)etSoc<et#$
gets the first socket available
Syntax' 6iPi.get=ocket();
%arameters' none
&eturns' int : the first socket available
(iFiClocal1%#$
3ets the 6iPi shieldRs 28 address
Syntax' 6iPi.local28();
%arameters' none
&eturns' the 28 address of the shield
+xample
$include X6iPi.hY
char ssidUV % Tour7etworkT; !!==2N of our network
int status % 64;2N4O;=:A:9=; !! the 6ifi radioRs status
28Address ip; !! the 28 address of our shield
void setup()
{
!! initiali?e serial:
=erial.begin(KHGG);
6iPi.begin(ssid);
if ( status *% 64;D577OD:ON) {
<MH
=erial.println(TDouldnRt get a wifi connectionT);
while(true);
}
!! if ou are connected, print out info about the connection:
else {
!!print the local 28 address
ip % 6iPi.local28();
=erial.println(ip);
}
}
void loop () {}
6iPi.macAddress()
3ets the @AD Address of our 6iPi shield
Syntax' 6iPi.macAddress(mac);
%arameters' mac: a H bte arra to hold the @AD address
&eturns' bte arra : H btes representing the @AD address of our shield
+xample
$include X=82.hY
$include X6iPi.hY
char ssidUV % Tour7etworkT; !! the name of our network
int status % 64;2N4O;=:A:9=; !! the 6ifi radioRs status
bte macUHV; !! the @AD address of our 6ifi shield
void setup()
{
=erial.begin(KHGG);
status % 6iPi.begin(ssid);
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
while(true);
}
!! if ou are connected, print our @AD address:
else {
6iPi.macAddress(mac);
=erial.print(T@AD: T);
=erial.print(macUJV,1OQ);
=erial.print(T:T);
=erial.print(macUFV,1OQ);
=erial.print(T:T);
=erial.print(macUBV,1OQ);
=erial.print(T:T);
<MM
=erial.print(macU<V,1OQ);
=erial.print(T:T);
=erial.print(macU+V,1OQ);
=erial.print(T:T);
=erial.println(macUGV,1OQ);
}
}
void loop () {}
(iFiC&SS1#$
3ets the signal strength of the connection to the router
Syntax' 6iPi.A==2();
6iPi.A==2(wifiAccess8oint);
%arameters' wifiAccess8oint: specifies from which network to get the information
&eturns' long : the current A==2 !Aeceived =ignal =trength in dCm
+xample
$include X=82.hY
$include X6iPi.hY
!!==2N of our network
char ssidUV % Tour7etworkT;
!!password of our 68A 7etwork
char passUV % Tsecret8asswordT;
void setup()
{
6iPi.begin(ssid, pass);
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
while(true);
}
!! if ou are connected, print out info about the connection:
else {
!! print the received signal strength:
long rssi % 6iPi.A==2();
=erial.print(TA==2:T);
=erial.println(rssi);
}
}
void loop () {}
<MI
(iFiCscan*etwor<s#$
=cans for available 6iPi networks and returns the discovered number
Syntax' 6iPi.scan7etworks();
%arameters' none
&eturns' bte : number of discovered networks
+xample
$include X=82.hY
$include X6iPi.hY
char ssidUV % Tour7etworkT; !! the name of our network
int status % 64;2N4O;=:A:9=; !! the 6ifi radioRs status
bte macUHV; !! the @AD address of our 6ifi shield
void setup()
{
=erial.begin(KHGG);
status % 6iPi.begin(ssid);
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
while(true);
}
!! if ou are connected, print our @AD address:
else {
=erial.println(T"" =can 7etworks ""T);
bte num=sid % 6iPi.scan7etworks();
=erial.print(T==2N 4ist:T);
=erial.println(num=sid);
}
}
void loop () {}
(iFiCSS1D#$
3ets the ==2N of the current network
Syntax' 6iPi.==2N();
6iPi.==2N(wifiAccess8oint)
%arameters' wifiAccess8oint: specifies from which network to get the information
&eturns' A string containing the ==2N the 6iPi shield is currentl connected to.
<MK
string containing name of network re)uested.
+xample
$include X=82.hY
$include X6iPi.hY
!!==2N of our network
char ssidUV % Tour7etworkT;
int status % 64;2N4O;=:A:9=; !! the 6ifi radioRs status
void setup()
{
!! initiali?e serial:
=erial.begin(KHGG);
!! scan for e.isting networks:
=erial.println(T=canning available networks...T);
scan7etworks();
!! attempt to connect using 6O8 encrption:
=erial.println(TAttempting to connect to open network...T);
status % 6iPi.begin(ssid);
=erial.print(T==2N: T);
=erial.println(ssid);
}
void loop () {}
void scan7etworks() {
!! scan for nearb networks:
=erial.println(T"" =can 7etworks ""T);
bte num=sid % 6iPi.scan7etworks();
!! print the list of networks seen:
=erial.print(T==2N 4ist:T);
=erial.println(num=sid);
!! print the network number and name for each network found:
for (int this7et % G; this7etXnum=sid; this7et&&) {
=erial.print(this7et);
=erial.print(T) 7etwork: T);
=erial.println(6iPi.==2N(this7et));
}
}
<IG
(iFiCsubnet-as<#$
3ets the 6iPi shieldRs subnet mask
Syntax' 6iPi.subnet();
%arameters' none
&eturns' the subnet mask of the shield
+xample
$include X6iPi.hY
int status % 64;2N4O;=:A:9=; !! the 6ifi radioRs status
!!==2N of our network
char ssidUV % Tour7etworkT;
!!password of our 68A 7etwork
char passUV % Tsecret8asswordT;
28Address ip;
28Address subnet;
28Address gatewa;
void setup()
{
6iPi.begin(ssid, pass);
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
while(true);
}
!! if ou are connected, print out info about the connection:
else {
!! print our subnet mask:
subnet % 6iPi.subnet@ask();
=erial.print(T7O:@A=E: T);
=erial.println();
}
}
void loop () {
}
<I+
(iFi ' Server class
serverCavailable#$
3ets a client that is connected to the server and has data available for reading. :he connection
persists when the returned client ob>ect goes out of scope; ou can close it b calling client.stop().
available() inherits from the =tream utilit class.
Syntax' server.available()
%arameters' 7one
&eturns' a Dlient ob>ect; if no Dlient has data available for reading, this ob>ect will evaluate to
false in an if#statement
+xample
$include X=82.hY
$include X6iPi.hY
char ssidUV % T7etworkT; !! our network ==2N (name)
char passUV % Tm8asswordT; !! our network password
int status % 64;2N4O;=:A:9=;
6iPi=erver server(IG);
void setup() {
!! initiali?e serial:
=erial.begin(KHGG);
=erial.println(TAttempting to connect to 68A network...T);
=erial.print(T==2N: T);
=erial.println(ssid);
status % 6iPi.begin(ssid, pass);
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
while(true);
}
else {
server.begin();
=erial.print(TDonnected to wifi. @ address:T);
28Address mAddress % 6iPi.local28();
=erial.println(mAddress);
}
}
void loop() {
!! listen for incoming clients
6iPiDlient client % server.available();
if (client) {
<I<
if (client.connected()) {
=erial.println(TDonnected to clientT);
}
!! close the connection:
client.stop();
}
}
6i4i + #erver class
serverCbe)in#$
:ells the server to begin listening for incoming connections.
Syntax' server.begin()
%arameters' 7one
&eturns' 7one
+xample
$include X=82.hY
$include X6iPi.hY
char ssidUV % TlamaisonT; !! our network ==2N (name)
char passUV % Ttenantaccess<FMT; !! our network password
int status % 64;2N4O;=:A:9=;
6iPi=erver server(IG);
void setup() {
!! initiali?e serial:
=erial.begin(KHGG);
=erial.println(TAttempting to connect to 68A network...T);
=erial.print(T==2N: T);
=erial.println(ssid);
status % 6iPi.begin(ssid, pass);
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
while(true);
}
else {
server.begin();
=erial.print(TDonnected to wifi. @ address:T);
28Address mAddress % 6iPi.local28();
=erial.println(mAddress);
}
}
void loop() {
}
<IB
6i4i + #erver class
(iFi Server#$
Dreates a server that listens for incoming connections on the specified port.
Syntax' =erver(port);
%arameters' port: the port to listen on (int)
&eturns' 7one
+xample
$include X=82.hY
$include X6iPi.hY
char ssidUV % Tm7etworkT; !! our network ==2N (name)
char passUV % Tm8asswordT; !! our network password
int status % 64;2N4O;=:A:9=;
6iPi=erver server(IG);
void setup() {
!! initiali?e serial:
=erial.begin(KHGG);
=erial.println(TAttempting to connect to 68A network...T);
=erial.print(T==2N: T);
=erial.println(ssid);
status % 6iPi.begin(ssid, pass);
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
while(true);
}
else {
server.begin();
=erial.print(TDonnected to wifi. @ address:T);
28Address mAddress % 6iPi.local28();
=erial.println(mAddress);
}
}
void loop() {
}
<IF
6i4i + #erver class
serverCprint#$
8rint data to all the clients connected to a server. 8rints numbers as a se)uence of digits, each an
A=D22 character (e.g. the number +<B is sent as the three characters R+R, R<R, RBR).
Syntax' server.print(data)
server.print(data, CA=O)
%arameters' data: the data to print (char, bte, int, long, or string)
CA=O (optional): the base in which to print numbers: C27 for binar (base <), NOD
for decimal (base +G), 5D: for octal (base I), 1OQ for he.adecimal (base +H).
&eturns' bte print() will return the number of btes written, though reading that number is
optional
6i4i + #erver class
serverCprintln#$
8rints data, followed b a newline, to all the clients connected to a server. 8rints numbers as a
se)uence of digits, each an A=D22 character (e.g. the number +<B is sent as the three characters R+R,
R<R, RBR).
Syntax' server.println()
server.println(data)
server.println(data, CA=O)
%arameters' data (optional): the data to print (char, bte, int, long, or string)
CA=O (optional): the base in which to print numbers: NOD for decimal (base +G),
5D: for octal (base I), 1OQ for he.adecimal (base +H).
&eturns' bte
println() will return the number of btes written, though reading that number is
optional
6i4i + #erver class
serverCwrite#$
6rite data to all the clients connected to a server.
Syntax' server.write(data)
%arameters' data: the value to write (bte or char)
&eturns' bte : the number of btes written. 2t is not necessar to read this.
+xample
$include X=82.hY
<IJ
$include X6iPi.hY
char ssidUV % Tour7etworkT;
char passUV % Tour8asswordT;
int status % 64;2N4O;=:A:9=;
6iPi=erver server(IG);
void setup() {
!! initiali?e serial:
=erial.begin(KHGG);
=erial.println(TAttempting to connect to 68A network...T);
=erial.print(T==2N: T);
=erial.println(ssid);
status % 6iPi.begin(ssid, pass);
if ( status *% 64;D577OD:ON) {
=erial.println(TDouldnRt get a wifi connectionT);
while(true);
}
else {
server.begin();
}
}
void loop() {
!! listen for incoming clients
6iPiDlient client % server.available();
if (client %% true) {
!! read btes from the incoming client and write them back
!! to an clients connected to the server:
server.write(client.read());
}
}
<IH
(ire .ibrary
:his librar allows ou to communicate with 2<D ! :62 devices. 5n most Arduino boards, =NA
(data line) is on analog input pin F, and =D4 (clock line) is on analog input pin J. 5n the Arduino
@ega, =NA is digital pin <G and =D4 is <+.
As of Arduino +.G, the librar inherits from the =tream functions, making it consistent with other
read!write libraries. Cecause of this, send() and receive() have been replaced with read() and
write().
Functions
# available()
# begin()
# begin:ransmission()
# end:ransmission()
# onAeceive()
# onAe)uest()
# read()
# re)uestProm()
# write()
*ote' :here are both M# and I#bit versions of 2<D addresses. M bits identif the device, and the
eighth bit determines if itRs being written to or read from. :he 6ire librar uses M bit
addresses throughout. 2f ou have a datasheet or sample code that uses I bit address, ouRll
want to drop the low bit (i.e. shift the value one bit to the right), ielding an address between
G and +<M.
(ireCavailable#$
Aeturns the number of btes available for retrieval with receive(). :his should be called on a master
device after a call to re)uestProm() or on a slave inside the onAeceive() handler.
available() inherits from the =tream utilit class.
8arameters: 7one
Aeturns: :he number of btes available for reading.
(ireCbe)in#$
2nitiate the 6ire librar and >oin the 2<D bus as a master or slave. :his should normall be called
onl once.
Syntax' 6ire.begin(address)
%arameters' address: the M#bit slave address (optional); if not specified, >oin the bus as a master.
&eturns' 7one
<IM
(ireCbe)inTransmission#address$
Cegin a transmission to the 2<D slave device with the given address. =ubse)uentl, )ueue btes for
transmission with the write() function and transmit them b calling end:ransmission().
Syntax' 6ire.begin:ransmission(address)
%arameters' address: the M#bit address of the device to transmit to
&eturns' 7one
(ireCendTransmission#$
Onds a transmission to a slave device that was begun b begin:ransmission() and transmits the
btes that were )ueued b write().
As of Arduino +.G.+, end:ransmission() accepts a boolean argument changing its behavior for
compatibilit with certain 2<D devices.
2f true, end:ransmission() sends a stop message after transmission, releasing the 2<D bus. 2f false,
end:ransmission() sends a restart message after transmission. :he bus will not be released, which
prevents another master device from transmitting between messages. :his allows one master device
to send multiple transmissions while in control.
:he default value is true.
Syntax' 6ire.end:ransmission()
6ire.end:ransmission(stop)
%arameters' stop : boolean. true will send a stop message, releasing the bus after transmission.
false will send a restart, keeping the connection active.
&eturns' bte, which indicates the status of the transmission:
# G:success
# +:data too long to fit in transmit buffer
# <:received 7ADE on transmit of address
# B:received 7ADE on transmit of data
# F:other error
(ireCon&eceive#handler$
Aegisters a function to be called when a slave device receives a transmission from a master.
%arameters' handler: the function to be called when the slave receives data; this should take a
single int parameter (the number of btes read from the master) and return nothing,
e.g.: void m1andler(int numCtes)
&eturns' 7one
<II
(ireCon&e0uest#handler$
Aegister a function to be called when a master re)uests data from this slave device.
%arameters' handler: the function to be called, takes no parameters and returns nothing, e.g.: void
m1andler()
&eturns' 7one
(ireCread#$
Aeads a bte that was transmitted from a slave device to a master after a call to re)uestProm() or
was transmitted from a master to a slave. read() inherits from the =tream utilit class.
Syntax' 6ire.read()
%arameters' none
&eturns' :he ne.t bte received
+xample
$include X6ire.hY
void setup()
{
6ire.begin(); !! >oin i<c bus (address optional for master)
=erial.begin(KHGG); !! start serial for output
}
void loop()
{
6ire.re)uestProm(<, H); !! re)uest H btes from slave device $<
while(6ire.available()) !! slave ma send less than re)uested
{
char c % 6ire.read(); !! receive a bte as character
=erial.print(c); !! print the character
}
dela(JGG);
}
(ireCreceive#$
Aetrieve a bte that was transmitted from a slave device to a master after a call to re)uestProm or
was transmitted from a master to a slave.
%arameters' 7one
&eturns' :he ne.t bte received.
<IK
(ireCre0uestFrom#$
9sed b the master to re)uest btes from a slave device. :he btes ma then be retrieved with the
available() and read() functions.
As of Arduino +.G.+, re)uestProm() accepts a boolean argument changing its behavior for
compatibilit with certain 2<D devices.
2f true, re)uestProm() sends a stop message after the re)uest, releasing the 2<D bus. 2f false,
re)uestProm() sends a restart message after the re)uest. :he bus will not be released, which
prevents another master device from re)uesting between messages. :his allows one master device
to send multiple re)uests while in control.
:he default value is true.
Syntax' 6ire.re)uestProm(address, )uantit)
6ire.re)uestProm(address, )uantit, stop)
%arameters' address: the M#bit address of the device to re)uest btes from
)uantit: the number of btes to re)uest
stop : boolean. true will send a stop message after the re)uest, releasing the bus. false
will continuall send a restart after the re)uest, keeping the connection active.
&eturns' 7one
(ireCsend#$
=ends data from a slave device in response to a re)uest from a master, or )ueues btes for
transmission from a master to slave device (in#between calls to begin:ransmission() and
end:ransmission()).
Syntax' 6ire.send(value)
6ire.send(string)
6ire.send(data, )uantit)
%arameters' value: a bte to send (bte)
string: a string to send (char ")
data: an arra of data to send (bte ")
)uantit: the number of btes of data to transmit (bte)
&eturns' 7one
<KG
(ireCwrite#$
6rites data from a slave device in response to a re)uest from a master, or )ueues btes for
transmission from a master to slave device (in#between calls to begin:ransmission() and
end:ransmission()).
Syntax' 6ire.write(value)
6ire.write(string)
6ire.write(data, length)
%arameters' value: a value to send as a single bte
string: a string to send as a series of btes
data: an arra of data to send as btes
length: the number of btes to transmit
&eturns' bte
write() will return the number of btes written, though reading that number is
optional
+xample
$include X6ire.hY
bte val % G;
void setup()
{
6ire.begin(); !! >oin i<c bus
}
void loop()
{
6ire.begin:ransmission(FF); !! transmit to device $FF (G.<c)
!! device address is specified in datasheet
6ire.write(val); !! sends value bte
6ire.end:ransmission(); !! stop transmitting
val&&; !! increment value
if(val %% HF) !! if reached HFth position (ma.)
{
val % G; !! start over from lowest value
}
dela(JGG);
}
<K+
word#$
Donvert a value to the word data tpe or create a word from two btes.
Syntax' word(.)
word(h, l)
%arameters' .: a value of an tpe
h: the high#order (leftmost) bte of the word
l: the low#order (rightmost) bte of the word
&eturns' word
word
A word stores a +H#bit unsigned number, from G to HJJBJ. =ame as an unsigned int.
+xample
word w % +GGGG;
<K<
Trgymutat
Abs(.)...................................................................................................................................................J
Addition, =ubtraction, @ultiplication, ' Nivision...............................................................................M
AnalogAead().......................................................................................................................................J
AnalogAeference(tpe).........................................................................................................................H
Analog6rite().......................................................................................................................................H
Arduino!8rocessing 4anguage Domparison.......................................................................................<F
Arra # creating, declaring ...................................................................................................................I
Arra, accessing....................................................................................................................................K
Arras...................................................................................................................................................I
Assignment operator (%) .....................................................................................................................K
Attached().........................................................................................................................................+MG
Attach2nterrupt().................................................................................................................................+G
Cegin()................................................................................................................................................++
Cit().....................................................................................................................................................+<
CitDlear()............................................................................................................................................+<
CitAead()............................................................................................................................................+<
Cit=et()...............................................................................................................................................+B
Citshift left (XX), bitshift right (YY)....................................................................................................+B
Citwise A7N (')...............................................................................................................................+F
Citwise 75: (/).................................................................................................................................+I
Citwise 5A (,).....................................................................................................................................+J
Citwise Q5A (-).................................................................................................................................+H
Cit6rite()...........................................................................................................................................+K
Coolean operators # * (not)..................................................................................................................+K
Coolean operators # '' (logical and)................................................................................................+K
Coolean operators # ,, (logical or).......................................................................................................+K
Creak...................................................................................................................................................<<
Cte.....................................................................................................................................................<<
Cte()..................................................................................................................................................<<
Dhar....................................................................................................................................................<B
Dhar()..................................................................................................................................................<B
Domments...........................................................................................................................................<B
Dompound bitwise A7N ('%)...........................................................................................................+H
Dompound bitwise 5A (,%).................................................................................................................+M
Donst keword....................................................................................................................................<H
Donstrain(., a, b)................................................................................................................................<H
Dontinue.............................................................................................................................................<M
Dos(rad)..............................................................................................................................................<M
Durl Craces # {} ...............................................................................................................................<G
NDPMM 4ibrar...................................................................................................................................<I
Necrement (##)....................................................................................................................................I<
Nefine ($define)..................................................................................................................................<K
Nefining Nigital 8ins, 2789:, 2789:;894498, and 59:89:.....................................................<J
Nefining 4ogical 4evels, true and false (Coolean Donstants)............................................................<F
Nefining 8in 4evels, 1231 and 456...............................................................................................<J
Nela()................................................................................................................................................BG
Nela@icroseconds()..........................................................................................................................BG
Netach2nterrupt()................................................................................................................................B+
NigitalAead()......................................................................................................................................B+
<KB
Nigital6rite().....................................................................................................................................B<
No # while...........................................................................................................................................BB
Nouble................................................................................................................................................BB
OO8A5@ 4ibrar...............................................................................................................................BB
OO8A5@.read().................................................................................................................................BF
OO8A5@.write()................................................................................................................................BF
Othernet client.available()...................................................................................................................BI
Othernet client.connect().....................................................................................................................FG
Othernet client.connected().................................................................................................................BK
Othernet client.flush().........................................................................................................................F<
Othernet client.print()..........................................................................................................................F<
Othernet client.println()......................................................................................................................FB
Othernet client.read()..........................................................................................................................FB
Othernet client.stop()..........................................................................................................................FB
Othernet client.write().........................................................................................................................FF
Othernet Dlient().................................................................................................................................F+
Othernet Othernet.maintain()..............................................................................................................FH
Othernet Othernet=erver()...................................................................................................................FH
Othernet if (OthernetDlient)................................................................................................................JH
Othernet 28Address()..........................................................................................................................FF
Othernet librar...................................................................................................................................BJ
Othernet server.available()..................................................................................................................JM
Othernet server.begin().......................................................................................................................JI
Othernet server.print().........................................................................................................................HG
Othernet server.println()......................................................................................................................HG
Othernet server.write()........................................................................................................................H+
Othernet =erver()................................................................................................................................JK
Othernet 9N8.available()....................................................................................................................FM
Othernet 9N8.begin().........................................................................................................................FI
Othernet 9N8.begin8acket()..............................................................................................................FK
Othernet 9N8.end8acket()..................................................................................................................JG
Othernet 9N8.parse8acket()...............................................................................................................J+
Othernet 9N8.read()...........................................................................................................................J<
Othernet 9N8.remote28()...................................................................................................................JB
Othernet 9N8.remote8ort()................................................................................................................JF
Othernet 9N8.write()..........................................................................................................................JJ
Othernet: Othernet=erver.....................................................................................................................FH
Othernet.begin()..................................................................................................................................BH
Othernet.local28()................................................................................................................................FJ
OthernetDlient()..................................................................................................................................BM
Pirmata 4ibrar...................................................................................................................................H<
Ploat....................................................................................................................................................HJ
Ploat().................................................................................................................................................HF
Por statements.....................................................................................................................................HJ
Punctions............................................................................................................................................HM
34DN e.ample sketch........................................................................................................................HK
34DN Punctions................................................................................................................................MG
34DN 4ibrar....................................................................................................................................HK
3oto....................................................................................................................................................MK
1ighCte()..........................................................................................................................................MK
2f.........................................................................................................................................................MK
2f ! else................................................................................................................................................IG
<KF
2nclude ($include)...............................................................................................................................I+
2ncrement (&&) ...................................................................................................................................I<
2nt........................................................................................................................................................IF
2nt().....................................................................................................................................................IB
2nteger Donstants................................................................................................................................IB
2nterrupts using...................................................................................................................................+G
2nterrupts()..........................................................................................................................................IB
Wostick Dontrol..................................................................................................................................KK
Eeboard Cutton e.ample..................................................................................................................KJ
Eeboard @odifiers, :ables...............................................................................................................IH
Eeboard.begin()................................................................................................................................IJ
Eeboard.end()...................................................................................................................................IJ
Eeboard.press()................................................................................................................................IM
Eeboard.print().................................................................................................................................II
Eeboard.println()..............................................................................................................................IK
Eeboard.release()..............................................................................................................................KG
Eeboard.releaseAll().........................................................................................................................IK
Eeboard.write()................................................................................................................................K+
4DN 4ibrar.....................................................................................................................................+GF
4cd.autoscroll()................................................................................................................................+GF
4cd.begin().......................................................................................................................................+GH
4cd.blink()........................................................................................................................................+GH
4cd.clear().........................................................................................................................................+GM
4cd.createDhar()...............................................................................................................................+GI
4cd.cursor()......................................................................................................................................+GK
4cd.displa().....................................................................................................................................++G
4cd.home().......................................................................................................................................+++
4cd.left:oAight()..............................................................................................................................+++
4cd.noAutoscroll()...........................................................................................................................+++
4cd.noClink()...................................................................................................................................+++
4cd.noDursor().................................................................................................................................+++
4cd.noNispla()................................................................................................................................++<
4cd.print().........................................................................................................................................++<
4cd.right:o4eft()..............................................................................................................................++B
4cd.scrollNispla4eft()....................................................................................................................++B
4cd.scrollNisplaAight()..................................................................................................................++F
4cd.setDursor().................................................................................................................................++J
4cd.write()........................................................................................................................................++H
4ibraries............................................................................................................................................+G<
4i)uidDrstal().................................................................................................................................+GM
4ong..................................................................................................................................................++M
4ong()...............................................................................................................................................++M
4oop()...............................................................................................................................................++M
4owCte().........................................................................................................................................++I
@ap()................................................................................................................................................++I
@a.(., )..........................................................................................................................................++K
@icros()............................................................................................................................................++K
@illis()..............................................................................................................................................+<G
@in(., )...........................................................................................................................................+<G
@odulo (()......................................................................................................................................+<+
@ouse and Eeboard e.ample...........................................................................................................KB
@ouse.begin()...................................................................................................................................+<<
<KJ
@ouse.click()....................................................................................................................................+<<
@ouse.end()......................................................................................................................................+<B
@ouse.is8ressed().............................................................................................................................+<B
@ouse.move()...................................................................................................................................+<F
@ouse.press()...................................................................................................................................+<H
@ouse.release().................................................................................................................................+<M
@ouseDontinousNrawing O.ample....................................................................................................KH
7o2nterrupts()...................................................................................................................................+B+
7o:one()..........................................................................................................................................+B+
5ne#6ire 8rotocol............................................................................................................................+B<
5ther operators (&% , #% , "% , !%).......................................................................................................I<
8ing...................................................................................................................................................+BI
8ing # 7ew8ing.................................................................................................................................+<I
8in@ode().........................................................................................................................................+FG
8ointer operators...............................................................................................................................+FG
8ow()................................................................................................................................................+FG
8A53@O@......................................................................................................................................+FB
8ulse2n()...........................................................................................................................................+FH
Aandom()..........................................................................................................................................+FM
Aandom=eed(seed)...........................................................................................................................+FI
Aeturn...............................................................................................................................................+FI
=d e.ample: Dard2nfo.......................................................................................................................+HF
=d e.ample: Natalogger....................................................................................................................+H+
=d e.ample: NumpPile.....................................................................................................................+HB
=d file#class: file.available().............................................................................................................+JB
=d file#class: file.close()...................................................................................................................+JB
=d file#class: file.flush()...................................................................................................................+JB
=d file#class: file.isNirector().........................................................................................................+JF
=d file#class: file.open7e.tPile()......................................................................................................+JJ
=d file#class: file.peek()....................................................................................................................+JH
=d file#class: file.position()..............................................................................................................+JH
=d file#class: file.print()....................................................................................................................+JH
=d file#class: file.println().................................................................................................................+JM
=d file#class: file.read().....................................................................................................................+JM
=d file#class: file.rewindNirector().................................................................................................+JI
=d file#class: file.seek()....................................................................................................................+JK
=d file#class: file.si?e().....................................................................................................................+JK
=d file#class: file.write()...................................................................................................................+JK
=N librar.........................................................................................................................................+JG
=d.begin().........................................................................................................................................+JG
=d.e.ists().........................................................................................................................................+J+
=d.mkdir().........................................................................................................................................+J+
=d.open()..........................................................................................................................................+J<
=d.remove()......................................................................................................................................+J<
=d.rmdir().........................................................................................................................................+J<
=emicolon (;)....................................................................................................................................+HH
=erial.................................................................................................................................................+HH
=erialOvent().....................................................................................................................................+HM
=ervo librar.....................................................................................................................................+HK
=ervo.attach()....................................................................................................................................+MG
=ervo.attached()................................................................................................................................+MG
=ervo.detach()...................................................................................................................................+M+
<KH
=ervo.read()......................................................................................................................................+M+
=ervo.write().....................................................................................................................................+M+
=ervo.write@icroseconds()...............................................................................................................+M<
=etup()..............................................................................................................................................+MB
=hift2n()............................................................................................................................................+MB
=hift5ut()..........................................................................................................................................+MB
=imple=NAudio................................................................................................................................+MH
=in(rad).............................................................................................................................................+I+
=i?eof................................................................................................................................................+I+
=oftware=erial 4ibrar.....................................................................................................................+I<
=oftware=erial: available()...............................................................................................................+IF
=oftware=erial: begin(speed)............................................................................................................+IF
=oftware=erial: is4istening()............................................................................................................+IJ
=oftware=erial: listen().....................................................................................................................+IH
=oftware=erial: overflow()...............................................................................................................+IM
=oftware=erial: peek.........................................................................................................................+II
=oftware=erial: print(data)...............................................................................................................+II
=oftware=erial: println(data)............................................................................................................+IK
=oftware=erial: read.........................................................................................................................+KG
=oftware=erial: write(data)...............................................................................................................+KG
=82 # Nigital 8otentiometer Dontrol.................................................................................................+KH
=82 librar.........................................................................................................................................+K+
=82.begin()........................................................................................................................................+KM
=82.end()...........................................................................................................................................+KM
=82.setCit5rder()..............................................................................................................................+KI
=82.setDlockNivider()......................................................................................................................+KI
=82.setNata@ode()...........................................................................................................................+KI
=82.transfer()....................................................................................................................................+KK
=)rt(.)...............................................................................................................................................+KK
=tatic.................................................................................................................................................+KK
=tepper librar..................................................................................................................................<GG
=tepper.set=peed(rpms)....................................................................................................................<GB
=tepper.step(steps)............................................................................................................................<GB
=tepper(steps, pin+, pin<, pinB, pinF)...............................................................................................<GB
=tepper(steps, pin+, pin<).................................................................................................................<GB
=tream...............................................................................................................................................<GF
=tream.available().............................................................................................................................<GJ
=tream.find().....................................................................................................................................<GJ
=tream.find9ntil()............................................................................................................................<GJ
=tream.flush()...................................................................................................................................<GH
=tream.parsePloat()..........................................................................................................................<GH
=tream.parse2nt()..............................................................................................................................<GH
=tream.peek()....................................................................................................................................<GM
=tream.read()....................................................................................................................................<GI
=tream.readCtes()...........................................................................................................................<GM
=tream.readCtes9ntil()...................................................................................................................<GM
=tream.set:imeout().........................................................................................................................<GI
=tring................................................................................................................................................<GI
=tring (U V (element access))..............................................................................................................<<+
=tring (& operator)............................................................................................................................<<H
=tring (%% operator)..........................................................................................................................<<<
=tring class........................................................................................................................................<+G
<KM
=tring.charAt()..................................................................................................................................<<+
=tring.compare:o()..........................................................................................................................<<+
=tring.concat()..................................................................................................................................<<<
=tring.ends6ith().............................................................................................................................<<F
=tring.e)uals()..................................................................................................................................<<F
=tring.e)uals2gnoreDase()................................................................................................................<<F
=tring.getCtes()...............................................................................................................................<<F
=tring.inde.5f()................................................................................................................................<<J
=tring.last2nde.5f()..........................................................................................................................<<J
=tring.length()...................................................................................................................................<<J
=tring.replace().................................................................................................................................<<H
=tring.setDharAt()............................................................................................................................<<H
=tring.starts6ith()............................................................................................................................<<M
=tring.substring()..............................................................................................................................<<M
=tring.toDharArra()........................................................................................................................<<M
=tring.to4owerDase().......................................................................................................................<<I
=tring.to9pperDase()........................................................................................................................<<I
=tring.trim()......................................................................................................................................<<I
=tring()..............................................................................................................................................<<B
=tringAddition5perator....................................................................................................................<++
=tringAppend5perator.....................................................................................................................<+B
=tringDaseDhanges...........................................................................................................................<+J
=tringDharacters...............................................................................................................................<+M
=tringDomparison5perators.............................................................................................................<+K
=tringDonstructors............................................................................................................................<++
=tring2nde.5f...................................................................................................................................<+<
=tring4ength:rim.............................................................................................................................<+B
=tringAeplace...................................................................................................................................<+H
=tring=tarts6ithOnds6ith...............................................................................................................<+I
=tring=ubstring.................................................................................................................................<<G
=witch ! case statements...................................................................................................................<<K
:an(rad)............................................................................................................................................<<K
:ime librar......................................................................................................................................<BG
:one()...............................................................................................................................................<BF
9 ' 4 formatters................................................................................................................................IB
9nsigned char...................................................................................................................................<BF
9nsigned int......................................................................................................................................<BF
9nsigned long...................................................................................................................................<BJ
Lariable scope..................................................................................................................................+FK
Lariables...........................................................................................................................................<BH
Loid..................................................................................................................................................<BM
Lolatile keword..............................................................................................................................<BI
6hile loops.......................................................................................................................................<BK
6iPi # client.available()....................................................................................................................<HM
6iPi # client.connect()......................................................................................................................<MG
6iPi # client.connected()..................................................................................................................<HK
6iPi # client.flush()..........................................................................................................................<M+
6iPi # client.print()..........................................................................................................................<MB
6iPi # client.println().......................................................................................................................<MB
6iPi # client.read()...........................................................................................................................<MB
6iPi # client.stop()...........................................................................................................................<MF
6iPi # client.write()..........................................................................................................................<MF
<KI
6iPi # server.available()...................................................................................................................<I<
6iPi # server.begin()........................................................................................................................<IB
6iPi # server.print()..........................................................................................................................<IJ
6iPi # server.println()......................................................................................................................<IJ
6iPi # server.write().........................................................................................................................<IJ
6iPi : Dlient class............................................................................................................................<HM
6iPi e.ample # Dhat =erver............................................................................................................<FK
6iPi e.ample # Donnect7oOncrption............................................................................................<F+
6iPi e.ample # Donnect6ith6O8..................................................................................................<FB
6iPi e.ample # Donnect6ith68A..................................................................................................<FJ
6iPi e.ample # Aepeating 6ifi 6eb client.....................................................................................<H+
6iPi e.ample # =can7etworks.........................................................................................................<FM
6iPi e.ample # 6eb =erver............................................................................................................<HB
6iPi e.ample # 6eb client...............................................................................................................<JK
6iPi e.ample # 6iPi:witterDlient..................................................................................................<JM
6iPi librar......................................................................................................................................<BK
6iPi =erver()....................................................................................................................................<IF
6iPi.begin().....................................................................................................................................<HH
6iPi.C==2N()...................................................................................................................................<HH
6iPi.disconnect().............................................................................................................................<MF
6iPi.encrption:pe().....................................................................................................................<MF
6iPi.gatewa28().............................................................................................................................<MJ
6iPi.get=ocket()..............................................................................................................................<MH
6iPi.local28()...................................................................................................................................<MH
6iPi.macAddress()..........................................................................................................................<MM
6iPi.A==2()......................................................................................................................................<MI
6iPi.scan7etworks()........................................................................................................................<MK
6iPi.==2N()......................................................................................................................................<MK
6iPi.subnet@ask()...........................................................................................................................<I+
6iPiDlient().....................................................................................................................................<M+
6ire 4ibrar.....................................................................................................................................<IM
6ire.available()................................................................................................................................<IM
6ire.begin()......................................................................................................................................<IM
6ire.begin:ransmission(address)....................................................................................................<II
6ire.end:ransmission()...................................................................................................................<II
6ire.onAeceive(handler)..................................................................................................................<II
6ire.onAe)uest(handler)..................................................................................................................<IK
6ire.read()........................................................................................................................................<IK
6ire.receive()...................................................................................................................................<IK
6ire.re)uestProm()..........................................................................................................................<KG
6ire.send().......................................................................................................................................<KG
6ire.write()......................................................................................................................................<K+
6ord.................................................................................................................................................<K<
6ord()..............................................................................................................................................<K<
7ss8e9ll:totta+ #olti Imre ;<=;
<KK

Vous aimerez peut-être aussi