Arduino Cookbook
Arduino Cookbook
0LFKDHO0DUJROLV
Beijing • Cambridge • Farnham • Köln • Sebastopol • Tokyo
Arduino Cookbook
E\0LFKDHO0DUJROLV
&RS\ULJKW0LFKDHO0DUJROLVDQG1LFKRODV:HOGLQ$OOULJKWVUHVHUYHG
3ULQWHGLQWKH8QLWHG6WDWHVRI$PHULFD
3XEOLVKHGE\2¦5HLOO\0HGLD,QF*UDYHQVWHLQ+LJKZD\1RUWK6HEDVWRSRO&$
2¦5HLOO\ERRNVPD\EHSXUFKDVHGIRUHGXFDWLRQDOEXVLQHVVRUVDOHVSURPRWLRQDOXVH2QOLQHHGLWLRQV
DUHDOVRDYDLODEOHIRUPRVWWLWOHV KWWSP\VDIDULERRNVRQOLQHFRP )RUPRUHLQIRUPDWLRQFRQWDFWRXU
FRUSRUDWHLQVWLWXWLRQDOVDOHVGHSDUWPHQW RUFRUSRUDWH#RUHLOO\FRP
Editors: 6LPRQ6W/DXUHQWDQG%ULDQ-HSVRQ
Production Editor: 7HUHVD(OVH\
Copyeditor: $XGUH\'R\OH
Proofreader: 7HUHVD(OVH\
Indexer: /XFLH+DVNLQV
Cover Designer: .DUHQ0RQWJRPHU\
Interior Designer: 'DYLG)XWDWR
Illustrator: 5REHUW5RPDQR
Printing History:
0DUFK
)LUVW(GLWLRQ
1XWVKHOO+DQGERRNWKH1XWVKHOO+DQGERRNORJRDQGWKH2¦5HLOO\ORJRDUHUHJLVWHUHGWUDGHPDUNVRI
2¦5HLOO\0HGLD,QF$UGXLQR&RRNERRNWKHLPDJHRIDWR\UDEELWDQGUHODWHGWUDGHGUHVVDUHWUDGHPDUNV
RI2¦5HLOO\0HGLD,QF
0DQ\RIWKHGHVLJQDWLRQVXVHGE\PDQXIDFWXUHUVDQGVHOOHUVWRGLVWLQJXLVKWKHLUSURGXFWVDUHFODLPHGDV
WUDGHPDUNV:KHUHWKRVHGHVLJQDWLRQVDSSHDULQWKLVERRNDQG2¦5HLOO\0HGLD,QFZDVDZDUHRID
WUDGHPDUNFODLPWKHGHVLJQDWLRQVKDYHEHHQSULQWHGLQFDSVRULQLWLDOFDSV
:KLOHHYHU\SUHFDXWLRQKDVEHHQWDNHQLQWKHSUHSDUDWLRQRIWKLVERRNWKHSXEOLVKHUDQGDXWKRUVDVVXPH
QRUHVSRQVLELOLW\IRUHUURUVRURPLVVLRQVRUIRUGDPDJHVUHVXOWLQJIURPWKHXVHRIWKHLQIRUPDWLRQFRQ
WDLQHGKHUHLQ
,6%1
>/6,@
Table of Contents
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
1. Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
,QVWDOOLQJWKH,QWHJUDWHG'HYHORSPHQW(QYLURQPHQW ,'(
6HWWLQJ8SWKH$UGXLQR%RDUG
8VLQJWKH,QWHJUDWHG'HYHORSPHQW(QYLURQPHQW ,'( WR3UHSDUH
DQ$UGXLQR6NHWFK
8SORDGLQJDQG5XQQLQJWKH%OLQN6NHWFK
&UHDWLQJDQG6DYLQJD6NHWFK
8VLQJ$UGXLQR
2. Making the Sketch Do Your Bidding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
6WUXFWXULQJDQ$UGXLQR3URJUDP
8VLQJ6LPSOH3ULPLWLYH7\SHV 9DULDEOHV
8VLQJ)ORDWLQJ3RLQW1XPEHUV
:RUNLQJZLWK*URXSVRI9DOXHV
8VLQJ$UGXLQR6WULQJ)XQFWLRQDOLW\
8VLQJ&&KDUDFWHU6WULQJV
6SOLWWLQJ&RPPD6HSDUDWHG7H[WLQWR*URXSV
&RQYHUWLQJD1XPEHUWRD6WULQJ
&RQYHUWLQJD6WULQJWRD1XPEHU
6WUXFWXULQJ<RXU&RGHLQWR)XQFWLRQDO%ORFNV
5HWXUQLQJ0RUH7KDQ2QH9DOXHIURPD)XQFWLRQ
7DNLQJ$FWLRQV%DVHGRQ&RQGLWLRQV
5HSHDWLQJD6HTXHQFHRI6WDWHPHQWV
5HSHDWLQJ6WDWHPHQWVZLWKD&RXQWHU
%UHDNLQJ2XWRI/RRSV
7DNLQJD9DULHW\RI$FWLRQV%DVHGRQD6LQJOH9DULDEOH
&RPSDULQJ&KDUDFWHUDQG1XPHULF9DOXHV
&RPSDULQJ6WULQJV
3HUIRUPLQJ/RJLFDO&RPSDULVRQV
v
3HUIRUPLQJ%LWZLVH2SHUDWLRQV
&RPELQLQJ2SHUDWLRQVDQG$VVLJQPHQW
3. Using Mathematical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
$GGLQJ6XEWUDFWLQJ0XOWLSO\LQJDQG'LYLGLQJ
,QFUHPHQWLQJDQG'HFUHPHQWLQJ9DOXHV
)LQGLQJWKH5HPDLQGHU$IWHU'LYLGLQJ7ZR9DOXHV
'HWHUPLQLQJWKH$EVROXWH9DOXH
&RQVWUDLQLQJD1XPEHUWRD5DQJHRI9DOXHV
)LQGLQJWKH0LQLPXPRU0D[LPXPRI6RPH9DOXHV
5DLVLQJD1XPEHUWRD3RZHU
7DNLQJWKH6TXDUH5RRW
5RXQGLQJ)ORDWLQJ3RLQW1XPEHUV8SDQG'RZQ
8VLQJ7ULJRQRPHWULF)XQFWLRQV
*HQHUDWLQJ5DQGRP1XPEHUV
6HWWLQJDQG5HDGLQJ%LWV
6KLIWLQJ%LWV
([WUDFWLQJ+LJKDQG/RZ%\WHVLQDQLQWRUORQJ
)RUPLQJDQLQWRUORQJIURP+LJKDQG/RZ%\WHV
4. Serial Communications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
6HQGLQJ'HEXJ,QIRUPDWLRQIURP$UGXLQRWR<RXU&RPSXWHU
6HQGLQJ)RUPDWWHG7H[WDQG1XPHULF'DWDIURP$UGXLQR
5HFHLYLQJ6HULDO'DWDLQ$UGXLQR
6HQGLQJ0XOWLSOH7H[W)LHOGVIURP$UGXLQRLQD6LQJOH0HVVDJH
5HFHLYLQJ0XOWLSOH7H[W)LHOGVLQD6LQJOH0HVVDJHLQ$UGXLQR
6HQGLQJ%LQDU\'DWDIURP$UGXLQR
5HFHLYLQJ%LQDU\'DWDIURP$UGXLQRRQD&RPSXWHU
6HQGLQJ%LQDU\9DOXHVIURP3URFHVVLQJWR$UGXLQR
6HQGLQJWKH9DOXHRI0XOWLSOH$UGXLQR3LQV
+RZWR0RYHWKH0RXVH&XUVRURQD3&RU0DF
&RQWUROOLQJ*RRJOH(DUWK8VLQJ$UGXLQR
/RJJLQJ$UGXLQR'DWDWRD)LOHRQ<RXU&RPSXWHU
6HQGLQJ'DWDWR7ZR6HULDO'HYLFHVDWWKH6DPH7LPH
5HFHLYLQJ6HULDO'DWDIURP7ZR'HYLFHVDWWKH6DPH7LPH
6HWWLQJ8S3URFHVVLQJRQ<RXU&RPSXWHUWR6HQG
DQG5HFHLYH6HULDO'DWD
5. Simple Digital and Analog Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
8VLQJD6ZLWFK
8VLQJD6ZLWFK:LWKRXW([WHUQDO5HVLVWRUV
5HOLDEO\'HWHFWLQJWKH&ORVLQJRID6ZLWFK
'HWHUPLQLQJ+RZ/RQJD6ZLWFK,V3UHVVHG
vi | Table of Contents
5HDGLQJD.H\SDG
5HDGLQJ$QDORJ9DOXHV
&KDQJLQJWKH5DQJHRI9DOXHV
5HDGLQJ0RUH7KDQ6L[$QDORJ,QSXWV
'LVSOD\LQJ9ROWDJHV8SWR9
5HVSRQGLQJWR&KDQJHVLQ9ROWDJH
0HDVXULQJ9ROWDJHV0RUH7KDQ9 9ROWDJH'LYLGHUV
6. Getting Input from Sensors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
'HWHFWLQJ0RYHPHQW
'HWHFWLQJ/LJKW
'HWHFWLQJ0RWLRQ ,QWHJUDWLQJ3DVVLYH,QIUDUHG'HWHFWRUV
0HDVXULQJ'LVWDQFH
0HDVXULQJ'LVWDQFH$FFXUDWHO\
'HWHFWLQJ9LEUDWLRQ
'HWHFWLQJ6RXQG
0HDVXULQJ7HPSHUDWXUH
5HDGLQJ5),'7DJV
7UDFNLQJWKH0RYHPHQWRID'LDO
7UDFNLQJWKH0RYHPHQWRI0RUH7KDQ2QH5RWDU\(QFRGHU
7UDFNLQJWKH0RYHPHQWRID'LDOLQD%XV\6NHWFK
8VLQJD0RXVH
*HWWLQJ/RFDWLRQIURPD*36
'HWHFWLQJ5RWDWLRQ8VLQJD*\URVFRSH
'HWHFWLQJ'LUHFWLRQ
*HWWLQJ,QSXWIURPD*DPH&RQWURO3DG 3OD\6WDWLRQ
5HDGLQJ$FFHOHUDWLRQ
7. Visual Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
&RQQHFWLQJDQG8VLQJ/('V
$GMXVWLQJWKH%ULJKWQHVVRIDQ/('
'ULYLQJ+LJK3RZHU/('V
$GMXVWLQJWKH&RORURIDQ/('
6HTXHQFLQJ0XOWLSOH/('V&UHDWLQJD%DU*UDSK
6HTXHQFLQJ0XOWLSOH/('V0DNLQJD&KDVH6HTXHQFH .QLJKW
5LGHU
&RQWUROOLQJDQ/('0DWUL[8VLQJ0XOWLSOH[LQJ
'LVSOD\LQJ,PDJHVRQDQ/('0DWUL[
&RQWUROOLQJD0DWUL[RI/('V&KDUOLHSOH[LQJ
'ULYLQJD6HJPHQW/(''LVSOD\
'ULYLQJ0XOWLGLJLW6HJPHQW/(''LVSOD\V0XOWLSOH[LQJ
'ULYLQJ0XOWLGLJLW6HJPHQW/(''LVSOD\V8VLQJ0$;6KLIW
5HJLVWHUV
Table of Contents | vii
&RQWUROOLQJDQ$UUD\RI/('VE\8VLQJ0$;[[6KLIW5HJLVWHUV
,QFUHDVLQJWKH1XPEHURI$QDORJ2XWSXWV8VLQJ3:0([WHQGHU
&KLSV 7/&
8VLQJDQ$QDORJ3DQHO0HWHU$VD'LVSOD\
8. Physical Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
&RQWUROOLQJWKH3RVLWLRQRID6HUYR
&RQWUROOLQJ2QHRU7ZR6HUYRVZLWKD3RWHQWLRPHWHU
RU6HQVRU
&RQWUROOLQJWKH6SHHGRI&RQWLQXRXV5RWDWLRQ6HUYRV
&RQWUROOLQJ6HUYRVIURPWKH6HULDO3RUW
'ULYLQJD%UXVKOHVV0RWRU 8VLQJD+REE\6SHHG&RQWUROOHU
&RQWUROOLQJ6ROHQRLGVDQG5HOD\V
0DNLQJDQ2EMHFW9LEUDWH
'ULYLQJD%UXVKHG0RWRU8VLQJD7UDQVLVWRU
&RQWUROOLQJWKH'LUHFWLRQRID%UXVKHG0RWRU
ZLWKDQ+%ULGJH
&RQWUROOLQJWKH'LUHFWLRQDQG6SHHGRID%UXVKHG0RWRUZLWKDQ
+%ULGJH
8VLQJ6HQVRUVWR&RQWUROWKH'LUHFWLRQDQG6SHHGRI%UXVKHG
0RWRUV /+%ULGJH
'ULYLQJD%LSRODU6WHSSHU0RWRU
'ULYLQJD%LSRODU6WHSSHU0RWRU 8VLQJWKH(DV\'ULYHU%RDUG
'ULYLQJD8QLSRODU6WHSSHU0RWRU 8/1$
9. Audio Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
3OD\LQJ7RQHV
3OD\LQJD6LPSOH0HORG\
*HQHUDWLQJ0RUH7KDQ2QH6LPXOWDQHRXV7RQH
*HQHUDWLQJ$XGLR7RQHVDQG)DGLQJDQ/('
3OD\LQJD:$9)LOH
&RQWUROOLQJ0,',
0DNLQJDQ$XGLR6\QWKHVL]HU
10. Remotely Controlling External Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
5HVSRQGLQJWRDQ,QIUDUHG5HPRWH&RQWURO
'HFRGLQJ,QIUDUHG5HPRWH&RQWURO6LJQDOV
,PLWDWLQJ5HPRWH&RQWURO6LJQDOV
&RQWUROOLQJD'LJLWDO&DPHUD
&RQWUROOLQJ$&'HYLFHVE\+DFNLQJD5HPRWH&RQWUROOHG6ZLWFK
11. Using Displays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
&RQQHFWLQJDQG8VLQJD7H[W/&''LVSOD\
viii | Table of Contents
)RUPDWWLQJ7H[W
7XUQLQJWKH&XUVRUDQG'LVSOD\2QRU2II
6FUROOLQJ7H[W
'LVSOD\LQJ6SHFLDO6\PEROV
&UHDWLQJ&XVWRP&KDUDFWHUV
'LVSOD\LQJ6\PEROV/DUJHU7KDQD6LQJOH&KDUDFWHU
'LVSOD\LQJ3L[HOV6PDOOHU7KDQD6LQJOH&KDUDFWHU
&RQQHFWLQJDQG8VLQJD*UDSKLFDO/&''LVSOD\
&UHDWLQJ%LWPDSVIRU8VHZLWKD*UDSKLFDO'LVSOD\
'LVSOD\LQJ7H[WRQD79
12. Using Time and Dates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
&UHDWLQJ'HOD\V
8VLQJPLOOLVWR'HWHUPLQH'XUDWLRQ
0RUH3UHFLVHO\0HDVXULQJWKH'XUDWLRQRID3XOVH
8VLQJ$UGXLQR$VD&ORFN
&UHDWLQJDQ$ODUPWR3HULRGLFDOO\&DOOD)XQFWLRQ
8VLQJD5HDO7LPH&ORFN
13. Communicating Using I2C and SPI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
&RQWUROOLQJDQ5*%/('8VLQJWKH%OLQN00RGXOH
8VLQJWKH:LL1XQFKXFN$FFHOHURPHWHU
,QWHUIDFLQJWRDQ([WHUQDO5HDO7LPH&ORFN
$GGLQJ([WHUQDO((35200HPRU\
5HDGLQJ7HPSHUDWXUHZLWKD'LJLWDO7KHUPRPHWHU
'ULYLQJ)RXU6HJPHQW/('V8VLQJ2QO\7ZR:LUHV
,QWHJUDWLQJDQ,&3RUW([SDQGHU
'ULYLQJ0XOWLGLJLW6HJPHQW'LVSOD\V8VLQJ63,
&RPPXQLFDWLQJ%HWZHHQ7ZRRU0RUH$UGXLQR%RDUGV
14. Wireless Communication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425
6HQGLQJ0HVVDJHV8VLQJ/RZ&RVW:LUHOHVV0RGXOHV
&RQQHFWLQJ$UGXLQRWRD=LJ%HHRU1HWZRUN
6HQGLQJD0HVVDJHWRD3DUWLFXODU;%HH
6HQGLQJ6HQVRU'DWD%HWZHHQ;%HHV
$FWLYDWLQJDQ$FWXDWRU&RQQHFWHGWRDQ;%HH
15. Ethernet and Networking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
6HWWLQJ8SWKH(WKHUQHW6KLHOG
2EWDLQLQJ<RXU,3$GGUHVV$XWRPDWLFDOO\
5HVROYLQJ+RVWQDPHVWR,3$GGUHVVHV '16
5HTXHVWLQJ'DWDIURPD:HE6HUYHU
5HTXHVWLQJ'DWDIURPD:HE6HUYHU8VLQJ;0/
Table of Contents | ix
6HWWLQJ8SDQ$UGXLQRWR%HD:HE6HUYHU
+DQGOLQJ,QFRPLQJ:HE5HTXHVWV
+DQGOLQJ,QFRPLQJ5HTXHVWVIRU6SHFLILF3DJHV
8VLQJ+70/WR)RUPDW:HE6HUYHU5HVSRQVHV
6HUYLQJ:HE3DJHV8VLQJ)RUPV 3267
6HUYLQJ:HE3DJHV&RQWDLQLQJ/DUJH$PRXQWVRI'DWD
6HQGLQJ7ZLWWHU0HVVDJHV
6HQGLQJDQG5HFHLYLQJ6LPSOH0HVVDJHV 8'3
*HWWLQJWKH7LPHIURPDQ,QWHUQHW7LPH6HUYHU
0RQLWRULQJ3DFKXEH)HHGV
6HQGLQJ,QIRUPDWLRQWR3DFKXEH
16. Using, Modifying, and Creating Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515
8VLQJWKH%XLOWLQ/LEUDULHV
,QVWDOOLQJ7KLUG3DUW\/LEUDULHV
0RGLI\LQJD/LEUDU\
&UHDWLQJ<RXU2ZQ/LEUDU\
&UHDWLQJD/LEUDU\7KDW8VHV2WKHU/LEUDULHV
17. Advanced Coding and Memory Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531
8QGHUVWDQGLQJWKH$UGXLQR%XLOG3URFHVV
'HWHUPLQLQJWKH$PRXQWRI)UHHDQG8VHG5$0
6WRULQJDQG5HWULHYLQJ1XPHULF9DOXHVLQ3URJUDP0HPRU\
6WRULQJDQG5HWULHYLQJ6WULQJVLQ3URJUDP0HPRU\
8VLQJGHILQHDQGFRQVW,QVWHDGRI,QWHJHUV
8VLQJ&RQGLWLRQDO&RPSLODWLRQV
18. Using the Controller Chip Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547
6WRULQJ'DWDLQ3HUPDQHQW((35200HPRU\
8VLQJ+DUGZDUH,QWHUUXSWV
6HWWLQJ7LPHU'XUDWLRQ
6HWWLQJ7LPHU3XOVH:LGWKDQG'XUDWLRQ
&UHDWLQJD3XOVH*HQHUDWRU
&KDQJLQJD7LPHU¦V3:0)UHTXHQF\
&RXQWLQJ3XOVHV
0HDVXULQJ3XOVHV0RUH$FFXUDWHO\
0HDVXULQJ$QDORJ9DOXHV4XLFNO\
5HGXFLQJ%DWWHU\'UDLQ
6HWWLQJ'LJLWDO3LQV4XLFNO\
A. Electronic Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 579
B. Using Schematic Diagrams and Data Sheets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585
x | Table of Contents
C. Building and Connecting the Circuit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591
D. Tips on Troubleshooting Software Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595
E. Tips on Troubleshooting Hardware Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599
F. Digital and Analog Pins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603
G. ASCII and Extended Character Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 607
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 611
Table of Contents | xi
Preface
7KLVERRNZDVZULWWHQE\0LFKDHO0DUJROLVZLWK1LFN:HOGLQWRKHOS\RXH[SORUHWKH
DPD]LQJWKLQJV\RXFDQGRZLWK$UGXLQR
$UGXLQRLVDIDPLO\RIPLFURFRQWUROOHUV WLQ\FRPSXWHUV DQGDVRIWZDUHFUHDWLRQHQYL
URQPHQWWKDWPDNHVLWHDV\IRU\RXWRFUHDWHSURJUDPV FDOOHGVNHWFKHV WKDWFDQLQWHUDFW
ZLWK WKH SK\VLFDO ZRUOG 7KLQJV \RX PDNH ZLWK $UGXLQR FDQ VHQVH DQG UHVSRQG WR
WRXFKVRXQGSRVLWLRQKHDWDQGOLJKW7KLVW\SHRIWHFKQRORJ\RIWHQUHIHUUHGWRDV
SK\VLFDOFRPSXWLQJLVXVHGLQDOONLQGVRIWKLQJVIURPWKHL3KRQHWRDXWRPRELOHHOHF
WURQLFVV\VWHPV$UGXLQRPDNHVLWSRVVLEOHIRUDQ\RQH¢HYHQSHRSOHZLWKQRSURJUDP
PLQJRUHOHFWURQLFVH[SHULHQFH¢WRXVHWKLVULFKDQGFRPSOH[WHFKQRORJ\
Who This Book Is For
8QOLNHLQPRVWWHFKQLFDOFRRNERRNVH[SHULHQFHZLWKVRIWZDUHDQGKDUGZDUHLVQRW
DVVXPHG7KLVERRNLVDLPHGDWDEURDGUDQJHRIUHDGHUVLQWHUHVWHGLQXVLQJFRPSXWHU
WHFKQRORJ\WRLQWHUDFWZLWKWKHHQYLURQPHQW,WLVIRUSHRSOHZKRZDQWWRTXLFNO\ILQG
WKHVROXWLRQWRKDUGZDUHDQGVRIWZDUHSUREOHPV
<RXPD\KDYHQRSURJUDPPLQJH[SHULHQFH¢SHUKDSV\RXKDYHDJUHDWLGHDIRUDQLQ
WHUDFWLYHSURMHFWEXWGRQ¦WKDYHWKHVNLOOVWRGHYHORSLW7KLVERRNZLOOKHOS\RXOHDUQ
ZKDW\RXQHHGWRNQRZWRZULWHFRGHWKDWZRUNVXVLQJH[DPSOHVWKDWFRYHUWKHNLQGV
RIWDVNV\RXZDQWWRSHUIRUP
,I\RXKDYHVRPHSURJUDPPLQJH[SHULHQFHEXWDUHQHZWR$UGXLQRWKHERRNZLOOKHOS
\RXEHFRPHSURGXFWLYHTXLFNO\E\GHPRQVWUDWLQJKRZWRLPSOHPHQWVSHFLILF$UGXLQR
FDSDELOLWLHVIRU\RXUSURMHFW
3HRSOHDOUHDG\XVLQJ$UGXLQRVKRXOGILQGWKHFRQWHQWKHOSIXOIRUTXLFNO\OHDUQLQJQHZ
WHFKQLTXHVZKLFKDUHH[SODLQHGXVLQJSUDFWLFDOH[DPSOHV7KLVZLOOKHOS\RXWRHPEDUN
RQPRUHFRPSOH[SURMHFWVE\VKRZLQJKRZWRVROYHSUREOHPVDQGXVHFDSDELOLWLHVWKDW
PD\EHQHZWR\RX
([SHULHQFHG&&SURJUDPPHUVZLOOILQGH[DPSOHVRIKRZWRXVHWKHORZOHYHO$95
UHVRXUFHV LQWHUUXSWV WLPHUV ,& (WKHUQHW HWF WR EXLOG DSSOLFDWLRQV XVLQJ WKH
$UGXLQRHQYLURQPHQW
xiii
How This Book Is Organized
7KHERRNFRQWDLQVLQIRUPDWLRQWKDWFRYHUVWKHEURDGUDQJHRIWKH$UGXLQR¦VFDSDELOL
WLHVIURPEDVLFFRQFHSWVDQGFRPPRQWDVNVWRDGYDQFHGWHFKQRORJ\(DFKWHFKQLTXH
LVH[SODLQHGLQDUHFLSHWKDWVKRZV\RXKRZWRLPSOHPHQWDVSHFLILFFDSDELOLW\<RXGR
QRWQHHGWRUHDGWKHFRQWHQWLQVHTXHQFH
&KDSWHU*HWWLQJ6WDUWHGLQWURGXFHVWKH$UGXLQRHQYLURQPHQWDQGSURYLGHVKHOSRQ
JHWWLQJWKH$UGXLQRGHYHORSPHQWHQYLURQPHQWDQGKDUGZDUHLQVWDOOHGDQGZRUNLQJ
7KH QH[W FRXSOH RI FKDSWHUV LQWURGXFH $UGXLQR VRIWZDUH GHYHORSPHQW &KDSWHU 0DNLQJWKH6NHWFK'R<RXU%LGGLQJFRYHUVHVVHQWLDOVRIWZDUHFRQFHSWVDQGWDVNVDQG
&KDSWHU8VLQJ0DWKHPDWLFDO2SHUDWRUVVKRZVKRZWRPDNHXVHRIWKHPRVWFRPPRQ
PDWKHPDWLFDOIXQFWLRQV
&KDSWHU6HULDO&RPPXQLFDWLRQVGHVFULEHVKRZWRJHW$UGXLQRWRFRQQHFWDQGFRP
PXQLFDWHZLWK\RXUFRPSXWHUDQGRWKHUGHYLFHV6HULDOLVWKHPRVWFRPPRQPHWKRG
IRU $UGXLQR LQSXW DQG RXWSXW DQG WKLV FDSDELOLW\ LV XVHG LQ PDQ\ RI WKH UHFLSHV
WKURXJKRXWWKHERRN
&KDSWHU6LPSOH'LJLWDODQG$QDORJ,QSXWLQWURGXFHVDUDQJHRIEDVLFWHFKQLTXHVIRU
UHDGLQJGLJLWDODQGDQDORJVLJQDOV&KDSWHU*HWWLQJ,QSXWIURP6HQVRUVEXLOGVRQWKLV
ZLWKUHFLSHVWKDWH[SODLQKRZWRXVHGHYLFHVWKDWHQDEOH$UGXLQRWRVHQVHWRXFKVRXQG
SRVLWLRQKHDWDQGOLJKW
&KDSWHU9LVXDO2XWSXWFRYHUVFRQWUROOLQJOLJKW5HFLSHVFRYHUVZLWFKLQJRQRQHRU
PDQ\/('VDQGFRQWUROOLQJEULJKWQHVVDQGFRORU7KLVFKDSWHUH[SODLQVKRZ\RXFDQ
GULYHEDUJUDSKVDQGQXPHULF/('GLVSOD\VDVZHOODVFUHDWHSDWWHUQVDQGDQLPDWLRQV
ZLWK/('DUUD\V,QDGGLWLRQWKHFKDSWHUSURYLGHVDJHQHUDOLQWURGXFWLRQWRGLJLWDODQG
DQDORJRXWSXWIRUWKRVHZKRDUHQHZWRWKLV
&KDSWHU3K\VLFDO2XWSXWH[SODLQVKRZ\RXFDQPDNHWKLQJVPRYHE\FRQWUROOLQJ
PRWRUVZLWK$UGXLQR$ZLGHUDQJHRIPRWRUW\SHVDUHFRYHUHGVROHQRLGVVHUYRPRWRUV
'&PRWRUVDQGVWHSSHUPRWRUV
&KDSWHU$XGLR2XWSXWVKRZVKRZWRJHQHUDWHVRXQGZLWK$UGXLQRWKURXJKDQRXW
SXWGHYLFHVXFKDVDVSHDNHU,WFRYHUVSOD\LQJVLPSOHWRQHVDQGPHORGLHVDQGSOD\LQJ
:$9ILOHVDQG0,',
&KDSWHU5HPRWHO\&RQWUROOLQJ([WHUQDO'HYLFHVGHVFULEHVWHFKQLTXHVWKDWFDQEH
XVHGWRLQWHUDFWZLWKDOPRVWDQ\GHYLFHWKDWXVHVVRPHIRUPRIUHPRWHFRQWUROOHULQ
FOXGLQJ79DXGLRHTXLSPHQWFDPHUDVJDUDJHGRRUVDSSOLDQFHVDQGWR\V,WEXLOGV
RQ WHFKQLTXHV XVHG LQ SUHYLRXV FKDSWHUV IRU FRQQHFWLQJ $UGXLQR WR GHYLFHV DQG
PRGXOHV
&KDSWHU8VLQJ'LVSOD\VFRYHUVLQWHUIDFLQJWH[WDQGJUDSKLFDO/&'GLVSOD\V7KH
FKDSWHUVKRZVKRZ\RXFDQFRQQHFWWKHVHGHYLFHVWRGLVSOD\WH[WVFUROORUKLJKOLJKW
ZRUGVDQGFUHDWHVSHFLDOV\PEROVDQGFKDUDFWHUV
xiv | Preface
&KDSWHU8VLQJ7LPHDQG'DWHVFRYHUVEXLOWLQ$UGXLQRWLPHUHODWHGIXQFWLRQVDQG
LQWURGXFHVPDQ\DGGLWLRQDOWHFKQLTXHVIRUKDQGOLQJWLPHGHOD\VWLPHPHDVXUHPHQW
DQGUHDOZRUOGWLPHVDQGGDWHV
&KDSWHU &RPPXQLFDWLQJ 8VLQJ ,& DQG 63, FRYHUV WKH ,QWHU,QWHJUDWHG &LUFXLW
,& DQG6HULDO3HULSKHUDO,QWHUIDFH 63, VWDQGDUGV7KHVHVWDQGDUGVSURYLGHVLPSOH
ZD\VIRUGLJLWDOLQIRUPDWLRQWREHWUDQVIHUUHGEHWZHHQVHQVRUVDQG$UGXLQR7KLVFKDS
WHUVKRZVKRZWRXVH,&DQG63,WRFRQQHFWWRFRPPRQGHYLFHV,WDOVRVKRZVKRZWR
FRQQHFWWZRRUPRUH$UGXLQRERDUGVXVLQJ,&IRUPXOWLERDUGDSSOLFDWLRQV
&KDSWHU:LUHOHVV&RPPXQLFDWLRQFRYHUVZLUHOHVVFRPPXQLFDWLRQZLWK;%HH7KLV
FKDSWHUSURYLGHVH[DPSOHVUDQJLQJIURPVLPSOHZLUHOHVVVHULDOSRUWUHSODFHPHQWVWR
PHVKQHWZRUNVFRQQHFWLQJPXOWLSOHERDUGVWRPXOWLSOHVHQVRUV
&KDSWHU(WKHUQHWDQG1HWZRUNLQJGHVFULEHVWKHPDQ\ZD\V\RXFDQXVH$UGXLQR
ZLWKWKH,QWHUQHW,WKDVH[DPSOHVWKDWGHPRQVWUDWHKRZWREXLOGDQGXVHZHEFOLHQWV
DQGVHUYHUVDQGVKRZVKRZWRXVHWKHPRVWFRPPRQ,QWHUQHWFRPPXQLFDWLRQSURWRFROV
ZLWK$UGXLQR
$UGXLQRVRIWZDUHOLEUDULHVDUHDVWDQGDUGZD\RIDGGLQJIXQFWLRQDOLW\WRWKH$UGXLQR
HQYLURQPHQW&KDSWHU8VLQJ0RGLI\LQJDQG&UHDWLQJ/LEUDULHVH[SODLQVKRZWR
XVHDQGPRGLI\VRIWZDUHOLEUDULHV,WDOVRSURYLGHVJXLGDQFHRQKRZWRFUHDWH\RXURZQ
OLEUDULHV
&KDSWHU$GYDQFHG&RGLQJDQG0HPRU\+DQGOLQJFRYHUVDGYDQFHGSURJUDPPLQJ
WHFKQLTXHVDQGWKHWRSLFVKHUHDUHPRUHWHFKQLFDOWKDQWKHRWKHUUHFLSHVLQWKLVERRN
EHFDXVHWKH\FRYHUWKLQJVWKDWDUHXVXDOO\FRQFHDOHGE\WKHIULHQGO\$UGXLQRZUDSSHU
7KHWHFKQLTXHVLQWKLVFKDSWHUFDQEHXVHGWRPDNHDVNHWFKPRUHHIILFLHQW¢WKH\FDQ
KHOSLPSURYHSHUIRUPDQFHDQGUHGXFHWKHFRGHVL]HRI\RXUVNHWFKHV
&KDSWHU8VLQJWKH&RQWUROOHU&KLS+DUGZDUHVKRZVKRZWRDFFHVVDQGXVHKDUG
ZDUHIXQFWLRQVWKDWDUHQRWIXOO\H[SRVHGWKURXJKWKHGRFXPHQWHG$UGXLQRODQJXDJH
,WFRYHUVORZOHYHOXVDJHRIWKHKDUGZDUHLQSXWRXWSXWUHJLVWHUVWLPHUVDQGLQWHUUXSWV
$SSHQGL[$(OHFWURQLF&RPSRQHQWVSURYLGHVDQRYHUYLHZRIWKHFRPSRQHQWVXVHG
WKURXJKRXWWKHERRN
$SSHQGL[%8VLQJ6FKHPDWLF'LDJUDPVDQG'DWD6KHHWVH[SODLQVKRZWRXVHVFKHPDWLF
GLDJUDPVDQGGDWDVKHHWV
$SSHQGL[&%XLOGLQJDQG&RQQHFWLQJWKH&LUFXLWSURYLGHVDEULHILQWURGXFWLRQWRXVLQJ
DEUHDGERDUGFRQQHFWLQJDQGXVLQJH[WHUQDOSRZHUVXSSOLHVDQGEDWWHULHVDQGXVLQJ
FDSDFLWRUVIRUGHFRXSOLQJ
$SSHQGL['7LSVRQ7URXEOHVKRRWLQJ6RIWZDUH3UREOHPVSURYLGHVWLSVRQIL[LQJFRP
SLOHDQGUXQWLPHSUREOHPV
$SSHQGL[(7LSVRQ7URXEOHVKRRWLQJ+DUGZDUH3UREOHPVFRYHUVSUREOHPVZLWKHOHF
WURQLFFLUFXLWV
Preface | xv
$SSHQGL[)'LJLWDODQG$QDORJ3LQVSURYLGHVWDEOHVLQGLFDWLQJIXQFWLRQDOLW\SURYLGHG
E\WKHSLQVRQVWDQGDUG$UGXLQRERDUGV
$SSHQGL[ * $6&,, DQG ([WHQGHG &KDUDFWHU 6HWV SURYLGHV WDEOHV VKRZLQJ $6&,,
FKDUDFWHUV
What Was Left Out
7KHUHLVQ¦WURRPLQWKLVERRNWRFRYHUHOHFWURQLFVWKHRU\DQGSUDFWLFHDOWKRXJKJXLG
DQFHLVSURYLGHGIRUEXLOGLQJWKHFLUFXLWVXVHGLQWKHUHFLSHV)RUPRUHGHWDLOUHDGHUV
PD\ZDQWWRUHIHUWRPDWHULDOWKDWLVZLGHO\DYDLODEOHRQWKH,QWHUQHWRUWRERRNVVXFK
DVWKHIROORZLQJ
0DNH(OHFWURQLFVE\&KDUOHV3ODWW 2¦5HLOO\
*HWWLQJ6WDUWHGLQ(OHFWURQLFVE\)RUUHVW0LPV 0DVWHU3XEOLVKLQJ
3K\VLFDO&RPSXWLQJE\7RP,JRH &HQJDJH
3UDFWLFDO(OHFWURQLFVIRU,QYHQWRUVE\3DXO6FKHU] 0F*UDZ+LOO
7KLVFRRNERRNH[SODLQVKRZWRZULWHFRGHWRDFFRPSOLVKVSHFLILFWDVNVEXWLWLVQRWDQ
LQWURGXFWLRQWRSURJUDPPLQJ5HOHYDQWSURJUDPPLQJFRQFHSWVDUHEULHIO\H[SODLQHG
EXWWKHUH LV LQVXIILFLHQWURRP WR FRYHU WKH GHWDLOV ,I \RX ZDQWWROHDUQPRUHDERXW
SURJUDPPLQJ\RXPD\ZDQWWRUHIHUWRWKH,QWHUQHWRUWRRQHRIWKHIROORZLQJERRNV
3UDFWLFDO&3URJUDPPLQJE\6WHYH2XDOOLQH 2¦5HLOO\
$%RRNRQ&E\$O.HOOH\DQG,UD3RKO $GGLVRQ:HVOH\
0\ IDYRULWH DOWKRXJK QRW UHDOO\ D EHJLQQHU¦V ERRN LV WKH ERRN , XVHG WR OHDUQ
&SURJUDPPLQJ
7KH & 3URJUDPPLQJ /DQJXDJH E\ %ULDQ : .HUQLJKDQ DQG 'HQQLV 0 5LWFKLH
3UHQWLFH+DOO
Code Style (About the Code)
7KHFRGHXVHGWKURXJKRXWWKLVERRNKDVEHHQWDLORUHGWRFOHDUO\LOOXVWUDWHWKHWRSLF
FRYHUHGLQHDFKUHFLSH$VDFRQVHTXHQFHVRPHFRPPRQFRGLQJVKRUWFXWVKDYHEHHQ
DYRLGHGSDUWLFXODUO\LQWKHHDUO\FKDSWHUV([SHULHQFHG&SURJUDPPHUVRIWHQXVHULFK
EXWWHUVHH[SUHVVLRQVWKDWDUHHIILFLHQWEXWFDQEHDOLWWOHGLIILFXOWIRUEHJLQQHUVWRUHDG
)RUH[DPSOHWKHHDUO\FKDSWHUVLQFUHPHQWYDULDEOHVXVLQJH[SOLFLWH[SUHVVLRQVWKDWDUH
HDV\IRUQRQSURJUDPPHUVWRUHDG
result = result + 1; // increment the count
5DWKHUWKDQWKHIROORZLQJFRPPRQO\XVHGE\H[SHULHQFHGSURJUDPPHUVWKDWGRHVWKH
VDPHWKLQJ
result++;
xvi | Preface
// increment using the post increment operator
)HHOIUHHWRVXEVWLWXWH\RXUSUHIHUUHGVW\OH%HJLQQHUVVKRXOGEHUHDVVXUHGWKDWWKHUHLV
QREHQHILWLQSHUIRUPDQFHRUFRGHVL]HLQXVLQJWKHWHUVHIRUP
6RPHSURJUDPPLQJH[SUHVVLRQVDUHVRFRPPRQWKDWWKH\DUHXVHGLQWKHLUWHUVHIRUP
)RUH[DPSOHWKHORRSH[SUHVVLRQVDUHZULWWHQDVIROORZV
for(int i=0; i < 4; i++)
7KLVLVHTXLYDOHQWWRWKHIROORZLQJ
int i;
for(i=0; i < 4; i = i+1)
6HH&KDSWHUIRUPRUHGHWDLOVRQWKHVHDQGRWKHUH[SUHVVLRQVXVHGWKURXJKRXWWKH
ERRN
*RRGSURJUDPPLQJSUDFWLFHLQYROYHVHQVXULQJWKDWYDOXHVXVHGDUHYDOLG JDUEDJHLQ
HTXDOVJDUEDJHRXW E\FKHFNLQJWKHPEHIRUHXVLQJWKHPLQFDOFXODWLRQV+RZHYHUWR
NHHS WKH FRGH IRFXVHG RQ WKH UHFLSH WRSLF YHU\ OLWWOH HUURUFKHFNLQJ FRGH KDV EHHQ
LQFOXGHG
Arduino Platform Release Notes
7KHFRGHKDVEHHQWHVWHGXVLQJ$UGXLQRUHOHDVHVIURPYHUVLRQWKURXJKYHUVLRQ
7KLVERRNZDVZULWWHQEHIRUH$UGXLQRYZDVILQDOL]HGDQGDOWKRXJKDOPRVW
DOORIWKHH[DPSOHVVKRXOGVWLOOZRUNVPDOOFKDQJHVUHTXLUHGIRUUXQQLQJZLWKYZLOO
EHSXEOLVKHGRQWKHVLWHIRUWKHERRN
KWWSZZZRUHLOO\FRPFDWDORJ
7KHUH¦VDOVRDOLQNWRHUUDWDWKHUH(UUDWDJLYHUHDGHUVDZD\WROHWXVNQRZDERXWW\SRV
HUURUVDQGRWKHUSUREOHPVZLWKWKHERRN(UUDWDZLOOEHYLVLEOHRQWKHSDJHLPPHGL
DWHO\DQGZH¦OOFRQILUPWKHPDIWHUFKHFNLQJWKHPRXW2¦5HLOO\FDQDOVRIL[HUUDWDLQ
IXWXUHSULQWLQJVRIWKHERRNDQGRQ6DIDULPDNLQJIRUDEHWWHUUHDGHUH[SHULHQFHSUHWW\
TXLFNO\
,I\RXKDYHSUREOHPVPDNLQJH[DPSOHVZRUNFKHFNWKHZHEOLQNWRVHHLIWKHFRGHKDV
EHHQXSGDWHG,IWKDWGRHVQ¦WIL[WKHSUREOHPVHH$SSHQGL['ZKLFKFRYHUVWURXEOH
VKRRWLQJVRIWZDUHSUREOHPV7KH$UGXLQRIRUXPLVDJRRGSODFHWRSRVWDTXHVWLRQLI
\RXQHHGPRUHKHOSKWWSZZZDUGXLQRFF
:H KRSH WR NHHS WKLV ERRN XSGDWHG IRU IXWXUH $UGXLQR YHUVLRQV DQG ZH ZLOO DOVR
LQFRUSRUDWHVXJJHVWLRQVDQGFRPSODLQWVLQWRIXWXUHHGLWLRQV
,I\RXOLNH¢RUGRQ¦WOLNH¢WKLVERRNE\DOOPHDQVSOHDVHOHWSHRSOHNQRZ$PD]RQ
UHYLHZVDUHRQHSRSXODUZD\WRVKDUH\RXUKDSSLQHVV RUODFNRIKDSSLQHVV RU\RXFDQ
OHDYHUHYLHZVDWWKHVLWHIRUWKHERRN
Preface | xvii
Conventions Used in This Book
7KHIROORZLQJIRQWFRQYHQWLRQVDUHXVHGLQWKLVERRN
,WDOLF
,QGLFDWHVSDWKQDPHVILOHQDPHVDQGSURJUDPQDPHV,QWHUQHWDGGUHVVHVVXFKDV
GRPDLQQDPHVDQG85/VDQGQHZLWHPVZKHUHWKH\DUHGHILQHG
Constant width
,QGLFDWHVFRPPDQGOLQHVDQGRSWLRQVWKDWVKRXOGEHW\SHGYHUEDWLPQDPHVDQG
NH\ZRUGVLQSURJUDPVLQFOXGLQJPHWKRGQDPHVYDULDEOHQDPHVDQGFODVVQDPHV
DQG+70/HOHPHQWWDJV
Constant width bold
,QGLFDWHVHPSKDVLVLQSURJUDPFRGHOLQHV
Constant width italic
,QGLFDWHVWH[WWKDWVKRXOGEHUHSODFHGZLWKXVHUVXSSOLHGYDOXHV
7KLVLFRQVLJQLILHVDWLSVXJJHVWLRQRUJHQHUDOQRWH
7KLVLFRQLQGLFDWHVDZDUQLQJRUFDXWLRQ
Using Code Examples
7KLVERRNLVKHUHWRKHOS\RXPDNHWKLQJVZLWK$UGXLQR,QJHQHUDO\RXPD\XVHWKH
FRGHLQWKLVERRNLQ\RXUSURJUDPVDQGGRFXPHQWDWLRQ<RXGRQRWQHHGWRFRQWDFW
XVIRUSHUPLVVLRQXQOHVV\RX¦UHUHSURGXFLQJDVLJQLILFDQWSRUWLRQRIWKHFRGH)RUH[
DPSOHZULWLQJDSURJUDPWKDWXVHVVHYHUDOFKXQNVRIFRGHIURPWKLVERRNGRHVQRW
UHTXLUH SHUPLVVLRQ 6HOOLQJ RU GLVWULEXWLQJ D &'520 RI H[DPSOHV IURP WKLV ERRN
GRHVUHTXLUHSHUPLVVLRQ$QVZHULQJDTXHVWLRQE\FLWLQJWKLVERRNDQGTXRWLQJH[DPSOH
FRGHGRHVQRWUHTXLUHSHUPLVVLRQ,QFRUSRUDWLQJDVLJQLILFDQWDPRXQWRIH[DPSOHFRGH
IURPWKLVERRNLQWR\RXUSURGXFW¦VGRFXPHQWDWLRQGRHVUHTXLUHSHUPLVVLRQ
:HDSSUHFLDWHEXWGRQRWUHTXLUHDWWULEXWLRQ$QDWWULEXWLRQXVXDOO\LQFOXGHVWKHWLWOH
DXWKRUSXEOLVKHUDQG,6%1)RUH[DPSOH£$UGXLQR&RRNERRNE\0LFKDHO0DUJROLV
ZLWK1LFN:HOGLQ 2¦5HLOO\ &RS\ULJKW0LFKDHO0DUJROLVDQG1LFKRODV:HOGLQ
¤
,I\RXIHHO\RXUXVHRIFRGHH[DPSOHVIDOOVRXWVLGHIDLUXVHRUWKHSHUPLVVLRQJLYHQKHUH
IHHOIUHHWRFRQWDFWXVDWSHUPLVVLRQV#RUHLOO\FRP
xviii | Preface
Safari® Books Online
6DIDUL%RRNV2QOLQHLVDQRQGHPDQGGLJLWDOOLEUDU\WKDWOHWV\RXHDVLO\
VHDUFKRYHUWHFKQRORJ\DQGFUHDWLYHUHIHUHQFHERRNVDQGYLGHRVWR
ILQGWKHDQVZHUV\RXQHHGTXLFNO\
:LWKDVXEVFULSWLRQ\RXFDQUHDGDQ\SDJHDQGZDWFKDQ\YLGHRIURPRXUOLEUDU\RQOLQH
5HDGERRNVRQ\RXUFHOOSKRQHDQGPRELOHGHYLFHV$FFHVVQHZWLWOHVEHIRUHWKH\DUH
DYDLODEOHIRUSULQWDQGJHWH[FOXVLYHDFFHVVWRPDQXVFULSWVLQGHYHORSPHQWDQGSRVW
IHHGEDFNIRUWKHDXWKRUV&RS\DQGSDVWHFRGHVDPSOHVRUJDQL]H\RXUIDYRULWHVGRZQ
ORDGFKDSWHUVERRNPDUNNH\VHFWLRQVFUHDWHQRWHVSULQWRXWSDJHVDQGEHQHILWIURP
WRQVRIRWKHUWLPHVDYLQJIHDWXUHV
2¦5HLOO\0HGLDKDVXSORDGHGWKLVERRNWRWKH6DIDUL%RRNV2QOLQHVHUYLFH7RKDYHIXOO
GLJLWDODFFHVVWRWKLVERRNDQGRWKHUVRQVLPLODUWRSLFVIURP2¦5HLOO\DQGRWKHUSXE
OLVKHUVVLJQXSIRUIUHHDWKWWSP\VDIDULERRNVRQOLQHFRP
How to Contact Us
:HKDYHWHVWHGDQGYHULILHGWKHLQIRUPDWLRQLQWKLVERRNWRWKHEHVWRIRXUDELOLW\EXW
\RXPD\ILQGWKDWIHDWXUHVKDYHFKDQJHG RUHYHQWKDWZHKDYHPDGHDIHZPLVWDNHV 3OHDVHOHWXVNQRZDERXWDQ\HUURUV\RXILQGDVZHOODV\RXUVXJJHVWLRQVIRUIXWXUH
HGLWLRQVE\ZULWLQJWR
2¦5HLOO\0HGLD,QF
*UDYHQVWHLQ+LJKZD\1RUWK
6HEDVWRSRO&$
LQWKH8QLWHG6WDWHVRU&DQDGD
LQWHUQDWLRQDOORFDO
ID[
:HKDYHDZHESDJHIRUWKLVERRNZKHUHZHOLVWHUUDWDH[DPSOHVDQGDQ\DGGLWLRQDO
LQIRUPDWLRQ<RXFDQDFFHVVWKLVSDJHDW
KWWSZZZRUHLOO\FRPFDWDORJ
7RFRPPHQWRUDVNWHFKQLFDOTXHVWLRQVDERXWWKLVERRNVHQGHPDLOWR
ERRNTXHVWLRQV#RUHLOO\FRP
)RUPRUHLQIRUPDWLRQDERXWRXUERRNVFRXUVHVFRQIHUHQFHVDQGQHZVVHHRXUZHEVLWH
DWKWWSZZZRUHLOO\FRP
)LQGXVRQ)DFHERRNKWWSIDFHERRNFRPRUHLOO\
)ROORZXVRQ7ZLWWHUKWWSWZLWWHUFRPRUHLOO\PHGLD
:DWFKXVRQ<RX7XEHKWWSZZZ\RXWXEHFRPRUHLOO\PHGLD
Preface | xix
Acknowledgments
1LFN :HOGLQ¦V FRQWULEXWLRQ ZDV LQYDOXDEOH IRU WKH FRPSOHWLRQ RI WKLV ERRN ,W ZDV
SHUFHQWZULWWHQZKHQ1LFNFDPHRQERDUG¢DQGZLWKRXWKLVVNLOODQGHQWKXVLDVP
LWZRXOGVWLOOEHSHUFHQWZULWWHQ+LVKDQGVRQH[SHULHQFHUXQQLQJ$UGXLQRZRUN
VKRSVIRUDOOOHYHOVRIXVHUVHQDEOHGXVWRPDNHWKHDGYLFHLQWKLVERRNSUDFWLFDOIRURXU
EURDGUDQJHRIUHDGHUV7KDQN\RX1LFNIRU\RXUNQRZOHGJHDQGJHQLDOFROODERUDWLYH
QDWXUH
6LPRQ6W/DXUHQWZDVWKHHGLWRUDW2¦5HLOO\ZKRILUVWH[SUHVVHGLQWHUHVWLQWKLVERRN
$QGLQWKHHQGKHLVWKHPDQZKRSXOOHGLWWRJHWKHU+LVVXSSRUWDQGHQFRXUDJHPHQW
NHSWXVLQVSLUHGDVZHVLIWHGRXUZD\WKURXJKWKHYROXPHVRIPDWHULDOQHFHVVDU\WRGR
WKHVXEMHFWMXVWLFH
%ULDQ-HSVRQKHOSHGPHJHWVWDUWHGZLWKWKHZULWLQJRIWKLVERRN+LVYDVWNQRZOHGJH
RIWKLQJV$UGXLQRDQGKLVFRQFHUQDQGH[SHUWLVHIRUFRPPXQLFDWLQJDERXWWHFKQRORJ\
LQSODLQ(QJOLVKVHWDKLJKVWDQGDUG+HZDVDQLGHDOJXLGLQJKDQGIRUVKDSLQJWKHERRN
DQGPDNLQJWHFKQRORJ\UHDGLO\DFFHVVLEOHIRUUHDGHUV:HDOVRKDYH%ULDQWRWKDQNIRU
WKH;%HHFRQWHQWLQ&KDSWHU
$XGUH\ 'R\OH ZRUNHG WLUHOHVVO\ WR VWDPS RXW W\SRV DQG JUDPPDWLFDO HUURUV LQ WKH
PDQXVFULSWDQGXQWDQJOHVRPHRIWKHPRUHFRQYROXWHGH[SUHVVLRQV
3KLOLS /LQGVD\ FROODERUDWHG RQ &KDSWHU DQG KLV FRPELQDWLRQ RI GHHS WHFKQLFDO
NQRZOHGJHDQGFOHDUXQGHUVWDQGLQJRIWKHQHHGVRIQRQWHFKQLFDOSHRSOHZDVHVVHQWLDO
LQPDNLQJWKHFRPSOH[VXEMHFWRI(WKHUQHWDFFHVVLEOH
0LNDO +DUW ZURWH UHFLSHV FRYHULQJ *36 DQG VRIWZDUH VHULDO 0LNDO ZDV WKH QDWXUDO
FKRLFHIRUWKLV¢QRWRQO\EHFDXVHKHZURWHWKHOLEUDULHVEXWDOVREHFDXVHKHLVDIOXHQW
FRPPXQLFDWRUDQ$UGXLQRHQWKXVLDVWDQGDSOHDVXUHWRFROODERUDWHZLWK
$UGXLQRLVSRVVLEOHEHFDXVHRIWKHFUHDWLYLW\RIWKHFRUH$UGXLQRGHYHORSPHQWWHDP
0DVVLPR%DQ]L'DYLG&XDUWLHOOHV7RP,JRH*LDQOXFD0DUWLQRDQG'DYLG0HOOLV2Q
EHKDOIRIDOO$UGXLQRXVHUV,ZLVKWRH[SUHVVRXUDSSUHFLDWLRQIRUWKHLUHIIRUWVLQPDNLQJ
WKLVIDVFLQDWLQJWHFKQRORJ\VLPSOHDQGWKHLUJHQHURVLW\LQPDNLQJLWIUHH
6SHFLDO WKDQNV WR $OH[DQGUD 'HVFKDPSV6RQVLQR &(2 RI 7LQNHU /RQGRQ ZKRVH
ZRUNVKRSVSURYLGHGLPSRUWDQWXQGHUVWDQGLQJRIWKHQHHGVRIXVHUV7KDQNVDOVRWR
3HWHU.QLJKWZKRKDVSURYLGHGDOONLQGVRIFOHYHU$UGXLQRVROXWLRQVDVZHOODVWKHEDVLV
RIDQXPEHURIUHFLSHVLQWKLVERRN
2Q EHKDOI RI HYHU\RQH ZKR KDV GRZQORDGHG XVHUFRQWULEXWHG $UGXLQR OLEUDULHV ,
ZRXOGOLNHWRWKDQNWKHDXWKRUVZKRKDYHJHQHURXVO\VKDUHGWKHLUNQRZOHGJH
7KHDYDLODELOLW\RIDZLGHUDQJHRIKDUGZDUHLVDODUJHSDUWRIZKDWPDNHV$UGXLQR
H[FLWLQJ¢WKDQNVWRWKHVXSSOLHUVIRUVWRFNLQJDQGVXSSRUWLQJDEURDGUDQJHRIJUHDW
GHYLFHV7KHIROORZLQJZHUHKHOSIXOLQSURYLGLQJKDUGZDUHXVHGLQWKHERRN6SDUN)XQ
0DNHU6WRUH*UDYLWHFKDQG1.&(OHFWURQLFV2WKHUVXSSOLHUVWKDWKDYHEHHQKHOSIXO
xx | Preface
LQFOXGH 0RGHUQ 'HYLFH /LTXLGZDUH $GDIUXLW 0DNHUERW ,QGXVWULHV 0LQGNLWV
2RPORXWDQG6.3DQJ
1LFNZRXOGOLNHWRWKDQN$OH[DQGUDDQG3HWHUDW7LQNHU/RQGRQDVZHOODV%URFN&UDIW
DQGHVSHFLDOO\'DQLHO6ROWLVIRUDOOWKHZRUNVKRSVZHKDYHGRQHWRJHWKHU
1LFNZRXOGDOVROLNHWRWKDQNHYHU\RQHZKRKDVDVVLVWHGDWZRUNVKRSVDQGSDUWLFLSDQWV
ZKRDVNHGD£VLOO\¤TXHVWLRQDVWKHUHDUHQRVLOO\TXHVWLRQV0DQ\RIWKRVHKDYHOHGWR
FODULILFDWLRQVDQGFRUUHFWLRQVLQWKLVERRN
1LFN¦VILQDOWKDQNVJRWRKLVIDPLO\-HDQLH(PLO\DQG)LQQZKRDJUHHGWROHWKLPGR
WKLVRYHUWKHLUVXPPHUKROLGD\DQGRIFRXUVHPXFKORQJHUDIWHUWKDWWKDQWKH\RULJL
QDOO\WKRXJKWDQGWRKLVSDUHQWV)UDQNDQG(YDIRUEULQJLQJKLPXSWRWDNHWKLQJV
DSDUW
/DVWEXWQRWOHDVW,H[SUHVVWKDQNVWRWKHIROORZLQJSHRSOH
-RVKXD1REOHIRULQWURGXFLQJPHWR2¦5HLOO\+LVERRN3URJUDPPLQJ,QWHUDFWLYLW\LV
KLJKO\UHFRPPHQGHGIRUWKRVHLQWHUHVWHGLQEURDGHQLQJWKHLUNQRZOHGJHLQLQWHUDFWLYH
FRPSXWLQJ
5REHUW/DF\7KRPSVRQIRURIIHULQJDGYLFHHDUO\RQZLWKWKHERRN
0DUN0DUJROLVIRUKLVVXSSRUWDQGKHOSDVDVRXQGLQJERDUGLQWKHERRN¦VFRQFHSWLRQ
DQGGHYHORSPHQW
,WKDQNP\SDUHQWVIRUKHOSLQJPHWRVHHWKDWWKHFUHDWLYHDUWVDQGWHFKQRORJ\ZHUHQRW
GLVWLQFWLYHHQWLWLHVDQGWKDWZKHQFRPELQHGWKH\FDQOHDGWRH[WUDRUGLQDU\UHVXOWV
$QGILQDOO\WKLVERRNZRXOGQRWKDYHEHHQVWDUWHGRUILQLVKHGZLWKRXWWKHVXSSRUWRI
P\ZLIH%DUEDUD)DGHQ0\JUDWHIXODSSUHFLDWLRQWRKHUIRUNHHSLQJPHPRWLYDWHGDQG
IRUKHUFDUHIXOUHDGLQJDQGFRQWULEXWLRQVWRWKHPDQXVFULSW
Preface | xxi
CHAPTER 1
Getting Started
1.0 Introduction
7KH$UGXLQRHQYLURQPHQWKDVEHHQGHVLJQHGWREHHDV\WRXVHIRUEHJLQQHUVZKRKDYH
QRVRIWZDUHRUHOHFWURQLFVH[SHULHQFH:LWK$UGXLQR\RXFDQEXLOGREMHFWVWKDWFDQ
UHVSRQGWRDQGRUFRQWUROOLJKWVRXQGWRXFKDQGPRYHPHQW$UGXLQRKDVEHHQXVHG
WR FUHDWH DQ DPD]LQJ YDULHW\ RI WKLQJV LQFOXGLQJ PXVLFDO LQVWUXPHQWV URERWV OLJKW
VFXOSWXUHVJDPHVLQWHUDFWLYHIXUQLWXUHDQGHYHQLQWHUDFWLYHFORWKLQJ
,I\RX¦UHQRWDEHJLQQHUSOHDVHIHHOIUHHWRVNLSDKHDGWRUHFLSHVWKDW
LQWHUHVW\RX
$UGXLQRLVXVHGLQPDQ\HGXFDWLRQDOSURJUDPVDURXQGWKHZRUOGSDUWLFXODUO\E\GH
VLJQHUVDQGDUWLVWVZKRZDQWWRHDVLO\FUHDWHSURWRW\SHVEXWGRQRWQHHGDGHHSXQGHU
VWDQGLQJRIWKHWHFKQLFDOGHWDLOVEHKLQGWKHLUFUHDWLRQV%HFDXVHLWLVGHVLJQHGWREHXVHG
E\QRQWHFKQLFDOSHRSOHWKHVRIWZDUHLQFOXGHVSOHQW\RIH[DPSOHFRGHWRGHPRQVWUDWH
KRZWRXVHWKH$UGXLQRERDUG¦VYDULRXVIDFLOLWLHV
7KRXJKLWLVHDV\WRXVH$UGXLQR¦VXQGHUO\LQJKDUGZDUHZRUNVDWWKHVDPHOHYHORI
VRSKLVWLFDWLRQWKDWHQJLQHHUVHPSOR\WREXLOGHPEHGGHGGHYLFHV3HRSOHDOUHDG\ZRUN
LQJZLWKPLFURFRQWUROOHUVDUHDOVRDWWUDFWHGWR$UGXLQREHFDXVHRILWVDJLOHGHYHORSPHQW
FDSDELOLWLHVDQGLWVIDFLOLW\IRUTXLFNLPSOHPHQWDWLRQRILGHDV
$UGXLQRLVEHVWNQRZQIRULWVKDUGZDUHEXW\RXDOVRQHHGVRIWZDUHWRSURJUDPWKDW
KDUGZDUH%RWKWKHKDUGZDUHDQGWKHVRIWZDUHDUHFDOOHG£$UGXLQR¤7KHFRPELQDWLRQ
HQDEOHV\RXWRFUHDWHSURMHFWVWKDWVHQVHDQGFRQWUROWKHSK\VLFDOZRUOG7KHVRIWZDUH
LVIUHHRSHQVRXUFHDQGFURVVSODWIRUP7KHERDUGVDUHLQH[SHQVLYHWREX\RU\RXFDQ
EXLOG\RXURZQ WKHKDUGZDUHGHVLJQVDUHDOVRRSHQVRXUFH ,QDGGLWLRQWKHUHLVDQ
DFWLYHDQGVXSSRUWLYH$UGXLQRFRPPXQLW\WKDWLVDFFHVVLEOHZRUOGZLGHWKURXJKWKH
$UGXLQRIRUXPVDQGWKHZLNL NQRZQDVWKH$UGXLQR3OD\JURXQG 7KHIRUXPVDQGWKH
1
ZLNLRIIHUSURMHFWGHYHORSPHQWH[DPSOHVDQGVROXWLRQVWRSUREOHPVWKDWFDQSURYLGH
LQVSLUDWLRQDQGDVVLVWDQFHDV\RXSXUVXH\RXURZQSURMHFWV
7KHUHFLSHVLQWKLVFKDSWHUZLOOJHW\RXVWDUWHGE\H[SODLQLQJKRZWRVHWXSWKHGHYHO
RSPHQWHQYLURQPHQWDQGKRZWRFRPSLOHDQGUXQDQH[DPSOHVNHWFK
6RXUFHFRGHFRQWDLQLQJFRPSXWHULQVWUXFWLRQVIRUFRQWUROOLQJ$UGXLQR
IXQFWLRQDOLW\LVXVXDOO\UHIHUUHGWRDVDVNHWFKLQWKH$UGXLQRFRPPXQLW\
7KHZRUGVNHWFKZLOOEHXVHGWKURXJKRXWWKLVERRNWRUHIHUWR$UGXLQR
SURJUDPFRGH
7KH%OLQNVNHWFKZKLFKFRPHVZLWK$UGXLQRLVXVHGDVDQH[DPSOHIRUUHFLSHVLQWKLV
FKDSWHUWKRXJKWKHODVWUHFLSHLQWKHFKDSWHUJRHVIXUWKHUE\DGGLQJVRXQGDQGFRO
OHFWLQJLQSXWWKURXJKVRPHDGGLWLRQDOKDUGZDUHQRWMXVWEOLQNLQJWKHOLJKWEXLOWLQWR
WKHERDUG&KDSWHUFRYHUVKRZWRVWUXFWXUHDVNHWFKIRU$UGXLQRDQGSURYLGHVDQ
LQWURGXFWLRQWRSURJUDPPLQJ
,I\RXDOUHDG\NQRZ\RXUZD\DURXQG$UGXLQREDVLFVIHHOIUHHWRMXPS
IRUZDUGWRODWHUFKDSWHUV,I\RX¦UHDILUVWWLPH$UGXLQRXVHUSDWLHQFH
LQWKHVHHDUO\UHFLSHVZLOOSD\RIIZLWKVPRRWKHUUHVXOWVODWHU
Arduino Software
6RIWZDUHSURJUDPVFDOOHGVNHWFKHVDUHFUHDWHGRQDFRPSXWHUXVLQJWKH$UGXLQRLQWH
JUDWHGGHYHORSPHQWHQYLURQPHQW ,'( 7KH,'(HQDEOHV\RXWRZULWHDQGHGLWFRGH
DQGFRQYHUWWKLVFRGHLQWRLQVWUXFWLRQVWKDW$UGXLQRKDUGZDUHXQGHUVWDQGV7KH,'(
DOVRWUDQVIHUVWKRVHLQVWUXFWLRQVWRWKH$UGXLQRERDUG DSURFHVVFDOOHGXSORDGLQJ Arduino Hardware
7KH$UGXLQRERDUGLVZKHUHWKHFRGH\RXZULWHLVH[HFXWHG7KHERDUGFDQRQO\FRQWURO
DQG UHVSRQG WR HOHFWULFLW\ VR VSHFLILF FRPSRQHQWV DUH DWWDFKHG WR LW WR HQDEOH LW WR
LQWHUDFWZLWKWKHUHDOZRUOG7KHVHFRPSRQHQWVFDQEHVHQVRUVZKLFKFRQYHUWVRPH
DVSHFWRIWKHSK\VLFDOZRUOGWRHOHFWULFLW\VRWKDWWKHERDUGFDQVHQVHLWRUDFWXDWRUV
ZKLFKJHWHOHFWULFLW\IURPWKHERDUGDQGFRQYHUWLWLQWRVRPHWKLQJWKDWFKDQJHVWKH
ZRUOG([DPSOHVRIVHQVRUVLQFOXGHVZLWFKHVDFFHOHURPHWHUVDQGXOWUDVRXQGGLVWDQFH
VHQVRUV$FWXDWRUVDUHWKLQJVOLNHOLJKWVDQG/('VVSHDNHUVPRWRUVDQGGLVSOD\V
7KHUHDUHDYDULHW\RIRIILFLDOERDUGVWKDW\RXFDQXVHZLWK$UGXLQRVRIWZDUHDQGDZLGH
UDQJHRI$UGXLQRFRPSDWLEOHERDUGVSURGXFHGE\PHPEHUVRIWKHFRPPXQLW\
7KHPRVWSRSXODUERDUGVFRQWDLQD86%FRQQHFWRUWKDWLVXVHGWRSURYLGHSRZHUDQG
FRQQHFWLYLW\ IRU XSORDGLQJ \RXU VRIWZDUH RQWR WKH ERDUG )LJXUH VKRZV D EDVLF
ERDUGWKH$UGXLQR8QR
2 | Chapter 1:ಗGetting Started
)LJXUH%DVLFERDUGWKH$UGXLQR8QR
<RXFDQJHWERDUGVDVVPDOODVDSRVWDJHVWDPSVXFKDVWKH$UGXLQR0LQLDQG3UR0LQL
ODUJHUERDUGVWKDWKDYHPRUHFRQQHFWLRQRSWLRQVDQGPRUHSRZHUIXOSURFHVVRUVVXFK
DVWKH$UGXLQR0HJDDQGERDUGVWDLORUHGIRUVSHFLILFDSSOLFDWLRQVVXFKDVWKH/LO\3DG
IRUZHDUDEOHDSSOLFDWLRQVWKH)LRIRUZLUHOHVVSURMHFWVDQGWKH$UGXLQR3URIRUHP
EHGGHGDSSOLFDWLRQV VWDQGDORQHSURMHFWVWKDWDUHRIWHQEDWWHU\RSHUDWHG 0DQ\RWKHU
$UGXLQRFRPSDWLEOHERDUGVDUHDOVRDYDLODEOHLQFOXGLQJWKHIROORZLQJ
$UGXLQR1DQRDWLQ\ERDUGZLWK86%FDSDELOLW\IURP*UDYLWHFK KWWSVWRUHJUDY
LWHFKXVDUQDZLDWQKWPO
%DUH%RQHV%RDUGDORZFRVWERDUGDYDLODEOHZLWKRUZLWKRXW86%FDSDELOLW\IURP
0RGHUQ'HYLFH KWWSZZZPRGHUQGHYLFHFRPSURGXFWVEEENLW
%RDUGXLQR D ORZFRVW EUHDGERDUGFRPSDWLEOH ERDUG IURP $GDIUXLW ,QGXVWULHV
KWWSZZZDGDIUXLWFRP
6HHHGXLQR D IOH[LEOH YDULDWLRQ RI WKH VWDQGDUG 86% ERDUG IURP 6HHHG 6WXGLR
%D]DDU KWWSZZZVHHHGVWXGLRFRP
7HHQV\DQG7HHQV\WLQ\EXWH[WUHPHO\YHUVDWLOHERDUGVIURP3-5& KWWSZZZ
SMUFFRPWHHQV\
$FRPSUHKHQVLYHOLVWRI$UGXLQRFRPSDWLEOHERDUGVLVDYDLODEOHDWKWWSZZZIUHHGXLQR
RUJ
See Also
$QRYHUYLHZRI$UGXLQRERDUGVKWWSZZZDUGXLQRFFHQ0DLQ+DUGZDUH
2QOLQH JXLGHV IRU JHWWLQJ VWDUWHG ZLWK $UGXLQR DUH DYDLODEOH DW KWWSDUGXLQRFFHQ
*XLGH:LQGRZVIRU:LQGRZVKWWSDUGXLQRFFHQ*XLGH0DF26;IRU0DF26;DQG
KWWSZZZDUGXLQRFFSOD\JURXQG/HDUQLQJ/LQX[IRU/LQX[
1.0 Introduction | 3
1.1 Installing the Integrated Development Environment (IDE)
Problem
<RXZDQWWRLQVWDOOWKH$UGXLQRGHYHORSPHQWHQYLURQPHQWRQ\RXUFRPSXWHU
Solution
7KH$UGXLQRVRIWZDUHIRU:LQGRZV0DFDQG/LQX[FDQEHGRZQORDGHGIURPKWWS
DUGXLQRFFHQ0DLQ6RIWZDUH
7KH :LQGRZV GRZQORDG LV D =,3 ILOH 8Q]LS WKH ILOH WR DQ\ FRQYHQLHQW GLUHFWRU\¢
3URJUDP)LOHV$UGXLQRLVDVHQVLEOHSODFH
$IUHHXWLOLW\IRUXQ]LSSLQJILOHVFDOOHG=LSFDQEHGRZQORDGHGIURP
KWWSZZZ]LSRUJ
8Q]LSSLQJWKHILOHZLOOFUHDWHDIROGHUQDPHG$UGXLQRQQ! ZKHUHQQ!LVWKHYHU
VLRQ QXPEHU RI WKH $UGXLQR UHOHDVH \RX GRZQORDGHG 7KH GLUHFWRU\ FRQWDLQV WKH
H[HFXWDEOHILOH QDPHG$UGXLQRH[H DORQJZLWKYDULRXVRWKHUILOHVDQGIROGHUV'RXEOH
FOLFNWKH$UGXLQRH[HILOHDQGWKHVSODVKVFUHHQVKRXOGDSSHDU VHH)LJXUH IROORZHG
E\WKHPDLQSURJUDPZLQGRZ VHH)LJXUH %HSDWLHQWDVLWFDQWDNHVRPHWLPHIRU
WKHVRIWZDUHWRORDG
)LJXUH$UGXLQRVSODVKVFUHHQ YHUVLRQLQ:LQGRZV
4 | Chapter 1:ಗGetting Started
)LJXUH$UGXLQR,'(PDLQZLQGRZ YHUVLRQLQ:LQGRZV
7KH$UGXLQRGRZQORDGIRUWKH0DFLVDGLVNLPDJH GPJ GRXEOHFOLFNWKHILOHZKHQ
WKHGRZQORDGLVFRPSOHWH7KHLPDJHZLOOPRXQW LWZLOODSSHDUOLNHDPHPRU\VWLFN
RQWKHGHVNWRS ,QVLGHWKHGLVNLPDJHLVWKH$UGXLQRDSSOLFDWLRQ&RS\WKLVWRVRPH
ZKHUHFRQYHQLHQW¢WKH$SSOLFDWLRQVIROGHULVDVHQVLEOHSODFH'RXEOHFOLFNWKHDSSOL
FDWLRQRQFH\RXKDYHFRSLHGLWRYHU LWLVQRWDJRRGLGHDWRUXQLWIURPWKHGLVNLPDJH 7KHVSODVKVFUHHQZLOODSSHDUIROORZHGE\WKHPDLQSURJUDPZLQGRZ
/LQX[LQVWDOODWLRQYDULHVGHSHQGLQJRQWKH/LQX[GLVWULEXWLRQ\RXDUHXVLQJ6HHWKH
$UGXLQRZLNLIRULQIRUPDWLRQ KWWSZZZDUGXLQRFFSOD\JURXQG/HDUQLQJ/LQX[ 7RHQDEOHWKH$UGXLQRGHYHORSPHQWHQYLURQPHQWWRFRPPXQLFDWHZLWKWKHERDUG\RX
QHHGWRLQVWDOOGULYHUV
1.1 Installing the Integrated Development Environment (IDE) | 5
2Q:LQGRZVXVHWKH86%FDEOHWRFRQQHFW\RXU3&DQGWKH$UGXLQRERDUGDQGZDLW
IRUWKH)RXQG1HZ+DUGZDUH:L]DUGWRDSSHDU,I\RXDUHXVLQJ:LQGRZV9LVWDRU
:LQGRZVDQGDUHRQOLQH\RXFDQOHWWKHZL]DUGVHDUFKIRUGULYHUVDQGWKH\ZLOOLQVWDOO
DXWRPDWLFDOO\2Q:LQGRZV;3\RXVKRXOGVSHFLI\WKHORFDWLRQRIWKHGULYHUV8VHWKH
ILOH VHOHFWRU WR QDYLJDWH WR WKH GULYHUV GLUHFWRU\ ORFDWHG LQ WKH GLUHFWRU\ ZKHUH \RX
XQ]LSSHGWKH$UGXLQRILOHV:KHQWKHGULYHUKDVLQVWDOOHGWKH)RXQG1HZ+DUGZDUH
:L]DUGZLOODSSHDUDJDLQVD\LQJDQHZVHULDOSRUWKDVEHHQIRXQG)ROORZWKHVDPH
SURFHVVDVEHIRUH
,WLVLPSRUWDQWWKDW\RXJRWKURXJKWKHVHTXHQFHRIVWHSVWRLQVWDOOWKH
GULYHUVWZRWLPHVRUWKHVRIWZDUHZLOOQRWEHDEOHWRFRPPXQLFDWHZLWK
WKHERDUG
2QWKH0DFWKHODWHVW$UGXLQRERDUGVVXFKDVWKH8QRFDQEHXVHGZLWKRXWDGGLWLRQDO
GULYHUVEXWLI\RXDUHXVLQJHDUOLHUERDUGV\RXZLOOQHHGWRLQVWDOOGULYHUVRIWZDUH7KHUH
LVDSDFNDJHQDPHG)7',86%6HULDO'ULYHUZLWKDUDQJHRIQXPEHUVDIWHULWLQVLGHWKH
GLVNLPDJH'RXEOHFOLFNWKLVDQGWKHLQVWDOOHUZLOOWDNH\RXWKURXJKWKHSURFHVV<RX
ZLOOQHHGWRNQRZDQDGPLQLVWUDWRUSDVVZRUGWRFRPSOHWHWKHSURFHVV
2Q/LQX[PRVWGLVWULEXWLRQVKDYHWKHGULYHUDOUHDG\LQVWDOOHGEXWIROORZWKH/LQX[
OLQNJLYHQLQWKLVFKDSWHU¦VLQWURGXFWLRQIRUVSHFLILFLQIRUPDWLRQIRU\RXUGLVWULEXWLRQ
Discussion
,IWKHVRIWZDUHIDLOVWRVWDUWFKHFNWKHWURXEOHVKRRWLQJVHFWLRQRIWKH$UGXLQRZHEVLWH
KWWSDUGXLQRFFHQ*XLGH7URXEOHVKRRWLQJIRUKHOSVROYLQJLQVWDOODWLRQSUREOHPV
See Also
2QOLQH JXLGHV IRU JHWWLQJ VWDUWHG ZLWK $UGXLQR DUH DYDLODEOH DW KWWSDUGXLQRFFHQ
*XLGH:LQGRZVIRU:LQGRZVKWWSDUGXLQRFFHQ*XLGH0DF26;IRU0DF26;DQG
KWWSZZZDUGXLQRFFSOD\JURXQG/HDUQLQJ/LQX[IRU/LQX[
1.2 Setting Up the Arduino Board
Problem
<RXZDQWWRSRZHUXSDQHZERDUGDQGYHULI\WKDWLWLVZRUNLQJ
Solution
3OXJWKHERDUGLQWRD86%SRUWRQ\RXUFRPSXWHUDQGFKHFNWKDWWKHJUHHQ/('SRZHU
LQGLFDWRURQWKHERDUGLOOXPLQDWHV6WDQGDUG$UGXLQRERDUGV 8QR'XHPLODQRYHDQG
0HJD KDYHDJUHHQ/('SRZHULQGLFDWRUORFDWHGQHDUWKHUHVHWVZLWFK
6 | Chapter 1:ಗGetting Started
$QRUDQJH/('QHDUWKHFHQWHURIWKHERDUG ODEHOHG£3LQ/('¤LQ)LJXUH VKRXOG
IODVKRQDQGRIIZKHQWKHERDUGLVSRZHUHGXS ERDUGVFRPHIURPWKHIDFWRU\SUHORDGHG
ZLWKVRIWZDUHWRIODVKWKH/('DVDVLPSOHFKHFNWKDWWKHERDUGLVZRUNLQJ )LJXUH%DVLF$UGXLQRERDUG 8QRDQG'XHPLODQRYH
Discussion
,IWKHSRZHU/('GRHVQRWLOOXPLQDWHZKHQWKHERDUGLVFRQQHFWHGWR\RXUFRPSXWHU
WKHERDUGLVSUREDEO\QRWUHFHLYLQJSRZHU
7KH IODVKLQJ /(' FRQQHFWHG WR GLJLWDO RXWSXW SLQ LV EHLQJ FRQWUROOHG E\ FRGH
UXQQLQJRQWKHERDUG QHZERDUGVDUHSUHORDGHGZLWKWKH%OLQNH[DPSOHVNHWFK ,IWKH
SLQ/('LVIODVKLQJWKHVNHWFKLVUXQQLQJFRUUHFWO\ZKLFKPHDQVWKHFKLSRQWKH
ERDUGLVZRUNLQJ,IWKHJUHHQSRZHU/('LVRQEXWWKHSLQ/('LVQRWIODVKLQJLW
FRXOG EH WKDW WKH IDFWRU\ FRGH LV QRW RQ WKH FKLS IROORZ WKH LQVWUXFWLRQV LQ 5HF
LSHWRORDGWKH%OLQNVNHWFKRQWRWKHERDUGWRYHULI\WKDWWKHERDUGLVZRUNLQJ,I
\RXDUHQRWXVLQJDVWDQGDUGERDUGLWPD\QRWKDYHDEXLOWLQ/('RQSLQVRFKHFN
WKHGRFXPHQWDWLRQIRUGHWDLOVRI\RXUERDUG
See Also
2QOLQH JXLGHV IRU JHWWLQJ VWDUWHG ZLWK $UGXLQR DUH DYDLODEOH DW KWWSDUGXLQRFFHQ
*XLGH:LQGRZVIRU:LQGRZVKWWSDUGXLQRFFHQ*XLGH0DF26;IRU0DF26;DQG
KWWSZZZDUGXLQRFFSOD\JURXQG/HDUQLQJ/LQX[IRU/LQX[
$WURXEOHVKRRWLQJJXLGHFDQEHIRXQGDWKWWSDUGXLQRFFHQ*XLGH7URXEOHVKRRWLQJ
1.2 Setting Up the Arduino Board | 7
1.3 Using the Integrated Development Environment (IDE) to
Prepare an Arduino Sketch
Problem
<RXZDQWWRJHWDVNHWFKDQGSUHSDUHLWIRUXSORDGLQJWRWKHERDUG
Solution
8VHWKH$UGXLQR,'(WRFUHDWHRSHQDQGPRGLI\VNHWFKHVWKDWGHILQHZKDWWKHERDUG
ZLOOGR<RXFDQXVHEXWWRQVDORQJWKHWRSRIWKH,'(WRSHUIRUPWKHVHDFWLRQV VKRZQ
LQ)LJXUH RU\RXFDQXVHWKHPHQXVRUNH\ERDUGVKRUWFXWV VKRZQLQ)LJXUH 7KH6NHWFK(GLWRUDUHDLVZKHUH\RXYLHZDQGHGLWFRGHIRUDVNHWFK,WVXSSRUWVFRP
PRQWH[WHGLWLQJNH\VVXFKDV&WUO) ໜ)RQD0DF IRUILQG&WUO= ໜ=RQD0DF
IRUXQGR&WUO& ໜ&RQD0DF WRFRS\KLJKOLJKWHGWH[WDQG&WUO9 ໜ9RQD0DF
WRSDVWHKLJKOLJKWHGWH[W
)LJXUHVKRZVKRZWRORDGWKH%OLQNVNHWFK WKHVNHWFKWKDWFRPHVSUHORDGHGRQD
QHZ$UGXLQRERDUG $IWHU\RX¦YHVWDUWHGWKH,'(JRWRWKH)LOHൺ([DPSOHVPHQXDQGVHOHFW%DVLFVൺ%OLQN
DVVKRZQLQ)LJXUH7KHFRGHIRUEOLQNLQJWKHEXLOWLQ/('ZLOOEHGLVSOD\HGLQWKH
6NHWFK(GLWRUZLQGRZ UHIHUWR)LJXUH %HIRUHWKHFRGHFDQEHVHQWWRWKHERDUGLWQHHGVWREHFRQYHUWHGLQWRLQVWUXFWLRQVWKDW
FDQEHUHDGDQGH[HFXWHGE\WKH$UGXLQRFRQWUROOHUFKLSWKLVLVFDOOHGFRPSLOLQJ7R
GRWKLVFOLFNWKHFRPSLOHEXWWRQ WKHWRSOHIWEXWWRQZLWKDWULDQJOHLQVLGH RUVHOHFW
6NHWFKൺ9HULI\&RPSLOH
<RXVKRXOGVHHDPHVVDJHWKDWUHDGV£&RPSLOLQJ¤LQWKHPHVVDJHDUHDEHORZWKHWH[W
HGLWLQJZLQGRZ$IWHUDVHFRQGRUWZRDPHVVDJHWKDWUHDGV£'RQH&RPSLOLQJ¤ZLOO
DSSHDU7KHEODFNFRQVROHDUHDZLOOFRQWDLQWKHIROORZLQJDGGLWLRQDOPHVVDJH
Binary sketch size: 1008 bytes (of a 32256 byte maximum)
7KHH[DFWPHVVDJHPD\GLIIHUGHSHQGLQJRQWKH$UGXLQRYHUVLRQLWLVWHOOLQJ\RXWKH
VL]HRIWKHVNHWFKDQGWKHPD[LPXPVL]HWKDW\RXUERDUGFDQDFFHSW
8 | Chapter 1:ಗGetting Started
)LJXUH$UGXLQR,'(
Discussion
6RXUFHFRGHIRU$UGXLQRLVFDOOHGDVNHWFK7KHSURFHVVWKDWWDNHVDVNHWFKDQGFRQYHUWV
LWLQWRDIRUPWKDWZLOOZRUNRQWKHERDUGLVFDOOHGFRPSLODWLRQ7KH,'(XVHVDQXPEHU
RIFRPPDQGOLQHWRROVEHKLQGWKHVFHQHVWRFRPSLOHDVNHWFK)RUPRUHLQIRUPDWLRQ
RQWKLVVHH5HFLSH
1.3 Using the Integrated Development Environment (IDE) to Prepare an Arduino Sketch | 9
)LJXUH,'(PHQX VHOHFWLQJWKH%OLQNH[DPSOHVNHWFK
7KHILQDOPHVVDJHWHOOLQJ\RXWKHVL]HRIWKHVNHWFKLQGLFDWHVKRZPXFKSURJUDPVSDFH
LVQHHGHGWRVWRUHWKHFRQWUROOHULQVWUXFWLRQVRQWKHERDUG,IWKHVL]HRIWKHFRPSLOHG
VNHWFKLVJUHDWHUWKDQWKHDYDLODEOHPHPRU\RQWKHERDUGWKHIROORZLQJHUURUPHVVDJH
LVGLVSOD\HG
Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size
for tips on reducing it.
,IWKLVKDSSHQV\RXQHHGWRPDNH\RXUVNHWFKVPDOOHUWREHDEOHWRSXWLWRQWKHERDUG
RUJHWDERDUGZLWKKLJKHUFDSDFLW\
10 | Chapter 1:ಗGetting Started
,IWKHUHDUHHUURUVLQWKHFRGHWKHFRPSLOHUZLOOSULQWRQHRUPRUHHUURUPHVVDJHVLQWKH
FRQVROHZLQGRZ7KHVHPHVVDJHVFDQKHOSLGHQWLI\WKHHUURU¢VHH$SSHQGL['RQVRIW
ZDUHHUURUVIRUWURXEOHVKRRWLQJWLSV
7R SUHYHQW DFFLGHQWDO RYHUZULWLQJ RI WKH H[DPSOHV WKH $UGXLQR ,'(
GRHVQRWDOORZ\RXWRVDYHFKDQJHVWRWKHSURYLGHGH[DPSOHVNHWFKHV
<RXPXVWUHQDPHWKHPXVLQJWKH6DYH$VPHQXRSWLRQ<RXFDQVDYH
VNHWFKHV\RXZULWH\RXUVHOIZLWKWKH6DYHEXWWRQ VHH5HFLSH $V\RXGHYHORSDQGPRGLI\DVNHWFK\RXVKRXOGDOVRFRQVLGHUXVLQJWKH)LOHൺ6DYH$V
PHQXRSWLRQDQGXVLQJDGLIIHUHQWQDPHRUYHUVLRQQXPEHUUHJXODUO\VRWKDWDV\RX
LPSOHPHQWHDFKELW\RXFDQJREDFNWRDQROGHUYHUVLRQLI\RXQHHGWR
&RGHXSORDGHGRQWRWKHERDUGFDQQRWEHGRZQORDGHGEDFNRQWR\RXU
FRPSXWHU0DNHVXUH\RXVDYH\RXUVNHWFKFRGHRQ\RXUFRPSXWHU<RX
FDQQRWVDYHFKDQJHVEDFNWRWKHH[DPSOHILOHV\RXQHHGWRXVH6DYH$V
DQGJLYHWKHFKDQJHGILOHDQRWKHUQDPH
See Also
5HFLSHVKRZVDQH[DPSOHVNHWFK$SSHQGL['KDVWLSVRQWURXEOHVKRRWLQJVRIWZDUH
SUREOHPV
1.4 Uploading and Running the Blink Sketch
Problem
<RXZDQWWRWUDQVIHU\RXUFRPSLOHGVNHWFKWRWKH$UGXLQRERDUGDQGVHHLWZRUNLQJ
Solution
&RQQHFW\RXU$UGXLQRERDUGWR\RXUFRPSXWHUXVLQJWKH86%FDEOH/RDGWKH%OLQN
VNHWFKLQWRWKH,'(DVGHVFULEHGLQ5HFLSH
1H[WVHOHFW7RROVൺ%RDUGIURPWKHGURSGRZQPHQXDQGVHOHFWWKHQDPHRIWKHERDUG
\RXKDYHFRQQHFWHG LILWLVWKHVWDQGDUG8QRERDUGLWLVSUREDEO\WKHILUVWHQWU\LQWKH
ERDUGOLVW 1RZVHOHFW7RROVൺ6HULDO3RUW<RXZLOOJHWDGURSGRZQOLVWRIDYDLODEOHVHULDOSRUWVRQ
\RXUFRPSXWHU(DFKPDFKLQHZLOOKDYHDGLIIHUHQWFRPELQDWLRQRIVHULDOSRUWVGH
SHQGLQJRQZKDWRWKHUGHYLFHV\RXKDYHXVHGZLWK\RXUFRPSXWHU
2Q:LQGRZVWKH\ZLOOEHOLVWHGDVQXPEHUHG&20HQWULHV,IWKHUHLVRQO\RQHHQWU\
VHOHFWLW,IWKHUHDUHPXOWLSOHHQWULHV\RXUERDUGZLOOSUREDEO\EHWKHODVWHQWU\
1.4 Uploading and Running the Blink Sketch | 11
2QWKH0DF\RXUERDUGZLOOEHOLVWHGWZLFHLILWLVDQ8QRERDUG
/dev/tty.usbmodem-XXXXXXX
/dev/cu.usbmodem-XXXXXXX
,I\RXKDYHDQROGHUERDUGLWZLOOEHOLVWHGDVIROORZV
/dev/tty.usbserial-XXXXXXX
/dev/cu.usbserial-XXXXXXX
(DFKERDUGZLOOKDYHGLIIHUHQWYDOXHVIRUXXXXXXX6HOHFWHLWKHUHQWU\
&OLFNRQWKHXSORDGEXWWRQ LQ)LJXUHLW¦VWKHILIWKEXWWRQIURPWKHOHIW RUFKRRVH
)LOHൺ8SORDGWR,2ERDUG
7KHVRIWZDUHZLOOFRPSLOHWKHFRGHDVLQ5HFLSH$IWHUWKHVRIWZDUHLVFRPSLOHGLW
LVXSORDGHGWRWKHERDUG,I\RXORRNDW\RXUERDUG\RXZLOOVHHWKH/('VWRSIODVKLQJ
DQGWZROLJKWV ODEHOHGDV6HULDO/('VLQ)LJXUH MXVWEHORZWKHSUHYLRXVO\IODVKLQJ
/('VKRXOGIOLFNHUIRUDFRXSOHRIVHFRQGVDVWKHFRGHXSORDGV7KHRULJLQDOOLJKWVKRXOG
WKHQVWDUWIODVKLQJDJDLQDVWKHFRGHUXQV
Discussion
)RUWKH,'(WRVHQGWKHFRPSLOHGFRGHWRWKHERDUGWKHERDUGQHHGVWREHSOXJJHG
LQWRWKHFRPSXWHUDQG\RXQHHGWRWHOOWKH,'(ZKLFKERDUGDQGVHULDOSRUW\RXDUH
XVLQJ
:KHQDQXSORDGVWDUWVZKDWHYHUVNHWFKLVUXQQLQJRQWKHERDUGLVVWRSSHG LI\RXZHUH
UXQQLQJWKH%OLQNVNHWFKWKH/('ZLOOVWRSIODVKLQJ 7KHQHZVNHWFKLVXSORDGHGWR
WKHERDUGUHSODFLQJWKHSUHYLRXVVNHWFK7KHQHZVNHWFKZLOOVWDUWUXQQLQJZKHQWKH
XSORDGKDVVXFFHVVIXOO\FRPSOHWHG
2OGHU$UGXLQRERDUGVDQGVRPHFRPSDWLEOHVGRQRWDXWRPDWLFDOO\LQ
WHUUXSWWKHUXQQLQJVNHWFKWRLQLWLDWHXSORDG,QWKLVFDVH\RXQHHGWR
SUHVVWKH5HVHWEXWWRQRQWKHERDUGMXVWDIWHUWKHVRIWZDUHUHSRUWVWKDW
LWLVGRQHFRPSLOLQJ ZKHQ\RXVHHWKHPHVVDJHDERXWWKHVL]HRIWKH
VNHWFK ,WPD\WDNHDIHZDWWHPSWVWRJHWWKHWLPLQJULJKWEHWZHHQWKH
HQGRIWKHFRPSLODWLRQDQGSUHVVLQJWKH5HVHWEXWWRQ
7KH,'(ZLOOGLVSOD\DQHUURUPHVVDJHLIWKHXSORDGLVQRWVXFFHVVIXO3UREOHPVDUH
XVXDOO\GXHWRWKHZURQJERDUGRUVHULDOSRUWEHLQJVHOHFWHGRUWKHERDUGQRWEHLQJ
SOXJJHGLQ
,I\RXKDYHWURXEOHLGHQWLI\LQJWKHFRUUHFWSRUWRQ:LQGRZVWU\XQSOXJJLQJWKHERDUG
DQGWKHQVHOHFWLQJ7RROVൺ6HULDO3RUWWRVHHZKLFK&20SRUWLVQRORQJHURQWKHGLVSOD\
OLVW$QRWKHUDSSURDFKLVWRVHOHFWWKHSRUWVRQHE\RQHXQWLO\RXVHHWKHOLJKWVRQWKH
ERDUGIOLFNHUWRLQGLFDWHWKDWWKHFRGHLVXSORDGLQJ
12 | Chapter 1:ಗGetting Started
See Also
7KH$UGXLQRWURXEOHVKRRWLQJSDJHKWWSZZZDUGXLQRFFHQ*XLGH7URXEOHVKRRWLQJ
1.5 Creating and Saving a Sketch
Problem
<RXZDQWWRFUHDWHDVNHWFKDQGVDYHLWWR\RXUFRPSXWHU
Solution
7RRSHQDQHGLWRUZLQGRZUHDG\IRUDQHZVNHWFKODXQFKWKH,'( VHH5HFLSH JR
WRWKH)LOHPHQXDQGVHOHFW1HZ3DVWHWKHIROORZLQJFRGHLQWRWKH6NHWFK(GLWRUZLQ
GRZ LW¦VVLPLODUWRWKH%OLQNVNHWFKEXWWKHEOLQNVODVWWZLFHDVORQJ const int ledPin =
13;
// LED connected to digital pin 13
void setup()
{
pinMode(ledPin, OUTPUT);
}
void loop()
{
digitalWrite(ledPin, HIGH);
delay(2000);
digitalWrite(ledPin, LOW);
delay(2000);
}
// set the LED on
// wait for two seconds
// set the LED off
// wait for two seconds
&RPSLOHWKHFRGHE\FOLFNLQJWKHFRPSLOHEXWWRQ WKHWRSOHIWEXWWRQZLWKDWULDQJOH
LQVLGH RUVHOHFW6NHWFKൺ9HULI\&RPSLOH VHH5HFLSH 8SORDGWKHFRGHE\FOLFNLQJRQWKHXSORDGEXWWRQRUFKRRVH)LOHൺ8SORDGWR,2ERDUG
VHH5HFLSH $IWHUXSORDGLQJWKH/('VKRXOGEOLQNZLWKHDFKIODVKODVWLQJWZR
VHFRQGV
<RX FDQ VDYH WKLV VNHWFK WR \RXU FRPSXWHU E\ FOLFNLQJ WKH 6DYH EXWWRQ RU VHOHFW
)LOHൺ6DYH
<RXFDQVDYHWKHVNHWFKXVLQJDQHZQDPHE\VHOHFWLQJWKH6DYH$VPHQXRSWLRQ$
GLDORJER[ZLOORSHQZKHUH\RXFDQHQWHUWKHILOHQDPH
Discussion
:KHQ\RXVDYHDILOHLQWKH,'(DVWDQGDUGGLDORJER[IRUWKHRSHUDWLQJV\VWHPZLOO
RSHQ,WVXJJHVWVWKDW\RXVDYHWKHVNHWFKWRDIROGHUFDOOHG$UGXLQRLQ\RXU0\'RFX
PHQWVIROGHU RU\RXU'RFXPHQWVIROGHURQD0DF <RXFDQUHSODFHWKHGHIDXOWVNHWFK
1.5 Creating and Saving a Sketch | 13
QDPHZLWKDPHDQLQJIXOQDPHWKDWUHIOHFWVWKHSXUSRVHRI\RXUVNHWFK&OLFN6DYHWR
VDYHWKHILOH
7KHGHIDXOWQDPHLVWKHZRUGVNHWFKIROORZHGE\WKHFXUUHQWGDWH6H
TXHQWLDOOHWWHUVVWDUWLQJIURPDDUHXVHGWRGLVWLQJXLVKVNHWFKHVFUHDWHG
RQWKHVDPHGD\5HSODFLQJWKHGHIDXOWQDPHZLWKVRPHWKLQJPHDQLQJ
IXOKHOSV\RXWRLGHQWLI\WKHSXUSRVHRIDVNHWFKZKHQ\RXFRPHEDFN
WRLWODWHU
,I\RXXVHFKDUDFWHUVWKDWWKH,'(GRHVQRWDOORZ HJWKHVSDFHFKDUDFWHU WKH,'(
ZLOODXWRPDWLFDOO\UHSODFHWKHVHZLWKYDOLGFKDUDFWHUV
$UGXLQRVNHWFKHVDUHVDYHGDVSODLQWH[WILOHVZLWKWKHH[WHQVLRQSGH7KH\DUHDXWR
PDWLFDOO\VDYHGLQDIROGHUZLWKWKHVDPHQDPHDVWKHVNHWFK
<RXFDQVDYH\RXUVNHWFKHVWRDQ\IROGHURQ\RXUFRPSXWHUEXWLI\RXXVHWKHGHIDXOW
IROGHU WKH$UGXLQRIROGHULQ\RXU'RFXPHQWVIROGHU \RXUVNHWFKHVZLOODXWRPDWLFDOO\
DSSHDULQWKH6NHWFKERRNPHQXRIWKH$UGXLQRVRIWZDUHDQGEHHDVLHUWRORFDWH
,I\RXKDYHHGLWHGRQHRIWKHH[DPSOHVIURPWKH$UGXLQRGRZQORDG\RX
ZLOOQRWEHDEOHWRVDYHWKHFKDQJHGILOHXVLQJWKHVDPHILOHQDPH7KLV
SUHVHUYHVWKHVWDQGDUGH[DPSOHVLQWDFW,I\RXZDQWWRVDYHDPRGLILHG
H[DPSOH\RXZLOOQHHGWRVHOHFWDQRWKHUORFDWLRQIRUWKHVNHWFK
$IWHU\RXKDYHPDGHFKDQJHV\RXZLOOVHHDGLDORJER[DVNLQJLI\RXZDQWWRVDYHWKH
VNHWFKZKHQDVNHWFKLVFORVHG
7KHV\PEROIROORZLQJWKHQDPHRIWKHVNHWFKLQWKHWRSEDURIWKH,'(
ZLQGRZLQGLFDWHVWKDWWKHVNHWFKFRGHKDVFKDQJHVWKDWKDYHQRW\HW
EHHQVDYHGRQWKHFRPSXWHU7KLVV\PEROLVUHPRYHGZKHQ\RXVDYHWKH
VNHWFK
7KH$UGXLQRVRIWZDUHGRHVQRWSURYLGHDQ\NLQGRIYHUVLRQFRQWUROVRLI\RXZDQWWR
EHDEOHWRUHYHUWWRROGHUYHUVLRQVRIDVNHWFK\RXFDQXVH6DYH$VUHJXODUO\DQGJLYH
HDFKUHYLVLRQRIWKHVNHWFKDVOLJKWO\GLIIHUHQWQDPH
)UHTXHQWFRPSLOLQJDV\RXPRGLI\RUDGGFRGHLVDJRRGZD\WRFKHFNIRUHUURUVDV\RX
ZULWH\RXUFRGH,WZLOOEHHDVLHUWRILQGDQGIL[DQ\HUURUVEHFDXVHWKH\ZLOOXVXDOO\EH
DVVRFLDWHGZLWKZKDW\RXKDYHMXVWZULWWHQ
2QFHDVNHWFKKDVEHHQXSORDGHGRQWRWKHERDUGWKHUHLVQRZD\WR
GRZQORDGLWEDFNWR\RXUFRPSXWHU0DNHVXUH\RXVDYHDQ\FKDQJHV
WR\RXUVNHWFKHVWKDW\RXZDQWWRNHHS
14 | Chapter 1:ಗGetting Started
,I\RXRSHQVNHWFKHV\RXJHWIURPRWKHUSHRSOHWKDWDUHQRWLQDIROGHUZLWKWKHVDPH
QDPHDVWKHVNHWFKWKH,'(ZLOOWHOO\RXDQG\RXFDQFOLFN2.WRSXWWKHPLQDIROGHU
ZLWKWKHVDPHQDPH
6NHWFKHVPXVWEHORFDWHGLQDIROGHUZLWKWKHVDPHQDPHDVWKHVNHWFK
7KH,'(ZLOOFUHDWHWKHIROGHUDXWRPDWLFDOO\ZKHQ\RXVDYHDQHZVNHWFK
1.6 Using Arduino
Problem
<RXZDQWWRJHWVWDUWHGZLWKDSURMHFWWKDWLVHDV\WREXLOGDQGIXQWRXVH
Solution
7KLVUHFLSHSURYLGHVDWDVWHRIVRPHRIWKHWHFKQLTXHVWKDWDUHFRYHUHGLQGHWDLOLQODWHU
FKDSWHUV
7KHVNHWFKLVEDVHGRQWKH/('EOLQNLQJFRGHIURPWKHSUHYLRXVUHFLSHEXWLQVWHDGRI
XVLQJDIL[HGGHOD\WKHUDWHLVGHWHUPLQHGE\DOLJKWVHQVLWLYHVHQVRUFDOOHGDOLJKWGH
SHQGHQWUHVLVWRURU/'5 VHH5HFLSH :LUHWKH/'5DVVKRZQLQ)LJXUH
)LJXUH$UGXLQRZLWKOLJKWGHSHQGHQWUHVLVWRU
7KHIROORZLQJVNHWFKUHDGVWKHOLJKWOHYHORIDQ/'5FRQQHFWHGWRDQDORJSLQ7KH
OLJKWOHYHOVWULNLQJWKH/'5ZLOOFKDQJHWKHEOLQNUDWHRIWKHLQWHUQDO/('FRQQHFWHGWR
SLQ
1.6 Using Arduino | 15
const int ledPin = 13;
const int sensorPin = 0;
// LED connected to digital pin 13
// connect sensor to analog input 0
void setup()
{
pinMode(ledPin, OUTPUT); // enable output on the led pin
}
void loop()
{
int rate = analogRead(sensorPin);
// read the analog input
Serial.println(rate);
rate = map(rate, 200,800,minDuration, maxDuration); // convert to blink rate
digitalWrite(ledPin, HIGH);
// set the LED on
delay(rate);
// wait duration dependent on light level
digitalWrite(ledPin, LOW);
// set the LED off
delay(rate);
}
Discussion
7KHYDOXHRIWKH.UHVLVWRULVQRWFULWLFDO$Q\WKLQJIURP.WR.FDQEHXVHG7KH
OLJKWOHYHORQWKH/'5ZLOOFKDQJHWKHYROWDJHOHYHORQDQDORJSLQ7KH analogRead
FRPPDQG VHH&KDSWHU SURYLGHVDYDOXHWKDWUDQJHVIURPDURXQGZKHQWKH/'5
LVGDUNWRRUVRZKHQLWLVYHU\EULJKW7KLVYDOXHGHWHUPLQHVWKHGXUDWLRQRIWKH
/('RQDQGRIIWLPHVVRWKHEOLQNUDWHLQFUHDVHVZLWKOLJKWLQWHQVLW\
<RXFDQVFDOHWKHEOLQNUDWHE\XVLQJWKH$UGXLQRmapIXQFWLRQDVIROORZV
const int ledPin = 13;
const int sensorPin = 0;
// LED connected to digital pin 13
// connect sensor to analog input 0
// the next two lines set the min and max delay between blinks
const int minDuration = 100; // minimum wait between blinks
const int maxDuration = 1000; // maximum wait between blinks
void setup()
{
pinMode(ledPin, OUTPUT); // enable output on the led pin
}
void loop()
{
int rate = analogRead(sensorPin);
// read the analog input
// the next line scales the blink rate between the min and max values
rate = map(rate, 200,800,minDuration, maxDuration); // convert to blink rate
digitalWrite(ledPin, HIGH);
// set the LED on
delay(rate);
// wait duration dependent on light level
digitalWrite(ledPin, LOW);
// set the LED off
delay(rate);
}
5HFLSHSURYLGHVPRUHGHWDLOVRQXVLQJWKHmapIXQFWLRQWRVFDOHYDOXHV
16 | Chapter 1:ಗGetting Started
,I\RXZDQWWRYLHZWKHYDOXHRIWKHUDWHYDULDEOHRQ\RXUFRPSXWHU\RXFDQSULQWWKLV
WR WKH $UGXLQR 6HULDO 0RQLWRU DV VKRZQ LQ WKH UHYLVHG ORRS FRGH WKDW IROORZV 7KH
VNHWFKZLOOGLVSOD\WKHEOLQNUDWHLQWKH6HULDO0RQLWRU<RXRSHQWKH6HULDO0RQLWRU
ZLQGRZLQWKH$UGXLQR,'( VHH&KDSWHUIRUPRUHRQXVLQJWKH6HULDO0RQLWRU const int ledPin = 13;
const int sensorPin = 0;
// LED connected to digital pin 13
// connect sensor to analog input 0
// the next two lines set the min and max delay between blinks
const int minDuration = 100; // minimum wait between blinks
const int maxDuration = 1000; // maximum wait between blinks
void setup()
{
pinMode(ledPin, OUTPUT); // enable output on the led pin
Serial.begin(9600);
// initialize Serial
}
void loop()
{
int rate = analogRead(sensorPin);
// read the analog input
// the next line scales the blink rate between the min and max values
rate = map(rate, 200,800,minDuration, maxDuration); // convert to blink rate
Serial.println(rate);
// print rate to serial monitor
digitalWrite(ledPin, HIGH);
// set the LED on
delay(rate);
// wait duration dependent on light level
digitalWrite(ledPin, LOW);
// set the LED off
delay(rate);
}
<RXFDQXVHWKH/'5WRFRQWUROWKHSLWFKRIDVRXQGE\FRQQHFWLQJDVPDOOVSHDNHUWR
WKHSLQDVVKRZQLQ)LJXUH
)LJXUH&RQQHFWLRQVIRUDVSHDNHUZLWKWKH/'5FLUFXLW
1.6 Using Arduino | 17
<RXZLOOQHHGWRLQFUHDVHWKHRQRIIUDWHRQWKHSLQWRDIUHTXHQF\LQWKHDXGLRVSHFWUXP
7KLVLVDFKLHYHGDVVKRZQLQWKHIROORZLQJFRGHE\GLYLGLQJWKHUDWHE\LQWKHOLQH
DIWHUWKHmapIXQFWLRQ
const int ledPin = 13;
const int sensorPin = 0;
// LED connected to digital pin 13
// connect sensor to analog input 0
const int minDuration = 100; // minimum wait between blinks
const int maxDuration = 1000; // maximum wait between blinks
void setup()
{
pinMode(ledPin, OUTPUT); // enable output on the led pin
}
void loop()
{
int sensorReading = analogRead(sensorPin);
// read the analog input
int rate = map(sensorReading, 200,800,minDuration, maxDuration);
rate = rate / 100;
// add this line for audio frequency
digitalWrite(ledPin, HIGH);
// set the LED on
delay(rate);
// wait duration dependent on light level
digitalWrite(ledPin, LOW);
// set the LED off
delay(rate);
}
See Also
6HH&KDSWHUIRUPRUHRQFUHDWLQJVRXQGZLWK$UGXLQR
18 | Chapter 1:ಗGetting Started
Download from Wow! eBook <www.wowebook.com>
CHAPTER 2
Making the Sketch Do Your Bidding
2.0 Introduction
7KRXJKPXFKRIDQ$UGXLQRSURMHFWZLOOLQYROYHLQWHJUDWLQJWKH$UGXLQRERDUGZLWK
VXSSRUWLQJKDUGZDUH\RXQHHGWREHDEOHWRWHOOWKHERDUGZKDWWRGRZLWKWKHUHVWRI
\RXUSURMHFW7KLVFKDSWHULQWURGXFHVFRUHHOHPHQWVRI$UGXLQRSURJUDPPLQJVKRZLQJ
QRQSURJUDPPHUVKRZWRXVHFRPPRQODQJXDJHFRQVWUXFWVDQGSURYLGLQJDQRYHUYLHZ
RIWKHODQJXDJHV\QWD[IRUUHDGHUVZKRDUHQRWIDPLOLDUZLWK&RU&WKHODQJXDJH
EHLQJXVHG
6LQFH PDNLQJ WKH H[DPSOHV LQWHUHVWLQJ UHTXLUHV PDNLQJ $UGXLQR GR VRPHWKLQJ WKH
UHFLSHVXVHSK\VLFDOFDSDELOLWLHVRIWKHERDUGWKDWDUHH[SODLQHGLQGHWDLOLQODWHUFKDS
WHUV,IDQ\RIWKHFRGHLQWKLVFKDSWHULVQRWFOHDUIHHOIUHHWRMXPSIRUZDUGSDUWLFXODUO\
WR&KDSWHUIRUPRUHRQVHULDORXWSXWDQG&KDSWHUIRUPRUHRQXVLQJGLJLWDODQG
DQDORJSLQV<RXGRQ¦WQHHGWRXQGHUVWDQGDOOWKHFRGHLQWKHH[DPSOHVWKRXJKWRVHH
KRZWRSHUIRUPWKHVSHFLILFFDSDELOLWLHVWKDWDUHWKHIRFXVRIWKHUHFLSHV+HUHDUHVRPH
RIWKHPRUHFRPPRQIXQFWLRQVXVHGLQWKHH[DPSOHVWKDWDUHFRYHUHGLQWKHQH[WIHZ
FKDSWHUV
Serial.println(value);
3ULQWVWKHYDOXHWRWKH6HULDO0RQLWRURQ\RXUFRPSXWHUVHH5HFLSH
pinMode(pin, mode);
&RQILJXUHVDGLJLWDOSLQWRUHDG LQSXW RUZULWH RXWSXW DGLJLWDOYDOXHVHHWKH
LQWURGXFWLRQWR&KDSWHU
digitalRead(pin);
5HDGVDGLJLWDOYDOXH HIGHRULOW RQDSLQVHWIRULQSXWVHH5HFLSH
digitalWrite(pin, value);
:ULWHVWKHGLJLWDOYDOXH HIGHRULOW WRDSLQVHWIRURXWSXWVHH5HFLSH
19
2.1 Structuring an Arduino Program
Problem
<RXDUHQHZWRSURJUDPPLQJDQGZDQWWRXQGHUVWDQGWKHEXLOGLQJEORFNVRIDQ$UGXLQR
SURJUDP
Solution
3URJUDPVIRU$UGXLQRDUHXVXDOO\UHIHUUHGWRDVVNHWFKHVWRHPSKDVL]HWKHDJLOHQDWXUH
RIGHYHORSPHQW7KHWHUPVVNHWFKDQGSURJUDPDUHLQWHUFKDQJHDEOH6NHWFKHVFRQWDLQ
FRGH¢WKHLQVWUXFWLRQVWKHERDUGZLOOFDUU\RXW&RGHWKDWQHHGVWRUXQRQO\RQFH VXFK
DVWRVHWXSWKHERDUGIRU\RXUDSSOLFDWLRQ VKRXOGEHSODFHGLQWKH setupIXQFWLRQ
&RGHWREHUXQFRQWLQXRXVO\DIWHUWKHLQLWLDOVHWXSKDVILQLVKHGJRHVLQWRWKHloopIXQF
WLRQ+HUHLVDW\SLFDOVNHWFK
const int ledPin =
13;
// LED connected to digital pin 13
// The setup() method runs once, when the sketch starts
void setup()
{
pinMode(ledPin, OUTPUT);
// initialize the digital pin as an output
}
// the loop() method runs over and over again,
void loop()
{
digitalWrite(ledPin, HIGH);
// turn the LED on
delay(1000);
// wait a second
digitalWrite(ledPin, LOW);
// turn the LED off
delay(1000);
// wait a second
}
:KHQWKHERDUGILQLVKHVXSORDGLQJWKHFRGHRULVWXUQHGRQRQFHLWFRQWDLQVWKLVFRGH
LWVWDUWVDWWKHWRSRIWKHVNHWFKDQGFDUULHVRXWWKHLQVWUXFWLRQVVHTXHQWLDOO\,WUXQVWKH
FRGHLQsetupRQFHDQGWKHQJRHVWKURXJKWKHFRGHLQloop:KHQLWJHWVWRWKHHQGRI
loop PDUNHGE\WKHFORVLQJEUDFNHW} LWJRHVEDFNWRWKHEHJLQQLQJRIloop
Discussion
7KLVH[DPSOHFRQWLQXRXVO\IODVKHVDQ/('E\ZULWLQJ HIGHDQG LOWRXWSXWVWRDSLQ
6HH&KDSWHUWROHDUQPRUHDERXWXVLQJ$UGXLQRSLQV:KHQWKHVNHWFKEHJLQVWKH
FRGHLQsetupVHWVWKHSLQPRGH VRLW¦VFDSDEOHRIOLJKWLQJDQ/(' $IWHUWKHFRGHLQ
setupLVFRPSOHWHGWKHFRGHLQloopLVUHSHDWHGO\FDOOHG WRIODVKWKH/(' IRUDVORQJ
DVWKH$UGXLQRERDUGLVSRZHUHGRQ
<RXGRQ¦WQHHGWRNQRZWKLVWRZULWH$UGXLQRVNHWFKHVEXWH[SHULHQFHG&&SUR
JUDPPHUVPD\ZRQGHUZKHUHWKHH[SHFWHGmain()HQWU\SRLQWIXQFWLRQKDVJRQH,W¦V
WKHUHEXWLW¦VKLGGHQXQGHUWKHFRYHUVE\WKH$UGXLQREXLOGHQYLURQPHQW7KHEXLOG
20 | Chapter 2:ಗMaking the Sketch Do Your Bidding
SURFHVVFUHDWHVDQLQWHUPHGLDWHILOHWKDWLQFOXGHVWKHVNHWFKFRGHDQGWKHIROORZLQJ
DGGLWLRQDOVWDWHPHQWV
int main(void)
{
init();
setup();
for (;;)
loop();
return 0;
}
7KHILUVWWKLQJWKDWKDSSHQVLVDFDOOWRDQinit()IXQFWLRQWKDWLQLWLDOL]HVWKH$UGXLQR
KDUGZDUH1H[WWKHVNHWFK¦Vsetup()IXQFWLRQLVFDOOHG)LQDOO\WKHloop()IXQFWLRQLV
FDOOHGRYHUDQGRYHU%HFDXVHWKH forORRSQHYHUWHUPLQDWHVWKH returnVWDWHPHQWLV
QHYHUH[HFXWHG
See Also
&KDSWHUDQGKWWSZZZDUGXLQRFFHQ+DFNLQJ%XLOG3URFHVVSURYLGHPRUHRQWKH
EXLOGSURFHVV
2.2 Using Simple Primitive Types (Variables)
Problem
$UGXLQRKDVGLIIHUHQWW\SHVRIYDULDEOHVWRHIILFLHQWO\UHSUHVHQWYDOXHV<RXZDQWWR
NQRZKRZWRVHOHFWDQGXVHWKHVH$UGXLQRGDWDW\SHV
Solution
$OWKRXJKWKH int VKRUWIRULQWHJHUDELWYDOXHLQ$UGXLQR GDWDW\SHLVWKHPRVW
FRPPRQFKRLFHIRUWKHQXPHULFYDOXHVHQFRXQWHUHGLQ$UGXLQRDSSOLFDWLRQV\RXFDQ
XVH7DEOHWRGHWHUPLQHWKHGDWDW\SHWKDWILWVWKHUDQJHRIYDOXHV\RXUDSSOLFDWLRQ
H[SHFWV
7DEOH$UGXLQRGDWDW\SHV
Numeric types
Bytes
Range
Use
int
2
-32768 to 32767
Represents positive and negative integer values.
unsigned int
2
0 to 65535
Represents only positive values; otherwise, similar to int.
long
4
-2147483648 to
2147483647
Represents a very large range of positive and negative values.
unsigned
long
4
4294967295
Represents a very large range of positive values.
2.2 Using Simple Primitive Types (Variables) | 21
Numeric types
Bytes
Range
Use
float
4
3.4028235E+38 to
-3.4028235E+38
Represents numbers with fractions; use to approximate realworld measurements.
double
4
Same as float
In Arduino, double is just another name for float.
boolean
1
false (0) or true (1)
Represents true and false values.
char
1
-128 to 127
Represents a single character. Can also represent a signed value
between -128 and 127.
byte
1
0 to 255
Similar to char, but for unsigned values.
Other types
string
Represents arrays of chars (characters) typically used to contain text.
void
Used only in function declarations where no value is returned.
Discussion
([FHSWLQVLWXDWLRQVZKHUHPD[LPXPSHUIRUPDQFHRUPHPRU\HIILFLHQF\LVUHTXLUHG
YDULDEOHVGHFODUHGXVLQJ intZLOOEHVXLWDEOHIRUQXPHULFYDOXHVLIWKHYDOXHVGRQRW
H[FHHGWKHUDQJH VKRZQLQWKHILUVWURZLQ7DEOH DQGLI\RXGRQ¦WQHHGWRZRUN
ZLWK IUDFWLRQDO YDOXHV 0RVW RI WKH RIILFLDO $UGXLQR H[DPSOH FRGH GHFODUHV QXPHULF
YDULDEOHVDVint%XWVRPHWLPHV\RXGRQHHGWRFKRRVHDW\SHWKDWVSHFLILFDOO\VXLWV\RXU
DSSOLFDWLRQ
6RPHWLPHV\RXQHHGQHJDWLYHQXPEHUVDQGVRPHWLPHV\RXGRQ¦WVRQXPHULFW\SHV
FRPHLQWZRYDULHWLHVsignedDQGunsignedunsignedYDOXHVDUHDOZD\VSRVLWLYH9DUL
DEOHVZLWKRXWWKHNH\ZRUGunsignedLQIURQWDUHVLJQHGVRWKDWWKH\FDQUHSUHVHQWQHJ
DWLYH DQG SRVLWLYH YDOXHV 2QH UHDVRQ WR XVH unsigned YDOXHV LV ZKHQ WKH UDQJH RI
signedYDOXHVZLOOQRWILWWKHUDQJHRIWKHYDULDEOH DQXQVLJQHGYDULDEOHKDVWZLFHWKH
FDSDFLW\RIDVLJQHGYDULDEOH $QRWKHUUHDVRQSURJUDPPHUVFKRRVHWRXVH unsigned
W\SHVLVWRFOHDUO\LQGLFDWHWRSHRSOHUHDGLQJWKHFRGHWKDWWKHYDOXHH[SHFWHGZLOOQHYHU
EHDQHJDWLYHQXPEHU
booleanW\SHVKDYHWZRSRVVLEOHYDOXHV trueRU false7KH\DUHFRPPRQO\XVHGIRU
WKLQJVOLNHFKHFNLQJWKHVWDWHRIDVZLWFK LILW¦VSUHVVHGRUQRW <RXFDQDOVRXVHHIGH
DQG LOW DV HTXLYDOHQWV WR true DQG false ZKHUH WKLV PDNHV PRUH VHQVH digital
Write(pin, HIGH)LVDPRUHH[SUHVVLYHZD\WRWXUQRQDQ/('WKDQdigitalWrite(pin,
true)RU digitalWrite(pin,1)DOWKRXJKDOORIWKHVHDUHWUHDWHGLGHQWLFDOO\ZKHQWKH
VNHWFKDFWXDOO\UXQVDQG\RXDUHOLNHO\WRFRPHDFURVVDOORIWKHVHIRUPVLQFRGHSRVWHG
RQWKH:HE
See Also
7KH$UGXLQRUHIHUHQFHDWKWWSZZZDUGXLQRFFHQ5HIHUHQFH+RPH3DJHSURYLGHVGH
WDLOVRQGDWDW\SHV
22 | Chapter 2:ಗMaking the Sketch Do Your Bidding
2.3 Using Floating-Point Numbers
Problem
)ORDWLQJSRLQWQXPEHUVDUHXVHGIRUYDOXHVH[SUHVVHGZLWKGHFLPDOSRLQWV WKLVLVWKH
ZD\WRUHSUHVHQWIUDFWLRQDOYDOXHV <RXZDQWWRFDOFXODWHDQGFRPSDUHWKHVHYDOXHVLQ
\RXUVNHWFK
Solution
7KHIROORZLQJFRGHVKRZVKRZWRGHFODUHIORDWLQJSRLQWYDULDEOHVLOOXVWUDWHVSUREOHPV
\RXFDQHQFRXQWHUZKHQFRPSDULQJIORDWLQJSRLQWYDOXHVDQGGHPRQVWUDWHVKRZWR
RYHUFRPHWKHP
/*
* Floating-point example
* This sketch initialized a float value to 1.1
* It repeatedly reduces the value by 0.1 until the value is 0
*/
float
value = 1.1;
void setup()
{
Serial.begin(9600);
}
void loop()
{
value = value - 0.1;
// reduce value by 0.1 each time through the loop
if( value == 0)
Serial.println("The value is exactly zero");
else if(fabs(value) < .0001) // function to take the absolute value of a float
Serial.println("The value is close enough to zero");
else
Serial.println(value);
delay(100);
}
Discussion
)ORDWLQJSRLQWPDWKLVQRWH[DFWDQGYDOXHVUHWXUQHGFDQKDYHDVPDOODSSUR[LPDWLRQ
HUURU7KHHUURURFFXUVEHFDXVHIORDWLQJSRLQWYDOXHVFRYHUDKXJHUDQJHVRWKHLQWHUQDO
UHSUHVHQWDWLRQRIWKHYDOXHFDQRQO\KROGDQDSSUR[LPDWLRQ%HFDXVHRIWKLV\RXQHHG
WRWHVWLIWKHYDOXHVDUHZLWKLQDUDQJHRIWROHUDQFHUDWKHUWKDQH[DFWO\HTXDO
7KHRXWSXWIURPWKLVVNHWFKLVDVIROORZV
1.00
0.90
2.3 Using Floating-Point Numbers | 23
0.80
0.70
0.60
0.50
0.40
0.30
0.20
0.10
The value is close enough to zero
-0.10
-0.20
7KHRXWSXWFRQWLQXHVWRSURGXFHQHJDWLYHQXPEHUV
<RXPD\H[SHFWWKHORRSWRVWRSDIWHUvalueLV0.1DQGWKHQLVVXEWUDFWHGIURPWKLV
%XWvalueQHYHUHTXDOV]HURLWJHWVYHU\FORVHEXWWKDWLVQRWJRRGHQRXJKWRSDVVWKH
WHVWif (value == 0)7KLVLVEHFDXVHWKHRQO\PHPRU\HIILFLHQWZD\WKDWIORDWLQJSRLQW
QXPEHUVFDQFRQWDLQWKHKXJHUDQJHLQYDOXHVWKH\FDQUHSUHVHQWLVE\VWRULQJDQDS
SUR[LPDWLRQRIWKHQXPEHU
7KHVROXWLRQWRWKLVLVWRFKHFNLIDYDULDEOHLVFORVHWRWKHGHVLUHGYDOXHDVVKRZQLQ
WKHFRGHLQWKLVUHFLSH¦V6ROXWLRQ
else if(fabs(value) < .0001) // function to take absolute value of a float
Serial.println("The value is close enough to zero");
7KLVWHVWVLIWKHYDULDEOHvalueLVZLWKLQRIWKHGHVLUHGWDUJHWDQGSULQWVDPHVVDJH
LIVR7KHIXQFWLRQQDPHGfabs VKRUWIRUIORDWLQJSRLQWDEVROXWHYDOXH UHWXUQVWKHDE
VROXWHYDOXHRIDIORDWLQJSRLQWYDULDEOH7KHIXQFWLRQUHWXUQVWKHPDJQLWXGHRIWKH
YDOXHDQGLIWKLVLVZLWKLQRIWKHFRGHZLOOSULQWWKHPHVVDJHWKDWWKHYDOXHV
DUHFORVHHQRXJK
)ORDWLQJSRLQWDSSUR[LPDWHVQXPEHUVEHFDXVHLWRQO\XVHVELWVWR
KROGDOOYDOXHVZLWKLQDKXJHUDQJH(LJKWELWVDUHXVHGIRUWKHGHFLPDO
PXOWLSOLHU WKH H[SRQHQW DQG WKDW OHDYHV ELWV IRU WKH VLJQ DQG
YDOXH¢RQO\HQRXJKIRUVHYHQVLJQLILFDQWGHFLPDOGLJLWV
$OWKRXJKfloatDQGdoubleDUHH[DFWO\WKHVDPHRQ$UGXLQRdoubleVGR
KDYHDKLJKHUSUHFLVLRQRQPDQ\RWKHUSODWIRUPV,I\RXDUHLPSRUWLQJ
FRGHWKDWXVHVfloatDQGdoubleIURPDQRWKHUSODWIRUPFKHFNWKDWWKHUH
LVVXIILFLHQWSUHFLVLRQIRU\RXUDSSOLFDWLRQ
See Also
7KH$UGXLQRUHIHUHQFHIRUfloatKWWSZZZDUGXLQRFFHQ5HIHUHQFH)ORDW
24 | Chapter 2:ಗMaking the Sketch Do Your Bidding
2.4 Working with Groups of Values
Problem
<RXZDQWWRFUHDWHDQGXVHDJURXSRIYDOXHV FDOOHGDUUD\V 7KHDUUD\VPD\EHDVLPSOH
OLVWRUWKH\FRXOGKDYHWZRRUPRUHGLPHQVLRQV<RXZDQWWRNQRZKRZWRGHWHUPLQH
WKHVL]HRIWKHDUUD\DQGKRZWRDFFHVVWKHHOHPHQWVLQWKHDUUD\
Solution
7KLVVNHWFKFUHDWHVWZRDUUD\VDQDUUD\RILQWHJHUVIRUSLQVFRQQHFWHGWRVZLWFKHVDQG
DQDUUD\RISLQVFRQQHFWHGWR/('VDVVKRZQLQ)LJXUH
/*
array sketch
an array of switches controls an array of LEDs
see Chapter 5 for more on using switches
see Chapter 7 for information on LEDs
*/
int inputPins[] = {2,3,4,5}; // create an array of pins for switch inputs
int ledPins[] = {10,11,12,13};
// create array of output pins for LEDs
void setup()
{
for(int index = 0; index < 4; index++)
{
pinMode(ledPins[index], OUTPUT);
pinMode(inputPins[index], INPUT);
digitalWrite(inputPins[index],HIGH);
}
// declare LED as output
// declare pushbutton as input
// enable pull-up resistors
//(see Recipe 5.2)
}
void loop(){
for(int index = 0; index < 4; index++)
{
int val = digitalRead(inputPins[i]); // read input value
if (val == LOW)
// check if the switch is pressed
{
digitalWrite(ledPins[index], HIGH); // turn LED on if switch is pressed
}
else
{
digitalWrite(ledPins[i], LOW);
// turn LED off
}
}
}
2.4 Working with Groups of Values | 25
)LJXUH&RQQHFWLRQVIRU/('VDQGVZLWFKHV
Discussion
$UUD\VDUHFROOHFWLRQVRIFRQVHFXWLYHYDULDEOHVRIWKHVDPHW\SH(DFKYDULDEOHLQWKH
FROOHFWLRQLVFDOOHGDQHOHPHQW7KHQXPEHURIHOHPHQWVLVFDOOHGWKHGLPHQVLRQRIWKH
DUUD\
7KHSUHFHGLQJH[DPSOHGHPRQVWUDWHVDFRPPRQXVHRIDUUD\VLQ$UGXLQRFRGHVWRULQJ
DFROOHFWLRQRISLQV+HUHWKHSLQVFRQQHFWWRVZLWFKHVDQG/('V DWRSLFFRYHUHGLQ
PRUHGHWDLOLQ&KDSWHU 7KHLPSRUWDQWSDUWVRIWKLVH[DPSOHDUHWKHGHFODUDWLRQRI
WKHDUUD\DQGDFFHVVWRWKHDUUD\HOHPHQWV
7KHIROORZLQJOLQHRIFRGHGHFODUHV FUHDWHV DQDUUD\RILQWHJHUVZLWKIRXUHOHPHQWVDQG
LQLWLDOL]HVHDFKHOHPHQW7KHILUVWHOHPHQWLVVHWHTXDOWRWKHVHFRQGWRDQGVRRQ
int inputPins[] = {2,3,4,5};
26 | Chapter 2:ಗMaking the Sketch Do Your Bidding
,I\RXGRQ¦WQHHGWRLQLWLDOL]HWKHYDOXHVZKHQ\RXGHFODUHDQDUUD\ SHUKDSVWKHYDOXHV
ZLOORQO\EHDYDLODEOHZKHQWKHVNHWFKLVUXQQLQJ \RXFDQGHFODUHWKHDUUD\DVIROORZV
int array[4];
7KLVGHFODUHVDQDUUD\RIIRXUHOHPHQWVZLWKWKHLQLWLDOYDOXHRIHDFKHOHPHQWVHWWR]HUR
7KHQXPEHUZLWKLQWKHVTXDUHEUDFNHWV [] LVWKHGLPHQVLRQDQGWKLVVHWVWKHQXPEHU
RIHOHPHQWV7KLVDUUD\KDVDGLPHQVLRQRIIRXUDQGFDQKROGDWPRVWIRXULQWHJHU
YDOXHV7KHGLPHQVLRQFDQEHRPLWWHGLIDUUD\GHFODUDWLRQFRQWDLQVLQLWLDOL]HUV DVVKRZQ
LQWKHILUVWH[DPSOH EHFDXVHWKHFRPSLOHUILJXUHVRXWKRZELJWRPDNHWKHDUUD\E\
FRXQWLQJWKHQXPEHURILQLWLDOL]HUV
7KHILUVWHOHPHQWRIWKHDUUD\LVelement[0]
int firstElement = inputPin[0];
// this is the first element
7KHODVWHOHPHQWLVRQHOHVVWKDQWKHGLPHQVLRQVRLQWKHSUHFHGLQJH[DPSOHZLWKD
GLPHQVLRQRIIRXUWKHODVWHOHPHQWLVHOHPHQW
Int lastElement = inputPin[3]; // this is the last element
,WPD\VHHPRGGWKDWDQDUUD\ZLWKDGLPHQVLRQRIIRXUKDVWKHODVWHOHPHQWDFFHVVHG
XVLQJarray[3]EXWEHFDXVHWKHILUVWHOHPHQWLVarray[0]WKHIRXUHOHPHQWVDUH
array[0],array[1],array[2],array[3]
,QWKHSUHYLRXVVNHWFKWKHIRXUHOHPHQWVDUHDFFHVVHGXVLQJDforORRS
for(int index = 0; index < 4; index++)
{
//get the pin number by accessing each element in the pin arrays
pinMode(ledPins[index], OUTPUT);
// declare LED as output
pinMode(inputPins[index], INPUT);
// declare pushbutton as input
}
7KLVORRSZLOOVWHSWKURXJKWKHYDULDEOH indexZLWKYDOXHVVWDUWLQJDWDQGHQGLQJDW
,WLVDFRPPRQPLVWDNHWRDFFLGHQWDOO\DFFHVVDQHOHPHQWWKDWLVEH\RQGWKHDFWXDO
GLPHQVLRQRIWKHDUUD\7KLVLVDEXJWKDWFDQKDYHPDQ\GLIIHUHQWV\PSWRPVDQGFDUH
PXVW EH WDNHQ WR DYRLG LW 2QH ZD\ WR NHHS \RXU ORRSV XQGHU FRQWURO LV WR VHW WKH
GLPHQVLRQRIDQDUUD\E\XVLQJDFRQVWDQWDVIROORZV
const int PIN_COUNT = 4; // define a constant for the number of elements
int inputPins[PIN_COUNT] = {2,3,4,5};
for(int index = 0; index < PIN_COUNT; index++)
pinMode(inputPins[index], INPUT);
7KHFRPSLOHUZLOOQRWUHSRUWDQHUURULI\RXDFFLGHQWDOO\WU\WRVWRUHRU
UHDGEH\RQGWKHVL]HRIWKHDUUD\<RXPXVWEHFDUHIXOWKDW\RXRQO\
DFFHVVHOHPHQWVWKDWDUHZLWKLQWKHERXQGV\RXKDYHVHW8VLQJDFRQ
VWDQWWRVHWWKHGLPHQVLRQRIDQDUUD\DQGLQFRGHUHIHUULQJWRLWVHOHPHQWV
KHOSV\RXUFRGHVWD\ZLWKLQWKHERXQGVRIWKHDUUD\
2.4 Working with Groups of Values | 27
$QRWKHUFRPPRQXVHRIDUUD\VLVWRKROGDVWULQJRIWH[WFKDUDFWHUV,Q$UGXLQRFRGH
WKHVHDUHFDOOHGFKDUDFWHUVWULQJV VWULQJVIRUVKRUW $FKDUDFWHUVWULQJFRQVLVWVRIRQH
RUPRUHFKDUDFWHUVIROORZHGE\WKHQXOOFKDUDFWHU WKHYDOXH WRLQGLFDWHWKHHQGRI
WKHVWULQJ
7KHQXOODWWKHHQGRIDFKDUDFWHUVWULQJLVQRWWKHVDPHDVWKHFKDUDFWHU
7KHQXOOKDVDQ$6&,,YDOXHRIZKHUHDVKDVDQ$6&,,YDOXHRI
0HWKRGVWRXVHVWULQJVDUHFRYHUHGLQ5HFLSHVDQG
See Also
5HFLSH5HFLSH
2.5 Using Arduino String Functionality
Problem
<RXZDQWWRPDQLSXODWHWH[W<RXQHHGWRFRS\LWDGGELWVWRJHWKHUDQGGHWHUPLQH
WKHQXPEHURIFKDUDFWHUV
Solution
5HFLSHGHVFULEHV$UGXLQRDUUD\VLQJHQHUDO7H[WLVVWRUHGLQDUUD\VRIFKDUDFWHUV
7KH\DUHXVXDOO\FDOOHGVWULQJV$UGXLQRKDVDQDGGHGFDSDELOLW\IRUXVLQJDQDUUD\RI
FKDUDFWHUVFDOOHGStringWKDWFDQVWRUHDQGPDQLSXODWHWH[WVWULQJV
7KHZRUG6WULQJZLWKDQXSSHUFDVH6UHIHUVWRWKH$UGXLQRWH[WFDSDELOLW\
SURYLGHGE\WKH$UGXLQR6WULQJOLEUDU\7KHZRUGVWULQJZLWKDORZHUFDVH
V UHIHUV WR WKH JURXS RI FKDUDFWHUV UDWKHU WKDQ WKH $UGXLQR String
IXQFWLRQDOLW\
7KLVUHFLSHGHPRQVWUDWHVKRZWRXVH$UGXLQRVWULQJV
7KH StringFDSDELOLW\ZDVLQWURGXFHGLQYHUVLRQRI$UGXLQR,I\RX
DUHXVLQJDQROGHUYHUVLRQ\RXFDQXVHWKH7H[W6WULQJOLEUDU\VHHWKH
OLQNDWWKHHQGRIWKLVUHFLSH
/RDGWKHIROORZLQJVNHWFKRQWR\RXUERDUGDQGRSHQWKH6HULDO0RQLWRUWRYLHZWKH
UHVXOWV
28 | Chapter 2:ಗMaking the Sketch Do Your Bidding
/*
Basic_Strings sketch
*/
String text1 = "This string";
String text2 = " has more text";
String text3; // to be assigned within the sketch
void setup()
{
Serial.begin(9600);
Serial.print( text1);
Serial.print(" is ");
Serial.print(text1.length());
Serial.println(" characters long.");
Serial.print("text2 is ");
Serial.print(text2.length());
Serial.println(" characters long.");
}
text1.concat(text2);
Serial.println("text1 now contains: ");
Serial.println(text1);
void loop()
{
}
Discussion
7KLVVNHWFKFUHDWHVWZRYDULDEOHVRIW\SH StringFDOOHG messageDQG anotherMessage
9DULDEOHVRIW\SHStringKDYHEXLOWLQFDSDELOLWLHVIRUPDQLSXODWLQJWH[W7KHVWDWHPHQW
message.length()UHWXUQV SURYLGHVWKHYDOXHRI WKHOHQJWK QXPEHURIFKDUDFWHUV LQ
WKHVWULQJmessage
message.concat(anotherMessage)FRPELQHVWKHFRQWHQWVRIVWULQJVLQWKLVFDVHLWDS
SHQGV WKH FRQWHQWV RI anotherMessage WR WKH HQG RI message concat LV VKRUW IRU
FRQFDWHQDWH 7KH6HULDO0RQLWRUZLOOGLVSOD\WKHIROORZLQJ
This string is 11 characters long.
text2 is 14 characters long.
text1 now contains:
This string has more text
$QRWKHUZD\WRFRPELQHVWULQJVLVWRXVHWKHVWULQJDGGLWLRQRSHUDWRU$GGWKHVHWZR
OLQHVWRWKHHQGRIWKHsetupFRGH
text3 = text1 + " and more";
Serial.println(text3);
2.5 Using Arduino String Functionality | 29
7KHQHZFRGHZLOOUHVXOWLQWKH6HULDO0RQLWRUDGGLQJWKHIROORZLQJOLQHWRWKHHQGRI
WKHGLVSOD\
This is a string with more text and more
<RXFDQXVHWKHindexOfDQG lastIndexOfIXQFWLRQVWRILQGDQLQVWDQFHRIDSDUWLFXODU
FKDUDFWHULQDVWULQJ
%HFDXVHWKH StringFODVVLVDQHZDGGLWLRQWR$UGXLQR\RXZLOOFRPH
DFURVV D ORW RI FRGH WKDW XVHV DUUD\V RI FKDUDFWHUV UDWKHU WKDQ WKH
StringW\SH6HH5HFLSHIRUPRUHRQXVLQJDUUD\VRIFKDUDFWHUVZLWK
RXWWKHKHOSRIWKH$UGXLQRStringIXQFWLRQDOLW\
,I\RXVHHDOLQHVXFKDVWKHIROORZLQJ
char oldString[] = "this is a character array";
WKHFRGHLVXVLQJ&VW\OHFKDUDFWHUDUUD\V VHH5HFLSH ,IWKHGHFODUDWLRQORRNVOLNH
WKLV
String newString = "this is a string object";
WKH FRGH XVHV $UGXLQR StringV 7R FRQYHUW D &VW\OH FKDUDFWHU DUUD\ WR DQ $UGXLQR
StringMXVWDVVLJQWKHFRQWHQWVRIWKHDUUD\WRWKHStringREMHFW
char oldString[] = "I want this character array in a String object";
String newsString = oldString;
See Also
7KH$UGXLQRGLVWULEXWLRQSURYLGHVStringH[DPSOHVNHWFKHV
7XWRULDOVIRUWKHQHZ6WULQJOLEUDU\DUHDYDLODEOHDWKWWSDUGXLQRFFHQ7XWRULDO+RPH
3DJHDQGDWXWRULDOIRUWKHRULJLQDO6WULQJOLEUDU\LVDYDLODEOHDWKWWSZZZDUGXLQRFF
HQ7XWRULDO7H[W6WULQJ
2.6 Using C Character Strings
Problem
<RXZDQWWRXQGHUVWDQGKRZWRXVHUDZFKDUDFWHUVWULQJV\RXZDQWWRNQRZKRZWR
FUHDWHDVWULQJILQGLWVOHQJWKDQGFRPSDUHFRS\RUDSSHQGVWULQJV7KH&ODQJXDJH
GRHVQRWVXSSRUWWKH$UGXLQRVW\OHStringFDSDELOLW\VR\RXZDQWWRXQGHUVWDQGFRGH
ZULWWHQWRRSHUDWHZLWKSULPLWLYHFKDUDFWHUDUUD\V
30 | Chapter 2:ಗMaking the Sketch Do Your Bidding
Solution
$UUD\VRIFKDUDFWHUVDUHVRPHWLPHVFDOOHGFKDUDFWHUVWULQJV RUVLPSO\VWULQJVIRUVKRUW 5HFLSHGHVFULEHV$UGXLQRDUUD\VLQJHQHUDO7KLVUHFLSHGHVFULEHVIXQFWLRQVWKDW
RSHUDWHRQFKDUDFWHUVWULQJV
<RXGHFODUHVWULQJVOLNHWKLV
char StringA[8]; // declare a string of up to 7 chars plus terminating null
char StringB[8] = "Arduino"; // as above and init(ialize) the string to
"Arduino";
char StringC[16] = "Arduino"; // as above, but string has room to grow
char StringD[ ] = "Arduino"; // the compiler inits the string
and calculates size
8VH strlen VKRUWIRUVWULQJOHQJWK WRGHWHUPLQHWKHQXPEHURIFKDUDFWHUVEHIRUHWKH
QXOO
int length = strlen(string); // return the number of characters in the string
lengthZLOOEHIRU StringADQGIRUWKHRWKHUVWULQJVVKRZQLQWKHSUHFHGLQJFRGH
7KHQXOOWKDWLQGLFDWHVWKHHQGRIWKHVWULQJLVQRWFRXQWHGE\strlen
8VHstrcpy VKRUWIRUVWULQJFRS\ WRFRS\RQHVWULQJWRDQRWKHU
strcpy(destination, source);
// copy string source to destination
8VHstrncpyWROLPLWWKHQXPEHURIFKDUDFWHUVWRFRS\ XVHIXOWRSUHYHQWZULWLQJPRUH
FKDUDFWHUVWKDQWKHGHVWLQDWLRQVWULQJFDQKROG <RXFDQVHHWKLVXVHGLQ5HFLSH
strncpy(destination, source, 6);
destination
// copy up to 6 characters from source to
8VHstrcat VKRUWIRUVWULQJFRQFDWHQDWH WRDSSHQGRQHVWULQJWRWKHHQGRIDQRWKHU
strcat(destination, source);
destination string
// append source string to the end of the
$OZD\VPDNHVXUHWKHUHLVHQRXJKURRPLQWKHGHVWLQDWLRQZKHQFRS\LQJ
RUFRQFDWHQDWLQJVWULQJV'RQ¦WIRUJHWWRDOORZURRPIRUWKHWHUPLQDWLQJ
QXOO
8VHstrcmp VKRUWIRUVWULQJFRPSDUH WRFRPSDUHWZRVWULQJV<RXFDQVHHWKLVXVHGLQ
5HFLSH
if(strcmp(str, "Arduino") == 0)
// do something if the variable str is equal to "Arduino"
Discussion
7H[W LV UHSUHVHQWHG LQ WKH $UGXLQR HQYLURQPHQW XVLQJ DQ DUUD\ RI FKDUDFWHUV FDOOHG
VWULQJV$VWULQJFRQVLVWVRIDQXPEHURIFKDUDFWHUVIROORZHGE\DQXOO WKHYDOXH 7KH
QXOOLVQRWGLVSOD\HGEXWLWLVQHHGHGWRLQGLFDWHWKHHQGRIWKHVWULQJWRWKHVRIWZDUH
2.6 Using C Character Strings | 31
See Also
6HHRQHRIWKHPDQ\RQOLQH&&UHIHUHQFHSDJHVVXFKDVKWWSZZZFSOXVSOXVFRP
UHIHUHQFHFOLEUDU\FVWULQJDQGKWWSZZZFSSUHIHUHQFHFRPZLNLVWULQJFVWDUW
2.7 Splitting Comma-Separated Text into Groups
Problem
<RXKDYHDVWULQJWKDWFRQWDLQVWZRRUPRUHSLHFHVRIGDWDVHSDUDWHGE\FRPPDV RU
DQ\RWKHUVHSDUDWRU <RXZDQWWRVSOLWWKHVWULQJVRWKDW\RXFDQXVHHDFKLQGLYLGXDO
SDUW
Solution
7KLVVNHWFKSULQWVWKHWH[WIRXQGEHWZHHQHDFKFRPPD
/*
* SplitSplit sketch
* split a comma-separated string
*/
String
int
message= "Peter,Paul,Mary"; // an example string
commaPosition; // the position of the next comma in the string
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.println(message);
// show the source string
do
{
commaPosition = message.indexOf(',');
if(commaPosition != -1)
{
Serial.println( message.substring(0,commaPosition));
message = message.substring(commaPosition+1, message.length());
}
else
{ // here after the last comma is found
if(message.length() > 0)
Serial.println(message); // if there is text after the last comma,
print it
}
}
while(commaPosition >=0);
delay(5000);
}
32 | Chapter 2:ಗMaking the Sketch Do Your Bidding
7KH6HULDO0RQLWRUZLOOGLVSOD\WKHIROORZLQJ
Peter,Paul,Mary
Peter
Paul
Discussion
7KLVVNHWFKXVHVStringIXQFWLRQVWRH[WUDFWWH[WIURPEHWZHHQFRPPDV7KHIROORZLQJ
FRGH
commaPosition = message.indexOf(',');
VHWVWKHYDULDEOHcommaPositionZLWKWKHSRVLWLRQRIWKHILUVWFRPPDLQWKHStringQDPHG
message LWZLOOEHVHWWRLIQRFRPPDLVIRXQG ,IWKHUHLVDFRPPDWKHsubstring
IXQFWLRQLVXVHGWRSULQWWKHWH[WIURPWKHEHJLQQLQJRIWKHVWULQJWRWKHSRVLWLRQRIWKH
FRPPD7KHWH[WWKDWZDVSULQWHGLVUHPRYHGIURPmessageLQWKLVOLQH
message = message.substring(commaPosition+1, message.length());
substringUHWXUQVDVWULQJVWDUWLQJIURPcommaPosition+1 WKHSRVLWLRQMXVWDIWHUWKHILUVW
FRPPD XSWRWKHOHQJWKRIWKHPHVVDJH7KLVUHVXOWVLQWKDWPHVVDJHFRQWDLQLQJRQO\
WKHWH[WIROORZLQJWKHILUVWFRPPD7KLVLVUHSHDWHGXQWLOQRPRUHFRPPDVDUHIRXQG
commaIndexZLOOEHHTXDOWR ,I\RXDUHDQH[SHULHQFHGSURJUDPPHU\RXFDQDOVRXVHWKHORZOHYHOIXQFWLRQVWKDW
DUHSDUWRIWKHVWDQGDUG&OLEUDU\7KHIROORZLQJVNHWFKKDVVLPLODUIXQFWLRQDOLW\WRWKH
SUHFHGLQJRQHXVLQJ$UGXLQRVWULQJV
/*
* SplitSplit sketch
* split a comma-separated string
*/
const int MAX_STRING_LEN = 20; // set this to the largest string you'll process
char stringList[] = "Peter,Paul,Mary"; // an example string
char stringBuffer[MAX_STRING_LEN+1];
output
// a static buffer for computation and
void setup()
{
Serial.begin(9600);
}
void loop()
{
char *str;
char *p;
strncpy(stringBuffer, stringList, MAX_STRING_LEN); // copy source string
Serial.println(stringBuffer);
// show the source string
for( str = strtok_r(stringBuffer, ",", &p);
// split using comma
str;
// loop while str is not null
str = strtok_r(NULL, ",", &p)
// get subsequent tokens
)
2.7 Splitting Comma-Separated Text into Groups | 33
{
}
}
Serial.println(str);
if(strcmp(str, "Paul") == 0)
Serial.println("found Paul");
delay(5000);
7KHFRUHIXQFWLRQDOLW\FRPHVIURPWKHIXQFWLRQQDPHGstrtok_r WKHQDPHRIWKHYHU
VLRQ RI strtok WKDW FRPHV ZLWK WKH $UGXLQR FRPSLOHU 7KH ILUVW WLPH \RX FDOO
strtok_r\RXSDVVLWWKHVWULQJ\RXZDQWWRWRNHQL]H VHSDUDWHLQWRLQGLYLGXDOYDOXHV %XWstrtok_rRYHUZULWHVWKHFKDUDFWHUVLQWKLVVWULQJHDFKWLPHLWILQGVDQHZWRNHQVR
LW¦VEHVWWRSDVVDFRS\RIWKHVWULQJDVVKRZQLQWKLVH[DPSOH(DFKFDOOWKDWIROORZV
XVHVDNULLWRWHOOWKHIXQFWLRQWKDWLWVKRXOGPRYHRQWRWKHQH[WWRNHQ,QWKLVH[DPSOH
HDFKWRNHQLVSULQWHGWRWKHVHULDOSRUWDQGDOVRFRPSDUHGWRDWDUJHWVWULQJ "Paul" ,I \RXU WRNHQV FRQVLVW RQO\ RI QXPEHUV VHH 5HFLSH 7KLV VKRZV KRZ WR H[WUDFW
QXPHULFYDOXHVVHSDUDWHGE\FRPPDVLQDVWUHDPRIVHULDOFKDUDFWHUV
See Also
5HFLSHRQOLQHUHIHUHQFHVWRWKH&&IXQFWLRQVstrtok_rDQGstrcmp
2.8 Converting a Number to a String
Problem
<RXQHHGWRFRQYHUWDQXPEHUWRDVWULQJSHUKDSVWRVKRZWKHQXPEHURQDQ/&'RU
RWKHUGLVSOD\
Solution
7KH StringYDULDEOHZLOOFRQYHUWQXPEHUVWRVWULQJVRIFKDUDFWHUVDXWRPDWLFDOO\<RX
FDQXVHOLWHUDOYDOXHVRUWKHFRQWHQWVRIDYDULDEOH)RUH[DPSOHWKHIROORZLQJFRGH
ZLOOZRUN
String myNumber = 1234;
$VZLOOWKLV
int value = 127
String myReadout = "The reading was ";
myReadout.concat(value);
2UWKLV
int value = 127;
String myReadout = "The reading was ";
myReadout += value;
34 | Chapter 2:ಗMaking the Sketch Do Your Bidding
Discussion
,I\RXDUHFRQYHUWLQJDQXPEHUWRGLVSOD\DVWH[WRQDQ/&'RUVHULDOGHYLFHWKHVLPSOHVW
VROXWLRQLVWRXVHWKHFRQYHUVLRQFDSDELOLW\EXLOWLQWRWKH/&'DQG6HULDOOLEUDULHV VHH
5HFLSH %XWSHUKDSV\RXDUHXVLQJDGHYLFHWKDWGRHVQRWKDYHWKLVEXLOWLQVXSSRUW
VHH&KDSWHU RU\RXZDQWWRPDQLSXODWHWKHQXPEHUDVDVWULQJLQ\RXUVNHWFK
7KH$UGXLQR StringFODVVDXWRPDWLFDOO\FRQYHUWVQXPHULFDOYDOXHVZKHQWKH\DUHDV
VLJQHGWRDStringYDULDEOH<RXFDQFRPELQH FRQFDWHQDWH QXPHULFYDOXHVDWWKHHQG
RIDVWULQJXVLQJWKHconcatIXQFWLRQRUWKHVWULQJ+RSHUDWRU
7KH +RSHUDWRULVXVHGZLWKQXPEHUW\SHVDVZHOODVVWULQJVEXWLWEH
KDYHVGLIIHUHQWO\ZLWKHDFK
7KHIROORZLQJFRGHUHVXOWVLQnumberKDYLQJDYDOXHRI13
int number = 12;
number += 1;
:LWKDStringDVVKRZQKHUH
String textNumber = 12
textNumber += 1;
textNumberLVWKHWH[WVWULQJ"121"
3ULRUWRWKHLQWURGXFWLRQRIWKHStringFODVVLWZDVFRPPRQWRILQG$UGXLQRFRGHXVLQJ
WKHitoaRUltoaIXQFWLRQ7KHQDPHVFRPHIURP£LQWHJHUWR$6&,,¤ itoa DQG£ORQJ
WR$6&,,¤ ltoa 7KHStringYHUVLRQGHVFULEHGHDUOLHULVHDVLHUWRXVHEXWWKHIROORZLQJ
ZLOOKHOSLI\RXZDQWWRXQGHUVWDQGFRGHWKDWXVHVitoaRUltoa
7KHVHIXQFWLRQVWDNHWKUHHSDUDPHWHUVWKHYDOXHWRFRQYHUWWKHEXIIHUWKDWZLOOKROG
WKHRXWSXWVWULQJDQGWKHQXPEHUEDVH IRUDGHFLPDOQXPEHUIRUKH[DQGIRU
ELQDU\ 7KHIROORZLQJVNHWFKLOOXVWUDWHVKRZWRFRQYHUWQXPHULFYDOXHVXVLQJltoa
/*
* NumberToString
* Creates a string from a given number
*/
void setup()
{
Serial.begin(9600);
}
char buffer[12];
// long data type has 11 characters (including the
// minus sign) and a terminating null
2.8 Converting a Number to a String | 35
void loop()
{
long value = 12345;
ltoa(value, buffer, 10);
Serial.print( value);
Serial.print(" has ");
Serial.print(strlen(buffer));
Serial.println(" digits");
value = 123456789;
ltoa(value, buffer, 10);
Serial.print( value);
Serial.print(" has ");
Serial.print(strlen(buffer));
Serial.println(" digits");
delay(1000);
}
<RXUEXIIHUPXVWEHODUJHHQRXJKWRKROGWKHPD[LPXPQXPEHURIFKDUDFWHUVLQWKH
VWULQJ)RUELWLQWHJHUVWKDWLVVHYHQFKDUDFWHUV ILYHGLJLWVDSRVVLEOHPLQXVVLJQ
DQGDWHUPLQDWLQJWKDWDOZD\VVLJQLILHVWKHHQGRIDVWULQJ ELWORQJLQWHJHUVQHHG
FKDUDFWHUEXIIHUV GLJLWVWKHPLQXVVLJQDQGWKHWHUPLQDWLQJ 1RZDUQLQJLV
JLYHQ LI \RX H[FHHG WKH EXIIHU VL]H WKLV LV D EXJ WKDW FDQ FDXVH DOO NLQGV RI VWUDQJH
V\PSWRPVEHFDXVHWKHRYHUIORZZLOOFRUUXSWVRPHRWKHUSDUWRIPHPRU\WKDWPD\EH
XVHGE\\RXUSURJUDP7KHHDVLHVWZD\WRKDQGOHWKLVLVWRDOZD\VXVHDFKDUDFWHU
EXIIHUDQGDOZD\VXVHltoaEHFDXVHWKLVZLOOZRUNRQERWKELWDQGELWYDOXHV
2.9 Converting a String to a Number
Problem
<RXQHHGWRFRQYHUWDVWULQJWRDQXPEHU3HUKDSV\RXKDYHUHFHLYHGDYDOXHDVDVWULQJ
RYHUDFRPPXQLFDWLRQOLQNDQG\RXQHHGWRXVHWKLVDVDQLQWHJHURUIORDWLQJSRLQWYDOXH
Solution
7KHUHDUHDQXPEHURIZD\VWRVROYHWKLV,IWKHVWULQJLVUHFHLYHGDVVHULDOGDWDLWFDQ
EHFRQYHUWHGRQWKHIO\DVHDFKFKDUDFWHULVUHFHLYHG6HH5HFLSHIRUDQH[DPSOHRI
KRZWRGRWKLVXVLQJWKHVHULDOSRUW
$QRWKHUDSSURDFKWRFRQYHUWLQJWH[WVWULQJVUHSUHVHQWLQJQXPEHUVLVWRXVHWKH&ODQ
JXDJHFRQYHUVLRQIXQFWLRQFDOOHGatoi IRUintYDULDEOHV RUatol IRUlongYDULDEOHV 7KLVFRGHIUDJPHQWWHUPLQDWHVWKHLQFRPLQJGLJLWVRQDQ\FKDUDFWHUWKDWLVQRWDGLJLW
RULIWKHEXIIHULVIXOO int blinkRate;
char strValue[6];
int index = 0;
// blink rate stored in this variable
// must be big enough to hold all the digits and the
// 0 that terminates the string
// the index into the array storing the received digits
36 | Chapter 2:ಗMaking the Sketch Do Your Bidding
void loop()
{
if( Serial.available())
{
char ch = Serial.read();
if(index < 5 && ch >= '0' && ch <= '9'){
strValue[index++] = ch; // add the ASCII character to the string;
}
else
{
// here when buffer full or on the first non digit
strValue[index] = 0;
// terminate the string with a 0
blinkRate = atoi(strValue); // use atoi to convert the string to an int
index = 0;
}
}
blink();
}
Discussion
7KHREVFXUHO\QDPHG atoi IRU$6&,,WR int DQG atol IRU$6&,,WR long IXQFWLRQV
FRQYHUWDVWULQJLQWRLQWHJHUVRUORQJLQWHJHUV7RXVHWKHP\RXKDYHWRUHFHLYHDQG
VWRUHWKHHQWLUHVWULQJLQDFKDUDFWHUDUUD\EHIRUH\RXFDQFDOOWKHFRQYHUVLRQIXQFWLRQ
7KHFRGHFUHDWHVDFKDUDFWHUDUUD\QDPHGstrValueWKDWFDQKROGXSWRILYHGLJLWV LW¦V
GHFODUHGDVchar strValue[6]EHFDXVHWKHUHPXVWEHURRPIRUWKHWHUPLQDWLQJQXOO ,W
ILOOVWKLVDUUD\ZLWKGLJLWVIURP Serial.readXQWLOLWJHWVWKHILUVWFKDUDFWHUWKDWLVQRWD
YDOLGGLJLW7KHDUUD\LVWHUPLQDWHGZLWKDQXOODQGWKHatoiIXQFWLRQLVFDOOHGWRFRQYHUW
WKHFKDUDFWHUDUUD\LQWRWKHYDULDEOHblinkRate
$ IXQFWLRQ FDOOHG blink LV FDOOHG WKDW XVHV WKH YDOXH VWRUHG LQ blinkRate 7KH blink
IXQFWLRQLVVKRZQLQ5HFLSH
$VPHQWLRQHGLQWKHZDUQLQJLQ5HFLSH\RXPXVWEHFDUHIXOQRWWRH[FHHGWKHERXQG
RIWKHDUUD\,I\RXDUHQRWVXUHKRZWRGRWKDWUHDGWKURXJK5HFLSH
7KLVH[DPSOHEXLOGVDFKDUDFWHUDUUD\UDWKHUWKDQXVLQJWKHStringFODVV$WWKHWLPH
RIWKLVZULWLQJWKH$UGXLQR6WULQJOLEUDU\GLGQRWKDYHWKHIXQFWLRQDOLW\WRFRQYHUWD
VWULQJRIQXPEHUVLQWRDQXPHULFYDOXH
See Also
6HHRQHRIWKHPDQ\RQOLQH&&UHIHUHQFHSDJHVVXFKDVKWWSZZZFSOXVSOXVFRP
UHIHUHQFHFOLEUDU\FVWGOLEDWRLRUKWWSZZZFSSUHIHUHQFHFRPZLNLVWULQJFDWRL
2.9 Converting a String to a Number | 37
Download from Wow! eBook <www.wowebook.com>
2.10 Structuring Your Code into Functional Blocks
Problem
<RXZDQWWRNQRZKRZWRDGGIXQFWLRQVWRDVNHWFKDQGWKHFRUUHFWDPRXQWRIIXQF
WLRQDOLW\WRJRLQWR\RXUIXQFWLRQV<RXDOVRZDQWWRXQGHUVWDQGKRZWRSODQWKHRYHUDOO
VWUXFWXUHRIWKHVNHWFK
Solution
)XQFWLRQVDUHXVHGWRRUJDQL]HWKHDFWLRQVSHUIRUPHGE\\RXUVNHWFKLQWRIXQFWLRQDO
EORFNV)XQFWLRQVSDFNDJHIXQFWLRQDOLW\LQWRZHOOGHILQHGLQSXWV LQIRUPDWLRQJLYHQWR
DIXQFWLRQ DQGRXWSXWV LQIRUPDWLRQSURYLGHGE\DIXQFWLRQ WKDWPDNHLWHDVLHUWR
VWUXFWXUHPDLQWDLQDQGUHXVH\RXUFRGH<RXDUHDOUHDG\IDPLOLDUZLWKWKHWZRIXQF
WLRQV WKDW DUH LQ HYHU\ $UGXLQR VNHWFK setup DQG loop <RX FUHDWH D IXQFWLRQ E\
GHFODULQJLWVUHWXUQW\SH WKHLQIRUPDWLRQLWSURYLGHV LWVQDPHDQGDQ\RSWLRQDOSD
UDPHWHUV YDOXHV WKDWWKHIXQFWLRQZLOOUHFHLYHZKHQLWLVFDOOHG+HUHLVDVLPSOHIXQF
WLRQWKDWMXVWEOLQNVDQ/(',WKDVQRSDUDPHWHUVDQGGRHVQ¦WUHWXUQDQ\WKLQJ WKH
voidSUHFHGLQJWKHIXQFWLRQLQGLFDWHVWKDWQRWKLQJZLOOEHUHWXUQHG // blink an LED once
void blink1()
{
digitalWrite(13,HIGH);
delay(500);
digitalWrite(13,LOW);
delay(500);
}
// turn the LED on
// wait 500 milliseconds
// turn the LED off
// wait 500 milliseconds
7KHIROORZLQJYHUVLRQKDVDSDUDPHWHU WKHLQWHJHUQDPHGcount WKDWGHWHUPLQHVKRZ
PDQ\WLPHVWKH/('ZLOOIODVK
// blink an LED the number of times given in the count parameter
void blink2(int count)
{
while(count > 0 ) // repeat until count is no longer greater than zero
{
digitalWrite(13,HIGH);
delay(500);
digitalWrite(13,LOW);
delay(500);
count = count -1; // decrement count
}
}
7KDWYHUVLRQFKHFNVWRVHHLIWKHYDOXHRIcountLV0,IQRWLWEOLQNVWKH/('DQGWKHQ
UHGXFHVWKHYDOXHRIcountE\RQH7KLVZLOOEHUHSHDWHGXQWLOcountLVQRORQJHUJUHDWHU
WKDQ0
38 | Chapter 2:ಗMaking the Sketch Do Your Bidding
$SDUDPHWHULVVRPHWLPHVUHIHUUHGWRDVDQDUJXPHQWLQVRPHGRFXPHQ
WDWLRQ)RUSUDFWLFDOSXUSRVHV\RXFDQWUHDWWKHVHWHUPVDVPHDQLQJWKH
VDPHWKLQJ
+HUHLVDQH[DPSOHVNHWFKWKDWWDNHVDSDUDPHWHUDQGUHWXUQVDYDOXH7KHSDUDPHWHU
GHWHUPLQHVWKH/('RQDQGRIIWLPHV LQPLOOLVHFRQGV 7KHIXQFWLRQFRQWLQXHVWRIODVK
WKH/('XQWLODEXWWRQLVSUHVVHGDQGWKHQXPEHURIWLPHVWKH/('IODVKHGLVUHWXUQHG
IURPWKHIXQFWLRQ
/*
blink3 sketch
demonstrates calling a function with a parameter and returning a value
uses the same wiring as the pull-up sketch from Recipe 5.2
The LED flashes when the program starts
and stops when a switch connected to pin 2 is pressed
the program prints the number of times the LED flashes.
*/
const int ledPin = 13;
const int inputPin = 2;
// output pin for the LED
// input pin for the switch
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(inputPin, INPUT);
digitalWrite(inputPin,HIGH); // use internal pull-up resistor (Recipe 5.2)
Serial.begin(9600);
}
void loop(){
Serial.println("Press and hold the switch to stop blinking");
int count = blink3(250); // blink the LED 250ms on and 250ms off
Serial.print("The number of times the switch blinked was ");
Serial.println(count);
}
// blink an LED using the given delay period
// return the number of times the LED flashed
int blink3(int period)
{
int result = 0;
int switchVal = HIGH; //with pull-ups, this will be high when switch is up
while(switchVal == HIGH) // repeat this loop until switch is pressed
// (it will go low when pressed)
{
digitalWrite(13,HIGH);
delay(period);
digitalWrite(13,LOW);
delay(period);
result = result + 1; // increment the count
switchVal = digitalRead(inputPin); // read input value
}
2.10 Structuring Your Code into Functional Blocks | 39
}
// here when switchVal is no longer HIGH because the switch is pressed
return result; // this value will be returned
Discussion
7KHFRGHLQWKLVUHFLSH¦V6ROXWLRQLOOXVWUDWHVWKHWKUHHIRUPVRIIXQFWLRQFDOOWKDW\RX
ZLOOFRPHDFURVVblink1KDVQRSDUDPHWHUDQGQRUHWXUQYDOXH,WVIRUPLV
void blink1()
{
// implementation code goes here...
}
blink2WDNHVDVLQJOHSDUDPHWHUEXWGRHVQRWUHWXUQDYDOXH
void blink2(int count)
{
// implementation code goes here...
}
blink3KDVDVLQJOHSDUDPHWHUDQGUHWXUQVDYDOXH
int blink3(int period)
{
// implementation code goes here...
}
7KHGDWDW\SHWKDWSUHFHGHVWKHIXQFWLRQQDPHLQGLFDWHVWKHUHWXUQW\SH RUQRUHWXUQ
W\SHLIvoid :KHQGHFODULQJWKHIXQFWLRQ ZULWLQJRXWWKHFRGHWKDWGHILQHVWKHIXQFWLRQ
DQGLWVDFWLRQ \RXGRQRWSXWDVHPLFRORQIROORZLQJWKHSDUHQWKHVLVDWWKHHQG:KHQ
\RXXVH FDOO WKHIXQFWLRQ\RXGRQHHGDVHPLFRORQDWWKHHQG
0RVW RI WKH IXQFWLRQV \RX FRPH DFURVV ZLOO EH VRPH YDULDWLRQ RQ WKHVH IRUPV )RU
H[DPSOHKHUHLVDIXQFWLRQWKDWWDNHVDSDUDPHWHUDQGUHWXUQVDYDOXH
int sensorPercent(int pin)
{
int percent;
}
val = analogRead(pin); // read the sensor (ranges from 0 to 1023)
percent = map(val,0,1023,0,100); // percent will range from 0 to 100.
return percent;
7KH IXQFWLRQ QDPH LV sensorPercent ,W LV JLYHQ DQ DQDORJ SLQ QXPEHU WR UHDG DQG
UHWXUQVWKHYDOXHDVDSHUFHQW VHH5HFLSHIRUPRUHRQ analogReadDQG map 7KH
intLQIURQWRIWKHGHFODUDWLRQWHOOVWKHFRPSLOHU DQGUHPLQGVWKHSURJUDPPHU WKDW
WKHIXQFWLRQZLOOUHWXUQDQLQWHJHU:KHQFUHDWLQJIXQFWLRQVFKRRVHWKHUHWXUQW\SH
DSSURSULDWHWRWKHDFWLRQWKHIXQFWLRQSHUIRUPV7KLVIXQFWLRQUHWXUQVDQLQWHJHUYDOXH
IURPWRVRDUHWXUQW\SHRIintLVDSSURSULDWH
40 | Chapter 2:ಗMaking the Sketch Do Your Bidding
,WLVUHFRPPHQGHGWKDW\RXJLYH\RXUIXQFWLRQVPHDQLQJIXOQDPHVDQG
LWLVDFRPPRQSUDFWLFHWRFRPELQHZRUGVE\FDSLWDOL]LQJWKHILUVWOHWWHU
RIHDFKZRUGH[FHSWIRUWKHILUVWZRUG8VHZKDWHYHUVW\OH\RXSUHIHU
EXWLWKHOSVRWKHUVZKRUHDG\RXUFRGHLI\RXNHHS\RXUQDPLQJVW\OH
FRQVLVWHQW
sensorPercentKDVDSDUDPHWHUFDOOHGpin ZKHQWKHIXQFWLRQLVFDOOHGpinLVJLYHQWKH
YDOXHWKDWLVSDVVHGWRWKHIXQFWLRQ 7KHERG\RIWKHIXQFWLRQ WKHFRGHZLWKLQWKHEUDFNHWV SHUIRUPVWKHDFWLRQ\RXZDQW¢
KHUH LW UHDGV D YDOXH IURP DQ DQDORJ LQSXW SLQ DQG PDSV LW WR D SHUFHQWDJH ,Q WKH
SUHFHGLQJH[DPSOHWKHSHUFHQWDJHLVWHPSRUDULO\KHOGLQDYDULDEOHFDOOHGpercent7KH
IROORZLQJVWDWHPHQWFDXVHVWKHYDOXHKHOGLQWKHWHPSRUDU\YDULDEOH percentWREHUH
WXUQHGWRWKHFDOOLQJDSSOLFDWLRQ
return percent;
7KHVDPHIXQFWLRQDOLW\FDQEHDFKLHYHGZLWKRXWXVLQJDWHPSRUDU\YDULDEOH
int sensorPercent(int pin)
{
val = analogRead(pin); // read the sensor (ranges from 0 to 1023)
return map(val,0,1023,0,100); // percent will ranges from 0 to 100.
}
+HUHLVKRZWKHIXQFWLRQFDQEHFDOOHG
// print the percent value of 6 analog pins
for(int sensorPin = 0; sensorPin < 6; sensorPin++)
{
Serial.print("Percent of sensor on pin ");
Serial.print(sensorPin);
Serial.print(" is ");
int val = sensorPercent(sensorPin);
Serial.print(val);
}
See Also
7KH$UGXLQRIXQFWLRQUHIHUHQFHSDJHKWWSZZZDUGXLQRFFHQ5HIHUHQFH)XQFWLRQ'H
FODUDWLRQ
2.11 Returning More Than One Value from a Function
Problem
<RXZDQWWRUHWXUQWZRRUPRUHYDOXHVIURPDIXQFWLRQ5HFLSHSURYLGHGH[DPSOHV
IRUWKHPRVWFRPPRQIRUPRIDIXQFWLRQRQHWKDWUHWXUQVMXVWRQHYDOXHRUQRQHDWDOO
%XWVRPHWLPHV\RXQHHGWRPRGLI\RUUHWXUQPRUHWKDQRQHYDOXH
2.11 Returning More Than One Value from a Function | 41
Download from Wow! eBook <www.wowebook.com>
Solution
7KHUHDUHYDULRXVZD\VWRVROYHWKLV7KHHDVLHVWWRXQGHUVWDQGLVWRKDYHWKHIXQFWLRQ
FKDQJHVRPHJOREDOYDULDEOHVDQGQRWDFWXDOO\UHWXUQDQ\WKLQJIURPWKHIXQFWLRQ
/*
swap sketch
demonstrates changing two values using global variables
*/
int x; // x and y are global variables
int y;
void setup() {
Serial.begin(9600);
}
void loop(){
x = random(10); // pick some random numbers
y = random(10);
Serial.print("The value of x and y before swapping are: ");
Serial.print(x); Serial.print(","); Serial.println(y);
swap();
Serial.print("The value of x and y after swapping are: ");
Serial.print(x); Serial.print(","); Serial.println(y);Serial.println();
delay(1000);
}
// swap the two global values
void swap()
{
int temp;
temp = x;
x = y;
y = temp;
}
7KH swapIXQFWLRQFKDQJHVWZRYDOXHVE\XVLQJJOREDOYDULDEOHV*OREDOYDULDEOHVDUH
HDV\WRXQGHUVWDQG JOREDOYDULDEOHVDUHYDOXHVWKDWDUHDFFHVVLEOHHYHU\ZKHUHDQGDQ\
WKLQJFDQFKDQJHWKHP EXWWKH\DUHDYRLGHGE\H[SHULHQFHGSURJUDPPHUVEHFDXVHLW¦V
HDV\WRLQDGYHUWHQWO\PRGLI\WKHYDOXHRIDYDULDEOHRUWRKDYHDIXQFWLRQVWRSZRUNLQJ
EHFDXVH\RXFKDQJHGWKHQDPHRUW\SHRIDJOREDOYDULDEOHHOVHZKHUHLQWKHVNHWFK
$VDIHUDQGPRUHHOHJDQWVROXWLRQLVWRSDVVUHIHUHQFHVWRWKHYDOXHV\RXZDQWWRFKDQJH
DQGOHWWKHIXQFWLRQXVHWKHUHIHUHQFHVWRPRGLI\WKHYDOXHV7KLVLVGRQHDVIROORZV
/*
functionReferences sketch
demonstrates returning more than one value by passing references
*/
42 | Chapter 2:ಗMaking the Sketch Do Your Bidding
void swap(int &value1, int &value2); // functions with references must be
declared before use
void setup() {
Serial.begin(9600);
}
void loop(){
int x = random(10); // pick some random numbers
int y = random(10);
Serial.print("The value of x and y before swapping are: ");
Serial.print(x); Serial.print(","); Serial.println(y);
swap(x,y);
Serial.print("The value of x and y after swapping are: ");
Serial.print(x); Serial.print(","); Serial.println(y);Serial.println();
delay(1000);
}
// swap the two given values
void swap(int &value1, int &value2)
{
int temp;
temp = value1;
value1 = value2;
value2 = temp;
}
Discussion
7KH swap IXQFWLRQ LV VLPLODU WR WKH IXQFWLRQV ZLWK SDUDPHWHUV GHVFULEHG LQ 5HF
LSHEXWWKHDPSHUVDQG & V\PEROLQGLFDWHVWKDWWKHSDUDPHWHUVDUHUHIHUHQFHV
7KLV PHDQV FKDQJHV LQ YDOXHV ZLWKLQ WKH IXQFWLRQ ZLOO DOVR FKDQJH WKH YDOXH RI WKH
YDULDEOHWKDWLVJLYHQZKHQWKHIXQFWLRQLVFDOOHG<RXFDQVHHKRZWKLVZRUNVE\ILUVW
UXQQLQJWKHFRGHLQWKLVUHFLSH¦V6ROXWLRQDQGYHULI\LQJWKDWWKHSDUDPHWHUVDUHVZDS
SHG7KHQPRGLI\WKHFRGHE\UHPRYLQJDOOIRXUDPSHUVDQGV WKHWZRLQWKHGHFODUDWLRQ
DWWKHWRSDQGWKHWZRLQWKHGHILQLWLRQDWWKHERWWRP 7KHWZRFKDQJHGOLQHVVKRXOGORRNOLNHWKLV
void swap(int value1, int value2); // functions with references must be declared
before use
...
void swap(int value1, int value2)
5XQQLQJWKHFRGHVKRZVWKDWWKHYDOXHVDUHQRWVZDSSHG¢FKDQJHVPDGHZLWKLQWKH
IXQFWLRQDUHORFDOWRWKHIXQFWLRQDQGDUHORVWZKHQWKHIXQFWLRQUHWXUQV
2.11 Returning More Than One Value from a Function | 43
$IXQFWLRQGHFODUDWLRQLVDSURWRW\SH¢DVSHFLILFDWLRQRIWKHQDPHWKH
W\SHVRIYDOXHVWKDWPD\EHSDVVHGWRWKHIXQFWLRQDQGWKHIXQFWLRQ¦V
UHWXUQW\SH7KH$UGXLQREXLOGSURFHVVXVXDOO\FUHDWHVWKHGHFODUDWLRQV
IRU\RXXQGHUWKHFRYHUV%XWZKHQ\RXXVHQRQVWDQGDUG IRU$UGXLQR
V\QWD[WKHEXLOGSURFHVVZLOOQRWFUHDWHWKHGHFODUDWLRQDQG\RXQHHG
WRDGGLWWR\RXUFRGH\RXUVHOIDVGRQHKHUHZLWKWKHOLQHMXVWEHIRUH
setup
$IXQFWLRQGHILQLWLRQLVWKHIXQFWLRQKHDGHUDQGWKHIXQFWLRQERG\7KH
IXQFWLRQKHDGHULVVLPLODUWRWKHGHFODUDWLRQH[FHSWLWGRHVQRWKDYHD
VHPLFRORQDWWKHHQG7KHIXQFWLRQERG\LVWKHFRGHZLWKLQWKHEUDFNHWV
WKDWLVUXQWRSHUIRUPVRPHDFWLRQZKHQWKHIXQFWLRQLVFDOOHG
2.12 Taking Actions Based on Conditions
Problem
<RXZDQWWRH[HFXWHDEORFNRIFRGHRQO\LIDSDUWLFXODUFRQGLWLRQLVWUXH)RUH[DPSOH
\RXPD\ZDQWWROLJKWDQ/('LIDVZLWFKLVSUHVVHGRULIDQDQDORJYDOXHLVJUHDWHUWKDQ
VRPHWKUHVKROG
Solution
7KHIROORZLQJFRGHXVHVWKHZLULQJVKRZQLQ5HFLSH
/*
*/
Pushbutton sketch
a switch connected to pin 2 lights the LED on pin 13
const int ledPin = 13;
const int inputPin = 2;
// choose the pin for the LED
// choose the input pin (for a pushbutton)
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(inputPin, INPUT);
}
// declare LED pin as output
// declare pushbutton pin as input
void loop(){
int val = digitalRead(inputPin);
if (val == HIGH)
{
digitalWrite(ledPin, HIGH);
}
}
// read input value
// check if the input is HIGH
// turn LED on if switch is pressed
Discussion
7KHifVWDWHPHQWLVXVHGWRWHVWWKHYDOXHRIdigitalRead$QifVWDWHPHQWPXVWKDYHD
WHVWZLWKLQWKHSDUHQWKHVHVWKDWFDQRQO\EHWUXHRUIDOVH,QWKHH[DPSOHLQWKLVUHFLSH¦V
44 | Chapter 2:ಗMaking the Sketch Do Your Bidding
6ROXWLRQLW¦Vval == HIGHDQGWKHFRGHEORFNIROORZLQJWKHifVWDWHPHQWLVRQO\H[H
FXWHGLIWKHH[SUHVVLRQLVWUXH$FRGHEORFNFRQVLVWVRIDOOFRGHZLWKLQWKHEUDFNHWV RU
LI\RXGRQ¦WXVHEUDFNHWVWKHEORFNLVMXVWWKHQH[WH[HFXWDEOHVWDWHPHQWWHUPLQDWHGE\
DVHPLFRORQ ,I \RX ZDQW WR GR RQH WKLQJ LI D VWDWHPHQW LV WUXH DQG DQRWKHU LI LW LV IDOVH XVH WKH
if...elseVWDWHPHQW
/*
*/
Pushbutton sketch
a switch connected to pin 2 lights the LED on pin 13
const int ledPin = 13;
const int inputPin = 2;
// choose the pin for the LED
// choose the input pin (for a pushbutton)
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(inputPin, INPUT);
}
// declare LED pin as output
// declare pushbutton pin as input
void loop(){
int val = digitalRead(inputPin); // read input value
if (val == HIGH)
// check if the input is HIGH
{
// do this if val is HIGH
digitalWrite(ledPin, HIGH);
// turn LED on if switch is pressed
}
else
{
// else do this if val is not HIGH
digitalWrite(ledPin, LOW);
// turn LED off
}
}
See Also
6HHWKHGLVFXVVLRQRQ%RROHDQW\SHVLQ5HFLSH
2.13 Repeating a Sequence of Statements
Problem
<RXZDQWWRUHSHDWDEORFNRIVWDWHPHQWVZKLOHDQH[SUHVVLRQLVWUXH
2.13 Repeating a Sequence of Statements | 45
Solution
$whileORRSUHSHDWVRQHRUPRUHLQVWUXFWLRQVZKLOHDQH[SUHVVLRQLVWUXH
while(analogRead(sensorPin) > 100)
{
flashLED();
// call a function to turn an LED on and off
}
7KLVFRGHZLOOH[HFXWHWKHVWDWHPHQWVLQWKHEORFNZLWKLQWKHEUDFNHWV {}ZKLOHWKH
YDOXHIURP analogReadLVJUHDWHUWKDQ7KLVFRXOGEHXVHGWRIODVKDQ/('DVD
YLVLEOHZDUQLQJWKDWVRPHYDOXHH[FHHGHGDWKUHVKROG7KH/('LVRIIZKHQWKHVHQVRU
YDOXHLVRUOHVVLWIODVKHVFRQWLQXRXVO\ZKHQWKHYDOXHLVJUHDWHUWKDQ
7KH {}V\PEROVWKDWGHILQHDEORFNRIFRGHDUHJLYHQYDULRXVQDPHV
LQFOXGLQJEUDFNHWVFXUO\EUDFHVDQGEUDFHV7KLVERRNUHIHUVWRWKHP
DVEUDFNHWV
Discussion
%UDFNHWVGHILQHWKHH[WHQWRIWKHFRGHEORFNWREHH[HFXWHGLQDORRS,IEUDFNHWVDUH
QRWXVHGRQO\WKHILUVWOLQHRIFRGHZLOOEHUHSHDWHGLQWKHORRS
while(analogRead(sensorPin) > 100)
flashLED();
// line immediately following the loop expression is executed
Serial.print(analogRead(sensorPin)); // this is not executed until after
// the while loop finishes!!!
/RRSVZLWKRXWEUDFNHWVFDQEHKDYHXQH[SHFWHGO\LI\RXKDYHPRUHWKDQ
RQHOLQHRIFRGH
7KHdo...whileORRSLVVLPLODUWRWKHwhileORRSEXWWKHLQVWUXFWLRQVLQWKHFRGHEORFN
DUHH[HFXWHGEHIRUHWKHFRQGLWLRQLVFKHFNHG8VHWKLVIRUPZKHQ\RXPXVWKDYHWKH
FRGHH[HFXWHGDWOHDVWRQFHHYHQLIWKHH[SUHVVLRQLVIDOVH
do
{
flashLED(); // call a function to turn an LED on and off
}
while (analogRead(sensorPin) > 100);
7KHSUHFHGLQJFRGHZLOOIODVKWKH/('DWOHDVWRQFHDQGZLOONHHSIODVKLQJDVORQJDV
WKHYDOXHUHDGIURPDVHQVRULVJUHDWHUWKDQ,IWKHYDOXHLVQRWJUHDWHUWKDQWKH
/('ZLOORQO\IODVKRQFH7KLVFRGHFRXOGEHXVHGLQDEDWWHU\FKDUJLQJFLUFXLWLILW
ZHUHFDOOHGRQFHHYHU\VHFRQGVRUVRDVLQJOHIODVKVKRZVWKDWWKHFLUFXLWLVDFWLYH
ZKHUHDVFRQWLQXRXVIODVKLQJLQGLFDWHVWKHEDWWHU\LVFKDUJHG
46 | Chapter 2:ಗMaking the Sketch Do Your Bidding
See Also
&KDSWHUVDQG
2.14 Repeating Statements with a Counter
Problem
<RXZDQWWRUHSHDWRQHRUPRUHVWDWHPHQWVDFHUWDLQQXPEHURIWLPHV7KHforORRSLV
VLPLODU WR WKH while ORRS EXW \RX KDYH PRUH FRQWURO RYHU WKH VWDUWLQJ DQG HQGLQJ
FRQGLWLRQV
Solution
7KLVVNHWFKFRXQWVIURP]HURWRIRXUE\SULQWLQJWKHYDOXHRIWKHYDULDEOHiLQDforORRS
/*
*/
ForLoop sketch
demonstrates for loop
void setup() {
Serial.begin(9600);}
void loop(){
Serial.println("for(int i=0; i < 4; i++)");
for(int i=0; i < 4; i++)
{
Serial.println(i);
}
}
7KHRXWSXWIURPWKLVLVDVIROORZV
for(int i=0; i < 4; i++)
0
1
2
3
Discussion
$forORRSFRQVLVWVRIWKUHHSDUWVLQLWLDOL]DWLRQFRQGLWLRQDOWHVWDQGLWHUDWLRQ DVWDWH
PHQWWKDWLVH[HFXWHGDWWKHHQGRIHYHU\SDVVWKURXJKWKHORRS (DFKSDUWLVVHSDUDWHG
E\DVHPLFRORQ,QWKHFRGHLQWKLVUHFLSH¦V6ROXWLRQ int i=0;LQLWLDOL]HVWKHYDULDEOH
iWR0i < 4;WHVWVWKHYDULDEOHWRVHHLILW¦VOHVVWKDQDQGi++LQFUHPHQWVi
2.14 Repeating Statements with a Counter | 47
$forORRSFDQXVHDQH[LVWLQJYDULDEOHRULWFDQFUHDWHDYDULDEOHIRUH[FOXVLYHXVHLQ
WKHORRS7KLVYHUVLRQXVHVWKHYDOXHRIWKHYDULDEOHjFUHDWHGHDUOLHULQWKHVNHWFK
int j;
Serial.println("for(j=0; j < 4; j++ )");
for(j=0; j < 4; j++ )
{
Serial.println(j);
}
7KLVLVDOPRVWWKHVDPHDVWKHHDUOLHUH[DPSOHEXWLWGRHVQRWKDYHWKHintNH\ZRUGLQ
WKHLQLWLDOL]DWLRQSDUWEHFDXVHWKHYDULDEOH jZDVDOUHDG\GHILQHG7KHRXWSXWRIWKLV
YHUVLRQLVVLPLODUWRWKHRXWSXWRIWKHHDUOLHUYHUVLRQ
for(j=0; i < 4; i++)
0
1
2
3
<RXFDQOHDYHRXWWKHLQLWLDOL]DWLRQSDUWFRPSOHWHO\LI\RXZDQWWKHORRSWRXVHWKHYDOXH
RIDYDULDEOHGHILQHGHDUOLHU7KLVFRGHVWDUWVWKHORRSZLWKjHTXDOWR
int j = 1;
Serial.println("for(
for( ; j < 4; j++ )
{
Serial.println(j);
}
; j < 4; j++ )");
7KHSUHFHGLQJFRGHSULQWVWKHIROORZLQJ
for(
1
2
3
; j < 4; j++)
<RXFRQWUROZKHQWKHORRSVWRSVLQWKHFRQGLWLRQDOWHVW7KHSUHYLRXVH[DPSOHVWHVWLI
WKHORRSYDULDEOHLVOHVVWKDQDQGZLOOWHUPLQDWHZKHQWKHFRQGLWLRQLVQRORQJHUWUXH
,I\RXUORRSYDULDEOHVWDUWVDWDQG\RXZDQWLWWRUHSHDWIRXUWLPHV
\RXUFRQGLWLRQDOVWDWHPHQWVKRXOGWHVWIRUDYDOXHOHVVWKDQ7KHORRS
UHSHDWVZKLOHWKHFRQGLWLRQLVWUXHDQGWKHUHDUHIRXUYDOXHVWKDWDUHOHVV
WKDQZLWKDORRSVWDUWLQJDW
7KHIROORZLQJFRGHWHVWVLIWKHYDOXHRIWKHORRSYDULDEOHLVOHVVWKDQRUHTXDOWR,W
ZLOOSULQWWKHGLJLWVIURPWR
Serial.println("for(int i=0; i <= 4; i++)");
for(int i=0; i <= 4; i++)
{
48 | Chapter 2:ಗMaking the Sketch Do Your Bidding
}
Serial.println(i);
7KHWKLUGSDUWRID forORRSLVWKHLWHUDWRUVWDWHPHQWWKDWJHWVH[HFXWHGDWWKHHQGRI
HDFKSDVVWKURXJKWKHORRS7KLVFDQEHDQ\YDOLG&&VWDWHPHQW7KHIROORZLQJ
LQFUHDVHVWKHYDOXHRIiE\WZRRQHDFKSDVV
Serial.println("for(int i=0; i < 4; i+= 2)");
for(int i=0; i < 4; i+=2)
{
Serial.println(i);
}
7KDWH[SUHVVLRQRQO\SULQWVWKHYDOXHVDQG
7KHLWHUDWRUH[SUHVVLRQFDQEHXVHGWRFDXVHWKHORRSWRFRXQWIURPKLJKWRORZLQWKLV
FDVHIURPWR
Serial.println("for(int i=3; i > = 0 ; i--)");
for(int i=3; i > = 0 ; i--)
{
Serial.println(i);
}
/LNHWKHRWKHUSDUWVRIDforORRSWKHLWHUDWRUH[SUHVVLRQFDQEHOHIWEODQN \RXPXVW
DOZD\VKDYHWKHWZRVHPLFRORQVVHSDUDWLQJWKHWKUHHSDUWVHYHQLIWKH\DUHEODQN 7KLVYHUVLRQRQO\LQFUHPHQWViZKHQDQLQSXWSLQLVKLJK7KHforORRSGRHVQRWFKDQJH
WKHYDOXHRIiLWLVRQO\FKDQJHGE\WKHifVWDWHPHQWDIWHUSerial.print
Serial.println("for(int i=0; i < 4; )");
for(int i=0; i < 4; )
{
Serial.println(i);
if(digitalRead(inPin) == HIGH);
i++; // only increment the value if the input is high
}
See Also
$UGXLQRUHIHUHQFHIRUWKHforVWDWHPHQWKWWSZZZDUGXLQRFFHQ5HIHUHQFH)RU
2.15 Breaking Out of Loops
Problem
<RXZDQWWRWHUPLQDWHDORRSHDUO\EDVHGRQVRPHFRQGLWLRQ\RXDUHWHVWLQJ
Solution
8VHWKHIROORZLQJFRGH
while(analogRead(sensorPin) > 100)
{
2.15 Breaking Out of Loops | 49
}
if(digitalRead(switchPin) == HIGH)
{
break;
//exit the loop if the switch is pressed
}
flashLED();
// call a function to turn an LED on and off
Discussion
7KLVFRGHLVVLPLODUWRWKHRQHXVLQJwhileORRSVEXWLWXVHVWKHbreakVWDWHPHQWWRH[LW
WKHORRSLIDGLJLWDOSLQJRHVKLJK)RUH[DPSOHLIDVZLWFKLVFRQQHFWHGRQWKHSLQDV
VKRZQLQ5HFLSHWKHORRSZLOOEHH[LWHGDQGWKH/('ZLOOVWRSIODVKLQJHYHQLIWKH
FRQGLWLRQLQWKHwhileORRSLVWUXH
See Also
$UGXLQRUHIHUHQFHIRUWKHbreakVWDWHPHQWKWWSZZZDUGXLQRFFHQ5HIHUHQFH%UHDN
2.16 Taking a Variety of Actions Based on a Single Variable
Problem
<RXQHHGWRGRGLIIHUHQWWKLQJVGHSHQGLQJRQVRPHYDOXH<RXFRXOGXVHPXOWLSOH if
DQGelse ifVWDWHPHQWVEXWWKHFRGHVRRQJHWVFRPSOH[DQGGLIILFXOWWRXQGHUVWDQGRU
PRGLI\$GGLWLRQDOO\\RXPD\ZDQWWRWHVWIRUDUDQJHRIYDOXHV
Solution
7KHswitchVWDWHPHQWSURYLGHVIRUVHOHFWLRQRIDQXPEHURIDOWHUQDWLYHV,WLVIXQFWLRQ
DOO\VLPLODUWRPXOWLSOHifelse ifVWDWHPHQWVEXWLVPRUHFRQFLVH
/*
* SwitchCase sketch
* example showing switch statement by switching on chars from the serial port
*
* sending the character 1 blinks the LED once, sending 2 blinks twice
* sending + turns the LED on, sending - turns it off
* any other character prints a message to the Serial Monitor
*/
const int ledPin = 13; // the pin the LED is connected to
void setup()
{
Serial.begin(9600); // Initialize serial port to send and receive at 9600 baud
pinMode(13, OUTPUT);
}
void loop()
{
if ( Serial.available()) // Check to see if at least one character is available
{
50 | Chapter 2:ಗMaking the Sketch Do Your Bidding
char ch = Serial.read();
switch(ch)
{
case '1':
blink();
break;
case '2':
blink();
blink();
break;
case '+':
digitalWrite(ledPin,HIGH);
break;
case '-':
digitalWrite(ledPin,LOW);
break;
default :
Serial.print(ch);
Serial.println(" was received but not expected");
break;
}
}
}
void blink()
{
digitalWrite(ledPin,HIGH);
delay(500);
digitalWrite(ledPin,LOW);
delay(500);
}
Discussion
7KH switch VWDWHPHQW HYDOXDWHV WKH YDULDEOH ch UHFHLYHG IURP WKH VHULDO SRUW DQG
EUDQFKHVWRWKHODEHOWKDWPDWFKHVLWVYDOXH7KHODEHOVPXVWEHQXPHULFFRQVWDQWV \RX
FDQXVHVWULQJVLQDcaseVWDWHPHQW DQGQRWZRODEHOVFDQKDYHWKHVDPHYDOXH,I\RX
GRQ¦W KDYH D break VWDWHPHQW IROORZLQJ HDFK H[SUHVVLRQ WKH H[HFXWLRQ ZLOO IDOO
WKURXJKLQWRWKHVWDWHPHQW
case '1':
blink();
case '2':
blink();
blink();
break;
// no break statement before the next label
// case '1' will continue here
// break statement will exit the switch expression
,IWKHbreakVWDWHPHQWDWWKHHQGRIcase '1':ZDVUHPRYHG DVVKRZQLQWKHSUHFHGLQJ
FRGH ZKHQchLVHTXDOWRWKHFKDUDFWHU1WKHblinkIXQFWLRQZLOOEHFDOOHGWKUHHWLPHV
$FFLGHQWDOO\IRUJHWWLQJWKH breakLVDFRPPRQPLVWDNH,QWHQWLRQDOO\OHDYLQJRXWWKH
breakLVVRPHWLPHVKDQG\LWFDQEHFRQIXVLQJWRRWKHUVUHDGLQJ\RXUFRGHVRLW¦VD
JRRGSUDFWLFHWRFOHDUO\LQGLFDWH\RXULQWHQWLRQVZLWKFRPPHQWVLQWKHFRGH
2.16 Taking a Variety of Actions Based on a Single Variable | 51
,I\RXUswitchVWDWHPHQWLVPLVEHKDYLQJFKHFNWRHQVXUHWKDW\RXKDYH
QRWIRUJRWWHQWKHbreakVWDWHPHQWV
7KH default:ODEHOLVXVHGWRFDWFKYDOXHVWKDWGRQ¦WPDWFKDQ\RIWKH caseODEHOV,I
WKHUHLVQRdefaultODEHOWKHswitchH[SUHVVLRQZLOOQRWGRDQ\WKLQJLIWKHUHLVQRPDWFK
See Also
$UGXLQRUHIHUHQFHIRUWKHswitchDQGcaseVWDWHPHQWVKWWSZZZDUGXLQRFFHQ5HIHU
HQFH6ZLWFK&DVH
2.17 Comparing Character and Numeric Values
Problem
<RXZDQWWRGHWHUPLQHWKHUHODWLRQVKLSEHWZHHQYDOXHV
Solution
&RPSDUHLQWHJHUYDOXHVXVLQJWKHUHODWLRQDORSHUDWRUVVKRZQLQ7DEOH
7DEOH5HODWLRQDODQGHTXDOLW\RSHUDWRUV
Operator
Test for
Example
==
Equal to
2 == 3 // evaluates to false
!=
Not equal to
2 != 3 // evaluates to true
>
Greater than
2 > 3 // evaluates to false
<
Less than
2 < 3 // evaluates to true
>=
Greater than or equal to
2 >= 3 // evaluates to false
<=
Less than or equal to
2 <= 3 // evaluates to true
7KHIROORZLQJVNHWFKGHPRQVWUDWHVWKHUHVXOWVRIXVLQJWKHFRPSDULVRQRSHUDWRUV
/*
* RelationalExpressions sketch
* demonstrates comparing values
*/
int i = 1;
int j = 2;
// some values to start with
void setup() {
Serial.begin(9600);
}
52 | Chapter 2:ಗMaking the Sketch Do Your Bidding
void loop(){
Serial.print("i = ");
Serial.print(i);
Serial.print(" and j = ");
Serial.println(j);
if(i < j)
Serial.println(" i is less than j");
if(i <= j)
Serial.println(" i is less than or equal to j");
if(i != j)
Serial.println(" i is not equal to j");
if(i == j)
Serial.println(" i is equal to j");
if(i >= j)
Serial.println(" i is greater than or equal to j");
if(i > j)
Serial.println(" i is greater than j");
Serial.println();
i = i + 1;
if(i > j + 1)
delay(10000); // long delay after i is no longer close to j
}
+HUHLVWKHRXWSXW
i = 1 and j = 2
i is less than j
i is less than or equal to j
i is not equal to j
i = 2 and j = 2
i is less than or equal to j
i is equal to j
i is greater than or equal to j
i = 3 and j = 2
i is not equal to j
i is greater than or equal to j
i is greater than j
Discussion
1RWHWKDWWKHHTXDOLW\RSHUDWRULVWKHGRXEOHHTXDOVVLJQ==2QHRIWKHPRVWFRPPRQ
SURJUDPPLQJPLVWDNHVLVWRFRQIXVHWKLVZLWKWKHDVVLJQPHQWRSHUDWRUZKLFKXVHVD
VLQJOHHTXDOVVLJQ
7KHIROORZLQJH[SUHVVLRQZLOOFRPSDUHWKHYDOXHRIiWR7KHSURJUDPPHULQWHQGHG
WKLV
if(i == 3)
// test if i equals 3
%XWKHSXWWKLVLQWKHVNHWFK
if(i = 3)
// single equals sign used by mistake!!!!
2.17 Comparing Character and Numeric Values | 53
7KLVZLOODOZD\VUHWXUQ trueEHFDXVH iZLOOEHVHWWR 3VRWKH\ZLOOEHHTXDOZKHQ
FRPSDUHG
$WLSWRKHOSDYRLGWKDWWUDSZKHQFRPSDULQJYDULDEOHVWRFRQVWDQWV IL[HGYDOXHV LVWR
SXWWKHFRQVWDQWRQWKHOHIWVLGHRIWKHH[SUHVVLRQ
if(3 = i)
// single equals sign used by mistake!!!!
7KHFRPSLOHUZLOOWHOO\RXDERXWWKLVHUURUEHFDXVHLWNQRZVWKDW\RXFDQ¦WDVVLJQD
GLIIHUHQWYDOXHWRDFRQVWDQW
7KHHUURUPHVVDJHLVWKHVRPHZKDWXQIULHQGO\£YDOXHUHTXLUHGDVOHIW
RSHUDQGRIDVVLJQPHQW¤,I\RXVHHWKLVPHVVDJHWKHFRPSLOHULVWHOOLQJ
\RXWKDW\RXDUHWU\LQJWRDVVLJQDYDOXHWRVRPHWKLQJWKDWFDQQRWEH
FKDQJHG
See Also
$UGXLQRUHIHUHQFHIRUFRQGLWLRQDODQGFRPSDULVRQRSHUDWRUVKWWSZZZDUGXLQRFF
HQ5HIHUHQFH,I
2.18 Comparing Strings
Problem
<RXZDQWWRVHHLIWZRFKDUDFWHUVWULQJVDUHLGHQWLFDO
Solution
7KHUHLVDIXQFWLRQWRFRPSDUHVWULQJVFDOOHG strcmp VKRUWIRUVWULQJFRPSDUH +HUH
LVDIUDJPHQWVKRZLQJLWVXVH
char String1[ ] = "left";
char String2[ ] = "right";
if(strcmp(String1, String2) == 0)
Serial.print("strings are equal)
Discussion
strcmpUHWXUQVWKHYDOXH 0LIWKHVWULQJVDUHHTXDODQGDYDOXHJUHDWHUWKDQ]HURLIWKH
ILUVWFKDUDFWHUWKDWGRHVQRWPDWFKKDVDJUHDWHUYDOXHLQWKHILUVWVWULQJWKDQLQWKH
VHFRQG,WUHWXUQVDYDOXHOHVVWKDQ]HURLIWKHILUVWQRQPDWFKLQJFKDUDFWHULQWKHILUVW
VWULQJLVOHVVWKDQLQWKHVHFRQG8VXDOO\\RXRQO\ZDQWWRNQRZLIWKH\DUHHTXDODQG
DOWKRXJKWKHWHVWIRU]HURPD\VHHPXQLQWXLWLYHDWILUVW\RX¦OOVRRQJHWXVHGWRLW
54 | Chapter 2:ಗMaking the Sketch Do Your Bidding
%HDULQPLQGWKDWVWULQJVRIXQHTXDOOHQJWKZLOOQRWEHHYDOXDWHGDVHTXDOHYHQLIWKH
VKRUWHUVWULQJLVFRQWDLQHGLQWKHORQJHURQH6R
strcmp("left", "leftcenter") == 0)
// this will evaluate to false
<RXFDQFRPSDUHVWULQJVXSWRDJLYHQQXPEHURIFKDUDFWHUVE\XVLQJWKHstrncmpIXQF
WLRQ<RXJLYHstrncmpWKHPD[LPXPQXPEHURIFKDUDFWHUVWRFRPSDUHDQGLWZLOOVWRS
FRPSDULQJDIWHUWKDWPDQ\FKDUDFWHUV
strncmp("left", "leftcenter", 4) == 0)
// this will evaluate to true
See Also
0RUHLQIRUPDWLRQRQstrcmpLVDYDLODEOHDWKWWSZZZFSOXVSOXVFRPUHIHUHQFHFOLEUDU\
FVWULQJVWUFPS
2.19 Performing Logical Comparisons
Problem
<RXZDQWWRHYDOXDWHWKHORJLFDOUHODWLRQVKLSEHWZHHQWZRRUPRUHH[SUHVVLRQV)RU
H[DPSOH \RX ZDQW WR WDNH D GLIIHUHQW DFWLRQ GHSHQGLQJ RQ WKH FRQGLWLRQV RI DQ if
VWDWHPHQW
Solution
8VHWKHORJLFDORSHUDWRUVDVRXWOLQHGLQ7DEOH
7DEOH/RJLFDORSHUDWRUV
Symbol
Function
Comments
&&
Logical And
Evaluates as true if the condition on both sides of the && operator are true
||
Logical Or
Evaluates as true if the condition on at least one side of the || operator is true
!
Not
Evaluates as true if the expression is false, and false if the expression is true
Discussion
/RJLFDORSHUDWRUVUHWXUQWUXHRUIDOVHYDOXHVEDVHGRQWKHORJLFDOUHODWLRQVKLS
7KH ORJLFDO $QG RSHUDWRU && ZLOO UHWXUQ true LI ERWK LWV WZR RSHUDQGV DUH WUXH DQG
falseRWKHUZLVH7KHORJLFDO2URSHUDWRU||ZLOOUHWXUQtrueLIHLWKHURILWVWZRRSHUDQGV
DUHWUXHDQGfalseLIERWKRSHUDQGVDUHIDOVH7KH1RWRSHUDWRU!KDVRQO\RQHRSHUDQG
ZKRVHYDOXHLVLQYHUWHG¢LWUHVXOWVLQfalseLILWVRSHUDQGLVWUXHDQGtrueLILWVRSHUDQG
LVIDOVH
2.19 Performing Logical Comparisons | 55
2.20 Performing Bitwise Operations
Problem
<RXZDQWWRVHWRUFOHDUFHUWDLQELWVLQDYDOXH
Solution
8VHWKHELWRSHUDWRUVDVRXWOLQHGLQ7DEOH
7DEOH%LWRSHUDWRUV
Symbol
Function
Comment
&
Bitwise And
Sets bits in each place to 1 if both bits are 1; otherwise,
bits are set to 0.
|
Bitwise Or
Sets bits in each place to 1 if either bit is 1.
Example
3 & 1 equals 1
(11 & 01 equals 01)
3 | 1 equals 3
(11 | 01 equals 11)
^
Bitwise Exclusive
Or
Sets bits in each place to 1 only if one of the two bits
is 1.
~
Bitwise Negation
Inverts the value of each bit. The result depends on the
number of bits in the data type.
3 ^ 1 equals 2
(11 ^ 01 equals 10)
~1 equals 254
(~00000001 equals 11111110)
+HUHLVDVNHWFKWKDWGHPRQVWUDWHVWKHH[DPSOHYDOXHVVKRZQLQ7DEOH
/*
* bits sketch
* demonstrates bitwise operators
*/
void setup() {
Serial.begin(9600);
}
void loop(){
Serial.print("3 & 1 equals "); // bitwise And 3 and 1
Serial.print(3 & 1);
// print the result
Serial.print(" decimal, or in binary: ");
Serial.println(3 & 1 , BIN);
// print the binary representation of the result
Serial.print("3 | 1 equals "); // bitwise Or 3 and 1
Serial.print(3 | 1 );
Serial.print(" decimal, or in binary: ");
Serial.println(3 | 1 , BIN);
// print the binary representation of the result
Serial.print("3 ^ 1 equals "); // bitwise exclusive or 3 and 1
Serial.print(3 ^ 1);
56 | Chapter 2:ಗMaking the Sketch Do Your Bidding
Serial.print(" decimal, or in binary: ");
Serial.println(3 ^ 1 , BIN);
// print the binary representation of the result
byte byteVal = 1;
int intVal = 1;
byteVal = ~byteVal;
intVal = ~intVal;
// do the bitwise negate
Serial.print("~byteVal (1) equals "); // bitwise negate an 8 bit value
Serial.println(byteVal, BIN); // print the binary representation of the result
Serial.print("~intVal (1) equals "); // bitwise negate a 16 bit value
Serial.println(intVal, BIN);
// print the binary representation of the result
}
delay(10000);
7KLVLVZKDWLVGLVSOD\HGRQWKH6HULDO0RQLWRU
3 & 1 equals 1 decimal, or in binary: 1
3 | 1 equals 3 decimal, or in binary: 11
3 ^ 1 equals 2 decimal, or in binary: 10
~byteVal (1) equals 11111110
~intVal (1) equals 11111111111111111111111111111110
Discussion
%LWZLVHRSHUDWRUVDUHXVHGWRVHWRUWHVWELWV:KHQ\RX£$QG¤RU£2U¤WZRYDOXHVWKH
RSHUDWRUZRUNVRQHDFKLQGLYLGXDOELW,WLVHDVLHUWRVHHKRZWKLVZRUNVE\ORRNLQJDW
WKHELQDU\UHSUHVHQWDWLRQRIWKHYDOXHV
'HFLPDOLVELQDU\DQGGHFLPDOLV%LWZLVH$QGRSHUDWHVRQ
HDFKELW7KHULJKWPRVWELWVDUHERWKVRWKHUHVXOWRI$QGLQJWKHVHLV0RYLQJWR
WKHOHIWWKHQH[WELWVDUHDQG$QGLQJWKHVHUHVXOWVLQ$OOWKHUHPDLQLQJELWVDUH
VRWKHELWZLVHUHVXOWRIWKHVHZLOOEH,QRWKHUZRUGVIRUHDFKELWSRVLWLRQZKHUH
WKHUHLVDLQERWKSODFHVWKHUHVXOWZLOOKDYHDRWKHUZLVHLWZLOOKDYHD6R11 &
01HTXDOV
7DEOHVDQGVKRXOGKHOSWRFODULI\WKHELWZLVH$QG2UDQG([FOXVLYH2U
YDOXHV
7DEOH%LWZLVH$QG
Bit 1
Bit 2
Bit 1 and Bit 2
0
0
0
0
1
0
1
0
0
1
1
1
2.20 Performing Bitwise Operations | 57
7DEOH%LWZLVH2U
Bit 1
Bit 2
Bit 1 or Bit 2
0
0
0
0
1
1
1
0
1
1
1
1
7DEOH%LWZLVH([FOXVLYH2U
Bit 1
Bit 2
Bit 1 ^ Bit 2
0
0
0
0
1
1
1
0
1
1
1
0
$OOWKHELWZLVHH[SUHVVLRQVRSHUDWHRQWZRYDOXHVH[FHSWIRUWKHQHJDWLRQRSHUDWRU
7KLVVLPSO\IOLSVHDFKELWVREHFRPHVDQGEHFRPHV,QWKHH[DPSOHWKH byte
ELW YDOXHEHFRPHV7KHintYDOXHKDVELWVVRZKHQHDFKLV
IOLSSHGWKHUHVXOWLVRQHVIROORZHGE\DVLQJOH]HUR
See Also
$UGXLQRUHIHUHQFHIRUWKHELWZLVH$QG2UDQG([FOXVLYH2URSHUDWRUVKWWSZZZ
DUGXLQRFFHQ5HIHUHQFH%LWZLVH
2.21 Combining Operations and Assignment
Problem
<RX ZDQW WR XQGHUVWDQG DQG XVH FRPSRXQG RSHUDWRUV ,W LV QRW XQFRPPRQ WR VHH
SXEOLVKHGFRGHWKDWXVHVH[SUHVVLRQVWKDWGRPRUHWKDQRQHWKLQJLQDVLQJOHVWDWHPHQW
<RXZDQWWRXQGHUVWDQGa += ba >>= bDQGa &= b
Solution
7DEOH VKRZV WKH FRPSRXQG DVVLJQPHQW RSHUDWRUV DQG WKHLU HTXLYDOHQW IXOO
H[SUHVVLRQ
58 | Chapter 2:ಗMaking the Sketch Do Your Bidding
7DEOH&RPSRXQGRSHUDWRUV
Operator
Example
Equivalent expression
+=
Value += 5;
Value = Value + 5; // add 5 to Value
-=
Value -= 4;
Value = Value - 4; // subtract 4 from Value
*=
Value *= 3;
Value = Value * 3; // multiply Value by 3
/=
Value /= 2;
Value = Value / 2; // divide Value by 2
>>=
Value >>= 2;
Value = Value >> 2; // shift Value right two places
<<=
Value <<= 2;
Value = Value << 2; // shift Value left two places
&=
Mask &= 2;
Mask = Mask & 2; // binary and Mask with 2
|=
Mask |= 2;
Mask = Mask | 2; // binary or Mask with 2
Discussion
7KHVHFRPSRXQGVWDWHPHQWVDUHQRPRUHHIILFLHQWDWUXQWLPHWKDQWKHHTXLYDOHQWIXOO
H[SUHVVLRQDQGLI\RXDUHQHZWRSURJUDPPLQJXVLQJWKHIXOOH[SUHVVLRQLVFOHDUHU
([SHULHQFHGFRGHUVRIWHQXVHWKHVKRUWHUIRUPVRLWLVKHOSIXOWREHDEOHWRUHFRJQL]H
WKHH[SUHVVLRQVZKHQ\RXUXQDFURVVWKHP
See Also
6HHKWWSZZZDUGXLQRFFHQ5HIHUHQFH+RPH3DJHIRUDQLQGH[WRWKHUHIHUHQFHSDJHV
IRUFRPSRXQGRSHUDWRUV
2.21 Combining Operations and Assignment | 59
CHAPTER 3
Using Mathematical Operators
3.0 Introduction
$OPRVWHYHU\VNHWFKXVHVPDWKHPDWLFDORSHUDWRUVWRPDQLSXODWHWKHYDOXHRIYDULDEOHV
7KLVFKDSWHUSURYLGHVDEULHIRYHUYLHZRIWKHPRVWFRPPRQPDWKHPDWLFDORSHUDWRUV
$VWKHSUHFHGLQJFKDSWHULVWKLVVXPPDU\LVSULPDULO\IRUQRQSURJUDPPHUVRUSUR
JUDPPHUV ZKR DUH QRW IDPLOLDU ZLWK & RU & )RU PRUH GHWDLOV VHH RQH RI WKH
&UHIHUHQFHERRNVPHQWLRQHGLQWKH3UHIDFH
3.1 Adding, Subtracting, Multiplying, and Dividing
Problem
<RXZDQWWRSHUIRUPVLPSOHPDWKRQYDOXHVLQ\RXUVNHWFK<RXZDQWWRFRQWUROWKH
RUGHULQZKLFKWKHRSHUDWLRQVDUHSHUIRUPHGDQG\RXPD\QHHGWRKDQGOHGLIIHUHQW
YDULDEOHW\SHV
Solution
8VHWKHIROORZLQJFRGH
int myValue;
myValue = 1 + 2;
myValue = 3 - 2;
myValue = 3 * 2;
myValue = 3 / 2;
// addition
// subtraction
// multiplication
// division (the result is 1)
Discussion
$GGLWLRQVXEWUDFWLRQDQGPXOWLSOLFDWLRQIRULQWHJHUVZRUNPXFKDV\RXH[SHFW
61
0DNHVXUH\RXUUHVXOWZLOOQRWH[FHHGWKHPD[LPXPVL]HRIWKHGHVWL
QDWLRQYDULDEOH6HH5HFLSH
,QWHJHUGLYLVLRQWUXQFDWHVWKHIUDFWLRQDOUHPDLQGHULQWKHGLYLVLRQH[DPSOHVKRZQLQ
WKLVUHFLSH¦V6ROXWLRQ myValueZLOOHTXDODIWHUWKHGLYLVLRQ VHH5HFLSHLI\RXU
DSSOLFDWLRQUHTXLUHVIUDFWLRQDOUHVXOWV int value =
1 + 2 * 3 + 4;
&RPSRXQGVWDWHPHQWVVXFKDVWKHSUHFHGLQJVWDWHPHQWPD\DSSHDUDPELJXRXVEXW
WKHSUHFHGHQFH RUGHU RIHYHU\RSHUDWRULVZHOOGHILQHG0XOWLSOLFDWLRQDQGGLYLVLRQ
KDYHDKLJKHUSUHFHGHQFHWKDQDGGLWLRQDQGVXEWUDFWLRQVRWKHUHVXOWZLOOEH,W¦V
DGYLVDEOHWRXVHEUDFNHWVLQ\RXUFRGHWRPDNHWKHGHVLUHGFDOFXODWLRQSUHFHGHQFHFOHDU
int value = 1 + (2 * 3) + 4;SURGXFHVWKHVDPHUHVXOWEXWLVHDVLHUWRUHDG
8VHSDUHQWKHVHVLI\RXQHHGWRDOWHUWKHSUHFHGHQFHDVLQWKLVH[DPSOH
int value =
((1 + 2) * 3) + 4;
7KHUHVXOWZLOOEH7KHH[SUHVVLRQLQWKHLQQHUSDUHQWKHVHVLVFDOFXODWHGILUVWVR
JHWVDGGHGWRWKLVWKHQJHWVPXOWLSOLHGE\DQGILQDOO\LVDGGHGWR\LHOGLQJ
See Also
5HFLSH5HFLSH
3.2 Incrementing and Decrementing Values
Problem
<RXZDQWWRLQFUHDVHRUGHFUHDVHWKHYDOXHRIDYDULDEOH
Solution
8VHWKHIROORZLQJFRGH
int myValue = 0;
myValue = myvalue + 1;
myValue += 1;
// this adds one to the variable myValue
// this does the same as the above
myValue = myvalue - 1;
myValue -= 1;
// this subtracts one from the variable myValue
// this does the same as the above
myValue = myvalue + 5;
myValue += 5;
// this adds five to the variable myValue
// this does the same as the above
62 | Chapter 3:ಗUsing Mathematical Operators
Discussion
,QFUHDVLQJDQGGHFUHDVLQJWKHYDOXHVRIYDULDEOHVLVRQHRIWKHPRVWFRPPRQSURJUDP
PLQJWDVNVDQGWKH$UGXLQRERDUGKDVRSHUDWRUVWRPDNHWKLVHDV\,QFUHDVLQJDYDOXH
E\ RQH LV FDOOHG LQFUHPHQWLQJ DQG GHFUHDVLQJ LW E\ RQH LV FDOOHG GHFUHPHQWLQJ 7KH
ORQJKDQGZD\WRGRWKLVLVDVIROORZV
myValue = myvalue + 1;
// this adds one to the variable myValue
%XW\RXFDQDOVRFRPELQHWKHLQFUHPHQWDQGGHFUHPHQWRSHUDWRUVZLWKWKHDVVLJQRS
HUDWRUOLNHWKLV
myValue += 1;
// this does the same as the above
See Also
5HFLSH
3.3 Finding the Remainder After Dividing Two Values
Problem
<RXZDQWWRILQGWKHUHPDLQGHUDIWHU\RXGLYLGHWZRYDOXHV
Solution
8VHWKH%V\PERO WKHPRGXOXVRSHUDWRU WRJHWWKHUHPDLQGHU
int myValue0 =
int myValue1 =
20 % 10;
21 % 10;
// get the modulus(remainder) of 20 divided by 10
// get the modulus(remainder) of 21 divided by 10
myValue0HTXDOV0 GLYLGHGE\KDVDUHPDLQGHURI myValue1HTXDOV1 GLYLGHG
E\KDVDUHPDLQGHURI Discussion
7KHPRGXOXVRSHUDWRULVVXUSULVLQJO\XVHIXOSDUWLFXODUO\ZKHQ\RXZDQWWRVHHLID
YDOXHLVHYHQO\GLYLVLEOHE\DQXPEHU)RUH[DPSOHWKHFRGHLQWKLVUHFLSH¦V6ROXWLRQ
FDQEHHQKDQFHGWRGHWHFWZKHQDYDOXHLVDPXOWLSOHRI
int myValue;
//... code here to set the value of myValue
if( myValue % 10 == 0)
{
Serial.println("The value is a multiple of 10";
}
7KHSUHFHGLQJFRGHWDNHVWKHPRGXOXVRIWKHmyValueYDULDEOHDQGFRPSDUHVWKHUHVXOW
WR]HUR VHH5HFLSH ,ILWLV]HURDPHVVDJHLVSULQWHGVD\LQJWKHUHVXOWLVGLYLVLEOH
E\
3.3 Finding the Remainder After Dividing Two Values | 63
+HUHLVDVLPLODUH[DPSOHEXWE\XVLQJZLWKWKHPRGXOXVRSHUDWRUWKHUHVXOWFDQEH
XVHGWRFKHFNLIDYDOXHLVRGGRUHYHQ
int myValue;
//... code here to set the value of myValue
if( myValue % 2 == 0)
{
Serial.println("The value is even";
}
else
{
Serial.println("The value is odd";
}
7KLVH[DPSOHWUDFNVWKHGD\RIWKHZHHNIURPDYDULDEOHWKDWLVLQFUHPHQWHG E\RWKHU
FRGH HDFKGD\DQGUHSRUWVZKHQLWLVWKHILUVWGD\RIWKHZHHN
int dayCount;
int day = dayCount % 7;
if( day == 0)
{
Serial.println("This is the first day of the week");
}
See Also
$UGXLQRUHIHUHQFHIRU % WKHPRGXOXVRSHUDWRU KWWSZZZDUGXLQRFFHQ5HIHUHQFH
0RGXOR
3.4 Determining the Absolute Value
Problem
<RXZDQWWRJHWWKHDEVROXWHYDOXHRIDQXPEHU
Solution
abs(x)FRPSXWHVWKHDEVROXWHYDOXHRI x7KHIROORZLQJH[DPSOHWDNHVWKHDEVROXWH
YDOXHRIWKHGLIIHUHQFHEHWZHHQUHDGLQJVRQWZRDQDORJLQSXWSRUWV VHH&KDSWHUIRU
PRUHRQanalogRead() int x = analogRead(0);
int y = analogRead(1);
if(abs(x-y) > 10)
{
Serial.println("The analog values differ by more than 10");
}
64 | Chapter 3:ಗUsing Mathematical Operators
Discussion
abs(x-y);UHWXUQVWKHDEVROXWHYDOXHRIWKHGLIIHUHQFHEHWZHHQ xDQG y,WLVXVHGIRU
LQWHJHU DQGlongLQWHJHU YDOXHV7RUHWXUQWKHDEVROXWHYDOXHRIIORDWLQJSRLQWYDOXHV
VHH5HFLSH
See Also
$UGXLQRUHIHUHQFHIRUabsKWWSZZZDUGXLQRFFHQ5HIHUHQFH$EV
3.5 Constraining a Number to a Range of Values
Problem
<RXZDQWWRHQVXUHWKDWDYDOXHLVDOZD\VZLWKLQVRPHORZHUDQGXSSHUOLPLW
Solution
constrain(x, min, max)UHWXUQVDYDOXHWKDWLVZLWKLQWKHERXQGVRIminDQGmax
myConstrainedValue
= constrain(myValue, 100, 200);
Discussion
myConstrainedValueLVVHWWRDYDOXHWKDWZLOODOZD\VEHJUHDWHUWKDQRUHTXDOWRDQG
OHVVWKDQRUHTXDOWR,ImyValueLVOHVVWKDQWKHUHVXOWZLOOEHLILWLVPRUH
WKDQLWZLOOEHVHWWR
7DEOHVKRZVVRPHH[DPSOHRXWSXWYDOXHVXVLQJDminRIDQGDmaxRI
7DEOH2XWSXWIURPFRQVWUDLQZLWKPLQ DQGPD[ myValue (the input value)
constrain(myValue, 100, 200)
99
100
100
100
150
150
200
200
201
200
See Also
5HFLSH
3.5 Constraining a Number to a Range of Values | 65
Download from Wow! eBook <www.wowebook.com>
3.6 Finding the Minimum or Maximum of Some Values
Problem
<RXZDQWWRILQGWKHPLQLPXPRUPD[LPXPRIWZRRUPRUHYDOXHV
Solution
min(x,y) UHWXUQV WKH VPDOOHU RI WZR QXPEHUV max(x,y) UHWXUQV WKH ODUJHU RI WZR
QXPEHUV
myValue = analogRead(0);
myMinValue = min(myValue, 200);
myMaxValue = max(myValue, 100);
// myMinValue will be the smaller of
// myVal or 200
// myMaxValue will be the larger of
// myVal or 100
Discussion
7DEOHVKRZVVRPHH[DPSOHRXWSXWYDOXHVXVLQJDminRI7KHWDEOHVKRZVWKDW
WKHRXWSXWLVWKHVDPHDVWKHLQSXW myValue XQWLOWKHYDOXHEHFRPHVJUHDWHUWKDQ
7DEOH2XWSXWIURPPLQ P\9DOXH
myValue (the input value)
Min(myValue, 200)
99
99
100
100
150
150
200
200
201
200
7DEOHVKRZVWKHRXWSXWXVLQJDmaxRI7KHWDEOHVKRZVWKDWWKHRXWSXWLVWKH
VDPHDVWKHLQSXW myValue ZKHQWKHYDOXHLVJUHDWHUWKDQRUHTXDOWR
7DEOH2XWSXWIURPPD[ P\9DOXH
myValue (the input value)
Max(myValue, 200)
99
100
100
100
150
150
200
200
201
201
66 | Chapter 3:ಗUsing Mathematical Operators
8VH minZKHQ\RXZDQWWROLPLWWKHXSSHUERXQG7KDWPD\EHFRXQWHULQWXLWLYHEXW
E\UHWXUQLQJWKHVPDOOHURIWKHLQSXWYDOXHDQGWKHPLQLPXPYDOXHWKHRXWSXWIURP
minZLOOQHYHUEHKLJKHUWKDQWKHPLQLPXPYDOXH LQWKHH[DPSOH 6LPLODUO\XVH maxWROLPLWWKHORZHUERXQG7KHRXWSXWIURP maxZLOOQHYHUEHORZHU
WKDQWKHPD[LPXPYDOXH LQWKHH[DPSOH ,I\RXZDQWWRILQGWKH minRU maxYDOXHIURPPRUHWKDQWZRYDOXHV\RXFDQFDVFDGH
WKHYDOXHVDVIROORZV
// myMinValue will be the smaller of the three analog readings:
int myMinValue = min(analogRead(0), min(analogRead(1), analogRead(2)) );
,QWKLVH[DPSOHWKHPLQLPXPYDOXHLVIRXQGIRUDQDORJSRUWVDQGDQGWKHQWKH
PLQLPXPRIWKDWDQGSRUW7KLVFDQEHH[WHQGHGIRUDVPDQ\LWHPVDV\RXQHHGEXW
WDNHFDUHWRSRVLWLRQWKHSDUHQWKHVHVFRUUHFWO\7KHIROORZLQJH[DPSOHJHWVWKHPD[L
PXPRIIRXUYDOXHV
int myMaxValue = max(analogRead(0), max(analogRead(1), max(analogRead(2),
analogRead(3))));
See Also
5HFLSH
3.7 Raising a Number to a Power
Problem
<RXZDQWWRUDLVHDQXPEHUWRDSRZHU
Solution
pow(x, y)UHWXUQVWKHYDOXHRIxUDLVHGWRWKHSRZHURIy
myValue =
pow(3,2);
7KLVFDOFXODWHVVRmyValueZLOOHTXDO
Discussion
7KHpowIXQFWLRQFDQRSHUDWHRQLQWHJHURUIORDWLQJSRLQWYDOXHVDQGLWUHWXUQVWKHUHVXOW
DVDIORDWLQJSRLQWYDOXH
Serial.print(pow(3,2)); // this prints 9.00
int z = pow(3,2);
Serial.println(z);
// this prints 9
7KHILUVWRXWSXWLV9.00DQGWKHVHFRQGLV 9WKH\DUHQRWH[DFWO\WKHVDPHEHFDXVHWKH
ILUVW printGLVSOD\VWKHRXWSXWDVDIORDWLQJSRLQWQXPEHUDQGWKHVHFRQGWUHDWVWKH
YDOXHDVDQLQWHJHUEHIRUHSULQWLQJDQGWKHUHIRUHGLVSOD\VZLWKRXWWKHGHFLPDOSRLQW
3.7 Raising a Number to a Power | 67
,I\RXXVHWKHpowIXQFWLRQ\RXPD\ZDQWWRUHDG5HFLSHWRXQGHUVWDQGWKHGLIIHU
HQFHEHWZHHQWKHVHDQGLQWHJHUYDOXHV
+HUHLVDQH[DPSOHRIUDLVLQJDQXPEHUWRDIUDFWLRQDOSRZHU
float s = pow(2, 1.0 / 12); // the twelfth root of two
7KHWZHOIWKURRWRIWZRLVWKHVDPHDVWRWKHSRZHURI7KHUHVXOWDQWYDOXH
sLV WKLVLVWKHUDWLRRIWKHIUHTXHQF\RIWZRDGMDFHQWQRWHVRQDSLDQR 3.8 Taking the Square Root
Problem
<RXZDQWWRFDOFXODWHWKHVTXDUHURRWRIDQXPEHU
Solution
7KHsqrt(x)IXQFWLRQUHWXUQVWKHVTXDUHURRWRIx
Serial.print( sqrt(9) ); // this prints 3.00
Discussion
7KH sqrtIXQFWLRQUHWXUQVDIORDWLQJSRLQWQXPEHU VHHWKH powIXQFWLRQGLVFXVVHGLQ
5HFLSH 3.9 Rounding Floating-Point Numbers Up and Down
Problem
<RXZDQWWKHQH[WVPDOOHVWRUODUJHVWLQWHJHUYDOXHRIDIORDWLQJSRLQWQXPEHU floor
RUceil Solution
floor(x)UHWXUQVWKHODUJHVWLQWHJUDOYDOXHWKDWLVQRWJUHDWHUWKDQxceil(x)UHWXUQVWKH
VPDOOHVWLQWHJUDOYDOXHWKDWLVQRWOHVVWKDQx
Discussion
7KHVHIXQFWLRQVDUHXVHGIRUURXQGLQJIORDWLQJSRLQWQXPEHUVXVHfloorWRURXQGGRZQ
DQGceilWRURXQGXS
+HUHLVVRPHH[DPSOHRXWSXWXVLQJfloor
Serial.println( floor(1) );
Serial.println( floor(1.1) );
Serial.println( floor(0) );
68 | Chapter 3:ಗUsing Mathematical Operators
// this prints
// this prints
// this prints
1.00
1.00
0.00
Serial.println( floor(.1) );
// this prints 0.00
Serial.println( floor(-1) );
// this prints -1.00
Serial.println( floor(-1.1) ); // this prints -2.00
+HUHLVVRPHH[DPSOHRXWSXWXVLQJceil
Serial.println( ceil(1) );
Serial.println( ceil(1.1) );
Serial.println( ceil(0) );
Serial.println( ceil(.1) );
Serial.println( ceil(-1) );
Serial.println( ceil(-1.1) );
// this prints 1.00
// this prints 2.00
// this prints 0.00
// this prints 1.00
// this prints -1.00
// this prints -1.00
<RXFDQWUXQFDWHDIORDWLQJSRLQWQXPEHUE\FDVWLQJ FRQYHUWLQJ WRDQ
intEXWWKLVGRHVQRWURXQGFRUUHFWO\1HJDWLYHQXPEHUVVXFKDV
VKRXOGURXQGGRZQWREXWZKHQFDVWWRDQintWKH\DUHURXQGHGXS
WR7KHVDPHSUREOHPH[LVWVZLWKSRVLWLYHQXPEHUVVKRXOGURXQG
XSWREXWZLOOURXQGGRZQWR8VHfloorDQGceilWRJHWWKHFRUUHFW
UHVXOWV
3.10 Using Trigonometric Functions
Problem
<RXZDQWWRJHWWKHVLQHFRVLQHRUWDQJHQWRIDQDQJOHJLYHQLQUDGLDQVRUGHJUHHV
Solution
sin(x)UHWXUQVWKHVLQHRIDQJOHxcos(x)UHWXUQVWKHFRVLQHRIDQJOHxtan(x)UHWXUQV
WKHWDQJHQWRIDQJOHx
Discussion
$QJOHV DUH VSHFLILHG LQ UDGLDQV DQG WKH UHVXOW LV D IORDWLQJSRLQW QXPEHU VHH 5HF
LSH 7KHIROORZLQJH[DPSOHLOOXVWUDWHVWKHWULJIXQFWLRQV
float deg = 30;
float rad = deg * PI / 180;
Serial.println(rad);
Serial.println sin(rad));
Serial.println (cos(rad));
// angle in degrees
// convert to radians
// print the radians
// print the sine
// print the cosine
7KLVFRQYHUWVWKHDQJOHLQWRUDGLDQVDQGSULQWVWKHVLQHDQGFRVLQH+HUHLVWKHRXWSXW
ZLWKDQQRWDWLRQDGGHG
0.52
0.50
0.87
30 degrees is 0.5235988 radians, print only shows two decimal places
sine of 30 degrees is .5000000, displayed here to two decimal places
cosine is .8660254, which rounds up to 0.87
3.10 Using Trigonometric Functions | 69
$OWKRXJKWKHVNHWFKFDOFXODWHVWKHVHYDOXHVXVLQJWKHIXOOSUHFLVLRQRIIORDWLQJSRLQW
QXPEHUVWKHSerial.printURXWLQHVKRZVWKHYDOXHVRIIORDWLQJSRLQWQXPEHUVWRWZR
GHFLPDOSODFHV
7KHFRQYHUVLRQIURPUDGLDQVWRGHJUHHVDQGEDFNDJDLQLVWH[WERRNWULJRQRPHWU\PILV
WKHIDPLOLDUFRQVWDQWIRUπ PIDQG180DUHERWKFRQVWDQWVDQG$UGXLQR
SURYLGHV VRPH SUHFDOFXODWHG FRQVWDQWV \RX FDQ XVH WR SHUIRUP GHJUHHUDGLDQ
FRQYHUVLRQV
rad = deg * DEG_TO_RAD;
deg = rad * RAD_TO_DEG;
// a way to convert degrees to radians
// a way to convert radians to degrees
8VLQJ deg * DEG_TO_RADORRNVPRUHHIILFLHQWWKDQ deg * PI / 180EXWLW¦VQRWVLQFH
WKH$UGXLQRFRPSLOHULVVPDUWHQRXJKWRUHFRJQL]HWKDWPI / 180LVDFRQVWDQW WKHYDOXH
ZLOOQHYHUFKDQJH VRLWVXEVWLWXWHVWKHUHVXOWRIGLYLGLQJPIE\ZKLFKKDSSHQVWR
EHWKHYDOXHRIWKHFRQVWDQW DEG_TO_RADLV 6R\RXFDQXVHZKLFK
HYHUDSSURDFK\RXSUHIHU
See Also
$UGXLQRUHIHUHQFHVIRU sin KWWSZZZDUGXLQRFFHQ5HIHUHQFH6LQ cos KWWSDUGXL
QRFFHQ5HIHUHQFH&RV DQGtan KWWSDUGXLQRFFHQ5HIHUHQFH7DQ
3.11 Generating Random Numbers
Problem
<RXZDQWWRJHWDUDQGRPQXPEHUHLWKHUUDQJLQJIURP]HURXSWRDVSHFLILHGPD[LPXP
RUFRQVWUDLQHGEHWZHHQDPLQLPXPDQGPD[LPXPYDOXH\RXSURYLGH
Solution
8VHWKHrandomIXQFWLRQWRUHWXUQDUDQGRPQXPEHU&DOOLQJrandomZLWKDVLQJOHSD
UDPHWHUVHWVWKHXSSHUERXQGWKHYDOXHVUHWXUQHGZLOOUDQJHIURP]HURWRRQHOHVVWKDQ
WKHXSSHUERXQG
random(max);
// returns a random number between 0 and max -1
&DOOLQJ randomZLWKWZRSDUDPHWHUVVHWVWKHORZHUDQGXSSHUERXQGVWKHYDOXHVUH
WXUQHGZLOOUDQJHIURPWKHORZHUERXQG LQFOXVLYH WRRQHOHVVWKDQWKHXSSHUERXQG
random(min, max); // returns a random number between min and max -1
Discussion
$OWKRXJKWKHUHDSSHDUVWREHQRREYLRXVSDWWHUQWRWKHQXPEHUVUHWXUQHGWKHYDOXHV
DUHQRWWUXO\UDQGRP([DFWO\WKHVDPHVHTXHQFHZLOOUHSHDWHDFKWLPHWKHVNHWFKVWDUWV
,QPDQ\DSSOLFDWLRQVWKLVGRHVQRWPDWWHU%XWLI\RXQHHGDGLIIHUHQWVHTXHQFHHDFK
WLPH\RXUVNHWFKVWDUWVXVHWKHIXQFWLRQrandomSeed(seed)ZLWKDGLIIHUHQWVHHGYDOXH
70 | Chapter 3:ಗUsing Mathematical Operators
HDFKWLPH LI\RXXVHWKHVDPHVHHGYDOXH\RX¦OOJHWWKHVDPHVHTXHQFH 7KLVIXQFWLRQ
VWDUWVWKHUDQGRPQXPEHUJHQHUDWRUDWVRPHDUELWUDU\SODFHEDVHGRQWKHVHHGSDUDP
HWHU\RXSDVV
randomSeed(1234);
// change the starting sequence of random numbers.
+HUHLVDQH[DPSOHWKDWXVHVWKHGLIIHUHQWIRUPVRIUDQGRPQXPEHUJHQHUDWLRQDYDLODEOH
RQ$UGXLQR
// Random
// demonstrates generating random numbers
int randNumber;
void setup()
{
Serial.begin(9600);
// Print random numbers with no seed value
Serial.println("Print 20 random numbers between 0 and 9");
for(int i=0; i < 20; i++)
{
randNumber = random(10);
Serial.print(randNumber);
Serial.print(" ");
}
Serial.println();
Serial.println("Print 20 random numbers between 2 and 9");
for(int i=0; i < 20; i++)
{
randNumber = random(2,10);
Serial.print(randNumber);
Serial.print(" ");
}
// Print random numbers with the same seed value each time
randomSeed(1234);
Serial.println();
Serial.println("Print 20 random numbers between 0 and 9 after constant seed ");
for(int i=0; i < 20; i++)
{
randNumber = random(10);
Serial.print(randNumber);
Serial.print(" ");
}
// Print random numbers with a different seed value each time
randomSeed(analogRead(0)); // read from an analog port with nothing connected
Serial.println();
Serial.println("Print 20 random numbers between 0 and 9 after floating seed ");
for(int i=0; i < 20; i++)
{
randNumber = random(10);
Serial.print(randNumber);
Serial.print(" ");
3.11 Generating Random Numbers | 71
Download from Wow! eBook <www.wowebook.com>
}
}
Serial.println();
Serial.println();
void loop()
{
}
+HUHLVWKHRXWSXWIURPWKLVFRGH
Print 20 random numbers between 0 and 9
7 9 3 8 0 2 4 8 3 9 0 5 2 2 7 3 7 9 0 2
Print 20 random numbers between 2 and 9
9 3 7 7 2 7 5 8 2 9 3 4 2 5 4 3 5 7 5 7
Print 20 random numbers between 0 and 9 after constant seed
8 2 8 7 1 8 0 3 6 5 9 0 3 4 3 1 2 3 9 4
Print 20 random numbers between 0 and 9 after floating seed
0 9 7 4 4 7 7 4 4 9 1 6 0 2 3 1 5 9 1 1
,I\RXSUHVVWKHUHVHWEXWWRQRQ\RXU$UGXLQRWRUHVWDUWWKHVNHWFKWKHILUVWWKUHHOLQHV
RIUDQGRPQXPEHUVZLOOEHXQFKDQJHG2QO\WKHODVWOLQHFKDQJHVHDFKWLPHWKHVNHWFK
VWDUWVEHFDXVHLWVHWVWKHVHHGWRDGLIIHUHQWYDOXHE\UHDGLQJLWIURPDQXQFRQQHFWHG
DQDORJLQSXWSRUWDVDVHHGWRWKH randomSeedIXQFWLRQ,I\RXDUHXVLQJDQDORJSRUW
IRUVRPHWKLQJHOVHFKDQJHWKHDUJXPHQWWRanalogReadWRDQXQXVHGDQDORJSRUW
See Also
$UGXLQR UHIHUHQFHV IRU random KWWSZZZDUGXLQRFFHQ5HIHUHQFH5DQGRP DQG
randomSeed KWWSDUGXLQRFFHQ5HIHUHQFH5DQGRP6HHG
3.12 Setting and Reading Bits
Problem
<RXZDQWWRUHDGRUVHWDSDUWLFXODUELWLQDQXPHULFYDULDEOH
Solution
8VHWKHIROORZLQJIXQFWLRQV
bitSet(x, bitPosition)VHWV ZULWHVDWR WKHJLYHQbitPositionRIYDULDEOHx
bitClear(x, bitPosition)FOHDUV ZULWHVDWR WKHJLYHQbitPositionRIYDULDEOHx
bitRead(x, bitPosition) UHWXUQV WKH YDOXH DV RU RI WKH ELW DW WKH JLYHQ
bitPositionRIYDULDEOHx
bitWrite(x, bitPosition, value)VHWVWKHJLYHQYDOXH DVRU RIWKHELWDWWKH
JLYHQbitPositionRIYDULDEOHx
bit(bitPosition)UHWXUQVWKHYDOXHRIWKHJLYHQELWSRVLWLRQbit(0)LVbit(1)LV
bit(2)LVDQGVRRQ
72 | Chapter 3:ಗUsing Mathematical Operators
,QDOOWKHVHIXQFWLRQVbitPosition 0LVWKHOHDVWVLJQLILFDQW ULJKWPRVW ELW
+HUHLVDVNHWFKWKDWXVHVWKHVHIXQFWLRQVWRPDQLSXODWHWKHELWVRIDQELWYDULDEOH
FDOOHGflags
// bitFunctions
// demonstrates using the bit functions
byte flags = 0; // these examples set, clear or read bits in a variable called flags.
// bitSet example
void setFlag( int flagNumber)
{
bitSet(flags, flagNumber);
}
// bitClear example
void clearFlag( int flagNumber)
{
bitClear(flags, flagNumber);
}
// bitPosition example
int
{
getFlag( int flagNumber)
return
bitRead(flags, flagNumber);
}
void setup()
{
Serial.begin(9600);
}
void loop()
{
showFlags();
setFlag(2); // set some flags;
setFlag(5);
showFlags();
clearFlag(2);
showFlags();
delay(10000); // wait a very long time
}
// reports flags that are set
void showFlags()
{
for(int flag=0; flag < 8; flag++)
{
if(getFlag(flag) == true)
Serial.print("* bit set for flag ");
3.12 Setting and Reading Bits | 73
else
Serial.print("bit clear for flag ");
}
Serial.println(flag);
}
Serial.println();
7KLVFRGHZLOOSULQWWKHIROORZLQJ
bit clear for flag 0
bit clear for flag 1
bit clear for flag 2
bit clear for flag 3
bit clear for flag 4
bit clear for flag 5
bit clear for flag 6
bit clear for flag 7
bit clear for flag 0
bit clear for flag 1
* bit set for flag 2
bit clear for flag 3
bit clear for flag 4
* bit set for flag 5
bit clear for flag 6
bit clear for flag 7
bit clear for flag 0
bit clear for flag 1
bit clear for flag 2
bit clear for flag 3
bit clear for flag 4
* bit set for flag 5
bit clear for flag 6
bit clear for flag 7
Discussion
5HDGLQJDQGVHWWLQJELWVLVDFRPPRQWDVNDQGPDQ\RIWKH$UGXLQROLEUDULHVXVHWKLV
IXQFWLRQDOLW\2QHRIWKHPRUHFRPPRQXVHVRIELWRSHUDWLRQVLVWRHIILFLHQWO\VWRUHDQG
UHWULHYHELQDU\YDOXHV RQRIIWUXHIDOVHKLJKORZHWF $UGXLQRGHILQHVWKHFRQVWDQWVtrueDQGHIGHDVDQGfalseDQGLOWDV
7KHVWDWHRIHLJKWVZLWFKHVFDQEHSDFNHGLQWRDVLQJOHELWYDOXHLQVWHDGRIUHTXLULQJ
HLJKWE\WHVRULQWHJHUV7KHH[DPSOHLQWKLVUHFLSH¦V6ROXWLRQVKRZVKRZHLJKWYDOXHV
FDQEHLQGLYLGXDOO\VHWRUFOHDUHGLQDVLQJOHE\WH
74 | Chapter 3:ಗUsing Mathematical Operators
7KHWHUPIODJLVDSURJUDPPLQJWHUPIRUYDOXHVWKDWVWRUHWKHVWDWHRIVRPHDVSHFWRID
SURJUDP,QWKLVVNHWFKWKHIODJELWVDUHUHDGXVLQJbitReadDQGWKH\DUHVHWRUFOHDUHG
XVLQJbitSetRUbitClear7KHVHIXQFWLRQVWDNHWZRSDUDPHWHUVWKHILUVWLVWKHYDOXHWR
UHDGRUZULWH flagsLQWKLVH[DPSOH DQGWKHVHFRQGLVWKHELWSRVLWLRQLQGLFDWLQJZKHUH
WKHUHDGRUZULWHVKRXOGWDNHSODFH%LWSRVLWLRQLVWKHOHDVWVLJQLILFDQW ULJKWPRVW ELW
SRVLWLRQLVWKHVHFRQGSRVLWLRQIURPWKHULJKWDQGVRRQ6R
bitRead(2, 1); // returns 1 because 2 is binary 10 and the bit in position 1
is 1
bitRead(4, 1); // returns 0 because 4 is binary 100 and the bit in position 1
is 0
7KHUHLVDOVRDIXQFWLRQFDOOHGbitWKDWUHWXUQVWKHYDOXHRIHDFKELWSRVLWLRQ
bit(0)
bit(1)
bit(2)
...
bit(7)
is equal to 1;
is equal to 2;
is equql to 4;
is equal to 128
See Also
$UGXLQRUHIHUHQFHVIRUELWDQGE\WHIXQFWLRQV
lowByte
KWWSZZZDUGXLQRFFHQ5HIHUHQFH/RZ%\WH
highByte
KWWSDUGXLQRFFHQ5HIHUHQFH+LJK%\WH
bitRead
KWWSZZZDUGXLQRFFHQ5HIHUHQFH%LW5HDG
bitWrite
KWWSDUGXLQRFFHQ5HIHUHQFH%LW:ULWH
bitSet
KWWSDUGXLQRFFHQ5HIHUHQFH%LW6HW
bitClear
KWWSDUGXLQRFFHQ5HIHUHQFH%LW&OHDU
bit
KWWSDUGXLQRFFHQ5HIHUHQFH%LW
3.13 Shifting Bits
Problem
<RXQHHGWRSHUIRUPELWRSHUDWLRQVWKDWVKLIWELWVOHIWRUULJKWLQDbyteintRUlong
3.13 Shifting Bits | 75
Solution
8VHWKH<< ELWVKLIWOHIW DQG>> ELWVKLIWULJKW RSHUDWRUVWRVKLIWWKHELWVRIDYDOXH
Discussion
7KLVIUDJPHQWVHWVYDULDEOHxHTXDOWR,WVKLIWVWKHELWVOHIWE\RQHDQGSULQWVWKHQHZ
YDOXH 12 7KHQWKDWYDOXHLVVKLIWHGULJKWWZRSODFHV DQGLQWKLVH[DPSOHEHFRPHV
HTXDOWR3 int x = 6;
int result = x << 1; // 6 shifted left 1 is 12
Serial.println(result);
int result = x >> 2;
// 12 shifted right 2 is 3;
Serial.println(result);
+HUHLVKRZWKLVZRUNVVKLIWHGOHIWRQHSODFHHTXDOVEHFDXVHWKHGHFLPDOQXPEHU
LVLQELQDU\:KHQWKHGLJLWVDUHVKLIWHGOHIWWKHYDOXHEHFRPHV GHFLPDO
6KLIWLQJULJKWWZRSODFHVEHFRPHV GHFLPDO <RXPD\QRWLFHWKDW
VKLIWLQJDQXPEHUOHIWE\QSODFHVLVWKHVDPHDVPXOWLSO\LQJWKHYDOXHE\UDLVHGWRWKH
SRZHURIQ6KLIWLQJDQXPEHUULJKWE\QSODFHVLVWKHVDPHDVGLYLGLQJWKHYDOXHE\
UDLVHGWRWKHSRZHURIQ,QRWKHUZRUGVWKHIROORZLQJSDLUVRIH[SUHVVLRQVDUHWKHVDPH
x << 1LVWKHVDPHDVx * 2
x << 2LVWKHVDPHDVx * 4
x << 3LVWKHVDPHDVx * 8
x >> 1LVWKHVDPHDVx / 2
x >> 2LVWKHVDPHDVx / 4
x >> 3LVWKHVDPHDVx / 8
7KH$UGXLQRFRQWUROOHUFKLSFDQVKLIWELWVPRUHHIILFLHQWO\WKDQLWFDQPXOWLSO\DQG
GLYLGHDQG\RXPD\FRPHDFURVVFRGHWKDWXVHVWKHELWVKLIWWRPXOWLSO\DQGGLYLGH
int c = (a << 1) + (b >> 2); //add (a times 2) plus ( b divided by 4)
7KHH[SUHVVLRQ(a << 1) + (b >> 2);GRHVQRWORRNPXFKOLNH(a * 2) + (b / 4);EXW
ERWKH[SUHVVLRQVGRWKHVDPHWKLQJ,QGHHGWKH$UGXLQRFRPSLOHULVVPDUWHQRXJKWR
UHFRJQL]HWKDWVKLIWLQJDQLQWHJHUE\DFRQVWDQWWKDWLVDSRZHURIWZRLVLGHQWLFDOWRD
VKLIWDQGZLOOSURGXFHWKHVDPHPDFKLQHFRGHDVWKHYHUVLRQXVLQJVKLIW7KHVRXUFH
FRGHXVLQJDULWKPHWLFRSHUDWRUVLVHDVLHUIRUKXPDQVWRUHDGVRLWLVSUHIHUUHGZKHQWKH
LQWHQWLVWRPXOWLSO\DQGGLYLGH
See Also
$UGXLQRUHIHUHQFHVIRUELWDQGE\WHIXQFWLRQV lowByte highByte bitRead bitWrite
bitSetbitClearDQGbit VHH5HFLSH
76 | Chapter 3:ಗUsing Mathematical Operators
3.14 Extracting High and Low Bytes in an int or long
Problem
<RXZDQWWRH[WUDFWWKHKLJKE\WHRUORZE\WHRIDQLQWHJHUIRUH[DPSOHZKHQVHQGLQJ
LQWHJHUYDOXHVDVE\WHVRQDVHULDORURWKHUFRPPXQLFDWLRQOLQH
Solution
8VHlowByte(i)WRJHWWKHOHDVWVLJQLILFDQWE\WHIURPDQLQWHJHU8VHhighByte(i)WRJHW
WKHPRVWVLJQLILFDQWE\WHIURPDQLQWHJHU
7KHIROORZLQJVNHWFKFRQYHUWVDQLQWHJHUYDOXHLQWRORZDQGKLJKE\WHV
//ByteOperators
int intValue = 258; // 258 in hexadecimal notation is 0x102
void setup()
{
Serial.begin(9600);
}
void loop()
{
int loWord,hiWord;
byte loByte, hiByte;
hiByte = highByte(intValue);
loByte = lowByte(intValue);
Serial.println(intValue,DEC);
Serial.println(intValue,HEX);
Serial.println(loByte,DEC);
Serial.println(hiByte,DEC);
}
delay(10000); // wait a very long time
Discussion
7KHH[DPSOHVNHWFKSULQWVintValueIROORZHGE\WKHORZE\WHDQGKLJKE\WH
258
102
2
1
// the integer value to be converted
// the value in hexadecimal notation
// the low byte
// the high byte
7RH[WUDFWWKHE\WHYDOXHVIURPDlongWKHELWORQJYDOXHILUVWJHWVEURNHQLQWRWZR
ELWZRUGVZKLFKFDQWKHQEHFRQYHUWHGLQWRE\WHVDVVKRZQLQWKHHDUOLHUFRGH$W
WKHWLPHRIWKLVZULWLQJWKHVWDQGDUG$UGXLQROLEUDU\GLGQRWKDYHDIXQFWLRQWRSHUIRUP
3.14 Extracting High and Low Bytes in an int or long | 77
WKLVRSHUDWLRQRQDlongEXW\RXFDQDGGWKHIROORZLQJOLQHVWR\RXUVNHWFKWRSURYLGH
WKLV
#define highWord(w) ((w) >> 16)
#define lowWord(w) ((w) & 0xffff)
7KHVHDUHPDFURH[SUHVVLRQVhiWordSHUIRUPVDELWVKLIWRSHUDWLRQWRSURGXFHD
ELWYDOXHDQG lowWord PDVNV WKH ORZHU ELWV XVLQJ WKH ELWZLVH$QGRSHUDWRU VHH
5HFLSH 7KHQXPEHURIELWVLQDQintYDULHVRQGLIIHUHQWSODWIRUPV2Q$UGXLQR
LWLVELWVEXWLQRWKHUHQYLURQPHQWVLWLVELWV7KHWHUPZRUGDV
XVHGKHUHUHIHUVWRDELWYDOXH
7KLVFRGHFRQYHUWVWKHELWKH[YDOXH[WRLWVELWFRQVWLWXHQWKLJKDQG
ORZYDOXHV
loword = lowWord(longValue);
hiword = highWord(longValue);
Serial.println(loword,DEC);
Serial.println(hiword,DEC);
7KLVSULQWVWKHIROORZLQJYDOXHV
772
258
// 772 is 0x0304 in hexadecimal
// 258 is 0x0102 in hexadecimal
1RWHWKDWLQGHFLPDOLV[LQKH[DGHFLPDOZKLFKLVWKHORZRUGHUZRUG ELWV RIWKHlongValue 0x1020304<RXPD\UHFRJQL]HIURPWKHILUVWSDUWRIWKLVUHFLSH
DVWKHYDOXHSURGXFHGE\FRPELQLQJDKLJKE\WHRIDQGDORZE\WHRI [LQ
KH[DGHFLPDO See Also
$UGXLQRUHIHUHQFHVIRUELWDQGE\WHIXQFWLRQV lowByte highByte bitRead bitWrite
bitSetbitClearDQGbit VHH5HFLSH
3.15 Forming an int or long from High and Low Bytes
Problem
<RXZDQWWRFUHDWHDELW int RUELW long LQWHJHUYDOXHIURPLQGLYLGXDOE\WHV
IRUH[DPSOHZKHQUHFHLYLQJLQWHJHUVDVLQGLYLGXDOE\WHVRYHUDVHULDOFRPPXQLFDWLRQ
OLQN7KLVLVWKHLQYHUVHRSHUDWLRQRI5HFLSH
78 | Chapter 3:ಗUsing Mathematical Operators
Solution
8VHWKHword(h,l)IXQFWLRQWRFRQYHUWWZRE\WHVLQWRDVLQJOH$UGXLQRLQWHJHU+HUHLV
WKHFRGHIURP5HFLSHH[SDQGHGWRFRQYHUWWKHLQGLYLGXDOKLJKDQGORZE\WHVEDFN
LQWRDQLQWHJHU
//ByteOperators
int intValue = 0x102;
// 258
void setup()
{
Serial.begin(9600);
}
void loop()
{
int loWord,hiWord;
byte loByte, hiByte;
hiByte = highByte(intValue);
loByte = lowByte(intValue);
Serial.println(intValue,DEC);
Serial.println(loByte,DEC);
Serial.println(hiByte,DEC);
loWord = word(hiByte, loByte);
// convert the bytes back into a word
Serial.println(loWord,DEC);
delay(10000); // wait a very long time
}
Discussion
7KHword(high,low)H[SUHVVLRQDVVHPEOHVDKLJKDQGORZE\WHLQWRDELWYDOXH7KH
FRGHLQWKLVUHFLSH¦V6ROXWLRQWDNHVWKHORZDQGKLJKE\WHVIRUPHGDVVKRZQLQ5HF
LSHDQGDVVHPEOHVWKHPEDFNLQWRDZRUG7KHRXWSXWLVWKHLQWHJHUYDOXHWKH
ORZE\WHWKHKLJKE\WHDQGWKHE\WHVFRQYHUWHGEDFNWRDQLQWHJHUYDOXH
258
2
1
258
$UGXLQRGRHVQRWKDYHDIXQFWLRQWRPDNHDELWORQJYDOXHWZRELWZRUGV DWWKH
WLPHRIWKLVZULWLQJ EXW\RXFDQDGG\RXURZQ makeLong()FDSDELOLW\E\DGGLQJWKH
IROORZLQJOLQHWRWKHWRSRI\RXUVNHWFK
#define makeLong(hi, low)
((hi) << 16 & (low))
3.15 Forming an int or long from High and Low Bytes | 79
7KLVGHILQHVDFRPPDQGWKDWZLOOVKLIWWKHKLJKYDOXHELWVWRWKHOHIWDQGDGGLWWR
WKHORZYDOXH
#define makeLong(hi, low) (((long) hi) << 16 | (low))
#define highWord(w) ((w) >> 16)
#define lowWord(w) ((w) & 0xffff)
// declare a value to test
long longValue = 0x1020304; // in decimal: 16909060
// in binary : 00000001 00000010 00000011 00000100
void setup()
{
Serial.begin(9600);
}
void loop()
{
int loWord,hiWord;
Serial.println(longValue,DEC); // this prints 16909060
loWord = lowWord(longValue);
// convert long to two words
hiWord = highWord(longValue);
Serial.println(loWord,DEC);
// print the value 772
Serial.println(hiWord,DEC);
// print the value 258
longValue = makeLong( hiWord, loWord); // convert the words back to a long
Serial.println(longValue,DEC); // this again prints 16909060
}
delay(10000); // wait a very long time
7KHRXWSXWLV
16909060
772
258
16909060
See Also
$UGXLQRUHIHUHQFHVIRUELWDQGE\WHIXQFWLRQV lowByte highByte bitRead bitWrite
bitSetbitClearDQGbit VHH5HFLSH
80 | Chapter 3:ಗUsing Mathematical Operators
CHAPTER 4
Serial Communications
4.0 Introduction
6HULDOFRPPXQLFDWLRQVSURYLGHDQHDV\DQGIOH[LEOHZD\IRU\RXU$UGXLQRERDUGWR
LQWHUDFWZLWK\RXUFRPSXWHUDQGRWKHUGHYLFHV7KLVFKDSWHUH[SODLQVKRZWRVHQGDQG
UHFHLYHLQIRUPDWLRQXVLQJWKLVFDSDELOLW\
&KDSWHUGHVFULEHGKRZWRFRQQHFWWKH$UGXLQRVHULDOSRUWWR\RXUFRPSXWHUWRXSORDG
VNHWFKHV7KHXSORDGSURFHVVVHQGVGDWDIURP\RXUFRPSXWHUWR$UGXLQRDQG$UGXLQR
VHQGVVWDWXVPHVVDJHVEDFNWRWKHFRPSXWHUWRFRQILUPWKHWUDQVIHULVZRUNLQJ7KH
UHFLSHVKHUHVKRZKRZ\RXFDQXVHWKLVFRPPXQLFDWLRQOLQNWRVHQGDQGUHFHLYHDQ\
LQIRUPDWLRQEHWZHHQ$UGXLQRDQG\RXUFRPSXWHURUDQRWKHUVHULDOGHYLFH
6HULDOFRPPXQLFDWLRQVDUHDOVRDKDQG\WRROIRUGHEXJJLQJ<RXFDQ
VHQGGHEXJPHVVDJHVIURP$UGXLQRWRWKHFRPSXWHUDQGGLVSOD\WKHP
RQ\RXUFRPSXWHUVFUHHQ
7KH$UGXLQR,'( GHVFULEHGLQ5HFLSH SURYLGHVD6HULDO0RQLWRU VKRZQLQ)LJ
XUH WRGLVSOD\VHULDOGDWDUHFHLYHGE\$UGXLQR
<RXFDQDOVRVHQGGDWDIURPWKH6HULDO0RQLWRUWR$UGXLQRE\HQWHULQJWH[WLQWKHWH[W
ER[WRWKHOHIWRIWKH6HQGEXWWRQ%DXGUDWHLVVHOHFWHGXVLQJWKHGURSGRZQER[RQ
WKHERWWRPULJKW<RXFDQXVHWKHGURSGRZQODEHOHG£1ROLQHHQGLQJ¤WRDXWRPDWLFDOO\
VHQGDFDUULDJHUHWXUQRUDFRPELQDWLRQRIDFDUULDJHUHWXUQDQGDOLQHDWWKHHQGRIHDFK
PHVVDJHVHQWZKHQFOLFNLQJWKH6HQGEXWWRQ
<RXU$UGXLQRVNHWFKFDQXVHWKHVHULDOSRUWWRLQGLUHFWO\DFFHVV XVXDOO\YLDDSUR[\
SURJUDPZULWWHQLQDODQJXDJHOLNH3URFHVVLQJ DOOWKHUHVRXUFHV PHPRU\VFUHHQNH\
ERDUGPRXVHQHWZRUNFRQQHFWLYLW\HWF WKDW\RXUFRPSXWHUKDV<RXUFRPSXWHUFDQ
DOVRXVHWKHVHULDOOLQNWRLQWHUDFWZLWKVHQVRUVRURWKHUGHYLFHVFRQQHFWHGWR$UGXLQR
,PSOHPHQWLQJVHULDOFRPPXQLFDWLRQVLQYROYHVKDUGZDUHDQGVRIWZDUH7KHKDUGZDUH
SURYLGHVWKHHOHFWULFDOVLJQDOLQJEHWZHHQ$UGXLQRDQGWKHGHYLFHLWLVWDONLQJWR7KH
81
)LJXUH$UGXLQR6HULDO0RQLWRUVFUHHQ
VRIWZDUHXVHVWKHKDUGZDUHWRVHQGE\WHVRUELWVWKDWWKHFRQQHFWHGKDUGZDUHXQGHU
VWDQGV7KH$UGXLQRVHULDOOLEUDULHVLQVXODWH\RXIURPPRVWRIWKHKDUGZDUHFRPSOH[LW\
EXWLWLVKHOSIXOIRU\RXWRXQGHUVWDQGWKHEDVLFVHVSHFLDOO\LI\RXQHHGWRWURXEOHVKRRW
DQ\GLIILFXOWLHVZLWKVHULDOFRPPXQLFDWLRQVLQ\RXUSURMHFWV
Serial Hardware
6HULDOKDUGZDUHVHQGVDQGUHFHLYHVGDWDDVHOHFWULFDOSXOVHVWKDWUHSUHVHQWVHTXHQWLDO
ELWV7KH]HURVDQGRQHVWKDWFDUU\WKHLQIRUPDWLRQWKDWPDNHVXSDE\WHFDQEHUHSUH
VHQWHGLQYDULRXVZD\V7KHVFKHPHXVHGE\$UGXLQRLVYROWVWRUHSUHVHQWDELWYDOXH
RIDQGYROWV RUYROWV WRUHSUHVHQWDELWYDOXHRI
8VLQJYROWV IRU DQGYROWV IRU LVYHU\FRPPRQ7KLVLVUHIHUUHG
WRDVWKH77/OHYHOEHFDXVHWKDWZDVKRZVLJQDOVZHUHUHSUHVHQWHGLQ
RQH RI WKH ILUVW LPSOHPHQWDWLRQV RI GLJLWDO ORJLF FDOOHG 7UDQVLVWRU
7UDQVLVWRU/RJLF 77/ %RDUGVLQFOXGLQJWKH8QR'XHPLODQRYH'LHFLPLOD1DQRDQG0HJDKDYHDFKLSWR
FRQYHUWWKHKDUGZDUHVHULDOSRUWRQWKH$UGXLQRFKLSWR8QLYHUVDO6HULDO%XV 86% IRU
FRQQHFWLRQWRWKHKDUGZDUHVHULDOSRUW2WKHUERDUGVVXFKDVWKH0LQL3UR3UR0LQL
%RDUGXLQR6DQJXLQRDQG0RGHUQ'HYLFH%DUH%RQHV%RDUGGRQRWKDYH86%VXSSRUW
DQGUHTXLUHDQDGDSWHUIRUFRQQHFWLQJWR\RXUFRPSXWHUWKDWFRQYHUWV77/WR86%6HH
KWWSZZZDUGXLQRFFHQ0DLQ+DUGZDUHIRUPRUHGHWDLOVRQWKHVHERDUGV
82 | Chapter 4:ಗSerial Communications
6RPHSRSXODU86%DGDSWHUVLQFOXGH
0LQL86%$GDSWHU KWWSDUGXLQRFFHQ0DLQ0LQL86%
)7',86%77/$GDSWHU KWWSZZZIWGLFKLSFRP3URGXFWV)75KWP
0RGHUQ'HYLFH86%%8%ERDUG KWWSVKRSPRGHUQGHYLFHFRPSURGXFWVXVEEXE
6RPHVHULDOGHYLFHVXVHWKH56VWDQGDUGIRUVHULDOFRQQHFWLRQ7KHVHXVXDOO\KDYH
DQLQHSLQFRQQHFWRUDQGDQDGDSWHULVUHTXLUHGWRXVHWKHPZLWKWKH$UGXLQR56
LVDQROGDQGYHQHUDWHGFRPPXQLFDWLRQVSURWRFROWKDWXVHVYROWDJHOHYHOVQRWFRPSDW
LEOHZLWK$UGXLQRGLJLWDOSLQV
<RXFDQEX\$UGXLQRERDUGVWKDWDUHEXLOWIRU56VLJQDOOHYHOVVXFKDVWKH)UHH
GXLQR6HULDOY KWWSZZZQNFHOHFWURQLFVFRPIUHHGXLQRVHULDOYERDUGNLWDUGXL
QRGLHFLPLODFRPSDWLEKWPO 56DGDSWHUVWKDWFRQQHFW56VLJQDOVWR$UGXLQR9 RU9 SLQVLQFOXGHWKH
IROORZLQJ
56 WR 77/ 99 DGDSWHU KWWSZZZQNFHOHFWURQLFVFRPUVWRWWOFRQ
YHUWHUERDUGYKWPO
356WR77/6HULDO$GDSWHU.LWV KWWSVKRSPRGHUQGHYLFHFRPSURGXFWVS
56 6KLIWHU 60' KWWSZZZVSDUNIXQFRPFRPPHUFHSURGXFWBLQIRSKS"SURG
XFWVBLG $VWDQGDUG$UGXLQRKDVDVLQJOHKDUGZDUHVHULDOSRUWEXWVHULDOFRPPXQLFDWLRQLVDOVR
SRVVLEOHXVLQJVRIWZDUHOLEUDULHVWRHPXODWHDGGLWLRQDOSRUWV FRPPXQLFDWLRQFKDQQHOV
WRSURYLGHFRQQHFWLYLW\WRPRUHWKDQRQHGHYLFH6RIWZDUHVHULDOUHTXLUHVDORWRIKHOS
IURPWKH$UGXLQRFRQWUROOHUWRVHQGDQGUHFHLYHGDWDVRLW¦VQRWDVIDVWRUHIILFLHQWDV
KDUGZDUHVHULDO
7KH$UGXLQR0HJDKDVIRXUKDUGZDUHVHULDOSRUWVWKDWFDQFRPPXQLFDWHZLWKXSWR
IRXUGLIIHUHQWVHULDOGHYLFHV2QO\RQHRIWKHVHKDVD86%DGDSWHUEXLOWLQ \RXFRXOG
ZLUHD86%77/DGDSWHUWRDQ\RIWKHRWKHUVHULDOSRUWV 7DEOHVKRZVWKHSRUW
QDPHVDQGSLQVXVHGIRUDOORIWKH0HJDVHULDOSRUWV
7DEOH$UGXLQR0HJDVHULDOSRUWV
Port name
Transmit pin
Receive pin
Serial
1 (also USB)
0 (also USB)
Serial1
18
19
Serial2
16
17
Serial3
14
15
4.0 Introduction | 83
Software Serial
<RXZLOOXVXDOO\XVHWKHEXLOWLQ$UGXLQRVHULDOOLEUDU\WRFRPPXQLFDWHZLWKWKHKDUG
ZDUHVHULDOSRUWV6HULDOOLEUDULHVVLPSOLI\WKHXVHRIWKHVHULDOSRUWVE\LQVXODWLQJ\RX
IURPKDUGZDUHFRPSOH[LWLHV
6RPHWLPHV\RXQHHGPRUHVHULDOSRUWVWKDQWKHQXPEHURIKDUGZDUHVHULDOSRUWVDYDLO
DEOH,IWKLVLVWKHFDVH\RXFDQXVHDQDGGLWLRQDOOLEUDU\WKDWXVHVVRIWZDUHWRHPXODWH
VHULDOKDUGZDUH5HFLSHVDQGVKRZKRZWRXVHDVRIWZDUHVHULDOOLEUDU\WR
FRPPXQLFDWHZLWKPXOWLSOHGHYLFHV
Serial Message Protocol
7KHKDUGZDUHRUVRIWZDUHVHULDOOLEUDULHVKDQGOHVHQGLQJDQGUHFHLYLQJLQIRUPDWLRQ
7KLVLQIRUPDWLRQRIWHQFRQVLVWVRIJURXSVRIYDULDEOHVWKDWQHHGWREHVHQWWRJHWKHU)RU
WKHLQIRUPDWLRQWREHLQWHUSUHWHGFRUUHFWO\WKHUHFHLYLQJVLGHQHHGVWRUHFRJQL]HZKHUH
HDFK PHVVDJH EHJLQV DQG HQGV 0HDQLQJIXO VHULDO FRPPXQLFDWLRQ RU DQ\ NLQG RI
PDFKLQHWRPDFKLQHFRPPXQLFDWLRQFDQRQO\EHDFKLHYHGLIWKHVHQGLQJDQGUHFHLYLQJ
VLGHVIXOO\DJUHHKRZLQIRUPDWLRQLVRUJDQL]HGLQWKHPHVVDJH7KHIRUPDORUJDQL]DWLRQ
RILQIRUPDWLRQLQDPHVVDJHDQGWKHUDQJHRIDSSURSULDWHUHVSRQVHVWRUHTXHVWVLVFDOOHG
DFRPPXQLFDWLRQVSURWRFRO
0HVVDJHVFDQFRQWDLQRQHRUPRUHVSHFLDOFKDUDFWHUVWKDWLGHQWLI\WKHVWDUWRIWKHPHV
VDJH¢WKLVLVFDOOHGWKHKHDGHU2QHRUPRUHFKDUDFWHUVFDQDOVREHXVHGWRLGHQWLI\WKH
HQGRIDPHVVDJH¢WKLVLVFDOOHGWKHIRRWHU7KHUHFLSHVLQWKLVFKDSWHUVKRZH[DPSOHV
RIPHVVDJHVLQZKLFKWKHYDOXHVWKDWPDNHXSWKHERG\RIDPHVVDJHFDQEHVHQWLQ
HLWKHUWH[WRUELQDU\IRUPDW
6HQGLQJDQGUHFHLYLQJPHVVDJHVLQWH[WIRUPDWLQYROYHVVHQGLQJFRPPDQGVDQGQX
PHULFYDOXHVDVKXPDQUHDGDEOHOHWWHUVDQGZRUGV1XPEHUVDUHVHQWDVWKHVWULQJRI
GLJLWVWKDWUHSUHVHQWWKHYDOXH)RUH[DPSOHLIWKHYDOXHLVWKHFKDUDFWHUV
DQGDUHVHQWDVLQGLYLGXDOFKDUDFWHUV
%LQDU\PHVVDJHVFRPSULVHWKHE\WHVWKDWWKHFRPSXWHUXVHVWRUHSUHVHQWYDOXHV%LQDU\
GDWDLVXVXDOO\PRUHHIILFLHQW UHTXLULQJIHZHUE\WHVWREHVHQW EXWWKHGDWDLVQRWDV
KXPDQUHDGDEOHDVWH[WZKLFKPDNHVLWPRUHGLIILFXOWWRGHEXJ)RUH[DPSOH$UGXLQR
UHSUHVHQWVDVWKHE\WHVDQG ,IWKHGHYLFH\RXDUH
FRQQHFWLQJWRVHQGVRUUHFHLYHVRQO\ELQDU\GDWDWKDWLVZKDW\RXZLOOKDYHWRXVHEXW
LI\RXKDYHWKHFKRLFHWH[WPHVVDJHVDUHHDVLHUWRLPSOHPHQWDQGGHEXJ
84 | Chapter 4:ಗSerial Communications
7KHUHDUHPDQ\ZD\VWRDSSURDFKVRIWZDUHSUREOHPVDQGVRPHRIWKHUHFLSHVLQWKLV
FKDSWHUVKRZWZRRUWKUHHGLIIHUHQWZD\VWRDFKLHYHDVLPLODUUHVXOW7KHGLIIHUHQFHV
HJVHQGLQJWH[WLQVWHDGRIUDZELQDU\GDWD PD\RIIHUDGLIIHUHQWEDODQFHEHWZHHQ
VLPSOLFLW\DQGHIILFLHQF\:KHUHFKRLFHVDUHRIIHUHGSLFNWKHVROXWLRQWKDW\RXILQG
HDVLHVWWRXQGHUVWDQGDQGDGDSW¢WKLVZLOOSUREDEO\EHWKHILUVWVROXWLRQFRYHUHG$O
WHUQDWLYHVPD\EHDOLWWOHPRUHHIILFLHQWRUWKH\PD\EHPRUHDSSURSULDWHIRUDVSHFLILF
SURWRFROWKDW\RXZDQWWRFRQQHFWWREXWWKH£ULJKWZD\¤LVWKHRQH\RXILQGHDVLHVWWR
JHWZRUNLQJLQ\RXUSURMHFW
The Processing Development Environment
6RPHRIWKHH[DPSOHVLQWKLVFKDSWHUXVHWKH3URFHVVLQJODQJXDJHWRVHQGDQGUHFHLYH
VHULDOPHVVDJHVRQDFRPSXWHUWDONLQJWR$UGXLQR
3URFHVVLQJLVDIUHHRSHQVRXUFHWRROWKDWXVHVDVLPLODUGHYHORSPHQWHQYLURQPHQWWR
$UGXLQR<RXFDQUHDGPRUHDERXW3URFHVVLQJDQGGRZQORDGHYHU\WKLQJ\RXQHHGDW
WKH3URFHVVLQJZHEVLWH
3URFHVVLQJLVEDVHGRQWKH-DYDODQJXDJHEXWWKH3URFHVVLQJFRGHVDPSOHVLQWKLVERRN
VKRXOGEHHDV\WRWUDQVODWHLQWRRWKHUHQYLURQPHQWVWKDWVXSSRUWVHULDOFRPPXQLFD
WLRQV 3URFHVVLQJ FRPHV ZLWK VRPH H[DPSOH VNHWFKHV LOOXVWUDWLQJ FRPPXQLFDWLRQ
EHWZHHQ$UGXLQRDQG3URFHVVLQJ6LPSOH5HDGLVD3URFHVVLQJH[DPSOHWKDWLQFOXGHV
$UGXLQRFRGH,Q3URFHVVLQJVHOHFW)LOHൺ([DPSOHVൺ/LEUDULHVൺ6HULDOൺ6LPSOH5HDGWR
VHHDQH[DPSOHWKDWUHDGVGDWDIURPWKHVHULDOSRUWDQGFKDQJHVWKHFRORURIDUHFWDQJOH
ZKHQDVZLWFKFRQQHFWHGWR$UGXLQRLVSUHVVHGDQGUHOHDVHG
See Also
$Q$UGXLQR56WXWRULDOLVDYDLODEOHDWKWWSZZZDUGXLQRFFHQ7XWRULDO$UGXLQR
6RIWZDUH56/RWVRILQIRUPDWLRQDQGOLQNVDUHDYDLODEOHDWWKH6HULDO3RUW&HQWUDO
ZHEVLWHKWWSZZZOYUFRPVHUSRUWKWP
,QDGGLWLRQDQXPEHURIERRNVRQ3URFHVVLQJDUHDOVRDYDLODEOH
*HWWLQJ6WDUWHGZLWK3URFHVVLQJ$4XLFN+DQGVRQ,QWURGXFWLRQE\&DVH\5HDVDQG
%HQ)U\ 0DNH 3URFHVVLQJ$3URJUDPPLQJ+DQGERRNIRU9LVXDO'HVLJQHUVDQG$UWLVWVE\&DVH\
5HDVDQG%HQ)U\ 0,73UHVV 9LVXDOL]LQJ'DWDE\%HQ)U\ 2¦5HLOO\ 3URFHVVLQJ&UHDWLYH&RGLQJDQG&RPSXWDWLRQDO$UWE\,UD*UHHQEHUJ $SUHVV 0DNLQJ7KLQJV7DONE\7RP,JRH 0DNH 7KLVERRNFRYHUV3URFHVVLQJDQG$UGXLQR
DQGSURYLGHVPDQ\H[DPSOHVRIFRPPXQLFDWLRQFRGH
4.0 Introduction | 85
4.1 Sending Debug Information from Arduino to
Your Computer
Problem
<RXZDQWWRVHQGWH[WDQGGDWDWREHGLVSOD\HGRQ\RXU3&RU0DFXVLQJWKH$UGXLQR
,'(RUWKHVHULDOWHUPLQDOSURJUDPRI\RXUFKRLFH
Solution
7KLVVNHWFKSULQWVVHTXHQWLDOQXPEHUVRQWKH6HULDO0RQLWRU
/*
* SerialOutput sketch
* Print numbers to the serial port
*/
void setup()
{
Serial.begin(9600); // send and receive at 9600 baud
}
int number = 0;
void loop()
{
Serial.print("The number is ");
Serial.println(number);
// print the number
}
delay(500); // delay half second between numbers
number++; // to the next number
&RQQHFW$UGXLQRWR\RXUFRPSXWHUMXVWDV\RXGLGLQ&KDSWHUDQGXSORDGWKLVVNHWFK
&OLFNWKH6HULDO0RQLWRULFRQLQWKH,'(DQG\RXVKRXOGVHHWKHRXWSXWGLVSOD\HGDV
IROORZV
The number is 0
The number is 1
The number is 2
Discussion
7RSULQWWH[WDQGQXPEHUVIURP\RXUVNHWFKSXWWKHSerial.begin(9600)VWDWHPHQWLQ
setup()DQGWKHQXVHSerial.print()VWDWHPHQWVWRSULQWWKHWH[WDQGYDOXHV\RXZDQW
WRVHH
7KH$UGXLQR6HULDO0RQLWRUIXQFWLRQFDQGLVSOD\VHULDOGDWDVHQWIURP$UGXLQR7R
VWDUWWKH6HULDO0RQLWRUFOLFNWKH6HULDO0RQLWRUWRROEDULFRQDVVKRZQLQ)LJXUH
$QHZZLQGRZZLOORSHQIRUGLVSOD\LQJRXWSXWIURP$UGXLQR
86 | Chapter 4:ಗSerial Communications
)LJXUH&OLFNLQJWKH6HULDO0RQLWRULFRQWRVHHVHULDORXWSXW
<RXU VNHWFK PXVW FDOO WKH Serial.begin() IXQFWLRQ EHIRUH LW FDQ XVH VHULDO LQSXW RU
RXWSXW7KHIXQFWLRQWDNHVDVLQJOHSDUDPHWHUWKHGHVLUHGFRPPXQLFDWLRQVSHHG<RX
PXVWXVHWKHVDPHVSHHGIRUWKHVHQGLQJVLGHDQGWKHUHFHLYLQJVLGHRU\RXZLOOVHH
JREEOHG\JRRN RUQRWKLQJDWDOO RQWKHVFUHHQ7KLVH[DPSOHDQGPRVWRIWKHRWKHUV
LQWKLVERRNXVHDVSHHGRIEDXG EDXGLVDPHDVXUHRIWKHQXPEHURIELWVWUDQV
PLWWHGSHUVHFRQG 7KHEDXGUDWHLVDSSUR[LPDWHO\FKDUDFWHUVSHUVHFRQG
<RXFDQVHQGDWORZHURUKLJKHUUDWHV WKHUDQJHLVWR EXWPDNHVXUHERWK
VLGHVXVHWKHVDPHVSHHG7KH6HULDO0RQLWRUVHWVWKHVSHHGXVLQJWKHEDXGUDWHGURS
GRZQ DWWKHERWWRPULJKWRIWKH6HULDO0RQLWRUZLQGRZLQ)LJXUH ,I\RXURXWSXW
ORRNVVRPHWKLQJOLNHWKLV
`3??f<ÌxÌႠႠႠü`³??f<
\RXVKRXOGFKHFNWKDWWKHVHOHFWHGEDXGUDWHRQ\RXUFRPSXWHUPDWFKHVWKHUDWHVHWE\
Serial.begin()LQ\RXUVNHWFK
,I\RXUVHQGLQJDQGUHFHLYLQJVHULDOVSHHGVDUHVHWFRUUHFWO\EXW\RXDUH
VWLOOJHWWLQJXQUHDGDEOHWH[WFKHFNWKDW\RXKDYHWKHFRUUHFWERDUGVH
OHFWHGLQWKH,'(7RROVൺ%RDUGPHQX,I\RXKDYHVHOHFWHGWKHZURQJ
ERDUGFKDQJHLWWRWKHFRUUHFWRQHDQGXSORDGWRWKHERDUGDJDLQ
4.1 Sending Debug Information from Arduino to Your Computer | 87
<RXFDQGLVSOD\WH[WXVLQJWKH Serial.print()IXQFWLRQ6WULQJV WH[WZLWKLQGRXEOH
TXRWHV ZLOOEHSULQWHGDVLV EXWZLWKRXWWKHTXRWHV )RUH[DPSOHWKHIROORZLQJFRGH
Serial.print("The number is ");
SULQWVWKLV
The number is
7KHYDOXHV QXPEHUV WKDW\RXSULQWGHSHQGRQWKHW\SHRIYDULDEOHVHH5HFLSHIRU
PRUHDERXWWKLV%XWIRUQRZSULQWLQJDQLQWHJHUZLOOSULQWLWVQXPHULFYDOXHVRLIWKH
YDULDEOHnumberLV1WKHIROORZLQJFRGH
Serial.println(number);
ZLOOSULQWWKLV
1
,Q WKH H[DPSOH VNHWFK WKH QXPEHU SULQWHG ZLOO EH 0 ZKHQ WKH ORRS VWDUWV DQG ZLOO
LQFUHDVHE\RQHHDFKWLPHWKURXJKWKHORRS7KH lnDWWKHHQGRI printlnFDXVHVWKH
QH[WSULQWVWDWHPHQWWRVWDUWRQDQHZOLQH
7KDWVKRXOGJHW\RXVWDUWHGSULQWLQJWH[WDQGWKHGHFLPDOYDOXHRILQWHJHUV6HH5HF
LSHIRUPRUHGHWDLORQSULQWIRUPDWWLQJRSWLRQV
<RXPD\ZDQWWRFRQVLGHUDWKLUGSDUW\WHUPLQDOSURJUDPWKDWKDVPRUHIHDWXUHVWKDQ
6HULDO0RQLWRU'LVSOD\LQJGDWDLQWH[WRUELQDU\IRUPDW RUERWK GLVSOD\LQJFRQWURO
FKDUDFWHUVDQGORJJLQJWRDILOHDUHMXVWDIHZRIWKHDGGLWLRQDOFDSDELOLWLHVDYDLODEOH
IURPWKHPDQ\WKLUGSDUW\WHUPLQDOSURJUDPV+HUHDUHVRPHWKDWKDYHEHHQUHFRP
PHQGHGE\$UGXLQRXVHUV
&XWH&RP
$QRSHQVRXUFHWHUPLQDOSURJUDPIRU/LQX[
%UD\7HUPLQDO
$IUHHH[HFXWDEOHIRUWKH3&
*18VFUHHQ
$QRSHQVRXUFHYLUWXDOVFUHHQPDQDJHPHQWSURJUDPWKDWVXSSRUWVVHULDOFRPPX
QLFDWLRQVLQFOXGHGZLWK/LQX[DQG0DF26;
PRVHULDO
$QRWKHURSHQVRXUFHWHUPLQDOSURJUDPIRU/LQX[
3X77<
$QRSHQVRXUFH66+SURJUDPIRU:LQGRZVVXSSRUWVVHULDOFRPPXQLFDWLRQV
5HDO7HUP
$QRSHQVRXUFHWHUPLQDOSURJUDPIRUWKH3&
=7HUP
$VKDUHZDUHSURJUDPIRUWKH0DF
88 | Chapter 4:ಗSerial Communications
,QDGGLWLRQDQDUWLFOHLQWKH$UGXLQRZLNLH[SODLQVKRZWRFRQILJXUH/LQX[WRFRP
PXQLFDWHZLWK$UGXLQRXVLQJ77< VHHKWWSZZZDUGXLQRFFSOD\JURXQG,QWHUIDFLQJ
/LQX[77< <RXFDQXVHDOLTXLGFU\VWDOGLVSOD\DVDVHULDORXWSXWGHYLFHDOWKRXJKLWZLOOEHYHU\
OLPLWHGLQIXQFWLRQDOLW\&KHFNWKHGRFXPHQWDWLRQWRVHHKRZ\RXUGLVSOD\KDQGOHV
FDUULDJHUHWXUQVDVVRPHGLVSOD\VPD\QRWDXWRPDWLFDOO\DGYDQFHWRDQHZOLQHDIWHU
printlnVWDWHPHQWV
See Also
7KH$UGXLQR/LTXLG&U\VWDOOLEUDU\IRUWH[W/&'VXVHVXQGHUO\LQJSULQWIXQFWLRQDOLW\
VLPLODUWRWKH6HULDOOLEUDU\VR\RXFDQXVHPDQ\RIWKHVXJJHVWLRQVFRYHUHGLQWKLV
FKDSWHUZLWKWKDWOLEUDU\ VHH&KDSWHU 4.2 Sending Formatted Text and Numeric Data from Arduino
Problem
<RXZDQWWRVHQGVHULDOGDWDIURP$UGXLQRGLVSOD\HGDVWH[WGHFLPDOYDOXHVKH[DGHF
LPDORUELQDU\
Solution
<RXFDQSULQWGDWDWRWKHVHULDOSRUWLQPDQ\GLIIHUHQWIRUPDWVKHUHLVDVNHWFKWKDW
GHPRQVWUDWHVDOOWKHIRUPDWRSWLRQV
/*
* SerialFormatting
* Print values in various formats to the serial port
*/
char chrValue = 65; // these are the starting values to print
int intValue = 65;
float floatValue = 65.0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.println("chrValue: ");
Serial.println(chrValue);
Serial.println(chrValue,BYTE);
Serial.println(chrValue,DEC);
4.2 Sending Formatted Text and Numeric Data from Arduino | 89
Serial.println("intValue: ");
Serial.println(intValue);
Serial.println(intValue,BYTE);
Serial.println(intValue,DEC);
Serial.println(intValue,HEX);
Serial.println(intValue,OCT);
Serial.println(intValue,BIN);
Serial.println("floatValue: ");
Serial.println(floatValue);
}
delay(1000); // delay a second between numbers
chrValue++; // to the next value
intValue++;
7KHRXWSXW FRQGHQVHGKHUHRQWRDIHZOLQHV LVDVIROORZV
chrValue: A A 65
intValue: 65 A 65 41 101 1000001
floatValue: 65.00
chrValue: B B 66
intValue: 66 B 66 42 102 1000010
Discussion
3ULQWLQJ D WH[W VWULQJ LV VLPSOH Serial.print("hello world"); VHQGV WKH WH[W VWULQJ
£KHOORZRUOG¤WRDGHYLFHDWWKHRWKHUHQGRIWKHVHULDOSRUW,I\RXZDQW\RXURXWSXWWR
SULQWDQHZOLQHDIWHUWKHRXWSXWXVHSerial.println()LQVWHDGRISerial.print()
3ULQWLQJQXPHULFYDOXHVFDQEHPRUHFRPSOLFDWHG7KHZD\WKDWE\WHDQGLQWHJHUYDOXHV
DUHSULQWHGGHSHQGVRQWKHW\SHRIYDULDEOHDQGDQRSWLRQDOIRUPDWWLQJSDUDPHWHU7KH
$UGXLQRODQJXDJHLVYHU\HDV\JRLQJDERXWKRZ\RXFDQUHIHUWRWKHYDOXHRIGLIIHUHQW
GDWDW\SHV VHH5HFLSHIRUPRUHRQGDWDW\SHV %XWWKLVIOH[LELOLW\FDQEHFRQIXVLQJ
EHFDXVHHYHQZKHQWKHQXPHULFYDOXHVDUHVLPLODUWKHFRPSLOHUFRQVLGHUVWKHPWREH
VHSDUDWHW\SHVZLWKGLIIHUHQWEHKDYLRUV)RUH[DPSOHSULQWLQJDcharZLOOQRWQHFHVVDULO\
SURGXFHWKHVDPHRXWSXWDVSULQWLQJDQintRIWKHVDPHYDOXH
+HUHDUHVRPHVSHFLILFH[DPSOHVDOORIWKHPFUHDWHYDULDEOHVWKDWKDYHVLPLODUYDOXHV
char asciiValue = 'A';
// ASCII A has a value of 65
char chrValue = 65;
// an 8 bit character, this also is ASCII 'A'
int intValue = 65;
// a 16 bit integer set to a value of 65
float floatValue = 65.0; // float with a value of 65
7DEOHVKRZVZKDW\RXZLOOVHHZKHQ\RXSULQWYDULDEOHVXVLQJ$UGXLQRURXWLQHV
90 | Chapter 4:ಗSerial Communications
7DEOH2XWSXWIRUPDWVXVLQJ6HULDOSULQW
Print
Print
Print
Print
Print
Print
Data type
(val)
(val,DEC)
(val,BYTE)
(val,HEX)
(val,OCT)
(val,BIN)
char
A
65
A
41
101
1000001
int
65
65
A
41
101
1000001
long
Format of long is the same as int
float
65.00
Formatting not supported for floating-point values
double
65.00
double is the same as float
7KHVNHWFKLQWKLVUHFLSHXVHVDVHSDUDWHOLQHRIVRXUFHFRGHIRUHDFKSULQWVWDWHPHQW
7KLVFDQPDNHFRPSOH[SULQWVWDWHPHQWVEXON\)RUH[DPSOHWRSULQWWKHIROORZLQJOLQH
At 5 seconds: speed = 17, distance = 120
\RX¦GW\SLFDOO\KDYHWRFRGHLWOLNHWKLV
Serial.print("At ");
Serial.print(seconds);
Serial.print(" seconds: speed = ");
Serial.print(speed);
Serial.print(", distance = ");
Serial.println(distance);
7KDW¦VDORWRIFRGHOLQHVIRUDVLQJOHOLQHRIRXWSXW<RXFRXOGFRPELQHWKHPOLNHWKLV
Serial.print("At "); Serial.print(seconds); Serial.print(" seconds, speed = ");
Serial.print(speed); Serial.print(", distance = ");Serial.println(distance);
2U \RX FRXOG XVH WKH LQVHUWLRQVW\OH FDSDELOLW\ RI WKH FRPSLOHU XVHG E\ $UGXLQR WR
IRUPDW\RXUSULQWVWDWHPHQWV<RXFDQWDNHDGYDQWDJHRIVRPHDGYDQFHG&FDSD
ELOLWLHV VWUHDPLQJLQVHUWLRQV\QWD[DQGWHPSODWHV WKDW\RXFDQXVHLI\RXGHFODUHD
VWUHDPLQJ WHPSODWH LQ \RXU VNHWFK 7KLV LV PRVW HDVLO\ DFKLHYHG E\ LQFOXGLQJ WKH
6WUHDPLQJOLEUDU\GHYHORSHGE\0LNDO+DUW<RXFDQUHDGPRUHDERXWWKLVOLEUDU\DQG
GRZQORDGWKHFRGHIURP0LNDO¦VZHEVLWH
,I\RXXVHWKH6WUHDPLQJOLEUDU\WKHIROORZLQJJLYHVWKHVDPHRXWSXWDVWKHOLQHVVKRZQ
HDUOLHU
Serial << "At " << seconds << " seconds, speed = " << speed << ", distance =
" << distance;
See Also
&KDSWHUSURYLGHVPRUHLQIRUPDWLRQRQGDWDW\SHVXVHGE\$UGXLQR7KH$UGXLQRZHE
UHIHUHQFHDWKWWSDUGXLQRFFHQ5HIHUHQFH+RPH3DJHFRYHUVWKHVHULDOFRPPDQGVDQG
WKH $UGXLQR ZHE UHIHUHQFH DW KWWSZZZDUGXLQRFFSOD\JURXQG0DLQ6WUHDPLQJ2XW
SXWFRYHUVVWUHDPLQJ LQVHUWLRQVW\OH RXWSXW
4.2 Sending Formatted Text and Numeric Data from Arduino | 91
4.3 Receiving Serial Data in Arduino
Problem
<RXZDQWWRUHFHLYHGDWDRQ$UGXLQRIURPDFRPSXWHURUDQRWKHUVHULDOGHYLFHIRU
H[DPSOHWRKDYH$UGXLQRUHDFWWRFRPPDQGVRUGDWDVHQWIURP\RXUFRPSXWHU
Solution
,W¦VHDV\WRUHFHLYHELWYDOXHV FKDUVDQGE\WHV EHFDXVHWKHSerialIXQFWLRQVXVH
ELWYDOXHV7KLVVNHWFKUHFHLYHVDGLJLW VLQJOHFKDUDFWHUVWKURXJK DQGEOLQNVWKH
/('RQSLQDWDUDWHSURSRUWLRQDOWRWKHUHFHLYHGGLJLWYDOXH
/*
* SerialReceive sketch
* Blink the LED at a rate proportional to the received digit value
*/
const int ledPin = 13; // pin the LED is connected to
int blinkRate=0;
// blink rate stored in this variable
void setup()
{
Serial.begin(9600); // Initialize serial port to send and receive at 9600 baud
pinMode(ledPin, OUTPUT); // set this pin as output
}
void loop()
{
if ( Serial.available()) // Check to see if at least one character is available
{
char ch = Serial.read();
if(ch >= '0' && ch <= '9') // is this an ascii digit between 0 and 9?
{
blinkRate = (ch - '0');
// ASCII value converted to numeric value
blinkRate = blinkRate * 100; // actual blinkrate is 100 mS times received
digit
}
}
blink();
}
// blink the LED with the on and off times determined by blinkRate
void blink()
{
digitalWrite(ledPin,HIGH);
delay(blinkRate); // delay depends on blinkrate value
digitalWrite(ledPin,LOW);
delay(blinkRate);
}
8SORDGWKHVNHWFKDQGVHQGPHVVDJHVXVLQJWKH6HULDO0RQLWRU2SHQWKH6HULDO0RQLWRU
E\FOLFNLQJWKH0RQLWRULFRQ VHH5HFLSH DQGW\SHDGLJLWLQWKHWH[WER[DWWKHWRS
92 | Chapter 4:ಗSerial Communications
RIWKH6HULDO0RQLWRUZLQGRZ&OLFNLQJWKH6HQGEXWWRQZLOOVHQGWKHFKDUDFWHUW\SHG
LQWRWKHWH[WER[\RXVKRXOGVHHWKHEOLQNUDWHFKDQJH
Discussion
&RQYHUWLQJWKHUHFHLYHG$6&,,FKDUDFWHUVWRQXPHULFYDOXHVPD\QRWEHREYLRXVLI\RX
DUHQRWIDPLOLDUZLWKWKHZD\$6&,,UHSUHVHQWVFKDUDFWHUV7KHIROORZLQJFRQYHUWVWKH
FKDUDFWHUchWRLWVQXPHULFYDOXH
blinkRate = (ch - '0');
// ASCII value converted to numeric value
7KLVLVGRQHE\VXEWUDFWLQJEHFDXVHLVWKH$6&,,YDOXHRIWKHGLJLW)RUH[DPSOH
LIchLVUHSUHVHQWLQJWKHFKDUDFWHULWV$6&,,YDOXHLV7KHH[SUHVVLRQ49- '0'LVWKH
VDPHDV49-487KLVHTXDOVZKLFKLVWKHQXPHULFYDOXHRIWKHFKDUDFWHU
,QRWKHUZRUGVWKHH[SUHVVLRQ(ch - '0')LVWKHVDPHDV(ch - 48)WKLVFRQYHUWVWKH
$6&,,YDOXHRIWKHYDULDEOHchWRDQXPHULFYDOXH
7RJHWDFOHDUHULGHDRIWKHUHODWLRQVKLSEHWZHHQWKH$6&,,YDOXHVRIFKDUDFWHUVUHSUH
VHQWLQJWKHGLJLWVWKURXJKDQGWKHLUDFWXDOQXPHULFYDOXHVVHHWKH$6&,,WDEOHLQ
$SSHQGL[*
5HFHLYLQJQXPEHUVZLWKPRUHWKDQRQHGLJLWLQYROYHVDFFXPXODWLQJFKDUDFWHUVXQWLOD
FKDUDFWHU WKDW LV QRW D YDOLG GLJLW LV GHWHFWHG 7KH IROORZLQJ FRGH XVHV WKH VDPH
setup()DQGblink()IXQFWLRQVDVWKRVHVKRZQHDUOLHUEXWLWJHWVGLJLWVXQWLOWKHQHZOLQH
FKDUDFWHULVUHFHLYHG,WXVHVWKHDFFXPXODWHGYDOXHWRVHWWKHEOLQNUDWH
7KHQHZOLQHFKDUDFWHU $6&,,YDOXH FDQEHDSSHQGHGDXWRPDWLFDOO\
HDFKWLPH\RXFOLFN6HQG7KH6HULDO0RQLWRUKDVDGURSGRZQER[DW
WKH ERWWRP RIWKH 6HULDO 0RQLWRU VFUHHQ VHH )LJXUH FKDQJHWKH
RSWLRQIURP£1ROLQHHQGLQJ¤WR£1HZOLQH¤
&KDQJHWKHFRGHWKDWWKHloopFRGHIROORZV(QWHUDYDOXHVXFKDV123LQWRWKH0RQLWRU
WH[WER[DQGFOLFN6HQGDQGWKHEOLQNGHOD\ZLOOEHVHWWRPLOOLVHFRQGV
int value;
void loop()
{
if( Serial.available())
{
char ch = Serial.read();
if(ch >= '0' && ch <= '9') // is this an ascii digit between 0 and 9?
{
value = (value * 10) + (ch - '0'); // yes, accumulate the value
}
else if (ch == 10) // is the character the newline character
{
blinkRate = value; // set blinkrate to the accumulated value
Serial.println(blinkRate);
value = 0; // reset val to 0 ready for the next sequence of digits
4.3 Receiving Serial Data in Arduino | 93
}
}
blink();
}
(DFKGLJLWLVFRQYHUWHGIURPLWV$6&,,YDOXHWRLWVQXPHULFYDOXH%HFDXVHWKHQXPEHUV
DUHGHFLPDOQXPEHUV EDVH HDFKVXFFHVVLYHQXPEHULVPXOWLSOLHGE\)RUH[
DPSOHWKHYDOXHRIWKHQXPEHULV 7KHFRGHWRDFFRPSOLVKWKDW
LV
if(ch >= '0' && ch <= '9') // is this an ascii digit between 0 and 9?
{
value = (value * 10) + (ch - '0'); // yes, accumulate the value
}
,I \RX ZDQW WR KDQGOH QHJDWLYH QXPEHUV \RXU FRGH QHHGV WR UHFRJQL]H WKH PLQXV
'-' VLJQ)RUH[DPSOH
int value = 0;
int sign = 1;
void loop()
{
if( Serial.available())
{
char ch = Serial.read();
if(ch >= '0' && ch <= '9') // is this an ascii digit between 0 and 9?
value = (value * 10) + (ch - '0'); // yes, accumulate the value
else if( ch == '-')
sign = -1;
else // this assumes any char not a digit or minus sign terminates the value
{
value = value * sign ; // set value to the accumulated value
Serial.println(value);
value = 0; // reset value to 0 ready for the next sequence of digits
sign = 1;
}
}
}
$QRWKHUDSSURDFKWRFRQYHUWLQJWH[WVWULQJVUHSUHVHQWLQJQXPEHUVLVWRXVHWKH&ODQ
JXDJHFRQYHUVLRQIXQFWLRQFDOOHG atoi IRU intYDULDEOHV RU atol IRU longYDULDEOHV 7KHVHREVFXUHO\QDPHGIXQFWLRQVFRQYHUWDVWULQJLQWRLQWHJHUVRUORQJLQWHJHUV7RXVH
WKHP\RXKDYHWRUHFHLYHDQGVWRUHWKHHQWLUHVWULQJLQDFKDUDFWHUDUUD\EHIRUH\RXFDQ
FDOOWKHFRQYHUVLRQIXQFWLRQ
7KLVFRGHIUDJPHQWWHUPLQDWHVWKHLQFRPLQJGLJLWVRQDQ\FKDUDFWHUWKDWLVQRWDGLJLW
RULIWKHEXIIHULVIXOO const int MaxChars = 5; // an int string contains up to 5 digits and
// is terminated by a 0 to indicate end of string
char strValue[MaxChars+1]; // must be big enough for digits and terminating null
int index = 0;
// the index into the array storing the received digits
void loop()
94 | Chapter 4:ಗSerial Communications
{
}
if( Serial.available())
{
char ch = Serial.read();
if(index < MaxChars && ch >= '0' && ch <= '9'){
strValue[index++] = ch; // add the ASCII character to the string;
}
else
{
// here when buffer full or on the first non digit
strValue[index] = 0;
// terminate the string with a 0
blinkRate = atoi(strValue); // use atoi to convert the string to an int
index = 0;
}
}
blink();
strValueLVDQXPHULFVWULQJEXLOWXSIURPFKDUDFWHUVUHFHLYHGIURPWKHVHULDOSRUW
6HH5HFLSHIRULQIRUPDWLRQDERXWFKDUDFWHUVWULQJV
atoi VKRUWIRU$6&,,WRLQWHJHU LVDIXQFWLRQWKDWFRQYHUWVDFKDUDFWHUVWULQJWRDQ
LQWHJHU atolFRQYHUWVWRDORQJLQWHJHU See Also
$ZHEVHDUFKIRU£DWRL¤RU£DWRO¤SURYLGHVPDQ\UHIHUHQFHVWRWKHVHIXQFWLRQV$OVRVHH
WKH:LNLSHGLDUHIHUHQFHDWKWWSHQZLNLSHGLDRUJZLNL$WRL
4.4 Sending Multiple Text Fields from Arduino in a
Single Message
Problem
<RXZDQWWRVHQGDPHVVDJHWKDWFRQWDLQVPRUHWKDQRQHSLHFHRILQIRUPDWLRQ ILHOG )RUH[DPSOH\RXUPHVVDJHPD\FRQWDLQYDOXHVIURPWZRRUPRUHVHQVRUV<RXZDQW
WRXVHWKHVHYDOXHVLQDSURJUDPVXFKDV3URFHVVLQJUXQQLQJRQ\RXU3&RU0DF
Solution
7KHHDVLHVWZD\WRGRWKLVLVWRVHQGDWH[WVWULQJZLWKDOOWKHILHOGVVHSDUDWHGE\D
GHOLPLWLQJ VHSDUDWLQJ FKDUDFWHUVXFKDVDFRPPD
// CommaDelimitedOutput sketch
void setup()
4.4 Sending Multiple Text Fields from Arduino in a Single Message | 95
{
}
Serial.begin(9600);
void loop()
{
int value1 = 10;
int value2 = 100;
int value3 = 1000;
// some hardcoded values to send
Serial.print('H'); // unique header to identify start of message
Serial.print(",");
Serial.print(value1,DEC);
Serial.print(",");
Serial.print(value2,DEC);
Serial.print(",");
Serial.print(value3,DEC);
Serial.print(","); // note that a comma is sent after the last field
Serial.println(); // send a cr/lf
delay(100);
}
+HUHLVWKH3URFHVVLQJVNHWFKWKDWUHDGVWKLVGDWDIURPWKHVHULDOSRUW
//CommaDelimitedInput.pde (Processing Sketch)
import processing.serial.*;
Serial myPort;
char HEADER = 'H';
short LF = 10;
short portIndex = 0;
// Create object from Serial class
// character to identify the start of a message
// ASCII linefeed
// select the com port, 0 is the first port
void setup() {
size(200, 200);
// WARNING!
// If necessary, change the definition of portIndex at the top of this
// sketch to the desired serial port.
//
println(Serial.list());
println(" Connecting to -> " + Serial.list()[portIndex]);
myPort = new Serial(this,Serial.list()[portIndex], 9600);
}
void draw() {
}
void serialEvent(Serial p)
{
String message = myPort.readStringUntil(LF); // read serial data
96 | Chapter 4:ಗSerial Communications
if(message != null)
{
print(message);
String [] data = message.split(","); // Split the comma-separated message
if(data[0].charAt(0) == HEADER)
// check for header character in the
first field
{
for( int i = 1; i < data.length-1; i++) // skip the header and terminating
cr and lf
{
int value = Integer.parseInt(data[i]);
println("Value" + i + " = " + value); //Print the value for each field
}
println();
}
}
}
Discussion
7KHFRGHLQWKLVUHFLSH¦V6ROXWLRQZLOOVHQGWKHIROORZLQJWH[WVWULQJWRWKHVHULDOSRUW
\rLQGLFDWHVDFDUULDJHUHWXUQDQG\nLQGLFDWHVDOLQHIHHG H10,100,1000,\r\n
<RXPXVWFKRRVHDVHSDUDWLQJFKDUDFWHUWKDWZLOOQHYHURFFXUZLWKLQDFWXDOGDWDLI\RXU
GDWDFRQVLVWVRQO\RIQXPHULFYDOXHVDFRPPDLVDJRRGFKRLFHIRUDGHOLPLWHU<RX
PD\DOVRZDQWWRHQVXUHWKDWWKHUHFHLYLQJVLGHFDQGHWHUPLQHWKHVWDUWRIDPHVVDJHWR
PDNHVXUHLWKDVDOOWKHGDWDIRUDOOWKHILHOGV<RXGRWKLVE\VHQGLQJDKHDGHUFKDUDFWHU
WRLQGLFDWHWKHVWDUWRIWKHPHVVDJH7KHKHDGHUFKDUDFWHUPXVWDOVREHXQLTXHLWVKRXOG
QRWDSSHDUZLWKLQDQ\RIWKHGDWDILHOGVDQGLWPXVWDOVREHGLIIHUHQWIURPWKHVHSDUDWRU
FKDUDFWHU7KHH[DPSOHKHUHXVHVDQXSSHUFDVH+WRLQGLFDWHWKHVWDUWRIWKHPHVVDJH
7KHPHVVDJHFRQVLVWVRIWKHKHDGHUWKUHHFRPPDVHSDUDWHGQXPHULFYDOXHVDV$6&,,
VWULQJVDQGDFDUULDJHUHWXUQDQGOLQHIHHG
7KHFDUULDJHUHWXUQDQGOLQHIHHGFKDUDFWHUVDUHVHQWZKHQHYHU$UGXLQRSULQWVXVLQJ
WKH println()IXQFWLRQDQGWKLVLVXVHGWRKHOSWKHUHFHLYLQJVLGHNQRZWKDWWKHIXOO
PHVVDJHVWULQJKDVEHHQUHFHLYHG$FRPPDLVVHQWDIWHUWKHODVWQXPHULFDOYDOXHWRDLG
WKHUHFHLYLQJVLGHLQGHWHFWLQJWKHHQGRIWKHYDOXH
7KH3URFHVVLQJFRGHUHDGVWKHPHVVDJHDVDVWULQJDQGXVHVWKH-DYDsplit()PHWKRGWR
FUHDWHDQDUUD\IURPWKHFRPPDVHSDUDWHGILHOGV
,QPRVWFDVHVWKHILUVWVHULDOSRUWZLOOEHWKHRQH\RXZDQWZKHQXVLQJ
D 0DF DQG WKH ODVW VHULDO SRUW ZLOO EH WKH RQH \RX ZDQW ZKHQ XVLQJ
:LQGRZV7KH3URFHVVLQJVNHWFKLQFOXGHVFRGHWKDWVKRZVWKHSRUWV
DYDLODEOH DQG WKH RQH FXUUHQWO\ VHOHFWHG¢FKHFN WKDW WKLV LV WKH SRUW
FRQQHFWHGWR$UGXLQR
4.4 Sending Multiple Text Fields from Arduino in a Single Message | 97
See Also
7KH3URFHVVLQJZHEVLWHSURYLGHVPRUHLQIRUPDWLRQRQLQVWDOOLQJDQGXVLQJWKLVSUR
JUDPPLQJHQYLURQPHQW6HHKWWSSURFHVVLQJRUJ
4.5 Receiving Multiple Text Fields in a Single Message
in Arduino
Problem
<RXZDQWWRUHFHLYHDPHVVDJHWKDWFRQWDLQVPRUHWKDQRQHILHOG)RUH[DPSOH\RXU
PHVVDJHPD\FRQWDLQDQLGHQWLILHUWRLQGLFDWHDSDUWLFXODUGHYLFH VXFKDVDPRWRURU
RWKHUDFWXDWRU DQGZKDWYDOXH VXFKDVVSHHG WRVHWLWWR
Solution
$UGXLQR GRHV QRW KDYH WKH split() IXQFWLRQ XVHG LQ WKH 3URFHVVLQJ FRGH LQ 5HF
LSHEXWWKHIXQFWLRQDOLW\FDQEHLPSOHPHQWHGDVVKRZQLQWKLVUHFLSH7KHIROORZLQJ
FRGHUHFHLYHVDPHVVDJHZLWKWKUHHQXPHULFILHOGVVHSDUDWHGE\FRPPDV,WXVHVWKH
WHFKQLTXH GHVFULEHG LQ 5HFLSH IRU UHFHLYLQJ GLJLWV DQG LW DGGV FRGH WR LGHQWLI\
FRPPDVHSDUDWHGILHOGVDQGVWRUHWKHYDOXHVLQWRDQDUUD\
/*
* SerialReceiveMultipleFields sketch
* This code expects a message in the format: 12,345,678
* This code requires a newline character to indicate the end of the data
* Set the serial monitor to send newline characters
*/
const int NUMBER_OF_FIELDS = 3; // how many comma separated fields we expect
int fieldIndex = 0;
// the current field being received
int values[NUMBER_OF_FIELDS];
// array holding values for all the fields
void setup()
{
Serial.begin(9600); // Initialize serial port to send and receive at 9600 baud
}
void loop()
{
if( Serial.available())
{
char ch = Serial.read();
if(ch >= '0' && ch <= '9') // is this an ascii digit between 0 and 9?
{
// yes, accumulate the value
values[fieldIndex] = (values[fieldIndex] * 10) + (ch - '0');
}
98 | Chapter 4:ಗSerial Communications
else if (ch == ',') // comma is our separator, so move on to the next field
{
if(fieldIndex < NUMBER_OF_FIELDS-1)
fieldIndex++;
// increment field index
}
else
{
// any character not a digit or comma ends the acquisition of fields
// in this example it's the newline character sent by the Serial Monitor
Serial.print( fieldIndex +1);
Serial.println(" fields received:");
for(int i=0; i <= fieldIndex; i++)
{
Serial.println(values[i]);
values[i] = 0; // set the values to zero, ready for the next message
}
fieldIndex = 0; // ready to start over
}
}
}
Discussion
7KLVVNHWFKDFFXPXODWHVYDOXHV DVH[SODLQHGLQ5HFLSH EXWKHUHHDFKYDOXHLV
DGGHGWRDQDUUD\ ZKLFKPXVWEHODUJHHQRXJKWRKROGDOOWKHILHOGV ZKHQDFRPPD
LVUHFHLYHG$FKDUDFWHURWKHUWKDQDGLJLWRUFRPPD VXFKDVWKHQHZOLQHFKDUDFWHUVHH
5HFLSH WULJJHUVWKHSULQWLQJRIDOOWKHYDOXHVWKDWKDYHEHHQVWRUHGLQWKHDUUD\
$QRWKHUDSSURDFKLVWRXVHDOLEUDU\FDOOHG7H[W)LQGHUZKLFKLVDYDLODEOHIURPWKH
$UGXLQR3OD\JURXQGRUIURPWKHZHEVLWHIRUWKLVERRN7H[W)LQGHUZDVFUHDWHGWRH[
WUDFWLQIRUPDWLRQIURPZHEVWUHDPV VHH&KDSWHU EXWLWZRUNVMXVWDVZHOOZLWK
VHULDOGDWD7KHIROORZLQJVNHWFKXVHV7H[W)LQGHUWRSURYLGHVLPLODUIXQFWLRQDOLW\WRWKH
SUHYLRXVVNHWFK
#include <TextFinder.h>
TextFinder finder(Serial);
const int NUMBER_OF_FIELDS = 3; // how many comma-separated fields we expect
int fieldIndex = 0;
// the current field being received
int values[NUMBER_OF_FIELDS];
// array holding values for all the fields
void setup()
{
Serial.begin(9600); // Initialize serial port to send and receive at 9600 baud
}
void loop()
{
for(fieldIndex = 0; fieldIndex < 3; fieldIndex ++)
{
values[fieldIndex] = finder.getValue(); // get a numeric value
4.5 Receiving Multiple Text Fields in a Single Message in Arduino | 99
}
Serial.print( fieldIndex);
Serial.println(" fields received:");
for(int i=0; i < fieldIndex; i++)
{
Serial.println(values[i]);
}
fieldIndex = 0; // ready to start over
}
<RX FDQ GRZQORDG WKH 7H[W)LQGHU OLEUDU\ IURP KWWSZZZDUGXLQRFFSOD\JURXQG
&RGH7H[W)LQGHU
+HUHLVDVXPPDU\RIWKHPHWKRGVVXSSRUWHGE\7H[W)LQGHU QRWDOODUHXVHGLQWKH
SUHFHGLQJH[DPSOH boolean find(char *target);
5HDGVIURPWKHVWUHDPXQWLOWKHJLYHQWDUJHWLVIRXQG,WUHWXUQV trueLIWKHWDUJHW
VWULQJLVIRXQG$UHWXUQRIfalsePHDQVWKHGDWDKDVQRWEHHQIRXQGDQ\ZKHUHLQ
WKHVWUHDPDQGWKDWWKHUHLVQRPRUHGDWDDYDLODEOH1RWHWKDW7H[W)LQGHUWDNHVD
VLQJOHSDVVWKURXJKWKHVWUHDPWKHUHLVQRZD\WRJREDFNWRWU\WRILQGRUJHW
VRPHWKLQJHOVH VHHWKHfindUntilPHWKRG boolean findUntil(char *target, char *terminate);
6LPLODUWRWKHfindPHWKRGEXWWKHVHDUFKZLOOVWRSLIWKHWHUPLQDWHVWULQJLVIRXQG
5HWXUQVtrueRQO\LIWKHWDUJHWLVIRXQG7KLVLVXVHIXOWRVWRSDVHDUFKRQDNH\ZRUG
RUWHUPLQDWRU)RUH[DPSOH
finder.findUntil("target", "\n");
ZLOOWU\WRVHHNWRWKHVWULQJ "value"EXWZLOOVWRSDWDQHZOLQHFKDUDFWHUVRWKDW
\RXUVNHWFKFDQGRVRPHWKLQJHOVHLIWKHWDUJHWLVQRWIRXQG
long getValue();
5HWXUQVWKHILUVWYDOLG ORQJ LQWHJHUYDOXH/HDGLQJFKDUDFWHUVWKDWDUHQRWGLJLWV
RUDPLQXVVLJQDUHVNLSSHG7KHLQWHJHULVWHUPLQDWHGE\WKHILUVWQRQGLJLWFKDUDFWHU
IROORZLQJWKHQXPEHU,IQRGLJLWVDUHIRXQGWKHIXQFWLRQUHWXUQV0
long getValue(char skipChar);
6DPHDVgetValueEXWWKHJLYHQskipCharZLWKLQWKHQXPHULFYDOXHLVLJQRUHG7KLV
FDQEHKHOSIXOZKHQSDUVLQJDVLQJOHQXPHULFYDOXHWKDWXVHVDFRPPDEHWZHHQ
EORFNVRIGLJLWVLQODUJHQXPEHUVEXWEHDULQPLQGWKDWWH[WYDOXHVIRUPDWWHGZLWK
FRPPDVFDQQRWEHSDUVHGDVDFRPPDVHSDUDWHGVWULQJ
float getFloat();
7KHfloatYHUVLRQRIgetValue
int getString(char *pre_string,char *post_string,char *buf,int length);
)LQGVWKHpre_stringDQGWKHQSXWVWKHLQFRPLQJFKDUDFWHUVLQWRWKHJLYHQEXIIHU
XQWLOWKHpost_stringLVGHWHFWHG7KHHQGRIWKHVWULQJLVGHWHUPLQHGE\DPDWFK
RIDFKDUDFWHUWRWKHILUVW char post_string6WULQJVORQJHUWKDQWKHJLYHQ length
100 | Chapter 4:ಗSerial Communications
DUHWUXQFDWHGWRILW7KHIXQFWLRQUHWXUQVWKHQXPEHURIFKDUDFWHUVSODFHGLQWKH
EXIIHU 0PHDQVQRYDOLGGDWDZDVIRXQG See Also
&KDSWHUSURYLGHVPRUHH[DPSOHVRI7H[W)LQGHUXVHGWRILQGDQGH[WUDFWGDWDIURP
DVWUHDP
4.6 Sending Binary Data from Arduino
Problem
<RXQHHGWRVHQGGDWDLQELQDU\IRUPDWEHFDXVH\RXZDQWWRSDVVLQIRUPDWLRQZLWK
WKHIHZHVWQXPEHURIE\WHVRUEHFDXVHWKHDSSOLFDWLRQ\RXDUHFRQQHFWLQJWRRQO\KDQ
GOHVELQDU\GDWD
Solution
7KLVVNHWFKVHQGVDKHDGHUIROORZHGE\WZRLQWHJHU ELW YDOXHVDVELQDU\GDWD7KH
YDOXHVDUHJHQHUDWHGXVLQJWKH$UGXLQRrandomIXQFWLRQ VHH5HFLSH /*
* SendBinary sketch
* Sends a header followed by two random integer values as binary data.
*/
int intValue;
// an integer value (16 bits)
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.print('H'); // send a header character
// send a random integer
intValue = random(599); // generate a random number between 0 and 599
// send the two bytes that comprise an integer
Serial.print(lowByte(intValue), BYTE); // send the low byte
Serial.print(highByte(intValue), BYTE); // send the high byte
// send another random integer
intValue = random(599); // generate a random number between 0 and 599
// send the two bytes that comprise an integer
Serial.print(lowByte(intValue), BYTE); // send the low byte
Serial.print(highByte(intValue), BYTE); // send the high byte
delay(1000);
}
4.6 Sending Binary Data from Arduino | 101
Discussion
6HQGLQJELQDU\GDWDUHTXLUHVFDUHIXOSODQQLQJEHFDXVH\RXZLOOJHWJLEEHULVKXQOHVVWKH
VHQGLQJVLGHDQGWKHUHFHLYLQJVLGHXQGHUVWDQGDQGDJUHHH[DFWO\KRZWKHGDWDZLOOEH
VHQW8QOLNHWH[WGDWDZKHUHWKHHQGRIDPHVVDJHFDQEHGHWHUPLQHGE\WKHSUHVHQFH
RIWKHWHUPLQDWLQJFDUULDJHUHWXUQ RUDQRWKHUXQLTXHFKDUDFWHU\RXSLFN LWPD\QRW
EHSRVVLEOHWRWHOOZKHQDELQDU\PHVVDJHVWDUWVRUHQGVE\ORRNLQJMXVWDWWKHGDWD¢
GDWDWKDWFDQKDYHDQ\YDOXHFDQWKHUHIRUHKDYHWKHYDOXHRIDKHDGHURUWHUPLQDWRU
FKDUDFWHU
7KLVFDQEHRYHUFRPHE\GHVLJQLQJ\RXUPHVVDJHVVRWKDWWKHVHQGLQJDQGUHFHLYLQJ
VLGHVNQRZH[DFWO\KRZPDQ\E\WHVDUHH[SHFWHG7KHHQGRIDPHVVDJHLVGHWHUPLQHG
E\WKHQXPEHURIE\WHVVHQWUDWKHUWKDQGHWHFWLRQRIDVSHFLILFFKDUDFWHU7KLVFDQEH
LPSOHPHQWHGE\VHQGLQJDQLQLWLDOYDOXHWRVD\KRZPDQ\E\WHVZLOOIROORZ2U\RXFDQ
IL[WKHVL]HRIWKHPHVVDJHVRWKDWLW¦VELJHQRXJKWRKROGWKHGDWD\RXZDQWWRVHQG
'RLQJHLWKHURIWKHVHLVQRWDOZD\VHDV\DVGLIIHUHQWSODWIRUPVDQGODQJXDJHVFDQXVH
GLIIHUHQWVL]HVIRUWKHELQDU\GDWDW\SHV¢ERWKWKHQXPEHURIE\WHVDQGWKHLURUGHUPD\
EHGLIIHUHQWIURP$UGXLQR)RUH[DPSOH$UGXLQRGHILQHVDQintDVWZRE\WHVEXW3UR
FHVVLQJ -DYD GHILQHVDQintDVIRXUE\WHV shortLVWKH-DYDW\SHIRUDELWLQWHJHU 6HQGLQJDQ intYDOXHDVWH[W DVVHHQLQHDUOLHUWH[WUHFLSHV VLPSOLILHVWKLVSUREOHP
EHFDXVHHDFKLQGLYLGXDOGLJLWLVVHQWDVDVHTXHQWLDOGLJLW MXVWDVWKHQXPEHULVZULWWHQ 7KHUHFHLYLQJVLGHUHFRJQL]HVZKHQWKHYDOXHKDVEHHQFRPSOHWHO\UHFHLYHGE\DFDUULDJH
UHWXUQRURWKHUQRQGLJLWGHOLPLWHU%LQDU\WUDQVIHUVFDQRQO\NQRZDERXWWKHFRPSR
VLWLRQRIDPHVVDJHLILWLVGHILQHGLQDGYDQFHRUVSHFLILHGLQWKHPHVVDJH
7KLVUHFLSH¦V6ROXWLRQUHTXLUHVDQXQGHUVWDQGLQJRIWKHGDWDW\SHVRQWKHVHQGLQJDQG
UHFHLYLQJSODWIRUPVDQGVRPHFDUHIXOSODQQLQJ5HFLSHVKRZVH[DPSOHFRGHXVLQJ
WKH3URFHVVLQJODQJXDJHWRUHFHLYHWKHVHPHVVDJHV
6HQGLQJ VLQJOH E\WHV LV HDV\ XVH Serial.print(byteVal) 7R VHQG DQ LQWHJHU IURP
$UGXLQR\RXQHHGWRVHQGWKHORZDQGKLJKE\WHVWKDWPDNHXSWKHLQWHJHU VHH5HF
LSHIRUPRUHRQGDWDW\SHV <RXGRWKLVXVLQJWKH lowByteDQGhighByteIXQFWLRQV
VHH5HFLSH Serial.print(lowByte(intValue), BYTE);
Serial.print(highByte(intValue), BYTE);
7KHSUHFHGLQJFRGHVHQGVWKHORZE\WHIROORZHGE\WKHKLJKE\WH7KHFRGHFDQDOVR
EHZULWWHQZLWKRXWWKH BYTESDUDPHWHU VHH5HFLSH EXWXVLQJWKHSDUDPHWHULVD
XVHIXOUHPLQGHU ZKHQ\RXFRPHEDFNODWHUWRPDNHFKDQJHVRUIRURWKHUVZKRPD\
UHDG\RXUFRGH WKDW\RXULQWHQWLRQLVWRVHQGE\WHVUDWKHUWKDQ$6&,,FKDUDFWHUV
6HQGLQJDORQJLQWHJHULVGRQHE\EUHDNLQJGRZQWKHIRXUE\WHVWKDWFRPSULVHDlongLQ
WZRVWHSV7KHlongLVILUVWEURNHQLQWRWZRELWLQWHJHUVHDFKLVWKHQVHQWXVLQJWKH
PHWKRGIRUVHQGLQJLQWHJHUVGHVFULEHGHDUOLHU
int longValue = 1000;
int intValue;
102 | Chapter 4:ಗSerial Communications
)LUVW\RXVHQGWKHORZHUELWLQWHJHUYDOXH
intValue = longValue && 0xFFFF; // get the value of the lower 16 bits
Serial.print(lowByte(intVal), BYTE);
Serial.print(highByte(intVal), BYTE);
7KHQ\RXVHQGWKHKLJKHUELWLQWHJHUYDOXH
intValue = longValue >> 16; // get the value of the higher 16 bits
Serial.print(lowByte(intVal), BYTE);
Serial.print(highByte(intVal), BYTE);
<RXPD\ILQGLWFRQYHQLHQWWRFUHDWHIXQFWLRQVWRVHQGWKHGDWD+HUHLVDIXQFWLRQWKDW
XVHVWKHFRGHVKRZQHDUOLHUWRSULQWDELWLQWHJHUWRWKHVHULDOSRUW
// function to send the given integer value to the serial port
void sendBinary(int value)
{
// send the two bytes that comprise a two byte (16 bit) integer
Serial.print(lowByte(value), BYTE); // send the low byte
Serial.print(highByte(value), BYTE); // send the high byte
}
7KHIROORZLQJIXQFWLRQVHQGVWKHYDOXHRID long E\WH LQWHJHUE\ILUVWVHQGLQJWKH
WZRORZ ULJKWPRVW E\WHVIROORZHGE\WKHKLJK OHIWPRVW E\WHV
// function to send the given long integer value to the serial port
void sendBinary(long value)
{
// first send the low 16 bit integer value
int temp = value && 0xFFFF; // get the value of the lower 16 bits
sendBinary(temp);
// then send the higher 16 bit integer value:
temp = value >> 16; // get the value of the higher 16 bits
sendBinary(temp);
}
7KHVHIXQFWLRQVWRVHQGELQDU\ intDQG longYDOXHVKDYHWKHVDPHQDPH sendBinary
7KHFRPSLOHUGLVWLQJXLVKHVWKHPE\WKHW\SHRIYDOXH\RXXVHIRUWKHSDUDPHWHU,I\RXU
FRGHFDOOVprintBinaryZLWKDE\WHYDOXHWKHYHUVLRQGHFODUHGDVvoid sendBinary(int
value) ZLOO EH FDOOHG ,I WKH SDUDPHWHU LV D long YDOXH WKH YHUVLRQ GHFODUHG DV void
sendBinary(long value) ZLOO EH FDOOHG 7KLV EHKDYLRU LV FDOOHG IXQFWLRQ RYHUORDGLQJ
5HFLSHSURYLGHVDQRWKHULOOXVWUDWLRQRIWKLVWKHGLIIHUHQWIXQFWLRQDOLW\\RXVDZLQ
Serial.printLVGXHWRWKHFRPSLOHUGLVWLQJXLVKLQJWKHGLIIHUHQWYDULDEOHW\SHVXVHG
<RXFDQDOVRVHQGELQDU\GDWDXVLQJVWUXFWXUHV6WUXFWXUHVDUHDPHFKDQLVPIRURUJDQ
L]LQJGDWDDQGLI\RXDUHQRWDOUHDG\IDPLOLDUZLWKWKHLUXVH\RXPD\EHEHWWHURIIVWLFNLQJ
ZLWKWKHVROXWLRQVGHVFULEHGHDUOLHU)RUWKRVHZKRDUHFRPIRUWDEOHZLWKWKHFRQFHSW
RIVWUXFWXUHSRLQWHUVWKHIROORZLQJLVDIXQFWLRQWKDWZLOOVHQGWKHE\WHVZLWKLQDVWUXF
WXUHWRWKHVHULDOSRUWDVELQDU\GDWD
void sendStructure( char *structurePointer, int structureLength)
{
int i;
4.6 Sending Binary Data from Arduino | 103
Download from Wow! eBook <www.wowebook.com>
for (i = 0 ; i < structureLength ; i++)
serial.print(structurePointer[i], BYTE);
}
sendStructure((char *)&myStruct, sizeof(myStruct));
6HQGLQJGDWDDVELQDU\E\WHVLVPRUHHIILFLHQWWKDQVHQGLQJGDWDDVWH[WEXWLWZLOORQO\
ZRUNUHOLDEO\LIWKHVHQGLQJDQGUHFHLYLQJVLGHVDJUHHH[DFWO\RQWKHFRPSRVLWLRQRIWKH
GDWD+HUHLVDVXPPDU\RIWKHLPSRUWDQWWKLQJVWRFKHFNZKHQZULWLQJ\RXUFRGH
9DULDEOHVL]H
0DNHVXUHWKHVL]HRIWKHGDWDEHLQJVHQWLVWKHVDPHRQERWKVLGHV$QLQWHJHULV
E\WHVRQ$UGXLQRE\WHVRQPRVWRWKHUSODWIRUPV$OZD\VFKHFN\RXUSURJUDP
PLQJODQJXDJH¦VGRFXPHQWDWLRQRQGDWDW\SHVL]HWRHQVXUHDJUHHPHQW7KHUHLV
QRSUREOHPZLWKUHFHLYLQJDE\WH$UGXLQRLQWHJHUDVDE\WHLQWHJHULQ3URFHVVLQJ
DVORQJDV3URFHVVLQJH[SHFWVWRJHWRQO\WZRE\WHV%XWEHVXUHWKDWWKHVHQGLQJ
VLGHGRHVQRWXVHYDOXHVWKDWZLOORYHUIORZWKHW\SHXVHGE\WKHUHFHLYLQJVLGH
%\WHRUGHU
0DNHVXUHWKHE\WHVZLWKLQDQintRUlongDUHVHQWLQWKHVDPHRUGHUH[SHFWHGE\
WKHUHFHLYLQJVLGH
6\QFKURQL]DWLRQ
(QVXUHWKDW\RXUUHFHLYLQJVLGHFDQUHFRJQL]HWKHEHJLQQLQJDQGHQGRIDPHVVDJH
,I\RXVWDUWOLVWHQLQJLQWKHPLGGOHRIDWUDQVPLVVLRQVWUHDP\RXZLOOQRWJHWYDOLG
GDWD7KLVFDQEHDFKLHYHGE\VHQGLQJDVHTXHQFHRIE\WHVWKDWZRQ¦WRFFXULQWKH
ERG\ RI D PHVVDJH )RU H[DPSOH LI \RX DUH VHQGLQJ ELQDU\ YDOXHV IURP analog
ReadWKHVHFDQRQO\UDQJHIURPWRVRWKHPRVWVLJQLILFDQWE\WHPXVWEH
OHVVWKDQ WKHintYDOXHRILVVWRUHGDVWKHE\WHVDQG WKHUHIRUHWKHUH
ZLOOQHYHUEHGDWDZLWKWZRFRQVHFXWLYHE\WHVJUHDWHUWKDQ6RVHQGLQJWZRE\WHV
RI RUDQ\YDOXHJUHDWHUWKDQ FDQQRWEHYDOLGGDWDDQGFDQEHXVHGWRLQGLFDWH
WKHVWDUWRUHQGRIDPHVVDJH
6WUXFWXUHSDFNLQJ
,I\RXVHQGRUUHFHLYHGDWDDVVWUXFWXUHVFKHFN\RXUFRPSLOHUGRFXPHQWDWLRQWR
PDNHVXUHWKHSDFNLQJLVWKHVDPHRQERWKVLGHV3DFNLQJLVWKHSDGGLQJWKDWD
FRPSLOHUXVHVWRDOLJQGDWDHOHPHQWVRIGLIIHUHQWVL]HVLQDVWUXFWXUH
)ORZFRQWURO
(LWKHUFKRRVHDWUDQVPLVVLRQVSHHGWKDWHQVXUHVWKDWWKHUHFHLYLQJVLGHFDQNHHS
XSZLWKWKHVHQGLQJVLGHRUXVHVRPHNLQGRIIORZFRQWURO)ORZFRQWUROLVDKDQG
VKDNHWKDWWHOOVWKHVHQGLQJVLGHWKDWWKHUHFHLYHULVUHDG\WRJHWPRUHGDWD
See Also
&KDSWHUSURYLGHVPRUHLQIRUPDWLRQRQWKHYDULDEOHW\SHVXVHGLQ$UGXLQRVNHWFKHV
$OVRFKHFNWKH$UGXLQRUHIHUHQFHVIRUlowByteDWKWWSZZZDUGXLQRFFHQ5HIHUHQFH
/RZ%\WHDQGhighByteDWKWWSZZZDUGXLQRFFHQ5HIHUHQFH+LJK%\WH
104 | Chapter 4:ಗSerial Communications
7KH$UGXLQRFRPSLOHUSDFNVVWUXFWXUHVRQE\WHERXQGDULHVVHHWKHGRFXPHQWDWLRQIRU
WKHFRPSLOHU\RXXVHRQ\RXUFRPSXWHUWRVHWLWIRUWKHVDPHSDFNLQJ,I\RXDUHQRW
FOHDURQKRZWRGRWKLV\RXPD\ZDQWWRDYRLGXVLQJVWUXFWXUHVWRVHQGGDWD
)RUPRUHRQIORZFRQWUROVHHKWWSHQZLNLSHGLDRUJZLNL)ORZBFRQWURO
4.7 Receiving Binary Data from Arduino on a Computer
Problem
<RXZDQWWRUHVSRQGWRELQDU\GDWDVHQWIURP$UGXLQRLQDSURJUDPPLQJODQJXDJH
VXFKDV3URFHVVLQJ)RUH[DPSOH\RXZDQWWRUHVSRQGWR$UGXLQRPHVVDJHVVHQWLQ
5HFLSH
Solution
7KLVUHFLSH¦V6ROXWLRQGHSHQGVRQWKHSURJUDPPLQJHQYLURQPHQW\RXXVHRQ\RXU3&
RU0DF,I\RXGRQ¦WDOUHDG\KDYHDIDYRULWHSURJUDPPLQJWRRODQGZDQWRQHWKDWLV
HDV\WROHDUQDQGZRUNVZHOOZLWK$UGXLQR3URFHVVLQJLVDQH[FHOOHQWFKRLFH
+HUHDUHWKHWZROLQHVRI3URFHVVLQJFRGHWRUHDGDE\WHWDNHQIURPWKH3URFHVVLQJ
SimpleReadH[DPSOH VHHWKLVFKDSWHU¦VLQWURGXFWLRQ if ( myPort.available() > 0) {
val = myPort.read();
// If data is available,
// read it and store it in val
$V\RXFDQVHHWKLVLVYHU\VLPLODUWRWKH$UGXLQRFRGH\RXVDZLQHDUOLHUUHFLSHV
7KHIROORZLQJLVD3URFHVVLQJVNHWFKWKDWVHWVWKHVL]HRIDUHFWDQJOHSURSRUWLRQDOWRWKH
LQWHJHUYDOXHVUHFHLYHGIURPWKH$UGXLQRVNHWFKLQ5HFLSH
/*
* ReceiveBinaryData_P
*
* portIndex must be set to the port connected to the Arduino
*/
import processing.serial.*;
Serial myPort;
short portIndex = 1;
// Create object from Serial class
// select the com port, 0 is the first port
char HEADER = 'H';
int value1, value2;
// Data received from the serial port
void setup()
{
size(600, 600);
// Open whatever serial port is connected to Arduino.
String portName = Serial.list()[portIndex];
println(Serial.list());
println(" Connecting to -> " + Serial.list()[portIndex]);
myPort = new Serial(this, portName, 9600);
4.7 Receiving Binary Data from Arduino on a Computer | 105
}
void draw()
{
// read the header and two binary *(16 bit) integers:
if ( myPort.available() >= 5) // If at least 5 bytes are available,
{
if( myPort.read() == HEADER) // is this the header
{
value1 = myPort.read();
// read the least significant byte
value1 = myPort.read() * 256 + value1; // add the most significant byte
value2 = myPort.read();
// read the least significant byte
value2 = myPort.read() * 256 + value2; // add the most significant byte
}
println("Message received: " + value1 + "," + value2);
}
background(255);
// Set background to white
fill(0);
// set fill to black
// draw rectangle with coordinates based on the integers received from Arduino
rect(0, 0, value1,value2);
}
Discussion
7KH3URFHVVLQJODQJXDJHLQIOXHQFHG$UGXLQRDQGWKHWZRDUHLQWHQWLRQDOO\VLPLODU7KH
setup IXQFWLRQ LQ 3URFHVVLQJ LV XVHG WR KDQGOH RQHWLPH LQLWLDOL]DWLRQ MXVW OLNH LQ
$UGXLQR3URFHVVLQJKDVDGLVSOD\ZLQGRZDQGsetupVHWVLWVVL]HWRÜSL[HOV
ZLWKWKHFDOOWRsize(600,600)
7KHOLQHString portName = Serial.list()[portIndex];VHOHFWVWKHVHULDOSRUW¢LQ3UR
FHVVLQJDOODYDLODEOHVHULDOSRUWVDUHFRQWDLQHGLQWKH Serial.listREMHFWDQGWKLVH[
DPSOHXVHVWKHYDOXHRIDYDULDEOHFDOOHGportIndexprintln(Serial.list())SULQWVDOO
WKHDYDLODEOHSRUWVDQGWKHOLQH myPort = new Serial(this, portName, 9600);RSHQV
WKHSRUWVHOHFWHGDV portName(QVXUHWKDW\RXVHW portIndexWRWKHVHULDOSRUWWKDWLV
FRQQHFWHGWR\RXU$UGXLQR
7KHdrawIXQFWLRQLQ3URFHVVLQJZRUNVOLNHloopLQ$UGXLQRLWLVFDOOHGUHSHDWHGO\7KH
FRGH LQ draw FKHFNV LI GDWD LV DYDLODEOH RQ WKH VHULDO SRUW LI VR E\WHV DUH UHDG DQG
FRQYHUWHGWRWKHLQWHJHUYDOXHUHSUHVHQWHGE\WKHE\WHV$UHFWDQJOHLVGUDZQEDVHGRQ
WKHLQWHJHUYDOXHVUHFHLYHG
See Also
<RXFDQUHDGPRUHDERXW3URFHVVLQJRQWKH3URFHVVLQJZHEVLWH
106 | Chapter 4:ಗSerial Communications
4.8 Sending Binary Values from Processing to Arduino
Problem
<RXZDQWWRVHQGELQDU\E\WHVLQWHJHUVRUORQJYDOXHVIURP3URFHVVLQJWR$UGXLQR
)RUH[DPSOH\RXZDQWWRVHQGDPHVVDJHFRQVLVWLQJRIDPHVVDJHLGHQWLILHU£WDJ¤DQ
LQGH[ SHUKDSVLQGLFDWLQJDSDUWLFXODUGHYLFHDWWDFKHGWR$UGXLQR DQGDELWYDOXH
Solution
8VHWKLVFRGH
/* SendingBinaryToArduino
* Language: Processing
*/
import processing.serial.*;
Serial myPort; // Create object from Serial class
public static final char HEADER = '|';
public static final char MOUSE = 'M';
void setup()
{
size(200, 400);
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
}
void draw(){
}
void serialEvent(Serial p) {
// handle incoming serial data
String inString = myPort.readStringUntil('\n');
if(inString != null) {
println( inString ); // echo text string from Arduino
}
}
:KHQWKHPRXVHLVFOLFNHGLQWKH3URFHVVLQJZLQGRZsendMessageZLOOEHFDOOHGZLWK
index HTXDO WR WKH YHUWLFDO SRVLWLRQ RI WKH PRXVH LQ WKH ZLQGRZ ZKHQ FOLFNHG DQG
valueHTXDOWRWKHKRUL]RQWDOSRVLWLRQ7KHZLQGRZVL]HZDVVHWWRVR index
ZRXOGILWLQWRDVLQJOHE\WHDQGvalueZRXOGILWLQWRWZRE\WHV
void mousePressed() {
int index = mouseY;
int value = mouseX;
sendMessage(MOUSE, index, value);
}
4.8 Sending Binary Values from Processing to Arduino | 107
sendMessageVHQGVDKHDGHUWDJDQGLQGH[DVVLQJOHE\WHV,WVHQGVWKHYDOXHDVWZR
E\WHVZLWKWKHPRVWVLJQLILFDQWE\WHILUVW
void sendMessage(char tag, int index, int value){
// send the given index and value to the serial port
myPort.write(HEADER);
myPort.write(tag);
myPort.write(index);
char c = (char)(value / 256); // msb
myPort.write(c);
c = (char)(value & 0xff); // lsb
myPort.write(c);
}
7KH$UGXLQRFRGHWRUHFHLYHWKLVDQGHFKRWKHUHVXOWVEDFNWR3URFHVVLQJLV
//BinaryDataFromProcessing
7KHQH[WWKUHHdefineVPXVWPLUURUWKHGHILQLWLRQVXVHGLQWKHVHQGLQJSURJUDP
#define HEADER
'|'
#define MOUSE
'M'
#define MESSAGE_BYTES 5 // the total bytes in a message
void setup()
{
Serial.begin(9600);
}
void loop(){
7KHFKHFNWRHQVXUHWKDWDWOHDVW MESSAGE_BYTESKDYHEHHQUHFHLYHGHQVXUHVWKDWZH
GRQ¦WWU\WRSURFHVVWKHPHVVDJHXQWLODOOWKHUHTXLUHGGDWDLVDYDLODEOH
if ( Serial.available() >= MESSAGE_BYTES)
{
2QO\UHDGWKHUHVWRIWKHPHVVDJHLIDYDOLGKHDGHUKDVEHHQUHFHLYHG
if( Serial.read() == HEADER)
{
char tag = Serial.read();
if(tag == MOUSE)
{
int index = Serial.read(); // this was sent as a char
but it's ok to use it as an int
7KHQH[WOLQHVFRQYHUWWKHWZRE\WHVEDFNWRDQLQWHJHUSerial.read() * 256;UHVWRUHV
WKHPRVWVLJQLILFDQWE\WHWRLWVRULJLQDOYDOXH&RPSDUHWKLVWR3URFHVVLQJFRGHWKDWVHQW
WKHWZRE\WHVFRPSULVLQJWKHYDOXH
int val = Serial.read() * 256;
val = val + Serial.read();
Serial.print("Received mouse msg, index = ");
Serial.print(index);
Serial.print(", value ");
108 | Chapter 4:ಗSerial Communications
Download from Wow! eBook <www.wowebook.com>
Serial.println(val);
}
else
{
,IWKHFRGHJHWVKHUHWKHWDJZDVQRWUHFRJQL]HG7KLVKHOSV\RXWRLJQRUHGDWDWKDWPD\
EHLQFRPSOHWHRUFRUUXSWHG
}
}
}
}
Serial.print("got message with unknown tag ");
Serial.println(tag);
Discussion
7KLVFRGHLVVLPLODUWRWKH3URFHVVLQJFRGHLQWKHSUHYLRXVUHFLSHVZLWKWKHDGGLWLRQRI
DIXQFWLRQFDOOHG sendMessage,QWKLVH[DPSOHWKHIXQFWLRQLVFDOOHGZLWKWKUHHSD
UDPHWHUVDWDJDQLQGH[DQGDYDOXH7KHIXQFWLRQILUVWVHQGVWKHKHDGHUFKDUDFWHUWR
LGHQWLI\WKHVWDUWRIWKHPHVVDJH7KHQWKHVLQJOHE\WHLQGH[LVVHQWIROORZHGE\WKHWZR
E\WHVWKDWFRPSULVHWKHLQWHJHUYDOXH<RXFDQPDNH\RXURZQYHUVLRQRIWKLVIXQFWLRQ
WRVHQGWKHFRPELQDWLRQRIYDOXHVWKDW\RXQHHGIRU\RXUDSSOLFDWLRQ
4.9 Sending the Value of Multiple Arduino Pins
Problem
<RXZDQWWRVHQGJURXSVRIELQDU\E\WHVLQWHJHUVRUORQJYDOXHVIURP$UGXLQR)RU
H[DPSOH\RXPD\ZDQWWRVHQGWKHYDOXHVRIWKHGLJLWDODQGDQDORJSLQVWR3URFHVVLQJ
Solution
7KLVUHFLSHVHQGVDKHDGHUIROORZHGE\DQLQWHJHUFRQWDLQLQJWKHELWYDOXHVRIGLJLWDO
SLQVWR7KLVLVIROORZHGE\VL[LQWHJHUVFRQWDLQLQJWKHYDOXHVRIDQDORJSLQV
WKURXJK&KDSWHUKDVPDQ\UHFLSHVWKDWVHWYDOXHVRQWKHDQDORJDQGGLJLWDOSLQV
WKDW\RXFDQXVHWRWHVWWKLVVNHWFK
/*
* SendBinaryFields
* Sends digital and analog pin values as binary data
*/
const char HEADER = 'H'; // a single character header to indicate the start
of a message
// these are the values that will be sent in binary format
void setup()
{
Serial.begin(9600);
for(int i=2; i <= 13; i++)
4.9 Sending the Value of Multiple Arduino Pins | 109
{
pinMode(i, INPUT);
digitalWrite(i, HIGH);
// set pins 2 through 13 to inputs
// turn on pull-ups
}
}
void loop()
{
Serial.print(HEADER,BYTE); // send the header
// put the bit values of the pins into an integer
int values = 0;
int bit = 0;
for(int i=2; i <= 13; i++)
{
bitWrite(values, bit, digitalRead(i)); // set the bit to 0 or 1 depending
// on value of the given pin
bit = bit + 1;
// increment to the next bit
}
sendBinary(values); // send the integer
for(int i=0; i < 6; i++)
{
values = analogRead(i);
sendBinary(values); // send the integer
}
delay(1000); //send every second
}
// function to send the given integer value to the serial port
void sendBinary( int value)
{
// send the two bytes that comprise an integer
Serial.print(lowByte(value), BYTE); // send the low byte
Serial.print(highByte(value), BYTE); // send the high byte
}
Discussion
7KHFRGHVHQGVDKHDGHU WKHFKDUDFWHU H IROORZHGE\DQLQWHJHUKROGLQJWKHGLJLWDO
SLQYDOXHVXVLQJWKHbitReadIXQFWLRQWRVHWDVLQJOHELWLQWKHLQWHJHUWRFRUUHVSRQGWR
WKHYDOXHRIWKHSLQ VHH&KDSWHU ,WWKHQVHQGVVL[LQWHJHUVFRQWDLQLQJWKHYDOXHVUHDG
IURPWKHVL[DQDORJSRUWV VHH&KDSWHUIRUPRUHLQIRUPDWLRQ $OOWKHLQWHJHUYDOXHV
DUHVHQWXVLQJsendBinaryLQWURGXFHGLQ5HFLSH7KHPHVVDJHLVE\WHVORQJ¢
E\WHIRUWKHKHDGHUE\WHVIRUWKHGLJLWDOSLQYDOXHVDQGE\WHVIRUWKHVL[DQDORJ
LQWHJHUV7KHFRGHIRUWKHGLJLWDODQGDQDORJLQSXWVLVH[SODLQHGLQ&KDSWHU
$VVXPLQJDQDORJSLQVKDYHYDOXHVRIRQSLQRQSLQDQGRQSLQWKURXJK
RQSLQDQGGLJLWDOSLQVWKURXJKDUHKLJKDQGWKURXJKDUHORZWKLVLVWKH
GHFLPDOYDOXHRIHDFKE\WHWKDWJHWVVHQW
72
63
// the character 'H' - this is the header
// two bytes in low high order containing bits representing pins 2-13
// binary 00111111 : this indicates that pins 2-7 are high
110 | Chapter 4:ಗSerial Communications
0
0
0
// this indicates that 8-13 are low
// two bytes for each pin representing the analog value
// pin 0 has an integer value of 0 so this is sent as two bytes
100 // pin 1 has a value of 100, sent as a byte of 100 and a byte of 0
0
...
// pin 5 has a value of 500
244 // the remainder when dividing 500 by 256
1
// the number of times 500 can be divided by 256
7KLV3URFHVVLQJFRGHUHDGVWKLVPHVVDJHDQGSULQWVWKHYDOXHVWRWKH3URFHVVLQJFRQVROH
/*
* ReceiveMultipleFieldsBinary_P
*
* portIndex must be set to the port connected to the Arduino
*/
import processing.serial.*;
Serial myPort;
short portIndex = 0;
// Create object from Serial class
// select the com port, 0 is the first port
char HEADER = 'H';
void setup()
{
size(200, 200);
// Open whatever serial port is connected to Arduino.
String portName = Serial.list()[portIndex];
println(Serial.list());
println(" Connecting to -> " + Serial.list()[portIndex]);
myPort = new Serial(this, portName, 9600);
}
void draw()
{
int val;
if ( myPort.available() >= 15) // wait for the entire message to arrive
{
if( myPort.read() == HEADER) // is this the header
{
println("Message received:");
// header found
// get the integer containing the bit values
val = readArduinoInt();
// print the value of each bit
for(int pin=2, bit=1; pin <= 13; pin++){
print("digital pin " + pin + " = " );
int isSet = (val & bit);
if( isSet == 0)
println("0");
4.9 Sending the Value of Multiple Arduino Pins | 111
else
println("1");
bit = bit * 2; // shift the bit
}
println();
// print the six analog values
for(int i=0; i < 6; i ++){
val = readArduinoInt();
println("analog port " + i + "= " + val);
}
println("----");
}
}
}
// return the integer value from bytes received on the serial port (in low,high
order)
int readArduinoInt()
{
int val;
// Data received from the serial port
}
val = myPort.read();
// read the least significant byte
val = myPort.read() * 256 + val; // add the most significant byte
return val;
7KH3URFHVVLQJFRGHZDLWVIRUFKDUDFWHUVWRDUULYH,IWKHILUVWFKDUDFWHULVWKHKHDGHU
LWWKHQFDOOVWKHIXQFWLRQQDPHGreadArduinoIntWRUHDGWZRE\WHVDQGWUDQVIRUPWKHP
EDFNLQWRDQLQWHJHUE\GRLQJWKHFRPSOHPHQWDU\PDWKHPDWLFDORSHUDWLRQWKDWZDV
SHUIRUPHGE\$UGXLQRWRJHWWKHLQGLYLGXDOELWVUHSUHVHQWLQJWKHGLJLWDOSLQV7KHVL[
LQWHJHUVDUHWKHQUHSUHVHQWLQJWKHDQDORJYDOXHV
See Also
7RVHQG$UGXLQRYDOXHVEDFNWRWKHFRPSXWHURUGULYHWKHSLQVIURPWKHFRPSXWHU
ZLWKRXWPDNLQJGHFLVLRQVRQWKHERDUG FRQVLGHUXVLQJ)LUPDWD KWWSZZZILUPDWD
RUJ 7KH)LUPDWDOLEUDU\LVLQFOXGHGLQWKH$UGXLQRVRIWZDUHDQGDOLEUDU\LVDYDLODEOH
WRXVHLQ3URFHVVLQJ<RXORDGWKH)LUPDWDFRGHRQWR$UGXLQRFRQWUROZKHWKHUSLQV
DUHLQSXWVRURXWSXWVIURPWKHFRPSXWHUDQGWKHQVHWRUUHDGWKRVHSLQV
4.10 How to Move the Mouse Cursor on a PC or Mac
Problem
<RXZDQW$UGXLQRWRLQWHUDFWZLWKDQDSSOLFDWLRQRQ\RXUFRPSXWHUE\PRYLQJWKH
PRXVHFXUVRU3HUKDSV\RXZDQWWRPRYHWKHPRXVHSRVLWLRQLQUHVSRQVHWR$UGXLQR
LQIRUPDWLRQ )RU H[DPSOH VXSSRVH \RX KDYH FRQQHFWHG D :LL QXQFKXFN VHH
5HFLSH WR\RXU$UGXLQRDQG\RXZDQW\RXUKDQGPRYHPHQWVWRFRQWUROWKHSR
VLWLRQRIWKHPRXVHFXUVRULQDSURJUDPUXQQLQJLQD3&
112 | Chapter 4:ಗSerial Communications
Solution
<RXFDQVHQGVHULDOFRPPDQGVWKDWFRQWDLQWKHPRXVHFXUVRUSRVLWLRQWRDSURJUDP
UXQQLQJRQWKHWDUJHWFRPSXWHU+HUHLVDVNHWFKWKDWPRYHVWKHPRXVHFXUVRUEDVHG
RQWKHSRVLWLRQRIWZRSRWHQWLRPHWHUV
// SerialMouse sketch
#define potXPin 4
#define potYPin 5
void setup()
{
Serial.begin(9600);
}
void loop()
{
int x = analogRead(potXPin);
int y = analogRead(potYPin);
Serial.print(x,DEC);
Serial.print(",");
Serial.print(y,DEC);
Serial.println(); // send a cr/lf
delay(50); // send position 20 times a second
}
)LJXUHLOOXVWUDWHVWKHZLULQJIRUWZRSRWHQWLRPHWHUV VHH&KDSWHUIRUPRUHGHWDLOV )LJXUH:LULQJIRUWZRSRWHQWLRPHWHUV
4.10 How to Move the Mouse Cursor on a PC or Mac | 113
7KH3URFHVVLQJFRGHLVEDVHGRQWKHFRGHVKRZQLQ5HFLSH
/*
* ArduinoMouse.pde
*/
(Processing sketch)
/* WARNING: This sketch takes over your mouse
Press escape to close running sketch */
import processing.serial.*;
Serial myPort;
Robot myRobot;
// Create object from Serial class
// create object from Robot class;
public static final char HEADER = 'M';
a message
public static final short LF = 10;
public static final short portIndex = 1;
port
// character to identify the start of
// ASCII linefeed
// select the com port, 0 is the first
void setup() {
size(200, 200);
println(Serial.list());
println(" Connecting to -> " + Serial.list()[portIndex]);
myPort = new Serial(this,Serial.list()[portIndex], 9600);
try {
myRobot = new Robot(); // the Robot class gives access to the mouse
}
catch (AWTException e) { // this is the Java exception handler
e.printStackTrace();
}
}
void draw() {
}
void serialEvent(Serial p) {
String message = myPort.readStringUntil(LF); // read serial data
if(message != null)
{
print(message);
String [] data = message.split(","); // Split the comma-separated message
if(data[0].charAt(0) == HEADER) // check for header character in the first
field
{
if( data.length > 3)
{
int x = Integer.parseInt(data[1]);
int y = Integer.parseInt(data[2]);
print("x= " + x);
println(", y= " + y);
myRobot.mouseMove(x,y); // move mouse to received x and y position
}
}
114 | Chapter 4:ಗSerial Communications
}
}
7KH3URFHVVLQJFRGHVSOLWVWKHPHVVDJHFRQWDLQLQJWKH[DQG\FRRUGLQDWHVDQGVHQGV
WKHPWRWKHmouseMovePHWKRGRIWKH-DYDRobotFODVV
Discussion
7KLVWHFKQLTXHIRUFRQWUROOLQJDSSOLFDWLRQVUXQQLQJRQ\RXUFRPSXWHULVHDV\WRLP
SOHPHQW DQG VKRXOG ZRUN ZLWK DQ\ RSHUDWLQJ V\VWHP WKDW FDQ UXQ WKH 3URFHVVLQJ
DSSOLFDWLRQ
6RPHSODWIRUPVUHTXLUHVSHFLDOSULYLOHJHVRUH[WHQVLRQVWRDFFHVVORZ
OHYHO LQSXW FRQWURO ,I \RX FDQ¦W JHW FRQWURO RI WKH PRXVH FKHFN WKH
GRFXPHQWDWLRQIRU\RXURSHUDWLQJV\VWHP
,I\RXUHTXLUH$UGXLQRWRDFWXDOO\DSSHDUDVWKRXJKLWZHUHDPRXVHWRWKHFRPSXWHU
\RXKDYHWRHPXODWHWKHDFWXDO86%SURWRFROUHDOPLFHXVH7KLVSURWRFROIRU+XPDQ
,QWHUIDFH'HYLFHV +,' LVFRPSOH[EXW3KLOOLS/LQGVD\KDVVRPHXVHIXOLQIRUPDWLRQ
DQGFRGHDWKWWSFRGHJRRJOHFRPSYXVEIRUDUGXLQR
$UXQDZD\RobotREMHFWKDVWKHDELOLW\WRUHPRYH\RXUFRQWURORYHUWKH
PRXVHDQGNH\ERDUGLIXVHGLQDQHQGOHVVORRS
See Also
*RWRKWWSMDYDVXQFRPMVHGRFVDSLMDYDDZW5RERWKWPOIRUPRUHLQIRUPDWLRQ
RQWKH-DYDRobotFODVV
$QDUWLFOHRQXVLQJWKHRobotFODVVLVDYDLODEOHDWKWWSZZZGHYHORSHUFRPMDYDRWKHU
DUWLFOHSKSBB
,I\RXSUHIHUWRXVHD:LQGRZVSURJUDPPLQJODQJXDJHWKHORZOHYHO:LQGRZV$3,
IXQFWLRQ WR LQVHUW NH\ERDUG DQG PRXVH HYHQWV LQWR WKH LQSXW VWUHDP LV FDOOHG
SendInput <RX FDQ YLVLW KWWSPVGQPLFURVRIWFRPHQXVOLEUDU\PV 96
DVS[IRUPRUHLQIRUPDWLRQ
4.11 Controlling Google Earth Using Arduino
Problem
<RXZDQWWRFRQWUROPRYHPHQWLQDQDSSOLFDWLRQVXFKDV*RRJOH(DUWKXVLQJVHQVRUV
DWWDFKHGWR$UGXLQR)RUH[DPSOH\RXZDQWVHQVRUVWRGHWHFWKDQGPRYHPHQWVWRDFW
4.11 Controlling Google Earth Using Arduino | 115
DVWKHFRQWUROVWLFNIRUWKHIOLJKWVLPXODWRULQ*RRJOH(DUWK7KHVHQVRUVFRXOGXVHD
MR\VWLFN VHH5HFLSH RUD:LLQXQFKXFN VHH5HFLSH Solution
*RRJOH(DUWKOHWV\RX£IO\¤DQ\ZKHUHRQ(DUWKWRYLHZVDWHOOLWHLPDJHU\PDSVWHUUDLQ
DQG'EXLOGLQJV VHH)LJXUH ,WFRQWDLQVDIOLJKWVLPXODWRUWKDWFDQEHFRQWUROOHG
E\DPRXVHDQGWKLVUHFLSHXVHVWHFKQLTXHVGHVFULEHGLQ5HFLSHFRPELQHGZLWKD
VHQVRUFRQQHFWHGWR$UGXLQRWRSURYLGHWKHMR\VWLFNLQSXW
)LJXUH*RRJOH(DUWKIOLJKWVLPXODWRU
7KLVUHFLSH¦V6ROXWLRQLVEDVHGRQWKHPHWKRGXVHGLQ5HFLSHIRUHPXODWLQJDPRXVH
E\VHQGLQJ$UGXLQRGDWDWR3URFHVVLQJ7KH$UGXLQRFRGHVHQGVWKHKRUL]RQWDODQG
YHUWLFDOSRVLWLRQVGHWHUPLQHGE\UHDGLQJWKHMR\VWLFNYDOXHV WKHMR\VWLFNFRGHLVGLV
FXVVHGLQ5HFLSH IURPD3OD\6WDWLRQJDPHFRQWUROOHU
*
* GoogleEarthPSX
*
* Send joystick data from PSX to Processing
* uses PSX library discussed in Recipe 6.17
*/
#include <Psx.h>
// Includes the Psx Library
Psx Psx;
const int dataPin = 5;
// Create an instance of the Psx library
116 | Chapter 4:ಗSerial Communications
const int cmndPin = 4;
const int attPin = 3;
const int clockPin = 2;
const int psxDelay = 10; // this determines the clock delay in microseconds
const byte nudge = 64;
// the amount of movement to be sent when stick is pushed
const byte HEADER = 255; // this value is sent as the header
unsigned int data;
byte x,y, buttons;
void setup()
{
Serial.begin(9600);
Psx.setupPins(dataPin, cmndPin, attPin, clockPin, psxDelay);
}
// initialize Psx
void loop()
{
data = Psx.read();
x = y = 127;
buttons = 0;
// get the psx controller button data
// center x & y values, offsets are added if buttons pressed
if(data & psxLeft || data & psxSqu)
x = x - nudge;
if(data & psxDown ||data & psxX)
y = y + nudge;
if(data & psxRight ||data & psxO)
x = x + nudge;
if(data & psxUp ||data & psxTri)
y = y - nudge;
if(data & psxStrt) // (Z button)
buttons = buttons + 2;
if(data & psxSlct) // (C button)
buttons = buttons + 1;
Serial.print(HEADER);
Serial.print(x);
Serial.print(y);
Serial.print(buttons);
delay(20); // send position 50 times a second
}
7KH3URFHVVLQJVNHWFKUHDGVWKHKHDGHUE\WHDQGWKUHHGDWDE\WHVIRU[DQG\PRXVH
SRVLWLRQ DQG EXWWRQ VWDWH 7KH WHFKQLTXH IRU KDQGOLQJ ELQDU\ GDWD LV GLVFXVVHG LQ
5HFLSH
/**
* GoogleEarthFS_P
*
* Read Arduino Serial packets
* and send mouse position to Google Earth
4.11 Controlling Google Earth Using Arduino | 117
*
*/
import processing.serial.*;
Serial myPort;
int portIndex = 1;
int HEADER = 255;
int val;
// Create object from Serial class
// select the com port, 0 is the first port
// Data received from the serial port
GoogleFS myGoogle;
void setup()
{
size(256, 256);
println(Serial.list());
println(" Connecting to -> " + Serial.list()[portIndex]);
myPort = new Serial(this,Serial.list()[portIndex], 9600);
myGoogle = new GoogleFS();
smooth();
fill(255);
background(255);
println("Start Google FS in the center of your screen");
println("center the mouse pointer in google earth
and press Z button to start");
do{
getData();
}
while(buttons != 2 ); // wait for data and Z button to start
println("started");
myGoogle.mousePress(InputEvent.BUTTON1_MASK); // starts the FS
}
int accx,accy,buttons;
int xOffset, yOffset = 0;
boolean getData(){
if ( myPort.available() >= 4) { // If a data packet is available,
if(myPort.read() == HEADER){ // check for header
// erase the old markers
stroke(255);
ellipse(accx, accy,4,4);
accx = myPort.read();
accy = myPort.read();
buttons = myPort.read();
if(xOffset == 0){
// here if first time
xOffset = accx;
yOffset = accy;
}
if( buttons == 1) {
println("tbutton: c");
118 | Chapter 4:ಗSerial Communications
xOffset = accx;
yOffset = accy;
}
if(buttons == 3 ){
exit();
}
return true; // data available
}
}
}
return false;
void draw()
{
if(getData()){
if(buttons != 2 ){
// only activate the mouse when the Z button is not pressed
myGoogle.move(accx- xOffset, accy - yOffset);
}
print("accx: ");
print("\taccy: ");
println();
print(accx);
print(accy);
stroke(255,0,0);
ellipse(accx, accy,4,4);
}
}
class GoogleFS {
Robot myRobot;
// create object from Robot class;
int centerX,centerY;
GoogleFS(){
try {
myRobot = new Robot();
}
catch (AWTException e) {
e.printStackTrace();
}
Dimension screen = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
centerY = (int)screen.getHeight() / 2 ;
centerX = (int)screen.getWidth() / 2;
}
// moves mouse from center of screen by given offset
void move(int offsetX, int offsetY){
myRobot.mouseMove(centerX + 4 * offsetX,centerY + -4 * offsetY);
}
void mousePress( int button){
myRobot.mousePress(button) ;
}
}
Discussion
$UGXLQRGHWHUPLQHVWKHKRUL]RQWDODQGYHUWLFDOSRVLWLRQVE\UHDGLQJWKHMR\VWLFNYDOXH
IURPWKH36; 3OD\6WDWLRQJDPHFRQWUROOHU 7KLVFRQWUROGRHVQRWDFWXDOO\SURYLGHD
4.11 Controlling Google Earth Using Arduino | 119
YDOXHSURSRUWLRQDOWRWKHVWLFNSRVLWLRQVRWKH$UGXLQRFRGHVHQGVDQRIIVHWIURPWKH
FHQWHUZKHQWKHVWLFNLVPRYHG¢WKLVLVWKHnudgeYDULDEOHDQGLWGHWHUPLQHVWKHYDOXH
RIWKLVRIIVHWDQGWKHUHIRUHWKHVHQVLWLYLW\RIWKHFRQWURO7KHVWDWHRIWKH6HOHFWDQG
6WDUWVZLWFKHVLVDOVRVHQW ZKHQSUHVVHG6HOHFWKDVDYDOXHRIDQG6WDUWKDVDYDOXH
RIZKHQERWKDUHSUHVVHGWKHYDOXHLVDQGZKHQQREXWWRQLVSUHVVHGWKHYDOXHLV )ROORZWKHLQVWUXFWLRQVIRUFRQQHFWLQJWKH36;LQ5HFLSH
*RRJOH(DUWKLVDIUHHGRZQORDG\RXFDQJHWLWIURPWKH*RRJOHZHEVLWHKWWSHDUWK
JRRJOHFRPGRZQORDGHDUWKKWPO'RZQORDGDQGUXQWKHYHUVLRQIRU\RXURSHUDWLQJ
V\VWHPWRLQVWDOOLWRQ\RXUFRPSXWHU6WDUW*RRJOH(DUWKDQGIURPWKH7RROVPHQX
VHOHFW(QWHU)OLJKW6LPXODWRU6HOHFWDQDLUFUDIW WKH65LVHDVLHUWRIO\WKDQWKH)
DQGDQDLUSRUW7KH-R\VWLFNVXSSRUWVKRXOGEHOHIWXQFKHFNHG¢\RXZLOOEHXVLQJWKH
PRXVHWRFRQWUROWKHDLUFUDIW&OLFNWKH6WDUW)OLJKWEXWWRQDQGLPPHGLDWHO\SUHVVWKH
VSDFHEDUWRSDXVHWKHVLPXODWRUVRWKDW\RXFDQJHWWKH3URFHVVLQJVNHWFKUXQQLQJ
5XQWKH*RRJOH(DUWK)6B3VNHWFKDQGSUHVVWKH6WDUWEXWWRQRQWKH36;FRQWUROOHU<RX
ZLOOVHHDGRWLQWKH3URFHVVLQJGUDZZLQGRZVKRZLQJWKHMR\VWLFNSRVLWLRQDQG\RX
VKRXOGVHHWKLVPRYHDV\RXSUHVVWKH36;FRQWUROOHUMR\VWLFNEXWWRQV$WWKLVSRLQW
WKHPRXVHSRVLWLRQLVXQGHUWKHFRQWURORI$UGXLQREXWFRQWUROUHWXUQVWR\RXUFRP
SXWHUPRXVHZKHQ\RXKROGWKH36;6WDUWEXWWRQ0DNH*RRJOH(DUWKWKH$FWLYHZLQ
GRZE\KROGLQJWKH36;6WDUWEXWWRQDQGFOLFNLQJRQ*RRJOH(DUWK
<RXDUHQRZUHDG\WRIO\5HOHDVHWKH36;6WDUWEXWWRQSUHVV3DJH8SRQ\RXUNH\ERDUG
DIHZWLPHVWRLQFUHDVHWKHWKURWWOHDQGWKHQSUHVVWKHVSDFHEDURQ\RXUNH\ERDUGWR
XQSDXVHWKHVLPXODWRU:KHQWKH65UHDFKHVDQDLUVSHHGWKDWLVDOLWWOHRYHU
NQRWV\RXFDQ£SXOOEDFN¤RQWKHVWLFNDQGIO\,QIRUPDWLRQH[SODLQLQJWKHVLPXODWRU
FRQWUROVLVDYDLODEOHLQWKH+HOSPHQX
+HUHLVDQRWKHUYDULDWLRQWKDWVHQGVDVLPLODUPHVVDJHWRWKH3URFHVVLQJVNHWFK7KLV
RQHXVHVWKH:LLQXQFKXFNFRGHIURP5HFLSH
/*
* WiichuckSerial
*
* based on code from Tod E. Kurt, http://thingm.com/
* Modified to send serial packets to Processing
*
*/
#include <Wire.h>
#include "nunchuck_funcs.h"
int loop_cnt=0;
const byte header = 254;
// a value to indicate start of message
byte accx,accy,joyx,joyy,buttons;
// set the current coordinates as the center points
120 | Chapter 4:ಗSerial Communications
void setup()
{
Serial.begin(9600);
nunchuck_setpowerpins();
nunchuck_init(); // send the initialization handshake
nunchuck_get_data(); // ignore the first time
delay(50);
}
void loop()
{
if( loop_cnt > 50 ) { // every 50 msecs get new data
loop_cnt = 0;
nunchuck_get_data();
accx = nunchuck_accelx();
accy = nunchuck_accely();
buttons = nunchuck_zbutton() * 2;
buttons = buttons + nunchuck_cbutton(); // cbutton is least significant bit
Serial.print((byte)HEADER);
Serial.print((byte)accx);
Serial.print((byte)accy);
Serial.print((byte)buttons);
// value indicating start of message
}
loop_cnt++;
delay(1);
}
7KHFRQQHFWLRQVDUHVKRZQLQ5HFLSH2SHUDWLRQLVVLPLODUWRWKH36;YHUVLRQ
H[FHSW\RXXVHWKH=EXWWRQRQWKHQXQFKXFNLQVWHDGRIWKH6WDUWEXWWRQ
See Also
7KH*RRJOH(DUWKZHEVLWHFRQWDLQVWKHGRZQORDGDEOHFRGHDQGLQVWUXFWLRQVQHHGHGWR
JHWWKLVJRLQJRQ\RXUFRPSXWHUKWWSHDUWKJRRJOHFRP
4.12 Logging Arduino Data to a File on Your Computer
Problem
<RX ZDQW WR FUHDWH D ILOH FRQWDLQLQJ LQIRUPDWLRQ UHFHLYHG RYHU WKH VHULDO SRUW IURP
$UGXLQR)RUH[DPSOH\RXZDQWWRVDYHWKHYDOXHVRIWKHGLJLWDODQGDQDORJSLQVDW
UHJXODULQWHUYDOVWRDORJILOH
Solution
:HFRYHUHGVHQGLQJLQIRUPDWLRQIURP$UGXLQRWR\RXUFRPSXWHULQSUHYLRXVUHFLSHV
7KLV VROXWLRQ XVHV WKH VDPH $UGXLQR FRGH H[SODLQHG LQ 5HFLSH 7KH 3URFHVVLQJ
4.12 Logging Arduino Data to a File on Your Computer | 121
VNHWFKWKDWKDQGOHVILOHORJJLQJLVEDVHGRQWKH3URFHVVLQJVNHWFKDOVRGHVFULEHGLQWKDW
UHFLSH
7KLV3URFHVVLQJVNHWFKFUHDWHVDILOH XVLQJWKHFXUUHQWGDWHDQGWLPHDVWKHILOHQDPH
LQDGLUHFWRU\FDOOHG$UGXLQR0HVVDJHVUHFHLYHGIURP$UGXLQRDUHDGGHGWRWKHILOH
3UHVVLQJDQ\NH\VDYHVWKHILOHDQGH[LWVWKHSURJUDP
/*
* ReceiveMultipleFieldsBinaryToFile_P
*
* portIndex must be set to the port connected to the Arduino
* based on ReceiveMultipleFieldsBinary, this version saves data to file
* Press any key to stop logging and save file
*/
import processing.serial.*;
PrintWriter output;
DateFormat fnameFormat= new SimpleDateFormat("yyMMdd_HHmm");
DateFormat timeFormat = new SimpleDateFormat("hh:mm:ss");
String fileName;
Serial myPort;
short portIndex = 0;
char HEADER = 'H';
// Create object from Serial class
// select the com port, 0 is the first port
void setup()
{
size(200, 200);
// Open whatever serial port is connected to Arduino.
String portName = Serial.list()[portIndex];
println(Serial.list());
println(" Connecting to -> " + Serial.list()[portIndex]);
myPort = new Serial(this, portName, 9600);
Date now = new Date();
fileName = fnameFormat.format(now);
output = createWriter(fileName + ".txt"); // save the file in the sketch folder
}
void draw()
{
int val;
String time;
if ( myPort.available() >= 15) // wait for the entire message to arrive
{
if( myPort.read() == HEADER) // is this the header
{
String timeString = timeFormat.format(new Date());
println("Message received at " + timeString);
output.println(timeString);
// header found
// get the integer containing the bit values
val = readArduinoInt();
122 | Chapter 4:ಗSerial Communications
// print the value of each bit
for(int pin=2, bit=1; pin <= 13; pin++){
print("digital pin " + pin + " = " );
output.print("digital pin " + pin + " = " );
int isSet = (val & bit);
if( isSet == 0){
println("0");
output.println("0");
}
else {
println("1");
output.println("0");
}
bit = bit * 2; // shift the bit
}
// print the six analog values
for(int i=0; i < 6; i ++){
val = readArduinoInt();
println("analog port " + i + "= " + val);
output.println("analog port " + i + "= " + val);
}
println("----");
output.println("----");
}
}
}
void keyPressed() {
output.flush(); // Writes the remaining data to the file
output.close(); // Finishes the file
exit(); // Stops the program
}
// return the integer value from bytes received on the serial port (in low,high
order)
int readArduinoInt()
{
int val;
// Data received from the serial port
}
val = myPort.read();
// read the least significant byte
val = myPort.read() * 256 + val; // add the most significant byte
return val;
'RQ¦WIRUJHWWKDW\RXQHHGWRVHWportIndexWRWKHVHULDOSRUWFRQQHFWHGWR$UGXLQR
Discussion
7KHEDVHQDPHIRUWKHORJILOHLVIRUPHGXVLQJWKHDateFormatIXQFWLRQLQ3URFHVVLQJ
DateFormat fnameFormat= new SimpleDateFormat("yyMMdd_HHmm");
7KHIXOOILOHQDPHLVFUHDWHGZLWKFRGHWKDWDGGVDGLUHFWRU\DQGILOHH[WHQVLRQ
output = createWriter(fileName + ".txt");
4.12 Logging Arduino Data to a File on Your Computer | 123
7KHILOHZLOOEHFUHDWHGLQWKHVDPHGLUHFWRU\DVWKH3URFHVVLQJVNHWFK WKHVNHWFKQHHGV
WREHVDYHGDWOHDVWRQFHWRHQVXUHWKDWWKHGLUHFWRU\H[LVWV createWriterLVWKH3UR
FHVVLQJIXQFWLRQWKDWRSHQVWKHILOHWKLVFUHDWHVDQREMHFW DXQLWRIUXQWLPHIXQFWLRQ
DOLW\ FDOOHGoutputWKDWKDQGOHVWKHDFWXDOILOHRXWSXW7KHWH[WZULWWHQWRWKHILOHLVWKH
VDPHDVZKDWLVSULQWHGWRWKHFRQVROHLQ5HFLSHEXW\RXFDQIRUPDWWKHILOHFRQWHQWV
DVUHTXLUHGE\XVLQJWKHVWDQGDUGVWULQJKDQGOLQJFDSDELOLWLHVRI3URFHVVLQJ)RUH[DP
SOHWKHIROORZLQJYDULDWLRQRQWKHGUDZURXWLQHSURGXFHVDFRPPDVHSDUDWHGILOHWKDW
FDQEHUHDGE\DVSUHDGVKHHWRUGDWDEDVH7KHUHVWRIWKH3URFHVVLQJVNHWFKFDQEHWKH
VDPHDOWKRXJK\RXPD\ZDQWWRFKDQJHWKHH[WHQVLRQIURPW[WWRFVY
void draw()
{
int val;
String time;
if ( myPort.available() >= 15) // wait for the entire message to arrive
{
if( myPort.read() == HEADER) // is this the header
{
String timeString = timeFormat.format(new Date());
output.print(timeString);
val = readArduinoInt(); // read but don't output the digital values
// output the six analog values delimited by a comma
for(int i=0; i < 6; i ++){
val = readArduinoInt();
output.print("," + val);
}
output.println();
}
}
}
See Also
)RUPRUHRQcreateWriterVHHKWWSSURFHVVLQJRUJUHIHUHQFHFUHDWH:ULWHUBKWPO
4.13 Sending Data to Two Serial Devices at the Same Time
Problem
<RXZDQWWRVHQGGDWDWRDVHULDOGHYLFHVXFKDVDVHULDO/&'EXW\RXDUHDOUHDG\XVLQJ
WKHEXLOWLQVHULDOSRUWWRFRPPXQLFDWHZLWK\RXUFRPSXWHU
Solution
2QD0HJDWKLVLVQRWDSUREOHPDVLWKDVIRXUKDUGZDUHVHULDOSRUWVMXVWFUHDWHWZR
VHULDOREMHFWVDQGXVHRQHIRUWKH/&'DQGRQHIRUWKHFRPSXWHU
124 | Chapter 4:ಗSerial Communications
void setup() {
// initialize two serial ports on a megaL
Serial.begin(9600);
Serial1.begin(9600);
}
2QDVWDQGDUG$UGXLQRERDUG VXFKDVWKH8QRRU'XHPLODQRYH WKDWRQO\KDVRQH
KDUGZDUHVHULDOSRUW\RXZLOOQHHGWRFUHDWHDQHPXODWHGRU£VRIW¤VHULDOSRUW
<RXFDQXVH0LNDO+DUW¦V1HZ6RIW6HULDODVHULDOSRUWHPXODWLRQOLEUDU\DYDLODEOHDW
KWWSDUGXLQLDQDRUJOLEUDULHVQHZVRIWVHULDO'RZQORDGDQGLQVWDOO1HZ6RIW6HULDO
7KH $UGXLQR WHDP LV SODQQLQJ WR SURYLGH 1HZ6RIW6HULDO ZLWK IXWXUH
$UGXLQRGRZQORDGV&KHFNWKHUHOHDVHQRWHVIRU\RXU$UGXLQRYHUVLRQ
WRVHHLIWKLVVRIWZDUHLVDOUHDG\LQFOXGHG
6HOHFWWZRDYDLODEOHGLJLWDOSLQVRQHHDFKIRUWUDQVPLWDQGUHFHLYHDQGFRQQHFW\RXU
VHULDOGHYLFHWRWKHP,WLVFRQYHQLHQWWRXVHWKHKDUGZDUHVHULDOSRUWIRUFRPPXQLFDWLRQ
ZLWKWKHFRPSXWHUEHFDXVHWKLVKDVD86%DGDSWHURQWKHERDUG&RQQHFWWKHGHYLFH¦V
WUDQVPLWOLQHWRWKHUHFHLYHSLQDQGWKHUHFHLYHOLQHWRWKHWUDQVPLWSLQ,Q)LJXUH
ZHKDYHVHOHFWHGSLQDVWKHUHFHLYHSLQDQGSLQDVWKHWUDQVPLWSLQ
)LJXUH&RQQHFWLQJDVHULDOGHYLFHWRD£VRIW¤VHULDOSRUW
,Q\RXUVNHWFKFUHDWHDNewSoftSerialREMHFWDQGWHOOLWZKLFKSLQV\RXFKRVHDV\RXU
HPXODWHGVHULDOSRUW,QWKLVH[DPSOHZH¦UHFUHDWLQJDQREMHFWQDPHGserial_lcdZKLFK
ZHLQVWUXFWWRXVHSLQVDQG
/*
* NewSoftSerialOutput sketch
* Output data to a software serial port
*/
4.13 Sending Data to Two Serial Devices at the Same Time | 125
#include <NewSoftSerial.h>
...
const int rxpin = 2;
// pin used to receive from LCD
const int txpin = 3;
// pin used to send to LCD
NewSoftSerial serial_lcd(txpin, rxpin); // new serial port on pins 2 and 3
void setup()
{
Serial.begin(9600); // 9600 baud for the built-in serial port
serial_lcd.begin(9600); //initialize the software serial port also for 9600
}
int number = 0;
void loop()
{
serial_lcd.print("The number is "); // send text to the LCD
serial_lcd.println(number);
// print the number on the LCD
Serial.print("The number is ");
Serial.println(number);
// print the number on the PC console
}
delay(500); // delay half second between numbers
number++;
// to the next number
7KLVVNHWFKDVVXPHVWKDWDVHULDO/&'KDVEHHQFRQQHFWHGWRSLQVDQGDVVKRZQLQ
)LJXUHDQGWKDWDVHULDOFRQVROHLVFRQQHFWHGWRWKHEXLOWLQSRUW7KHORRSZLOO
UHSHDWHGO\GLVSOD\WKHVDPHPHVVDJHRQHDFK
The number is 0
The number is 1
...
Discussion
(YHU\$UGXLQRPLFURFRQWUROOHUFRQWDLQVDWOHDVWRQHEXLOWLQVHULDOSRUW7KLVVSHFLDO
SLHFHRIKDUGZDUHLVUHVSRQVLEOHIRUJHQHUDWLQJWKHVHULHVRISUHFLVHO\WLPHGSXOVHVLWV
SDUWQHUGHYLFHVHHVDVGDWDDQGIRULQWHUSUHWLQJWKHVLPLODUVWUHDPWKDWLWUHFHLYHVLQ
UHWXUQ$OWKRXJKWKH0HJDKDVIRXUVXFKSRUWVPRVW$UGXLQRIODYRUVKDYHRQO\RQH
)RUSURMHFWVWKDWUHTXLUHFRQQHFWLRQVWRWZRRUPRUHVHULDOGHYLFHV\RX¦OOQHHGDVRIW
ZDUHOLEUDU\WKDWHPXODWHVWKHDGGLWLRQDOSRUWV$£VRIWZDUHVHULDO¤OLEUDU\HIIHFWLYHO\
WXUQVDQDUELWUDU\SDLURIGLJLWDO,2SLQVLQWRDQHZVHULDOSRUW
$OWKRXJKRQHVXFKOLEUDU\6RIWZDUH6HULDOLVLQFOXGHGLQHYHU\$UGXLQRGLVWULEXWLRQ
PRVWSURJUDPPHUVSUHIHUWRXVHWKHPRUHSRZHUIXODQGIHDWXUHODGHQ1HZ6RIW6HULDO
OLEUDU\1HZ6RIW6HULDOVXSSRUWVDZLGHUUDQJHRIEDXGUDWHVDQGXVHVVRPHDGYDQFHG
IHDWXUHVRIWKH$UGXLQRSURFHVVRUWRHQVXUHPRUHUHOLDEOHGDWDUHFHSWLRQ,WDOVRVXS
SRUWVPXOWLSOHVLPXOWDQHRXVHPXODWHGSRUWV<RXFDQUHDGPRUHDERXW1HZ6RIW6HULDO
RQ0LNDO+DUW¦VZHEVLWH
7DEOHFRPSDUHVWKHIHDWXUHVRIWKH1HZ6RIW6HULDODQG6RIWZDUH6HULDOOLEUDULHV
126 | Chapter 4:ಗSerial Communications
7DEOH)HDWXUHFRPSDULVRQRIWZRHPXODWLRQOLEUDULHV
Feature
NewSoftSerial
SoftwareSerial
Distributed with Arduino software
Noa
Yes
Max transmit baud rate
115.2K
To about 9,600
Max receive baud rate
38.4K
To about 9,600
Supports 8 MHz processors
Yes
No
Reliable interrupt-driven receives
Yes
No
Supports multiple emulated ports
Yes
No
.available() and .overflow() methods
Yes
N/A
a Note that as of Arduino release 22, NewSoftSerial was available only as a third-party library, but future releases may include it with the
base distribution.
7REXLOG\RXUVRIWZDUHVHULDOSRUW\RXVHOHFWDSDLURISLQVWKDWZLOODFWDVWKHSRUW¦V
WUDQVPLWDQGUHFHLYHOLQHVLQPXFKWKHVDPHZD\WKDWSLQVDQGDUHFRQWUROOHGE\
$UGXLQR¦VEXLOWLQSRUW,Q)LJXUHSLQVDQGDUHVKRZQEXWDQ\DYDLODEOHGLJLWDO
SLQVFDQEHXVHG,W¦VZLVHWRDYRLGXVLQJDQGEHFDXVHWKHVHDUHDOUHDG\EHLQJGULYHQ
E\WKHEXLOWLQSRUW
7KHV\QWD[IRUZULWLQJWRWKHVRIWSRUWLVLGHQWLFDOWRWKDWIRUWKHKDUGZDUHSRUW,QWKH
H[DPSOHVNHWFKGDWDLVVHQWWRERWKWKH£UHDO¤DQGHPXODWHGSRUWVXVLQJprint()DQG
println()
serial_lcd.print("The number is ");
serial_lcd.println(number);
// send text to the LCD
// send the number on the LCD
Serial.print("The number is ");
Serial.println(number);
// send text to the hardware port
// to output on Arduino Serial Monitor
,I\RXDUHXVLQJDXQLGLUHFWLRQDOVHULDOGHYLFH¢WKDWLVRQHWKDWRQO\VHQGVRUUHFHLYHV¢
\RX FDQ FRQVHUYH UHVRXUFHV E\ VSHFLI\LQJ D QRQH[LVWHQW SLQ QXPEHU LQ WKH
NewSoftSerialFRQVWUXFWRUIRUWKHOLQH\RXGRQ¦WQHHG)RUH[DPSOHDVHULDO/&'LV
IXQGDPHQWDOO\DQRXWSXWRQO\GHYLFH,I\RXGRQ¦WH[SHFW RUZDQW WRUHFHLYHGDWDIURP
LW\RXFDQWHOO1HZ6RIW6HULDOXVLQJWKLVV\QWD[
#include <NewSoftSerial.h>
...
const int no_such_pin = 255;
const int txpin = 3;
NewSoftSerial serial_lcd(txpin, no_such_pin); // TX-only on pin 3
,QWKLVFDVHZHZRXOGRQO\SK\VLFDOO\FRQQHFWDVLQJOHSLQ WRWKHVHULDO/&'¦V£LQSXW¤
RU£5;¤OLQH
4.13 Sending Data to Two Serial Devices at the Same Time | 127
4.14 Receiving Serial Data from Two Devices at the Same Time
Problem
<RXZDQWWRUHFHLYHGDWDIURPDVHULDOGHYLFHVXFKDVDVHULDO*36EXW\RXDUHDOUHDG\
XVLQJWKHEXLOWLQVHULDOSRUWWRFRPPXQLFDWHZLWK\RXUFRPSXWHU
Solution
7KLVSUREOHPLVVLPLODUWRWKHSUHFHGLQJRQHDQGLQGHHGWKHVROXWLRQLVPXFKWKHVDPH
,I\RXU$UGXLQR¦VVHULDOSRUWLVFRQQHFWHGWRWKHFRQVROHDQG\RXZDQWWRDWWDFKDVHFRQG
VHULDOGHYLFH\RXPXVWFUHDWHDQHPXODWHGSRUWXVLQJDVRIWZDUHVHULDOOLEUDU\VXFKDV
1HZ6RIW6HULDO,QWKLVFDVHZHZLOOEHUHFHLYLQJGDWDIURPWKHHPXODWHGSRUWLQVWHDG
RIZULWLQJWRLWEXWWKHEDVLFVROXWLRQLVYHU\VLPLODU
'RZQORDG1HZ6RIW6HULDOIURP0LNDO+DUW¦VZHEVLWH6HOHFWWZRSLQVWRXVHDV\RXU
WUDQVPLWDQGUHFHLYHOLQHV
&RQQHFW\RXU*36DVVKRZQLQ)LJXUH5[ UHFHLYH LVQRWXVHGLQWKLVH[DPSOHVR
\RXFDQLJQRUHWKH5[FRQQHFWLRQWRSLQLI\RXU*36GRHVQRWKDYHDUHFHLYHSLQ
)LJXUH&RQQHFWLQJDVHULDO*36GHYLFHWRD£VRIW¤VHULDOSRUW
$V\RXGLGLQ5HFLSHFUHDWHDNewSoftSerialREMHFWLQ\RXUVNHWFKDQGWHOOLWZKLFK
SLQV WR FRQWURO ,Q WKH IROORZLQJ H[DPSOH ZH GHILQH D VRIW VHULDO SRUW FDOOHG
serial_gpsXVLQJSLQVDQGIRUUHFHLYHDQGWUDQVPLWUHVSHFWLYHO\
/*
* NewSoftSerialInput sketch
* Read data from a software serial port
*/
128 | Chapter 4:ಗSerial Communications
#include <NewSoftSerial.h>
const int rxpin = 2;
// pin used to receive from GPS
const int txpin = 3;
// pin used to send to GPS
NewSoftSerial serial_gps(txpin, rxpin); // new serial port on pins 2 and 3
void setup()
{
Serial.begin(9600); // 9600 baud for the built-in serial port
serial_gps.begin(4800); // initialize the port, most GPS devices use 4800 baud
}
void loop()
{
if (serial_gps.available() > 0) // any character arrived yet?
{
char c = serial_gps.read();
// if so, read it from the GPS
Serial.print(c, BYTE);
// and echo it to the serial console
}
}
7KLVVKRUWVNHWFKVLPSO\IRUZDUGVDOOLQFRPLQJGDWDIURPWKH*36WRWKH$UGXLQR6HULDO
0RQLWRU,IWKH*36LVIXQFWLRQLQJDQG\RXUZLULQJLVFRUUHFW\RXVKRXOGVHH*36GDWD
GLVSOD\HGRQWKH6HULDO0RQLWRU
Discussion
<RXLQLWLDOL]HDQHPXODWHG1HZ6RIW6HULDOSRUWE\SURYLGLQJSLQQXPEHUVIRUWUDQVPLW
DQGUHFHLYH7KHIROORZLQJFRGHZLOOVHWXSWKHSRUWWRVHQGRQSLQDQGUHFHLYHRQ
SLQ
const int rxpin = 2;
// pin used to receive from GPS
const int txpin = 3;
// pin used to send to GPS
NewSoftSerial serial_gps(txpin, rxpin); // new serial port on pins 2 and 3
7KHV\QWD[IRUUHDGLQJDQHPXODWHGSRUWLVYHU\VLPLODUWRWKDWIRUUHDGLQJIURPDEXLOW
LQ SRUW )LUVW FKHFN WR PDNH VXUH D FKDUDFWHU KDV DUULYHG IURP WKH *36 ZLWK
available()DQGWKHQUHDGLWZLWKread()
,W¦VLPSRUWDQWWRUHPHPEHUWKDWVRIWZDUHVHULDOSRUWVFRQVXPHWLPHDQGUHVRXUFHV$Q
HPXODWHGVHULDOSRUWPXVWGRHYHU\WKLQJWKDWDKDUGZDUHSRUWGRHVXVLQJWKHVDPH
SURFHVVRU \RXU VNHWFK LV WU\LQJ WR GR £UHDO ZRUN¤ ZLWK :KHQHYHU D QHZ FKDUDFWHU
DUULYHVWKHSURFHVVRUPXVWLQWHUUXSWZKDWHYHULWZDVGRLQJWRKDQGOHLW7KLVFDQEH
WLPHFRQVXPLQJ $W EDXG IRU H[DPSOH LW WDNHV WKH $UGXLQR DERXW WZR
PLOOLVHFRQGVWRSURFHVVDVLQJOHFKDUDFWHU:KLOHWZRPLOOLVHFRQGVPD\QRWVRXQGOLNH
PXFKFRQVLGHUWKDWLI\RXUSHHUGHYLFH¢VD\WKH*36XQLWVKRZQHDUOLHU¢WUDQVPLWV
WRFKDUDFWHUVSHUVHFRQG\RXUVNHWFKLVVSHQGLQJWRSHUFHQWRILWVWLPH
WU\LQJWRNHHSXSZLWKWKHVHULDOLQSXW7KLVOHDYHVYHU\OLWWOHWLPHWRDFWXDOO\SURFHVVDOO
WKDWGDWD7KHOHVVRQLVWKDWLI\RXKDYHWZRVHULDOGHYLFHVZKHQSRVVLEOHFRQQHFWWKH
RQHZLWKWKHKLJKHUEDQGZLGWKFRQVXPSWLRQWRWKHEXLOWLQ KDUGZDUH SRUW,I\RX
PXVWFRQQHFWDKLJKEDQGZLGWKGHYLFHWRDVRIWZDUHVHULDOSRUWPDNHVXUHWKHUHVWRI
\RXUVNHWFK¦VORRSLVYHU\HIILFLHQW
4.14 Receiving Serial Data from Two Devices at the Same Time | 129
Download from Wow! eBook <www.wowebook.com>
Receiving data from multiple NewSoftSerial ports
:LWK1HZ6RIW6HULDO EXWQRW6RIWZDUH6HULDO LWLVSRVVLEOHWRFUHDWHPXOWLSOH£VRIW¤
VHULDOSRUWVLQWKHVDPHVNHWFK7KLVLVDXVHIXOZD\WRFRQWUROVD\VHYHUDO;%HHUDGLRV
LQWKHVDPHSURMHFW7KHFDYHDWLVWKDWDWDQ\JLYHQWLPHRQO\RQHRIWKHVHSRUWVFDQ
DFWLYHO\ UHFHLYH GDWD 5HOLDEOH UHFHSWLRQ RQ D VRIWZDUH SRUW UHTXLUHV WKH SURFHVVRU¦V
XQGLYLGHGDWWHQWLRQ7KDW¦VZK\1HZ6RIW6HULDOFDQRQO\DFWLYDWHRQHSRUWIRUGDWDUH
FHSWLRQDWDJLYHQWLPH 7KLVUHVWULFWLRQGRHVQRWDSSO\WRVHQGLQJGDWDRQO\UHFHLYLQJ
LW6HHWKH1HZ6RIW6HULDOGRFXPHQWDWLRQIRUVSHFLILFV
,WLVSRVVLEOHWRUHFHLYHRQWZRGLIIHUHQW1HZ6RIW6HULDOSRUWVLQWKHVDPHVNHWFK<RX
MXVWKDYHWRWDNHVRPHFDUHWKDW\RXDUHQ¦WWU\LQJWRUHFHLYHIURPERWKDWWKHVDPHWLPH
7KHUHDUHPDQ\VXFFHVVIXOGHVLJQVZKLFKVD\PRQLWRUDVHULDO*36GHYLFHIRUDZKLOH
WKHQODWHULQWKHVNHWFKDFFHSWLQSXWIURPDQ;%HH7KHNH\LVWRDOWHUQDWHEHWZHHQ
WKHP1HZ6RIW6HULDOFRQVLGHUVWKH£DFWLYH¤SRUWWREHZKLFKHYHUSRUW\RXKDYHPRVW
UHFHQWO\DFFHVVHGXVLQJWKHreadprintprintlnRUavailablePHWKRG7KHIROORZLQJ
FRGHIUDJPHQWLOOXVWUDWHVKRZ\RXGHVLJQDVNHWFKWRUHDGILUVWIURPRQHSRUWDQGWKHQ
IURPDQRWKHU
/*
* MultiRX sketch
* Receive data from two software serial ports
*/
#include <NewSoftSerial.h>
const int rxpin1 = 2;
const int txpin1 = 3;
const int rxpin2 = 4;
const int txpin2 = 5;
NewSoftSerial gps(txpin1, rxpin1); // gps device connected to pins 2 and 3
NewSoftSerial xbee(txpin2, rxpin2); // gps device connected to pins 2 and 3
void setup()
{
gps.begin(4800);
xbee.begin(9600);
}
void loop()
{
if (xbee.available() > 0) // xbee is active. Any characters available?
{
if (xbee.read() == 'y') // if xbee received a 'y' character
{
unsigned long start = millis(); // begin listening to the GPS
while (start + 100000 > millis())
// listen for 10 seconds
130 | Chapter 4:ಗSerial Communications
{
}
if (gps.available() > 0) // now gps device is active
{
char c = gps.read();
// *** process gps data here
}
}
}
}
7KLV VNHWFK LV GHVLJQHG WR WUHDW WKH ;%HH UDGLR DV WKH DFWLYH SRUW XQWLO LW UHFHLYHV D
y FKDUDFWHU DW ZKLFK SRLQW WKH *36 EHFRPHV DFWLYH $IWHU SURFHVVLQJ *36 GDWD IRU
VHFRQGVWKHVNHWFKRQFHDJDLQUHWXUQVWROLVWHQLQJWRWKH;%HHSRUW'DWDWKDWDUULYHV
RQDQLQDFWLYHSRUWLVVLPSO\GLVFDUGHG
1RWHWKDWWKH£DFWLYHSRUW¤UHVWULFWLRQRQO\DSSOLHVWRPXOWLSOHVRIWSRUWV,I\RXUGHVLJQ
UHDOO\ PXVW UHFHLYH GDWD IURP PRUH WKDQ RQH VHULDO GHYLFH VLPXOWDQHRXVO\ FRQVLGHU
DWWDFKLQJRQHRIWKHVHWRWKHEXLOWLQKDUGZDUHSRUW$OWHUQDWLYHO\LWLVSHUIHFWO\SRVVLEOH
WRDGGDGGLWLRQDOKDUGZDUHSRUWVWR\RXUSURMHFWVXVLQJH[WHUQDOFKLSVGHYLFHVFDOOHG
8$57V
4.15 Setting Up Processing on Your Computer to Send
and Receive Serial Data
Problem
<RXZDQWWRXVHWKH3URFHVVLQJGHYHORSPHQWHQYLURQPHQWWRVHQGDQGUHFHLYHVHULDO
GDWD
Solution
<RXFDQJHWWKH3URFHVVLQJDSSOLFDWLRQIURPWKH'RZQORDGVVHFWLRQRIWKH3URFHVVLQJ
ZHEVLWH KWWSSURFHVVLQJRUJ )LOHV DUH DYDLODEOH IRU HDFK PDMRU RSHUDWLQJ V\VWHP
'RZQORDGWKHDSSURSULDWHRQHIRU\RXURSHUDWLQJV\VWHPDQGXQ]LSWKHILOHWRVRPH
ZKHUHWKDW\RXQRUPDOO\VWRUHDSSOLFDWLRQV2QD:LQGRZVFRPSXWHUWKLVPLJKWEHD
ORFDWLRQ OLNH &?3URJUDP )LOHV?3URFHVVLQJ? 2Q D 0DF LW PLJKW EH VRPHWKLQJ
OLNH$SSOLFDWLRQV3URFHVVLQJ
,I\RXLQVWDOOHG3URFHVVLQJRQWKHVDPHFRPSXWHUWKDWLVUXQQLQJWKH$UGXLQR,'(WKH
RQO\RWKHUWKLQJ\RXQHHGWRGRLVLGHQWLI\WKHVHULDOSRUWLQ3URFHVVLQJ7KHIROORZLQJ
3URFHVVLQJVNHWFKSULQWVWKHVHULDOSRUWVDYDLODEOH
/**
* GettingStarted
*
* A sketch to list the available serial ports
* and display characters received
*/
4.15 Setting Up Processing on Your Computer to Send and Receive Serial Data | 131
import processing.serial.*;
Serial myPort;
int portIndex = 0;
int val;
// Create object from Serial class
// set this to the port connected to Arduino
// Data received from the serial port
void setup()
{
size(200, 200);
println(Serial.list()); // print the list of all the ports
println(" Connecting to -> " + Serial.list()[portIndex]);
myPort = new Serial(this, Serial.list()[portIndex], 9600);
}
void draw()
{
if ( myPort.available() > 0) // If data is available,
{
val = myPort.read();
// read it and store it in val
print(val);
}
}
,I\RXDUHUXQQLQJ3URFHVVLQJRQDFRPSXWHUWKDWLVQRWUXQQLQJWKH$UGXLQRGHYHORS
PHQWHQYLURQPHQW\RXQHHGWRLQVWDOOWKH$UGXLQR86%GULYHUV &KDSWHUGHVFULEHV
KRZWRGRWKLV 6HWWKHYDULDEOH portIndexWRPDWFKWKHSRUWXVHGE\$UGXLQR<RXFDQVHHWKHSRUW
QXPEHUVSULQWHGLQWKH3URFHVVLQJWH[WZLQGRZ WKHDUHDEHORZWKHVRXUFHFRGHQRW
WKH VHSDUDWH 'LVSOD\ ZLQGRZ VHH KWWSSURFHVVLQJRUJUHIHUHQFHHQYLURQPHQW 5HFLSHGHVFULEHVKRZWRILQGRXWZKLFKVHULDOSRUW\RXU$UGXLQRERDUGLVXVLQJ
132 | Chapter 4:ಗSerial Communications
CHAPTER 5
Simple Digital and Analog Input
5.0 Introduction
7KH$UGXLQR¦VDELOLW\WRVHQVHGLJLWDODQGDQDORJLQSXWVDOORZVLWWRUHVSRQGWR\RXDQG
WRWKHZRUOGDURXQG\RX7KLVFKDSWHULQWURGXFHVWHFKQLTXHV\RXFDQXVHWRGRXVHIXO
WKLQJVZLWKWKHVHLQSXWV7KLVLVWKHILUVWRIPDQ\FKDSWHUVWRFRPHWKDWFRYHUHOHFWULFDO
FRQQHFWLRQVWR$UGXLQR,I\RXGRQ¦WKDYHDQHOHFWURQLFVEDFNJURXQG\RXPD\ZDQW
WRORRNWKURXJK$SSHQGL[$RQHOHFWURQLFFRPSRQHQWV$SSHQGL[%RQVFKHPDWLFGL
DJUDPVDQGGDWDVKHHWV$SSHQGL[&RQEXLOGLQJDQGFRQQHFWLQJFLUFXLWVDQG$SSHQ
GL[(RQKDUGZDUHWURXEOHVKRRWLQJ,QDGGLWLRQPDQ\JRRGLQWURGXFWRU\WXWRULDOVDUH
DYDLODEOHFRYHULQJHOHFWURQLFV7ZRWKDWDUHSDUWLFXODUO\UHOHYDQWWR$UGXLQRDUH*HWWLQJ
6WDUWHGZLWK$UGXLQRE\0DVVLPR%DQ]L 2¦5HLOO\ DQG0DNLQJ7KLQJV7DONE\7RP
,JRH 2¦5HLOO\ 2WKHUERRNVRIIHULQJDEDFNJURXQGRQHOHFWURQLFVWRSLFVFRYHUHGLQ
WKLVDQGWKHIROORZLQJFKDSWHUVLQFOXGH*HWWLQJ6WDUWHGLQ(OHFWURQLFVE\)RUUHVW0LPV
0DVWHU3XEOLVKLQJ DQG3K\VLFDO&RPSXWLQJE\7RP,JRH &HQJDJH ,IZLULQJFRPSRQHQWVWR\RXU$UGXLQRLVQHZWR\RXEHFDUHIXODERXW
KRZ\RXFRQQHFWDQGSRZHUWKHWKLQJV\RXDWWDFK$UGXLQRXVHVDUR
EXVWFRQWUROOHUFKLSWKDWFDQWDNHDIDLUDPRXQWRIDEXVHEXW\RXFDQ
GDPDJHWKHFKLSLI\RXFRQQHFWWKHZURQJYROWDJHVRUVKRUWFLUFXLWDQ
RXWSXWSLQ0RVW$UGXLQRFRQWUROOHUFKLSVDUHSRZHUHGE\YROWVDQG
\RX PXVW QRW FRQQHFW H[WHUQDO SRZHU WR $UGXLQR SLQV ZLWK D KLJKHU
YROWDJHWKDQWKLV RUYROWVLI\RXU$UGXLQRFRQWUROOHUUXQVRQWKLV
YROWDJH $UGXLQR ERDUGV WKDW DUH DLPHG DW EHJLQQHUV KDYH WKH PDLQ FKLS LQ D
VRFNHWWKDWFDQEHUHPRYHGDQGUHSODFHGVR\RXGRQ¦WQHHGWRUHSODFH
WKHZKROHERDUGLI\RXGDPDJHWKHFKLS
)LJXUHVKRZVWKHDUUDQJHPHQWRISLQVRQDVWDQGDUG$UGXLQRERDUG6HHKWWSZZZ
DUGXLQRFFHQ0DLQ+DUGZDUHIRUDOLVWRIDOOWKHRIILFLDOERDUGVDORQJZLWKOLQNVWR
FRQQHFWLRQLQIRUPDWLRQIRUHDFK,I\RXUERDUGLVQRWRQWKDWOLVWFKHFN\RXUERDUG
VXSSOLHU¦VZHEVLWHIRUFRQQHFWLRQLQIRUPDWLRQ
133
)LJXUH6WDQGDUG$UGXLQRERDUG
7KLVFKDSWHUFRYHUVWKH$UGXLQRSLQVWKDWFDQVHQVHGLJLWDODQGDQDORJLQSXWV'LJLWDO
LQSXWSLQVVHQVHWKHSUHVHQFHDQGDEVHQFHRIYROWDJHRQDSLQ$QDORJLQSXWSLQVPHDV
XUHDUDQJHRIYROWDJHVRQDSLQ
7KH$UGXLQRIXQFWLRQWRGHWHFWGLJLWDOLQSXWLVdigitalReadDQGLWWHOOV\RXUVNHWFKLID
YROWDJHRQDSLQLVHIGH YROWV RULOW YROWV 7KH$UGXLQRIXQFWLRQWRFRQILJXUHD
SLQIRUUHDGLQJLQSXWLVpinMode(pin, INPUT)
2QDW\SLFDOERDUGWKHUHDUHGLJLWDOSLQV QXPEHUHGWR DVVKRZQDWWKHWRSRI
)LJXUH3LQVDQG PDUNHG5;DQG7; DUHXVHGIRUWKH86%VHULDOFRQQHFWLRQ
DQGVKRXOGEHDYRLGHGIRURWKHUXVHV,I\RXQHHGPRUHGLJLWDOSLQVRQDVWDQGDUGERDUG
\RXFDQXVHWKHDQDORJSLQVDVGLJLWDOSLQV DQDORJSLQVWKURXJKFDQEHXVHGDV
GLJLWDOSLQVWKURXJK 7KH0HJDERDUGKDVPDQ\PRUHGLJLWDODQGDQDORJSLQV'LJLWDOSLQVWKURXJKDQG
DQDORJSLQVWKURXJKDUHORFDWHGLQWKHVDPHSODFHDVRQWKHVWDQGDUGERDUGVRWKDW
KDUGZDUHVKLHOGVGHVLJQHGIRUWKHVWDQGDUGERDUGFDQILWRQWRD0HJD$VZLWKWKH
VWDQGDUGERDUG\RXFDQXVHDQDORJSLQVDVGLJLWDOSLQVEXWZLWKWKH0HJDDQDORJSLQV
WKURXJKDUHGLJLWDOSLQQXPEHUVWKURXJK)LJXUHVKRZVWKH0HJDSLQ
OD\RXW
0RVWERDUGVKDYHDQ/('FRQQHFWHGWRSLQDQGVRPHRIWKHUHFLSHVXVHWKLVDVDQ
RXWSXWLQGLFDWRU,I\RXUERDUGGRHVQRWKDYHDQ/('RQSLQVNLSDKHDGWR5HF
LSHLI\RXQHHGKHOSFRQQHFWLQJDQ/('WRDGLJLWDOSLQ
5HFLSHVFRYHULQJGLJLWDOLQSXWVRPHWLPHVXVHH[WHUQDOUHVLVWRUVWRSURYLGHWKHYROWDJH
WKDWLVVHQVHGE\ digitalRead7KHVHUHVLVWRUVDUHFDOOHGSXOOXSUHVLVWRUV VRQDPHG
EHFDXVHWKHYROWDJHLV£SXOOHGXS¤WRWKH9OLQHWKDWWKHUHVLVWRULVFRQQHFWHGWR RU
134 | Chapter 5:ಗSimple Digital and Analog Input
)LJXUH$UGXLQR0HJDERDUG
SXOOGRZQUHVLVWRUV WKHYROWDJHLV£SXOOHGGRZQ¤WRYROWV $OWKRXJK.RKPVLVD
FRPPRQO\XVHGYDOXHDQ\WKLQJEHWZHHQ.DQG.RUPRUHZLOOZRUNVHH$SSHQ
GL[$IRUPRUHLQIRUPDWLRQDERXWWKHFRPSRQHQWVXVHGLQWKLVFKDSWHU
8QOLNHDGLJLWDOYDOXHZKLFKLVRQO\RQRURIIDQDORJYDOXHVDUHFRQWLQXRXVO\YDULDEOH
7KHYROXPHVHWWLQJRIDGHYLFHLVDJRRGH[DPSOHLWLVQRWMXVWRQRURIIEXWLWFDQKDYH
DUDQJHRIYDOXHVLQEHWZHHQ0DQ\VHQVRUVSURYLGHLQIRUPDWLRQE\YDU\LQJWKHYROWDJH
WR FRUUHVSRQG WR WKH VHQVRU PHDVXUHPHQW $UGXLQR FRGH XVHV D IXQFWLRQ FDOOHG
analogReadWRJHWDYDOXHSURSRUWLRQDOWRWKHYROWDJHLWVHHVRQRQHRILWVDQDORJSLQV
7KHYDOXHZLOOEHLIWKHUHDUHYROWVRQWKHSLQDQGIRUYROWV7KHYDOXHLQ
EHWZHHQZLOOEHSURSRUWLRQDOWRWKHYROWDJHRQWKHSLQVRYROWV KDOIRIYROWV ZLOO
UHVXOWLQDYDOXHRIURXJKO\ KDOIRI <RXFDQVHHWKHVL[DQDORJLQSXWSLQV
PDUNHGWR DWWKHERWWRPRI)LJXUH WKHVHSLQVFDQDOVREHXVHGDVGLJLWDOSLQV
WRLIWKH\DUHQRWQHHGHGIRUDQDORJ 6RPHRIWKHDQDORJUHFLSHVXVHDSRWHQWL
RPHWHU SRWIRUVKRUWDOVRFDOOHGDYDULDEOHUHVLVWRU WRYDU\WKHYROWDJHRQDSLQ:KHQ
FKRRVLQJDSRWHQWLRPHWHUDYDOXHRI.LVWKHEHVWRSWLRQIRUFRQQHFWLQJWRDQDORJ
SLQV
$OWKRXJKPRVWRIWKHFLUFXLWVLQWKLVFKDSWHUDUHUHODWLYHO\HDV\WRFRQQHFW\RXPD\
ZDQWWRFRQVLGHUJHWWLQJDVROGHUOHVVEUHDGERDUGWRVLPSOLI\\RXUZLULQJWRH[WHUQDO
FRPSRQHQWVVRPHFKRLFHVDUHWKH-DPHFR WZREXVURZVSHUVLGH 5DGLR6KDFN
RQHEXVURZSHUVLGH 'LJL.H\1'DQG6SDUN)XQ357
$QRWKHUKDQG\LWHPLVDQLQH[SHQVLYHPXOWLPHWHU$OPRVWDQ\ZLOOGRDVORQJDVLWFDQ
PHDVXUHYROWDJHDQGUHVLVWDQFH&RQWLQXLW\FKHFNLQJDQGFXUUHQWPHDVXUHPHQWDUHQLFH
DGGLWLRQDOIHDWXUHVWRKDYH 7KH-DPHFR5DGLR6KDFNDQG6SDUN)XQ
72/RIIHUWKHVHIHDWXUHV
5.0 Introduction | 135
5.1 Using a Switch
Problem
<RXZDQW\RXUVNHWFKWRUHVSRQGWRWKHFORVLQJRIDQHOHFWULFDOFRQWDFWIRUH[DPSOHD
SXVKEXWWRQRURWKHUVZLWFKRUDQH[WHUQDOGHYLFHWKDWPDNHVDQHOHFWULFDOFRQQHFWLRQ
Solution
8VHdigitalReadWRGHWHUPLQHWKHVWDWHRIDVZLWFKFRQQHFWHGWRDQ$UGXLQRGLJLWDOSLQ
VHWDVLQSXW7KHIROORZLQJFRGHOLJKWVDQ/('ZKHQDVZLWFKLVSUHVVHG )LJXUH
VKRZVKRZLWVKRXOGEHZLUHGXS /*
*/
Pushbutton sketch
a switch connected to pin 2 lights the LED on pin 13
const int ledPin = 13;
const int inputPin = 2;
// choose the pin for the LED
// choose the input pin (for a pushbutton)
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(inputPin, INPUT);
}
// declare LED as output
// declare pushbutton as input
void loop(){
int val = digitalRead(inputPin);
if (val == HIGH)
{
digitalWrite(ledPin, HIGH);
}
else
{
digitalWrite(ledPin, LOW);
}
}
// read input value
// check if the input is HIGH
// turn LED on if switch is pressed
// turn LED off
6WDQGDUG$UGXLQRERDUGVKDYHDEXLOWLQ/('FRQQHFWHGWRSLQ,I
\RXUERDUGGRHVQRWVHH5HFLSHIRULQIRUPDWLRQRQFRQQHFWLQJDQ
/('WRDQ$UGXLQRSLQ
Discussion
7KHsetupIXQFWLRQFRQILJXUHVWKH/('SLQDVOUTPUTDQGWKHVZLWFKSLQDVINPUT
136 | Chapter 5:ಗSimple Digital and Analog Input
)LJXUH6ZLWFKFRQQHFWHGXVLQJSXOOGRZQUHVLVWRU
$SLQPXVWEHVHWWROUTPUTPRGHIRUdigitalWriteWRFRQWUROWKHSLQ¦V
RXWSXWYROWDJH,WPXVWEHLQINPUTPRGHWRUHDGWKHGLJLWDOLQSXW
7KHdigitalReadIXQFWLRQPRQLWRUVWKHYROWDJHRQWKHLQSXWSLQ inputPin DQGLWUH
WXUQVDYDOXHRIHIGHLIWKHYROWDJHLVKLJK YROWV DQGLOWLIWKHYROWDJHLVORZ YROWV $FWXDOO\DQ\YROWDJHWKDWLVJUHDWHUWKDQYROWV KDOIRIWKHYROWDJHSRZHULQJWKH
FKLS LVFRQVLGHUHGHIGHDQGOHVVWKDQWKLVLVWUHDWHGDVLOW,IWKHSLQLVOHIWXQFRQQHFWHG
NQRZQDVIORDWLQJ WKHYDOXHUHWXUQHGIURP digitalReadLVLQGHWHUPLQDWH LWPD\EH
HIGHRU LOWDQGLWFDQQRWEHUHOLDEO\XVHG 7KHUHVLVWRUVKRZQLQ)LJXUHHQVXUHV
WKDWWKHYROWDJHRQWKHSLQZLOOEHORZZKHQWKHVZLWFKLVQRWSUHVVHGEHFDXVHWKH
UHVLVWRU£SXOOVGRZQ¤WKHYROWDJHWRJURXQG:KHQWKHVZLWFKLVSXVKHGDFRQQHFWLRQ
LVPDGHEHWZHHQWKHSLQDQGYROWVVRWKHYDOXHRQWKHSLQLQWHUSUHWHGE\digital
ReadFKDQJHVIURPLOWWRHIGH
'RQRWFRQQHFWDGLJLWDORUDQDORJSLQWRDYROWDJHKLJKHUWKDQYROWV
RUYROWVRQD9ERDUG 7KLVFDQGDPDJHWKHSLQDQGSRVVLEO\
GHVWUR\WKHHQWLUHFKLS$OVRPDNHVXUH\RXGRQ¦WZLUHWKHVZLWFKVR
WKDWLWVKRUWVWKHYROWVWRJURXQG ZLWKRXWDUHVLVWRU $OWKRXJKWKLV
PD\QRWGDPDJHWKH$UGXLQRFKLSLWLVQRWJRRGIRUWKHSRZHUVXSSO\
5.1 Using a Switch | 137
,QWKLVH[DPSOHWKHYDOXHIURP digitalReadLVVWRUHGLQWKHYDULDEOH val7KLVZLOOEH
HIGHLIWKHEXWWRQLVSUHVVHGLOWRWKHUZLVH
7KHVZLWFKXVHGLQWKLVH[DPSOH DQGDOPRVWHYHU\ZKHUHHOVHLQWKLV
ERRN PDNHVHOHFWULFDOFRQWDFWZKHQSUHVVHGDQGEUHDNVFRQWDFWZKHQ
QRWSUHVVHG7KHVHVZLWFKHVDUHFDOOHG1RUPDOO\2SHQ 12 VHHWKLV
ERRN¦VZHEVLWHIRUSDUWQXPEHUV7KHRWKHUNLQGRIPRPHQWDU\VZLWFK
LVFDOOHG1RUPDOO\&ORVHG 1& 7KHRXWSXWSLQFRQQHFWHGWRWKH/('LVWXUQHGRQZKHQ\RXVHWvalWRHIGHLOOXPLQDWLQJ
WKH/('
$OWKRXJK$UGXLQRVHWVDOOGLJLWDOSLQVDVLQSXWVE\GHIDXOWLWLVDJRRGSUDFWLFHWRVHW
WKLVH[SOLFLWO\LQ\RXUVNHWFKWRUHPLQG\RXUVHOIDERXWWKHSLQV\RXDUHXVLQJ
<RXPD\VHHVLPLODUFRGHWKDWXVHVtrueLQVWHDGRIHIGHWKHVHFDQEHXVHGLQWHUFKDQJH
DEO\ WKH\DUHDOVRVRPHWLPHVUHSUHVHQWHGDV1 /LNHZLVHfalseLVWKHVDPHDVLOWDQG
08VHWKHIRUPWKDWEHVWH[SUHVVHVWKHPHDQLQJRIWKHORJLFLQ\RXUDSSOLFDWLRQ
$OPRVWDQ\VZLWFKFDQEHXVHGDOWKRXJKWKHRQHVFDOOHGPRPHQWDU\WDFWLOHVZLWFKHVDUH
SRSXODUEHFDXVHWKH\DUHLQH[SHQVLYHDQGFDQSOXJGLUHFWO\LQWRDEUHDGERDUG6HHWKH
ZHEVLWHIRUWKLVERRNIRUVRPHVXSSOLHUSDUWQXPEHUV
+HUHLVDQRWKHUZD\WRLPSOHPHQWWKHORJLFLQWKHSUHFHGLQJVNHWFK
void loop()
{
digitalWrite(ledPin, digitalRead(inputPin)); // turn LED ON if input pin is
HIGH, else turn OFF
}
7KLVGRHVQ¦WVWRUHWKHEXWWRQVWDWHLQWRDYDULDEOH,QVWHDGLWVHWVWKH/('RQRURII
GLUHFWO\IURPWKHYDOXHREWDLQHGIURP digitalRead,WLVDKDQG\VKRUWFXWEXWLI\RX
ILQGLWRYHUO\WHUVHWKHUHLVQRSUDFWLFDOGLIIHUHQFHLQSHUIRUPDQFHVRSLFNZKLFKHYHU
IRUP\RXILQGHDVLHUWRXQGHUVWDQG
7KHSXOOXSFRGHLVVLPLODUWRWKHSXOOGRZQYHUVLRQEXWWKHORJLFLVUHYHUVHGWKHYDOXH
RQWKHSLQJRHVLOWZKHQWKHEXWWRQLVSUHVVHG VHH)LJXUHIRUDVFKHPDWLFGLDJUDP
RIWKLV ,WPD\KHOSWRWKLQNRIWKLVDVSUHVVLQJWKHVZLWFKDOWNFDXVLQJWKHRXWSXWWR
JRLOW
void loop()
{
int val = digitalRead(inputPin);
if (val == HIGH)
{
digitalWrite(ledPin, LOW);
}
138 | Chapter 5:ಗSimple Digital and Analog Input
// read input value
// check if the input is HIGH
// turn LED OFF
}
else
{
digitalWrite(ledPin, HIGH);
}
// turn LED ON
)LJXUH6ZLWFKFRQQHFWHGXVLQJSXOOXSUHVLVWRU
See Also
7KH$UGXLQRUHIHUHQFHIRUdigitalReadKWWSDUGXLQRFFHQ5HIHUHQFH'LJLWDO5HDG
7KH$UGXLQRUHIHUHQFHIRUdigitalWriteKWWSDUGXLQRFFHQ5HIHUHQFH'LJLWDO:ULWH
7KH$UGXLQRUHIHUHQFHIRUpinModeKWWSDUGXLQRFFHQ5HIHUHQFH3LQ0RGH
7KH$UGXLQRUHIHUHQFHVIRUFRQVWDQWV HIGH LOWHWF KWWSDUGXLQRFFHQ5HIHUHQFH
&RQVWDQWV
$UGXLQRWXWRULDORQGLJLWDOSLQVKWWSDUGXLQRFFHQ7XWRULDO'LJLWDO3LQV
5.2 Using a Switch Without External Resistors
Problem
<RXZDQWWRVLPSOLI\\RXUZLULQJE\HOLPLQDWLQJH[WHUQDOSXOOXSUHVLVWRUVZKHQFRQ
QHFWLQJVZLWFKHV
5.2 Using a Switch Without External Resistors | 139
Solution
$VH[SODLQHGLQ5HFLSHGLJLWDOLQSXWVPXVWKDYHDUHVLVWRUWRKROGWKHSLQWRDNQRZQ
YDOXHZKHQWKHVZLWFKLVQRWSUHVVHG$UGXLQRKDVLQWHUQDOSXOOXSUHVLVWRUVWKDWFDQ
EHHQDEOHGE\ZULWLQJD HIGHYDOXHWRDSLQWKDWLVLQ INPUTPRGH WKHFRGHIRUWKLVLV
VKRZQLQ5HFLSH )RUWKLVH[DPSOHWKHVZLWFKLVZLUHGDVVKRZQLQ)LJXUH7KLVLVDOPRVWH[DFWO\WKH
VDPHDV)LJXUHEXWZLWKRXWDQH[WHUQDOUHVLVWRU
)LJXUH6ZLWFKZLUHGIRUXVHZLWKLQWHUQDOSXOOXSUHVLVWRU
7KHVZLWFKLVRQO\FRQQHFWHGEHWZHHQSLQDQG*QG*QGLVVKRUWIRUJURXQGDQGLV
DWYROWVE\GHILQLWLRQ
/*
Pullup sketch
a switch connected to pin 2 lights the LED on pin 13
*/
const int ledPin = 13;
const int inputPin = 2;
// output pin for the LED
// input pin for the switch
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(inputPin, INPUT);
digitalWrite(inputPin,HIGH);
// turn on internal pull-up on the inputPin
140 | Chapter 5:ಗSimple Digital and Analog Input
Download from Wow! eBook <www.wowebook.com>
}
void loop(){
int val = digitalRead(inputPin);
if (val == HIGH)
{
digitalWrite(ledPin, HIGH);
}
else
{
digitalWrite(ledPin, LOW);
}
}
// read input value
// check if the input is HIGH
// turn LED OFF
// turn LED ON
7KHUHDUHDIHZ*QGSLQVRQDQ$UGXLQRERDUGWKH\DUHDOOFRQQHFWHG
VRSLFNZKLFKHYHULVFRQYHQLHQW
Discussion
<RXHQDEOHLQWHUQDOSXOOXSUHVLVWRUVE\ZULWLQJD HIGHYDOXHWRDSLQLQLQSXWPRGH
8VLQJ digitalWrite(pin, HIGH)RQDSLQLQLQSXWPRGHPD\QRWEHLQWXLWLYHDWILUVW
EXW\RX¦OOVRRQJHWXVHGWRLW<RXFDQWXUQWKHSXOOXSRIIE\ZULWLQJDLOWYDOXHWRWKH
SLQ
,I\RXUDSSOLFDWLRQVZLWFKHVWKHSLQPRGHEDFNDQGIRUWKEHWZHHQLQSXWDQGRXWSXW
EHDULQPLQGWKDWWKHVWDWHRIWKHSLQZLOOUHPDLQHIGHRULOWZKHQ\RXFKDQJHPRGHV
,QRWKHUZRUGVLI\RXKDYHVHWDQRXWSXWSLQHIGHDQGWKHQFKDQJHWRLQSXWPRGHWKH
SXOOXSZLOOEHRQDQGUHDGLQJWKHSLQZLOOSURGXFHD HIGH,I\RXVHWWKHSLQ LOWLQ
RXWSXWPRGHZLWK digitalWrite(pin, LOW)DQGWKHQFKDQJHWRLQSXWPRGHZLWK pin
Mode(pin, INPUT)WKHSXOOXSZLOOEHRII,I\RXWXUQDSXOOXSRQFKDQJLQJWRRXWSXW
PRGHZLOOVHWWKHSLQ HIGHZKLFKFRXOGIRUH[DPSOHXQLQWHQWLRQDOO\OLJKWDQ/('
FRQQHFWHGWRLW
7KHLQWHUQDOSXOOXSUHVLVWRUVDUH.RKPV7KLVLVVXLWDEOHIRUPRVWDSSOLFDWLRQVEXW
VRPHGHYLFHVPD\UHTXLUHORZHUYDOXHUHVLVWRUV¢VHHWKHGDWDVKHHWIRUH[WHUQDOGHYLFHV
\RXZDQWWRFRQQHFWWR$UGXLQRWRVHHLIWKHLQWHUQDOSXOOXSVDUHVXLWDEOHRUQRW
5.3 Reliably Detecting the Closing of a Switch
Problem
<RXZDQWWRDYRLGIDOVHUHDGLQJVGXHWRFRQWDFWERXQFH FRQWDFWERXQFHSURGXFHVVSX
ULRXVVLJQDOVDWWKHPRPHQWWKHVZLWFKFRQWDFWVFORVHRURSHQ 7KHSURFHVVRIHOLPL
QDWLQJVSXULRXVUHDGLQJVLVFDOOHGGHERXQFLQJ
5.3 Reliably Detecting the Closing of a Switch | 141
Solution
7KHUH DUH PDQ\ ZD\V WR VROYH WKLV SUREOHP KHUH LV RQH XVLQJ WKH ZLULQJ VKRZQ LQ
)LJXUHIURP5HFLSH
/*
Debounce sketch
a switch connected to pin 2 lights the LED on pin 13
debounce logic prevents misreading of the switch state
*/
const int inputPin = 2;
const int ledPin = 13;
const int debounceDelay = 10;
// the number of the input pin
// the number of the output pin
// milliseconds to wait until stable
// debounce returns true if the switch in the given pin is closed and stable
boolean debounce(int pin)
{
boolean state;
boolean previousState;
previousState = digitalRead(pin);
// store switch state
for(int counter=0; counter < debounceDelay; counter++)
{
delay(1);
// wait for 1 millisecond
state = digitalRead(pin); // read the pin
if( state != previousState)
{
counter = 0; // reset the counter if the state changes
previousState = state; // and save the current state
}
}
// here when the switch state has been stable longer than the debounce period
return state;
}
void setup()
{
pinMode(inputPin, INPUT);
pinMode(ledPin, OUTPUT);
}
void loop()
{
if(debounce(inPin))
{
digitalWrite(outPin, HIGH);
}
}
7KHdebounceIXQFWLRQLVFDOOHG XVHG ZLWKWKHSLQQXPEHURIWKHVZLWFK\RXZDQWWR
GHERXQFH WKH IXQFWLRQ UHWXUQV true LI WKH VZLWFK LV SUHVVHG DQG VWDEOH ,W UHWXUQV
falseLILWLVQRWSUHVVHGRUQRW\HWVWDEOH
142 | Chapter 5:ಗSimple Digital and Analog Input
Discussion
7KHdebouncePHWKRGFKHFNVWRVHHLILWJHWVWKHVDPHUHDGLQJIURPWKHVZLWFKDIWHUD
GHOD\WKDWQHHGVWREHORQJHQRXJKIRUWKHVZLWFKFRQWDFWVWRVWRSERXQFLQJ<RXPD\
UHTXLUHORQJHULQWHUYDOVIRU£ERXQFLHU¤VZLWFKHV VRPHVZLWFKHVFDQUHTXLUHDVPXFKDV
PVRUPRUH 7KHIXQFWLRQZRUNVE\UHSHDWHGO\FKHFNLQJWKHVWDWHRIWKHVZLWFKIRU
DVPDQ\PLOOLVHFRQGVDVGHILQHGLQWKHdebounceWLPH,IWKHVZLWFKUHPDLQVVWDEOHIRU
WKLVWLPHWKHVWDWHRIWKHVZLWFKZLOOEHUHWXUQHG trueLISUHVVHGDQG falseLIQRW ,I
WKHVZLWFKVWDWHFKDQJHVZLWKLQWKHGHERXQFHSHULRGWKHFRXQWHULVUHVHWVRWKDWWKH
FKHFNVVWDUWRYHUXQWLOWKHVZLWFKVWDWHGRHVQRWFKDQJHZLWKLQWKHGHERXQFHWLPH
,I\RXUZLULQJXVHVSXOOXSUHVLVWRUVLQVWHDGRISXOOGRZQUHVLVWRUV VHH5HFLSH \RX
QHHGWRLQYHUWWKHYDOXHUHWXUQHGIURPWKH debounceIXQFWLRQEHFDXVHWKHVWDWHJRHV
LOW ZKHQ WKH VZLWFK LV SUHVVHG XVLQJ SXOOXSV EXW WKH IXQFWLRQ VKRXOG UHWXUQ true
trueLVWKHVDPHDVHIGH ZKHQWKHVZLWFKLVSUHVVHG7KHGHERXQFHFRGHXVLQJSXOO
XSVLVDVIROORZVRQO\WKHODVWIRXUOLQHV KLJKOLJKWHG DUHFKDQJHGIURPWKHSUHYLRXV
YHUVLRQ
boolean debounce(int pin)
{
boolean state;
boolean previousState;
previousState = digitalRead(pin);
// store switch state
for(int counter=0; counter < debounceDelay; counter++)
{
delay(1);
// wait for 1 millisecond
state = digitalRead(pin); // read the pin
if( state != previousState)
{
counter = 0; // reset the counter if the state changes
previousState = state; // and save the current state
}
}
// here when the switch state has been stable longer than the debounce period
if(state == LOW) // LOW means pressed (because pull-ups are used)
return true;
else
return false;
}
)RUWHVWLQJ\RXFDQDGGDcountYDULDEOHWRGLVSOD\WKHQXPEHURISUHVVHV,I\RXYLHZ
WKLVRQWKH6HULDO0RQLWRU VHH&KDSWHU \RXFDQVHHZKHWKHULWLQFUHPHQWVRQFHSHU
SUHVV,QFUHDVHWKHYDOXHRIdebounceDelayXQWLOWKHFRXQWNHHSVVWHSZLWKWKHSUHVVHV
7KHIROORZLQJIUDJPHQWSULQWVWKHYDOXHRIcountZKHQXVHGZLWKWKHdebounceIXQFWLRQ
VKRZQHDUOLHU
int count;
// add this variable to store the number of presses
void setup()
{
pinMode(inPin, INPUT);
5.3 Reliably Detecting the Closing of a Switch | 143
}
pinMode(outPin, OUTPUT);
Serial.begin(9600); // add this to the setup function
void loop()
{
if(debounce(inPin))
{
digitalWrite(outPin, HIGH);
count++;
// increment count
Serial.println(count); // display the count on the Serial Monitor
}
}
7KLVdebounce()IXQFWLRQZLOOZRUNIRUDQ\QXPEHURIVZLWFKHVEXW\RXPXVWHQVXUH
WKDWWKHSLQVXVHGDUHLQLQSXWPRGH
$SRWHQWLDOGLVDGYDQWDJHRIWKLVPHWKRGIRUVRPHDSSOLFDWLRQVLVWKDWIURPWKHWLPHWKH
debounceIXQFWLRQLVFDOOHGHYHU\WKLQJZDLWVXQWLOWKHVZLWFKLVVWDEOH,QPRVWFDVHV
WKLVGRHVQ¦WPDWWHUEXW\RXUVNHWFKPD\QHHGWREHDWWHQGLQJWRRWKHUWKLQJVZKLOH
ZDLWLQJIRU\RXUVZLWFKWRVWDELOL]H<RXFDQXVHWKHFRGHVKRZQLQ5HFLSHWRRYHU
FRPHWKLVSUREOHP
See Also
6HHWKH'HERXQFHH[DPSOHVNHWFKGLVWULEXWHGZLWK$UGXLQR)URPWKH)LOHPHQXVHOHFW
([DPSOHVൺ'LJLWDOൺ'HERXQFH
5.4 Determining How Long a Switch Is Pressed
Problem
<RXUDSSOLFDWLRQZDQWVWRGHWHFWWKHOHQJWKRIWLPHDVZLWFKKDVEHHQLQLWVFXUUHQW
VWDWH2U\RXZDQWWRLQFUHPHQWDYDOXHZKLOHDVZLWFKLVSXVKHGDQG\RXZDQWWKHUDWH
WRLQFUHDVHWKHORQJHUWKHVZLWFKLVKHOG WKHZD\PDQ\HOHFWURQLFFORFNVDUHVHW 2U
\RXZDQWWRNQRZLIDVZLWFKKDVEHHQSUHVVHGORQJHQRXJKIRUWKHUHDGLQJWREHVWDEOH
VHH5HFLSH Solution
7KHIROORZLQJVNHWFKGHPRQVWUDWHVWKHVHWWLQJRIDFRXQWGRZQWLPHU7KHZLULQJLVWKH
VDPHDVLQ)LJXUHIURP5HFLSH3UHVVLQJDVZLWFKVHWVWKHWLPHUE\LQFUHPHQWLQJ
WKHWLPHUFRXQWUHOHDVLQJWKHVZLWFKVWDUWVWKHFRXQWGRZQ7KHFRGHGHERXQFHVWKH
VZLWFKDQGDFFHOHUDWHVWKHUDWHDWZKLFKWKHFRXQWHULQFUHDVHVZKHQWKHVZLWFKLVKHOG
IRUORQJHUSHULRGV7KHWLPHUFRXQWLVLQFUHPHQWHGE\RQHZKHQWKHVZLWFKLVLQLWLDOO\
SUHVVHG DIWHUGHERXQFLQJ +ROGLQJWKHVZLWFKIRUPRUHWKDQRQHVHFRQGLQFUHDVHVWKH
LQFUHPHQWUDWHE\IRXUKROGLQJWKHVZLWFKIRUIRXUVHFRQGVLQFUHDVHVWKHUDWHE\WHQ
144 | Chapter 5:ಗSimple Digital and Analog Input
5HOHDVLQJWKHVZLWFKVWDUWVWKHFRXQWGRZQDQGZKHQWKHFRXQWUHDFKHV]HURDSLQLV
VHWHIGH LQWKLVH[DPSOHOLJKWLQJDQ/(' /*
SwitchTime sketch
Countdown timer that decrements every tenth of a second
lights an LED when 0
Pressing button increments count, holding button down increases
rate of increment
*/
const int ledPin = 13;
const int inPin = 2;
const int debounceTime = 20;
for the switch to be stable
const int fastIncrement = 1000;
milliseconds
const int veryFastIncrement = 4000;
this many milliseconds
int count = 0;
second until reaches 0
// the number of the output pin
// the number of the input pin
// the time in milliseconds required
// increment faster after this many
// and increment even faster after
// count decrements every tenth of a
void setup()
{
pinMode(inPin, INPUT);
digitalWrite(inPin, HIGH); // turn on pull-up resistor
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop()
{
int duration = switchTime();
if( duration > veryFastIncrement)
count = count + 10;
else if ( duration > fastIncrement)
count = count + 4;
else if ( duration > debounceTime)
count = count + 1;
else
{
// switch not pressed so service the timer
if( count == 0)
digitalWrite(ledPin, HIGH); // turn the LED on if the count is 0
else
{
digitalWrite(ledPin, LOW);
// turn the LED off if the count is not 0
count = count - 1;
// and decrement the count
}
}
5.4 Determining How Long a Switch Is Pressed | 145
}
Serial.println(count);
delay(100);
// return the time in milliseconds that the switch has been in pressed (LOW)
long switchTime()
{
// these variables are static - see Discussion for an explanation
static unsigned long startTime = 0; // the time the switch state change was
first detected
static boolean state;
// the current state of the switch
if(digitalRead(inPin) != state) // check to see if the switch has changed state
{
state = ! state;
// yes, invert the state
startTime = millis(); // store the time
}
if( state == LOW)
return millis() - startTime;
// switch pushed, return time in milliseconds
else
return 0; // return 0 if the switch is not pushed (in the HIGH state);
}
Discussion
7KHKHDUWRIWKLVUHFLSHLVWKH switchTimeIXQFWLRQ7KLVUHWXUQVWKHQXPEHURIPLOOL
VHFRQGV WKDW WKH VZLWFK KDV EHHQ SUHVVHG %HFDXVH WKLV UHFLSH XVHV LQWHUQDO SXOOXS
UHVLVWRUV VHH5HFLSH WKH digitalReadRIWKHVZLWFKSLQZLOOUHWXUQ LOWZKHQWKH
VZLWFKLVSUHVVHG
7KHloopFKHFNVWKHYDOXHUHWXUQHGIURPswitchTimeWRVHHZKDWVKRXOGKDSSHQ,IWKH
WLPHWKHVZLWFKKDVEHHQKHOGGRZQLVORQJHQRXJKIRUWKHIDVWHVWLQFUHPHQWWKHFRXQWHU
LVLQFUHPHQWHGE\WKDWDPRXQWLIQRWLWFKHFNVWKHfastYDOXHWRVHHLIWKDWVKRXOGEH
XVHGLIQRWLWFKHFNVLIWKHVZLWFKKDVEHHQKHOGGRZQORQJHQRXJKWRVWRSERXQFLQJ
DQGLIVRLWLQFUHPHQWVDVPDOODPRXQW$WPRVWRQHRIWKRVHZLOOKDSSHQ,IQRQHRI
WKHPDUHtrueWKHVZLWFKLVQRWEHLQJSUHVVHGRULWKDVQRWEHHQSUHVVHGORQJHQRXJK
WRKDYHVWRSSHGERXQFLQJ7KHFRXQWHUYDOXHLVFKHFNHGDQGDQ/('LVWXUQHGRQLILW
LV]HURLILW¦VQRW]HURWKHFRXQWHULVGHFUHPHQWHGDQGWKH/('LVWXUQHGRII
<RXFDQXVHWKHswitchTimeIXQFWLRQMXVWIRUGHERXQFLQJDVZLWFK7KHIROORZLQJFRGH
KDQGOHVGHERXQFHORJLFE\FDOOLQJWKHswitchTimeIXQFWLRQ
const int debounceTime = 20;
needs to be stable
// the time in milliseconds that the switch
if( switchTime() > debounceTime);
Serial.print("switch is debounced");
7KLVDSSURDFKWRGHERXQFLQJFDQEHKDQG\LI\RXKDYHPRUHWKDQRQHVZLWFKEHFDXVH
\RXFDQSHHNLQDQGORRNDWWKHDPRXQWRIWLPHDVZLWFKKDVEHHQSUHVVHGDQGSURFHVV
RWKHUWDVNVZKLOHZDLWLQJIRUDVZLWFKWREHFRPHVWDEOH7RLPSOHPHQWWKLV\RXQHHG
WR VWRUH WKH FXUUHQW VWDWH RI WKH VZLWFK SUHVVHG RU QRW DQG WKH WLPH WKH VWDWH ODVW
146 | Chapter 5:ಗSimple Digital and Analog Input
FKDQJHG7KHUHDUHPDQ\ZD\VWRGRWKLV¢LQWKLVH[DPSOH\RXZLOOXVHDVHSDUDWH
IXQFWLRQIRUHDFKVZLWFK<RXFRXOGVWRUHWKHYDULDEOHVDVVRFLDWHGZLWKDOOWKHVZLWFKHV
DWWKHWRSRI\RXUVNHWFKDVJOREDOYDULDEOHV FDOOHG£JOREDO¤EHFDXVHWKH\DUHDFFHVVLEOH
HYHU\ZKHUH %XWLWLVPRUHFRQYHQLHQWWRKDYHWKHYDULDEOHVIRUHDFKVZLWFKFRQWDLQHG
ZLWKWKHIXQFWLRQ
5HWDLQLQJYDOXHVRIYDULDEOHVGHILQHGLQDIXQFWLRQLVDFKLHYHGE\XVLQJVWDWLFYDULD
EOHV6WDWLFYDULDEOHVZLWKLQDIXQFWLRQSURYLGHSHUPDQHQWVWRUDJHIRUYDOXHVWKDWPXVW
EHPDLQWDLQHGEHWZHHQIXQFWLRQFDOOV$YDOXHDVVLJQHGWRDVWDWLFYDULDEOHLVUHWDLQHG
HYHQDIWHUWKHIXQFWLRQUHWXUQV7KHODVWYDOXHVHWZLOOEHDYDLODEOHWKHQH[WWLPHWKH
IXQFWLRQLVFDOOHG,QWKDWVHQVHVWDWLFYDULDEOHVDUHVLPLODUWRWKHJOREDOYDULDEOHV YDU
LDEOHVGHFODUHGRXWVLGHDIXQFWLRQXVXDOO\DWWKHEHJLQQLQJRIDVNHWFK WKDW\RXVDZ
LQWKHRWKHUUHFLSHV%XWXQOLNHJOREDOYDULDEOHVVWDWLFYDULDEOHVGHFODUHGLQDIXQFWLRQ
DUH RQO\ DFFHVVLEOH ZLWKLQ WKDW IXQFWLRQ 7KH EHQHILW RI VWDWLF YDULDEOHV LV WKDW WKH\
FDQQRWEHDFFLGHQWDOO\PRGLILHGE\VRPHRWKHUIXQFWLRQ
7KLVVNHWFKVKRZVDQH[DPSOHRIKRZ\RXFDQDGGVHSDUDWHIXQFWLRQVIRUGLIIHUHQW
VZLWFKHV7KHZLULQJIRUWKLVLVVLPLODUWR5HFLSHZLWKWKHVHFRQGVZLWFKZLUHG
VLPLODUO\WRWKHILUVW DVVKRZQLQ)LJXUH EXWFRQQHFWHGEHWZHHQSLQDQG*QG
/*
SwitchTimeMultiple sketch
Prints how long more than one switch has been pressed
*/
const int switchAPin = 2;
const int switchBPin = 3;
// the pin for switch A
// the pin for switch B
// functions with references must be explicitly declared
unsigned long switchTime(int pin, boolean &state, unsigned long
&startTime);
void setup()
{
pinMode(switchAPin, INPUT);
digitalWrite(switchAPin, HIGH); // turn on pull-up resistors
pinMode(switchBPin, INPUT);
digitalWrite(switchBPin, HIGH); // turn on pull-up resistors
Serial.begin(9600);
}
void loop()
{
unsigned long time;
Serial.print("switch A time =");
time = switchATime();
Serial.print(time);
Serial.print(", switch B time =");
time = switchBTime();
Serial.println(time);
delay(1000);
5.4 Determining How Long a Switch Is Pressed | 147
}
unsigned long switchTime(int pin, boolean &state, unsigned long &startTime)
{
if(digitalRead(pin) != state) // check to see if the switch has changed state
{
state = ! state;
//yes, invert the state
startTime = millis(); // store the time
}
if( state == LOW)
return millis() - startTime;
// return the time in milliseconds
else
return 0; // return 0 if the switch is not pushed (in the HIGH state);
}
long switchATime()
{
// these variables are static - see text for an explanation
static unsigned long startTime = 0;
// the time the switch state change was
first detected
static boolean state;
// the current state of the switch
return switchTime(switchAPin, state, startTime);
}
long switchBTime()
{
// these variables are static - see text for an explanation
static unsigned long startTime = 0;
// the time the switch state change was
first detected
static boolean state;
// the current state of the switch
return switchTime(switchBPin, state, startTime);
}
7KH WLPH FDOFXODWLRQ LV SHUIRUPHG LQ D IXQFWLRQ FDOOHG switchTime() 7KLV IXQFWLRQ
H[DPLQHVDQGXSGDWHVWKHVZLWFKVWDWHDQGGXUDWLRQ7KHIXQFWLRQXVHVUHIHUHQFHVWR
KDQGOHWKHSDUDPHWHUV¢UHIHUHQFHVZHUHFRYHUHGLQ5HFLSH$IXQFWLRQIRUHDFK
VZLWFK switchATime()DQGswitchBTime() LVXVHGWRUHWDLQWKHVWDUWWLPHDQGVWDWHIRU
HDFKVZLWFK%HFDXVHWKHYDULDEOHVKROGLQJWKHYDOXHVDUHGHFODUHGDVVWDWLFWKHYDOXHV
ZLOO EH UHWDLQHG ZKHQ WKH IXQFWLRQV H[LW +ROGLQJ WKH YDULDEOHV ZLWKLQ WKH IXQFWLRQ
HQVXUHVWKDWWKHZURQJYDULDEOHZLOOQRWEHXVHG7KHSLQVXVHGE\WKHVZLWFKHVDUH
GHFODUHGDVJOREDOYDULDEOHVEHFDXVHWKHYDOXHVDUHQHHGHGE\ setupWRFRQILJXUHWKH
SLQV%XWEHFDXVHWKHVHYDULDEOHVDUHGHFODUHGZLWKWKH constNH\ZRUGWKHFRPSLOHU
ZLOOQRWDOORZWKHYDOXHVWREHPRGLILHGVRWKHUHLVQRFKDQFHWKDWWKHVHZLOOEHDFFL
GHQWDOO\FKDQJHGE\WKHVNHWFKFRGH
/LPLWLQJWKHH[SRVXUHRIDYDULDEOHEHFRPHVPRUHLPSRUWDQWDVSURMHFWVEHFRPHPRUH
FRPSOH[7KH$UGXLQRHQYLURQPHQWSURYLGHVDPRUHHOHJDQWZD\WRKDQGOHWKLVVHH
5HFLSHIRUDGLVFXVVLRQRQKRZWRLPSOHPHQWWKLVXVLQJFODVVHV
148 | Chapter 5:ಗSimple Digital and Analog Input
5.5 Reading a Keypad
Problem
<RXKDYHDPDWUL[NH\SDGDQGZDQWWRUHDGWKHNH\SUHVVHVLQ\RXUVNHWFK)RUH[DPSOH
\RXKDYHDWHOHSKRQHVW\OHNH\SDGVLPLODUWRWKH6SDUN)XQEXWWRQNH\SDG 6SDUN
)XQ&20 Solution
:LUHWKHURZVDQGFROXPQVIURPWKHNH\SDGFRQQHFWRUWRWKH$UGXLQRDVVKRZQLQ
)LJXUH
)LJXUH&RQQHFWLQJWKH6SDUN)XQNH\ERDUGPDWUL[
,I\RX¦YHZLUHG\RXU$UGXLQRDQGNH\SDGDVVKRZQLQ)LJXUHWKHIROORZLQJVNHWFK
ZLOOSULQWNH\SUHVVHVWRWKH6HULDO0RQLWRU
/*
Keypad sketch
prints the key pressed on a keypad to the serial port
*/
const int numRows = 4;
// number of rows in the keypad
const int numCols = 3;
// number of columns
const int debounceTime = 20; // number of milliseconds for switch to be stable
5.5 Reading a Keypad | 149
// keymap defines the character returned when the corresponding key is pressed
const char keymap[numRows][numCols] = {
{ '1', '2', '3' } ,
{ '4', '5', '6' } ,
{ '7', '8', '9' } ,
{ '*', '0', '#' }
};
// this array determines the pins used for rows and columns
const int rowPins[numRows] = { 7, 2, 3, 6 }; // Rows 0 through 3
const int colPins[numCols] = { 5, 8, 4 };
// Columns 0 through 2
void setup()
{
Serial.begin(9600);
for (int row = 0; row < numRows; row++)
{
pinMode(rowPins[row],INPUT);
// Set row pins as input
digitalWrite(rowPins[row],HIGH);
// turn on Pull-ups
}
for (int column = 0; column < numCols; column++)
{
pinMode(colPins[column],OUTPUT);
// Set column pins as outputs for writing
digitalWrite(colPins[column],HIGH); // Make all columns inactive
}
}
void loop()
{
char key = getKey();
if( key != 0) {
// if the character is not 0 then it's a valid key press
Serial.print("Got key ");
Serial.println(key);
}
}
// returns with the key pressed, or 0 if no key is pressed
char getKey()
{
char key = 0;
// 0 indicates no key pressed
for(int column = 0; column < numCols; column++)
{
digitalWrite(colPins[column],LOW);
// Activate the current column.
for(int row = 0; row < numRows; row++)
// Scan all rows for a key press.
{
if(digitalRead(rowPins[row]) == LOW)
// Is a key pressed?
{
delay(debounceTime);
// debounce
while(digitalRead(rowPins[row]) == LOW)
;
// wait for key to be released
key = keymap[row][column];
// Remember which key was pressed.
}
}
150 | Chapter 5:ಗSimple Digital and Analog Input
digitalWrite(colPins[column],HIGH);
// De-activate the current column.
}
return key; // returns the key pressed or 0 if none
}
7KLVVNHWFKZLOORQO\ZRUNFRUUHFWO\LIWKHZLULQJDJUHHVZLWKWKHFRGH7DEOHVKRZV
KRZWKHURZVDQGFROXPQVVKRXOGEHFRQQHFWHGWR$UGXLQRSLQV,I\RXDUHXVLQJD
GLIIHUHQWNH\SDGFKHFN\RXUGDWDVKHHWWRGHWHUPLQHWKHURZDQGFROXPQFRQQHFWLRQV
&KHFNFDUHIXOO\DVLQFRUUHFWZLULQJFDQVKRUWRXWWKHSLQVDQGWKDWFRXOGGDPDJH\RXU
FRQWUROOHUFKLS
7DEOH0DSSLQJRI$UGXLQRSLQVWR6SDUN)XQFRQQHFWRUDQGNH\SDGURZVDQGFROXPQV
Arduino pin
Keypad connector
Keypad row/column
2
7
Row 1
3
6
Row 2
4
5
Column 2
5
4
Column 0
6
3
Row 3
7
2
Row 0
8
1
Column 1
Discussion
0DWUL[NH\SDGVW\SLFDOO\FRQVLVWRI1RUPDOO\2SHQVZLWFKHVWKDWFRQQHFWDURZZLWK
DFROXPQZKHQSUHVVHG $1RUPDOO\2SHQVZLWFKRQO\PDNHVHOHFWULFDOFRQQHFWLRQ
ZKHQSXVKHG )LJXUHVKRZVKRZWKHLQWHUQDOFRQGXFWRUVFRQQHFWWKHEXWWRQURZV
DQGFROXPQVWRWKHNH\ERDUGFRQQHFWRU(DFKRIWKHIRXUURZVLVFRQQHFWHGWRDQLQSXW
SLQDQGHDFKFROXPQLVFRQQHFWHGWRDQRXWSXWSLQ7KH setupIXQFWLRQVHWVWKHSLQ
PRGHVDQGHQDEOHVSXOOXSUHVLVWRUVRQWKHLQSXWSLQV VHHWKHSXOOXSUHFLSHVLQWKH
EHJLQQLQJRIWKLVFKDSWHU 7KHgetkeyIXQFWLRQVHTXHQWLDOO\VHWVWKHSLQIRUHDFKFROXPQLOWDQGWKHQFKHFNVWR
VHHLIDQ\RIWKHURZSLQVDUHLOW%HFDXVHSXOOXSUHVLVWRUVDUHXVHGWKHURZVZLOOEH
KLJK SXOOHGXS XQOHVVDVZLWFKLVFORVHG FORVLQJDVZLWFKSURGXFHVDLOWVLJQDORQWKH
LQSXWSLQ ,IWKH\DUH LOWWKLVLQGLFDWHVWKDWWKHVZLWFKIRUWKDWURZDQGFROXPQLV
FORVHG$GHOD\LVXVHGWRHQVXUHWKDWWKHVZLWFKLVQRWERXQFLQJ VHH5HFLSH WKH
FRGHZDLWVIRUWKHVZLWFKWREHUHOHDVHGDQGWKHFKDUDFWHUDVVRFLDWHGZLWKWKHVZLWFK
LVIRXQGLQWKHkeymapDUUD\DQGUHWXUQHGIURPWKHIXQFWLRQ$0LVUHWXUQHGLIQRVZLWFK
LVSUHVVHG
$OLEUDU\LQWKH$UGXLQR3OD\JURXQGWKDWLVVLPLODUWRWKHSUHFHGLQJH[DPSOHSURYLGHV
PRUHIXQFWLRQDOLW\7KHOLEUDU\PDNHVLWHDVLHUWRKDQGOHGLIIHUHQWQXPEHUVRINH\VDQG
LWFDQEHPDGHWRZRUNZKLOHVKDULQJVRPHRIWKHSLQVZLWKDQ/&'<RXFDQILQGWKH
OLEUDU\DWKWWSZZZDUGXLQRFFSOD\JURXQG0DLQ.H\SDG7XWRULDO
5.5 Reading a Keypad | 151
See Also
)RUPRUHLQIRUPDWLRQRQWKH6SDUN)XQEXWWRQNH\SDGJRWRKWWSZZZVSDUNIXQ
FRPFRPPHUFHSURGXFWBLQIRSKS"SURGXFWVBLG 5.6 Reading Analog Values
Problem
<RXZDQWWRUHDGWKHYROWDJHRQDQDQDORJSLQ3HUKDSV\RXZDQWDUHDGLQJIURPD
SRWHQWLRPHWHU SRW RUDGHYLFHRUVHQVRUWKDWSURYLGHVDYROWDJHEHWZHHQDQGYROWV
Solution
7KLVVNHWFKUHDGVWKHYROWDJHRQDQDQDORJSLQDQGIODVKHVDQ/('LQDSURSRUWLRQDO
UDWHWRWKHYDOXHUHWXUQHGIURPWKH analogReadIXQFWLRQ7KHYROWDJHLVDGMXVWHGE\D
SRWHQWLRPHWHUFRQQHFWHGDVVKRZQLQ)LJXUH
/*
Pot sketch
blink an LED at a rate set by the position of a potentiometer
*/
const int potPin = 0;
const int ledPin = 13;
int val = 0;
// select the input pin for the potentiometer
// select the pin for the LED
// variable to store the value coming from the sensor
void setup()
{
pinMode(ledPin, OUTPUT); // declare the ledPin as an OUTPUT
}
void loop() {
val = analogRead(potPin);
// read the voltage on the pot
digitalWrite(ledPin, HIGH); // turn the ledPin on
delay(val);
// blink rate set by pot value (in milliseconds)
digitalWrite(ledPin, LOW); // turn the ledPin off
delay(val);
// turn led off for same period as it was turned on
}
Discussion
7KLVVNHWFKXVHVWKH analogReadIXQFWLRQWRUHDGWKHYROWDJHRQWKHSRWHQWLRPHWHU¦V
ZLSHU WKHFHQWHUSLQ $SRWKDVWKUHHSLQVWZRDUHFRQQHFWHGWRDUHVLVWLYHPDWHULDO
DQGWKHWKLUGSLQ XVXDOO\LQWKHPLGGOH LVFRQQHFWHGWRDZLSHUWKDWFDQEHURWDWHGWR
PDNH FRQWDFW DQ\ZKHUH RQ WKH UHVLVWLYH PDWHULDO $V WKH SRWHQWLRPHWHU URWDWHV WKH
UHVLVWDQFHEHWZHHQWKHZLSHUDQGRQHRIWKHSLQVLQFUHDVHVZKLOHWKHRWKHUGHFUHDVHV
7KHVFKHPDWLFGLDJUDPIRUWKLVUHFLSH )LJXUH PD\KHOS\RXYLVXDOL]HKRZDSR
WHQWLRPHWHUZRUNVDVWKHZLSHUPRYHVWRZDUGWKHERWWRPHQGWKHZLSHU WKHOLQHZLWK
152 | Chapter 5:ಗSimple Digital and Analog Input
)LJXUH&RQQHFWLQJDSRWHQWLRPHWHUWR$UGXLQR
WKHDUURZ ZLOOKDYHORZHUUHVLVWDQFHFRQQHFWLQJWR*QGDQGKLJKHUUHVLVWDQFHFRQ
QHFWLQJWRYROWV$VWKHZLSHUPRYHVGRZQWKHYROWDJHRQWKHDQDORJSLQZLOOGHFUHDVH
WRDPLQLPXPRIYROWV 0RYLQJWKHZLSHUXSZDUGZLOOKDYHWKHRSSRVLWHHIIHFWDQG
WKHYROWDJHRQWKHSLQZLOOLQFUHDVH XSWRDPD[LPXPRIYROWV ,IWKHYROWDJHRQWKHSLQGHFUHDVHVUDWKHUWKDQLQFUHDVHVDV\RXLQFUHDVH
WKHURWDWLRQRIWKHSRWHQWLRPHWHU\RXFDQUHYHUVHWKHFRQQHFWLRQVWR
WKHYROWVDQG*QGSLQV
7KHYROWDJHLVPHDVXUHGXVLQJanalogReadZKLFKSURYLGHVDYDOXHSURSRUWLRQDOWRWKH
DFWXDOYROWDJHRQWKHDQDORJSLQ7KHYDOXHZLOOEHZKHQWKHUHDUHYROWVRQWKHSLQ
DQGZKHQWKHUHDUHYROWV$YDOXHLQEHWZHHQZLOOEHSURSRUWLRQDOWRWKHUDWLR
RIWKHYROWDJHRQWKHSLQWRYROWV
3RWHQWLRPHWHUVZLWKDYDOXHRI.RKPVDUHWKHEHVWFKRLFHIRUFRQQHFWLQJWRDQDORJ
SLQV6HHWKLVERRN¦VZHEVLWHIRUUHFRPPHQGHGSDUWQXPEHUV
potPinGRHVQRWQHHGWREHVHWDVLQSXW 7KLVLVGRQHIRU\RXDXWRPDW
LFDOO\HDFKWLPH\RXFDOOanalogRead
See Also
$SSHQGL[%IRUWLSVRQUHDGLQJVFKHPDWLFGLDJUDPV
$UGXLQRUHIHUHQFHIRUanalogReadKWWSZZZDUGXLQRFFHQ5HIHUHQFH$QDORJ5HDG
5.6 Reading Analog Values | 153
*HWWLQJ6WDUWHGZLWK$UGXLQRE\0DVVLPR%DQ]L 0DNH
5.7 Changing the Range of Values
Problem
<RXZDQWWRFKDQJHWKHUDQJHRIDYDOXHVXFKDVWKHYDOXHIURPanalogReadREWDLQHG
E\FRQQHFWLQJDSRWHQWLRPHWHURURWKHUGHYLFHWKDWSURYLGHVDYDULDEOHYROWDJH)RU
H[DPSOHVXSSRVH\RXZDQWWRGLVSOD\WKHSRVLWLRQRIDSRWHQWLRPHWHUNQREDVDSHU
FHQWDJHIURPSHUFHQWWRSHUFHQW
Solution
8VHWKH$UGXLQRmapIXQFWLRQWRVFDOHYDOXHVWRWKHUDQJH\RXZDQW7KLVVNHWFKUHDGV
WKHYROWDJHRQDSRWLQWRWKHYDULDEOH valDQGVFDOHVWKLVIURPWRDVWKHSRWLV
URWDWHGIURPRQHHQGWRWKHRWKHU,WEOLQNVDQ/('ZLWKDUDWHSURSRUWLRQDOWRWKH
YROWDJHRQWKHSLQDQGSULQWVWKHVFDOHGUDQJHWRWKHVHULDOSRUW VHH 5HFLSHIRU
LQVWUXFWLRQVRQPRQLWRULQJWKHVHULDOSRUW 5HFLSH VHH)LJXUH VKRZVKRZWKH
SRWLVFRQQHFWHG
/*
* Map sketch
* map the range of analog values from a pot to scale from 0 to 100
* resulting in an LED blink rate ranging from 0 to 100 milliseconds.
* and Pot rotation percent is written to the serial port
*/
const int potPin = 0;
int ledPin = 13;
// select the input pin for the potentiometer
// select the pin for the LED
void setup()
{
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
// declare the ledPin as an OUTPUT
void loop() {
int val;
int percent;
// The value coming from the sensor
// The mapped value
val = analogRead(potPin);
// read the voltage on the pot (val ranges
// from 0 to 1023)
percent = map(val,0,1023,0,100); // percent will range from 0 to 100.
digitalWrite(ledPin, HIGH);
// turn the ledPin on
delay(percent);
// On time given by percent value
digitalWrite(ledPin, LOW);
// turn the ledPin off
delay(100 - percent);
// Off time is 100 minus On time
Serial.println(percent);
// show the % of pot rotation on Serial Monitor
}
154 | Chapter 5:ಗSimple Digital and Analog Input
Discussion
5HFLSHGHVFULEHVKRZWKHSRVLWLRQRIDSRWLVFRQYHUWHGWRDYDOXH+HUH\RXXVH
WKLVYDOXHZLWKWKHmapIXQFWLRQWRVFDOHWKHYDOXHWR\RXUGHVLUHGUDQJH,QWKLVH[DPSOH
WKHYDOXHSURYLGHGE\analogRead 0WR1023 LVPDSSHGWRDSHUFHQWDJH WR 7KH
YDOXHVIURPanalogReadZLOOUDQJHIURP0WR1023LIWKHYROWDJHUDQJHVIURPWRYROWV
EXW\RXFDQXVHDQ\DSSURSULDWHYDOXHVIRUWKHVRXUFHDQGWDUJHWUDQJHV)RUH[DPSOH
DW\SLFDOSRWRQO\URWDWHVGHJUHHVIURPHQGWRHQGDQGLI\RXZDQWHGWRGLVSOD\
WKHDQJOHRIWKHNQRERQ\RXUSRW\RXFRXOGXVHWKLVFRGH
angle = map(val,0,1023,0,270); // angle of pot derived from analogRead val
5DQJHYDOXHVFDQDOVREHQHJDWLYH,I\RXZDQWWRGLVSOD\ 0ZKHQWKHSRWLVFHQWHUHG
DQGQHJDWLYHYDOXHVZKHQWKHSRWLVURWDWHGOHIWDQGSRVLWLYHYDOXHVZKHQLWLVURWDWHG
ULJKW\RXFDQGRWKLV
angle = map(val,0,1023,-135,135); // show angle of 270 degree pot with center
as 0
7KHmapIXQFWLRQFDQEHKDQG\ZKHUHWKHLQSXWUDQJH\RXDUHFRQFHUQHGZLWKGRHVQRW
VWDUWDW]HUR)RUH[DPSOHLI\RXKDYHDEDWWHU\ZKHUHWKHDYDLODEOHFDSDFLW\LVSURSRU
WLRQDOWRDYROWDJHWKDWUDQJHVIURPYROWV PLOOLYROWV WRYROWV PLO
OLYROWV \RXFDQGRWKHIROORZLQJ
const int empty
const int full
= 5000 / 1100; // the voltage is 1.1 volts (1100mv) when empty
= 5000 / 1500; // the voltage is 1.5 volts (1500mv) when full
int val = analogRead(potPin);
// read the analog voltage
int percent = map(val, empty, full, 0,100); // map the actual range of voltage
to a percent
Serial.println(percent);
6HH5HFLSHIRUPRUHGHWDLOVRQKRZanalogReadYDOXHVUHODWHWRDFWXDOYROWDJH
See Also
7KH$UGXLQRUHIHUHQFHIRUmapKWWSZZZDUGXLQRFFHQ5HIHUHQFH0DS
5.8 Reading More Than Six Analog Inputs
Problem
<RXKDYHPRUHDQDORJLQSXWVWRPRQLWRUWKDQ\RXKDYHDYDLODEOHDQDORJSLQV$VWDQG
DUG$UGXLQRERDUGKDVVL[DQDORJLQSXWV WKH0HJDKDV DQGWKHUHPD\QRWEHHQRXJK
DQDORJLQSXWVDYDLODEOHIRU\RXUDSSOLFDWLRQ3HUKDSV\RXZDQWWRDGMXVWHLJKWSDUDP
HWHUVLQ\RXUDSSOLFDWLRQE\WXUQLQJNQREVRQHLJKWSRWHQWLRPHWHUV
5.8 Reading More Than Six Analog Inputs | 155
Solution
8VHDPXOWLSOH[HUFKLSWRVHOHFWDQGFRQQHFWPXOWLSOHYROWDJHVRXUFHVWRRQHDQDORJ
LQSXW%\VHTXHQWLDOO\VHOHFWLQJIURPPXOWLSOHVRXUFHV\RXFDQUHDGHDFKVRXUFHLQWXUQ
7KLVUHFLSHXVHVWKHSRSXODUFKLSFRQQHFWHGWR$UGXLQRDVVKRZQLQ)LJXUH
<RXUDQDORJLQSXWVJHWFRQQHFWHGWRWKHSLQVPDUNHG&KWR&K0DNHVXUH
WKHYROWDJHRQWKHFKDQQHOLQSXWSLQVLVQHYHUKLJKHUWKDQYROWV
/*
multiplexer sketch
read 1 of 8 analog values into single analog input pin with 4051 multiplexer
*/
// array of pins used to select 1 of 8 inputs on multiplexer
const int select[] = {2,3,4}; // array of the pins connected to the 4051 input
select lines
const int analogPin = 0;
// the analog pin connected to the multiplexer
output
// this function returns the analog value for the given channel
int getValue( int channel)
{
// the following sets the selector pins HIGH and LOW to match the binary
value of channel
for(int bit = 0; bit < 3; bit++)
{
int pin = select[bit]; // the pin wired to the multiplexer select bit
int isBitSet = bitRead(channel, bit); // true if given bit set in channel
digitalWrite(pin, isBitSet);
}
return analogRead(analogPin);
}
void setup()
{
for(int bit = 0; bit < 3; bit++)
pinMode(select[bit], OUTPUT); // set the three select pins to output
Serial.begin(9600);
}
void loop () {
// print the values for each channel once per second
for(int channel = 0; channel < 8; channel++)
{
int value = getValue(channel);
Serial.print("Channel ");
Serial.print(channel);
Serial.print(" = ");
Serial.println(value);
}
delay (1000);
}
156 | Chapter 5:ಗSimple Digital and Analog Input
)LJXUH7KHPXOWLSOH[HUFRQQHFWHGWR$UGXLQR
Discussion
$QDORJPXOWLSOH[HUVDUHGLJLWDOO\FRQWUROOHGDQDORJVZLWFKHV7KHVHOHFWVRQHRI
HLJKWLQSXWVWKURXJKWKUHHVHOHFWRUSLQV 66DQG6 7KHUHDUHHLJKWGLIIHUHQWFRP
ELQDWLRQVRIYDOXHVIRUWKHWKUHHVHOHFWRUSLQVDQGWKHVNHWFKVHTXHQWLDOO\VHOHFWVHDFK
RIWKHSRVVLEOHELWSDWWHUQVVHH7DEOH
7DEOH7UXWKWDEOHIRUPXOWLSOH[HU
Selector pins
Selected input
S2
S1
S0
0
0
0
0
0
0
1
1
0
1
0
2
0
1
1
3
1
0
0
4
1
0
1
5
1
1
0
6
1
1
1
7
<RXPD\UHFRJQL]HWKHSDWWHUQLQ7DEOHDVWKHELQDU\UHSUHVHQWDWLRQRIWKHGHFLPDO
YDOXHVIURPWR
,QWKHSUHFHGLQJVNHWFKgetValue()LVWKHIXQFWLRQWKDWVHWVWKHFRUUHFWVHOHFWRUELWVIRU
WKHJLYHQFKDQQHOXVLQJdigitalWrite(pin, isBitSet)DQGUHDGVWKHDQDORJYDOXHIURP
5.8 Reading More Than Six Analog Inputs | 157
Download from Wow! eBook <www.wowebook.com>
WKHVHOHFWHGLQSXWZLWKanalogRead(analogPin)7KHFRGHWRSURGXFHWKHELWSDW
WHUQVXVHVWKHEXLOWLQbitReadIXQFWLRQ VHH5HFLSH 'RQ¦WIRUJHWWRFRQQHFWWKHJURXQGIURPWKHGHYLFHV\RXDUHPHDVXULQJ
WRWKHJURXQGRQWKHDQG$UGXLQRDVVKRZQLQ)LJXUH
%HDULQPLQGWKDWWKLVWHFKQLTXHVHOHFWVDQGPRQLWRUVWKHHLJKWLQSXWVVHTXHQWLDOO\VR
LWUHTXLUHVPRUHWLPHEHWZHHQWKHUHDGLQJVRQDJLYHQLQSXWFRPSDUHGWRXVLQJanalog
ReadGLUHFWO\,I\RXDUHUHDGLQJHLJKWLQSXWVLWZLOOWDNHHLJKWWLPHVORQJHUIRUHDFK
LQSXWWREHUHDG7KLVPD\PDNHWKLVPHWKRGXQVXLWDEOHIRULQSXWVWKDWFKDQJHYDOXH
TXLFNO\
See Also
$UGXLQR3OD\JURXQGWXWRULDOIRUWKHKWWSZZZDUGXLQRFFSOD\JURXQG/HDUQLQJ
&'GDWDVKHHWKWWSZZZIDLUFKLOGVHPLFRPGV&')&'%&SGI
$QDORJGLJLWDO08;EUHDNRXWERDUGGDWDVKHHWKWWSZZZQNFHOHFWURQLFVFRPDQDORJ
GLJLWDOPX[EUHDNRXWKWPO
5.9 Displaying Voltages Up to 5V
Problem
<RXZDQWWRPRQLWRUDQGGLVSOD\WKHYDOXHRIDYROWDJHEHWZHHQDQGYROWV)RU
H[DPSOHVXSSRVH\RXZDQWWRGLVSOD\WKHYROWDJHRIDVLQJOH9FHOORQWKH6HULDO
0RQLWRU
Solution
8VH AnalogRead WR PHDVXUH WKH YROWDJH RQ DQ DQDORJ SLQ &RQYHUW WKH UHDGLQJ WR D
YROWDJHE\XVLQJWKHUDWLRRIWKHUHDGLQJWRWKHUHIHUHQFHYROWDJH YROWV DVVKRZQLQ
)LJXUH
158 | Chapter 5:ಗSimple Digital and Analog Input
)LJXUH0HDVXULQJYROWDJHVXSWRYROWVXVLQJ9ERDUG
7KHVLPSOHVWVROXWLRQXVHVDIORDWLQJSRLQWFDOFXODWLRQWRSULQWWKHYROWDJHWKLVH[DPSOH
VNHWFKFDOFXODWHVDQGSULQWVWKHUDWLRDVDYROWDJH
/*
Display5vOrless sketch
prints the voltage on analog pin to the serial port
Warning - do not connect more than 5 volts directly to an Arduino pin.
*/
const int referenceVolts = 5;
const int batteryPin = 0;
// the default reference on a 5-volt board
// battery is connected to analog pin 0
void setup()
{
Serial.begin(9600);
}
void loop()
{
int val = analogRead(batteryPin); // read the value from the sensor
float volts = (val / 1023) * referenceVolts; // calculate the ratio
Serial.println(volts); // print the value in volts
}
7KHIRUPXODLV9ROWV DQDORJUHDGLQJDQDORJVWHSV Ü5HIHUHQFHYROWDJH
3ULQWLQJDIORDWLQJSRLQWYDOXHWRWKHVHULDOSRUWZLWK printlnZLOOIRUPDWWKHYDOXHWR
WZRGHFLPDOSODFHV
5.9 Displaying Voltages Up to 5V | 159
0DNHWKHIROORZLQJFKDQJHLI\RXDUHXVLQJD9ERDUG
const int referenceVolts = 3.3;
)ORDWLQJSRLQWQXPEHUVFRQVXPHORWVRIPHPRU\VRXQOHVV\RXDUHDOUHDG\XVLQJIORDW
LQJSRLQWHOVHZKHUHLQ\RXUVNHWFKLWLVPRUHHIILFLHQWWRXVHLQWHJHUYDOXHV7KHIRO
ORZLQJFRGHORRNVDOLWWOHVWUDQJHDWILUVWEXWEHFDXVH analogReadUHWXUQVDYDOXHRI
1023IRUYROWVHDFKVWHSLQYDOXHZLOOEHGLYLGHGE\,QXQLWVRIPLOOLYROWVWKLV
LVGLYLGHGE\
7KLVFRGHSULQWVWKHYDOXHLQPLOOLYROWV
const int
batteryPin = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
long val = analogRead(batteryPin);
// read the value from the sensor - note
val is a long int
Serial.println( (val * (500000/1023)) / 100); // print the value in millivolts
}
7KHIROORZLQJFRGHSULQWVWKHYDOXHXVLQJGHFLPDOSRLQWV,WSULQWV1.5LIWKHYROWDJHLV
YROWV
const int
batteryPin 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
int val = analogRead(batteryPin);
Serial.println(val/(1023/5));
Serial.print('.');
Serial.println(val % (1023/5));
}
// read the value from the sensor
// print the integer value of the voltage
// print the fraction
,I\RXDUHXVLQJD9ERDUGFKDQJH(1023/5)WR(int)(1023/3.3)
160 | Chapter 5:ಗSimple Digital and Analog Input
Discussion
7KHanalogRead()IXQFWLRQUHWXUQVDYDOXHWKDWLVSURSRUWLRQDOWRWKHUDWLRRIWKHPHDV
XUHGYROWDJHWRWKHUHIHUHQFHYROWDJH YROWV 7RDYRLGWKHXVHRIIORDWLQJSRLQW\HW
PDLQWDLQSUHFLVLRQWKHFRGHRSHUDWHVRQYDOXHVDVPLOOLYROWVLQVWHDGRIYROWV WKHUHDUH
PLOOLYROWVLQYROW %HFDXVHDYDOXHRI1023LQGLFDWHVPLOOLYROWVHDFKXQLW
UHSUHVHQWVGLYLGHGE\PLOOLYROWV WKDWLVPLOOLYROWV 7RHOLPLQDWHWKH
GHFLPDOSRLQWWKHYDOXHVDUHPXOWLSOLHGE\,QRWKHUZRUGVPLOOLYROWVWLPHV
GLYLGHGE\JLYHVWKHQXPEHURIPLOOLYROWVWLPHV'LYLGLQJWKLVE\
\LHOGVWKHYDOXHLQPLOOLYROWV,IPXOWLSO\LQJIUDFWLRQDOQXPEHUVE\WRHQDEOHWKH
FRPSLOHUWRSHUIRUPWKHFDOFXODWLRQXVLQJIL[HGSRLQWDULWKPHWLFVHHPVFRQYROXWHG\RX
FDQVWLFNWRWKHVORZHUDQGPRUHPHPRU\KXQJU\IORDWLQJSRLQWPHWKRG
7KLVVROXWLRQDVVXPHV\RXDUHXVLQJDVWDQGDUG$UGXLQRSRZHUHGIURPYROWV,I\RX
DUHXVLQJD9ERDUGWKHPD[LPXPYROWDJH\RXFDQPHDVXUHLVYROWVZLWKRXW
XVLQJDYROWDJHGLYLGHU¢VHH5HFLSH
5.10 Responding to Changes in Voltage
Problem
<RXZDQWWRPRQLWRURQHRUPRUHYROWDJHVDQGWDNHVRPHDFWLRQZKHQWKHYROWDJHULVHV
RUIDOOVEHORZDWKUHVKROG)RUH[DPSOH\RXZDQWWRIODVKDQ/('WRLQGLFDWHDORZ
EDWWHU\ OHYHO¢SHUKDSV WR VWDUW IODVKLQJ ZKHQ WKH YROWDJH GURSV EHORZ D ZDUQLQJ
WKUHVKROGDQGLQFUHDVLQJLQXUJHQF\DVWKHYROWDJHGURSVIXUWKHU
Solution
<RXFDQXVHWKHFRQQHFWLRQVVKRZQLQ)LJXUHLQ5HFLSHEXWKHUHZH¦OOFRPSDUH
WKH YDOXH IURP analogRead WR VHH LI LW GURSV EHORZ D WKUHVKROG 7KLV H[DPSOH VWDUWV
IODVKLQJDQ/('DWYROWVDQGLQFUHDVHVWKHRQWRRIIWLPHDVWKHYROWDJHGHFUHDVHV
EHORZWKHWKUHVKROG,IWKHYROWDJHGURSVEHORZDVHFRQGWKUHVKROGWKH/('VWD\VOLW
/*
RespondingToChanges sketch
flash an LED to indicate low voltage levels
*/
long warningThreshold = 1200;
long criticalThreshold = 1000;
// Warning level in millivolts - LED flashes
// Critical voltage level - LED stays on
const int batteryPin = 0;
const int ledPin = 13;
void setup()
{
pinMode(ledPin, OUTPUT);
}
5.10 Responding to Changes in Voltage | 161
void loop()
{
int val = analogRead(batteryPin);
// read the value from the sensor
if( val < (warningThreshold * 1023L)/5000) {
// in the line above, L following a number makes it a 32 bit value
flash(val) ;
}
}
// function to flash an led with on/off time determined by value passed
as percent
void flash(int percent)
{
digitalWrite(ledPin, HIGH);
delay(percent + 1);
digitalWrite(ledPin, LOW);
delay(100 - percent ); // check delay == 0?
}
Discussion
7KHKLJKOLJKWHGOLQHLQWKLVVNHWFKFDOFXODWHVWKHUDWLRRIWKHYDOXHUHDGIURPWKHDQDORJ
SRUWWRWKHYDOXHRIWKHWKUHVKROGYROWDJH)RUH[DPSOHZLWKDZDUQLQJWKUHVKROGRI
YROWDQGDUHIHUHQFHYROWDJHRIYROWV\RXZDQWWRNQRZZKHQWKHDQDORJUHDGLQJLV
RQHILIWKRIWKHUHIHUHQFHYROWDJH7KHH[SUHVVLRQ1023LWHOOVWKHFRPSLOHUWKDWWKLVLVD
ORQJ LQWHJHU D ELW LQWHJHU VHH 5HFLSH VR WKH FRPSLOHU ZLOO SURPRWH DOO WKH
YDULDEOHVLQWKLVH[SUHVVLRQWRORQJLQWHJHUVWRSUHYHQWRYHUIORZLQJWKHFDSDFLW\RIDQ
int DQRUPDOELWLQWHJHU :KHQUHDGLQJDQDORJYDOXHV\RXFDQZRUNLQWKHXQLWVWKDWDUHUHWXUQHGIURPanalog
Read¢UDQJLQJIURPWR¢RU\RXFDQZRUNLQWKHDFWXDOYROWDJHVWKH\UHSUHVHQW
VHH5HFLSH $VLQWKLVUHFLSHLI\RXDUHQRWGLVSOD\LQJYROWDJHLW¦VVLPSOHUDQG
PRUHHIILFLHQWWRXVHWKHRXWSXWRIanalogReadGLUHFWO\
5.11 Measuring Voltages More Than 5V (Voltage Dividers)
Problem
<RXZDQWWRPHDVXUHYROWDJHVJUHDWHUWKDQYROWV)RUH[DPSOH\RXZDQWWRGLVSOD\
WKHYROWDJHRID9EDWWHU\DQGWULJJHUDQDODUP/('ZKHQWKHYROWDJHIDOOVEHORZD
FHUWDLQOHYHO
Solution
8VHDVROXWLRQVLPLODUWR5HFLSHEXWFRQQHFWWKHYROWDJHWKURXJKDYROWDJHGLYLGHU
VHH)LJXUH )RUYROWDJHVXSWRYROWV\RXFDQXVHWZR.RKPUHVLVWRUV)RU
KLJKHUYROWDJHV\RXFDQGHWHUPLQHWKHUHTXLUHGUHVLVWRUVXVLQJ7DEOH
162 | Chapter 5:ಗSimple Digital and Analog Input
)LJXUH9ROWDJHGLYLGHUIRUPHDVXULQJYROWDJHVJUHDWHUWKDQYROWV
7DEOH5HVLVWRUYDOXHV
Calculation
Max voltage
R1
R2
R2(R1 + R2)
value of resistorFactor
5
Short (+V connected to
analog pin)
None (Gnd connected to
Gnd)
None
1023
10
1K
1K
1(1 + 1)
511
15
2K
1K
1(2 + 1)
341
20
3K
1K
1(3 + 1)
255
30
4K (3.9K)
1K
1(4 + 1)
170
6HOHFWWKHURZZLWKWKHKLJKHVWYROWDJH\RXQHHGWRPHDVXUHWRILQGWKHYDOXHVIRUWKH
WZRUHVLVWRUV
/*
DisplayMoreThan5V sketch
prints the voltage on analog pin to the serial port
Do not connect more than 5 volts directly to an Arduino pin.
*/
const int referenceVolts = 5;
//const float referenceVolts = 3.3;
// the default reference on a 5-volt board
// use this for a 3.3-volt board
const int R1 = 1000; // value for a maximum voltage of 10 volts
const int R2 = 1000;
// determine by voltage divider resistors, see text
const int resistorFactor = 1023.0 / (R2/(R1 + R2));
const int batteryPin = 0;
// +V from battery is connected to analog pin 0
5.11 Measuring Voltages More Than 5V (Voltage Dividers) | 163
Download from Wow! eBook <www.wowebook.com>
void setup()
{
Serial.begin(9600);
}
void loop()
{
int val = analogRead(batteryPin); // read the value from the sensor
float volts = (val / resistorFactor) * referenceVolts ; // calculate the ratio
Serial.println(volts); // print the value in volts
}
Discussion
/LNHWKHSUHYLRXVDQDORJUHFLSHVWKLVUHFLSHUHOLHVRQWKHIDFWWKDWWKHanalogReadYDOXH
LVDUDWLRRIWKHPHDVXUHGYROWDJHWRWKHUHIHUHQFH%XWEHFDXVHWKHPHDVXUHGYROWDJHLV
GLYLGHGE\WKHWZRGURSSLQJUHVLVWRUVWKHanalogReadYDOXHQHHGVWREHPXOWLSOLHGWR
JHW WKH DFWXDO YROWDJH 7KLV FRGH LV VLPLODU WR 5HFLSH EXW WKH YDOXH RI
resistorFactorLVVHOHFWHGEDVHGRQWKHYROWDJHGLYLGHUUHVLVWRUVDVVKRZQLQ7DEOH
const int resistorFactor = 511;
see Table 5-3
// determine by voltage divider resistors,
7KHYDOXHUHDGIURPWKHDQDORJSLQLVGLYLGHGQRWE\EXWE\DYDOXHGHWHUPLQHG
E\WKHGURSSLQJUHVLVWRUV
float volts = (val / resistorFactor) * referenceVolts ; // calculate the ratio
7KHFDOFXODWLRQXVHGWRSURGXFHWKHWDEOHLVEDVHGRQWKHIROORZLQJIRUPXODWKHRXWSXW
YROWDJHLVHTXDOWRWKHLQSXWYROWDJHWLPHV5GLYLGHGE\WKHVXPRI5DQG5,QWKH
H[DPSOHZKHUHWZRHTXDOYDOXHUHVLVWRUVDUHXVHGWRGURSWKHYROWDJHIURPD9EDWWHU\
E\KDOIresistorFactorLV KDOIRI VRWKHYDOXHRIWKHvoltsYDULDEOHZLOOEH
WZLFHWKHYROWDJHWKDWDSSHDUVRQWKHLQSXWSLQ:LWKUHVLVWRUVVHOHFWHGIRUYROWVWKH
DQDORJUHDGLQJIURPD9EDWWHU\ZLOOEHDSSUR[LPDWHO\
0RUHWKDQYROWVRQWKHSLQFDQGDPDJHWKHSLQDQGSRVVLEO\GHVWUR\
WKHFKLSGRXEOHFKHFNWKDW\RXKDYHFKRVHQWKHULJKWYDOXHUHVLVWRUV
DQGZLUHGWKHPFRUUHFWO\EHIRUHFRQQHFWLQJWKHPWRDQ$UGXLQRLQSXW
SLQ,I\RXKDYHDPXOWLPHWHUPHDVXUHWKHYROWDJHEHIRUHFRQQHFWLQJ
DQ\WKLQJWKDWFRXOGSRVVLEO\FDUU\YROWDJHVKLJKHUWKDQYROWV
164 | Chapter 5:ಗSimple Digital and Analog Input
CHAPTER 6
Getting Input from Sensors
6.0 Introduction
*HWWLQJDQGXVLQJLQSXWIURPVHQVRUVHQDEOHV$UGXLQRWRUHVSRQGWRRUUHSRUWRQWKH
ZRUOGDURXQGLW7KLVLVRQHRIWKHPRVWFRPPRQWDVNV\RXZLOOHQFRXQWHU7KLVFKDSWHU
SURYLGHVVLPSOHDQGSUDFWLFDOH[DPSOHVRIKRZWRXVHWKHPRVWSRSXODULQSXWGHYLFHV
DQGVHQVRUV:LULQJGLDJUDPVVKRZKRZWRFRQQHFWDQGSRZHUWKHGHYLFHVDQGFRGH
H[DPSOHVGHPRQVWUDWHKRZWRXVHGDWDGHULYHGIURPWKHVHQVRUV
6HQVRUVUHVSRQGWRLQSXWIURPWKHSK\VLFDOZRUOGDQGFRQYHUWWKLVLQWRDQHOHFWULFDO
VLJQDOWKDW$UGXLQRFDQUHDGRQDQLQSXWSLQ7KHQDWXUHRIWKHHOHFWULFDOVLJQDOSURYLGHG
E\ D VHQVRU GHSHQGV RQ WKH NLQG RI VHQVRU DQG KRZ PXFK LQIRUPDWLRQ LW QHHGV WR
WUDQVPLW6RPHVHQVRUV VXFKDVSKRWRUHVLVWRUVDQG3LH]RNQRFNVHQVRUV DUHFRQVWUXF
WHG IURP D VXEVWDQFH WKDW DOWHUV WKHLU HOHFWULFDO SURSHUWLHV LQ UHVSRQVH WR SK\VLFDO
FKDQJH2WKHUVDUHVRSKLVWLFDWHGHOHFWURQLFPRGXOHVWKDWXVHWKHLURZQPLFURFRQWUROOHU
WRSURFHVVLQIRUPDWLRQEHIRUHSDVVLQJDVLJQDORQIRUWKH$UGXLQR
6HQVRUVXVHWKHIROORZLQJPHWKRGVWRSURYLGHLQIRUPDWLRQ
'LJLWDORQRII
6RPHGHYLFHVVXFKDVWKHWLOWVHQVRULQ5HFLSHDQGWKHPRWLRQVHQVRULQ5HF
LSHVLPSO\VZLWFKDYROWDJHRQDQGRII7KHVHFDQEHWUHDWHGOLNHWKHVZLWFK
UHFLSHVVKRZQLQ&KDSWHU
$QDORJ
2WKHUVHQVRUVSURYLGHDQDQDORJVLJQDO DYROWDJHWKDWLVSURSRUWLRQDOWRZKDWLV
EHLQJVHQVHGVXFKDVWHPSHUDWXUHRUOLJKWOHYHO 7KHUHFLSHVIRUGHWHFWLQJOLJKW
5HFLSH PRWLRQ 5HFLSHVDQG YLEUDWLRQ 5HFLSH VRXQG 5HF
LSH DQGDFFHOHUDWLRQ 5HFLSH GHPRQVWUDWHKRZDQDORJVHQVRUVFDQEH
XVHG$OORIWKHPXVHWKHanalogReadFRPPDQGWKDWLVGLVFXVVHGLQ&KDSWHU
3XOVHZLGWK
'LVWDQFHVHQVRUVVXFKDVWKH3,1* LQ5HFLSHSURYLGHGDWDXVLQJSXOVHGX
UDWLRQSURSRUWLRQDOWRWKHGLVWDQFHYDOXH7KHVHVHQVRUVPHDVXUHWKHGXUDWLRQRID
SXOVHXVLQJWKHpulseInFRPPDQG
165
6HULDO
6RPHVHQVRUVSURYLGHYDOXHVXVLQJDVHULDOSURWRFRO)RUH[DPSOHWKH5),'UHDGHU
LQ5HFLSHDQGWKH*36LQ5HFLSHFRPPXQLFDWHWKURXJKWKH$UGXLQRVHULDO
SRUW VHH&KDSWHUIRUPRUHRQVHULDO 0RVW$UGXLQRERDUGVRQO\KDYHRQHKDUG
ZDUHVHULDOSRUWVRUHDG5HFLSHIRUDQH[DPSOHRIKRZ\RXFDQDGGDGGLWLRQDO
VRIWZDUHVHULDOSRUWVLI\RXKDYHPXOWLSOHVHULDOVHQVRUVRUWKHKDUGZDUHVHULDOSRUW
LVRFFXSLHGIRUVRPHRWKHUWDVN
6\QFKURQRXVSURWRFROV,&DQG63,
7KH,&DQG63,GLJLWDOVWDQGDUGVZHUHFUHDWHGIRUPLFURFRQWUROOHUVOLNH$UGXLQR
WRWDONWRH[WHUQDOVHQVRUVDQGPRGXOHV5HFLSHVKRZVKRZDFRPSDVVPRGXOH
LVFRQQHFWHGXVLQJV\QFKURQRXVGLJLWDOVLJQDOLQJ7KHVHSURWRFROVDUHXVHGH[WHQ
VLYHO\ IRU VHQVRUV DFWXDWRUV DQG SHULSKHUDOV DQG WKH\ DUH FRYHUHG LQ GHWDLO LQ
&KDSWHU
7KHUHLVDQRWKHUJHQHULFFODVVRIVHQVLQJGHYLFHVWKDW\RXPD\PDNHXVHRI7KHVHDUH
FRQVXPHUGHYLFHVWKDWFRQWDLQVHQVRUVEXWDUHVROGDVGHYLFHVLQWKHLURZQULJKWUDWKHU
WKDQDVVHQVRUV([DPSOHVRIWKHVHLQWKLVFKDSWHULQFOXGHD36PRXVHDQGD3OD\6WDWLRQ
JDPHFRQWUROOHU7KHVHGHYLFHVFDQEHYHU\XVHIXOWKH\SURYLGHVHQVRUVDOUHDG\LQFRU
SRUDWHGLQWRUREXVWDQGHUJRQRPLFGHYLFHV7KH\DUHDOVRLQH[SHQVLYH RIWHQOHVVH[
SHQVLYHWKDQEX\LQJWKHUDZVHQVRUVWKDWWKH\FRQWDLQ DVWKH\DUHPDVVSURGXFHG
<RXPD\KDYHVRPHRIWKHVHO\LQJDURXQG
,I\RXDUHXVLQJDGHYLFHWKDWLVQRWVSHFLILFDOO\FRYHUHGLQDUHFLSH\RXPD\EHDEOHWR
DGDSWDUHFLSHIRUDGHYLFHWKDWSURGXFHVDVLPLODUW\SHRIRXWSXW,QIRUPDWLRQDERXWD
VHQVRU¦VRXWSXWVLJQDOLVXVXDOO\DYDLODEOHIURPWKHFRPSDQ\IURPZKLFK\RXERXJKW
WKHGHYLFHRUIURPDGDWDVKHHWIRU\RXUGHYLFH ZKLFK\RXFDQILQGWKURXJKD*RRJOH
VHDUFKRIWKHGHYLFHSDUWQXPEHURUGHVFULSWLRQ 'DWDVKHHWVDUHDLPHGDWHQJLQHHUVGHVLJQLQJSURGXFWVWREHPDQXIDFWXUHGDQGWKH\
XVXDOO\SURYLGHPRUHGHWDLOWKDQ\RXQHHGWRMXVWJHWWKHSURGXFWXSDQGUXQQLQJ7KH
LQIRUPDWLRQRQRXWSXWVLJQDOZLOOXVXDOO\EHLQDVHFWLRQUHIHUULQJWRGDWDIRUPDWLQ
WHUIDFHRXWSXWVLJQDORUVRPHWKLQJVLPLODU'RQ¦WIRUJHWWRFKHFNWKHPD[LPXPYROWDJH
XVXDOO\LQDVHFWLRQODEHOHG£$EVROXWH0D[LPXP5DWLQJV¤ WRHQVXUHWKDW\RXGRQ¦W
GDPDJHWKHFRPSRQHQW
6HQVRUVGHVLJQHGIRUDPD[LPXPRIYROWVFDQEHGHVWUR\HGE\FRQ
QHFWLQJWKHPWRYROWV&KHFNWKHDEVROXWHPD[LPXPUDWLQJIRU\RXU
GHYLFHEHIRUHFRQQHFWLQJ
5HDGLQJVHQVRUVIURPWKHPHVV\DQDORJZRUOGLVDPL[WXUHRIVFLHQFHDUWDQGSHUVH
YHUDQFH<RXPD\QHHGWRXVHLQJHQXLW\DQGWULDODQGHUURUWRJHWDVXFFHVVIXOUHVXOW$
FRPPRQSUREOHPLVWKDWWKHVHQVRUMXVWWHOOV\RXDSK\VLFDOFRQGLWLRQKDVRFFXUUHG
QRWZKDWFDXVHGLW3XWWLQJWKHVHQVRULQWKHULJKWFRQWH[W ORFDWLRQUDQJHRULHQWDWLRQ
DQGOLPLWLQJLWVH[SRVXUHWRWKLQJVWKDW\RXGRQ¦WZDQWWRDFWLYDWHLWDUHVNLOOV\RXZLOO
DFTXLUHZLWKH[SHULHQFH
166 | Chapter 6:ಗGetting Input from Sensors
$QRWKHU LVVXH FRQFHUQV VHSDUDWLQJ WKH GHVLUHG VLJQDO IURP EDFNJURXQG QRLVH 5HF
LSHVKRZVKRZ\RXFDQXVHDWKUHVKROGWRGHWHFWZKHQDVLJQDOLVDERYHDFHUWDLQ
OHYHODQG5HFLSHVKRZVKRZ\RXFDQWDNHWKHDYHUDJHRIDQXPEHURIUHDGLQJVWR
VPRRWKRXWQRLVHVSLNHV
See Also
)RU LQIRUPDWLRQ RQ FRQQHFWLQJ HOHFWURQLF FRPSRQHQWV VHH 0DNH (OHFWURQLFV E\
&KDUOHV3ODWW 0DNH 6HHWKHLQWURGXFWLRQWR&KDSWHUDQG5HFLSHIRUPRUHRQUHDGLQJDQDORJYDOXHV
IURPVHQVRUV
6.1 Detecting Movement
Problem
<RXZDQWWRGHWHFWZKHQVRPHWKLQJLVPRYHGWLOWHGRUVKDNHQ
Solution
7KLVVNHWFKXVHVDVZLWFKWKDWFORVHVDFLUFXLWZKHQWLOWHGFDOOHGDWLOWVHQVRU7KHVZLWFK
UHFLSHVLQ&KDSWHU 5HFLSHVDQG ZLOOZRUNZLWKDWLOWVHQVRUVXEVWLWXWHGIRU
WKHVZLWFK
7KHVNHWFKEHORZ FLUFXLWVKRZQLQ)LJXUH ZLOOVZLWFKRQWKH/('DWWDFKHGWRSLQ
ZKHQWKHWLOWVHQVRULVWLOWHGRQHZD\DQGWKH/('FRQQHFWHGWRSLQZKHQLWLV
WLOWHGWKHRWKHUZD\
/*
tilt sketch
a tilt sensor attached to pin 2,
lights one of the LEDs connected to pins 11 and 12
depending on which way the sensor is tilted
*/
const int tiltSensorPin = 2;
const int firstLEDPin = 11;
const int secondLEDPin = 12;
//pin the tilt sensor is connected to
//pin for one LED
//pin for the other
void setup()
{
pinMode (tiltSensorPin, INPUT);
digitalWrite (tiltSensorPin, HIGH);
//the code will read this pin
// and use a pull-up resistor
pinMode (firstLEDPin, OUTPUT);
pinMode (secondLEDPin, OUTPUT);
//the code will control this pin
//and this one
}
6.1 Detecting Movement | 167
void loop()
{
if (digitalRead(tiltSensorPin)){
digitalWrite(firstLEDPin, HIGH);
digitalWrite(secondLEDPin, LOW);
}
else{
digitalWrite(firstLEDPin, LOW);
digitalWrite(secondLEDPin, HIGH);
}
}
//check if the pin is high
//if it is high turn on firstLED
//and turn off secondLED
//if it isn't
//do the opposite
)LJXUH7LOWVHQVRUDQG/('V
Discussion
7KHPRVWFRPPRQWLOWVHQVRULVDEDOOEHDULQJLQDER[ZLWKFRQWDFWVDWRQHHQG:KHQ
WKHER[LVWLOWHGWKHEDOOUROOVDZD\IURPWKHFRQWDFWVDQGWKHFRQQHFWLRQLVEURNHQ
:KHQWKHER[LVWLOWHGWRUROOWKHRWKHUZD\WKHEDOOWRXFKHVWKHFRQWDFWVDQGFRPSOHWHV
DFLUFXLW0DUNLQJVRUSLQFRQILJXUDWLRQVVKRZZKLFKZD\WKHVHQVRUVKRXOGEHRUL
HQWHG7LOWVHQVRUVDUHVHQVLWLYHWRVPDOOPRYHPHQWVRIDURXQGWRGHJUHHVZKHQ
RULHQWHGZLWKWKHEDOOMXVWWRXFKLQJWKHFRQWDFWV,I\RXSRVLWLRQWKHVHQVRUVRWKDWWKH
EDOOEHDULQJLVGLUHFWO\DERYH RUEHORZ WKHFRQWDFWVWKH/('VWDWHZLOORQO\FKDQJHLI
LWLVWXUQHGULJKWRYHU7KLVFDQEHXVHGWRWHOOLIVRPHWKLQJLVXSULJKWRUXSVLGHGRZQ
7RGHWHUPLQHLIVRPHWKLQJLVEHLQJVKDNHQ\RXQHHGWRFKHFNKRZORQJLW¦VEHHQVLQFH
WKHVWDWHRIWKHWLOWVHQVRUFKDQJHG WKLVUHFLSH¦V6ROXWLRQMXVWFKHFNVLIWKHVZLWFKZDV
RSHQRUFORVHG ,ILWKDVQ¦WFKDQJHGIRUDWLPH\RXFRQVLGHUVLJQLILFDQWWKHREMHFWLV
QRWVKDNLQJ&KDQJLQJWKHRULHQWDWLRQRIWKHWLOWVHQVRUZLOOFKDQJHKRZYLJRURXVWKH
VKDNLQJQHHGVWREHWRWULJJHULW7KHIROORZLQJFRGHOLJKWVDQ/('ZKHQWKHVHQVRULV
VKDNHQ
168 | Chapter 6:ಗGetting Input from Sensors
/*
shaken sketch
tilt sensor connected to pin 2
led connected to pin 13
*/
const int tiltSensorPin = 2;
const int ledPin = 13;
int tiltSensorPreviousValue = 0;
int tiltSensorCurrentValue = 0;
long lastTimeMoved = 0;
int shakeTime=50;
void setup()
{
pinMode (tiltSensorPin, INPUT);
digitalWrite (tiltSensorPin, HIGH);
pinMode (ledPin, OUTPUT);
}
void loop()
{
tiltSensorCurrentValue=digitalRead(tiltSensorPin);
if (tiltSensorPreviousValue != tiltSensorCurrentValue){
lastTimeMoved = millis();
tiltSensorPreviousValue = tiltSensorCurrentValue;
}
}
if (millis() - lastTimeMoved < shakeTime){
digitalWrite(ledPin, HIGH);
}
else{
digitalWrite(ledPin, LOW);
}
0DQ\PHFKDQLFDOVZLWFKVHQVRUVFDQEHXVHGLQVLPLODUZD\V$IORDWVZLWFKFDQWXUQ
RQZKHQWKHZDWHUOHYHOLQDFRQWDLQHUULVHVWRDFHUWDLQOHYHO VLPLODUWRWKHZD\DEDOO
FRFNZRUNVLQDWRLOHWFLVWHUQ $SUHVVXUHSDGVXFKDVWKHRQHXVHGLQVKRSHQWUDQFHV
FDQEHXVHGWRGHWHFWZKHQVRPHRQHVWDQGVRQLW,I\RXUVHQVRUWXUQVDGLJLWDOVLJQDO
RQDQGRIIVRPHWKLQJVLPLODUWRWKLVUHFLSH¦VVNHWFKVKRXOGEHVXLWDEOH
See Also
&KDSWHUFRQWDLQVEDFNJURXQGLQIRUPDWLRQRQXVLQJVZLWFKHVZLWK$UGXLQR
5HFLSHKDVPRUHRQXVLQJWKHmillisIXQFWLRQWRGHWHUPLQHGHOD\
6.1 Detecting Movement | 169
6.2 Detecting Light
Problem
<RXZDQWWRGHWHFWFKDQJHVLQOLJKWOHYHOV<RXPD\ZDQWWRGHWHFWDFKDQJHZKHQ
VRPHWKLQJSDVVHVLQIURQWRIDOLJKWGHWHFWRURUWRPHDVXUHWKHOLJKWOHYHO¢IRUH[DPSOH
GHWHFWLQJZKHQDURRPLVJHWWLQJWRRGDUN
Solution
7KHHDVLHVWZD\WRGHWHFWOLJKWOHYHOVLVWRXVHDOLJKWGHSHQGHQWUHVLVWRU /'5 7KLV
FKDQJHVUHVLVWDQFHZLWKFKDQJLQJOLJKWOHYHOVDQGZKHQFRQQHFWHGLQWKHFLUFXLWVKRZQ
LQ)LJXUHLWSURGXFHVDFKDQJHLQYROWDJHWKDWWKH$UGXLQRDQDORJLQSXWSLQVFDQ
VHQVH
)LJXUH&RQQHFWLQJDOLJKWGHSHQGHQWUHVLVWRU
Discussion
7KHFLUFXLWIRUWKLVUHFLSHLVWKHVWDQGDUGZD\WRXVHDQ\VHQVRUWKDWFKDQJHVLWVUHVLVW
DQFHEDVHGRQVRPHSK\VLFDOSKHQRPHQRQ VHH&KDSWHUIRUEDFNJURXQGLQIRUPDWLRQ
RQUHVSRQGLQJWRDQDORJVLJQDOV 7KHFLUFXLWLQ)LJXUHZLOOFKDQJHWKHYROWDJHRQ
DQDORJSLQZKHQWKHUHVLVWDQFHRIWKH/'5FKDQJHVZLWKYDU\LQJOLJKWOHYHOV
$FLUFXLWVXFKDVWKLVZLOOQRWJLYHWKHIXOOUDQJHRISRVVLEOHYDOXHVIURPWKHDQDORJ
LQSXW¢WR¢DVWKHYROWDJHZLOOQRWEHVZLQJLQJIURPYROWVWRYROWV7KLVLV
EHFDXVHWKHUHZLOODOZD\VEHDYROWDJHGURSDFURVVHDFKUHVLVWDQFHVRWKHYROWDJHZKHUH
WKH\PHHWZLOOQHYHUUHDFKWKHOLPLWVRIWKHSRZHUVXSSO\:KHQXVLQJVHQVRUVVXFKDV
WKHVHLWLVLPSRUWDQWWRFKHFNWKHDFWXDOYDOXHVWKHGHYLFHUHWXUQVLQWKHVLWXDWLRQ\RX
170 | Chapter 6:ಗGetting Input from Sensors
ZLOOEHXVLQJLW7KHQ\RXKDYHWRGHWHUPLQHKRZWRFRQYHUWWKHPWRWKHYDOXHV\RX
QHHGWRFRQWUROZKDWHYHU\RXDUHJRLQJWRFRQWURO6HH5HFLSHIRUPRUHGHWDLOVRQ
FKDQJLQJWKHUDQJHRIYDOXHV
7KH/'5LVDVLPSOHNLQGRIVHQVRUFDOOHGDUHVLVWLYHVHQVRU$UDQJHRIUHVLVWLYHVHQVRUV
UHVSRQGWRFKDQJHVLQGLIIHUHQWSK\VLFDOFKDUDFWHULVWLFV7KHVDPHFLUFXLWZLOOZRUNIRU
DQ\NLQGRIVLPSOHUHVLVWLYHVHQVRU
6.3 Detecting Motion (Integrating Passive Infrared Detectors)
Problem
<RXZDQWWRGHWHFWZKHQSHRSOHDUHPRYLQJQHDUDVHQVRU
Solution
8VHDPRWLRQVHQVRUVXFKDVD3DVVLYH,QIUDUHG 3,5 VHQVRUWRFKDQJHYDOXHVRQDGLJLWDO
SLQZKHQVRPHRQHPRYHVQHDUE\
6HQVRUVVXFKDVWKH6SDUN)XQ3,50RWLRQ6HQVRU 6(1 DQGWKH3DUDOOD[3,5
6HQVRU FDQEHHDVLO\FRQQHFWHGWR$UGXLQRSLQVDVVKRZQLQ)LJXUH
)LJXUH&RQQHFWLQJD3,5PRWLRQVHQVRU
&KHFNWKHGDWDVKHHWIRU\RXUVHQVRUWRLGHQWLI\WKHFRUUHFWSLQV7KH3DUDOOD[VHQVRU
KDVSLQVPDUNHG£287¤£¤DQG£¤ IRU2XWSXW*QGDQG9 7KH6SDUN)XQ
VHQVRULVPDUNHGZLWK£$ODUP¤£*1'¤DQG£'&¤ IRU2XWSXW*QGDQG9 6.3 Detecting Motion (Integrating Passive Infrared Detectors) | 171
7KHIROORZLQJVNHWFKZLOOOLJKWWKH/('RQ$UGXLQRSLQZKHQWKHVHQVRUGHWHFWV
PRWLRQ
/*
*/
PIR sketch
a Passive Infrared motion sensor connected to pin 2
lights the LED on pin 13
const int ledPin = 13;
const int inputPin = 2;
// choose the pin for the LED
// choose the input pin (for the PIR sensor)
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(inputPin, INPUT);
}
// declare LED as output
// declare pushbutton as input
void loop(){
int val = digitalRead(inputPin);
if (val == HIGH)
{
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);
}
}
// read input value
// check if the input is HIGH
// turn LED on if motion detected
// turn LED off
Discussion
7KLVFRGHLVVLPLODUWRWKHSXVKEXWWRQH[DPSOHVVKRZQLQ&KDSWHU7KDW¦VEHFDXVH
WKHVHQVRUDFWVOLNHDVZLWFKZKHQPRWLRQLVGHWHFWHG'LIIHUHQWNLQGVRI3,5VHQVRUV
DUHDYDLODEOHDQG\RXVKRXOGFKHFNWKHLQIRUPDWLRQIRUWKHRQH\RXKDYHFRQQHFWHG
6RPH VHQVRUV VXFK DV WKH 3DUDOOD[ KDYH D MXPSHU WKDW GHWHUPLQHV KRZ WKH RXWSXW
EHKDYHVZKHQPRWLRQLVGHWHFWHG,QRQHPRGHWKHRXWSXWUHPDLQVHIGHZKLOHPRWLRQ
LVGHWHFWHGRULWFDQEHVHWVRWKDWWKHRXWSXWJRHV HIGHEULHIO\DQGWKHQ LOWZKHQ
WULJJHUHG7KHH[DPSOHVNHWFKLQWKLVUHFLSH¦V6ROXWLRQZLOOZRUNLQHLWKHUPRGH
2WKHUVHQVRUVPD\JR LOWRQGHWHFWLQJPRWLRQ,I\RXUVHQVRU¦VRXWSXWSLQJRHV LOW
ZKHQPRWLRQLVGHWHFWHGFKDQJHWKHOLQHWKDWFKHFNVWKHLQSXWYDOXHVRWKDWWKH/('
LVWXUQHGRQZKHQLOW
if (val == LOW)
// motion when the input is LOW
3,5VHQVRUVFRPHLQDYDULHW\RIVW\OHVDQGDUHVHQVLWLYHRYHUGLIIHUHQWGLVWDQFHVDQG
DQJOHV&DUHIXOFKRLFHDQGSRVLWLRQLQJFDQPDNHWKHPUHVSRQGWRPRYHPHQWLQSDUWRI
DURRPUDWKHUWKDQDOORILW
3,5VHQVRUVUHVSRQGWRKHDWDQGFDQEHWULJJHUHGE\DQLPDOVVXFKDVFDWV
DQGGRJVDVZHOODVE\SHRSOHDQGRWKHUKHDWVRXUFHV
172 | Chapter 6:ಗGetting Input from Sensors
6.4 Measuring Distance
Problem
<RXZDQWWRPHDVXUHWKHGLVWDQFHWRVRPHWKLQJVXFKDVDZDOORUVRPHRQHZDONLQJ
WRZDUGWKH$UGXLQR
Solution
7KLVUHFLSHXVHVWKHSRSXODU3DUDOOD[3,1* XOWUDVRQLFGLVWDQFHVHQVRUWRPHDVXUH
WKHGLVWDQFHRIDQREMHFWUDQJLQJIURPFPWRDURXQGP,WGLVSOD\VWKHGLVWDQFHRQ
WKH6HULDO0RQLWRUDQGIODVKHVDQ/('IDVWHUDVREMHFWVJHWFORVHU )LJXUHVKRZVWKH
FRQQHFWLRQV /* Ping))) Sensor
* prints distance and changes LED flash rate
* depending on distance from the Ping))) sensor
*/
const int pingPin = 5;
const int ledPin = 13; // pin connected to LED
void setup()
{
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
void loop()
{
int cm = ping(pingPin) ;
Serial.println(cm);
digitalWrite(ledPin, HIGH);
delay(cm * 10 ); // each centimeter adds 10 milliseconds delay
digitalWrite(ledPin, LOW);
delay( cm * 10);
}
// following code based on http://www.arduino.cc/en/Tutorial/Ping
// returns the distance in cm
int ping(int pingPin)
{
// establish variables for duration of the ping,
// and the distance result in inches and centimeters:
long duration, cm;
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
6.4 Measuring Distance | 173
delayMicroseconds(5);
digitalWrite(pingPin, LOW);
pinMode(pingPin, INPUT);
duration = pulseIn(pingPin, HIGH);
}
// convert the time into a distance
cm = microsecondsToCentimeters(duration);
return cm ;
long microsecondsToCentimeters(long microseconds)
{
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the
// object we take half of the distance travelled.
return microseconds / 29 / 2;
}
)LJXUH3LQJ VHQVRUFRQQHFWLRQV
Discussion
8OWUDVRQLFVHQVRUVSURYLGHDPHDVXUHPHQWRIWKHWLPHLWWDNHVIRUVRXQGWRERXQFHRII
DQREMHFWDQGUHWXUQWRWKHVHQVRU
7KH£SLQJ¤VRXQGSXOVHLVJHQHUDWHGZKHQWKHpingPinOHYHOJRHVHIGHIRUWZRPLFUR
VHFRQGV7KHVHQVRUZLOOWKHQJHQHUDWHDSXOVHWKDWWHUPLQDWHVZKHQWKHVRXQGUHWXUQV
7KHZLGWKRIWKHSXOVHLVSURSRUWLRQDOWRWKHGLVWDQFHWKHVRXQGWUDYHOHGDQGWKHVNHWFK
WKHQXVHVWKH pulseInIXQFWLRQWRPHDVXUHWKDWGXUDWLRQ7KHVSHHGRIVRXQGLV
PHWHUVSHUVHFRQGZKLFKLVPLFURVHFRQGVSHUFHQWLPHWHU7KHIRUPXODIRUWKHGLV
WDQFHRIWKHURXQGWULSLV5RXQG7ULS PLFURVHFRQGV
174 | Chapter 6:ಗGetting Input from Sensors
6RWKHIRUPXODIRUWKHRQHZD\GLVWDQFHLQFHQWLPHWHUVLVPLFURVHFRQGV
7KH0D[%RWL[(=LVDQRWKHUXOWUDVRQLFVHQVRUWKDWFDQEHXVHGWRPHDVXUHGLVWDQFH
,WLVHDVLHUWRLQWHJUDWHWKDQWKH3LQJ EHFDXVHLWGRHVQRWQHHGWREH£SLQJHG¤,WFDQ
SURYLGHFRQWLQXRXVGLVWDQFHLQIRUPDWLRQHLWKHUDVDQDQDORJYROWDJHRUSURSRUWLRQDO
WRSXOVHZLGWK)LJXUHVKRZVWKHFRQQHFWLRQV
)LJXUH&RQQHFWLQJ(=3:RXWSXWWRDGLJLWDOLQSXWSLQ
7KHVNHWFKWKDWIROORZVXVHVWKH(=SXOVHZLGWKRXWSXWWRSURGXFHRXWSXWVLPLODUWR
WKDWRIWKHSUHYLRXVVNHWFK
/*
* EZ1Rangefinder Distance Sensor
* prints distance and changes LED flash rate
* depending on distance from the Ping))) sensor
*/
const int sensorPin = 5;
const int ledPin = 13; // pin connected to LED
long value = 0;
int cm = 0;
int inches = 0;
void setup()
{
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
void loop()
{
value = pulseIn(sensorPin, HIGH) ;
cm = value / 58;
// pulse width is 58 microseconds per cm
inches = value / 147;
// which is 147 microseconds per inch
6.4 Measuring Distance | 175
Serial.print(cm);
Serial.print(',');
Serial.println(inches);
digitalWrite(ledPin, HIGH);
delay(cm * 10 ); // each centimeter adds 10 milliseconds delay
digitalWrite(ledPin, LOW);
delay( cm * 10);
}
delay(20);
7KH (= LV SRZHUHG WKURXJK 9 DQG JURXQG SLQV DQG WKHVH DUH FRQQHFWHG WR WKH
UHVSHFWLYH$UGXLQRSLQV&RQQHFWWKH(=3:SLQ 3:LVWKH3XOVH:LGWKRXWSXW WR
$UGXLQRGLJLWDOSLQ7KHVNHWFKPHDVXUHVWKHZLGWKRIWKHSXOVHZLWKWKH pulseIn
FRPPDQG7KHZLGWKRIWKHSXOVHLVPLFURVHFRQGVSHUFHQWLPHWHURUPLFUR
VHFRQGVSHULQFK
<RX FDQ DOVR REWDLQ D GLVWDQFH UHDGLQJ IURP WKH (= WKURXJK LWV DQDORJ RXWSXW¢
FRQQHFWWKH$1SLQWRDQDQDORJLQSXWDQGUHDGWKHYDOXHZLWK analogRead7KHIRO
ORZLQJFRGHSULQWVWKHDQDORJLQSXWFRQYHUWHGWRLQFKHV
value = analogRead(0);
inches = value / 2;
// each digit of analog read is around 5mv
Serial.println(inches);
7KHDQDORJRXWSXWLVDURXQGP9SHULQFK7KHYDOXHIURP analogReadLVDURXQG
P9SHUXQLW VHH5HFLSHIRUPRUHRQanalogRead DQGWKHSUHFHGLQJFRGHURXQGV
WKHVHVRWKDWHDFKJURXSRIWZRXQLWVLVRQHLQFK7KHURXQGLQJHUURULVVPDOOFRPSDUHG
WRWKHDFFXUDF\RIWKHGHYLFHEXWLI\RXZDQWDPRUHSUHFLVHFDOFXODWLRQ\RXFDQXVH
IORDWLQJSRLQWDVIROORZV
value = analogRead(0);
float mv = (value /1024.0) * 5000 ;
float Inches = mv / 9.8; // 9.8mv per inch
Serial.println(Inches) ;
See Also
5HFLSHH[SODLQVKRZWRFRQYHUWUHDGLQJVIURPanalogInputLQWRYROWDJHYDOXHV
7KH$UGXLQRUHIHUHQFHIRUpulseInKWWSZZZDUGXLQRFFHQ5HIHUHQFH3XOVH,Q
6.5 Measuring Distance Accurately
Problem
<RXZDQWWRPHDVXUHKRZIDUREMHFWVDUHIURPWKH$UGXLQRZLWKPRUHDFFXUDF\WKDQ
LQ5HFLSH
176 | Chapter 6:ಗGetting Input from Sensors
Solution
,QIUDUHG ,5 VHQVRUVJHQHUDOO\SURYLGHDQDQDORJRXWSXWWKDWFDQEHPHDVXUHGXVLQJ
analogRead7KH\FDQKDYHJUHDWHUDFFXUDF\WKDQXOWUDVRQLFVHQVRUVDOEHLWZLWKDVPDOO
HUUDQJH DUDQJHRIFPWRPRUPLVW\SLFDOIRU,5VHQVRUV 7KLVVNHWFKSURYLGHV
VLPLODU IXQFWLRQDOLW\ WR 5HFLSH EXW LW XVHV DQ LQIUDUHG VHQVRU¢WKH 6KDUS
*3<$<.) )LJXUHVKRZVWKHFRQQHFWLRQV /* ir-distance sketch
* prints distance and changes LED flash rate based on distance from IR sensor
*/
const int ledPin
= 13; // the pin connected to the LED to flash
const int sensorPin = 0; // the analog pin connected to the sensor
const long referenceMv = 5000; // long int to prevent overflow when multiplied
void setup()
{
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
void loop()
{
int val = analogRead(sensorPin);
int mV = (val * referenceMv) / 1023;
Serial.print(mV);
Serial.print(",");
int cm = getDistance(mV);
Serial.println(cm);
digitalWrite(ledPin, HIGH);
delay(cm * 10 ); // each centimeter adds 10 milliseconds delay
digitalWrite(ledPin, LOW);
delay( cm * 10);
delay(100);
}
// the following is used to interpolate the distance from a table
// table entries are distances in steps of 250 millivolts
const int NBR_ELEMS = 10;
const int firstElement = 250; // first entry is 250 mV
const int interval = 250; // millivolts between each element
static int distance[TABLE_ENTRIES] = {150,140,130,100,60,50,40,35,30,25,20,15};
int getDistance(int mV)
{
if( mV > INTERVAL * TABLE_ENTRIES )
return distance[TABLE_ENTRIES-1];
else
{
6.5 Measuring Distance Accurately | 177
int index = mV / INTERVAL;
float frac = (mV % 250) / (float)INTERVAL;
return distance[index] - ((distance[index] - distance[index+1]) * frac);
}
}
)LJXUH&RQQHFWLQJWKH6KDUS,5GLVWDQFHVHQVRU
Discussion
7KH RXWSXW IURP WKH ,5 VHQVRU LV QRW OLQHDU¢LQ RWKHU ZRUGV WKH YDOXH UHDG IURP
analogReadLVQRWSURSRUWLRQDOWRGLVWDQFH6RWKHFDOFXODWLRQLVPRUHFRPSOLFDWHGWKDQ
WKHRQHXVHGLQ5HFLSH7KHVNHWFKLQWKLVUHFLSH¦V6ROXWLRQXVHVDWDEOHWRLQWHUSRODWH
WKHDFWXDOGLVWDQFHE\ILQGLQJWKHQHDUHVWHQWU\LQWKHWDEOHDQGDGMXVWLQJLWEDVHGRQ
WKHUDWLRRIWKHPHDVXUHGYDOXHWRWKHQH[WWDEOHHQWU\ WKLVWHFKQLTXHLVFDOOHGLQWHU
SRODWLQJ <RXPD\QHHGWRDGMXVWWKHWDEOHYDOXHVIRU\RXUVHQVRU¢\RXFDQGRWKLV
ZLWKLQIRUPDWLRQIURP\RXUGDWDVKHHWRUWKURXJKWULDODQGHUURU
$VYDOXHVIRUWKHWDEOHFDQEHIRXQGE\WULDODQGHUURU PHDVXULQJWKH
YROWDJHXQWLOLWFKDQJHVE\WKHUHTXLUHGDPRXQWDQGWKHQPHDVXULQJWKH
GLVWDQFH WKLVWHFKQLTXHFDQDOVREHXVHGZKHQ\RXGRQ¦WKDYHDQHTXD
WLRQWRLQWHUSUHWWKHYDOXHV¢IRUH[DPSOHZKHQ\RXGRQ¦WKDYHDSDUW
GDWDVKHHWIRUWKHGHYLFH\RXDUHXVLQJ
7KHFRQYHUVLRQIURPYROWDJHWRGLVWDQFHLVGRQHLQWKLVIXQFWLRQ
int getDistance(int mV)
178 | Chapter 6:ಗGetting Input from Sensors
7KHIXQFWLRQILUVWFKHFNVLIWKHYDOXHLVZLWKLQWKHUDQJHJLYHQLQWKHWDEOH7KHVKRUWHVW
YDOLGGLVWDQFHLVUHWXUQHGLIWKHYDOXHLVQRWZLWKLQUDQJH
if( mV > INTERVAL * TABLE_ENTRIES )
return distance[TABLE_ENTRIES-1]; //TABLE_ENTRIES-1 is last valid entry
,IWKHYDOXHLVZLWKLQWKHWDEOHUDQJHLQWHJHUGLYLVLRQFDOFXODWHVZKLFKHQWU\LVFORVHVW
EXWLVORZHUWKDQWKHUHDGLQJ
int index = mV / INTERVAL ;
7KHPRGXORRSHUDWRU VHH&KDSWHU LVXVHGWRFDOFXODWHDIUDFWLRQDOYDOXHZKHQD
UHDGLQJIDOOVEHWZHHQWZRHQWULHV
float frac = (mV % 250) / (float)INTERVAL;
return distance[index] + (distance[index]* (frac / interval));
7KHODVWOLQHLQWKH getDistanceIXQFWLRQXVHVWKHLQGH[DQGIUDFWLRQWRFDOFXODWHDQG
UHWXUQDGLVWDQFHYDOXH,WUHDGVWKHYDOXHIURPWKHWDEOHDQGWKHQDGGVDSURSRUWLRQ
RIWKDWYDOXHEDVHGRQWKHfracYDOXH7KLVILQDOHOHPHQWLVDQDSSUR[LPDWLRQEXWDVLW
LVIRUDVPDOOUDQJHRIWKHUHVXOWLWJLYHVDFFHSWDEOHUHVXOWV,ILWLVQRWDFFXUDWHHQRXJK
IRU\RX\RXQHHGWRSURGXFHDWDEOHZLWKPRUHYDOXHVFORVHUWRJHWKHU
$WDEOHFDQDOVREHXVHGWRLPSURYHSHUIRUPDQFHLIWKHFDOFXODWLRQWDNHVVLJQLILFDQW
WLPHWRFRPSOHWHRULVGRQHUHSHDWHGO\ZLWKDOLPLWHGQXPEHURIYDOXHV&DOFXODWLRQV
SDUWLFXODUO\ZLWKIORDWLQJSRLQWFDQEHVORZ5HSODFLQJWKHFDOFXODWLRQZLWKDWDEOHFDQ
VSHHGWKLQJVXS
7KHYDOXHVFDQHLWKHUEHKDUGFRGHGLQWRWKHVNHWFKOLNHWKLVRQHRUEHFDOFXODWHGLQ
setup()7KLVPD\PDNHWKHVNHWFKWDNHORQJHUWRVWDUWEXWDVWKLVRQO\KDSSHQVRQFH
HDFKWLPHWKH$UGXLQRJHWVSRZHU\RXZLOOWKHQJHWDVSHHGJDLQHYHU\WLPHDURXQGWKH
PDLQloop()7KHWUDGHRIIIRUWKHVSHHGLVWKDWWKHWDEOHFRQVXPHVPHPRU\¢WKHELJJHU
WKHWDEOHWKHPRUH5$0PHPRU\XVHG6HH&KDSWHUIRUKHOSXVLQJProgmemWRVWRUH
GDWDLQSURJUDPPHPRU\
<RXPD\QHHGWRDGGDFDSDFLWRUDFURVVWKH9DQG*QGOLQHVWRVWD
ELOL]HWKHSRZHUVXSSO\WRWKHVHQVRUVRWKDWWKHFRQQHFWLQJOHDGVDUH
QRWNHSWVKRUW,I\RXJHWHUUDWLFUHDGLQJVFRQQHFWDX)FDSDFLWRUDW
WKHVHQVRU VHH$SSHQGL[&IRUPRUHRQXVLQJGHFRXSOLQJFDSDFLWRUV See Also
$GHWDLOHGH[SODQDWLRQRIWKH6KDUS,5VHQVRULVDYDLODEOHDWKWWSZZZVRFLHW\RIURERWV
FRPVHQVRUVBVKDUSLUUDQJHVKWPO
6.5 Measuring Distance Accurately | 179
6.6 Detecting Vibration
Problem
<RXZDQWWRUHVSRQGWRYLEUDWLRQIRUH[DPSOHZKHQDGRRULVNQRFNHG
Solution
$3LH]RVHQVRUUHVSRQGVWRYLEUDWLRQ,WZRUNVEHVWZKHQFRQQHFWHGWRDODUJHUVXUIDFH
WKDWYLEUDWHV)LJXUHVKRZVWKHFRQQHFWLRQV
/* piezo sketch
* lights and LED when the Piezo is tapped
*/
const int sensorPin = 0; // the analog pin connected to the sensor
const int ledPin = 13;
// pin connected to LED
const int THRESHOLD = 100;
void setup()
{
pinMode(ledPin, OUTPUT);
}
void loop()
{
int val = analogRead(sensorPin);
if (val >= THRESHOLD)
{
digitalWrite(ledPin, HIGH);
delay(100); // to make the LED visible
}
else
digitalWrite(ledPin, LOW);
}
Discussion
$3LH]RVHQVRUDOVRNQRZQDVDNQRFNVHQVRUSURGXFHVDYROWDJHLQUHVSRQVHWRSK\VLFDO
VWUHVV7KHPRUHLWLVVWUHVVHGWKHKLJKHUWKHYROWDJH7KH3LH]RLVSRODUL]HGDQGWKH
SRVLWLYHVLGH XVXDOO\DUHGZLUHRUDZLUHPDUNHGZLWKD£¤ LVFRQQHFWHGWRWKHDQDORJ
LQSXWWKHQHJDWLYHZLUH XVXDOO\EODFNRUPDUNHGZLWKD£¤ LVFRQQHFWHGWRJURXQG
$KLJKYDOXHUHVLVWRU PHJRKP LVFRQQHFWHGDFURVVWKHVHQVRU
180 | Chapter 6:ಗGetting Input from Sensors
)LJXUH.QRFNVHQVRUFRQQHFWLRQV
7KHYROWDJHLVGHWHFWHGE\$UGXLQR analogReadWRWXUQRQDQ/(' VHH&KDSWHUIRU
PRUHDERXWWKH analogReadIXQFWLRQ 7KH THRESHOLDYDOXHGHWHUPLQHVWKHOHYHOIURP
WKHVHQVRUWKDWZLOOWXUQRQWKH/('DQG\RXFDQGHFUHDVHRULQFUHDVHWKLVYDOXHWR
PDNHWKHVNHWFKPRUHRUOHVVVHQVLWLYH
3LH]R VHQVRUV FDQ EH ERXJKW LQ SODVWLF FDVHV RU DV EDUH PHWDO GLVNV ZLWK WZR ZLUHV
DWWDFKHG7KHFRPSRQHQWVDUHWKHVDPHXVHZKLFKHYHUILWV\RXUSURMHFWEHVW
6RPHVHQVRUVVXFKDVWKH3LH]RFDQEHGULYHQE\WKH$UGXLQRWRSURGXFHWKHWKLQJ
WKDWWKH\FDQVHQVH&KDSWHUKDVPRUHDERXWXVLQJD3LH]RWRJHQHUDWHVRXQG
6.7 Detecting Sound
Problem
<RXZDQWWRGHWHFWVRXQGVVXFKDVFODSSLQJWDONLQJRUVKRXWLQJ
Solution
7KLVUHFLSHXVHVWKH%2%EUHDNRXWERDUGIRUWKH(OHFWUHW0LFURSKRQH 6SDUN
)XQ &RQQHFWWKHERDUGDVVKRZQLQ)LJXUHDQGORDGWKHFRGHWRWKHERDUG
6.7 Detecting Sound | 181
)LJXUH0LFURSKRQHERDUGFRQQHFWLRQV
7KHEXLOWLQ/('RQ$UGXLQRSLQZLOOWXUQRQZKHQ\RXFODSVKRXWRUSOD\ORXG
PXVLF QHDU WKH PLFURSKRQH <RX PD\ QHHG WR DGMXVW WKH WKUHVKROG¢XVH WKH 6HULDO
0RQLWRUWRYLHZWKHKLJKDQGORZYDOXHVDQGFKDQJHWKHWKUHVKROGYDOXHVRWKDWLWLV
EHWZHHQWKHKLJKYDOXHV\RXJHWZKHQQRLVHLVSUHVHQWDQGWKHORZYDOXHVZKHQWKHUH
LVOLWWOHRUQRQRLVH8SORDGWKHFKDQJHGFRGHWRWKHERDUGDQGWU\DJDLQ
/*
microphone sketch
SparkFun breakout board for Electret Microphone is connected to analog pin 0
*/
const int ledPin = 13;
const int middleValue = 512;
const int numberOfSamples = 128;
//the code will flash the LED in pin 13
//the middle of the range of analog values
//how many readings will be taken each time
int sample;
long signal;
long averageReading;
//the value read from microphone each time
//the reading once you have removed DC offset
//the average of that loop of readings
long runningAverage=0;
const int averagedOver= 16;
//the running average of calculated values
//how quickly new values affect running average
//bigger numbers mean slower
const int threshold=400;
//at what level the light turns on
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
long sumOfSquares = 0;
for (int i=0; i<numberOfSamples; i++) { //take many readings and average them
182 | Chapter 6:ಗGetting Input from Sensors
sample = analogRead(0);
signal = (sample - middleValue);
signal *= signal;
sumOfSquares += signal;
//take a reading
//work out its offset from the center
//square it to make all values positive
//add to the total
}
averageReading = sumOfSquares/numberOfSamples;
//calculate running average
runningAverage=(((averagedOver-1)*runningAverage)+averageReading)/averagedOver;
}
if (runningAverage>threshold){
digitalWrite(ledPin, HIGH);
}else{
digitalWrite(ledPin, LOW);
}
Serial.println(runningAverage);
//is average more than the threshold ?
//if it is turn on the LED
//if it isn't turn the LED off
//print the value so you can check it
Discussion
$PLFURSKRQHSURGXFHVYHU\VPDOOHOHFWULFDOVLJQDOV,I\RXFRQQHFWHGLWVWUDLJKWWRWKH
SLQRIDQ$UGXLQR\RXZRXOGQRWJHWDQ\GHWHFWDEOHFKDQJH7KHVLJQDOQHHGVWREH
DPSOLILHGILUVWWRPDNHLWXVDEOHE\$UGXLQR7KH6SDUN)XQERDUGKDVWKHPLFURSKRQH
ZLWKDQDPSOLILHUFLUFXLWEXLOWLQWRDPSOLI\WKHVLJQDOWRDOHYHOUHDGDEOHE\$UGXLQR
%HFDXVH\RXDUHUHDGLQJDQDXGLRVLJQDOLQWKLVUHFLSH\RXZLOOQHHGWRGRVRPHDGGL
WLRQDOFDOFXODWLRQVWRJHWXVHIXOLQIRUPDWLRQ$QDXGLRVLJQDOLVFKDQJLQJIDLUO\TXLFNO\
DQGWKHYDOXHUHWXUQHGE\analogReadZLOOGHSHQGRQZKDWSRLQWLQWKHXQGXODWLQJVLJQDO
\RX WDNH D UHDGLQJ ,I \RX DUH XQIDPLOLDU ZLWK XVLQJ analogRead VHH &KDSWHU DQG
5HFLSH$QH[DPSOHZDYHIRUPIRUDQDXGLRWRQHLVVKRZQLQ)LJXUH$VWLPH
FKDQJHVIURPOHIWWRULJKWWKHYROWDJHJRHVXSDQGGRZQLQDUHJXODUSDWWHUQ,I\RX
WDNHUHDGLQJVDWWKHWKUHHGLIIHUHQWWLPHVPDUNHGRQLW\RXZLOOJHWWKUHHGLIIHUHQWYDOXHV
,I\RXXVHGWKLVWRPDNHGHFLVLRQV\RXPLJKWLQFRUUHFWO\FRQFOXGHWKDWWKHVLJQDOJRW
ORXGHULQWKHPLGGOH
$QDFFXUDWHPHDVXUHPHQWUHTXLUHVPXOWLSOHUHDGLQJVWDNHQFORVHWRJHWKHU7KHSHDNV
DQGWURXJKVLQFUHDVHDVWKHVLJQDOJHWVELJJHU7KHGLIIHUHQFHEHWZHHQWKHERWWRPRID
WURXJKDQGWKHWRSRIDSHDNLVFDOOHGWKHDPSOLWXGHRIWKHVLJQDODQGWKLVLQFUHDVHVDV
WKHVLJQDOJHWVORXGHU
6.7 Detecting Sound | 183
)LJXUH$XGLRVLJQDOPHDVXUHGLQWKUHHSODFHV
7RPHDVXUHWKHVL]HRIWKHSHDNVDQGWURXJKV\RXPHDVXUHWKHGLIIHUHQFHEHWZHHQWKH
PLGSRLQWYROWDJHDQGWKHOHYHOVRIWKHSHDNVDQGWURXJKV<RXFDQYLVXDOL]HWKLVPLG
SRLQWYDOXHDVDOLQHUXQQLQJPLGZD\EHWZHHQWKHKLJKHVWSHDNDQGWKHORZHVWWURXJK
DVVKRZQLQ)LJXUH7KHOLQHUHSUHVHQWVWKH'&RIIVHWRIWKHVLJQDO LW¦VWKH'&
YDOXHZKHQWKHUHDUHQRSHDNVRUWURXJKV ,I\RXVXEWUDFWWKH'&RIIVHWYDOXHIURP
\RXUanalogReadYDOXHV\RXJHWWKHFRUUHFWUHDGLQJIRUWKHVLJQDODPSOLWXGH
)LJXUH$XGLRVLJQDOVKRZLQJ'&RIIVHW VLJQDOPLGSRLQW
$VWKHVLJQDOJHWVORXGHUWKHDYHUDJHVL]HRIWKHVHYDOXHVZLOOLQFUHDVHEXWDVVRPHRI
WKHPDUHQHJDWLYH ZKHUHWKHVLJQDOKDVGURSSHGEHORZWKH'&RIIVHW WKH\ZLOOFDQFHO
HDFKRWKHURXWDQGWKHDYHUDJHZLOOWHQGWREH]HUR7RIL[WKDWZHVTXDUHHDFKYDOXH
PXOWLSO\LWE\LWVHOI 7KLVZLOOPDNHDOOWKHYDOXHVSRVLWLYHDQGLWZLOOLQFUHDVHWKH
GLIIHUHQFHEHWZHHQVPDOOFKDQJHVZKLFKKHOSV\RXHYDOXDWHFKDQJHVDVZHOO7KHDYHU
DJHYDOXHZLOOQRZJRXSDQGGRZQDVWKHVLJQDODPSOLWXGHGRHV
184 | Chapter 6:ಗGetting Input from Sensors
7RGRWKHFDOFXODWLRQZHQHHGWRNQRZZKDWYDOXHWRXVHIRUWKH'&RIIVHW7RJHWD
FOHDQVLJQDOWKHDPSOLILHUFLUFXLWIRUWKHPLFURSKRQHZLOOKDYHEHHQGHVLJQHGWRKDYH
D'&RIIVHWDVFORVHDVSRVVLEOHWRWKHPLGGOHRIWKHSRVVLEOHUDQJHRIYROWDJHVRWKDW
WKHVLJQDOFDQJHWDVELJDVSRVVLEOHZLWKRXWGLVWRUWLQJ7KHFRGHDVVXPHVWKLVDQGXVHV
WKHYDOXH ULJKWLQWKHPLGGOHRIWKHDQDORJLQSXWUDQJHRIWR 7KHYDOXHVRIYDULDEOHVDWWKHWRSRIWKHVNHWFKFDQEHYDULHGLIWKHVNHWFKGRHVQRW
WULJJHUZHOOIRUWKHOHYHORIVRXQG\RXZDQW
7KHnumberOfSamplesLVVHWDW¢LILWLVVHWWRRVPDOOWKHDYHUDJHPD\QRWDGHTXDWHO\
FRYHUFRPSOHWHF\FOHVRIWKHZDYHIRUPDQG\RXZLOOJHWHUUDWLFUHDGLQJV,IWKHYDOXHLV
VHWWRRKLJK\RXZLOOEHDYHUDJLQJRYHUWRRORQJDWLPHDQGDYHU\VKRUWVRXQGPLJKW
EHPLVVHGDVLWGRHVQRWSURGXFHHQRXJKFKDQJHRQFHDODUJHQXPEHURIUHDGLQJVDUH
DYHUDJHG,WFRXOGDOVRVWDUWWRLQWURGXFHDQRWLFHDEOHGHOD\EHWZHHQDVRXQGDQGWKH
OLJKWJRLQJRQ&RQVWDQWVXVHGLQFDOFXODWLRQVVXFKDVnumberOfSamplesDQGaveraged
OverDUHVHWWRSRZHUVRI DQGUHVSHFWLYHO\ 7U\WRXVHYDOXHVHYHQO\GLYLVLEOH
E\WZRIRUWKHVHWRJLYH\RXWKHIDVWHVWSHUIRUPDQFH VHH&KDSWHUIRUPRUHRQPDWK
IXQFWLRQV 6.8 Measuring Temperature
Problem
<RXZDQWWRGLVSOD\WKHWHPSHUDWXUHRUXVHWKHYDOXHWRFRQWURODGHYLFHIRUH[DPSOH
WRVZLWFKVRPHWKLQJRQZKHQWKHWHPSHUDWXUHUHDFKHVDWKUHVKROG
Solution
7KLVUHFLSHGLVSOD\VWKHWHPSHUDWXUHLQ)DKUHQKHLWDQG&HOVLXV &HQWLJUDGH XVLQJWKH
SRSXODU/0KHDWGHWHFWLRQVHQVRU7KHVHQVRUORRNVVLPLODUWRDWUDQVLVWRUDQGLV
FRQQHFWHGDVVKRZQLQ)LJXUH
/*
lm35 sketch
prints the temperature to the Serial Monitor
*/
const int inPin = 0; // analog pin
void setup()
{
Serial.begin(9600);
}
void loop()
{
int value = analogRead(inPin);
6.8 Measuring Temperature | 185
Serial.print(value); Serial.print(" > ");
float millivolts = (value / 1024.0) * 5000;
float celsius = millivolts / 10; // sensor output is 10mV per degree Celsius
Serial.print(celsius);
Serial.print(" degrees Celsius, ");
Serial.print( (celsius * 9)/ 5 + 32 );
Serial.println(" degrees Fahrenheit");
//
converts to fahrenheit
delay(1000); // wait for one second
}
)LJXUH&RQQHFWLQJWKH/0WHPSHUDWXUHVHQVRU
Discussion
7KH /0 WHPSHUDWXUH VHQVRU SURGXFHV DQ DQDORJ YROWDJH GLUHFWO\ SURSRUWLRQDO WR
WHPSHUDWXUHZLWKDQRXWSXWRIPLOOLYROWSHU& P9SHUGHJUHH 7KHVNHWFKFRQYHUWVWKH analogReadYDOXHVLQWRPLOOLYROWV VHH&KDSWHU DQGGLYLGHV
WKLVE\WRJHWGHJUHHV
7KH VHQVRU DFFXUDF\ LV DURXQG & DQG LQ PDQ\ FDVHV \RX FDQ XVH LQWHJHU PDWK
LQVWHDGRIIORDWLQJSRLQW
7KHIROORZLQJVNHWFKWXUQVRQSLQZKHQWKHWHPSHUDWXUHLVDERYHDWKUHVKROG
const int inPin = 0; // sensor connected to this analog pin
const int outPin = 13; //2; // digital output pin
const int threshold = 25; // the degrees celsius that will trigger the output pin
186 | Chapter 6:ಗGetting Input from Sensors
void setup()
{
Serial.begin(9600);
pinMode(outPin, OUTPUT);
}
void loop()
{
int value = analogRead(inPin);
long celsius = (value * 500L) /1024;
Serial.print(celsius);
Serial.print(" degrees Celsius: ");
if(celsius > threshold)
{
digitalWrite(outPin, HIGH);
Serial.println("pin is on");
}
else
{
digitalWrite(outPin, LOW);
Serial.println("pin is off");
}
delay(1000); // wait for one second
}
// 10 mV per degree c, see text
7KHVNHWFKXVHVORQJ ELW LQWHJHUVWRFDOFXODWHWKHYDOXH7KHOHWWHU/DIWHUWKHQXP
EHUFDXVHVWKHFDOFXODWLRQWREHSHUIRUPHGXVLQJORQJLQWHJHUPDWKVRWKHPXOWLSOLFD
WLRQRIWKHPD[LPXPWHPSHUDWXUH RQD9$UGXLQR DQGWKHYDOXHUHDGIURPWKH
DQDORJLQSXWGRHVQRWRYHUIORZ6HHWKHUHFLSHVLQ&KDSWHUIRUPRUHDERXWFRQYHUWLQJ
DQDORJOHYHOVLQWRYROWDJHYDOXHV
,I\RXQHHGWKHYDOXHVLQ)DKUHQKHLW\RXFRXOGXVHWKH/0VHQVRUDVWKLVSURGXFHV
DQRXWSXWLQ)DKUHQKHLWRU\RXFDQFRQYHUWWKHYDOXHVLQWKLVUHFLSHXVLQJWKHIROORZLQJ
IRUPXOD
float
f = (celsius * 9)/ 5 + 32 );
6.9 Reading RFID Tags
Problem
<RXZDQWWRUHDGDQ5),'WDJDQGUHVSRQGWRVSHFLILF,'V
Solution
)LJXUHVKRZVD3DUDOOD[5),' UDGLRIUHTXHQF\LGHQWLILFDWLRQ UHDGHUFRQQHFWHG
WRWKH$UGXLQRVHULDOSRUW <RXPD\QHHGWRGLVFRQQHFWWKHUHDGHUIURPWKHVHULDOSRUW
ZKHQXSORDGLQJWKHVNHWFK
6.9 Reading RFID Tags | 187
)LJXUH6HULDO5),'UHDGHUFRQQHFWHGWR$UGXLQR
7KHVNHWFKUHDGVDQGGLVSOD\VWKHYDOXHRIDQ5),'WDJ
/*
RFID sketch
Displays the value read from an RFID tag
*/
const int startByte
= 10; // ASCII line feed precedes each tag
const int endByte
= 13; // ASCII carriage return terminates each tag
const int tagLength
= 10; // the number of digits in tag
const int totalLength = tagLength + 2; //tag length + start and end bytes
char tag[tagLength + 1];
// holds the tag and a terminating null
int bytesread = 0;
void setup()
{
Serial.begin(2400);
pinMode(2,OUTPUT);
digitalWrite(2, LOW);
}
// set this to the baud rate of your RFID reader
// connected to the RFID ENABLE pin
// enable the RFID reader
void loop()
{
if(Serial.available() >= totalLength) // check if there's enough data
{
if(Serial.read() == startByte)
{
bytesread = 0;
// start of tag so reset count to 0
188 | Chapter 6:ಗGetting Input from Sensors
}
}
while(bytesread < tagLength) // read 10 digit code
{
int val = Serial.read();
if((val == startByte)||(val == endByte)) // check for end of code
break;
tag[bytesread] = val;
bytesread = bytesread + 1; // ready to read next digit
}
if( Serial.read() == endByte) // check for the correct end character
{
tag[bytesread] = 0; // terminate the string
Serial.print("RFID tag is: ");
Serial.println(tag);
}
}
Discussion
$WDJFRQVLVWVRIDVWDUWFKDUDFWHUIROORZHGE\DGLJLWWDJDQGLVWHUPLQDWHGE\DQ
HQGFKDUDFWHU7KHVNHWFKZDLWVIRUDFRPSOHWHWDJPHVVDJHWREHDYDLODEOHDQGGLVSOD\V
WKHWDJLILWLVYDOLG7KHWDJLVUHFHLYHGDV$6&,,GLJLWV VHH5HFLSHIRUPRUHRQ
UHFHLYLQJ$6&,,GLJLWV <RXPD\ZDQWWRFRQYHUWWKLVLQWRDQXPEHULI\RXZDQWWR
VWRUHRUFRPSDUHWKHYDOXHVUHFHLYHG7RGRWKLVFKDQJHWKHODVWIHZOLQHVDVIROORZV
if( Serial.read() == endByte) // check for the correct end character
{
tag[bytesread] = 0; // terminate the string
long tagValue = atol(tag); // convert the ASCII tag to a long integer
Serial.print("RFID tag is: ");
Serial.println(tagValue);
}
5),'VWDQGVIRUUDGLRIUHTXHQF\LGHQWLILFDWLRQDQGDVWKHQDPHLPSOLHVLWLVVHQVLWLYH
WRUDGLRIUHTXHQFLHVDQGFDQEHSURQHWRLQWHUIHUHQFH7KHFRGHLQWKLVUHFLSH¦V6ROXWLRQ
ZLOORQO\XVHFRGHRIWKHFRUUHFWOHQJWKWKDWFRQWDLQVWKHFRUUHFWVWDUWDQGHQGELWV
ZKLFKVKRXOGHOLPLQDWHPRVWHUURUV%XW\RXFDQPDNHWKHFRGHPRUHUHVLOLHQWE\UHDG
LQJWKHWDJPRUHWKDQRQFHDQGRQO\XVLQJWKHGDWDLILW¦VWKHVDPHHDFKWLPH 5),'
UHDGHUVVXFKDVWKH3DUDOOD[ZLOOUHSHDWWKHFRGHZKLOHDYDOLGFDUGLVQHDUWKHUHDGHU
7RGRWKLVDGGWKHIROORZLQJOLQHVWRWKHODVWIHZOLQHVLQWKHSUHFHGLQJFRGHVQLSSHW
if( Serial.read() == endByte) // check for the correct end character
{
tag[bytesread] = 0; // terminate the string
long tagValue = atol(tag); // convert the ASCII tag to a long integer
if (tagValue == lastTagValue)
{
Serial.print("RFID tag is: ");
Serial.println(tagValue);
lasTagValue = tagValue;
}
}
6.9 Reading RFID Tags | 189
<RXZLOOQHHGWRDGGWKHGHFODUDWLRQIRUlastTagValueDWWKHWRSRIWKHVNHWFK
Long lastTagValue=0;
7KLVDSSURDFKLVVLPLODUWRWKHFRGHIURP5HFLSH,WPHDQV\RXZLOORQO\JHWFRQ
ILUPDWLRQRIDFDUGLILWLVSUHVHQWHGORQJHQRXJKIRUWZRUHDGLQJVWREHWDNHQEXWIDOVH
UHDGLQJVZLOOEHOHVVOLNHO\<RXFDQDYRLGDFFLGHQWDOWULJJHULQJE\PDNLQJLWQHFHVVDU\
IRUWKHFDUGWREHSUHVHQWIRUDFHUWDLQDPRXQWRIWLPHEHIRUHWKHQXPEHULVUHSRUWHG
6.10 Tracking the Movement of a Dial
Problem
<RXZDQWWRPHDVXUHDQGGLVSOD\WKHURWDWLRQRIVRPHWKLQJWRWUDFNLWVVSHHGDQGRU
GLUHFWLRQ
Solution
7RVHQVHWKLVNLQGRIPRYHPHQW\RXFRXOGXVHDURWDU\HQFRGHU&RQQHFWWKHHQFRGHU
DVVKRZQLQ)LJXUH
/*
Read a rotary encoder
This simple version polls the encoder pins
The position is displayed on the Serial Monitor
*/
const int encoderPinA = 4;
const int encoderPinB = 2;
const int encoderStepsPerRevolution=16;
int angle = 0;
int val;
int encoderPos = 0;
boolean encoderALast = LOW;
// remembers the previous pin state
void setup()
{
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
digitalWrite(encoderPinA, HIGH);
digitalWrite(encoderPinB, HIGH);
Serial.begin (9600);
}
void loop()
{
boolean encoderA = digitalRead(encoderPinA);
190 | Chapter 6:ಗGetting Input from Sensors
Download from Wow! eBook <www.wowebook.com>
if ((encoderALast == HIGH) && (encoderA == LOW))
{
if (digitalRead(encoderPinB) == LOW)
{
encoderPos--;
}
else
{
encoderPos++;
}
angle=(encoderPos % encoderStepsPerRevolution)*360/encoderStepsPerRevolution;
Serial.print (encoderPos);
Serial.print (" ");
Serial.println (angle);
}
}
encoderALast = encoderA;
)LJXUH5RWDU\HQFRGHU
Discussion
$URWDU\HQFRGHUSURGXFHVWZRVLJQDOVDVLWLVWXUQHG%RWKVLJQDOVDOWHUQDWHEHWZHHQ
HIGHDQGLOWDVWKHVKDIWLVWXUQHGEXWWKHVLJQDOVDUHVOLJKWO\RXWRISKDVHZLWKHDFK
RWKHU,I\RXGHWHFWWKHSRLQWZKHUHRQHRIWKHVLJQDOVFKDQJHVIURP HIGHWR LOWWKH
VWDWHRIWKHRWKHUSLQ ZKHWKHULWLV HIGHRU LOW ZLOOWHOO\RXZKLFKZD\WKHVKDIWLV
URWDWLQJ
6.10 Tracking the Movement of a Dial | 191
Download from Wow! eBook <www.wowebook.com>
6RWKHILUVWOLQHRIFRGHLQWKHloopIXQFWLRQUHDGVRQHRIWKHHQFRGHUSLQV
int encoderA = digitalRead(encoderPinA);
7KHQLWFKHFNVWKLVYDOXHDQGWKHSUHYLRXVRQHWRVHHLIWKHYDOXHKDVMXVWFKDQJHGWRLOW
if ((encoderALast == HIGH) && (encoderA == LOW))
,ILWKDVQRWWKHFRGHGRHVQ¦WH[HFXWHWKHIROORZLQJEORFNLWJRHVWRWKHERWWRPRI
loopVDYHVWKHYDOXHLWKDVMXVWUHDGLQ encoderALastDQGJRHVEDFNDURXQGWRWDNHD
IUHVKUHDGLQJ
:KHQWKHIROORZLQJH[SUHVVLRQLVtrue
if ((encoderALast == HIGH) && (encoderA == LOW))
WKHFRGHUHDGVWKHRWKHUHQFRGHUSLQDQGLQFUHPHQWVRUGHFUHPHQWV encoderPosGH
SHQGLQJRQWKHYDOXHUHWXUQHG,WFDOFXODWHVWKHDQJOHRIWKHVKDIW WDNLQJWREHWKH
SRLQWWKHVKDIWZDVDWZKHQWKHFRGHVWDUWHGUXQQLQJ ,WWKHQVHQGVWKHYDOXHVGRZQ
WKHVHULDOSRUWVRWKDW\RXFDQVHHLWLQWKH6HULDO0RQLWRU
(QFRGHUVFRPHLQGLIIHUHQWUHVROXWLRQVTXRWHGDVVWHSVSHUUHYROXWLRQ7KLVLQGLFDWHV
KRZPDQ\WLPHVWKHVLJQDOVDOWHUQDWHEHWZHHQ HIGHDQG LOWIRURQHUHYROXWLRQRIWKH
VKDIW9DOXHVFDQYDU\IURPWR7KHKLJKHUYDOXHVFDQGHWHFWVPDOOHUPRYH
PHQWVDQGWKHVHHQFRGHUVFRVWPXFKPRUHPRQH\7KHYDOXHIRUWKHHQFRGHULVKDUG
FRGHGLQWKHFRGHLQWKHIROORZLQJOLQH
const int encoderStepsPerRevolution=16;
,I\RXUHQFRGHULVGLIIHUHQW\RXQHHGWRFKDQJHWKDWWRJHWWKHFRUUHFWDQJOHYDOXHV
,I\RXJHWYDOXHVRXWWKDWGRQ¦WJRXSDQGGRZQEXWLQFUHDVHUHJDUGOHVVRIWKHGLUHFWLRQ
\RXWXUQWKHHQFRGHUWU\FKDQJLQJWKHWHVWWRORRNIRUDULVLQJHGJHUDWKHUWKDQDIDOOLQJ
RQH6ZDSWKHLOWDQGHIGHYDOXHVLQWKHOLQHWKDWFKHFNVWKHYDOXHVVRWKDWLWORRNVOLNH
WKLV
if ((encoderALast == LOW) && (encoderA == HIGH))
5RWDU\HQFRGHUVMXVWSURGXFHDQLQFUHPHQWGHFUHPHQWVLJQDOWKH\FDQQRWGLUHFWO\WHOO
\RXWKHVKDIWDQJOH7KHFRGHFDOFXODWHVWKLVEXWLWZLOOEHUHODWLYHWRWKHVWDUWSRVLWLRQ
HDFKWLPHWKHFRGHUXQV7KHFRGHPRQLWRUVWKHSLQVE\SROOLQJ FRQWLQXRXVO\FKHFNLQJ
WKHYDOXHRI WKHP7KHUHLVQRJXDUDQWHHWKDWWKHSLQVKDYHQRWFKDQJHGDIHZWLPHV
VLQFHWKHODVWWLPHWKHFRGHORRNHGVRLIWKHFRGHGRHVORWVRIRWKHUWKLQJVDVZHOODQG
WKHHQFRGHULVWXUQHGYHU\TXLFNO\LWLVSRVVLEOHWKDWVRPHRIWKHVWHSVZLOOEHPLVVHG
)RUKLJKUHVROXWLRQHQFRGHUVWKLVLVPRUHOLNHO\DVWKH\ZLOOVHQGVLJQDOVPXFKPRUH
RIWHQDVWKH\DUHWXUQHG
7RZRUNRXWWKHVSHHG\RXQHHGWRFRXQWKRZPDQ\VWHSVDUHUHJLVWHUHGLQRQHGLUHFWLRQ
LQDVHWWLPH
192 | Chapter 6:ಗGetting Input from Sensors
6.11 Tracking the Movement of More Than One Rotary Encoder
Problem
<RXKDYHWZRRUPRUHURWDU\HQFRGHUVDQG\RXZDQWWRPHDVXUHDQGGLVSOD\URWDWLRQ
Solution
7KHFLUFXLWXVHVWZRHQFRGHUVFRQQHFWHGDVVKRZQLQ)LJXUH<RXFDQUHDGPRUH
DERXWURWDU\HQFRGHUVLQ5HFLSH
/*
RotaryEncoderMultiPoll
This sketch has two encoders connected.
One is connected to pins 2 and 3
The other is connected to pins 4 and 5
*/
const int
ENCODERS = 2; // the number of encoders
const int encoderPinA[ENCODERS] = {2,4};
// encoderA pins on 2 and 4
const int encoderPinB[ENCODERS] = {3,5};
// encoderB pins on 3 and 5
int encoderPos[ ENCODERS] = { 0,0};
// initialize the positions to 0
boolean encoderALast[ENCODERS] = { LOW,LOW}; // holds last state of encoderA pin
void setup()
{
for (int i=2; i<6; i++){
pinMode(i, HIGH);
digitalWrite(i, HIGH);
}
Serial.begin (9600);
}
int updatePosition( int encoderIndex)
{
boolean encoderA = digitalRead(encoderPinA[encoderIndex]);
if ((encoderALast[encoderIndex] == HIGH) && (encoderA == LOW))
{
if (digitalRead(encoderPinB[encoderIndex]) == LOW)
{
encoderPos[encoderIndex]--;
}
else
{
encoderPos[encoderIndex]++;
}
Serial.print("Encoder ");
Serial.print(encoderIndex,DEC);
Serial.print("=");
Serial.print (encoderPos[encoderIndex]);
Serial.println ("/");
}
6.11 Tracking the Movement of More Than One Rotary Encoder | 193
}
encoderALast[encoderIndex] = encoderA;
void loop()
{
for(int i=0; i < ENCODERS;i++)
{
updatePosition(i);
}
}
)LJXUH&RQQHFWLQJWZRURWDU\HQFRGHUV
Discussion
7KLVUHFLSHXVHVWKHVDPHFRGHORJLFDV5HFLSHZKLFKZDVUHDGLQJRQHHQFRGHU
EXWLWXVHVDUUD\VIRUDOOWKHYDULDEOHVWKDWPXVWEHUHPHPEHUHGVHSDUDWHO\IRUHDFK
HQFRGHU<RXFDQWKHQXVHDforORRSWRJRWKURXJKHDFKRQHDQGUHDGLWDQGFDOFXODWH
LWVURWDWLRQ7RXVHPRUHHQFRGHUVVHWWKHENCODERSYDOXHVWRWKHQXPEHURIHQFRGHUV
\RXKDYHDQGH[WHQGWKHDUUD\VDQGWKHGHILQLWLRQVWRVD\ZKLFKSLQVWKH\DUHDWWDFKHG
WR
,I\RXJHWYDOXHVRXWWKDWGRQ¦WJRXSDQGGRZQEXWLQFUHDVHUHJDUGOHVVRIWKHGLUHFWLRQ
\RXWXUQWKHHQFRGHUWU\FKDQJLQJWKHWHVWWRORRNIRUDULVLQJHGJHUDWKHUWKDQDIDOOLQJ
RQH6ZDSWKHLOWDQGHIGHYDOXHVLQWKHOLQHWKDWFKHFNVWKHYDOXHVIURPWKLV
if ((encoderALast[encoderIndex] == HIGH) && (encoderA == LOW))
194 | Chapter 6:ಗGetting Input from Sensors
WRWKLV
if ((encoderALast[encoderIndex] == LOW) && (encoderA == HIGH))
,IRQHRIWKHHQFRGHUVZRUNVEXWWKHRWKHUMXVWFRXQWVXSVZLWFKRYHUWKH$DQG%
FRQQHFWLRQVIRUWKHRQHWKDWMXVWFRXQWVXS
6.12 Tracking the Movement of a Dial in a Busy Sketch
Problem
$V\RXH[WHQG\RXUFRGHDQGLWLVGRLQJRWKHUWKLQJVLQDGGLWLRQWRUHDGLQJWKHHQFRGHU
UHDGLQJWKHHQFRGHUVWDUWVWRJHWXQUHOLDEOH7KLVSUREOHPLVSDUWLFXODUO\EDGLIWKHVKDIW
URWDWHVTXLFNO\
Solution
7KHFLUFXLWLVWKHVDPHDVWKHRQHIRU5HFLSH:HZLOOXVHDQLQWHUUXSWRQWKH
$UGXLQRWRPDNHVXUHWKDWHYHU\WLPHDVWHSKDSSHQVWKHFRGHUHVSRQGVWRLW
/*
RotaryEncoderInterrupt sketch
*/
const int encoderPinA = 2;
const int encoderPinB = 4;
int Pos, oldPos;
volatile int encoderPos = 0; // variables changed within interrupts are volatile
void setup()
{
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
digitalWrite(encoderPinA, HIGH);
digitalWrite(encoderPinB, HIGH);
Serial.begin(9600);
attachInterrupt(0, doEncoder, FALLING); // encoder pin on interrupt 0 (pin 2)
}
void loop()
{
uint8_t oldSREG = SREG;
cli();
Pos = encoderPos;
SREG = oldSREG;
if(Pos != oldPos)
{
Serial.println(Pos,DEC);
oldPos = Pos;
6.12 Tracking the Movement of a Dial in a Busy Sketch | 195
}
}
Delay(1000);
void doEncoder()
{
if (digitalRead(encoderPinA) == digitalRead(encoderPinB))
encoderPos++;
// count up if both encoder pins are the same
else
encoderPos--;
//count down if pins are different
}
7KLVFRGHZLOORQO\UHSRUWWKHPosYDOXHRQWKHVHULDOSRUWDWPRVWRQFHHYHU\VHFRQG
EHFDXVHRIWKHGHOD\ EXWWKHYDOXHVUHSRUWHGZLOOWDNHLQWRDFFRXQWDQ\PRYHPHQW
WKDWPD\KDYHKDSSHQHGZKLOHLWZDVGHOD\LQJ
Discussion
$V\RXUFRGHKDVPRUHWKLQJVWRGRWKHHQFRGHUSLQVZLOOEHFKHFNHGOHVVRIWHQ,IWKH
SLQVJRWKURXJKDZKROHVWHSFKDQJHEHIRUHJHWWLQJUHDGWKH$UGXLQRZLOOQRWGHWHFW
WKDWVWHS0RYLQJWKHVKDIWTXLFNO\ZLOOFDXVHWKLVWRKDSSHQPRUHRIWHQDVWKHVWHSV
ZLOOEHKDSSHQLQJPRUHTXLFNO\
7RPDNHVXUHWKHFRGHUHVSRQGVHYHU\WLPHDVWHSKDSSHQV\RXQHHGWRXVHLQWHUUXSWV
:KHQWKHLQWHUUXSWFRQGLWLRQKDSSHQVWKHFRGHMXPSVIURPZKHUHYHULWLVGRHVZKDW
QHHGVWRKDSSHQDQGWKHQUHWXUQVWRZKHUHLWZDVDQGFDUULHVRQ
2QDVWDQGDUG$UGXLQRERDUGWZRSLQVFDQEHXVHGDVLQWHUUXSWVSLQVDQG7KH
LQWHUUXSWLVHQDEOHGWKURXJKWKHIROORZLQJOLQH
attachInterrupt(0, doEncoder, FALLING);
7KHWKUHHSDUDPHWHUVQHHGHGDUHWKHLQWHUUXSWSLQLGHQWLILHU IRUSLQIRUSLQ WKHIXQFWLRQWRMXPSWRZKHQWKHLQWHUUXSWKDSSHQVLQWKLVFDVHdoEncoderDQGILQDOO\
WKHSLQEHKDYLRUWRWULJJHUWKHLQWHUUXSWLQWKLVFDVHZKHQWKHYROWDJHIDOOVIURPWR
YROWV7KHRWKHURSWLRQVDUHRISING YROWDJHULVHVIURPWRYROWV DQGCHANGE YROWDJH
IDOOVRUULVHV 7KHdoEncoderIXQFWLRQFKHFNVWKHHQFRGHUSLQVWRVHHZKLFKZD\WKHVKDIWWXUQHGDQG
FKDQJHVencoderPosWRUHIOHFWWKLV
,IWKHYDOXHVUHSRUWHGRQO\LQFUHDVHUHJDUGOHVVRIWKHGLUHFWLRQRIURWDWLRQWU\FKDQJLQJ
WKHLQWHUUXSWWRORRNIRURISINGUDWKHUWKDQFALLING
%HFDXVHencoderPosLVFKDQJHGLQWKHIXQFWLRQWKDWLVFDOOHGZKHQWKHLQWHUUXSWKDSSHQV
LWQHHGVWREHGHFODUHGDV volatileZKHQLWLVFUHDWHG7KLVWHOOVWKHFRPSLOHUWKDWLW
FRXOGFKDQJHDWDQ\WLPHGRQ¦WRSWLPL]HWKHFRGHE\DVVXPLQJLWZRQ¦WKDYHFKDQJHG
DVWKHLQWHUUXSWFDQKDSSHQDWDQ\WLPH
196 | Chapter 6:ಗGetting Input from Sensors
7KH$UGXLQREXLOGSURFHVVRSWLPL]HVWKHFRGHE\UHPRYLQJFRGHDQG
YDULDEOHVWKDWDUHQRWXVHGE\\RXUVNHWFKFRGH9DULDEOHVWKDWDUHRQO\
PRGLILHGLQDQLQWHUUXSWKDQGOHUVKRXOGEHGHFODUHGDVvolatileWRWHOO
WKHFRPSLOHUQRWWRUHPRYHWKHVHYDULDEOHV
7RUHDGWKLVYDULDEOHLQWKHPDLQORRS\RXVKRXOGWDNHVSHFLDOSUHFDXWLRQVWRPDNH
VXUHWKHLQWHUUXSWGRHVQRWKDSSHQLQWKHPLGGOHRIUHDGLQJLW7KLVFKXQNRIFRGHGRHV
WKDW
uint8_t oldSREG = SREG;
cli();
Pos = encoderPos;
SREG = oldSREG;
)LUVW\RXVDYHWKHVWDWHRISREG WKHLQWHUUXSWUHJLVWHUV DQGWKHQcliWXUQVWKHLQWHUUXSW
RII7KHYDOXHLVUHDGDQGWKHQUHVWRULQJ SREGWXUQVWKHLQWHUUXSWEDFNRQDQGVHWV
HYHU\WKLQJEDFNDVLWZDV$Q\LQWHUUXSWWKDWRFFXUVZKHQLQWHUUXSWVDUHWXUQHGRIIZLOO
ZDLWXQWLOLQWHUUXSWVDUHWXUQHGEDFNRQ7KLVSHULRGLVVRVKRUWWKDWLQWHUUXSWVZLOOQRW
EHPLVVHG DVORQJDV\RXNHHSWKHFRGHLQWKHLQWHUUXSWKDQGOHUDVVKRUWDVSRVVLEOH 6.13 Using a Mouse
Problem
<RXZDQWWRGHWHFWPRYHPHQWVRID36FRPSDWLEOHPRXVHDQGUHVSRQGWRFKDQJHVLQ
WKH[DQG\FRRUGLQDWHV
Solution
7KLVVROXWLRQXVHV/('VWRLQGLFDWHPRXVHPRYHPHQW7KHEULJKWQHVVRIWKH/('V
FKDQJHVLQUHVSRQVHWRPRXVHPRYHPHQWLQWKH[ OHIWDQGULJKW DQG\ QHDUHUDQG
IDUWKHU GLUHFWLRQV&OLFNLQJWKHPRXVHEXWWRQVVHWVWKHFXUUHQWSRVLWLRQDVWKHUHIHUHQFH
SRLQW)LJXUHVKRZVWKHFRQQHFWLRQV
/*
Mouse
an arduino sketch using ps2 mouse library
see: http://www.arduino.cc/playground/ComponentLib/Ps2mouse
*/
// mouse library from :
#include <ps2.h>
http://www.arduino.cc/playground/ComponentLib/Ps2mouse
const int dataPin = 5
const int clockPin = 6;
const int xLedPin
const int yLedPin
= 9;
= 11;
6.13 Using a Mouse | 197
const int mouseRange = 255; // the maximum range of x/y values
int xPosition = 0;
int yPosition = 0;
int xBrightness = 128;
int yBrightness = 128;
// values incremented and decremented when mouse moves
// values increased and decreased based on mouse position
const byte REQUEST_DATA = 0xeb; // command to get data from the mouse
PS2 mouse(clockPin, dataPin);
void setup()
{
Serial.begin(115200);
mouseBegin();
}
// note the higher than usual serial speed
// get a reading from mouse and report it back to the host via the serial line
void loop()
{
char x;
// values read from the mouse
char y;
byte status;
// get a reading from the mouse
mouse.write(REQUEST_DATA); // ask the mouse for data
mouse.read();
// ignore ack
status = mouse.read(); // read the mouse buttons
if(status & 1) // this bit is set if the left mouse btn pressed
xPosition = 0; // center the mouse x position
if(status & 2) // this bit is set if the right mouse btn pressed
yPosition = 0; // center the mouse y position
x = mouse.read();
y = mouse.read();
if( x != 0 || y != 0)
{
// here if there is mouse movement
xPosition = xPosition + x; // accumulate the position
xPosition = constrain(xPosition,-mouseRange,mouseRange);
xBrightness = map(xPosition, -mouseRange, mouseRange, 0,255);
analogWrite(xLedPin, xBrightness);
yPosition = constrain(yPosition + y, -mouseRange,mouseRange);
yBrightness = map(yPosition, -mouseRange, mouseRange, 0,255);
analogWrite(yLedPin, yBrightness);
}
}
void mouseBegin()
{
// reset and initialize the mouse
198 | Chapter 6:ಗGetting Input from Sensors
mouse.write(0xff);
delayMicroseconds(100);
mouse.read();
mouse.read();
mouse.read();
mouse.write(0xf0);
mouse.read();
delayMicroseconds(100);
// reset
// ack byte
// blank
// blank
// remote mode
// ack
}
)LJXUH&RQQHFWLQJDPRXVHWRLQGLFDWHSRVLWLRQDQGOLJKW/('V
Discussion
&RQQHFWWKHPRXVHVLJQDO FORFNDQGGDWD DQGSRZHUOHDGVWR$UGXLQRDVVKRZQLQ
)LJXUH7KLVVROXWLRQRQO\ZRUNVZLWK36FRPSDWLEOHGHYLFHVVR\RXPD\QHHG
WRILQGDQROGHUPRXVH¢PRVWPLFHZLWKWKHURXQG36FRQQHFWRUVKRXOGZRUN
7KHmouseBeginIXQFWLRQLQLWLDOL]HVWKHPRXVHWRUHVSRQGWRUHTXHVWVIRUPRYHPHQWDQG
EXWWRQVWDWXV7KH36OLEUDU\IURPKWWSZZZDUGXLQRFFSOD\JURXQG&RPSRQHQW/LE
3VPRXVHKDQGOHVWKHORZOHYHOFRPPXQLFDWLRQ7KHmouse.writeFRPPDQGLVXVHGWR
LQVWUXFW WKH PRXVH WKDW GDWD ZLOO EH UHTXHVWHG 7KH ILUVW FDOO WR mouse.read JHWV DQ
DFNQRZOHGJPHQW ZKLFKLVLJQRUHGLQWKLVH[DPSOH 7KHQH[WFDOOWRmouse.readJHWV
6.13 Using a Mouse | 199
WKHEXWWRQVWDWXVDQGWKHODVWWZRmouse.readFDOOVJHWWKH[DQG\PRYHPHQWWKDWKDV
WDNHQSODFHVLQFHWKHSUHYLRXVUHTXHVW
7KHVNHWFKWHVWVWRVHHZKLFKELWVDUH HIGHLQWKH statusYDOXHWRGHWHUPLQHLIWKHOHIW
RUULJKWPRXVHEXWWRQZDVSUHVVHG7KHWZRULJKWPRVWELWVZLOOEHHIGHZKHQWKHOHIW
DQGULJKWEXWWRQVDUHSUHVVHGDQGWKHVHDUHFKHFNHGLQWKHIROORZLQJOLQHV
status = mouse.read(); // read the mouse buttons
if(status & 1) // rightmost bit is set if the left mouse btn pressed
xPosition = 0; // center the mouse x position
if(status & 2) // this bit is set if the right mouse btn pressed
yPosition = 0; // center the mouse y position
7KH xDQG yYDOXHVUHDGIURPWKHPRXVHUHSUHVHQWWKHPRYHPHQWVLQFHWKHSUHYLRXV
UHTXHVWDQGWKHVHYDOXHVDUHDFFXPXODWHGLQWKHYDULDEOHVxPositionDQGyPosition
7KHYDOXHVRIxDQGyZLOOEHSRVLWLYHLIWKHPRXVHPRYHVULJKWRUDZD\IURP\RXDQG
QHJDWLYHLILWPRYHVOHIWRUWRZDUG\RX
7KH VNHWFK HQVXUHV WKDW WKH DFFXPXODWHG YDOXH GRHV QRW H[FHHG WKH GHILQHG UDQJH
mouseRange XVLQJWKHconstrainIXQFWLRQ
xPosition = xPosition + x; // accumulate the position
xPosition = constrain(xPosition,-mouseRange,mouseRange);
7KHyPositionFDOFXODWLRQVKRZVDVKRUWKDQGZD\WRGRWKHVDPHWKLQJKHUHWKHFDO
FXODWLRQIRUWKHyYDOXHLVGRQHZLWKLQWKHFDOOWRconstrain
yPosition = constrain(yPosition + y,-mouseRange,mouseRange);
7KH xPosition DQG yPosition YDULDEOHV DUH UHVHW WR ]HUR LI WKH OHIW DQG ULJKW PRXVH
EXWWRQVDUHSUHVVHG
/('VDUHLOOXPLQDWHGWRFRUUHVSRQGWRSRVLWLRQXVLQJanalogWrite¢KDOIEULJKWQHVVLQ
WKHFHQWHUDQGLQFUHDVLQJDQGGHFUHDVLQJLQEULJKWQHVVDVWKHPRXVHSRVLWLRQLQFUHDVHV
DQGGHFUHDVHV
7KHSRVLWLRQFDQEHGLVSOD\HGRQWKH6HULDO0RQLWRUE\DGGLQJWKHIROORZLQJOLQHMXVW
DIWHUWKHanalogWriteIXQFWLRQ
printValues(); // show button and x and y values on Serial Monitor
$GGWKHIROORZLQJIXQFWLRQWRWKHHQGRIWKHVNHWFKWRSULQWWKHYDOXHVUHFHLYHGIURP
WKHPRXVH
void printValues()
{
Serial.println(status, BIN);
Serial.print("X=");
Serial.print(x,DEC);
Serial.print(", position= ");
Serial.print(xPosition);
Serial.print(", brightness= ");
Serial.println(xBrightness);
200 | Chapter 6:ಗGetting Input from Sensors
Serial.print("Y=");
Serial.print(y,DEC);
Serial.print(", position= ");
Serial.print(yPosition);
Serial.print(", brightness= ");
Serial.println(yBrightness);
Serial.println();
}
6.14 Getting Location from a GPS
Problem
<RXZDQWWRGHWHUPLQHORFDWLRQXVLQJD*36PRGXOH
Solution
$QXPEHURIILQH$UGXLQRFRPSDWLEOH*36XQLWVDUHDYDLODEOHWRGD\0RVWXVHDIDPLOLDU
VHULDOLQWHUIDFHWRFRPPXQLFDWHZLWKWKHLUKRVWPLFURFRQWUROOHUXVLQJDSURWRFRONQRZQ
DV10($7KLVLQGXVWU\VWDQGDUGSURYLGHVIRU*36GDWDWREHGHOLYHUHGWR£OLV
WHQHU¤GHYLFHVVXFKDV$UGXLQRDVKXPDQUHDGDEOH$6&,,£VHQWHQFHV¤)RUH[DPSOH
WKHIROORZLQJ10($VHQWHQFH
*3*//1:$ '
GHVFULEHVDPRQJRWKHUWKLQJVDORFDWLRQRQWKHJOREHDW 1RUWKODWLWXGHE\
:HVWORQJLWXGH
7RHVWDEOLVKORFDWLRQ\RXU$UGXLQRVNHWFKPXVWSDUVHWKHVHVWULQJVDQGFRQYHUWWKH
UHOHYDQW WH[W WR QXPHULF IRUP :ULWLQJ FRGH WR PDQXDOO\ H[WUDFW GDWD IURP 10($
VHQWHQFHVFDQEHWULFN\DQGFXPEHUVRPHLQWKH$UGXLQR¦VOLPLWHGDGGUHVVVSDFHEXW
IRUWXQDWHO\WKHUHLVDXVHIXOOLEUDU\WKDWGRHVWKLVZRUNIRU\RX0LNDO+DUW¦V7LQ\*36
'RZQORDGLWIURPKWWSDUGXLQLDQDRUJDQGLQVWDOOLW )RULQVWUXFWLRQVRQLQVWDOOLQJ
WKLUGSDUW\OLEUDULHVVHH&KDSWHU
7KHJHQHUDOVWUDWHJ\IRUXVLQJD*36LVDVIROORZV
3K\VLFDOO\FRQQHFWWKH*36GHYLFHWRWKH$UGXLQR
5HDGVHULDO10($GDWDIURPWKH*36GHYLFH
3URFHVVWKHGDWDWRGHWHUPLQHORFDWLRQ
8VLQJ7LQ\*36\RXGRWKHIROORZLQJ
3K\VLFDOO\FRQQHFWWKH*36GHYLFHWRWKH$UGXLQR
&UHDWHD7LQ\*36REMHFW
5HDGVHULDO10($GDWDIURPWKH*36GHYLFH
3URFHVVHDFKE\WHZLWK7LQ\*36¦Vencode()PHWKRG
3HULRGLFDOO\TXHU\7LQ\*36¦Vget_position()PHWKRGWRGHWHUPLQHORFDWLRQ
6.14 Getting Location from a GPS | 201
7KH IROORZLQJ VNHWFK LOOXVWUDWHV KRZ \RX FDQ DFTXLUH GDWD IURP D *36 DWWDFKHG WR
$UGXLQR¦VVHULDOSRUW,WOLJKWVWKHEXLOWLQ/('FRQQHFWHGWRSLQZKHQHYHUWKHGHYLFH
LVLQWKH6RXWKHUQ+HPLVSKHUH
// A simple sketch to detect the Southern Hemisphere
// Assumes: LED on pin 13, GPS connected to Hardware Serial pins 0/1
#include "TinyGPS.h"
TinyGPS gps; // create a TinyGPS object
#define HEMISPHERE_PIN 13
void setup()
{
6WDUWVHULDOFRPPXQLFDWLRQVXVLQJWKHUDWHUHTXLUHGE\\RXU*366HH&KDSWHULI\RX
QHHGPRUHLQIRUPDWLRQRQXVLQJ$UGXLQRVHULDOFRPPXQLFDWLRQV
Serial.begin(4800); // GPS devices frequently operate at 4800 baud
pinMode(HEMISPHERE_PIN, OUTPUT);
digitalWrite(HEMISPHERE_PIN, LOW); // turn off LED to start
}
void loop()
{
while (Serial.available())
{
int c = Serial.read();
}
// Encode() each byte
// Check for new position if encode() returns "True"
if (gps.encode(c))
{
long lat, lon;
gps.get_position(&lat, &lon);
if (lat < 0) // Southern Hemisphere?
digitalWrite(HEMISPHERE_PIN, HIGH);
else
digitalWrite(HEMISPHERE_PIN, LOW);
}
}
+HUHDEDXGFRQQHFWLRQLVHVWDEOLVKHGZLWKWKH*362QFHE\WHVEHJLQIORZLQJ
WKH\ DUH SURFHVVHG E\ encode() ZKLFK SDUVHV WKH 10($ GDWD $ true UHWXUQ IURP
encode()LQGLFDWHVWKDW7LQ\*36KDVVXFFHVVIXOO\SDUVHGDFRPSOHWHVHQWHQFHDQGWKDW
IUHVKSRVLWLRQGDWDPD\EHDYDLODEOH7KLVLVDJRRGWLPHWRFKHFNWKHGHYLFH¦VFXUUHQW
ORFDWLRQZLWKDFDOOWRget_position()
7LQ\*36¦Vget_position()UHWXUQVWKHPRVWUHFHQWO\REVHUYHGODWLWXGHDQGORQJLWXGH
7KHH[DPSOHH[DPLQHVODWLWXGHLILWLVOHVVWKDQ]HURWKDWLVVRXWKRIWKHHTXDWRUWKH
/('LVLOOXPLQDWHG
202 | Chapter 6:ಗGetting Input from Sensors
Discussion
$WWDFKLQJD*36XQLWWRDQ$UGXLQRLVXVXDOO\DVVLPSOHDVFRQQHFWLQJWZRRUWKUHHGDWD
OLQHV IURP WKH *36 WR LQSXW SLQV RQ WKH $UGXLQR 8VLQJ WKH SRSXODU 86*OREDO6DW
(0$*36PRGXOHDVDQH[DPSOH\RXFDQFRQQHFWWKHOLQHVDVVKRZQLQ7DEOH
7DEOH(0$*36SLQFRQQHFWLRQV
EM-406A line
Arduino pin
GND
Gnd
VIN
+Vcc
RX
TX (pin 1)
TX
RX (pin 0)
GND
Gnd
6RPH*36PRGXOHVXVH56YROWDJHOHYHOVZKLFKDUHLQFRPSDWLEOH
ZLWK$UGXLQR¦V77/ORJLF7KHVHUHTXLUHVRPHNLQGRILQWHUPHGLDWHORJLF
FRQYHUVLRQGHYLFHOLNHWKH0$;LQWHJUDWHGFLUFXLW
7KH FRGH LQ WKLV UHFLSH¦V 6ROXWLRQ DVVXPHV WKDW WKH *36 LV FRQQHFWHG GLUHFWO\ WR
$UGXLQR¦VEXLOWLQVHULDOSRUWEXWWKLVLVQRWXVXDOO\WKHPRVWFRQYHQLHQWGHVLJQ,Q
PDQ\SURMHFWVWKHKDUGZDUHVHULDOSRUWLVQHHGHGWRFRPPXQLFDWHZLWKDKRVW3&RU
RWKHUSHULSKHUDODQGFDQQRWEHXVHGE\WKH*36,QFDVHVOLNHWKLVVHOHFWDQRWKHUSDLU
RIGLJLWDOSLQVDQGXVHDVHULDOSRUWHPXODWLRQ £VRIWVHULDO¤ OLEUDU\WRWDONWRWKH*36
LQVWHDG
6RIWZDUH6HULDOLVWKHHPXODWLRQOLEUDU\WKDWFXUUHQWO\VKLSVZLWKWKH$UGXLQR,'(EXW
LWLVLQDGHTXDWHIRUPRVW*36SURFHVVLQJHVSHFLDOO\IRUPRGHUQGHYLFHVWKDWFRPPX
QLFDWHDWKLJKHUVSHHGV$VRI$UGXLQRUHYLVLRQWKHPRVWUREXVWDQGSRSXODU£VRIW
VHULDO¤SDFNDJHLVDWKLUGSDUW\OLEUDU\FDOOHG1HZ6RIW6HULDODOVRSXEOLVKHGDWKWWS
DUGXLQLDQDRUJ)URPWKHSURJUDPPHU¦VSRLQWRIYLHZ1HZ6RIW6HULDOLVXVHGVLPLODUO\
WRKDUGZDUHVHULDOVRPLJUDWLQJLVQRWXVXDOO\YHU\GLIILFXOW )RUDPRUHGHWDLOHGGLV
FXVVLRQRQXVLQJ1HZ6RIW6HULDOVHH5HFLSHVDQG
<RXFDQPRYHWKH*36¦V5;DQG7;OLQHVWRSLQVDQGWRIUHHXSWKHKDUGZDUHVHULDO
SRUWIRUGHEXJJLQJ/HDYLQJWKHVHULDOFDEOHFRQQHFWHGWRWKHKRVW3&PRGLI\WKHSUH
FHGLQJ VNHWFK WR XVH 1HZ6RIW6HULDO WR JHW D GHWDLOHG JOLPSVH RI 7LQ\*36 LQ DFWLRQ
WKURXJKWKH$UGXLQR¦V6HULDO0RQLWRU
// Another simple sketch to detect the Southern Hemisphere
// Assumes: LED on pin 13, GPS connected to pins 2/3
// (Optional) Serial debug console attached to hardware serial port 0/1
#include "TinyGPS.h"
#include "NewSoftSerial.h"
6.14 Getting Location from a GPS | 203
#define HEMISPHERE_PIN 13
#define GPS_RX_PIN 2
#define GPS_TX_PIN 3
TinyGPS gps; // create a TinyGPS object
NewSoftSerial nss(GPS_RX_PIN, GPS_TX_PIN); // create soft serial object
void setup()
{
1RWHWKDW\RXFDQXVHDGLIIHUHQWEDXGUDWHIRUFRQQHFWLRQWRWKH6HULDO0RQLWRUDQG
WKH*36
}
Serial.begin(9600); // for debugging
nss.begin(4800); // Use NewSoftSerial object to talk to GPS
pinMode(HEMISPHERE_PIN, OUTPUT);
digitalWrite(HEMISPHERE_PIN, LOW); // turn off LED to start
void loop()
{
while (nss.available())
{
int c = nss.read();
Serial.print(c, BYTE); // display NMEA data for debug
// Send each byte to encode()
// Check for new position if encode() returns "True"
if (gps.encode(c))
{
long lat, lon;
gps.get_position(&lat, &lon);
// Display new lat/lon on debug console
Serial.print("Lat: "); Serial.print(lat);
Serial.print(" Lon: "); Serial.println(lon);
}
if (lat < 0) // Southern Hemisphere?
digitalWrite(HEMISPHERE_PIN, HIGH);
else
digitalWrite(HEMISPHERE_PIN, LOW);
}
}
7KLVQHZVNHWFKEHKDYHVH[DFWO\WKHVDPHDVWKHHDUOLHUH[DPSOHEXWLVPXFKHDVLHUWR
GHEXJ$WDQ\WLPH\RXFDQVLPSO\KRRNDPRQLWRUXSWRWKHEXLOWLQVHULDOSRUWWR
ZDWFKWKH10($VHQWHQFHVDQG7LQ\*36GDWDVFUROOLQJE\
:KHQSRZHULVWXUQHGRQD*36XQLWLPPHGLDWHO\EHJLQVWUDQVPLWWLQJ10($VHQWHQ
FHV%XWEHFDXVHLWXVXDOO\WDNHVDZKLOHWRHVWDEOLVKDIL[¢XSWRWZRPLQXWHVLQVRPH
FDVHV¢WKHVH HDUO\ VHQWHQFHV W\SLFDOO\ GR QRW FRQWDLQ YDOLG ORFDWLRQ GDWD 6WRUP\
ZHDWKHURUWKHSUHVHQFHRIEXLOGLQJVRURWKHUREVWDFOHVPD\DOVRLQWHUIHUHZLWKWKH*36¦V
204 | Chapter 6:ಗGetting Input from Sensors
DELOLW\WRSLQSRLQWORFDWLRQ6RKRZGRHVWKHVNHWFKNQRZZKHWKHU7LQ\*36LVGHOLY
HULQJYDOLGSRVLWLRQGDWD"7KHDQVZHUOLHVLQWKHWKLUGSDUDPHWHUWRget_position()WKH
RSWLRQDOfix_age
,I\RXVXSSO\DSRLQWHUWRDQXQVLJQHGlongYDULDEOHDVget_position()¦VWKLUGSDUDP
HWHU7LQ\*36VHWVLWWRWKHQXPEHURIPLOOLVHFRQGVVLQFHWKHODVWYDOLGSRVLWLRQGDWD
ZDV DFTXLUHG VHH DOVR 5HFLSH $ YDOXH RI 0xFFFFFFFF KHUH V\PEROLFDOO\
GPS_INVALID_AGE PHDQV7LQ\*36KDVQRW\HWSDUVHGDQ\YDOLGVHQWHQFHVFRQWDLQLQJ
SRVLWLRQ GDWD ,Q WKLV FDVH WKH UHWXUQHG ODWLWXGH DQG ORQJLWXGH DUH LQYDOLG DV ZHOO
GPS_INVALID_ANGLE 8QGHUQRUPDORSHUDWLRQ\RXFDQH[SHFWWRVHHTXLWHORZYDOXHVIRUfix_age0RGHUQ
*36GHYLFHVDUHFDSDEOHRIUHSRUWLQJSRVLWLRQGDWDDVIUHTXHQWO\DVRQHWRILYHWLPHVSHU
VHFRQGRUPRUHVRDfix_ageLQH[FHVVRIPVRUVRVXJJHVWVWKDWWKHUHPD\EHD
SUREOHP3HUKDSVWKH*36LVWUDYHOLQJWKURXJKDWXQQHORUDZLULQJIODZLVFRUUXSWLQJ
WKH10($GDWDVWUHDPLQYDOLGDWLQJWKHFKHFNVXP DFDOFXODWLRQWRFKHFNWKDWWKHGDWD
LVQRWFRUUXSWHG ,QDQ\FDVHDODUJHfix_ageLQGLFDWHVWKDWWKHFRRUGLQDWHVUHWXUQHG
E\get_position()DUHVWDOH7KHIROORZLQJFRGHLVDQH[DPSOHRIKRZfix_ageFDQEH
XVHGWRHQVXUHWKDWWKHSRVLWLRQGDWDLVIUHVK
long lat, lon;
unsigned long fix_age;
gps.get_position(&lat, &lon, &fix_age);
if (fix_age == TinyGPS::INVALID_AGE)
Serial.println("No fix ever detected!");
else if (fix_age > 2000)
Serial.println("Data is getting STALE!");
else
Serial.println("Latitude and longitude valid!");
See Also
7LQ\*36DQG1HZ6RIW6HULDODUHDYDLODEOHIRUGRZQORDGDWKWWSDUGXLQLDQDRUJOLEUD
ULHVQHZVRIWVHULDO
)RUDGHHSHUXQGHUVWDQGLQJRIWKH10($SURWRFROUHDGWKH:LNLSHGLDDUWLFOHDWKWWS
HQZLNLSHGLDRUJZLNL10($
6HYHUDOVKRSVVHOO*36PRGXOHVWKDWLQWHUIDFHZHOOZLWK7LQ\*36DQG$UGXLQR7KHVH
GLIIHUPRVWO\LQSRZHUFRQVXPSWLRQYROWDJHDFFXUDF\SK\VLFDOLQWHUIDFHDQGZKHWKHU
WKH\VXSSRUWVHULDO10($6SDUN)XQ KWWSZZZVSDUNIXQFRP FDUULHVDODUJHUDQJH
RI*36PRGXOHVDQGKDVDQH[FHOOHQWEX\HU¦VJXLGH
*36WHFKQRORJ\KDVLQVSLUHGORWVRIFUHDWLYH$UGXLQRSURMHFWV$YHU\SRSXODUH[DPSOH
LVWKH*36GDWDORJJHULQZKLFKDPRYLQJGHYLFHUHFRUGVORFDWLRQGDWDDWUHJXODULQ
WHUYDOV WR WKH $UGXLQR ((3520 RU RWKHU RQERDUG VWRUDJH 6HH WKH EUHDGFUXPEV
SURMHFWDWKWWSFRGHJRRJOHFRPSEUHDGFUXPEVZLNL8VHU'RFXPHQWIRUDQH[DPSOH
/DG\DGDPDNHVDSRSXODU*36GDWDORJJLQJVKLHOGVHHKWWSZZZODG\DGDQHWPDNH
JSVVKLHOG
6.14 Getting Location from a GPS | 205
2WKHULQWHUHVWLQJ*36SURMHFWVLQFOXGHKREE\DLUSODQHVDQGKHOLFRSWHUVWKDWPDQHXYHU
WKHPVHOYHV WR SUHSURJUDPPHG GHVWLQDWLRQV XQGHU $UGXLQR VRIWZDUH FRQWURO 0LNDO
+DUWEXLOWD*36HQDEOHG£WUHDVXUHFKHVW¤ZLWKDQLQWHUQDOODWFKWKDWFDQQRWEHRSHQHG
XQWLOWKHER[LVSK\VLFDOO\PRYHGWRDFHUWDLQORFDWLRQ6HHKWWSDUGXLQLDQDRUJ
6.15 Detecting Rotation Using a Gyroscope
Problem
<RXZDQWWRUHVSRQGWRWKHUDWHRIURWDWLRQ7KLVFDQEHXVHGWRNHHSDYHKLFOHPRYLQJ
LQDVWUDLJKWOLQHRUWXUQLQJDWDGHVLUHGUDWH
Solution
0RVWORZFRVWJ\URVFRSHVXVHDQDQDORJYROWDJHSURSRUWLRQDOWRURWDWLRQUDWHDOWKRXJK
VRPH DOVR SURYLGH RXWSXW XVLQJ ,& VHH &KDSWHU IRU PRUH RQ XVLQJ ,& WR
FRPPXQLFDWHZLWKGHYLFHV 7KLVUHFLSHZRUNVZLWKDJ\URZLWKDQDQDORJRXWSXWSUR
SRUWLRQDO WR URWDWLRQ UDWH )LJXUH VKRZV DQ /,6<$/ EUHDNRXW ERDUG IURP
6SDUN)XQ0DQ\ORZFRVWJ\URVVXFKDVWKHRQHXVHGKHUHDUH9GHYLFHVDQGPXVW
QRWEHSOXJJHGLQWRWKH9SRZHUSLQ
&KHFN WKH PD[LPXP YROWDJH RI \RXU J\UR EHIRUH FRQQHFWLQJ SRZHU
3OXJJLQJD9J\URLQWRYROWVFDQSHUPDQHQWO\GDPDJHWKHGHYLFH
)LJXUH/,6<$/J\URFRQQHFWHGXVLQJ9SLQ
7KH*\UR287FRQQHFWLRQLVWKHDQDORJRXWSXWDQGLVFRQQHFWHGWR$UGXLQRDQDORJ
LQSXW7KH3'FRQQHFWLRQHQDEOHVWKHJ\URWREHVZLWFKHGLQWRORZSRZHUPRGHDQG
206 | Chapter 6:ಗGetting Input from Sensors
LVFRQQHFWHGWRDQDORJSLQ LQWKLVVNHWFKLWLVXVHGDVDGLJLWDORXWSXWSLQ <RXFDQ
FRQQHFW3'WRDQ\GLJLWDOSLQWKHSLQXVHGKHUHZDVFKRVHQWRNHHSWKHZLULQJQHDWHU
,I\RXGRQ¦WQHHGWRVZLWFKWKHJ\URLQWRORZSRZHUPRGH\RXFDQFRQQHFWWKH3'OLQH
WR*QG
$QDORJSLQVFDQDOVREHXVHGDVGLJLWDOSLQVWRLIWKH\DUHQRWQHHGHG
IRUUHDGLQJDQDORJYDOXHV6HHWKHLQWURGXFWLRQWR&KDSWHUIRUPRUH
RQXVLQJ$UGXLQRDQDORJDQGGLJLWDOSLQV
7KH67 VHOIWHVW OLQHLVIRUWHVWLQJDQGFDQEHOHIWXQFRQQHFWHG
/*
gyro sketch
displays the rotation rate on the Serial Monitor
*/
const int inputPin = 0;
// analog input 0
const int powerDownPin = 15; // analog input 1 is digital input 15
int rotationRate = 0;
void setup()
{
Serial.begin(9600);
// sets the serial port to 9600
pinMode(powerDownPin, OUTPUT);
digitalWrite(powerDown, LOW); // gyro not in power down mode
}
void loop()
{
rotationRate = analogRead(inputPin);
// read the gyro output
Serial.print("rotation rate is ");
Serial.println(rotation rate);
delay(100);
// wait 100ms for next reading
}
Discussion
7KLVVNHWFKVHWVWKHpowerDownPinWRLOWWRJHWWKHJ\URUXQQLQJLQQRUPDOPRGH \RX
FDQHOLPLQDWHWKLVFRGHIURPsetupLI\RXKDYHZLUHGWKH3'SLQWR*QG $QDORJLQSXWSLQVFDQEHXVHGDVGLJLWDOSLQV EXWQRWWKHRWKHUZD\
DURXQG $QDORJLQSXWLVGLJLWDOSLQDQDORJLQSXWLVGLJLWDOSLQ
DQGVRRQ
7KH loopFRGHUHDGVWKHJ\URYDOXHRQDQDORJSLQDQGGLVSOD\VWKLVRQWKH6HULDO
0RQLWRU
6.15 Detecting Rotation Using a Gyroscope | 207
6.16 Detecting Direction
Problem
<RXZDQW\RXUVNHWFKWRGHWHUPLQHGLUHFWLRQIURPDQHOHFWURQLFFRPSDVV
Solution
7KLVUHFLSHXVHVWKH+0%FRPSDVVPRGXOHIURP3DUDOOD[ )LJXUH
VKRZVWKHFRQQHFWLRQV
/*
HM55bCompass sketch
uses 'software SPI' serial protocol implemented using Arduino bit functions
(see Chapter 3)
prints compass angle to Serial Monitor
*/
const int enablePin = 2;
const int clockPin = 3;
const int dataPin
= 4;
// command codes (from HM55B data sheet)
const byte COMMAND_LENGTH = 4;
// the number of bits in a command
const byte RESET_COMMAND = B0000;
// reset the chip
const byte MEASURE_COMMAND = B1000;
// start a measurement
const byte READ_DATA_COMMAND = B1100; // read data and end flag
const byte MEASUREMENT_READY = B1100; // value returned when measurement complete
int angle;
void setup()
{
Serial.begin(9600);
pinMode(enablePin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, INPUT);
reset(); // reset the compass module
}
void loop()
{
startMeasurement();
delay(40); // wait for the data to be ready
if (readStatus()==MEASUREMENT_READY); // check if the data is ready
{
angle = readMeasurement();
//read measurement and calculate angle
Serial.print("Angle = ");
Serial.println(angle); // print angle
}
delay(100);
}
208 | Chapter 6:ಗGetting Input from Sensors
void reset()
{
pinMode(dataPin, OUTPUT);
digitalWrite(enablePin, LOW);
serialOut(RESET_COMMAND, COMMAND_LENGTH);
digitalWrite(enablePin, HIGH);
}
void startMeasurement()
{
pinMode(dataPin, OUTPUT);
digitalWrite(enablePin, LOW);
serialOut(MEASURE_COMMAND, COMMAND_LENGTH);
digitalWrite(enablePin, HIGH);
}
int readStatus()
{
int result = 0;
pinMode(dataPin, OUTPUT);
digitalWrite(enablePin, LOW);
serialOut(READ_DATA_COMMAND, COMMAND_LENGTH);
result = serialIn(4);
return result;
// returns the status
}
int readMeasurement()
{
int X_Data = 0;
int Y_Data = 0;
int calcAngle = 0;
X_Data = serialIn(11); // Field strength in X
Y_Data = serialIn(11); // and Y direction
digitalWrite(enablePin, HIGH); // deselect chip
calcAngle = atan2(-Y_Data , X_Data) / M_PI * 180; // angle is atan(-y/x)
if(calcAngle < 0)
calcAngle = calcAngle + 360; // angle from 0 to 259 instead of plus/minus 180
return calcAngle;
}
void serialOut(int value, int numberOfBits)
{
for(int i = numberOfBits; i > 0; i--) // shift the MSB first
{
digitalWrite(clockPin, LOW);
if(bitRead(value, i-1) == 1)
digitalWrite(dataPin, HIGH);
else
digitalWrite(dataPin, LOW);
digitalWrite(clockPin, HIGH);
}
}
int serialIn(int numberOfBits)
{
6.16 Detecting Direction | 209
int result = 0;
pinMode(dataPin, INPUT);
for(int i = numberOfBits; i > 0; i--) // get the MSB first
{
digitalWrite(clockPin, HIGH);
if (digitalRead(dataPin) == HIGH)
result = (result << 1) + 1;
else
result = (result << 1) + 0;
digitalWrite(clockPin, LOW);
}
// the following converts the result to a twos-complement negative number
// if the most significant bit in the 11 bit data is 1
if(bitRead(result, 11) == 1)
result = (B11111000 << 8) | result; // twos complement negation
}
return result;
)LJXUH+0%FRPSDVVFRQQHFWLRQV
210 | Chapter 6:ಗGetting Input from Sensors
Discussion
7KHFRPSDVVPRGXOHSURYLGHVPDJQHWLFILHOGLQWHQVLWLHVRQWZRSHUSHQGLFXODUD[HV [
DQG\ 7KHVHYDOXHVYDU\DVWKHFRPSDVVRULHQWDWLRQLVFKDQJHGZLWKUHVSHFWWRWKH
(DUWK¦VPDJQHWLFILHOG PDJQHWLFQRUWK 7KHGDWDVKHHWIRUWKHGHYLFHWHOOV\RXZKDWYDOXHVWRVHQGWRUHVHWWKHFRPSDVVFKHFN
LIDYDOLGUHDGLQJLVUHDG\ LIVRLWZLOOWUDQVPLWLW 7KHVNHWFKXVHVWKHIXQFWLRQVserialIn()DQGserialOut()WRKDQGOHWKHSLQPDQLSX
ODWLRQVWKDWVHQGDQGUHFHLYHPHVVDJHV
7KHFRPSDVVPRGXOHLVLQLWLDOL]HGLQWRDNQRZQVWDWHLQWKH reset()IXQFWLRQFDOOHG
IURPsetup()7KHstartMeasurement()IXQFWLRQLQLWLDWHVWKHPHDVXUHPHQWDQGDIWHUD
EULHI GHOD\ WKH readStatus() IXQFWLRQ LQGLFDWHV LI WKH GDWD LV UHDG\ $ YDOXH RI 0 LV
UHWXUQHGLIWKHPHDVXUHPHQWLVQRWUHDG\RU 12 ELQDU\ LIWKHFRPSDVVLVUHDG\
WRWUDQVPLWGDWD
(OHYHQELWVRIGDWDDUHUHDGLQWRWKHX_DataDQGY_DataYDULDEOHV,I\RXXVHDGLIIHUHQW
GHYLFH\RXZLOOQHHGWRFKHFNWKHGDWDVKHHWWRVHHKRZPDQ\ELWVDQGLQZKDWIRUPDW
WKHGDWDLVVHQWX_DataDQGY_DataVWRUHWKHPDJQHWLFILHOGUHDGLQJVDQGWKHDQJOHWR
PDJQHWLFQRUWKLVFDOFXODWHGDVIROORZV5DGLDQV DUFWDQ [\
7KLVLVLPSOHPHQWHGLQWKHVNHWFKLQWKHOLQH
angle = 180 * (atan2(-1 * Y_Data , X_Data) / M_PI);
7R PDNH D VHUYR IROORZ WKH FRPSDVV GLUHFWLRQ RYHU WKH ILUVW GHJUHHV DGG WKH
IROORZLQJ
#include <Servo.h>
Servo myservo;
LQsetup
myservo.attach(8);
DQGLQloopDIWHUWKHDQJOHLVFDOFXODWHG
angle = constrain(angle, 0,180); // the servo is driven only up to 180
degrees
myservo.write(angle);
6.17 Getting Input from a Game Control Pad (PlayStation)
Problem
<RXZDQWWRUHVSRQGWRMR\VWLFNSRVLWLRQVRUEXWWRQSUHVVHVIURPDJDPHFRQWUROSDG
6.17 Getting Input from a Game Control Pad (PlayStation) | 211
Solution
7KLVUHFLSHXVHVD6RQ\3OD\6WDWLRQ¡VW\OHFRQWUROOHUZLWKWKH36;OLEUDU\DWKWWS
ZZZDUGXLQRFFSOD\JURXQG0DLQ36;/LEUDU\)LJXUHVKRZVWKHFRQQHFWLRQV
)LJXUH3OD\6WDWLRQFRQWUROOHUSOXJFRQQHFWHGWR$UGXLQR
7KHVNHWFKXVHVWKH6HULDO0RQLWRUWRVKRZZKLFKEXWWRQLVSUHVVHG
/*
* PSX sketch
*
* Display joystick and button values
* uses PSX library written by Kevin Ahrendt
* http://www.arduino.cc/playground/Main/PSXLibrary
*/
#include <wProgram.h>
#include <Psx.h>
// Includes the Psx Library
Psx Psx;
const int dataPin = 5;
const int cmndPin = 4;
const int attPin
= 3;
const int clockPin = 2;
const int psxDelay = 50;
// Create an instance of the Psx library
// determine the clock delay in microseconds
unsigned int data = 0;
// data stores the controller response
void setup()
{
// initialize the Psx library
Psx.setupPins(dataPin, cmndPin, attPin, clockPin, psxDelay);
Serial.begin(9600); // results will be displayed on the Serial Monitor
}
212 | Chapter 6:ಗGetting Input from Sensors
void loop()
{
data = Psx.read();
// get the psx controller button data
// check the button bits to see if a button is pressed
if(data & psxLeft)
Serial.println("left button");
if(data & psxDown)
Serial.println("down button");
if(data & psxRight)
Serial.println("right button");
if(data & psxUp)
Serial.println("up button");
if(data & psxStrt)
Serial.println("start button");
if(data & psxSlct)
Serial.println("select button");
delay(100);
}
Discussion
*DPHFRQWUROOHUVSURYLGHLQIRUPDWLRQLQPDQ\GLIIHUHQWZD\V0RVWUHFHQWFRQWUROOHUV
FRQWDLQFKLSVWKDWUHDGWKHVZLWFKHVDQGMR\VWLFNLQWKHFRQWUROOHUDQGFRPPXQLFDWH
WKHLQIRUPDWLRQXVLQJDSURWRFROGHSHQGLQJRQWKHJDPHSODWIRUP2OGHUFRQWUROOHUV
DUHPRUHOLNHO\WRJLYHGLUHFWDFFHVVWRVZLWFKHVDQGMR\VWLFNVXVLQJFRQQHFWRUVZLWK
PDQ\ FRQQHFWLRQV7KH ODWHVW ZDYH RI JDPH SODWIRUPV XVHV 86%DVWKHFRQQHFWLRQ
7KHVHDUHPRUHGLIILFXOWWRZRUNZLWKXVLQJ$UGXLQR
See Also
5HFLSH5HFLSH
3OD\6WDWLRQ FRQWUROOHU SURWRFRO KWWSZZZJDPHV[FRPFRQWUROGDWDSV[FRQWSV[FRQW
KWP
6.18 Reading Acceleration
Problem
<RXZDQWWRUHVSRQGWRDFFHOHUDWLRQIRUH[DPSOHWRGHWHFWZKHQVRPHWKLQJVWDUWVRU
VWRSVPRYLQJ2U\RXZDQWWRGHWHFWKRZVRPHWKLQJLVRULHQWHGZLWKUHVSHFWWRWKH
(DUWK¦VVXUIDFH PHDVXUHDFFHOHUDWLRQGXHWRJUDYLW\ 6.18 Reading Acceleration | 213
Solution
/LNHPDQ\RIWKHVHQVRUVGLVFXVVHGLQWKLVFKDSWHUWKHUHLVDZLGHFKRLFHRIGHYLFHVDQG
PHWKRGVRIFRQQHFWLRQ5HFLSHJDYHDQH[DPSOHRIDYLUWXDOMR\VWLFNXVLQJWKH
DFFHOHURPHWHULQWKH:LLQXQFKXFNWRIROORZKDQGPRYHPHQWV5HFLSHKDVPRUH
LQIRUPDWLRQRQXVLQJWKH:LLQXQFKXFNDFFHOHURPHWHU7KHUHFLSHKHUHXVHVDQDORJ
RXWSXW SURSRUWLRQDO WR DFFHOHUDWLRQ 6XLWDEOH GHYLFHV LQFOXGH WKH $';/&( 6)
6(1 $';/ 6)6(1 DQG00$4 6)6(1 ¢FKHFNWKH
6SDUN)XQDFFHOHURPHWHUVHOHFWLRQJXLGHRQWKH6SDUN)XQZHEVLWHIRUPRUHLQIRUPDWLRQ
)LJXUHVKRZVWKHFRQQHFWLRQVIRUWKH[DQG\D[HVRIDQDQDORJDFFHOHURPHWHU
)LJXUH&RQQHFWLRQVIRU[DQG\D[HVRIDQDQDORJDFFHOHURPHWHU
&KHFNWKHGDWDVKHHWIRU\RXUGHYLFHWRHQVXUHWKDW\RXGRQ¦WH[FHHG
WKHPD[LPXPYROWDJH0DQ\DFFHOHURPHWHUVDUHGHVLJQHGIRU9RS
HUDWLRQDQGFDQEHGDPDJHGLIFRQQHFWHGWRWKH9SRZHUFRQQHFWLRQ
RQDQ$UGXLQRERDUG
214 | Chapter 6:ಗGetting Input from Sensors
7KHVLPSOHVNHWFKKHUHXVHVWKH$';/WRGLVSOD\WKHDFFHOHUDWLRQLQWKH[DQG
\D[HV
/*
accel sketch
simple sketch to output values on the x- and y-axes
*/
const int xPin = 0;
const int yPin = 1;
void setup()
{
Serial.begin(9600);
}
// analog input pins
void loop()
{
int xValue;
int yValue;
// note the higher than usual serial speed
// values from accelerometer stored here
xValue = analogRead(xPin);
yValue = analogRead(yPin);
Serial.print("X value = ");
Serial.println(xValue);
Serial.print("Y value = ");
Serial.println(yValue);
delay(100);
}
Discussion
<RXFDQXVHWHFKQLTXHVIURPWKHSUHYLRXVUHFLSHVWRH[WUDFWLQIRUPDWLRQIURPWKHDF
FHOHURPHWHUUHDGLQJV<RXPLJKWQHHGWRFKHFNIRUDWKUHVKROGWRZRUNRXWPRYHPHQW
<RXPD\QHHGWRDYHUDJHYDOXHVOLNHWKHVRXQGH[DPSOHWRJHWYDOXHVWKDWDUHRIXVH,I
WKHDFFHOHURPHWHULVUHDGLQJKRUL]RQWDOO\\RXFDQXVHWKHYDOXHVGLUHFWO\WRZRUNRXW
PRYHPHQW,ILWLVUHDGLQJYHUWLFDOO\\RXZLOOQHHGWRWDNHLQWRDFFRXQWWKHHIIHFWVRI
JUDYLW\RQWKHYDOXHV7KLVLVVLPLODUWRWKH'&RIIVHWLQWKHDXGLRH[DPSOHEXWLWFDQ
EHFRPSOLFDWHGDVWKHDFFHOHURPHWHUPD\EHFKDQJLQJRULHQWDWLRQVRWKDWWKHHIIHFWRI
JUDYLW\LVQRWDFRQVWDQWYDOXHIRUHDFKUHDGLQJ
See Also
6SDUN)XQ VHOHFWLRQ JXLGH KWWSZZZVSDUNIXQFRPFRPPHUFHWXWRULDOBLQIRSKS"WXWR
ULDOVBLG 6.18 Reading Acceleration | 215
CHAPTER 7
Visual Output
7.0 Introduction
9LVXDORXWSXWOHWVWKH$UGXLQRVKRZRIIDQGWRZDUGWKDWHQGWKH$UGXLQRVXSSRUWVD
EURDGUDQJHRI/('GHYLFHV%HIRUHGHOYLQJLQWRWKHUHFLSHVLQWKLVFKDSWHUZH¦OOGLVFXVV
$UGXLQRGLJLWDODQGDQDORJRXWSXW7KLVLQWURGXFWLRQZLOOEHDJRRGVWDUWLQJSRLQWLI
\RX DUH QRW \HW IDPLOLDU ZLWK XVLQJ GLJLWDO DQG DQDORJ RXWSXWV digitalWrite DQG
analogWrite Digital Output
$OO WKH SLQV WKDW FDQ EH XVHG IRU GLJLWDO LQSXW FDQ DOVR EH XVHG IRU GLJLWDO RXWSXW
&KDSWHU SURYLGHG DQ RYHUYLHZ RI WKH $UGXLQR SLQ OD\RXW \RX PD\ ZDQW WR ORRN
WKURXJKWKHLQWURGXFWLRQVHFWLRQLQWKDWFKDSWHULI\RXDUHXQIDPLOLDUZLWKFRQQHFWLQJ
WKLQJVWR$UGXLQRSLQV
'LJLWDORXWSXWFDXVHVWKHYROWDJHRQDSLQWREHHLWKHUKLJK YROWV RUORZ YROWV 8VHWKH digitalWrite(outputPin, value)IXQFWLRQWRWXUQVRPHWKLQJRQRURII7KH
IXQFWLRQKDVWZRSDUDPHWHUVoutputPinLVWKHSLQWRFRQWURODQG valueLVHLWKHUHIGH
YROWV RULOW YROWV )RUWKHSLQYROWDJHWRUHVSRQGWRWKLVFRPPDQGWKHSLQPXVWKDYHEHHQVHWLQRXWSXW
PRGHXVLQJWKHpinMode(outputPin, OUTPUT)FRPPDQG7KHVNHWFKLQ5HFLSHSUR
YLGHVDQH[DPSOHRIKRZWRXVHGLJLWDORXWSXW
Analog Output
$QDORJUHIHUVWROHYHOVWKDWFDQEHJUDGXDOO\YDULHGXSWRWKHLUPD[LPXPOHYHO WKLQNRI
OLJKWGLPPHUVDQGYROXPHFRQWUROV $UGXLQRKDVDQanalogWriteIXQFWLRQWKDWFDQEH
XVHGWRFRQWUROVXFKWKLQJVDVWKHLQWHQVLW\RIDQ/('FRQQHFWHGWRWKH$UGXLQR
7KHanalogWriteIXQFWLRQLVQRWWUXO\DQDORJDOWKRXJKLWFDQEHKDYHOLNHDQDORJDV\RX
ZLOO VHH analogWrite XVHV D WHFKQLTXH FDOOHG 3XOVH :LGWK 0RGXODWLRQ 3:0 WKDW
HPXODWHVDQDQDORJVLJQDOXVLQJGLJLWDOSXOVHV
217
3:0ZRUNVE\YDU\LQJWKHSURSRUWLRQRIWKHSXOVHV¦RQWLPHWRRIIWLPHDVVKRZQLQ
)LJXUH/RZOHYHORXWSXWLVHPXODWHGE\SURGXFLQJSXOVHVWKDWDUHRQIRURQO\D
VKRUWSHULRGRIWLPH+LJKHUOHYHORXWSXWLVHPXODWHGZLWKSXOVHVWKDWDUHRQPRUHWKDQ
WKH\DUHRII:KHQWKHSXOVHVDUHUHSHDWHGTXLFNO\HQRXJK DOPRVWWLPHVSHUVHFRQG
RQ$UGXLQR WKHSXOVLQJFDQQRWEHGHWHFWHGE\KXPDQVHQVHVDQGWKHRXWSXWIURP
WKLQJVVXFKDV/('VORRNVOLNHLWLVEHLQJVPRRWKO\YDULHGDVWKHSXOVHUDWHLVFKDQJHG
)LJXUH3:0RXWSXWIRUYDULRXVDQDORJ:ULWHYDOXHV
$UGXLQRKDVDOLPLWHGQXPEHURISLQVWKDWFDQEHXVHGIRUDQDORJRXWSXW2QDVWDQGDUG
ERDUG\RXFDQXVHSLQVDQG2QWKH$UGXLQR0HJDERDUG\RXFDQ
XVHSLQVWKURXJKIRUDQDORJRXWSXW0DQ\RIWKHUHFLSHVWKDWIROORZXVHSLQVWKDW
FDQEHXVHGIRUERWKGLJLWDODQGDQDORJWRPLQLPL]HUHZLULQJLI\RXZDQWWRWU\RXW
GLIIHUHQWUHFLSHV,I\RXZDQWWRVHOHFWGLIIHUHQWSLQVIRUDQDORJRXWSXWUHPHPEHUWR
FKRRVHRQHRIWKHVXSSRUWHGanalogWriteSLQV RWKHUSLQVZLOOQRWJLYHDQ\RXWSXW Controlling Light
&RQWUROOLQJOLJKWXVLQJGLJLWDORUDQDORJRXWSXWLVDYHUVDWLOHHIIHFWLYHDQGZLGHO\XVHG
PHWKRGIRUSURYLGLQJXVHULQWHUDFWLRQ6LQJOH/('VDUUD\VDQGQXPHULFGLVSOD\VDUH
218 | Chapter 7:ಗVisual Output
FRYHUHGH[WHQVLYHO\LQWKHUHFLSHVLQWKLVFKDSWHU/&'WH[WDQGJUDSKLFDOGLVSOD\VUH
TXLUHGLIIHUHQWWHFKQLTXHVDQGDUHFRYHUHGLQ&KDSWHU
LED specifications
$Q/('LVDVHPLFRQGXFWRUGHYLFH GLRGH ZLWKWZROHDGVDQDQRGHDQGDFDWKRGH
:KHQWKHYROWDJHRQWKHDQRGHLVPRUHSRVLWLYHWKDQWKDWRQWKHFDWKRGH E\DQDPRXQW
FDOOHGWKHIRUZDUGYROWDJH WKHGHYLFHHPLWVOLJKW SKRWRQV 7KHDQRGHLVXVXDOO\WKH
ORQJHUOHDGDQGWKHUHLVRIWHQDIODWVSRWRQWKHKRXVLQJWRLQGLFDWHWKHFDWKRGH VHH
)LJXUH 7KH/('FRORUDQGWKHH[DFWYDOXHRIWKHIRUZDUGYROWDJHGHSHQGRQWKH
FRQVWUXFWLRQRIWKHGLRGH
$W\SLFDOUHG/('KDVDIRUZDUGYROWDJHRIDURXQGYROWV,IWKHYROWDJHRQWKHDQRGH
LVQRWYROWVPRUHSRVLWLYHWKDQWKHFDWKRGHQRFXUUHQWZLOOIORZWKURXJKWKH/('
DQGQROLJKWZLOOEHSURGXFHG:KHQWKHYROWDJHRQWKHDQRGHEHFRPHVYROWVPRUH
SRVLWLYHWKDQWKDWRQWKHFDWKRGHWKH/('£WXUQVRQ¤ FRQGXFWV DQGHIIHFWLYHO\EH
FRPHVDVKRUWFLUFXLW<RXPXVWOLPLWWKHFXUUHQWZLWKDUHVLVWRURUWKH/('ZLOO VRRQHU
RUODWHU EXUQRXW5HFLSHVKRZV\RXKRZWRFDOFXODWHYDOXHVIRUFXUUHQWOLPLWLQJ
UHVLVWRUV
<RXPD\QHHGWRFRQVXOWDQ/('GDWDVKHHWWRVHOHFWWKHFRUUHFW/('IRU\RXUDSSOL
FDWLRQ SDUWLFXODUO\ WR GHWHUPLQH YDOXHV IRU IRUZDUG YROWDJH DQG PD[LPXP FXUUHQW
7DEOHVDQGVKRZWKHPRVWLPSRUWDQWILHOGV\RXVKRXOGORRNIRURQDQ/('GDWD
VKHHW
7DEOH.H\GDWDVKHHWVSHFLILFDWLRQVDEVROXWHPD[LPXPUDWLQJV
Parameter
Symbol
Rating
Units
Comment
Forward current
If
25
mA
The maximum continuous current for this LED
Peak forward current (1/10 duty @
1 KHz)
If
160
mA
The maximum pulsed current (given here for a
pulse that is 1/10 on and 9/10 off)
7DEOH.H\GDWDVKHHWVSHFLILFDWLRQVHOHFWURRSWLFDOFKDUDFWHULVWLFV
Parameter
Symbol
Rating
Units
Comment
Luminous intensity
Iv
2
mcd
If = 2 mA - brightness with 2 mA current
Iv
40
mcd
If = 20 mA - brightness with 20 mA current
Viewing angle
120
Degrees
The beam angle
Wavelength
620
nm
The dominant or peak wavelength (color)
1.8
Volts
The voltage across the LED when on
Forward voltage
Vf
$UGXLQRSLQVFDQVXSSO\XSWRP$RIFXUUHQW7KLVLVSOHQW\IRUDW\SLFDOPHGLXP
LQWHQVLW\/('EXWQRWHQRXJKWRGULYHWKHKLJKHUEULJKWQHVV/('VRUPXOWLSOH/('V
FRQQHFWHGWRDVLQJOHSLQ5HFLSHVKRZVKRZWRXVHDWUDQVLVWRUWRLQFUHDVHWKH
FXUUHQWWKURXJKWKH/('
7.0 Introduction | 219
0XOWLFRORU/('VFRQVLVWRIWZRRUPRUH/('VLQRQHSK\VLFDOSDFNDJH7KHVHPD\KDYH
PRUHWKDQWZROHDGVWRHQDEOHVHSDUDWHFRQWURORIWKHGLIIHUHQWFRORUV7KHUHDUHPDQ\
SDFNDJHYDULDQWVVR\RXVKRXOGFKHFNWKHGDWDVKHHWIRU\RXU/('WRGHWHUPLQHKRZ
WRFRQQHFWWKHOHDGV
6HOIFRORUFKDQJLQJPXOWLFRORU/('VZLWKDQLQWHJUDWHGFKLSFDQQRWEH
FRQWUROOHG LQ DQ\ ZD\ \RX FDQ¦W FKDQJH WKHLU FRORUV IURP $UGXLQR
%HFDXVH3:0UDSLGO\F\FOHVWKHSRZHURQDQGRII\RXDUHHIIHFWLYHO\
UHERRWLQJWKHLQWHJUDWHGFKLSPDQ\WLPHVHDFKVHFRQGVRWKHVH/('V
DUHXQVXLWDEOHIRU3:0DSSOLFDWLRQVDVZHOO
Multiplexing
$SSOLFDWLRQVWKDWQHHGWRFRQWUROPDQ\/('VFDQXVHDWHFKQLTXHFDOOHGPXOWLSOH[LQJ
0XOWLSOH[LQJZRUNVE\VZLWFKLQJJURXSVRI/('V XVXDOO\DUUDQJHGLQURZVRUFROXPQV
LQVHTXHQFH5HFLSHVKRZVKRZLQGLYLGXDO/('V HLJKW/('VSHUGLJLWLQFOXG
LQJGHFLPDOSRLQW ZLWKIRXUGLJLWVFDQEHGULYHQZLWKMXVWSLQV(LJKWSLQVGULYHD
GLJLW VHJPHQW IRU DOO WKH GLJLWV DQG IRXU SLQV VHOHFW ZKLFK GLJLW LV DFWLYH 6FDQQLQJ
WKURXJKWKHGLJLWVTXLFNO\HQRXJK DWOHDVWWLPHVSHUVHFRQG FUHDWHVWKHLPSUHVVLRQ
WKDWWKHOLJKWVUHPDLQRQUDWKHUWKDQSXOVLQJWKURXJKWKHSKHQRPHQRQRISHUVLVWHQFH
RIYLVLRQ
&KDUOLHSOH[LQJXVHVPXOWLSOH[LQJDORQJZLWKWKHIDFWWKDW/('VKDYHSRODULW\ WKH\RQO\
LOOXPLQDWHZKHQWKHDQRGHLVPRUHSRVLWLYHWKDQWKHFDWKRGH WRVZLWFKEHWZHHQWZR
/('VE\UHYHUVLQJWKHSRODULW\
7.1 Connecting and Using LEDs
Problem
<RXZDQWWRFRQWURORQHRUPRUH/('VDQGVHOHFWWKHFRUUHFWFXUUHQWOLPLWLQJUHVLVWRU
VRWKDW\RXGRQRWGDPDJHWKH/('V
Solution
7XUQLQJDQ/('RQDQGRIILVHDV\WRGRZLWK$UGXLQRDQGVRPHRIWKHUHFLSHVLQ
SUHYLRXVFKDSWHUVKDYHLQFOXGHGWKLVFDSDELOLW\ VHH 5HFLSHIRUDQH[DPSOHWKDW
FRQWUROVWKHEXLOWLQ/('RQSLQ 7KHUHFLSHKHUHSURYLGHVJXLGDQFHRQFKRRVLQJ
DQGXVLQJH[WHUQDO/('V)LJXUHVKRZVWKHZLULQJIRUWKUHH/('VEXW\RXFDQUXQ
WKLVVNHWFKZLWKMXVWRQHRUWZR
220 | Chapter 7:ಗVisual Output
)LJXUH&RQQHFWLQJH[WHUQDO/('V
7KHVFKHPDWLFV\PEROIRUWKHFDWKRGH WKHQHJDWLYHSLQ LVNQRWF7KH
VFKHPDWLFV\PEROFLVXVHGIRUDFDSDFLWRU
7KHIROORZLQJVNHWFKOLJKWVXSWKUHH/('VFRQQHFWHGWRSLQVDQGLQVHTXHQFH
IRURQHVHFRQG
/*
LEDs sketch
Blink three LEDs each connected to a different digital pin
*/
const int firstLedPin = 3;
const int secondLedPin = 5;
const int thirdLedPin = 6;
void setup()
{
pinMode(firstLedPin, OUTPUT);
pinMode(secondLedPin, OUTPUT);
pinMode(thirdLedPin, OUTPUT);
}
// choose the pin for each of the LEDs
// declare LED pins as output
// declare LED pins as output
// declare LED pins as output
void loop()
{
// flash each of the LEDs for 1000 milliseconds (1 second)
blinkLED(firstLedPin, 1000);
blinkLED(secondLedPin, 1000);
blinkLED(thirdLedPin, 1000);
}
7.1 Connecting and Using LEDs | 221
// blink the LED on the given pin for the duration in milliseconds
void blinkLED(int pin, int duration)
{
digitalWrite(pin, HIGH);
// turn LED on
delay(duration);
digitalWrite(pin, LOW);
// turn LED off
delay(duration);
}
7KHVNHWFKVHWVWKHSLQVFRQQHFWHGWR/('VDVRXWSXWLQWKHsetupIXQFWLRQ7KHloop
IXQFWLRQFDOOV blinkLEDWRIODVKWKH/('IRUHDFKRIWKHWKUHHSLQV blinkLEDVHWVWKH
LQGLFDWHGSLQHIGHIRURQHVHFRQG PLOOLVHFRQGV Discussion
%HFDXVHWKHDQRGHVDUHFRQQHFWHGWR$UGXLQRSLQVDQGWKHFDWKRGHVDUHFRQQHFWHGWR
JURXQGWKH/('VZLOOOLJKWZKHQWKHSLQJRHVHIGHDQGZLOOEHRIIZKHQWKHSLQLVORZ
,I\RXKDGFRQQHFWHGWKH/('VWKHRWKHUZD\DURXQG WKHFDWKRGHVWRWKHSLQVDQGWKH
DQRGHVWRJURXQG WKH/('VZRXOGOLJKWZKHQWKHSLQJRHVLOW WKHYLVXDOHIIHFWZRXOG
UHYHUVH¢RQHRIWKH/('VZRXOGWXUQRIIIRUDVHFRQGZKLOHWKHRWKHUWZRZRXOGEHOLW /('VUHTXLUHDVHULHVUHVLVWRUWRFRQWUROWKHFXUUHQWRUWKH\FDQTXLFNO\
EXUQRXW7KHEXLOWLQ/('RQSLQKDVDUHVLVWRURQWKHFLUFXLWERDUG
([WHUQDO/('VQHHGWREHFRQQHFWHGWKURXJKDVHULHVUHVLVWRURQHLWKHU
WKHDQRGHRUWKHFDWKRGH
$UHVLVWRULQVHULHVZLWKWKH/('LVXVHGWRFRQWUROWKHDPRXQWRIFXUUHQWWKDWZLOOIORZ
ZKHQWKH/('FRQGXFWV7RFDOFXODWHWKHUHVLVWRUYDOXH\RXQHHGWRNQRZWKHLQSXW
SRZHU VXSSO\ YROWDJH 9V XVXDOO\ YROWV WKH /(' IRUZDUG YROWDJH 9I DQG WKH
DPRXQWRIFXUUHQW , WKDW\RXZDQWWRIORZWKURXJKWKH/('
7KHIRUPXODIRUWKHUHVLVWDQFHLQRKPV NQRZQDV2KP¦VODZ LV5 9V9I ,
)RUH[DPSOHGULYLQJDQ/('ZLWKDIRUZDUGYROWDJHRIYROWVZLWKP$RIFXUUHQW
XVLQJDQLQSXWVXSSO\YROWDJHRIYROWVZRXOGXVHWKHIROORZLQJYDOXHV
9V IRUD9$UGXLQRERDUG
9I WKHIRUZDUGYROWDJHRIWKH/('
, PLOOLDPS>P$@LVRQHRQHWKRXVDQGWKRIDQDPSVRP$LV
DPSV
7KHYROWDJHDFURVVWKH/('ZKHQLWLVRQ 9V9I LVZKLFKLVYROWV
7KHUHIRUHWKHFDOFXODWLRQIRUWKHVHULHVUHVLVWRULVZKLFKLVRKPV
7KHYDOXHRIRKPVLVQRWDVWDQGDUGUHVLVWRUYDOXHVR\RXFDQURXQGWKLVXSWR
RKPV
222 | Chapter 7:ಗVisual Output
Download from Wow! eBook <www.wowebook.com>
7KHUHVLVWRULVVKRZQLQ)LJXUHFRQQHFWHGEHWZHHQWKHFDWKRGHDQGJURXQGEXWLW
FDQEHFRQQHFWHGWRWKHRWKHUVLGHRIWKH/('LQVWHDG EHWZHHQWKHYROWDJHVXSSO\DQG
WKHDQRGH $UGXLQRSLQVKDYHDPD[LPXPFXUUHQWRIP$,I\RXU/('QHHGV
PRUHFXUUHQWWKDQWKLV\RXVKRXOGXVHDWUDQVLVWRUWRVZLWFKWKH/('
DVVKRZQLQ5HFLSH
See Also
5HFLSH
7.2 Adjusting the Brightness of an LED
Problem
<RXZDQWWRFRQWUROWKHLQWHQVLW\RIRQHRUPRUH/('VIURP\RXUVNHWFK
Solution
&RQQHFWHDFK/('WRDQDQDORJ 3:0 RXWSXW8VHWKHZLULQJVKRZQLQ)LJXUH
7KHVNHWFKZLOOIDGHWKH/(' V IURPRIIWRPD[LPXPLQWHQVLW\DQGEDFNWRRIIZLWK
HDFKF\FOHWDNLQJDURXQGILYHVHFRQGV
/*
* LedBrightness sketch
* controls the brightness of LEDs on analog output ports
*/
const int firstLed
const int secondLed
const int thirdLed
= 3;
= 5;
= 6;
// specify the pin for each of the LEDs
int brightness = 0;
int increment = 1;
void setup()
{
// pins driven by analogWrite do not need to be declared as outputs
}
void loop()
{
if(brightness > 255)
{
increment = -1; // count down after reaching 255
}
else if(brightness < 1)
{
increment = 1; // count up after dropping back down to 0
7.2 Adjusting the Brightness of an LED | 223
Download from Wow! eBook <www.wowebook.com>
}
brightness = brightness + increment; // increment (or decrement sign is minus)
// write the brightness value to the LEDs
analogWrite(firstLed, brightness);
analogWrite(secondLed, brightness);
analogWrite(thirdLed, brightness );
}
delay(10); // 10ms for each step change means 2.55 secs to fade up or down
Discussion
7KLVXVHVWKHVDPHZLULQJDVWKHSUHYLRXVVNHWFKEXWKHUHWKHSLQVDUHFRQWUROOHGXV
LQJanalogWriteLQVWHDGRIdigitalWriteanalogWriteXVHV3:0WRFRQWUROWKHSRZHU
WRWKH/('VHHWKLVFKDSWHU¦VLQWURGXFWLRQVHFWLRQIRUPRUHRQDQDORJRXWSXW
7KHVNHWFKIDGHVWKHOLJKWOHYHOXSDQGGRZQE\LQFUHDVLQJ RQIDGHXS RUGHFUHDVLQJ
RQIDGHGRZQ WKHYDOXHRIWKHbrightnessYDULDEOHLQHDFKSDVVWKURXJKWKHORRS7KLV
YDOXHLVJLYHQWRWKHanalogWriteIXQFWLRQIRUWKHWKUHHFRQQHFWHG/('V7KHPLQLPXP
YDOXHIRUanalogWriteLV0¢WKLVNHHSVWKHYROWDJHRQWKHSLQDW7KHPD[LPXPYDOXH
LVDQGWKLVNHHSVWKHSLQDWYROWV
:KHQWKH brightnessYDULDEOHUHDFKHVWKHPD[LPXPYDOXHLWZLOOVWDUWWRGHFUHDVH
EHFDXVHWKHVLJQRIWKHincrementLVFKDQJHGIURPWR DGGLQJWRDYDOXHLVWKH
VDPHDVVXEWUDFWLQJIURPWKDWYDOXH See Also
7KLVFKDSWHU¦VLQWURGXFWLRQGHVFULEHVKRZ$UGXLQRDQDORJRXWSXWZRUNV
7.3 Driving High-Power LEDs
Problem
<RXQHHGWRVZLWFKRUFRQWUROWKHLQWHQVLW\RI/('VWKDWQHHGPRUHSRZHUWKDQWKH
$UGXLQRSLQVFDQSURYLGH$UGXLQRSLQVFDQRQO\KDQGOHFXUUHQWXSWRP$
Solution
8VHDWUDQVLVWRUWRVZLWFKRQDQGRIIWKHFXUUHQWIORZLQJWKURXJKWKH/('V&RQQHFW
WKH/('DVVKRZQLQ)LJXUH<RXFDQXVHWKHVDPHFRGHDVVKRZQLQWKHSUHYLRXV
UHFLSHV MXVWPDNHVXUHWKHSLQVFRQQHFWHGWRWKHWUDQVLVWRUEDVHPDWFKWKHSLQQXPEHU
XVHGLQ\RXUVNHWFK 224 | Chapter 7:ಗVisual Output
)LJXUH8VLQJWUDQVLVWRUVWRGULYHKLJKFXUUHQW/('V
Discussion
7KH/('VPD\QHHGDSRZHUVRXUFHVHSDUDWHIURPWKH$UGXLQRLIWKHWRWDOFXUUHQWLV
PRUHWKDQDIHZKXQGUHGP$6HH$SSHQGL[&IRULQIRUPDWLRQRQXVLQJDQH[WHUQDO
SRZHUVXSSO\
5HPHPEHUWRFRQQHFWWKHJURXQGRIWKHH[WHUQDOVXSSO\WRWKH$UGXLQR
JURXQG
&XUUHQW LV DOORZHG WR IORZ IURP WKH FROOHFWRU WR WKH HPLWWHU ZKHQ WKH WUDQVLVWRU LV
VZLWFKHGRQ1RVLJQLILFDQWFXUUHQWIORZVZKHQWKHWUDQVLVWRULVRII7KH$UGXLQRFDQ
WXUQDWUDQVLVWRURQE\PDNLQJWKHYROWDJHRQDSLQHIGHZLWKdigitalWrite$UHVLVWRU
LVQHFHVVDU\EHWZHHQWKHSLQDQGWKHWUDQVLVWRUEDVHWRSUHYHQWWRRPXFKFXUUHQWIURP
IORZLQJ¢.RKPVLVDW\SLFDOYDOXH WKLVSURYLGHVP$RIFXUUHQWWRWKHEDVHRIWKH
WUDQVLVWRU 6HH$SSHQGL[%IRUDGYLFHRQKRZWRUHDGDGDWDVKHHWDQGSLFNDQGXVHD
WUDQVLVWRU<RXFDQDOVRXVHVSHFLDOL]HGLQWHJUDWHGFLUFXLWVVXFKDVWKH8/1$IRU
GULYLQJPXOWLSOHRXWSXWV7KHVHFRQWDLQVHYHQKLJKFXUUHQW DPS RXWSXWGULYHUV
7KHUHVLVWRUXVHGWROLPLWWKHFXUUHQWIORZWKURXJKWKH/('LVFDOFXODWHGXVLQJWKH
WHFKQLTXHJLYHQLQ5HFLSHEXW\RXPD\QHHGWRWDNHLQWRDFFRXQWWKDWWKHVRXUFH
YROWDJHZLOOEHUHGXFHGVOLJKWO\EHFDXVHRIWKHVPDOOYROWDJHGURSWKURXJKWKHWUDQVLVWRU
7.3 Driving High-Power LEDs | 225
7KLVZLOOXVXDOO\EHOHVVWKDQWKUHHIRXUWKVRIDYROW WKHDFWXDOYDOXHFDQEHIRXQGE\
ORRNLQJDWFROOHFWRUHPLWWHUVDWXUDWLRQYROWDJHVHH$SSHQGL[% +LJKFXUUHQW/('V ZDWWRUPRUH DUHEHVWGULYHQXVLQJDFRQVWDQWFXUUHQWVRXUFH DFLUFXLWWKDWDFWLYHO\
FRQWUROVWKHFXUUHQW WRPDQDJHWKHFXUUHQWWKURXJKWKH/('
See Also
:HEUHIHUHQFHIRUFRQVWDQWFXUUHQWGULYHUVKWWSEORJPDNH]LQHFRPDUFKLYH
FRQVWDQWBFXUUHQWBOHGBGULYHUKWPO
7.4 Adjusting the Color of an LED
Problem
<RXZDQWWRFRQWUROWKHFRORURIDQ5*%/('XQGHUSURJUDPFRQWURO
Solution
5*%/('VKDYHUHGJUHHQDQGEOXHHOHPHQWVLQDVLQJOHSDFNDJHZLWKHLWKHUWKHDQRGHV
FRQQHFWHG WRJHWKHU NQRZQ DV FRPPRQ DQRGH RU WKH FDWKRGHV FRQQHFWHG WRJHWKHU
NQRZQ DV FRPPRQ FDWKRGH 8VH WKH ZLULQJ LQ )LJXUH IRU FRPPRQ DQRGH WKH
DQRGHVDUHFRQQHFWHGWRYROWVDQGWKHFDWKRGHVDUHFRQQHFWHGWRSLQV 8VH)LJ
XUHLI\RXU5*%/('VDUHFRPPRQFDWKRGH
)LJXUH5*%FRQQHFWLRQV FRPPRQDQRGH
226 | Chapter 7:ಗVisual Output
7KLVVNHWFKFRQWLQXRXVO\IDGHVWKURXJKWKHFRORUVSHFWUXPE\YDU\LQJWKHLQWHQVLW\RI
WKHUHGJUHHQDQGEOXHHOHPHQWV
/*
* RGB_LEDs sketch
* RGB LEDs driven from analog output ports
*/
const int redPin
= 3;
// choose the pin for each of the LEDs
const int greenPin = 5;
const int bluePin = 6;
const boolean invert = true; // set true if common anode, false if common cathode
int color = 0; // a value from 0 to 255 representing the hue
int R, G, B; // the Red Green and Blue color components
void setup()
{
// pins driven by analogWrite do not need to be declared as outputs
}
void loop()
{
int brightness = 255; // 255 is maximum brightness
hueToRGB( color, brightness); // call function to convert hue to RGB
// write the RGB values to the pins
analogWrite(redPin, R);
analogWrite(greenPin, G);
analogWrite(bluePin, B );
}
color++;
if(color > 255)
color = 0;
delay(10);
// increment the color
//
// function to convert a color to its Red, Green, and Blue components.
void hueToRGB( int hue, int brightness)
{
unsigned int scaledHue = (hue * 6);
unsigned int segment = scaledHue / 256; // segment 0 to 5 around the color
wheel
unsigned int segmentOffset = scaledHue - (segment * 256); // position within
the segment
unsigned int complement = 0;
unsigned int prev = (brightness * ( 255 - segmentOffset)) / 256;
unsigned int next = (brightness * segmentOffset) / 256;
7.4 Adjusting the Color of an LED | 227
if(invert)
{
brightness = 255-brightness;
complement = 255;
prev = 255-prev;
next = 255-next;
}
switch(segment ) {
case 0:
// red
R = brightness;
G = next;
B = complement;
break;
case 1:
// yellow
R = prev;
G = brightness;
B = complement;
break;
case 2:
// green
R = complement;
G = brightness;
B = next;
break;
case 3:
// cyan
R = complement;
G = prev;
B = brightness;
break;
case 4:
// blue
R = next;
G = complement;
B = brightness;
break;
case 5:
// magenta
default:
R = brightness;
G = complement;
B = prev;
break;
}
}
Discussion
7KHFRORURIDQ5*%/('LVGHWHUPLQHGE\WKHUHODWLYHLQWHQVLW\RILWVUHGJUHHQDQG
EOXHHOHPHQWV7KHFRUHIXQFWLRQLQWKHVNHWFK hueToRGB KDQGOHVWKHFRQYHUVLRQRID
KXHYDOXHUDQJLQJIURPWRLQWRDFRUUHVSRQGLQJFRORUUDQJLQJIURPUHGWKURXJK
WREOXH7KHVSHFWUXPRIYLVLEOHFRORUVLVRIWHQUHSUHVHQWHGXVLQJDFRORUZKHHOFRQ
VLVWLQJ RI WKH SULPDU\ DQG VHFRQGDU\ FRORUV ZLWK WKHLU LQWHUPHGLDWH JUDGLHQWV 7KH
VSRNHVRIWKHFRORUZKHHOUHSUHVHQWLQJWKHVL[SULPDU\DQGVHFRQGDU\FRORUVDUHKDQGOHG
E\VL[caseVWDWHPHQWV7KHFRGHLQDcaseVWDWHPHQWLVH[HFXWHGLIWKHVHJPHQWYDULDEOH
228 | Chapter 7:ಗVisual Output
PDWFKHVWKHFDVHQXPEHUDQGLIVRWKH5*%YDOXHVDUHVHWDVDSSURSULDWHIRUHDFK
6HJPHQWLVUHGVHJPHQWLV\HOORZVHJPHQWLVJUHHQDQGVRRQ
,I\RXDOVRZDQWWRDGMXVWWKHEULJKWQHVV\RXFDQUHGXFHWKHYDOXHRIWKH brightness
YDULDEOH7KHIROORZLQJVKRZVKRZWRDGMXVWWKHEULJKWQHVVZLWKDYDULDEOHUHVLVWRURU
VHQVRUFRQQHFWHGDVVKRZQLQ)LJXUHRU)LJXUH
int brightness = map( analogRead(0),0,1023, 0, 255);
// get brightness from sensor
7KH brightnessYDULDEOHZLOOUDQJHLQYDOXHIURPWRDVWKHDQDORJLQSXWUDQJHV
IURPWRFDXVLQJWKH/('WRLQFUHDVHEULJKWQHVVDVWKHYDOXHLQFUHDVHV
See Also
5HFLSH5HFLSH
7.5 Sequencing Multiple LEDs: Creating a Bar Graph
Problem
<RXZDQWDQ/('EDUJUDSKWKDWOLJKWV/('VLQSURSRUWLRQWRDYDOXHLQ\RXUVNHWFK
RUDYDOXHUHDGIURPDVHQVRU
Solution
<RXFDQFRQQHFWWKH/('VDVVKRZQLQ)LJXUH XVLQJDGGLWLRQDOSLQVLI\RXZDQW
PRUH/('V )LJXUHVKRZVVL[/('VFRQQHFWHGRQFRQVHFXWLYHSLQV
)LJXUH6L[/('VZLWKFDWKRGHVFRQQHFWHGWR$UGXLQRSLQV
7.5 Sequencing Multiple LEDs: Creating a Bar Graph | 229
7KHIROORZLQJVNHWFKWXUQVRQDVHULHVRI/('VZLWKWKHQXPEHUEHLQJSURSRUWLRQDOWR
WKH YDOXH RI D VHQVRU FRQQHFWHG WR DQ DQDORJ LQSXW SRUW VHH )LJXUH RU )LJ
XUHWRVHHKRZDVHQVRULVFRQQHFWHG /*
Bargraph sketch
Turns on a series of LEDs proportional to a value of an analog sensor.
Six LEDs are controlled but you can change the number of LEDs by changing
the value of NbrLEDs and adding the pins to the ledPins array
*/
const int NbrLEDs = 6;
const int ledPins[] = { 2, 3, 4, 5, 6, 7};
const int analogInPin = 0; // Analog input pin connected to the variable
resistor
const int wait = 30;
// Swap values of the following two constants if cathodes are connected to Gnd
const boolean LED_ON = LOW;
const boolean LED_OFF = HIGH;
int sensorValue = 0;
int ledLevel = 0;
// value read from the sensor
// sensor value converted into LED 'bars'
void setup() {
for (int led = 0; led < NbrLEDs; led++)
{
pinMode(ledPins[led], OUTPUT); // make all the LED pins outputs
}
}
void loop() {
sensorValue = analogRead(analogInPin);
// read the analog in value
ledLevel = map(sensorValue, 0, 1023, 0, NbrLEDs); // map to the number of LEDs
for (int led = 0; led < NbrLEDs; led++)
{
if (led < ledLevel ) {
digitalWrite(ledPins[led], LED_ON);
// turn on pins less than the level
}
else {
digitalWrite(ledPins[led], LED_OFF);
// turn off pins higher than the
level:
}
}
}
Discussion
7KHSLQVFRQQHFWHGWR/('VDUHKHOGLQWKHDUUD\ ledPins7RFKDQJHWKHQXPEHURI
/('V\RXFDQDGG RUUHPRYH HOHPHQWVIURPWKLVDUUD\EXWPDNHVXUHWKHYDULDEOH
NbrLEDsLVWKHVDPHDVWKHQXPEHURIHOHPHQWV ZKLFKVKRXOGEHWKHVDPHDVWKHQXPEHU
RISLQV <RXFDQKDYHWKHFRPSLOHUFDOFXODWHWKHYDOXHRINbrLEDsIRU\RXE\UHSODFLQJ
WKLVOLQH
230 | Chapter 7:ಗVisual Output
const int NbrLEDs = 6;
ZLWKWKLVOLQH
const int NbrLEDs = sizeof(ledPins) / sizof(ledPins[0];
7KHsizeofIXQFWLRQUHWXUQVWKHVL]H QXPEHURIE\WHV RIDYDULDEOH¢LQWKLVFDVHWKH
QXPEHURIE\WHVLQWKHledPinsDUUD\%HFDXVHLWLVDQDUUD\RILQWHJHUV ZLWKWZRE\WHV
SHUHOHPHQW WKHWRWDOQXPEHURIE\WHVLQWKHDUUD\LVGLYLGHGE\WKHVL]HRIRQHHOHPHQW
sizeof(ledPins[0]) DQGWKLVJLYHVWKHQXPEHURIHOHPHQWV
7KH$UGXLQRmapIXQFWLRQLVXVHGWRFDOFXODWHWKHQXPEHURI/('VWKDWVKRXOGEHOLWDV
DSURSRUWLRQRIWKHVHQVRUYDOXH7KHFRGHORRSVWKURXJKHDFK/('WXUQLQJLWRQLI
WKHSURSRUWLRQDOYDOXHRIWKHVHQVRULVJUHDWHUWKDQWKH/('QXPEHU)RUH[DPSOHLI
WKHVHQVRUYDOXHLV0QRSLQVDUHOLWLIWKHVHQVRULVDWKDOIYDOXHKDOIDUHOLW:KHQWKH
VHQVRULVDWPD[LPXPYDOXHDOOWKH/('VDUHOLW
)LJXUHVKRZVDOOWKHDQRGHVFRQQHFWHGWRJHWKHU NQRZQDVFRPPRQDQRGH DQGWKH
FDWKRGHVFRQQHFWHGWRWKHSLQVWKHSLQVQHHGWREHLOWIRUWKH/('WROLJKW,IWKH/('V
KDYHWKHDQRGHVFRQQHFWHGWRSLQV DVVKRZQLQ)LJXUH DQGWKHFDWKRGHVDUHFRQ
QHFWHGWRJHWKHU NQRZQDVFRPPRQFDWKRGH WKH/('LVOLWZKHQWKHSLQJRHV HIGH
7KHVNHWFKLQWKLVUHFLSHXVHVWKHFRQVWDQWQDPHV LED_ONDQG LED_OFFWRPDNHLWHDV\
WRVHOHFWFRPPRQDQRGHRUFRPPRQFDWKRGHFRQQHFWLRQV7RFKDQJHWKHVNHWFKIRU
FRPPRQFDWKRGHFRQQHFWLRQVZDSWKHYDOXHVRIWKHVHFRQVWDQWVDVIROORZV
const boolean LED_ON = HIGH;
const boolean LED_OFF = LOW;
// HIGH is on when using common cathode connection
<RXPD\ZDQWWRVORZGRZQWKHGHFD\ UDWHRIFKDQJH LQWKHOLJKWVIRUH[DPSOHWR
HPXODWHWKHPRYHPHQWRIWKHLQGLFDWRURIDVRXQGYROXPHPHWHU+HUHLVDYDULDWLRQ
RQWKHVNHWFKWKDWVORZO\GHFD\VWKH/('EDUVZKHQWKHOHYHOGURSV
/*
*/
LED bar graph - decay version
const int NbrLEDs = sizeof(ledPins) / sizof(ledPins[0];
const int ledPins[] = { 2, 3, 4, 5, 6, 7};
const int analogInPin = 0; // Analog input pin connected to variable resistor
const int decay = 10;
// increasing this reduces decay rate of storedValue
int sensorValue = 0;
int storedValue = 0;
int ledLevel = 0;
// value read from the sensor
// the stored (decaying) sensor value
// value converted into LED 'bars'
void setup() {
for (int led = 0; led < NbrLEDs; led++)
{
pinMode(ledPins[led], OUTPUT); // make all the LED pins outputs
}
}
7.5 Sequencing Multiple LEDs: Creating a Bar Graph | 231
void loop() {
sensorValue = analogRead(analogInPin);
// read the analog in value
storedValue = max(sensorValue, storedValue); // only use sensor value if
higher
ledLevel = map(storedValue, 0, 1023, 0, NbrLEDs); // map to number of LEDs
for (int led = 0; led < NbrLEDs; led++)
{
if (led < ledLevel ) {
digitalWrite(ledPins[led], HIGH); // turn on pins less than the level
}
else {
digitalWrite(ledPins[led], LOW);
// turn off pins higher than the level
}
}
storedValue = storedValue - decay;
// decay the value
delay(10);
// wait 10 ms before next loop
}
7KHGHFD\LVKDQGOHGE\WKHOLQHWKDWXVHVWKH maxIXQFWLRQ7KLVUHWXUQVHLWKHUWKH
VHQVRUYDOXHRUWKHVWRUHGGHFD\HGYDOXHZKLFKHYHULVKLJKHU,IWKHVHQVRULVKLJKHU
WKDQ WKH GHFD\HG YDOXH WKLV LV VDYHG LQ storedValue 2WKHUZLVH WKH OHYHO RI
storedValueLVUHGXFHGE\WKHFRQVWDQW decayHDFKWLPHWKURXJKWKHORRS VHWWR
PLOOLVHFRQGV E\ WKH delay IXQFWLRQ ,QFUHDVLQJ WKH YDOXH RI WKH decay FRQVWDQW ZLOO
UHGXFHWKHWLPHIRUWKH/('VWRIDGHWRDOORII
See Also
6HH5HFLSHVDQGLI\RXQHHGJUHDWHUSUHFLVLRQLQ\RXUGHFD\WLPHV7KHWRWDO
WLPHWKURXJKWKHORRSLVDFWXDOO\JUHDWHUWKDQPLOOLVHFRQGVEHFDXVHLWWDNHVDQDG
GLWLRQDOPLOOLVHFRQGRUVRWRH[HFXWHWKHUHVWRIWKHORRSFRGH
5HFLSHH[SODLQVWKHmaxIXQFWLRQ
5HFLSHKDVPRUHRQUHDGLQJDVHQVRUZLWKWKHanalogReadIXQFWLRQ
5HFLSHGHVFULEHVWKHmapIXQFWLRQ
7.6 Sequencing Multiple LEDs: Making a Chase Sequence
(Knight Rider)
Problem
<RXZDQWWROLJKW/('VLQD£FKDVLQJOLJKWV¤VHTXHQFH DVVHHQRQWKH79VKRZ.QLJKW
5LGHU 232 | Chapter 7:ಗVisual Output
Solution
<RXFDQXVHWKHVDPHFRQQHFWLRQDVVKRZQLQ)LJXUH
/* KnightRider
*/
const int NbrLEDs = 6;
const int ledPins[] = {2, 3, 4, 5, 6, 7};
const int wait = 30;
void setup(){
for (int led = 0; led < NbrLEDs; led++)
{
pinMode(ledPins[led], OUTPUT);
}
}
void loop() {
for (int led = 0; led < NbrLEDs-1; led++)
{
digitalWrite(ledPins[led], HIGH);
delay(wait);
digitalWrite(ledPins[led + 1], HIGH);
delay(wait);
digitalWrite(ledPins[led], LOW);
delay(wait*2);
}
for (int led = NbrLEDs; led > 0; led--) {
digitalWrite(ledPins[led], HIGH);
delay(wait);
digitalWrite(ledPins[led - 1], HIGH);
delay(wait);
digitalWrite(ledPins[led], LOW);
delay(wait*2);
}
}
Discussion
7KLVFRGHLVVLPLODUWRWKHFRGHLQ5HFLSHH[FHSWWKHSLQVDUHWXUQHGRQDQGRIILQ
DIL[HGVHTXHQFHUDWKHUWKDQGHSHQGLQJRQDVHQVRUOHYHO7KHUHDUHWZRforORRSVWKH
ILUVWSURGXFHVWKHOHIWWRULJKWSDWWHUQE\OLJKWLQJXS/('VIURPOHIWWRULJKW7KLVORRS
VWDUWVZLWKWKHILUVW OHIWPRVW /('DQGVWHSVWKURXJKDGMDFHQW/('VXQWLOLWUHDFKHV
DQGLOOXPLQDWHVWKHULJKWPRVW/('7KHVHFRQGforORRSOLJKWVWKH/('VIURPULJKWWR
OHIWE\VWDUWLQJDWWKHULJKWPRVW/('DQGGHFUHPHQWLQJ GHFUHDVLQJE\RQH WKH/('
WKDWLVOLWXQWLOLWJHWVWRWKHILUVW ULJKWPRVW /('7KHGHOD\SHULRGLVVHWE\WKH wait
YDULDEOHDQGFDQEHFKRVHQWRSURYLGHWKHPRVWSOHDVLQJDSSHDUDQFH
7.6 Sequencing Multiple LEDs: Making a Chase Sequence (Knight Rider) | 233
7.7 Controlling an LED Matrix Using Multiplexing
Problem
<RXKDYHDPDWUL[RI/('VDQGZDQWWRPLQLPL]HWKHQXPEHURI$UGXLQRSLQVQHHGHG
WRWXUQ/('VRQDQGRII
Solution
7KLVVNHWFKXVHVDQ/('PDWUL[RI/('VZLWKDQRGHVFRQQHFWHGLQURZVDQGFDWK
RGHVLQFROXPQV DVLQWKH)XWXUOHF/('05 'XDOFRORU/('GLVSOD\VPD\EHHDVLHU
WRREWDLQDQG\RXFDQGULYHMXVWRQHRIWKHFRORUVLIWKDWLVDOO\RXQHHG)LJXUH
VKRZVWKHFRQQHFWLRQV
/*
matrixMpx sketch
Sequence LEDs starting from first column and row until all LEDS are lit
Multiplexing is used to control 64 LEDs with 16 pins
*/
const int columnPins[] = { 2, 3, 4, 5, 6, 7, 8, 9};
const int rowPins[]
= { 10,11,12,15,16,17,18,19};
int pixel
= 0;
int columnLevel = 0;
int rowLevel
= 0;
// 0 to 63 LEDs in the matrix
// pixel value converted into LED column
// pixel value converted into LED row
void setup() {
for (int i = 0; i < 8; i++)
{
pinMode(columnPins[i], OUTPUT);
pinMode(rowPins[i], OUTPUT);
}
}
// make all the LED pins outputs
void loop() {
pixel = pixel + 1;
if(pixel > 63)
pixel = 0;
columnLevel = pixel / 8;
// map to the number of columns
rowLevel = pixel % 8;
// get the fractional value
for (int column = 0; column < 8; column++)
{
digitalWrite(columnPins[column], LOW);
// connect this column to Ground
for(int row = 0; row < 8; row++)
{
if (columnLevel > column)
{
digitalWrite(rowPins[row], HIGH); // connect all LEDs in row to +5 volts
}
else if (columnLevel == column && rowLevel >= row)
234 | Chapter 7:ಗVisual Output
{
digitalWrite(rowPins[row], HIGH);
}
else
{
digitalWrite(columnPins[column], LOW); // turn off all LEDs in this row
}
delayMicroseconds(300);
// delay gives frame time of 20ms for 64 LEDs
digitalWrite(rowPins[row], LOW);
// turn off LED
}
digitalWrite(columnPins[column], HIGH);
from Ground
}
}
// disconnect this column
)LJXUH$Q/('PDWUL[FRQQHFWHGWRGLJLWDOSLQV
/('PDWUL[GLVSOD\VGRQRWKDYHDVWDQGDUGSLQRXWVR\RXPXVWFKHFN
WKHGDWDVKHHWIRU\RXUGLVSOD\:LUHWKHURZVRIDQRGHVDQGFROXPQV
RIFDWKRGHVDVVKRZQLQ)LJXUHRU)LJXUHEXWXVHWKH/('SLQ
QXPEHUVVKRZQLQ\RXUGDWDVKHHW
7.7 Controlling an LED Matrix Using Multiplexing | 235
Discussion
7KHUHVLVWRU¦VYDOXHPXVWEHFKRVHQWRHQVXUHWKDWWKHPD[LPXPFXUUHQWWKURXJKDSLQ
GRHVQRWH[FHHGP$%HFDXVHWKHFXUUHQWIRUXSWRHLJKW/('VFDQIORZWKURXJK
HDFKFROXPQSLQWKHPD[LPXPFXUUHQWIRUHDFK/('PXVWEHRQHHLJKWKRIP$
RUP$(DFK/('LQDW\SLFDOVPDOOUHGPDWUL[KDVDIRUZDUGYROWDJHRIDURXQG
YROWV&DOFXODWLQJWKHUHVLVWRUWKDWUHVXOWVLQP$ZLWKDIRUZDUGYROWDJHRIYROWV
JLYHVDYDOXHRIRKPV&KHFN\RXUGDWDVKHHWWRILQGWKHIRUZDUGYROWDJHRIWKH
PDWUL[\RXZDQWWRXVH(DFKFROXPQRIWKHPDWUL[LVFRQQHFWHGWKURXJKWKHVHULHV
UHVLVWRUWRDGLJLWDOSLQ:KHQWKHFROXPQSLQJRHVORZDQGDURZSLQJRHVKLJKWKH
FRUUHVSRQGLQJ/('ZLOOOLJKW)RUDOO/('VZKHUHWKHFROXPQSLQLVKLJKRULWVURZSLQ
LVORZQRFXUUHQWZLOOIORZWKURXJKWKH/('DQGLWZLOOQRWOLJKW
7KHforORRSVFDQVWKURXJKHDFKURZDQGFROXPQDQGWXUQVRQVHTXHQWLDO/('VXQWLO
DOO/('VDUHOLW7KHORRSVWDUWVZLWKWKHILUVWFROXPQDQGURZDQGLQFUHPHQWVWKHURZ
FRXQWHUXQWLODOO/('VLQWKDWURZDUHOLWLWWKHQPRYHVWRWKHQH[WFROXPQDQGVRRQ
OLJKWLQJDQRWKHU/('ZLWKHDFKSDVVWKURXJKWKHORRSXQWLODOOWKH/('VDUHOLW
<RXFDQFRQWUROWKHQXPEHURIOLW/('VLQSURSRUWLRQWRWKHYDOXHIURPDVHQVRU VHH
5HFLSHIRUFRQQHFWLQJDVHQVRUWRWKHDQDORJSRUW E\PDNLQJWKHIROORZLQJFKDQJHV
WRWKHVNHWFK
&RPPHQWRXWRUUHPRYHWKHVHWKUHHOLQHVIURPWKHEHJLQQLQJRIWKHORRS
pixel = pixel + 1;
if(pixel > 63)
pixel = 0;
5HSODFHWKHPZLWKWKHIROORZLQJOLQHVWKDWUHDGWKHYDOXHRIDVHQVRURQSLQDQGPDS
WKLVWRDQXPEHURISL[HOVUDQJLQJIURP]HURWR
int sensorValue = analogRead(0);
pixel =
map(sensorValue, 0, 1023, 0, 63);
(LED)
// read the analog in value
// map sensor value to pixel
<RXFDQWHVWWKLVZLWKDYDULDEOHUHVLVWRUFRQQHFWHGWRDQDORJLQSXWSLQFRQQHFWHGDV
VKRZQLQ)LJXUHLQ&KDSWHU7KHQXPEHURI/('VOLWZLOOEHSURSRUWLRQDOWRWKH
YDOXHRIWKHVHQVRU
7.8 Displaying Images on an LED Matrix
Problem
<RXZDQWWRGLVSOD\RQHRUPRUHLPDJHVRQDQ/('PDWUL[SHUKDSVFUHDWLQJDQDQL
PDWLRQHIIHFWE\TXLFNO\DOWHUQDWLQJPXOWLSOHLPDJHV
236 | Chapter 7:ಗVisual Output
Solution
7KLV6ROXWLRQFDQXVHWKHVDPHZLULQJDVLQ5HFLSH7KHVNHWFKFUHDWHVWKHHIIHFWRI
DKHDUWEHDWLQJE\EULHIO\OLJKWLQJ/('VDUUDQJHGLQWKHVKDSHRIDKHDUW$VPDOOKHDUW
IROORZHGE\DODUJHUKHDUWLVIODVKHGIRUHDFKKHDUWEHDW WKHLPDJHVORRNOLNH)LJXUH /*
* matrixMpxAnimation sketch
* animates two heart images to show a beating heart
*/
// the heart images are stored as bitmaps - each bit corresponds to an LED
// a 0 indicates the LED is off, 1 is on
byte bigHeart[] = {
B01100110,
B11111111,
B11111111,
B11111111,
B01111110,
B00111100,
B00011000,
B00000000};
byte smallHeart[] = {
B00000000,
B00000000,
B00010100,
B00111110,
B00111110,
B00011100,
B00001000,
B00000000};
const int columnPins[] = { 2, 3, 4, 5, 6, 7, 8, 9};
const int rowPins[]
= { 10,11,12,15,16,17,18,19};
void setup() {
for (int i = 0; i < 8; i++)
{
pinMode(rowPins[i], OUTPUT);
pinMode(columnPins[i], OUTPUT);
digitalWrite(columnPins[i], HIGH);
}
}
void loop() {
int pulseDelay = 800 ;
show(smallHeart, 80);
show(bigHeart, 160);
delay(pulseDelay);
// make all the LED pins outputs
// disconnect column pins from Ground
// milliseconds to wait between beats
// show the small heart image for 100 ms
// followed by the big heart for 200ms
// show nothing between beats
}
7.8 Displaying Images on an LED Matrix | 237
// routine to show a frame of an image stored in the array pointed to by the
image parameter.
// the frame is repeated for the given duration in milliseconds
void show( byte * image, unsigned long duration)
{
unsigned long start = millis();
// begin timing the animation
while (start + duration > millis())
// loop until the duration period
has passed
{
for(int row = 0; row < 8; row++)
{
digitalWrite(rowPins[row], HIGH);
// connect row to +5 volts
for(int column = 0; column < 8; column++)
{
boolean pixel = bitRead(image[row],column);
if(pixel == 1)
{
digitalWrite(columnPins[column], LOW); // connect column to Gnd
}
delayMicroseconds(300);
// a small delay for each LED
digitalWrite(columnPins[column], HIGH);
// disconnect column from Gnd
}
digitalWrite(rowPins[row], LOW);
// disconnect LEDs
}
}
}
)LJXUH7KHWZRKHDUWLPDJHVGLVSOD\HGRQHDFKEHDW
Discussion
&ROXPQVDQGURZVDUHPXOWLSOH[HG VZLWFKHG VLPLODUWR5HFLSHEXWKHUHWKHYDOXH
ZULWWHQWRWKH/('LVEDVHGRQLPDJHVVWRUHGLQWKH bigHeartDQG smallHeartDUUD\V
(DFKHOHPHQWLQWKHDUUD\UHSUHVHQWVDSL[HO DVLQJOH/(' DQGHDFKDUUD\URZUHSUHVHQWV
238 | Chapter 7:ಗVisual Output
DURZLQWKHPDWUL[$URZFRQVLVWVRIHLJKWELWVUHSUHVHQWHGXVLQJELQDU\IRUPDW DV
GHVLJQDWHGE\WKHFDSLWDO%DWWKHVWDUWRIHDFKURZ $ELWZLWKDYDOXHRI 1LQGLFDWHV
WKDWWKHFRUUHVSRQGLQJ/('VKRXOGEHRQD0PHDQVRII7KHDQLPDWLRQHIIHFWLVFUHDWHG
E\UDSLGO\VZLWFKLQJEHWZHHQWKHDUUD\V
7KHloopIXQFWLRQZDLWVDVKRUWWLPH PLOOLVHFRQGV EHWZHHQEHDWVDQGWKHQFDOOV
WKH showIXQFWLRQILUVWZLWKWKH smallheartDUUD\DQGWKHQIROORZHGE\WKH bigHeart
DUUD\7KHshowIXQFWLRQVWHSVWKURXJKHDFKHOHPHQWLQDOOWKHURZVDQGFROXPQVOLJKW
LQJWKH/('LIWKHFRUUHVSRQGLQJELWLV7KHbitReadIXQFWLRQ VHH5HFLSH LVXVHG
WRGHWHUPLQHWKHYDOXHRIHDFKELW
$VKRUWGHOD\RIPLFURVHFRQGVEHWZHHQHDFKSL[HODOORZVWKHH\HWLPHWRSHUFHLYH
WKH/('7KHWLPLQJLVFKRVHQWRDOORZHDFKLPDJHWRUHSHDWTXLFNO\HQRXJK WLPHV
SHUVHFRQG VRWKDWEOLQNLQJLVQRWYLVLEOH
+HUHLVDYDULDWLRQWKDWFKDQJHVWKHUDWHDWZKLFKWKHKHDUWEHDWVEDVHGRQWKHYDOXH
IURPDVHQVRU<RXFDQWHVWWKLVXVLQJDYDULDEOHUHVLVWRUFRQQHFWHGWRDQDORJLQSXWSLQ
DVVKRZQLQ5HFLSH8VHWKHZLULQJDQGFRGHVKRZQHDUOLHUH[FHSWUHSODFHWKH
loopIXQFWLRQZLWKWKLVFRGH
void loop() {
sensorValue = analogRead(analogInPin);
// read the analog in value
int pulseRate = map(sensorValue,0,1023,40,240); // convert to beats / minute
int pulseDelay = (60000 / pulseRate ); // milliseconds to wait between beats
show(smallHeart, 80);
show(bigHeart, 160);
delay(pulseDelay);
// show the small heart image for 100 ms
// followed by the big heart for 200ms
// show nothing between beats
}
7KLV YHUVLRQ FDOFXODWHV WKH GHOD\ EHWZHHQ SXOVHV XVLQJ WKH map IXQFWLRQ VHH 5HF
LSH WRFRQYHUWWKHVHQVRUYDOXHLQWREHDWVSHUPLQXWH7KHFDOFXODWLRQGRHVQRW
DFFRXQWIRUWKHWLPHLWWDNHVWRGLVSOD\WKHKHDUWEXW\RXFDQVXEWUDFWPLOOLVHFRQGV
PVSOXVPVIRUWKHWZRLPDJHV LI\RXZDQWPRUHDFFXUDWHWLPLQJ
See Also
5HFLSHVDQGSURYLGHPRUHLQIRUPDWLRQRQKRZWRPDQDJHWLPHXVLQJWKH
millisIXQFWLRQ
6HH5HFLSHVDQGIRULQIRUPDWLRQRQKRZWRXVHVKLIWUHJLVWHUVWRGULYH/('V
LI\RXZDQWWRUHGXFHWKHQXPEHURI$UGXLQRSLQVQHHGHGIRUGULYLQJDQ/('PDWUL[
7.9 Controlling a Matrix of LEDs: Charlieplexing
Problem
<RXKDYHDPDWUL[RI/('VDQG\RXZDQWWRPLQLPL]HWKHQXPEHURISLQVQHHGHGWR
WXUQDQ\RIWKHPRQDQGRII
7.9 Controlling a Matrix of LEDs: Charlieplexing | 239
Solution
&KDUOLHSOH[LQJLVDVSHFLDONLQGRIPXOWLSOH[LQJWKDWLQFUHDVHVWKHQXPEHURI/('VWKDW
FDQEHGULYHQE\DJURXSRISLQV7KLVVNHWFKVHTXHQFHVWKURXJKVL[/('VXVLQJMXVW
WKUHHSLQV )LJXUHVKRZVWKHFRQQHFWLRQV /*
* Charlieplexing sketch
* light six LEDs in sequence that are connected to pins 2, 3, and 4
*/
byte pins[] = {2,3,4};
// the pins that are connected to LEDs
// the next two lines infer number of pins and LEDs from the above array
const int NUMBER_OF_PINS = sizeof(pins)/ sizeof(pins[0]);
const int NUMBER_OF_LEDS = NUMBER_OF_PINS * (NUMBER_OF_PINS-1);
byte pairs[NUMBER_OF_LEDS/2][2] = { {0,1}, {1,2}, {0,2} }; // maps pins to LEDs
void setup()
{
// nothing needed here
}
void loop(){
for(int i=0; i < NUMBER_OF_LEDS; i++)
{
lightLed(i); // light each LED in turn
delay(1000);
}
}
// this function lights the given LED, the first LED is 0
void lightLed(int led)
{
// the following four lines convert LED number to pin numbers
int indexA = pairs[led/2][0];
int indexB = pairs[led/2][1];
int pinA = pins[indexA];
int pinB = pins[indexB];
// turn off all pins not connected to the given LED
for(int i=0; i < NUMBER_OF_PINS; i++)
if( pins[i] != pinA && pins[i] != pinB)
{ // if this pin is not one of our pins
pinMode(pins[i], INPUT);
// set the mode to input
digitalWrite(pins[i],LOW); // make sure pull-up is off
}
// now turn on the pins for the given LED
pinMode(pinA, OUTPUT);
pinMode(pinB, OUTPUT);
if( led % 2 == 0)
{
240 | Chapter 7:ಗVisual Output
digitalWrite(pinA,LOW);
digitalWrite(pinB,HIGH);
}
else
{
digitalWrite(pinB,LOW);
digitalWrite(pinA,HIGH);
}
}
)LJXUH6L[/('VGULYHQWKURXJKWKUHHSLQVXVLQJ&KDUOLHSOH[LQJ
Discussion
7KHWHUP&KDUOLHSOH[LQJFRPHVIURP&KDUOLH$OOHQ RI0LFURFKLS7HFKQRORJ\,QF ZKRSXEOLVKHGWKHPHWKRG7KHWHFKQLTXHLVEDVHGRQWKHIDFWWKDW/('VRQO\WXUQRQ
ZKHQFRQQHFWHGWKH£ULJKWZD\¤DURXQG ZLWKWKHDQRGHPRUHSRVLWLYHWKDQWKHFDWK
RGH +HUHLVWKHWDEOHVKRZLQJWKH/('QXPEHU VHH)LJXUH WKDWLVOLWIRUWKHYDOLG
FRPELQDWLRQVRIWKHWKUHHSLQVLLVLOWHLVHIGHDQGiLVINPUTPRGH6HWWLQJDSLQLQ
INPUTPRGHHIIHFWLYHO\GLVFRQQHFWVLWIURPWKHFLUFXLW
2
L
L
H
i
i
L
H
Pins
3 4
L L
H i
L i
L H
H L
i H
i L
1
0
1
0
0
0
0
0
LEDs
2 3
0 0
0 0
1 0
0 1
0 0
0 0
0 0
4
0
0
0
0
1
0
0
5
0
0
0
0
0
1
0
6
0
0
0
0
0
0
1
7.9 Controlling a Matrix of LEDs: Charlieplexing | 241
<RXFDQGRXEOHWKHQXPEHURI/('VWRXVLQJMXVWRQHPRUHSLQ7KHILUVWVL[/('V
DUHFRQQHFWHGLQWKHVDPHZD\DVLQWKHSUHFHGLQJH[DPSOHDGGWKHDGGLWLRQDOVL[/('V
VRWKDWWKHFRQQHFWLRQVORRNOLNH)LJXUH
)LJXUH&KDUOLHSOH[LQJXVLQJIRXUSLQVWRGULYH/('V
0RGLI\WKHSUHFHGLQJVNHWFKE\DGGLQJWKHH[WUDSLQWRWKHpinsDUUD\
byte pins[] = {2,3,4,5};
// the pins that are connected to LEDs
$GGWKHH[WUDHQWULHVWRWKHpairsDUUD\VRWKDWLWUHDGVDVIROORZV
byte pairs[NUMBER_OF_LEDS/2][2] = { {0,1}, {1,2}, {0,2}, {2,3}, {1,3}, {0,3} };
(YHU\WKLQJHOVHFDQUHPDLQWKHVDPHVRWKHORRSZLOOVHTXHQFHWKURXJKDOO/('V
EHFDXVHWKHFRGHGHWHUPLQHVWKHQXPEHURI/('VIURPWKHQXPEHURIHQWULHVLQWKH
pinsDUUD\
%HFDXVH&KDUOLHSOH[LQJZRUNVE\FRQWUROOLQJWKH$UGXLQRSLQVVRWKDWRQO\DVLQJOH/('
LVWXUQHGRQDWDWLPHLWLVPRUHFRPSOLFDWHGWRFUHDWHWKHLPSUHVVLRQRIOLJKWLQJPXO
WLSOH/('V%XW\RXFDQOLJKWPXOWLSOH/('VXVLQJDPXOWLSOH[LQJWHFKQLTXHPRGLILHG
IRU&KDUOLHSOH[LQJ
7KLVVNHWFKFUHDWHVDEDUJUDSKE\OLJKWLQJDVHTXHQFHRI/('VEDVHGRQWKHYDOXHRID
VHQVRUFRQQHFWHGWRDQDORJSLQ
byte pins[] = {2,3,4};
const int NUMBER_OF_PINS = sizeof(pins)/ sizeof(pins[0]);
const int NUMBER_OF_LEDS = NUMBER_OF_PINS * (NUMBER_OF_PINS-1);
byte pairs[NUMBER_OF_LEDS/2][2] = { {0,1}, {1,2}, {0,2} };
int ledStates = 0; //holds states for up to 15 LEDs
int refreshedLed; // the LED that gets refreshed
void setup()
{
// nothing here
}
242 | Chapter 7:ಗVisual Output
void loop()
{
const int analogInPin = 0; // Analog input pin connected to the variable resistor
// here is the code from the bargraph recipe
int sensorValue = analogRead(analogInPin);
// read the analog in value
int ledLevel = map(sensorValue, 0, 1023, 0, NUMBER_OF_LEDS);
// map to the
number of LEDs
for (int led = 0; led < NUMBER_OF_LEDS; led++)
{
if (led < ledLevel ) {
setState(led, HIGH);
// turn on pins less than the level
}
else {
setState(led, LOW);
// turn off pins higher than the level
}
}
ledRefresh();
}
void setState( int led, boolean state)
{
bitWrite(ledStates,led, state);
}
void ledRefresh()
{
// refresh a different LED each time this is called.
if( refreshedLed++ > NUMBER_OF_LEDS) // increment to the next LED
refreshedLed = 0; // repeat from the first LED if all have been refreshed
}
if( bitRead(ledStates, refreshedLed ) == HIGH)
lightLed( refreshedLed );
// this function is identical to the sketch above
// it lights the given LED, the first LED is 0
void lightLed(int led)
{
// the following four lines convert LED number to pin numbers
int indexA = pairs[led/2][0];
int indexB = pairs[led/2][1];
int pinA = pins[indexA];
int pinB = pins[indexB];
// turn off all pins not connected to the given LED
for(int i=0; i < NUMBER_OF_PINS; i++)
if( pins[i] != pinA && pins[i] != pinB)
{ // if this pin is not one of our pins
pinMode(pins[i], INPUT);
// set the mode to input
digitalWrite(pins[i],LOW); // make sure pull-up is off
}
// now turn on the pins for the given LED
pinMode(pinA, OUTPUT);
7.9 Controlling a Matrix of LEDs: Charlieplexing | 243
pinMode(pinB, OUTPUT);
if( led % 2 == 0)
{
digitalWrite(pinA,LOW);
digitalWrite(pinB,HIGH);
}
else
{
digitalWrite(pinB,LOW);
digitalWrite(pinA,HIGH);
}
}
7KLVVNHWFKXVHVWKHYDOXHRIWKHELWVLQWKHYDULDEOHledStatesWRUHSUHVHQWWKHVWDWHRI
WKH/('V LIRIILIRQ 7KHrefreshIXQFWLRQFKHFNVHDFKELWDQGOLJKWVWKH/('V
IRUHDFKELWWKDWLVVHWWR7KHrefreshIXQFWLRQPXVWEHFDOOHGTXLFNO\DQGUHSHDWHGO\
RUWKH/('VZLOODSSHDUWREOLQN
$GGLQJGHOD\VLQWR\RXUFRGHFDQLQWHUIHUHZLWKWKH£SHUVLVWHQFHRIYL
VLRQ¤HIIHFWWKDWFUHDWHVWKHLOOXVLRQWKDWKLGHVWKHIODVKLQJRIWKH/('V
<RXFDQXVHDQLQWHUUXSWWRVHUYLFHWKH refreshIXQFWLRQLQWKHEDFNJURXQG ZLWKRXW
QHHGLQJWRH[SOLFLWO\FDOOWKHIXQFWLRQLQloop 7LPHULQWHUUXSWVDUHFRYHUHGLQ&KDS
WHUEXWKHUHLVDSUHYLHZRIRQHDSSURDFKIRUXVLQJDQLQWHUUXSWWRVHUYLFH\RXU/('
UHIUHVKHV7KLVXVHVDWKLUGSDUW\OLEUDU\FDOOHG)UHTXHQF\7LPHU DYDLODEOHIURPWKH
$UGXLQR3OD\JURXQG WRFUHDWHWKHLQWHUUXSW
#include <FrequencyTimer2.h>
byte pins[] = {2,3,4,5};
const int NUMBER_OF_PINS = sizeof(pins)/ sizeof(pins[0]);
const int NUMBER_OF_LEDS = NUMBER_OF_PINS * (NUMBER_OF_PINS-1);
byte pairs[NUMBER_OF_LEDS/2][2] = { {0,1}, {1,2}, {0,2} };
int ledStates = 0; //holds states for up to 15 LEDs
int refreshedLed; // the LED that gets refreshed
--#include <FrequencyTimer2.h> // include this library to handle the refresh
byte pins[] = {2,3,4};
const int NUMBER_OF_PINS = sizeof(pins)/ sizeof(pins[0]);
const int NUMBER_OF_LEDS = NUMBER_OF_PINS * (NUMBER_OF_PINS-1);
byte pairs[NUMBER_OF_LEDS/2][2] = { {0,1}, {1,2}, {0,2} };
int ledStates = 0; //holds states for up to 15 LEDs
int refreshedLed; // the LED that gets refreshed
244 | Chapter 7:ಗVisual Output
void setup()
{
FrequencyTimer2::setPeriod(20000/ NUMBER_OF_LEDS); // set the period
// the next line tells FrequencyTimer2 the function to call (ledRefresh)
FrequencyTimer2::setOnOverflow(ledRefresh);
FrequencyTimer2::enable();
}
void loop()
{
const int analogInPin = 0; // Analog input pin connected to the variable resistor
// here is the code from the bargraph recipe
int sensorValue = analogRead(analogInPin);
// read the analog in value
int ledLevel = map(sensorValue, 0, 1023, 0, NUMBER_OF_LEDS);
// map to the
number of LEDs
for (int led = 0; led < NUMBER_OF_LEDS; led++)
{
if (led < ledLevel ) {
setState(led, HIGH);
// turn on pins less than the level
}
else {
setState(led, LOW);
// turn off pins higher than the level
}
}
// the LED is no longer refreshed in loop, it's handled by FrequencyTimer2
}
// the remaining code is the same as the previous example
7KH)UHTXHQF\7LPHUOLEUDU\KDVWKHSHULRGVHWWRPLFURVHFRQGV PVGLYLGHG
E\WKHQXPEHURI/('V 7KHFrequencyTimer2setOnOverflowPHWKRGJHWVWKHIXQF
WLRQWRFDOO ledRefresh HDFKWLPHWKHWLPHU£WULJJHUV¤
See Also
&KDSWHUSURYLGHVPRUHLQIRUPDWLRQRQWLPHULQWHUUXSWV
7.10 Driving a 7-Segment LED Display
Problem
<RXZDQWWRGLVSOD\QXPHUDOVXVLQJDVHJPHQWQXPHULFGLVSOD\
Solution
7KHIROORZLQJVNHWFKGLVSOD\VQXPHUDOVIURP]HURWRQLQHRQDVLQJOHGLJLWVHJPHQW
GLVSOD\ )LJXUH VKRZV WKH FRQQHFWLRQV 7KH RXWSXW LV SURGXFHG E\ WXUQLQJ RQ
FRPELQDWLRQVRIVHJPHQWVWKDWUHSUHVHQWWKHQXPHUDOV
/*
* SevenSegment sketch
7.10 Driving a 7-Segment LED Display | 245
* Shows numerals ranging from 0 through 9 on a single-digit display
* This example counts seconds from 0 to 9
*/
// bits representing segments A through G (and decimal point) for numerals 0-9
const byte numeral[10] = {
//ABCDEFG /dp
B11111100, // 0
B01100000, // 1
B11011010, // 2
B11110010, // 3
B01100110, // 4
B10110110, // 5
B00111110, // 6
B11100000, // 7
B11111110, // 8
B11100110, // 9
};
// pins for decimal point and each segment
//
dp,G,F,E,D,C,B,A
const int segmentPins[8] = { 5,9,8,7,6,4,3,2};
void setup()
{
for(int i=0; i < 8; i++)
{
pinMode(segmentPins[i], OUTPUT); // set segment and DP pins to output
}
}
void loop()
{
for(int i=0; i <= 10; i++)
{
showDigit(i);
delay(1000);
}
// the last value if i is 10 and this will turn the display off
delay(2000); // pause two seconds with the display off
}
// Displays a number from 0 through 9 on a 7-segment display
// any value not within the range of 0-9 turns the display off
void showDigit( int number)
{
boolean isBitSet;
for(int segment = 1; segment < 8; segment++)
{
if( number < 0 || number > 9){
isBitSet = 0;
// turn off all segments
}
else{
246 | Chapter 7:ಗVisual Output
// isBitSet will be true if given bit is 1
isBitSet = bitRead(numeral[number], segment);
}
}
isBitSet = ! isBitSet; // remove this line if common cathode display
digitalWrite( segmentPins[segment], isBitSet);
}
)LJXUH&RQQHFWLQJDVHJPHQWGLVSOD\
Discussion
7KHVHJPHQWVWREHOLWIRUHDFKQXPHUDODUHKHOGLQWKHDUUD\FDOOHG numeral7KHUHLV
RQHE\WHSHUQXPHUDOZKHUHHDFKELWLQWKHE\WHUHSUHVHQWVRQHRIVHYHQVHJPHQWV RU
WKHGHFLPDOSRLQW 7KH DUUD\ FDOOHG segmentPins KROGV WKH SLQV DVVRFLDWHG ZLWK HDFK VHJPHQW 7KH
showDigitIXQFWLRQFKHFNVWKDWWKHQXPEHUUDQJHVIURP]HURWRDQGLIYDOLGORRNVDW
HDFK VHJPHQW ELW DQG WXUQV RQ WKH VHJPHQW LI WKH ELW LV VHW HTXDO WR 6HH 5HF
LSHIRUPRUHRQWKHbitReadIXQFWLRQ
7.10 Driving a 7-Segment LED Display | 247
$VPHQWLRQHGLQ5HFLSHDSLQLVVHWHIGHZKHQWXUQLQJRQDVHJPHQWRQDFRPPRQ
FDWKRGH GLVSOD\ DQG LW¦V VHW LOW ZKHQ WXUQLQJ RQ D VHJPHQW RQ D FRPPRQ DQRGH
GLVSOD\7KHFRGHKHUHLVIRUDFRPPRQDQRGHGLVSOD\VRLWLQYHUWVWKHYDOXH VHWVWR
DQGWR DVIROORZV
isBitSet = ! isBitSet; // remove this line if common cathode display
7KH!LVWKHQHJDWLRQRSHUDWRU¢VHH5HFLSH,I\RXUGLVSOD\LVDFRPPRQFDWKRGH
GLVSOD\ DOOWKHFDWKRGHVDUHFRQQHFWHGWRJHWKHUVHHWKHGDWDVKHHWLI\RXDUHQRWVXUH \RXFDQUHPRYHWKDWOLQH
7.11 Driving Multidigit, 7-Segment LED Displays: Multiplexing
Problem
<RXZDQWWRGLVSOD\QXPEHUVXVLQJDVHJPHQWGLVSOD\WKDWVKRZVWZRRUPRUHGLJLWV
Solution
0XOWLGLJLWVHJPHQWGLVSOD\VXVXDOO\XVHPXOWLSOH[LQJ,QHDUOLHUUHFLSHVPXOWLSOH[HG
URZV DQG FROXPQV RI /('V ZHUH FRQQHFWHG WRJHWKHU WR IRUP DQ DUUD\ KHUH FRUUH
VSRQGLQJVHJPHQWVIURPHDFKGLJLWDUHFRQQHFWHGWRJHWKHU VHH)LJXUH /*
* SevenSegmentMpx sketch
* Shows numbers ranging from 0 through 9999 on a four-digit display
* This example displays the value of a sensor connected to an analog input
*/
// bits representing segments A through G (and decimal point) for numerals 0-9
const int numeral[10] = {
//ABCDEFG /dp
B11111100, // 0
B01100000, // 1
B11011010, // 2
B11110010, // 3
B01100110, // 4
B10110110, // 5
B00111110, // 6
B11100000, // 7
B11111110, // 8
B11100110, // 9
};
// pins for decimal point and each segment
// dp,G,F,E,D,C,B,A
const int segmentPins[] = { 4,7,8,6,5,3,2,9};
const int nbrDigits= 4;
// the number of digits in the LED display
//dig 1 2 3 4
const int digitPins[nbrDigits] = { 10,11,12,13};
248 | Chapter 7:ಗVisual Output
void setup()
{
for(int i=0; i < 8; i++)
pinMode(segmentPins[i], OUTPUT); // set segment and DP pins to output
for(int i=0; i < nbrDigits; i++)
pinMode(digitPins[i], OUTPUT);
}
void loop()
{
int value = analogRead(0);
showNumber(value);
}
void showNumber( int number)
{
if(number == 0)
showDigit( 0, nbrDigits-1) ; // display 0 in the rightmost digit
else
{
// display the value corresponding to each digit
// leftmost digit is 0, rightmost is one less than the number of places
for( int digit = nbrDigits-1; digit >= 0; digit--)
{
if(number > 0)
{
showDigit( number % 10, digit) ;
number = number / 10;
}
}
}
}
// Displays given number on a 7-segment display at the given digit position
void showDigit( int number, int digit)
{
digitalWrite( digitPins[digit], HIGH );
for(int segment = 1; segment < 8; segment++)
{
boolean isBitSet = bitRead(numeral[number], segment);
// isBitSet will be true if given bit is 1
isBitSet = ! isBitSet; // remove this line if common cathode display
digitalWrite( segmentPins[segment], isBitSet);
}
delay(5);
digitalWrite( digitPins[digit], LOW );
}
7.11 Driving Multidigit, 7-Segment LED Displays: Multiplexing | 249
)LJXUH&RQQHFWLQJDPXOWLGLJLWVHJPHQWGLVSOD\ /7&
Discussion
7KLVVNHWFKKDVDshowDigitIXQFWLRQVLPLODUWRWKDWGLVFXVVHGLQ5HFLSH+HUHWKH
IXQFWLRQLVJLYHQWKHQXPHUDODQGWKHGLJLWSODFH7KHORJLFWROLJKWWKHVHJPHQWVWR
FRUUHVSRQGWRWKHQXPHUDOLVWKHVDPHEXWLQDGGLWLRQWKHFRGHVHWVWKHSLQFRUUH
VSRQGLQJWRWKHGLJLWSODFHHIGHVRRQO\WKDWGLJLWZLOOEHZULWWHQ VHHWKHHDUOLHUPXO
WLSOH[LQJH[SODQDWLRQV 7.12 Driving Multidigit, 7-Segment LED Displays Using
MAX7221 Shift Registers
Problem
<RXZDQWWRFRQWUROPXOWLSOHVHJPHQWGLVSOD\VEXW\RXZDQWWRPLQLPL]HWKHQXPEHU
RIUHTXLUHG$UGXLQRSLQV
Solution
7KLV6ROXWLRQXVHVWKHSRSXODU0$;/('GULYHUFKLSWRFRQWUROIRXUGLJLWFRP
PRQFDWKRGHGLVSOD\VVXFKDVWKH/LWH2Q/7&-5 'LJL.H\1' 7KH0$;SURYLGHVDVLPSOHUVROXWLRQWKDQ5HFLSHEHFDXVHLWKDQGOHVPXO
WLSOH[LQJDQGGLJLWGHFRGLQJLQKDUGZDUH
7KLV VNHWFK ZLOO GLVSOD\ D QXPEHU EHWZHHQ ]HUR DQG )LJXUH VKRZV WKH
FRQQHFWLRQV 250 | Chapter 7:ಗVisual Output
/*
Max7221_digits
*/
#include <SPI.h>
// Arduino SPI library introduced in Arduino version 0019
const int slaveSelect = 10; //pin used to enable the active slave
const int numberOfDigits = 2; // change these to match the number of digits
wired up
const int maxCount
= 99;
int number = 0;
void setup()
{
Serial.begin(9600);
SPI.begin();
// initialize SPI
pinMode(slaveSelect, OUTPUT);
digitalWrite(slaveSelect,LOW); //select slave
// prepare the 7221 to display 7-segment data - see data sheet
sendCommand(12,1); // normal mode (default is shutdown mode);
sendCommand(15,0); // Display test off
sendCommand(10,8); // set medium intensity (range is 0-15)
sendCommand(11,numberOfDigits); // 7221 digit scan limit command
sendCommand(9,255); // decode command, use standard 7-segment digits
digitalWrite(slaveSelect,HIGH); //deselect slave
}
void loop()
{
// display a number from the serial port terminated by the end of line
character
if(Serial.available())
{
char ch = Serial.read();
if( ch == '\n')
{
displayNumber(number);
number = 0;
}
else
number = (number * 10) + ch - '0'; // see Chapter 4 for details
}
}
// function to display up to four digits on a 7-segment display
void displayNumber( int number)
{
for(int i = 0; i < numberOfDigits; i++)
{
byte character = number % 10; // get the value of the rightmost decade
if(number == 0 && i > 0)
character = 0xf; // the 7221 will blank the segments when receiving value
// send digit number as command, first digit is command 1
7.12 Driving Multidigit, 7-Segment LED Displays Using MAX7221 Shift Registers | 251
}
sendCommand(numberOfDigits-i, character);
number = number / 10;
}
void sendCommand( int command, int value)
{
digitalWrite(slaveSelect,LOW); //chip select is active low
//2-byte data transfer to the 7221
SPI.transfer(command);
SPI.transfer(value);
digitalWrite(slaveSelect,HIGH); //release chip, signal end transfer
}
)LJXUH0$;GULYLQJDPXOWLGLJLWFRPPRQFDWKRGHVHJPHQWGLVSOD\
Solution
7KLV UHFLSH XVHV $UGXLQR 63, FRPPXQLFDWLRQ WR WDON WR WKH 0$; FKLS &KDS
WHUFRYHUV63,LQPRUHGHWDLODQG5HFLSHH[SODLQVWKH63,VSHFLILFFRGHXVHG
7KLVVNHWFKGLVSOD\VDQXPEHULIXSWRIRXUGLJLWVDUHUHFHLYHGRQWKHVHULDOSRUW¢VHH
&KDSWHUIRUDQH[SODQDWLRQRIWKHVHULDOFRGHLQ loop7KH displayNumberIXQFWLRQ
H[WUDFWVWKHYDOXHRIHDFKGLJLWVWDUWLQJIURPWKHULJKWPRVWGLJLWWRWKH0$;XVLQJ
WKHsendCommandIXQFWLRQWKDWVHQGVWKHYDOXHVWRWKH0$;
7KH ZLULQJ VKRZQ XVHV D IRXUGLJLW VHJPHQW GLVSOD\ EXW \RX FDQ XVH VLQJOH RU
GXDOGLJLWGLVSOD\VIRUXSWRHLJKWGLJLWV:KHQFRPELQLQJPXOWLSOHGLVSOD\VHDFKFRU
UHVSRQGLQJVHJPHQWSLQVKRXOGEHFRQQHFWHGWRJHWKHU 5HFLSHVKRZVWKHFRQ
QHFWLRQVIRUDFRPPRQGXDOGLJLWGLVSOD\
252 | Chapter 7:ಗVisual Output
7KH0$;[[FKLSVDUHGHVLJQHGIRUFRPPRQFDWKRGHGLVSOD\V7KH
DQRGHRIHDFKVHJPHQWLVDYDLODEOHRQDVHSDUDWHSLQDQGWKHFDWKRGHV
RIDOOWKHVHJPHQWVIRUHDFKGLJLWDUHFRQQHFWHGWRJHWKHU
7.13 Controlling an Array of LEDs by Using MAX72xx Shift
Registers
Problem
<RXKDYHDQ[DUUD\RI/('VWRFRQWURODQG\RXZDQWWRPLQLPL]HWKHQXPEHURI
UHTXLUHG$UGXLQRSLQV
Solution
$VLQ5HFLSH\RXFDQXVHDVKLIWUHJLVWHUWRUHGXFHWKHQXPEHURISLQVQHHGHGWR
FRQWURODQ/('PDWUL[7KLVVROXWLRQXVHVWKHSRSXODU0$;RU0$;/('
GULYHUFKLSWRSURYLGHWKLVFDSDELOLW\7KHVNHWFKXVHVWKHPDWUL[OLEUDU\GLVWULEXWHG
ZLWK$UGXLQREXWLWXVHVGLIIHUHQW$UGXLQRSLQVWKDQWKH$UGXLQRH[DPSOHVNHWFK7R
UXQ WKH IROORZLQJ FRGH FRQQHFW \RXU $UGXLQR PDWUL[ DQG 0$;[[ DV VKRZQ LQ
)LJXUH
)LJXUH0$;[[GULYLQJDQ[/('DUUD\
7.13 Controlling an Array of LEDs by Using MAX72xx Shift Registers | 253
7KLVVNHWFKLVEDVHGRQWKH$UGXLQRKHOORBPDWUL[OLEUDU\E\1LFKRODV=DPEHWWLZLWK
RQO\WKHSLQQXPEHUFKDQJHGWREHFRQVLVWHQWZLWKWKHZLULQJXVHGHOVHZKHUHLQWKLV
FKDSWHU
#include <Sprite.h>
#include <Matrix.h>
// Hello Matrix
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates the use of the Matrix library
// For MAX7219 LED Matrix Controllers
// Blinks welcoming face on screen
const int loadPin = 2;
const int clockPin = 3;
const int dataPin = 4;
Matrix myMatrix = Matrix(dataPin, clockPin, loadPin); // create a new Matrix
instance
void setup()
{
}
void loop()
{
myMatrix.clear(); // clear display
delay(1000);
// turn some pixels on
myMatrix.write(1, 5, HIGH);
myMatrix.write(2, 2, HIGH);
myMatrix.write(2, 6, HIGH);
myMatrix.write(3, 6, HIGH);
myMatrix.write(4, 6, HIGH);
myMatrix.write(5, 2, HIGH);
myMatrix.write(5, 6, HIGH);
myMatrix.write(6, 5, HIGH);
delay(1000);
}
Discussion
$PDWUL[LVFUHDWHGE\SDVVLQJSLQQXPEHUVIRUWKHGDWDORDGDQGFORFNSLQVloopXVHV
WKHwritePHWKRGWRWXUQSL[HOVRQWKHclarPHWKRGWXUQVWKHSL[HOVRIIwriteKDVWKUHH
SDUDPHWHUVWKHILUVWWZRLGHQWLI\WKHFROXPQDQGURZ [DQG\ RIDQ/('DQGWKHWKLUG
SDUDPHWHU HIGHRULOW WXUQVWKH/('RQRURII
254 | Chapter 7:ಗVisual Output
7KH SLQ QXPEHUV VKRZQ KHUH DUH IRU WKH JUHHQ /('V LQ WKH GXDOFRORU [ PDWUL[
DYDLODEOHIURPWKHVHVXSSOLHUV
6SDUN)XQ&20
1.&(OHFWURQLFV,WHP&20
7KHUHVLVWRU PDUNHG5LQ)LJXUH LVXVHGWRFRQWUROWKHPD[LPXPFXUUHQWWKDW
ZLOOEHXVHGWRGULYHDQ/('7KH0$;[[GDWDVKHHWKDVDWDEOHWKDWVKRZVDUDQJH
RIYDOXHV VHH7DEOH 7DEOH7DEOHRIUHVLVWRUYDOXHV IURP0$;[[GDWDVKHHW
LED forward voltage
Current
1.5V
2.0V
2.5V
3.0V
3.5V
40 mA
12 kΩ
12 kΩ
11 kΩ
10 kΩ
10 kΩ
30 mA
18 kΩ
17 kΩ
16 kΩ
15 kΩ
14 kΩ
20 mA
30 kΩ
28 kΩ
26 kΩ
24 kΩ
22 kΩ
10 mA
68 kΩ
64 kΩ
60 kΩ
56 kΩ
51 kΩ
7KHJUHHQ/('LQWKH/('PDWUL[VKRZQLQ)LJXUHKDVDIRUZDUGYROWDJHRI
YROWVDQGDIRUZDUGFXUUHQWRIP$7DEOHLQGLFDWHV.RKPVEXWWRDGGDOLWWOH
VDIHW\ PDUJLQ D UHVLVWRU RI . RU . ZRXOG EH D VXLWDEOH FKRLFH 7KH FDSDFLWRUV
XIDQGXI DUHUHTXLUHGWRSUHYHQWQRLVHVSLNHVIURPEHLQJJHQHUDWHGZKHQWKH
/('VDUHVZLWFKHGRQDQGRII¢VHH£8VLQJ&DSDFLWRUVIRU'HFRXSOLQJ¤RQSDJH
LQ$SSHQGL[&LI\RXDUHQRWIDPLOLDUZLWKFRQQHFWLQJGHFRXSOLQJFDSDFLWRUV
See Also
0$;[[GDWDVKHHWKWWSSGIVHUYPD[LPLFFRPHQGV0$;0$;SGI
7.14 Increasing the Number of Analog Outputs Using PWM
Extender Chips (TLC5940)
Problem
<RXZDQWWRKDYHLQGLYLGXDOFRQWURORIWKHLQWHQVLW\RIPRUH/('VWKDQ$UGXLQRFDQ
VXSSRUW RQDVWDQGDUGERDUGDQGRQWKH0HJD Solution
7KH7/&FKLSGULYHVXSWR/('VXVLQJRQO\ILYHGDWDSLQV)LJXUHVKRZV
WKHFRQQHFWLRQV7KLVVNHWFKLVEDVHGRQWKHH[FHOOHQW7OFOLEUDU\ZULWWHQE\$OH[
/HRQH DFOHRQH#JPDLOFRP <RX FDQ GRZQORDG WKH OLEUDU\ IURP KWWSFRGHJRRJOH
FRPSWOFDUGXLQR
7.14 Increasing the Number of Analog Outputs Using PWM Extender Chips (TLC5940) | 255
/*
* TLC sketch
* Create a Knight Rider-like effect on LEDs plugged into all the TLC outputs
* this version assumes one TLC with 16 LEDs
*/
#include "Tlc5940.h"
void setup()
{
Tlc.init();
}
// initialize the TLC library
void loop()
{
int direction = 1;
int intensity = 4095; // an intensity from 0 to 4095, full brightness is 4095
int dim = intensity / 4; // 1/4 the value dims the LED
for (int channel = 0; channel < 16; channel += direction) {
// the following TLC commands set values to be written by the update method
Tlc.clear(); // turn off all LEDs
if (channel == 0) {
direction = 1;
}
else {
Tlc.set(channel - 1, dim); // set intensity for prev LED
}
Tlc.set(channel, intensity); // full intensity on this LED
if (channel < 16){
Tlc.set(channel + 1, dim); // set the next LED to dim
}
else {
direction = -1;
}
}
Tlc.update();
delay(75);
// this method sends data to the TLC chips to change the LEDs
}
Discussion
7KLVVNHWFKORRSVWKURXJKHDFKFKDQQHO /(' VHWWLQJWKHSUHYLRXV/('WRGLPWKH
FXUUHQWFKDQQHOWRIXOOLQWHQVLW\DQGWKHQH[WFKDQQHOWRGLP7KH/('VDUHFRQWUROOHG
WKURXJKDIHZFRUHPHWKRGV
7KHTlc.initPHWKRGLQLWLDOL]HVTlcIXQFWLRQVSULRUWRDQ\RWKHUIXQFWLRQ
256 | Chapter 7:ಗVisual Output
Download from Wow! eBook <www.wowebook.com>
)LJXUH6L[WHHQ/('VGULYHQXVLQJH[WHUQDO3:0
7KHIROORZLQJIXQFWLRQVRQO\WDNHHIIHFWDIWHUFDOOLQJWKHupdate()PHWKRG
Tlc.clear
7XUQVRIIDOOFKDQQHOV
Tlc.set
6HWVWKHLQWHQVLW\IRUWKHJLYHQFKDQQHOWRDJLYHQYDOXH
Tlc.setAll
6HWVDOOFKDQQHOVWRDJLYHQYDOXH
Tlc.update
6HQGVWKHFKDQJHVIURPDQ\RIWKHSUHFHGLQJFRPPDQGVWRWKH7/&FKLS
0RUHIXQFWLRQVDUHDYDLODEOHLQWKHOLEUDU\VHHWKHOLQNWRWKHUHIHUHQFHDWWKHHQGRI
WKLVUHFLSH
7KH.UHVLVWRUEHWZHHQ7/&SLQ ,UHI DQG*QGZLOOOHWDURXQGP$WKURXJKHDFK
/('<RXFDQFDOFXODWHWKHUHVLVWRUYDOXH5IRUDGLIIHUHQWFXUUHQW LQPLOOLDPSHUHV
XVLQJWKHIRUPXOD5 P$5LVRKPDQGWKHFDOFXODWLRQGRHVQRWGHSHQG
RQWKH/('GULYLQJYROWDJH
,I\RXZDQWWKH/('VWRWXUQRIIZKHQWKH$UGXLQRLVUHVHWSXWDSXOOXSUHVLVWRU .
EHWZHHQ9DQG%/$1. SLQRIWKH7/&DQG$UGXLQRSLQ 7.14 Increasing the Number of Analog Outputs Using PWM Extender Chips (TLC5940) | 257
+HUHLVDYDULDWLRQWKDWXVHVDVHQVRUYDOXHWRVHWWKHPD[LPXP/('LQWHQVLW\<RXFDQ
WHVWWKLVXVLQJDYDULDEOHUHVLVWRUFRQQHFWHGDVVKRZQLQ)LJXUHRU)LJXUH
#include "Tlc5940.h"
const int sensorPin = 0; // connect sensor to analog input 0
void setup()
{
Tlc.init();
}
// initialize the TLC library
void loop()
{
int direction = 1;
int sensorValue = analogRead(0); // get the sensor value
int intensity = map(sensorValue, 0,1023, 0, 4095); // map to TLC range
int dim = intensity / 4; // 1/4 the value dims the LED
for (int channel = 0; channel < NUM_TLCS * 16; channel += direction) {
// the following TLC commands set values to be written by the update method
Tlc.clear(); // turn off all LEDs
if (channel == 0) {
direction = 1;
}
else {
Tlc.set(channel - 1, dim); // set intensity for prev LED
}
Tlc.set(channel, intensity); // full intensity on this LED
if (channel != NUM_TLCS * 16 - 1) {
Tlc.set(channel + 1, dim); // set the next LED to dim
}
else {
direction = -1;
}
}
Tlc.update();
delay(75);
// this method sends data to the TLC chips to change the LEDs
}
7KLVYHUVLRQDOVRDOORZVIRUPXOWLSOH7/&FKLSVLI\RXZDQWWRGULYHPRUHWKDQ/('V
<RXGRWKLVE\£GDLV\FKDLQLQJ¤WKH7/&FKLSV¢FRQQHFWWKH6RXW SLQ RIWKHILUVW
7/&WRWKH6LQ SLQ RIWKHQH[W7KH6LQ SLQ RIWKHILUVW7/&FKLSLVFRQQHFWHG
WR$UGXLQRSLQDVVKRZQLQ)LJXUH
7KHIROORZLQJSLQVVKRXOGEHFRQQHFWHGWRJHWKHUZKHQGDLV\FKDLQLQJ7/&FKLSV
$UGXLQRSLQWR;/$7 SLQ RIHDFK7/&
$UGXLQRSLQWR%/$1. SLQ RIHDFK7/&
$UGXLQRSLQWR6&/. SLQ RIHDFK7/&
(DFK7/&QHHGVLWVRZQUHVLVWRUEHWZHHQ,UHI SLQ DQG*QG
258 | Chapter 7:ಗVisual Output
<RXPXVWFKDQJHWKHYDOXHRIWKHNUM_TLCSFRQVWDQWGHILQHGLQWKH7OFOLEUDU\WR
PDWFKWKHQXPEHURIFKLSV\RXKDYHZLUHG
See Also
*RWRKWWSFRGHJRRJOHFRPSWOFDUGXLQRWRGRZQORDGWKLVOLEUDU\DQGDFFHVVLWV
GRFXPHQWDWLRQ
7.15 Using an Analog Panel Meter As a Display
Problem
<RXZRXOGOLNHWRFRQWUROWKHSRLQWHURIDQDQDORJSDQHOPHWHUIURP\RXUVNHWFK)OXF
WXDWLQJUHDGLQJVDUHHDVLHUWRLQWHUSUHWRQDQDQDORJPHWHUDQGDQDORJPHWHUVDGGD
FRROUHWURORRNWRDSURMHFW
Solution
&RQQHFWWKHPHWHUWKURXJKDVHULHVUHVLVWRU .RKPVIRUWKHW\SLFDOP$PHWHU DQG
FRQQHFWWRDQDQDORJ 3:0 RXWSXW VHH)LJXUH )LJXUH'ULYLQJDQDQDORJPHWHU
7.15 Using an Analog Panel Meter As a Display | 259
7KHSRLQWHUPRYHPHQWFRUUHVSRQGVWRWKHSRVLWLRQRIDSRW YDULDEOHUHVLVWRU /*
* AnalogMeter sketch
* Drives an analog meter through an Arduino PWM pin
* The meter level is controlled by a variable resistor on an analog input pin
*/
const int analogInPin = 0; // Analog input pin connected to the variable resistor
const int analogMeterPin = 9; // Analog output pin connecting to the meter
int sensorValue = 0;
int outputValue = 0;
// value read from the pot
// value output to the PWM (analog out)
void setup()
{
// nothing in setup
}
void loop()
{
sensorValue = analogRead(analogInPin);
outputValue = map(sensorValue, 0, 1023, 0, 255);
analog out
analogWrite(analogMeterPin, outputValue);
}
// read the analog in value
// map to the range of the
// write the analog out value
Discussion
,QWKLVYDULDWLRQRQ5HFLSHWKH$UGXLQRanalogWriteRXWSXWGULYHVDSDQHOPHWHU
3DQHOPHWHUVDUHXVXDOO\PXFKPRUHVHQVLWLYHWKDQ/('VDUHVLVWRUPXVWEHFRQQHFWHG
EHWZHHQWKH$UGXLQRRXWSXWDQGWKHPHWHUWRGURSWKHFXUUHQWWRWKHOHYHOIRUWKHPHWHU
7KHYDOXHRIWKHVHULHVUHVLVWRUGHSHQGVRQWKHVHQVLWLYLW\RIWKHPHWHU.RKPVJLYH
IXOOVFDOHGHIOHFWLRQZLWKDP$PHWHU<RXFDQXVH.UHVLVWRUVDVWKH\DUHHDVLHU
WRREWDLQWKDQ.DOWKRXJK\RXZLOOSUREDEO\QHHGWRUHGXFHWKHPD[LPXPYDOXHJLYHQ
WRanalogWriteWRRUVR+HUHLVKRZ\RXFDQFKDQJHWKHUDQJHLQWKHmapIXQFWLRQ
LI\RXXVHD.RKPUHVLVWRUZLWKDP$PHWHU
outputValue = map(sensorValue, 0, 1023, 0, 240);
// map to meter's range
,I\RXUPHWHUKDVDGLIIHUHQWVHQVLWLYLW\WKDQP$\RXZLOOQHHGWRXVHDGLIIHUHQWYDOXH
VHULHVUHVLVWRU7KHUHVLVWRUYDOXHLQRKPVLV5HVLVWRU P$
6RDPLFURDPSPHWHU P$ LVZKLFKLV . RKPV
6RPHVXUSOXVPHWHUVDOUHDG\KDYHDQLQWHUQDOVHULHVUHVLVWRU¢\RXPD\QHHGWRH[SHUL
PHQWWRGHWHUPLQHWKHFRUUHFWYDOXHRIWKHUHVLVWRUEXWEHFDUHIXOQRWWRDSSO\WRRPXFK
YROWDJHWR\RXUPHWHU
See Also
5HFLSH
260 | Chapter 7:ಗVisual Output
CHAPTER 8
Physical Output
8.0 Introduction
<RX FDQ PDNH WKLQJV PRYH E\ FRQWUROOLQJ PRWRUV ZLWK $UGXLQR 'LIIHUHQW W\SHV RI
PRWRUVVXLWGLIIHUHQWDSSOLFDWLRQVDQGWKLVFKDSWHUVKRZVKRZ$UGXLQRFDQGULYHPDQ\
GLIIHUHQWNLQGVRIPRWRUV
Motion Control Using Servos
6HUYRV HQDEOH \RX WR DFFXUDWHO\ FRQWURO SK\VLFDO PRYHPHQW EHFDXVH WKH\ JHQHUDOO\
PRYHWRDSRVLWLRQLQVWHDGRIFRQWLQXRXVO\URWDWLQJ7KH\DUHLGHDOIRUPDNLQJVRPH
WKLQJURWDWHRYHUDUDQJHRIWRGHJUHHV6HUYRVDUHHDV\WRFRQQHFWDQGFRQWURO
EHFDXVHWKHPRWRUGULYHULVEXLOWLQWRWKHVHUYR
6HUYRVFRQWDLQDVPDOOPRWRUFRQQHFWHGWKURXJKJHDUVWRDQRXWSXWVKDIW7KHRXWSXW
VKDIWGULYHVDVHUYRDUPDQGLVDOVRFRQQHFWHGWRDSRWHQWLRPHWHUWRSURYLGHSRVLWLRQ
IHHGEDFNWRDQLQWHUQDOFRQWUROFLUFXLW VHH)LJXUH <RXFDQJHWFRQWLQXRXVURWDWLRQVHUYRVWKDWKDYHWKHSRVLWLRQDOIHHGEDFNGLVFRQQHFWHG
VRWKDW\RXFDQLQVWUXFWWKHVHUYRWRURWDWHFRQWLQXRXVO\FORFNZLVHDQGFRXQWHUFORFN
ZLVHZLWKVRPHFRQWURORYHUWKHVSHHG7KHVHIXQFWLRQDOLWWOHOLNHWKHEUXVKHGPRWRUV
FRYHUHGLQ5HFLSHH[FHSWWKDWFRQWLQXRXVURWDWLRQVHUYRVXVHWKHVHUYROLEUDU\FRGH
LQVWHDGRIanalogWrite
6HUYRVUHVSRQGWRFKDQJHVLQWKHGXUDWLRQRIDSXOVH$VKRUWSXOVHRIPVRUOHVVZLOO
FDXVHWKHVHUYRWRURWDWHWRRQHH[WUHPHDSXOVHGXUDWLRQRIPVRUVRZLOOURWDWHWKH
VHUYRWRWKHRWKHUH[WUHPH VHH)LJXUH 3XOVHVUDQJLQJEHWZHHQWKHVHYDOXHVZLOO
URWDWHWKHVHUYRWRDSRVLWLRQSURSRUWLRQDOWRWKHSXOVHZLGWK7KHUHLVQRVWDQGDUGIRU
WKHH[DFWUHODWLRQVKLSEHWZHHQSXOVHVDQGSRVLWLRQDQG\RXPD\QHHGWRWLQNHUZLWK
WKHFRPPDQGVLQ\RXUVNHWFKWRDGMXVWIRUWKHUDQJHRI\RXUVHUYRV
261
)LJXUH(OHPHQWVLQVLGHDKREE\VHUYR
$OWKRXJK WKH GXUDWLRQ RI WKH SXOVH LV PRGXODWHG FRQWUROOHG VHUYRV
UHTXLUH SXOVHV WKDW DUH GLIIHUHQW IURP WKH 3XOVH :LGWK 0RGXODWLRQ
3:0 RXWSXWIURP analogWrite<RXFDQGDPDJHDKREE\VHUYRE\
FRQQHFWLQJ LW WR WKH RXWSXW IURP analogWrite¢XVH WKH 6HUYR OLEUDU\
LQVWHDG
Solenoids and Relays
$OWKRXJKPRVWPRWRUVSURGXFHURWDU\PRWLRQDVROHQRLGSURGXFHVOLQHDUPRYHPHQW
ZKHQSRZHUHG$VROHQRLGKDVDPHWDOOLFFRUHWKDWLVPRYHGE\DPDJQHWLFILHOGWKDWLV
FUHDWHGZKHQFXUUHQWLVSDVVHGWKURXJKDFRLO$PHFKDQLFDOUHOD\LVDW\SHRIVROHQRLG
WKDW FRQQHFWV RU GLVFRQQHFWV HOHFWULFDO FRQWDFWV LW¦V D VROHQRLG RSHUDWLQJ D VZLWFK 5HOD\VDUHFRQWUROOHGMXVWOLNHVROHQRLGV5HOD\VDQGVROHQRLGVOLNHPRVWPRWRUVUHTXLUH
PRUHFXUUHQWWKDQDQ$UGXLQRSLQFDQVDIHO\SURYLGHDQGWKHUHFLSHVLQWKLVFKDSWHU
VKRZKRZ\RXFDQXVHDWUDQVLVWRURUH[WHUQDOFLUFXLWWRGULYHWKHVHGHYLFHV
Brushed and Brushless Motors
0RVWORZFRVWGLUHFWFXUUHQW '& PRWRUVDUHVLPSOHGHYLFHVZLWKWZROHDGVFRQQHFWHG
WREUXVKHV FRQWDFWV WKDWFRQWUROWKHPDJQHWLFILHOGRIWKHFRLOVWKDWGULYHVDPHWDOOLF
FRUH DUPDWXUH 7KHGLUHFWLRQRIURWDWLRQFDQEHUHYHUVHGE\UHYHUVLQJWKHSRODULW\RI
WKHYROWDJHRQWKHFRQWDFWV'&PRWRUVDUHDYDLODEOHLQPDQ\GLIIHUHQWVL]HVEXWHYHQ
WKHVPDOOHVW VXFKDVYLEUDWLRQPRWRUVXVHGLQFHOOSKRQHV UHTXLUHDWUDQVLVWRURURWKHU
H[WHUQDO FRQWURO WR SURYLGH DGHTXDWH FXUUHQW 7KH UHFLSHV WKDW IROORZ VKRZ KRZ WR
FRQWUROPRWRUVXVLQJDWUDQVLVWRURUDQH[WHUQDOFRQWUROFLUFXLWFDOOHGDQ+%ULGJH
262 | Chapter 8:ಗPhysical Output
)LJXUH5HODWLRQVKLSEHWZHHQWKHSXOVHZLGWKDQGWKHVHUYRDQJOHWKHVHUYRRXWSXWDUPPRYHV
SURSRUWLRQDOO\DVWKHSXOVHZLGWKLQFUHDVHVIURPPVWRPV
7KHSULPDU\FKDUDFWHULVWLFLQVHOHFWLQJDPRWRULVWRUTXH7RUTXHGHWHUPLQHVKRZPXFK
ZRUNWKHPRWRUFDQGR7\SLFDOO\KLJKHUWRUTXHPRWRUVDUHODUJHUDQGKHDYLHUDQG
GUDZPRUHFXUUHQWWKDQORZHUWRUTXHPRWRUV
%UXVKOHVVPRWRUVXVXDOO\DUHPRUHSRZHUIXODQGHIILFLHQWIRUDJLYHQVL]HWKDQEUXVKHG
PRWRUVEXWWKH\UHTXLUHPRUHFRPSOLFDWHGHOHFWURQLFFRQWURO:KHUHWKHSHUIRUPDQFH
EHQHILWRIDEUXVKOHVVPRWRULVGHVLUHGFRPSRQHQWVFDOOHGHOHFWURQLFVVSHHGFRQWURO
OHUVLQWHQGHGIRUKREE\UDGLRFRQWUROXVHFDQEHHDVLO\FRQWUROOHGE\$UGXLQREHFDXVH
WKH\DUHFRQWUROOHGPXFKOLNHDVHUYRPRWRU
Stepper Motors
6WHSSHUVDUHPRWRUVWKDWURWDWHDVSHFLILFQXPEHURIGHJUHHVLQUHVSRQVHWRFRQWURO
SXOVHV7KHQXPEHURIGHJUHHVLQHDFKVWHSLVPRWRUGHSHQGHQWUDQJLQJIURPRQHRU
WZRGHJUHHVSHUVWHSWRGHJUHHVRUPRUH
7ZRW\SHVRIVWHSSHUVDUHFRPPRQO\XVHGZLWK$UGXLQRELSRODU W\SLFDOO\ZLWKIRXU
OHDGVDWWDFKHGWRWZRFRLOV DQGXQLSRODU ILYHRUVL[OHDGVDWWDFKHGWRWZRFRLOV 7KH
DGGLWLRQDOZLUHVLQDXQLSRODUVWHSSHUDUHLQWHUQDOO\FRQQHFWHGWRWKHFHQWHURIWKHFRLOV
LQWKHILYHOHDGYHUVLRQHDFKFRLOKDVDFHQWHUWDSDQGERWKFHQWHUWDSVDUHFRQQHFWHG
WRJHWKHU 7KHUHFLSHVFRYHULQJELSRODUDQGXQLSRODUVWHSSHUVKDYHGLDJUDPVLOOXVWUDWLQJ
WKHVHFRQQHFWLRQV
8.0 Introduction | 263
Troubleshooting Sidebar
7KHPRVWFRPPRQFDXVHRISUREOHPVZKHQFRQQHFWLQJGHYLFHVWKDWUHTXLUHH[WHUQDO
SRZHULVQHJOHFWLQJWRFRQQHFWDOOWKHJURXQGVWRJHWKHU<RXU$UGXLQRJURXQGPXVWEH
FRQQHFWHGWRWKHH[WHUQDOSRZHUVXSSO\JURXQGDQGWKHJURXQGVRIH[WHUQDOGHYLFHV
EHLQJSRZHUHG
8.1 Controlling the Position of a Servo
Problem
<RXZDQWWRFRQWUROWKHSRVLWLRQRIDVHUYRXVLQJDQDQJOHFDOFXODWHGLQ\RXUVNHWFK
)RUH[DPSOH\RXZDQWDVHQVRURQDURERWWRVZLQJWKURXJKDQDUFRUPRYHWRDSRVLWLRQ
\RXVHOHFW
Solution
8VHWKH6HUYROLEUDU\GLVWULEXWHGZLWK$UGXLQR&RQQHFWWKHVHUYRSRZHUDQGJURXQG
WR D VXLWDEOH SRZHU VXSSO\ D VLQJOH KREE\ VHUYR FDQ XVXDOO\ EH SRZHUHG IURP WKH
$UGXLQR9OLQH 5HFHQWYHUVLRQVRIWKHOLEUDU\HQDEOH\RXWRFRQQHFWWKHVHUYRVLJQDO
OHDGVWRDQ\$UGXLQRGLJLWDOSLQ
+HUH LV WKH H[DPSOH 6ZHHS VNHWFK GLVWULEXWHG ZLWK $UGXLQR )LJXUH VKRZV WKH
FRQQHFWLRQV
#include <Servo.h>
Servo myservo;
// create servo object to control a servo
int angle = 0;
// variable to store the servo position
void setup()
{
myservo.attach(9);
}
// attaches the servo on pin 10 to the servo object
void loop()
{
for(angle = 0; angle < 180; angle += 1) // goes from 0 degrees to 180 degrees
{
// in steps of 1 degree
myservo.write(angle);
// tell servo to go to position in variable 'angle'
delay(20);
// waits 20ms between servo commands
}
for(angle = 180; angle >= 1; angle -= 1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos);
// tell servo to go to position in variable 'pos'
delay(20);
// waits 20ms between servo commands
}
}
264 | Chapter 8:ಗPhysical Output
)LJXUH&RQQHFWLQJDVHUYRIRUWHVWLQJZLWKWKHH[DPSOH6ZHHSVNHWFK
Discussion
7KLVH[DPSOHVZHHSVWKHVHUYREHWZHHQDQGGHJUHHV<RXPD\QHHGWRWHOOWKH
OLEUDU\WRDGMXVWWKHPLQLPXPDQGPD[LPXPSRVLWLRQVVRWKDW\RXJHWWKHUDQJHRI
PRYHPHQW\RXZDQW&DOOLQJServo.attachZLWKRSWLRQDODUJXPHQWVIRUPLQLPXPDQG
PD[LPXPSRVLWLRQVZLOODGMXVWWKHPRYHPHQW
myservo.attach(9,1000,2000 );
// use pin 9, set min to 1000us, max to 2000us
%HFDXVHW\SLFDOVHUYRVUHVSRQGWRSXOVHVPHDVXUHGLQPLFURVHFRQGVDQGQRWGHJUHHV
WKHDUJXPHQWVIROORZLQJWKHSLQQXPEHULQIRUPWKH6HUYROLEUDU\KRZPDQ\PLFUR
VHFRQGVWRXVHZKHQGHJUHHVRUGHJUHHVDUHUHTXHVWHG1RWDOOVHUYRVZLOOPRYH
RYHUDIXOOGHJUHHUDQJHVR\RXPD\QHHGWRH[SHULPHQWZLWK\RXUVWRJHWWKHUDQJH
\RXZDQW
7KHSDUDPHWHUVIRUservo.attach(pin,min,max)DUHWKHIROORZLQJ
pin
7KHSLQQXPEHUWKDWWKHVHUYRLVDWWDFKHGWR PXVWEHRU
min RSWLRQDO
7KHSXOVHZLGWKLQPLFURVHFRQGVFRUUHVSRQGLQJWRWKHPLQLPXP GHJUHH DQJOH
RQWKHVHUYR GHIDXOWVWR
max RSWLRQDO
7KHSXOVHZLGWKLQPLFURVHFRQGVFRUUHVSRQGLQJWRWKHPD[LPXP GHJUHH
DQJOHRQWKHVHUYR GHIDXOWVWR
3RZHUUHTXLUHPHQWVYDU\GHSHQGLQJRQWKHVHUYRDQGKRZPXFKWRUTXHLVQHHGHGWR
URWDWHWKHVKDIW
8.1 Controlling the Position of a Servo | 265
Download from Wow! eBook <www.wowebook.com>
<RXPD\QHHGDQH[WHUQDOVRXUFHRIRUYROWVZKHQFRQQHFWLQJPXO
WLSOHVHUYRV)RXU$$FHOOVZRUNZHOOLI\RXZDQWWRXVHEDWWHU\SRZHU
5HPHPEHU WKDW \RX PXVW FRQQHFW WKH JURXQG RI WKH H[WHUQDO SRZHU
VRXUFHWR$UGXLQRJURXQG
8.2 Controlling One or Two Servos with a Potentiometer
or Sensor
Problem
<RXZDQWWRFRQWUROWKHURWDWLRQDOGLUHFWLRQDQGVSHHGRIRQHRUWZRVHUYRVZLWKD
SRWHQWLRPHWHU)RUH[DPSOH\RXZDQWWRFRQWUROWKHSDQDQGWLOWRIDFDPHUDRUVHQVRU
FRQQHFWHGWRWKHVHUYRV7KLVUHFLSHFDQZRUNZLWKDQ\YDULDEOHYROWDJHIURPDVHQVRU
WKDWFDQEHUHDGIURPDQDQDORJLQSXW
Solution
7KHVDPHOLEUDU\FDQEHXVHGDVLQ5HFLSHZLWKWKHDGGLWLRQRIFRGHWRUHDGWKH
YROWDJHRQDSRWHQWLRPHWHU7KLVYDOXHLVVFDOHGVRWKDWWKHSRVLWLRQRIWKHSRW IURP
0WR1023 LVPDSSHGWRDYDOXHEHWZHHQDQGGHJUHHV7KHRQO\GLIIHUHQFHLQWKH
ZLULQJLVWKHDGGLWLRQRIWKHSRWHQWLRPHWHUVHH)LJXUH
#include <Servo.h>
Servo myservo;
// create servo object to control a servo
int potpin = 0; // analog pin used to connect the potentiometer
int val;
// variable to read the value from the analog pin
void setup()
{
myservo.attach(9);
}
// attaches the servo on pin 9 to the servo object
void loop()
{
val = analogRead(potpin);
val = map(val, 0, 1023, 0, 179);
myservo.write(val);
delay(15);
}
266 | Chapter 8:ಗPhysical Output
// reads the value of the potentiometer
// scale it to use it with the servo
// sets position to the scaled value
// waits for the servo to get there
)LJXUH&RQWUROOLQJDVHUYRZLWKDSRWHQWLRPHWHU
Discussion
$Q\WKLQJWKDWFDQEHUHDGIURPanalogRead VHH&KDSWHUDQG&KDSWHU FDQEHXVHG¢
IRUH[DPSOHWKHJ\URDQGDFFHOHURPHWHUUHFLSHVLQ&KDSWHUFDQEHXVHGVRWKDWWKH
DQJOHRIWKHVHUYRLVFRQWUROOHGE\WKH\DZRIWKHJ\URRUDQJOHRIWKHDFFHOHURPHWHU
8.3 Controlling the Speed of Continuous Rotation Servos
Problem
<RXZDQWWRFRQWUROWKHURWDWLRQDOGLUHFWLRQDQGVSHHGRIVHUYRVPRGLILHGIRUFRQWLQ
XRXVURWDWLRQ)RUH[DPSOH\RXDUHXVLQJWZRFRQWLQXRXVURWDWLRQVHUYRVWRSRZHUD
URERWDQG\RXZDQWWKHVSHHGDQGGLUHFWLRQWREHFRQWUROOHGE\\RXUVNHWFK
Solution
&RQWLQXRXVURWDWLRQVHUYRVDUHDIRUPRIJHDUUHGXFHGPRWRUZLWKIRUZDUGDQGEDFN
ZDUG VSHHG DGMXVWPHQW &RQWURO RI FRQWLQXRXV URWDWLRQ VHUYRV LV VLPLODU WR QRUPDO
VHUYRV7KHVHUYRURWDWHVLQRQHGLUHFWLRQDVWKHDQJOHLVLQFUHDVHGIURPGHJUHHVLW
URWDWHVLQWKHRWKHUGLUHFWLRQZKHQWKHDQJOHLVGHFUHDVHGIURPGHJUHHV7KHDFWXDO
GLUHFWLRQ IRUZDUG RU EDFNZDUG GHSHQGV RQ KRZ \RX KDYH WKH VHUYRV DWWDFKHG )LJ
XUHVKRZVWKHFRQQHFWLRQVIRUFRQWUROOLQJWZRVHUYRV
7KLVH[DPSOHVZHHSVWKHVHUYRVIURPWRGHJUHHVVRLIWKHVHUYRVZHUHFRQQHFWHG
WRZKHHOVWKHYHKLFOHZRXOGPRYHIRUZDUGDWDVORZO\LQFUHDVLQJSDFHDQGWKHQVORZ
8.3 Controlling the Speed of Continuous Rotation Servos | 267
)LJXUH&RQWUROOLQJWZRVHUYRV
GRZQWRDVWRS%HFDXVHWKHVHUYRFRQWUROFRGHLVLQloopWKLVZLOOFRQWLQXHIRUDVORQJ
DVWKHUHLVSRZHU
#include <Servo.h>
Servo myservoLeft;
Servo myservoRight;
int pos = 0;
// create servo object to control a servo
// create servo object to control a servo
// variable to store the servo position
void setup()
{
myservoLeft.attach(9);
// attaches left servo on pin 9 to servo object
myservoRight.attach(10); // attaches right servo on pin 10 to servo object
}
void loop()
{
for(angle = 90; angle < 180; angle += 1) // goes from 90 to 180 degrees
{
// in steps of 1 degree
// 90 degrees is stopped
myservoLeft.write(angle);
// rotate servo at speed given by 'angle'
myservoRight.write(180-angle);
// go in the opposite direction
delay(20);
// waits 20ms between servo commands
}
for(angle = 180; angle >= 90; angle -= 1) // goes from 180 to 90 degrees
{
myservoLeft.write(angle);
// rotate at a speed given by 'angle'
myservoRight.write(180-angle);
// other servo goes in opposite direction
}
}
268 | Chapter 8:ಗPhysical Output
Discussion
<RXFDQXVHVLPLODUFRGHIRUFRQWLQXRXVURWDWLRQDQGQRUPDOVHUYRVEXWEHDZDUHWKDW
FRQWLQXRXV URWDWLRQ VHUYRV PD\ QRW VWRS URWDWLQJ ZKHQ ZULWLQJ H[DFWO\ GHJUHHV
6RPHVHUYRVKDYHDVPDOOSRWHQWLRPHWHU\RXFDQWULPWRDGMXVWIRUWKLVRU\RXFDQDGG
RUVXEWUDFWDIHZGHJUHHVWRVWRSWKHVHUYR)RUH[DPSOHLIWKHOHIWVHUYRVWRSVURWDWLQJ
DWGHJUHHV\RXFDQFKDQJHWKHOLQHVWKDWZULWHWRWKHVHUYRVDVIROORZV
myservoLeft.write(angle+TRIM); // declare int TRIM=2; at beginning of sketch
8.4 Controlling Servos from the Serial Port
Problem
<RXZDQWWRSURYLGHFRPPDQGVWRFRQWUROVHUYRVIURPWKHVHULDOSRUW3HUKDSV\RX
ZDQWWRFRQWUROVHUYRVIURPDSURJUDPUXQQLQJRQ\RXUFRPSXWHU
Solution
<RXFDQXVHVRIWZDUHWRFRQWUROWKHVHUYRV7KLVKDVWKHDGYDQWDJHWKDWDQ\QXPEHURI
VHUYRVFDQEHVXSSRUWHG+RZHYHU\RXUVNHWFKQHHGVWRFRQVWDQWO\DWWHQGWRUHIUHVKLQJ
WKHVHUYRSRVLWLRQVRWKHORJLFFDQJHWFRPSOLFDWHGDVWKHQXPEHURIVHUYRVLQFUHDVHV
LI\RXUSURMHFWQHHGVWRSHUIRUPDORWRIRWKHUWDVNV
7KLVUHFLSHGULYHVIRXUVHUYRVDFFRUGLQJWRFRPPDQGVUHFHLYHGRQWKHVHULDOSRUW7KH
FRPPDQGVDUHRIWKHIROORZLQJIRUP
180aZULWHVWRVHUYRD
90bZULWHVWRVHUYRE
0cZULWHVWRVHUYRF
17dZULWHVWRVHUYRG
+HUHLVWKHVNHWFKWKDWGULYHVIRXUVHUYRVFRQQHFWHGRQSLQVWKURXJK
#include <Servo.h>
// the servo library
#define SERVOS 4 // the number of servos
int servoPins[SERVOS] = {7,8,9,10}; // servos on pins 7 through 10
Servo myservo[SERVOS];
void setup()
{
Serial.begin(9600);
for(int i=0; i < SERVOS; i++)
myservo[i].attach(servoPins[i]);
}
void loop()
8.4 Controlling Servos from the Serial Port | 269
{
}
serviceSerial();
// serviceSerial checks the serial port and updates position with received data
// it expects servo data in the form:
// "180a" writes 180 to servo a
// "90b writes 90 to servo b
void serviceSerial()
{
static int pos = 0;
if ( Serial.available()) {
char ch = Serial.read();
}
if(ch >= '0' && ch <= '9')
// is ch a number?
pos = pos * 10 + ch - '0';
// yes, accumulate the value
else if(ch >= 'a' && ch <= 'a'+ SERVOS) // is ch a letter for our servos?
myservo[ch - 'a'].write(pos);
// yes, save position in position array
}
Discussion
&RQQHFWLQJWKHVHUYRVLVVLPLODUWRWKHSUHYLRXVUHFLSHV(DFKVHUYROLQHZLUHJHWVFRQ
QHFWHGWRDGLJLWDOSLQ$OOVHUYRJURXQGVDUHFRQQHFWHGWR$UGXLQRJURXQG7KHVHUYR
SRZHUOLQHVDUHFRQQHFWHGWRJHWKHUDQG\RXPD\QHHGDQH[WHUQDO9RU9SRZHU
VRXUFHLI\RXUVHUYRVUHTXLUHPRUHFXUUHQWWKDQWKH$UGXLQRSRZHUVXSSO\FDQSURYLGH
$QDUUD\QDPHGmyservo VHH5HFLSH LVXVHGWRKROGUHIHUHQFHVIRUWKHIRXUVHUYRV
$forORRSLQsetupDWWDFKHVHDFKVHUYRLQWKHDUUD\WRFRQVHFXWLYHSLQVGHILQHGLQWKH
servoPinsDUUD\
,IWKHFKDUDFWHUUHFHLYHGIURPVHULDOLVDGLJLW WKHFKDUDFWHUZLOOEHJUHDWHUWKDQRUHTXDO
WR]HURDQGOHVVWKDQRUHTXDOWR LWVYDOXHLVDFFXPXODWHGLQWKHYDULDEOHpos,IWKH
FKDUDFWHULVWKHOHWWHUDWKHSRVLWLRQLVZULWWHQWRWKHILUVWVHUYRLQWKHDUUD\ WKHVHUYR
FRQQHFWHGWRSLQ 7KHOHWWHUVEFDQGGFRQWUROWKHVXEVHTXHQWVHUYRV
See Also
6HH&KDSWHUIRUPRUHRQKDQGOLQJYDOXHVUHFHLYHGRYHUVHULDO
270 | Chapter 8:ಗPhysical Output
8.5 Driving a Brushless Motor (Using a Hobby Speed Controller)
Problem
<RXKDYHDKREE\EUXVKOHVVPRWRUDQG\RXZDQWWRFRQWUROLWVVSHHG
Solution
7KLVVNHWFKXVHVWKHVDPHFRGHDV5HFLSH7KHZLULQJLVVLPLODUH[FHSWIRUWKHVSHHG
FRQWUROOHUDQGPRWRU%UXVKOHVVPRWRUVKDYHWKUHHZLQGLQJVDQGWKHVHVKRXOGEHFRQ
QHFWHGIROORZLQJWKHLQVWUXFWLRQVIRU\RXUVSHHGFRQWUROOHU VHH)LJXUH )LJXUH&RQQHFWLQJDQHOHFWURQLFVVSHHGFRQWUROOHU
Discussion
&RQVXOWWKHGRFXPHQWDWLRQIRU\RXUVSHHGFRQWUROOHUWRFRQILUPWKDWLWLVVXLWDEOHIRU
\RXUEUXVKOHVVPRWRUDQGWRYHULI\WKHZLULQJ%UXVKOHVVPRWRUVKDYHWKUHHFRQQHFWLRQV
IRUWKHWKUHHPRWRUZLUHVDQGWZRFRQQHFWLRQVIRUSRZHU0DQ\VSHHGFRQWUROOHUVSUR
YLGHSRZHURQWKHFHQWHUSLQRIWKHVHUYRFRQQHFWRU8QOHVV\RXZDQWWRSRZHUWKH
$UGXLQRERDUGIURPWKHVSHHGFRQWUROOHU\RXPXVWGLVFRQQHFWRUFXWWKLVFHQWHUZLUH
,I\RXUVSHHGFRQWUROOHUKDVDIHDWXUHWKDWSURYLGHV9SRZHUWRVHUYRV
DQGRWKHUGHYLFHV FDOOHGDEDWWHU\HOLPLQDWRUFLUFXLWRU%(&IRUVKRUW \RXPXVWGLVFRQQHFWWKLVZLUHZKHQDWWDFKLQJWKH$UGXLQRWRWKHVSHHG
FRQWUROOHU VHH)LJXUH 8.5 Driving a Brushless Motor (Using a Hobby Speed Controller) | 271
8.6 Controlling Solenoids and Relays
Problem
<RXZDQWWRDFWLYDWHDVROHQRLGRUUHOD\XQGHUSURJUDPFRQWURO6ROHQRLGVDUHHOHFWUR
PDJQHWVWKDWFRQYHUWHOHFWULFDOHQHUJ\LQWRPHFKDQLFDOPRYHPHQW$QHOHFWURPDJQHWLF
UHOD\LVDVZLWFKWKDWLVDFWLYDWHGE\DVROHQRLG
Solution
0RVWVROHQRLGVUHTXLUHPRUHSRZHUWKDQDQ$UGXLQRSLQFDQSURYLGHVRDWUDQVLVWRU
LVXVHGWRVZLWFKWKHFXUUHQWQHHGHGWRDFWLYDWHDVROHQRLG$FWLYDWLQJWKHVROHQRLGLV
DFKLHYHGE\XVLQJdigitalWriteWRVHWWKHSLQHIGH
7KLVVNHWFKWXUQVRQDWUDQVLVWRUFRQQHFWHGDVVKRZQLQ)LJXUH7KHVROHQRLGZLOO
EHDFWLYDWHGIRURQHVHFRQGHYHU\KRXU
int solenoidPin = 2;
// Solenoid connected to transitor on pin 2
void setup()
{
pinMode(ledPin, OUTPUT);
}
void loop()
{
long interval = 1000 * 60 * 60 ;
// interval = 60 minutes
digitalWrite(solenoidPin, HIGH); // activates the solenoid
delay(1000);
// waits for a second
digitalWrite(ledPin, LOW);
// deactivates the solenoid
delay(interval);
// waits one hour
}
Discussion
7KHFKRLFHRIWUDQVLVWRULVGHSHQGHQWRQWKHDPRXQWRIFXUUHQWUHTXLUHGWRDFWLYDWHWKH
VROHQRLG RU UHOD\ 7KH GDWD VKHHW PD\ VSHFLI\ WKLV LQ PLOOLDPSHUHV P$ RU DV WKH
UHVLVWDQFHRIWKHFRLO7RILQGWKHFXUUHQWQHHGHGE\\RXUVROHQRLGRUUHOD\GLYLGHWKH
YROWDJHRIWKHFRLOE\LWVUHVLVWDQFHLQRKPV)RUH[DPSOHD9UHOD\ZLWKDFRLORI
RKPVGUDZVP$ YROWV RKPV DPSVZKLFKLVP$
6PDOOWUDQVLVWRUVVXFKDVWKH1DUHVXIILFLHQWIRUVROHQRLGVUHTXLULQJXSWRDIHZ
KXQGUHGPLOOLDPSV/DUJHUVROHQRLGVZLOOUHTXLUHDKLJKHUSRZHUWUDQVLVWRUOLNHWKH
7,37,3RUVLPLODU7KHUHDUHPDQ\VXLWDEOHWUDQVLVWRUDOWHUQDWLYHVVHH$SSHQ
GL[%IRUKHOSUHDGLQJDGDWDVKHHWDQGFKRRVLQJWUDQVLVWRUV
7KHSXUSRVHRIWKHGLRGHLVWRSUHYHQWUHYHUVH(0)IURPWKHFRLOIURPGDPDJLQJWKH
WUDQVLVWRU UHYHUVH(0)LVDYROWDJHSURGXFHGZKHQFXUUHQWWKURXJKDFRLOLVVZLWFKHG
272 | Chapter 8:ಗPhysical Output
)LJXUH'ULYLQJDVROHQRLGZLWKDWUDQVLVWRU
RII 7KH SRODULW\ RI WKH GLRGH LV LPSRUWDQW WKHUH LV D FRORUHG EDQG LQGLFDWLQJ WKH
FDWKRGH¢WKLVVKRXOGEHFRQQHFWHGWRWKHVROHQRLGSRVLWLYHSRZHUVXSSO\
(OHFWURPDJQHWLFUHOD\VDUHDFWLYDWHGMXVWOLNHVROHQRLGV$VSHFLDOUHOD\FDOOHGDVROLG
VWDWHUHOD\ 665 KDVLQWHUQDOHOHFWURQLFVWKDWFDQEHGULYHQGLUHFWO\IURPDQ$UGXLQR
SLQZLWKRXWWKHQHHGIRUWKHWUDQVLVWRU&KHFNWKHGDWDVKHHWIRU\RXUUHOD\WRVHHZKDW
YROWDJHDQGFXUUHQWLWUHTXLUHVDQ\WKLQJPRUHWKDQP$DWYROWVZLOOUHTXLUHDFLUFXLW
VXFKDVWKHRQHVKRZQLQ)LJXUH
8.7 Making an Object Vibrate
Problem
<RXZDQWVRPHWKLQJWRYLEUDWHXQGHU$UGXLQRFRQWURO)RUH[DPSOH\RXZDQW\RXU
SURMHFWWRVKDNHIRURQHVHFRQGHYHU\PLQXWH
Solution
&RQQHFWDYLEUDWLRQPRWRUDVVKRZQLQ)LJXUH
8.7 Making an Object Vibrate | 273
)LJXUH&RQQHFWLQJDYLEUDWLRQPRWRU
7KHIROORZLQJVNHWFKZLOOWXUQRQWKHYLEUDWLRQPRWRUIRURQHVHFRQGHDFKPLQXWH
/*
* Vibrate sketch
* Vibrate for one second every minute
*
*/
const int motorPin
= 3;
// vibration motor transistor is connected to pin 3
void setup()
{
pinMode(motorPin, OUTPUT);
}
void loop()
{
digitalWrite(motorPin, HIGH); //vibrate
delay(1000); // delay one second
digitalWrite(motorPin, LOW);
// stop vibrating
delay(59000); // wait 59 seconds.
}
Discussion
7KLVUHFLSHXVHVDPRWRUGHVLJQHGWRYLEUDWHVXFKDVWKH6SDUN)XQ52%,I\RX
KDYHDQROGFHOOSKRQH\RXQRORQJHUQHHGLWPD\FRQWDLQWLQ\YLEUDWLRQPRWRUVWKDW
ZRXOG EH VXLWDEOH 9LEUDWLRQ PRWRUV UHTXLUH PRUH SRZHU WKDQ DQ $UGXLQR SLQ FDQ
SURYLGHVRDWUDQVLVWRULVXVHGWRVZLWFKWKHPRWRUFXUUHQWRQDQGRII$OPRVWDQ\131
WUDQVLVWRUFDQEHXVHG)LJXUHVKRZVWKHFRPPRQ1 VHHWKLVERRN¦VZHE
VLWHIRUVXSSOLHULQIRUPDWLRQRQWKLVDQGWKHRWKHUFRPSRQHQWVXVHG $NLORKPUH
VLVWRUFRQQHFWVWKHRXWSXWSLQWRWKHWUDQVLVWRUEDVHWKHYDOXHLVQRWFULWLFDODQG\RX
FDQXVHYDOXHVXSWRNLORKPRUVR WKHUHVLVWRUSUHYHQWVWRRPXFKFXUUHQWIORZLQJ
274 | Chapter 8:ಗPhysical Output
WKURXJKWKHRXWSXWSLQ 7KHGLRGHDEVRUEV RUVQXEV¢LW¦VVRPHWLPHVFDOOHGDVQXEEHU
GLRGH YROWDJHVSURGXFHGE\WKHPRWRUZLQGLQJVDVLWURWDWHV7KHFDSDFLWRUDEVRUEV
YROWDJHVSLNHVSURGXFHGZKHQWKHEUXVKHV FRQWDFWVFRQQHFWLQJHOHFWULFFXUUHQWWRWKH
PRWRUZLQGLQJV RSHQDQGFORVH7KHRKPUHVLVWRULVQHHGHGWROLPLWWKHDPRXQWRI
FXUUHQWIORZLQJWKURXJKWKHPRWRU
7KLVVNHWFKVHWVWKHRXWSXWSLQHIGHIRURQHVHFRQG PLOOLVHFRQGV DQGWKHQZDLWV
IRUVHFRQGV7KHWUDQVLVWRUZLOOWXUQRQ FRQGXFW ZKHQWKHSLQLV HIGHDOORZLQJ
FXUUHQWWRIORZWKURXJKWKHPRWRU
+HUHLVDYDULDWLRQRIWKLVVNHWFKWKDWXVHVDVHQVRUWRPDNHWKHPRWRUYLEUDWH7KH
ZLULQJLVVLPLODUWRWKDWVKRZQLQ)LJXUHZLWKWKHDGGLWLRQRIDSKRWRFHOOFRQQHFWHG
WRDQDORJSLQ VHH5HFLSH /*
* Vibrate_Photocell sketch
* Vibrate when photosensor detects light above ambient level
*
*/
const int motorPin = 3; // vibration motor transistor is connected to pin 3
const int sensorPin = 0; // Photodetector connected to analog input 0
int sensorAmbient = 0;
// ambient light level (calibrated in setup)
const int thresholdMargin = 100;
// how much above ambient needed to vibrate
void setup()
{
pinMode(motorPin, OUTPUT);
sensorAmbient = analogRead(sensorPin); // get startup light level;
}
void loop()
{
int sensorValue = analogRead(sensorPin);
if( sensorValue > sensorAmbient + thresholdMargin)
{
digitalWrite(motorPin, HIGH); //vibrate
}
else
{
digitalWrite(motorPin, LOW);
// stop vibrating
}
}
+HUHWKHRXWSXWSLQLVWXUQHGRQZKHQDOLJKWVKLQHVRQWKHSKRWRFHOO:KHQWKHVNHWFK
VWDUWV WKH EDFNJURXQG OLJKW OHYHO RQ WKH VHQVRU LV UHDG DQG VWRUHG LQ WKH YDULDEOH
sensorAmbient /LJKW OHYHOV UHDG LQ loop WKDW DUH KLJKHU WKDQ WKLV ZLOO WXUQ RQ WKH
YLEUDWLRQPRWRU
8.7 Making an Object Vibrate | 275
8.8 Driving a Brushed Motor Using a Transistor
Problem
<RXZDQWWRWXUQDPRWRURQDQGRII<RXPD\ZDQWWRFRQWUROLWVVSHHG7KHPRWRU
RQO\QHHGVWRWXUQLQRQHGLUHFWLRQ
Solution
7KLVVNHWFKWXUQVWKHPRWRURQDQGRIIDQGFRQWUROVLWVVSHHGIURPFRPPDQGVUHFHLYHG
RQWKHVHULDOSRUW )LJXUHVKRZVWKHFRQQHFWLRQV /*
* SimpleBrushed sketch
* commands from serial port control motor speed
* digits '0' through '9' are valid where '0' is off, '9' is max speed
*/
const int motorPins = 3; // motor driver is connected to pin 3
void setup()
{
Serial.begin(9600);
}
void loop()
{
if ( Serial.available()) {
char ch = Serial.read();
if(ch >= '0' && ch <= '9')
// is ch a number?
{
int speed = map(ch, '0', '9', 0, 255);
analogWrite(3, speed);
Serial.println(speed);
}
else
{
Serial.print("Unexpected character ");
Serial.println(ch);
}
}
}
Discussion
7KLVUHFLSHLVVLPLODUWR5HFLSHWKHGLIIHUHQFHLVWKDWanalogWriteLVXVHGWRFRQWURO
WKHVSHHGRIWKHPRWRU6HH£$QDORJ2XWSXW¤RQSDJHLQ&KDSWHUIRUPRUHRQ
analogWriteDQG3XOVH:LGWK0RGXODWLRQ 3:0 276 | Chapter 8:ಗPhysical Output
)LJXUH'ULYLQJDEUXVKHGPRWRU
8.9 Controlling the Direction of a Brushed Motor
with an H-Bridge
Problem
<RXZDQWWRFRQWUROWKHGLUHFWLRQRIDEUXVKHGPRWRU¢IRUH[DPSOH\RXZDQWWRFDXVH
DPRWRUWRURWDWHLQRQHGLUHFWLRQRUWKHRWKHUIURPVHULDOSRUWFRPPDQGV
Solution
$Q+%ULGJHFDQFRQWUROWZREUXVKHGPRWRUV)LJXUHVKRZVWKHFRQQHFWLRQVIRU
WKH/'+%ULGJH,&\RXFDQDOVRXVHWKH61ZKLFKKDVWKHVDPHSLQOD\RXW
/*
* Brushed_H_Bridge_simple sketch
* commands from serial port control motor direction
* + or - set the direction, any other key stops the motor
*/
const int in1Pin = 5;
const int in2Pin = 4;
// H-Bridge input pins
void setup()
{
Serial.begin(9600);
pinMode(in1Pin, OUTPUT);
pinMode(in2Pin, OUTPUT);
Serial.println("+ - to set direction, any other key stops motor");
}
8.9 Controlling the Direction of a Brushed Motor with an H-Bridge | 277
void loop()
{
if ( Serial.available()) {
char ch = Serial.read();
if (ch == '+')
{
Serial.println("CW");
digitalWrite(in1Pin,LOW);
digitalWrite(in2Pin,HIGH);
}
else if (ch == '-')
{
Serial.println("CCW");
digitalWrite(in1Pin,HIGH);
digitalWrite(in2Pin,LOW);
}
else
{
Serial.print("Stop motor");
digitalWrite(in1Pin,LOW);
digitalWrite(in2Pin,LOW);
}
}
}
)LJXUH&RQQHFWLQJWZREUXVKHGPRWRUVXVLQJDQ/'+%ULGJH
278 | Chapter 8:ಗPhysical Output
Discussion
7DEOHVKRZVKRZWKHYDOXHVRQWKH+%ULGJHLQSXWDIIHFWWKHPRWRU,QWKHVNHWFK
LQWKLVUHFLSH¦V6ROXWLRQDVLQJOHPRWRULVFRQWUROOHGXVLQJWKH,1DQG,1SLQVWKH
(1SLQLVSHUPDQHQWO\HIGHEHFDXVHLWLVFRQQHFWHGWR9
7DEOH/RJLFWDEOHIRU+%ULGJH
EN
IN1
IN2
Function
HIGH
LOW
HIGH
Turn clockwise
HIGH
HIGH
LOW
Turn counterclockwise
HIGH
LOW
LOW
Motor stop
HIGH
HIGH
HIGH
Motor stop
LOW
Ignored
Ignored
Motor stop
)LJXUHVKRZVKRZDVHFRQGPRWRUFDQEHFRQQHFWHG7KHIROORZLQJVNHWFKFRQWUROV
ERWKPRWRUVWRJHWKHU
/*
* Brushed_H_Bridge_simple2 sketch
* commands from serial port control motor direction
* + or - set the direction, any other key stops the motors
*/
const int in1Pin = 5;
const int in2Pin = 4;
// H-Bridge input pins
const int in3Pin = 3;
const int in4Pin = 2;
// H-Bridge pins for second motor
void setup()
{
Serial.begin(9600);
pinMode(in1Pin, OUTPUT);
pinMode(in2Pin, OUTPUT);
pinMode(in3Pin, OUTPUT);
pinMode(in4Pin, OUTPUT);
Serial.println("+ - sets direction of motors, any other key stops motors");
}
void loop()
{
if ( Serial.available()) {
char ch = Serial.read();
if (ch == '+')
8.9 Controlling the Direction of a Brushed Motor with an H-Bridge | 279
{
Serial.println("CW");
// first motor
digitalWrite(in1Pin,LOW);
digitalWrite(in2Pin,HIGH);
//second motor
digitalWrite(in3Pin,LOW);
digitalWrite(in4Pin,HIGH);
}
else if (ch == '-')
{
Serial.println("CCW");
digitalWrite(in1Pin,HIGH);
digitalWrite(in2Pin,LOW);
digitalWrite(in3Pin,HIGH);
digitalWrite(in4Pin,LOW);
}
else
{
Serial.print("Stop motors");
digitalWrite(in1Pin,LOW);
digitalWrite(in2Pin,LOW);
digitalWrite(in3Pin,LOW);
digitalWrite(in4Pin,LOW);
}
}
}
8.10 Controlling the Direction and Speed of a Brushed Motor
with an H-Bridge
Problem
<RX ZDQW WR FRQWURO WKH GLUHFWLRQ DQG VSHHG RI D EUXVKHG PRWRU 7KLV H[WHQGV WKH
IXQFWLRQDOLW\ RI 5HFLSH E\ FRQWUROOLQJ ERWK PRWRU GLUHFWLRQ DQG VSHHG WKURXJK
FRPPDQGVIURPWKHVHULDOSRUW
Solution
&RQQHFWDEUXVKHGPRWRUWRWKHRXWSXWSLQVRIWKH+%ULGJHDVVKRZQLQ)LJXUH
280 | Chapter 8:ಗPhysical Output
)LJXUH&RQQHFWLQJDEUXVKHGPRWRUXVLQJDQDORJ:ULWHIRUVSHHGFRQWURO
7KLVVNHWFKXVHVFRPPDQGVIURPWKH6HULDO0RQLWRUWRFRQWUROWKHVSHHGDQGGLUHFWLRQ
RI WKH PRWRU 6HQGLQJ £¤ ZLOO VWRS WKH PRWRU DQG WKH GLJLWV £¤ WKURXJK £¤ ZLOO
FRQWUROWKHVSHHG6HQGLQJ£¤DQG£¤ZLOOVHWWKHPRWRUGLUHFWLRQ
/*
* Brushed_H_Bridge sketch
* commands from serial port control motor speed and direction
* digits '0' through '9' are valid where '0' is off, '9' is max speed
* + or - set the direction
*/
const int enPin = 5;
const int in1Pin = 7;
const int in2Pin = 4;
// H-Bridge enable pin
// H-Bridge input pins
void setup()
{
Serial.begin(9600);
pinMode(in1Pin, OUTPUT);
pinMode(in2Pin, OUTPUT);
Serial.println("Speed (0-9) or + - to set direction");
}
void loop()
{
if ( Serial.available()) {
char ch = Serial.read();
8.10 Controlling the Direction and Speed of a Brushed Motor with an H-Bridge | 281
if(ch >= '0' && ch <= '9')
// is ch a number?
{
int speed = map(ch, '0', '9', 0, 255);
analogWrite(enPin, speed);
Serial.println(speed);
}
else if (ch == '+')
{
Serial.println("CW");
digitalWrite(in1Pin,LOW);
digitalWrite(in2Pin,HIGH);
}
else if (ch == '-')
{
Serial.println("CCW");
digitalWrite(in1Pin,HIGH);
digitalWrite(in2Pin,LOW);
}
else
{
Serial.print("Unexpected character ");
Serial.println(ch);
}
}
}
Discussion
7KLVUHFLSHLVVLPLODUWR5HFLSHLQZKLFKPRWRUGLUHFWLRQLVFRQWUROOHGE\WKHOHYHOV
RQWKH,1DQG,1SLQV%XWLQDGGLWLRQVSHHGLVFRQWUROOHGE\WKHanalogWriteYDOXH
RQWKH(1SLQ VHH&KDSWHUIRUPRUHRQ3:0 :ULWLQJDYDOXHRI 0ZLOOVWRSWKH
PRWRUZULWLQJ255ZLOOUXQWKHPRWRUDWIXOOVSHHG7KHPRWRUVSHHGZLOOYDU\LQSUR
SRUWLRQWRYDOXHVZLWKLQWKLVUDQJH
8.11 Using Sensors to Control the Direction and Speed of
Brushed Motors (L293 H-Bridge)
Problem
<RXZDQWWRFRQWUROWKHGLUHFWLRQDQGVSHHGRIEUXVKHGPRWRUVZLWKIHHGEDFNIURP
VHQVRUV)RUH[DPSOH\RXZDQWWZRSKRWRVHQVRUVWRFRQWUROPRWRUVSHHGDQGGLUHFWLRQ
WRFDXVHDURERWWRPRYHWRZDUGDEHDPRIOLJKW
Solution
7KLV6ROXWLRQXVHVVLPLODUPRWRUFRQQHFWLRQVWRWKRVHVKRZQLQ)LJXUHEXWZLWK
WKHDGGLWLRQRIWZROLJKWGHSHQGHQWUHVLVWRUVDVVKRZQLQ)LJXUH
282 | Chapter 8:ಗPhysical Output
)LJXUH7ZRPRWRUVFRQWUROOHGXVLQJVHQVRUV
7KHVNHWFKPRQLWRUVWKHOLJKWOHYHORQWKHVHQVRUVDQGGULYHVWKHPRWRUVWRVWHHUWRZDUG
WKHVHQVRUGHWHFWLQJWKHEULJKWHUOLJKWOHYHO
/*
* Brushed_H_Bridge_Direction sketch
* uses photo sensors to control motor direction
* robot moves in the direction of a light
*/
int leftPins[] = {5,7,4}; // on pin for PWM, two pins for motor direction
int rightPins[] = {6,3,2};
const int leftSensorPin = 0; // analog pins with sensors
const int rightSensorPin = 1;
int sensorThreshold = 0;
int looks = 0;
// must have this much light on a sensor to move
// the number of attempts to turn and find light
void setup()
{
for(int i=1; i < 3; i++)
{
pinMode(leftPins[i], OUTPUT);
pinMode(rightPins[i], OUTPUT);
}
}
void loop()
{
int leftVal = analogRead(leftSensorPin);
8.11 Using Sensors to Control the Direction and Speed of Brushed Motors (L293 H-Bridge) | 283
int rightVal = analogRead(rightSensorPin);
if(sensorThreshold == 0) // have the sensors been calibrated ?
sensorThreshold = (leftVal + rightVal) / 2; // no, calibrate sensors
}
if( leftVal < sensorThreshold && rightVal < sensorThreshold)
{
if(looks < 4) // limit the number of consecutive looks
{
lookAround();
looks = looks + 1;
}
}
else
{
// if there is adequate light to move ahead
setSpeed(rightPins, map( rightVal,0,1023, 0,255));
setSpeed(leftPins, map(leftVal,0,1023,0,255));
looks = 0; // reset the looks counter
}
void lookAround()
{
// rotate left for half a second
setSpeed(leftPins, -127 );
setSpeed(rightPins, 127 );
delay(500);
setSpeed(rightPins, 0 );
setSpeed(leftPins, 127 );
}
void setSpeed(int pins[], int speed )
{
if(speed < 0)
{
digitalWrite(pins[1],HIGH);
digitalWrite(pins[2],LOW);
speed = -speed;
}
else
{
digitalWrite(pins[1],LOW);
digitalWrite(pins[2],HIGH);
}
analogWrite(pins[0], speed);
}
Discussion
7KLVVNHWFKFRQWUROVWKHVSHHGRIWZRPRWRUVLQUHVSRQVHWRWKHDPRXQWRIOLJKWGHWHFWHG
E\WZRSKRWRFHOOV7KHSKRWRFHOOVDUHDUUDQJHGVRWKDWDQLQFUHDVHLQOLJKWRQRQHVLGH
ZLOOLQFUHDVHWKHVSHHGRIWKHPRWRURQWKHRWKHUVLGH7KLVFDXVHVWKHURERWWRWXUQ
WRZDUGWKHVLGHZLWKWKHEULJKWHUOLJKW/LJKWVKLQLQJHTXDOO\RQERWKFHOOVPDNHVWKH
284 | Chapter 8:ಗPhysical Output
URERWPRYHIRUZDUGLQDVWUDLJKWOLQH,QVXIILFLHQWOLJKWFDXVHVWKHURERWWRVWRSDQG
ORRNDURXQGWRVHHLIWKHUHLVDOLJKWVRXUFHFRPLQJIURPDQ\RWKHUGLUHFWLRQ
/LJKWLVVHQVHGWKURXJKDQDORJLQSXWVDQG VHH5HFLSH :KHQWKHSURJUDP
VWDUWVWKHDPELHQWOLJKWLVPHDVXUHGDQGWKLVWKUHVKROGLVXVHGWRGHWHUPLQHWKHPLQL
PXP OLJKW OHYHO QHHGHG WR PRYH WKH URERW :KHQ OLJKW GURSV EHORZ WKH WKUHVKROG
WKHlookAroundIXQFWLRQLVFDOOHGWRURWDWHWKHURERWWRVHDUFKIRUPRUHOLJKW
0RWRUVSHHGLVFRQWUROOHGLQWKH setSpeedIXQFWLRQ7ZRSLQVDUHXVHGWRFRQWUROWKH
GLUHFWLRQIRUHDFKPRWRUDQGZLWKDQRWKHUSLQWRFRQWUROVSHHG7KHSLQQXPEHUVDUH
KHOGLQWKHleftPinsDQGrightPinsDUUD\V7KHILUVWSLQLQHDFKDUUD\LVWKHVSHHGSLQ
WKHRWKHUWZRSLQVDUHIRUGLUHFWLRQ
$QDOWHUQDWLYHWRWKH/LVWKH7RVKLED)%)1*7KLVFDQEHXVHGLQDQ\RIWKH
UHFLSHVVKRZLQJWKH/')LJXUHVKRZVWKHZLULQJIRUWKH)%DVXVHGRQ
WKH3ROROXEUHDNRXWERDUG 6SDUN)XQ52% )LJXUH+%ULGJHZLULQJIRUWKH3ROROXEUHDNRXWERDUG
<RXFDQUHGXFHWKHQXPEHURISLQVQHHGHGE\DGGLQJDGGLWLRQDOKDUGZDUHWRFRQWURO
WKHGLUHFWLRQSLQV7KLVLVGRQHE\XVLQJRQO\RQHSLQSHUPRWRUIRUGLUHFWLRQZLWKD
WUDQVLVWRURUORJLFJDWHWRLQYHUWWKHOHYHORQWKHRWKHU+%ULGJHLQSXW<RXFDQILQG
FLUFXLWGLDJUDPVIRUWKLVLQWKH$UGXLQRZLNLEXWLI\RXZDQWVRPHWKLQJDOUHDG\ZLUHG
XS\RXFDQXVHDQ+%ULGJHVKLHOGVXFKDVWKH)UHHGXLQR0RWRUFRQWUROVKLHOG 1.&
8.11 Using Sensors to Control the Direction and Speed of Brushed Motors (L293 H-Bridge) | 285
(OHFWURQLFV$5' RUWKH$UGXPRWRIURP6SDUN)XQ '(9 7KHVHVKLHOGV
SOXJGLUHFWO\LQWR$UGXLQRDQGRQO\UHTXLUHFRQQHFWLRQVWRWKHPRWRUSRZHUVXSSO\
DQGZLQGLQJV
+HUHLVWKHVNHWFKUHYLVHGIRUWKH$UGXPRWRVKLHOG
/*
* Brushed_H_Ardumoto sketch
* uses photo sensors to control motor direction
* robot moves in the direction of a light
*/
int leftPins[] = {10,12};
int rightPins[] = {11,13};
// one pin for PWM, one pin for motor direction
const int leftSensorPin = 0; // analog pins with sensors
const int rightSensorPin = 1;
int sensorThreshold = 0;
int looks = 0;
// must have this much light on a sensor to move
// the number of attempts to turn and find light
void setup()
{
pinMode(leftPins[1], OUTPUT);
pinMode(rightPins[1], OUTPUT);
Serial.begin(9600);
}
7KHloopDQGlookAroundIXQFWLRQVDUHLGHQWLFDOWRWKHSUHFHGLQJVNHWFKsetSpeedKDV
OHVVFRGHEHFDXVHKDUGZDUHRQWKHVKLHOGDOORZVDVLQJOHSLQWRFRQWUROPRWRUGLUHFWLRQ
void setSpeed(int pins[], int speed )
{
if(speed < 0)
{
digitalWrite(pins[1],HIGH);
speed = -speed;
}
else
{
digitalWrite(pins[1],LOW);
}
analogWrite(pins[0], speed);
}
7KHSLQDVVLJQPHQWVIRUWKH)UHHGXLQRVKLHOGDUHDVIROORZV
int leftPins[] = {10,13}; // PWM, Direction
int rightPins[] = {9,12}; // PWM, Direction
,I\RXKDYHDGLIIHUHQWVKLHOG\RXZLOOQHHGWRVHHWKHGDWDVKHHWDQGPDNHVXUHWKH
YDOXHVLQWKHVNHWFKPDWFKWKHSLQVXVHGIRU3:0DQGGLUHFWLRQ
286 | Chapter 8:ಗPhysical Output
See Also
7KHGDWDVKHHWIRUWKH3ROROXERDUGKWWSZZZSROROXFRPILOH-7%)1*SGI
7KH SURGXFW SDJH IRU WKH )UHHGXLQR VKLHOG KWWSZZZQNFHOHFWURQLFVFRPIUHHGXLQR
DUGXLQRPRWRUFRQWUROVKLHOGNLWKWPO
7KHSURGXFWSDJHIRUWKH$UGXPRWRVKLHOGKWWSZZZVSDUNIXQFRPFRPPHUFHSURG
XFWBLQIRSKS"SURGXFWVBLG 8.12 Driving a Bipolar Stepper Motor
Problem
<RXKDYHDELSRODU IRXUZLUH VWHSSHUPRWRUDQG\RXZDQWWRVWHSLWXQGHUSURJUDP
FRQWUROXVLQJDQ+%ULGJH
Solution
7KLVVNHWFKVWHSVWKHPRWRULQUHVSRQVHWRVHULDOFRPPDQGV$QXPHULFYDOXHIROORZHG
E\DVWHSVLQRQHGLUHFWLRQDVWHSVLQWKHRWKHU)RUH[DPSOHVWHSVDVWHS
PRWRUWKURXJKRQHFRPSOHWHUHYROXWLRQLQRQHGLUHFWLRQDQGVWHSVKDOIDUHYROXWLRQ
LQWKHRWKHUGLUHFWLRQ)LJXUHVKRZVWKHFRQQHFWLRQVWRDIRXUZLUHELSRODUVWHSSHU
XVLQJWKH/+%ULGJH
/*
* Stepper_bipolar sketch
*
* stepper is controlled from the serial port.
* a numeric value followed by '+' or '-' steps the motor
*
*
* http://www.arduino.cc/en/Reference/Stepper
*/
#include <Stepper.h>
// change this to the number of steps on your motor
#define STEPS 24
// create an instance of the stepper class, specifying
// the number of steps of the motor and the pins it's
// attached to
Stepper stepper(STEPS, 2, 3, 4, 5);
int steps = 0;
void setup()
{
// set the speed of the motor to 30 RPMs
8.12 Driving a Bipolar Stepper Motor | 287
}
stepper.setSpeed(30);
Serial.begin(9600);
void loop()
{
if ( Serial.available()) {
char ch = Serial.read();
if(ch >= '0' && ch <= '9'){
steps = steps * 10 + ch - '0';
}
else if(ch == '+'){
stepper.step(steps);
steps = 0;
}
else if(ch == '-'){
stepper.step(steps * -1);
steps = 0;
}
}
// is ch a number?
// yes, accumulate the value
}
)LJXUH)RXUZLUHELSRODUVWHSSHUXVLQJ/+%ULGJH
Discussion
,I\RXUVWHSSHUUHTXLUHVDKLJKHUFXUUHQWWKDQWKH/FDQSURYLGH P$IRUWKH
/' \RXFDQXVHWKH61FKLSWKDWKDQGOHVXSWRDPS)RUFXUUHQWXSWR
DPSV\RXFDQXVHWKH/FKLS7KH/FDQXVHWKHVDPHVNHWFKDVVKRZQLQWKLV
UHFLSH¦V6ROXWLRQDQGLWVKRXOGEHFRQQHFWHGDVVKRZQLQ)LJXUH
288 | Chapter 8:ಗPhysical Output
)LJXUH8QLSRODUVWHSSHUZLWK/
$VLPSOHZD\WRFRQQHFWDQ/WR$UGXLQRLVWRXVHWKH6SDUN)XQ$UGXPRWRVKLHOG
'(9 7KLVSOXJVRQWRSRIDQ$UGXLQRERDUGDQGRQO\UHTXLUHVH[WHUQDOFRQ
QHFWLRQWRWKHPRWRUZLQGLQJVWKHPRWRUSRZHUFRPHVIURPWKH$UGXLQR9LQ H[WHUQDO
9ROWDJH,QSXW SLQ,QLVFRQWUROOHGE\SLQDQG(1$LVSLQ,QLVFRQQHFWHG
WRSLQDQG(1%LVRQSLQ0DNHWKHIROORZLQJFKDQJHVWRWKHFRGHWRXVHWKH
SUHFHGLQJVNHWFKZLWK$UGXPRWR
Stepper stepper(STEPS, 12,13);
int steps = 0;
,Qsetup
pinMode(10, OUTPUT);
digitalWrite(10, LOW);
// enable A
// set the speed of the motor to 30 RPMs
stepper.setSpeed(30);
Serial.begin(9600);
pinMode(11, OUTPUT);
digitalWrite(11, LOW);
// enable B
7KHloopFRGHLVWKHVDPHDVWKHSUHYLRXVVNHWFK
8.12 Driving a Bipolar Stepper Motor | 289
8.13 Driving a Bipolar Stepper Motor (Using the EasyDriver
Board)
Problem
<RXKDYHDELSRODU IRXUZLUH VWHSSHUPRWRUDQG\RXZDQWWRVWHSLWXQGHUSURJUDP
FRQWUROXVLQJWKH(DV\'ULYHUERDUG
Solution
7KLV 6ROXWLRQ LV VLPLODU WR 5HFLSH EXW LW XVHV WKH SRSXODU (DV\'ULYHU ERDUG
)LJXUHVKRZVWKHFRQQHFWLRQV
)LJXUH&RQQHFWLQJWKH(DV\'ULYHUERDUG
7KHIROORZLQJVNHWFKFRQWUROVWKHVWHSGLUHFWLRQDQGFRXQWIURPWKHVHULDOSRUW8QOLNH
WKHFRGHLQ5HFLSHLWGRHVQRWUHTXLUHWKHVWHSSHUOLEUDU\EHFDXVHWKH(DV\'ULYHU
ERDUGKDQGOHVWKHFRQWURORIWKHPRWRUFRLOVLQKDUGZDUH
/*
* Stepper_Easystepper sketch
*
* stepper is controlled from the serial port.
* a numeric value followed by '+' or '-' steps the motor
290 | Chapter 8:ಗPhysical Output
*
*/
const int dirPin = 2;
const int stepPin = 3;
int speed = 100;
int steps = 0;
// desired speed in steps per second
// the number of steps to make
void setup()
{
pinMode(dirPin, OUTPUT);
pinMode(stepPin, OUTPUT);
Serial.begin(9600);
}
void loop()
{
if ( Serial.available()) {
char ch = Serial.read();
if(ch >= '0' && ch <= '9'){
steps = steps * 10 + ch - '0';
}
else if(ch == '+'){
step(steps);
steps = 0;
}
else if(ch == '-'){
step(-steps);
steps = 0;
}
else if(ch == 's'){
speed = steps;
Serial.print("Setting speed to ");
Serial.println(steps);
steps = 0;
}
}
// is ch a number?
// yes, accumulate the value
}
void step(int steps)
{
int stepDelay = 1000 / speed;
int stepsLeft;
//delay in ms for speed given as steps per sec
// determine direction based on whether steps_to_mode is + or if (steps > 0)
{
digitalWrite(dirPin, HIGH);
stepsLeft = steps;
}
if (steps < 0)
{
digitalWrite(dirPin, LOW);
8.13 Driving a Bipolar Stepper Motor (Using the EasyDriver Board) | 291
Download from Wow! eBook <www.wowebook.com>
}
stepsLeft = -steps;
}
// decrement the number of steps, moving one step each time
while(stepsLeft > 0)
{
digitalWrite(stepPin,HIGH);
delayMicroseconds(1);
digitalWrite(stepPin,LOW);
delay(stepDelay);
stepsLeft--;
// decrement the steps left
}
Discussion
7KH(DV\'ULYHUERDUGLVSRZHUHGWKURXJKWKHSLQVPDUNHG£0¤DQG£*QG¤ VKRZQ
LQWKHXSSHUULJKWRI)LJXUH 7KHERDUGRSHUDWHVZLWKYROWDJHVEHWZHHQYROWV
DQGYROWVFKHFNWKHVSHFLILFDWLRQVRI\RXUVWHSSHUPRWRUIRUWKHFRUUHFWRSHUDWLQJ
YROWDJH,I\RXDUHXVLQJD9VWHSSHU\RXPXVWSURYLGHYROWVWRWKHSLQVPDUNHG
£*QG¤DQG£9¤ WKHVHSLQVDUHRQWKHORZHUOHIWRIWKH(DV\'ULYHUERDUG DQGFXW
WKHMXPSHURQ WKH SULQWHG FLUFXLW ERDUG PDUNHG£$3:5¤ WKLVGLVFRQQHFWVWKHRQ
ERDUG UHJXODWRU DQG SRZHUV WKH PRWRU DQG (DV\'ULYHU ERDUG IURP DQ H[WHUQDO 9
VXSSO\ <RXFDQUHGXFHFXUUHQWFRQVXPSWLRQZKHQWKHPRWRULVQRWVWHSSLQJE\FRQQHFWLQJ
WKH(QDEOHSLQWRDVSDUHGLJLWDORXWSXWDQGVHWWLQJWKLV HIGHWRGLVDEOHRXWSXW D LOW
YDOXHHQDEOHVRXWSXW 6WHSSLQJRSWLRQVDUHVHOHFWHGE\FRQQHFWLQJWKH06DQG06SLQVWR9 HIGH RU
*QG LOW DVVKRZQLQ7DEOH7KHGHIDXOWRSWLRQVZLWKWKHERDUGFRQQHFWHGDV
VKRZQLQ)LJXUHZLOOXVHHLJKWKVWHSUHVROXWLRQ 06DQG06DUHHIGH5HVHWLV
HIGHDQG(QDEOHLVLOW 7DEOH0LFURVWHSRSWLRQV
Resolution
MS1
MS2
Full step
LOW
LOW
Half step
HIGH
LOW
Quarter step
LOW
HIGH
Eighth step
HIGH
HIGH
<RXFDQPRGLI\WKHFRGHVRWKDWWKHVSHHGYDOXHGHWHUPLQHVWKHUHYROXWLRQVSHUVHFRQG
DVIROORZV
// use the following for speed given in RPM
int speed = 100;
// desired speed in RPM
int stepsPerRevolution = 200; // this line sets steps for one revolution
292 | Chapter 8:ಗPhysical Output
&KDQJHWKHVWHSIXQFWLRQVRWKDWWKHILUVWOLQHLVDVIROORZV
int stepDelay = 60L * 1000L / stepsPerRevolution / speed; // speed as RPM
(YHU\WKLQJHOVHFDQUHPDLQWKHVDPHEXWQRZWKHVSHHGFRPPDQG\RXVHQGZLOOEH
WKH530RIWKHPRWRUZKHQLWVWHSV
8.14 Driving a Unipolar Stepper Motor (ULN2003A)
Problem
<RXKDYHDXQLSRODU ILYHRUVL[ZLUH VWHSSHUPRWRUDQG\RXZDQWWRFRQWUROLWXVLQJ
D8/1$'DUOLQJWRQGULYHUFKLS
Solution
&RQQHFWDXQLSRODUVWHSSHUDVVKRZQLQ)LJXUH7KH9FRQQHFWLRQJRHVWRDSRZHU
VXSSO\UDWHGIRUWKHYROWDJHDQGFXUUHQWQHHGHGE\\RXUPRWRU
)LJXUH8QLSRODUVWHSSHUFRQQHFWHGXVLQJ8/1GULYHU
8.14 Driving a Unipolar Stepper Motor (ULN2003A) | 293
7KHIROORZLQJVNHWFKVWHSVWKHPRWRUXVLQJFRPPDQGVIURPWKHVHULDOSRUW$QXPHULF
YDOXHIROORZHGE\DVWHSVLQRQHGLUHFWLRQDVWHSVLQWKHRWKHU
/*
* Stepper sketch
*
* stepper is controlled from the serial port.
* a numeric value followed by '+' or '-' steps the motor
*
*
* http://www.arduino.cc/en/Reference/Stepper
*/
#include <Stepper.h>
// change this to the number of steps on your motor
#define STEPS 24
// create an instance of the stepper class, specifying
// the number of steps of the motor and the pins it's
// attached to
Stepper stepper(STEPS, 2, 3, 4, 5);
int steps = 0;
void setup()
{
stepper.setSpeed(30);
Serial.begin(9600);
}
// set the speed of the motor to 30 RPMs
void loop()
{
if ( Serial.available()) {
char ch = Serial.read();
if(ch >= '0' && ch <= '9'){
steps = steps * 10 + ch - '0';
}
else if(ch == '+'){
stepper.step(steps);
steps = 0;
}
else if(ch == '-'){
stepper.step(steps * -1);
steps = 0;
}
294 | Chapter 8:ಗPhysical Output
// is ch a number?
// yes, accumulate the value
}
else if(ch == 's'){
stepper.setSpeed(steps);
Serial.print("Setting speed to ");
Serial.println(steps);
steps = 0;
}
}
Discussion
7KLVW\SHRIPRWRUKDVWZRSDLUVRIFRLOVDQGHDFKFRLOKDVDFRQQHFWLRQWRWKHFHQWHU
0RWRUVZLWKRQO\ILYHZLUHVKDYHERWKFHQWHUFRQQHFWLRQVEURXJKWRXWRQDVLQJOHZLUH
,I WKH FRQQHFWLRQV DUH QRW PDUNHG \RX FDQ LGHQWLI\ WKH ZLULQJ XVLQJ D PXOWLPHWHU
0HDVXUHWKHUHVLVWDQFHDFURVVSDLUVRIZLUHVWRILQGWKHWZRSDLUVRIZLUHVWKDWKDYHWKH
PD[LPXPUHVLVWDQFH7KHFHQWHUWDSZLUHVKRXOGKDYHKDOIWKHUHVLVWDQFHRIWKHIXOOFRLO
$VWHSE\VWHSSURFHGXUHLVDYDLODEOHDWKWWSWHFKUHIPDVVPLQGRUJWHFKUHILRVWHSSHU
ZLUHVDVS
8.14 Driving a Unipolar Stepper Motor (ULN2003A) | 295
CHAPTER 9
Audio Output
9.0 Introduction
7KH$UGXLQRLVQ¦WEXLOWWREHDV\QWKHVL]HUEXWLWFDQFHUWDLQO\SURGXFHVRXQGWKURXJK
DQRXWSXWGHYLFHVXFKDVDVSHDNHU
6RXQG LV SURGXFHG E\ YLEUDWLQJ DLU $ VRXQG KDV D GLVWLQFWLYHSLWFKLIWKHYLEUDWLRQ
UHSHDWV UHJXODUO\ 7KH $UGXLQR FDQ FUHDWH VRXQG E\ GULYLQJ D ORXGVSHDNHU RU 3LH]R
GHYLFH DVPDOOFHUDPLFWUDQVGXFHUWKDWSURGXFHVVRXQGZKHQSXOVHG FRQYHUWLQJHOHF
WURQLFYLEUDWLRQVLQWRVSHDNHUSXOVHVZKLFKYLEUDWHWKHDLU7KHSLWFK IUHTXHQF\ RIWKH
VRXQGLVGHWHUPLQHGE\WKHWLPHLWWDNHVWRSXOVHWKHVSHDNHULQDQGRXWWKHVKRUWHU
WKHDPRXQWRIWLPHWKHKLJKHUWKHIUHTXHQF\
7KHXQLWRIIUHTXHQF\LVPHDVXUHGLQKHUW]DQGLWUHIHUVWRWKHQXPEHURIWLPHVWKH
VLJQDOJRHVWKURXJKLWVUHSHDWLQJF\FOHLQRQHVHFRQG7KHUDQJHRIKXPDQKHDULQJLV
IURPDURXQGKHUW] +] XSWRKHUW] DOWKRXJKLWYDULHVE\SHUVRQDQGFKDQJHV
ZLWKDJH 7KH$UGXLQRVRIWZDUHLQFOXGHVDtoneIXQFWLRQIRUSURGXFLQJVRXQG5HFLSHVDQG
VKRZKRZWRXVHWKLVIXQFWLRQWRPDNHVRXQGVDQGWXQHV7KHtoneIXQFWLRQXVHV
KDUGZDUHWLPHUV2QDVWDQGDUG$UGXLQRERDUGRQO\RQHWRQHFDQEHSURGXFHGDWD
WLPH6NHWFKHVZKHUHWKHWLPHU timer2 LVQHHGHGIRURWKHUIXQFWLRQVVXFKDVanalog
WriteRQSLQRUFDQQRWXVHWKHtoneIXQFWLRQ7RRYHUFRPHWKLVOLPLWDWLRQ5HF
LSHVKRZVKRZWRXVHDQHQKDQFHGWRQHOLEUDU\IRUPXOWLSOHWRQHVDQG5HFLSH
VKRZVKRZVRXQGFDQEHSURGXFHGZLWKRXWXVLQJWKHtoneIXQFWLRQRUKDUGZDUHWLPHUV
7KHVRXQGWKDWFDQEHSURGXFHGE\SXOVLQJDVSHDNHULVOLPLWHGDQGGRHVQRWVRXQG
YHU\PXVLFDO7KHRXWSXWLVDVTXDUHZDYH VHH)LJXUH ZKLFKVRXQGVKDUVKDQG
PRUHOLNHDQDQWLTXHFRPSXWHUJDPHWKDQDPXVLFDOLQVWUXPHQW
,WLVGLIILFXOWIRU$UGXLQRWRSURGXFHPRUHPXVLFDOO\FRPSOH[VRXQGVZLWKRXWH[WHUQDO
KDUGZDUH<RXFDQDGGDVKLHOGWKDWH[WHQGV$UGXLQR¦VFDSDELOLWLHV5HFLSHVKRZV
KRZWRXVHWKH$GDIUXLWZDYHVKLHOGWRSOD\EDFNDXGLRILOHVIURPDPHPRU\FDUGRQ
WKHVKLHOG
297
)LJXUH*HQHUDWLQJVRXQGXVLQJGLJLWDOSXOVHV
<RXFDQDOVRXVH$UGXLQRWRFRQWURODQH[WHUQDOGHYLFHWKDWLVEXLOWWRPDNHVRXQG
5HFLSHVKRZVKRZWRVHQG0XVLFDO,QVWUXPHQW'LJLWDO,QWHUIDFH 0,', PHVVDJHV
WRD0,',GHYLFH7KHVHGHYLFHVSURGXFHKLJKTXDOLW\VRXQGVRIDKXJHYDULHW\RILQ
VWUXPHQWV DQG FDQ SURGXFH WKH VRXQGV RI PDQ\ LQVWUXPHQWV VLPXOWDQHRXVO\ 7KH
VNHWFKLQ5HFLSHVKRZVKRZWRJHQHUDWH0,',PHVVDJHVWRSOD\DPXVLFDOVFDOH
5HFLSHSURYLGHVDQRYHUYLHZRIDQDSSOLFDWLRQFDOOHG$XGXLQRWKDWXVHVFRPSOH[
VRIWZDUHSURFHVVLQJWRV\QWKHVL]HVRXQG
7KLVFKDSWHUFRYHUVWKHPDQ\ZD\V\RXFDQJHQHUDWHVRXQGHOHFWURQLFDOO\,I\RXZDQW
WRPDNHPXVLFE\JHWWLQJ$UGXLQRWRSOD\DFRXVWLFLQVWUXPHQWV VXFKDVJORFNHQVSLHOV
GUXPVDQGDFRXVWLFSLDQRV \RXFDQHPSOR\DFWXDWRUVVXFKDVVROHQRLGVDQGVHUYRV
WKDWDUHFRYHUHGLQ&KDSWHU
0DQ\RIWKHUHFLSHVLQWKLVFKDSWHUZLOOGULYHDVPDOOVSHDNHURU3LH]RGHYLFH7KHFLUFXLW
IRUFRQQHFWLQJRQHRIWKHVHWRDQ$UGXLQRSLQLVVKRZQLQ)LJXUH
7KHRKPUHVLVWRULVXVHGWROLPLWWKHFXUUHQWWKDWFDQIORZWKURXJKWKHVSHDNHU WRR
PXFKFXUUHQWFDQGDPDJHDQ$UGXLQRSLQ $VSHDNHUZLOOZRUNUHJDUGOHVVRIZKLFK
ZLUHLVDWWDFKHGWRJURXQGEXWD3LH]RLVSRODUL]HGVRFRQQHFWWKHQHJDWLYHZLUH XVXDOO\
EODFN WRWKH*QGSLQ,I\RXZDQWWRDGMXVWWKHYROXPH\RXFDQFRQQHFWDRU
.RKPYDULDEOHUHVLVWRUDVVKRZQLQ)LJXUH
$OWHUQDWLYHO\\RXFDQFRQQHFWWKHRXWSXWWRDQH[WHUQDODXGLRDPSOLILHU5HFLSH
VKRZVKRZDQRXWSXWSLQFDQEHFRQQHFWHGWRDQDXGLRMDFN
298 | Chapter 9:ಗAudio Output
)LJXUH&RQQHFWLQJWRDQDXGLRWUDQVGXFHU
7KHYROWDJHOHYHO YROWV LVKLJKHUWKDQDXGLRDPSOLILHUVH[SHFWVR\RX
PD\QHHGWRXVHDQRWKHU.YDULDEOHUHVLVWRUWRUHGXFHWKHYROWDJH
FRQQHFWRQHHQGWRSLQDQGWKHRWKHUHQGWRJURXQGWKHQFRQQHFW
WKHVOLGHUWRWKHWLSRIWKHMDFNSOXJ 9.1 Playing Tones
Problem
<RXZDQWWRSURGXFHDXGLRWRQHVWKURXJKDVSHDNHURURWKHUDXGLRWUDQVGXFHU<RX
ZDQWWRVSHFLI\WKHIUHTXHQF\DQGGXUDWLRQRIWKHWRQH
Solution
8VHWKH$UGXLQR toneIXQFWLRQ7KLVVNHWFKSOD\VDWRQHZLWKWKHIUHTXHQF\VHWE\D
YDULDEOHUHVLVWRU RURWKHUVHQVRU FRQQHFWHGWRDQDORJLQSXW VHH)LJXUH /*
* Tone sketch
*
* Plays tones through a speaker on digital pin 9
* frequency determined by values read from analog port
*/
const int speakerPin = 9;
const int pitchPin = 0;
// connect speaker to pin 9
// pot that will determine the frequency of the tone
void setup()
{
}
void loop()
{
int sensor0Reading = analogRead(pitchPin);
// read input to set frequency
9.1 Playing Tones | 299
}
// map the analog readings to a meaningful range
int frequency = map(sensor0Reading, 0, 1023, 100,5000); //100Hz to 5kHz
int duration = 250;
// how long the tone lasts
tone(speakerPin, frequency, duration); // play the tone
delay(1000); //pause one second
)LJXUH&RQQHFWLRQVIRUWKH7RQHVNHWFK
7KHtoneIXQFWLRQFDQWDNHXSWRWKUHHSDUDPHWHUVWKHSLQDWWDFKHGWRWKHVSHDNHUWKH
IUHTXHQF\WRSOD\ LQKHUW] DQGWKHOHQJWKRIWLPH LQPLOOLVHFRQGV WRSOD\WKHQRWH
7KHWKLUGSDUDPHWHULVRSWLRQDO,ILWLVRPLWWHGWKHQRWHZLOOFRQWLQXHXQWLOWKHUHLV
DQRWKHUFDOOWRtoneRUDFDOOWRnoTone7KHYDOXHIRUWKHIUHTXHQF\LVPDSSHGWRVHQVLEOH
YDOXHVIRUDXGLRIUHTXHQFLHVLQWKHIROORZLQJOLQH
int frequency
= map(sensor0Reading, 0, 1023, 100,5000); //100Hz to 5kHz
7KLVYDULDWLRQXVHVDVHFRQGYDULDEOHUHVLVWRU WKHULJKWKDQGSRWLQ)LJXUH WRVHW
WKHGXUDWLRQRIWKHWRQH
const int speakerPin = 9;
const int pitchPin = 0;
const int durationPin = 1;
// connect speaker to pin 9
// input that determines frequency of the tone
// input that will determine the duration of the tone
void setup()
{
}
void loop()
{
int sensor0Reading = analogRead(pitchPin);
// read input for frequency
int sensor1Reading = analogRead(durationPin); // read input for duration
// map the analog readings to a meaningful range
300 | Chapter 9:ಗAudio Output
}
int frequency = map(sensor0Reading, 0, 1023, 100,5000); // 100Hz to 5kHz
int duration = map(sensor1Reading, 0, 1023, 100,1000); // dur 0.1-1 second
tone(speakerPin, frequency, duration); // play the tone
delay(duration); //wait for the tone to finish
$QRWKHUYDULDWLRQLVWRDGGDVZLWFKVRWKDWWRQHVDUHJHQHUDWHGRQO\ZKHQWKHVZLWFK
LVSUHVVHG
(QDEOHSXOOXSUHVLVWRUVLQsetupZLWKWKLVOLQH VHH5HFLSHIRUDFRQQHFWLRQGLDJUDP
DQGH[SODQDWLRQ digitalWrite(inputPin,HIGH);
// turn on internal pull-up on the inputPin
0RGLI\WKH loopFRGHVRWKDWWKH toneDQG delayIXQFWLRQVDUHRQO\FDOOHGZKHQWKH
VZLWFKLVSUHVVHG
if( digitalRead(inputPin) = LOW) // read input value
{
tone(speakerPin, frequency, duration); // play the tone
delay(duration); //wait for the tone to finish
}
<RX FDQ XVH DOPRVW DQ\ DXGLR WUDQVGXFHU WR SURGXFH VRXQGV ZLWK $UGXLQR 6PDOO
VSHDNHUVZRUNYHU\ZHOO3LH]RWUDQVGXFHUVDOVRZRUNDQGDUHLQH[SHQVLYHUREXVWDQG
HDVLO\VDOYDJHGIURPROGDXGLRJUHHWLQJFDUGV3LH]RVGUDZOLWWOHFXUUHQW WKH\DUHKLJK
UHVLVWDQFHGHYLFHV VRWKH\FDQEHFRQQHFWHGGLUHFWO\WRWKHSLQ6SHDNHUVDUHXVXDOO\
RIPXFKORZHUUHVLVWDQFHDQGQHHGDUHVLVWRUWROLPLWWKHFXUUHQWIORZ7KHFRPSRQHQWV
WREXLOGWKHFLUFXLWSLFWXUHGLQ)LJXUHVKRXOGEHHDV\WRILQGVHHWKLVERRN¦VZHE
VLWHIRUVXJJHVWLRQVRQJHWWLQJSDUWV
See Also
<RXFDQDFKLHYHHQKDQFHGIXQFWLRQDOLW\XVLQJWKH7RQHOLEUDU\E\%UHWW+DJPDQWKDW
LVGHVFULEHGLQ5HFLSH
9.2 Playing a Simple Melody
Problem
<RXZDQW$UGXLQRWRSOD\DVLPSOHPHORG\
Solution
<RXFDQXVHWKHtoneIXQFWLRQGHVFULEHGLQ5HFLSHWRSOD\VRXQGVFRUUHVSRQGLQJWR
QRWHVRQDPXVLFDOLQVWUXPHQW7KLVVNHWFKXVHVtoneWRSOD\DVWULQJRIQRWHVWKH£+HOOR
ZRUOG¤RIOHDUQLQJWKHSLDQR£7ZLQNOH7ZLQNOH/LWWOH6WDU¤
/*
* Twinkle sketch
*
9.2 Playing a Simple Melody | 301
* Plays "Twinkle, Twinkle Little Star"
*
* speaker on digital pin 9
*/
const int speakerPin = 9; // connect speaker to pin 9
char noteNames[] =
{'C','D','E','F','G','a','b'};
unsigned int frequencies[] = {262,294,330,349,392,440,494};
const byte noteCount = sizeof(noteNames); // the number of notes (7 in this
example)
//notes, a space represents a rest
char score[] = "CCGGaaGFFEEDDC GGFFEEDGGFFEED CCGGaaGFFEEDDC ";
const byte scoreLen = sizeof(score); // the number of notes in the score
void setup()
{
}
void loop()
{
for (int i = 0; i < scoreLen; i++)
{
int duration = 333; // each note lasts for a third of a second
playNote(score[i], duration); // play the note
}
}
delay(4000); // wait four seconds before repeating the song
void playNote(char note, int duration)
{
// play the tone corresponding to the note name
for (int i = 0; i < noteCount; i++)
{
// try and find a match for the noteName to get the index to the note
if (noteNames[i] == note) // find a matching note name in the array
tone(speakerPin, frequencies[i], duration); // play the note using the
frequency
}
// if there is no match then the note is a rest, so just do the delay
delay(duration);
}
noteNamesLVDQDUUD\RIFKDUDFWHUVWRLGHQWLI\QRWHVLQDVFRUH(DFKHQWU\LQWKHDUUD\
LVDVVRFLDWHGZLWKDIUHTXHQF\GHILQHGLQWKHnotesDUUD\)RUH[DPSOHQRWH& WKHILUVW
HQWU\LQWKHnoteNamesDUUD\ KDVDIUHTXHQF\RI+] WKHILUVWHQWU\LQWKHnotesDUUD\ scoreLVDQDUUD\RIQRWHVUHSUHVHQWLQJWKHQRWHQDPHV\RXZDQWWRSOD\
char score[] = "CCGGaaGFFEEDDC GGFFEEDGGFFEED CCGGaaGFFEEDDC ";
represents a rest
302 | Chapter 9:ಗAudio Output
// a space
(DFKFKDUDFWHULQWKHVFRUHWKDWPDWFKHVDFKDUDFWHULQWKHnoteNamesDUUD\ZLOOPDNH
WKHQRWHSOD\7KHVSDFHFKDUDFWHULVXVHGDVDUHVWEXWDQ\FKDUDFWHUQRWGHILQHGLQ
noteNamesZLOODOVRSURGXFHDUHVW QRQRWHSOD\LQJ 7KHVNHWFKFDOOVplayNoteZLWKHDFKFKDUDFWHULQWKHVFRUHDQGDGXUDWLRQIRUWKHQRWHV
RIRQHWKLUGRIDVHFRQG
7KHplayNoteIXQFWLRQGRHVDORRNXSLQWKHnoteNamesDUUD\WRILQGDPDWFKDQGXVHV
WKHFRUUHVSRQGLQJHQWU\LQWKHfrequenciesDUUD\WRJHWWKHIUHTXHQF\WRVRXQG
(YHU\QRWHKDVWKHVDPHGXUDWLRQ,I\RXZDQWWRVSHFLI\WKHOHQJWKRIHDFKQRWH\RX
FDQDGGWKHIROORZLQJFRGHWRWKHVNHWFK
byte beats[scoreLen] = {1,1,1,1,1,1,2, 1,1,1,1,1,1,2,1,
1,1,1,1,1,1,2, 1,1,1,1,1,1,2,1,
1,1,1,1,1,1,2, 1,1,1,1,1,1,2};
byte beat = 180; // beats per minute for eighth notes
unsigned int speed = 60000 / beat; // the time in ms for one beat
beatsLVDQDUUD\VKRZLQJWKHOHQJWKRIHDFKQRWH1LVDQHLJKWKQRWH2DTXDUWHUQRWH
DQGVRRQ
beatLVWKHQXPEHURIEHDWVSHUPLQXWH
speedLVWKHFDOFXODWLRQWRFRQYHUWEHDWVSHUPLQXWHLQWRDGXUDWLRQLQPLOOLVHFRQGV
7KHRQO\FKDQJHWRWKH loopFRGHLVWRVHWWKHGXUDWLRQWRXVHWKHYDOXHLQWKH beats
DUUD\&KDQJH
int duration = 333;
// each note lasts for a third of a second
WR
int duration = beats[i] * speed; // use beats array to determine duration
9.3 Generating More Than One Simultaneous Tone
Problem
<RXZDQWWRSOD\WZRWRQHVDWWKHVDPHWLPH7KH$UGXLQR7RQHOLEUDU\RQO\SURGXFHV
DVLQJOHWRQHRQDVWDQGDUGERDUGDQG\RXZDQWWZRVLPXOWDQHRXVWRQHV1RWHWKDW
WKH0HJDERDUGKDVPRUHWLPHUVDQGFDQSURGXFHXSWRVL[WRQHV
Solution
7KH$UGXLQR7RQHOLEUDU\LVOLPLWHGWRDVLQJOHWRQHEHFDXVHDGLIIHUHQWWLPHULVUHTXLUHG
IRUHDFKWRQHDQGDOWKRXJKDVWDQGDUG$UGXLQRERDUGKDVWKUHHWLPHUVRQHLVXVHGIRU
WKHmillisIXQFWLRQDQGDQRWKHUIRUVHUYRV7KLVUHFLSHXVHVDOLEUDU\ZULWWHQE\%UHWW
+DJPDQWKHDXWKRURIWKH$UGXLQRtoneIXQFWLRQ7KHOLEUDU\HQDEOHV\RXWRJHQHUDWH
PXOWLSOHVLPXOWDQHRXVWRQHV<RXFDQGRZQORDGLWIURPKWWSFRGHJRRJOHFRPSURJXH
FRGHZLNL7RQH/LEUDU\'RFXPHQWDWLRQ
9.3 Generating More Than One Simultaneous Tone | 303
7KLVLVDQH[DPSOHVNHWFKIURPWKHGRZQORDGWKDWSOD\VWZRWRQHVVHOHFWDEOHIURPWKH
VHULDOSRUW
/*
* Dual Tones - Simultaneous tone generation.
* plays notes 'a' through 'g' sent over the Serial Monitor.
* lowercase letters for the first tone and uppercase for the second.
* 's' stops the current playing tone.
*/
#include <Tone.h>
int notes[] = { NOTE_A3,
NOTE_B3,
NOTE_C4,
NOTE_D4,
NOTE_E4,
NOTE_F4,
NOTE_G4 };
// You can declare the tones as an array
Tone notePlayer[2];
void setup(void)
{
Serial.begin(9600);
notePlayer[0].begin(11);
notePlayer[1].begin(12);
}
void loop(void)
{
char c;
if(Serial.available())
{
c = Serial.read();
switch(c)
{
case 'a'...'g':
notePlayer[0].play(notes[c - 'a']);
Serial.println(notes[c - 'a']);
break;
case 's':
notePlayer[0].stop();
break;
case 'A'...'G':
notePlayer[1].play(notes[c - 'A']);
Serial.println(notes[c - 'A']);
break;
case 'S':
notePlayer[1].stop();
break;
304 | Chapter 9:ಗAudio Output
}
default:
notePlayer[1].stop();
notePlayer[0].play(NOTE_B2);
delay(300);
notePlayer[0].stop();
delay(100);
notePlayer[1].play(NOTE_B2);
delay(300);
notePlayer[1].stop();
break;
}
}
Discussion
7RPL[WKHRXWSXWRIWKHWZRWRQHVWRDVLQJOHVSHDNHUXVHRKPUHVLVWRUVIURPHDFK
RXWSXWSLQDQGWLHWKHPWRJHWKHUDWWKHVSHDNHU7KHRWKHUVSHDNHUOHDGFRQQHFWVWR
*QGDVVKRZQLQWKHSUHYLRXVVNHWFKHV
2QDVWDQGDUG$UGXLQRERDUGWKHILUVWWRQHZLOOXVHWLPHU VR3:0RQSLQVDQG
ZLOOQRWEHDYDLODEOH WKHVHFRQGWRQHXVHVWLPHU SUHYHQWLQJWKH6HUYROLEUDU\DQG
3:0RQSLQVDQGIURPZRUNLQJ 2QD0HJDERDUGHDFKVLPXOWDQHRXVWRQH
ZLOOXVHWLPHUVLQWKHIROORZLQJRUGHU
3OD\LQJWKUHHVLPXOWDQHRXVQRWHVRQDVWDQGDUG$UGXLQRERDUGRUPRUH
WKDQVL[RQD0HJDLVSRVVLEOHEXWmillisDQGdelayZLOOQRORQJHUZRUN
SURSHUO\,WLVVDIHVWWRXVHRQO\WZRVLPXOWDQHRXVWRQHV RUILYHRQD
0HJD 9.4 Generating Audio Tones and Fading an LED
Problem
<RXZDQWWRSURGXFHVRXQGVWKURXJKDVSHDNHURURWKHUDXGLRWUDQVGXFHUDQG\RX
QHHGWRJHQHUDWHWKHWRQHLQVRIWZDUHLQVWHDGRIZLWKDWLPHUIRUH[DPSOHLI\RXQHHG
WRXVHanalogWriteRQSLQRU
Solution
7KHtoneIXQFWLRQGLVFXVVHGLQHDUOLHUUHFLSHVLVHDVLHUWRXVHEXWLWUHTXLUHVDKDUGZDUH
WLPHUZKLFKPD\EHQHHGHGIRURWKHUWDVNVVXFKDV analogWrite7KLVFRGHGRHVQRW
XVHDWLPHUEXWLWZLOOQRWGRDQ\WKLQJHOVHZKLOHWKHQRWHLVSOD\HG8QOLNHWKH$UGXLQR
toneIXQFWLRQWKHplayToneIXQFWLRQGHVFULEHGKHUHZLOOEORFN¢LWZLOOQRWUHWXUQXQWLO
WKHQRWHKDVILQLVKHG
7KLV VNHWFK JHQHUDWHV WRQHV ZLWKRXW D WLPHU ,W SOD\V VL[ QRWHV HDFK RQH WZLFH WKH
IUHTXHQF\RI DQRFWDYHKLJKHUWKDQ WKHSUHYLRXVRQH7KHplayToneIXQFWLRQJHQHUDWHV
9.4 Generating Audio Tones and Fading an LED | 305
Download from Wow! eBook <www.wowebook.com>
DWRQHIRUDVSHFLILHGGXUDWLRQRQDVSHDNHURU3LH]RGHYLFHFRQQHFWHGWRDGLJLWDORXWSXW
SLQDQGJURXQGVHH)LJXUH
byte speakerPin = 9;
byte ledPin = 10;
void setup()
{
pinMode(speakerPin, OUTPUT);
}
void playTone(int period, int duration)
{
// period is one cycle of tone
// duration is how long the pulsing should last in milliseconds
int pulse = period / 2;
for (long i = 0; i < duration * 1000L; i += period )
{
digitalWrite(speakerPin, HIGH);
delayMicroseconds(pulse);
digitalWrite(speakerPin, LOW);
delayMicroseconds(pulse);
}
}
void fadeLED(){
for (int brightness = 0; brightness < 255; brightness++)
{
analogWrite(ledPin, brightness);
delay(2);
}
for (int brightness = 255; brightness >= 0; brightness--) {
analogWrite(ledPin, brightness);
delay(2);
}
}
void loop()
{
// a note with period of 15289 is deep C (second lowest C note on piano)
for(int period=15289; period >= 477; period=period / 2) // play 6 octaves
{
playTone( period, 200); // play tone for 200 milliseconds
}
fadeLED();
}
Discussion
7ZRYDOXHVDUHXVHGE\playToneperiodDQGduration7KHYDULDEOHperiodUHSUHVHQWV
WKHWLPHIRURQHF\FOHRIWKHWRQHWRSOD\7KHVSHDNHULVSXOVHGKLJKDQGWKHQORZIRU
306 | Chapter 9:ಗAudio Output
)LJXUH&RQQHFWLRQVIRUVSHDNHUDQG/('
WKHQXPEHURIPLFURVHFRQGVJLYHQE\period7KHforORRSUHSHDWVWKHSXOVLQJIRUWKH
QXPEHURIPLOOLVHFRQGVJLYHQLQWKHdurationDUJXPHQW
,I\RXSUHIHUWRZRUNLQIUHTXHQF\UDWKHUWKDQSHULRG\RXFDQXVHWKHUHFLSURFDOUHOD
WLRQVKLSEHWZHHQIUHTXHQF\DQGSHULRGSHULRGLVHTXDOWRGLYLGHGE\IUHTXHQF\<RX
QHHGWKHSHULRGYDOXHLQPLFURVHFRQGVEHFDXVHWKHUHDUHPLOOLRQPLFURVHFRQGVLQ
RQHVHFRQGWKHSHULRGLVFDOFXODWHGDV/IUHTXHQF\ WKH£/¤DWWKHHQGRIWKDW
QXPEHUWHOOVWKHFRPSLOHUWKDWLWVKRXOGFDOFXODWHXVLQJORQJLQWHJHUPDWKWRSUHYHQW
WKHFDOFXODWLRQIURPH[FHHGLQJWKHUDQJHRIDQRUPDOLQWHJHU¢VHHWKHH[SODQDWLRQRI
ORQJLQWHJHUVLQ5HFLSH void playFrequency(int frequency, int duration)
{
int period = 1000000L / frequency;
int pulse = period / 2;
7KHUHVWRIWKHFRGHLVWKHVDPHDVplayTone
}
for (long i = 0; i < duration * 1000L; i += period )
{
digitalWrite(speakerPin, HIGH);
delayMicroseconds(pulse);
digitalWrite(speakerPin, LOW);
delayMicroseconds(pulse);
}
7KHFRGHLQWKLVUHFLSHVWRSVDQGZDLWVXQWLODWRQHKDVFRPSOHWHGEHIRUHLWFDQGRDQ\
RWKHUSURFHVVLQJ,WLVSRVVLEOHWRSURGXFHWKHVRXQGLQWKHEDFNJURXQG ZLWKRXWZDLW
LQJIRUWKHVRXQGWRILQLVK E\SXWWLQJWKHVRXQGJHQHUDWLRQFRGHLQDQLQWHUUXSWKDQGOHU
7KHVRXUFHFRGHIRUWKHtoneIXQFWLRQWKDWFRPHVZLWKWKH$UGXLQRGLVWULEXWLRQVKRZV
KRZWKLVLVGRQH
See Also
5HFLSH
9.4 Generating Audio Tones and Fading an LED | 307
+HUHDUHVRPHH[DPSOHVRIPRUHFRPSOH[DXGLRV\QWKHVLVWKDWFDQEHDFFRPSOLVKHG
ZLWKWKH$UGXLQR
3XOVH&RGH0RGXODWLRQ
3&0DOORZV\RXWRDSSUR[LPDWHDQDORJDXGLRXVLQJGLJLWDOVLJQDOLQJ$Q$UGXLQR
ZLNLDUWLFOHWKDWH[SODLQVKRZWRSURGXFHELW3&0XVLQJDWLPHULVDYDLODEOHDW
KWWSZZZDUGXLQRFFSOD\JURXQG&RGH3&0$XGLR
3RFNHW3LDQRVKLHOG
&ULWWHUDQG*XLWDUL¦V3RFNHW3LDQRVKLHOGJLYHV\RXDSLDQROLNHNH\ERDUGZDYH
WDEOH V\QWKHVLV )0 V\QWKHVLV DQG PRUH VHH KWWSZZZFULWWHUDQGJXLWDULFRP
KRPHVWRUHDUGXLQRSLDQRSKS
9.5 Playing a WAV File
Problem
8QGHUSURJUDPFRQWURO\RXZDQW$UGXLQRWRWULJJHUWKHSOD\LQJRID:$9ILOH
Solution
7KLVVNHWFKXVHVWKH$GDIUXLWZDYHVKLHOGDQGLVEDVHGRQRQHRIWKHH[DPSOHVNHWFKHV
OLQNHGIURPWKHSURGXFWSDJHDWKWWSZZZDGDIUXLWFRPLQGH[SKS"PDLQBSDJH SURG
XFWBLQIR SURGXFWVBLG 7KLVVNHWFKZLOOSOD\RQHRIQLQHILOHVGHSHQGLQJRQUHDGLQJVWDNHQIURPDYDULDEOH
UHVLVWRUFRQQHFWHGWRDQDORJLQSXWZKHQSUHVVLQJDEXWWRQFRQQHFWHGWRSLQ DQDORJ
LQSXW /*
* WaveShieldPlaySelection sketch
*
* play a selected WAV file
*
* Position of variable resistor slider when button pressed selects file to play
*
*/
#include <FatReader.h>
#include <SdReader.h>
//#include <avr/pgmspace.h>
#include "WaveHC.h"
#include "WaveUtil.h"
SdReader card;
FatVolume vol;
FatReader root;
FatReader file;
WaveHC wave;
// This object holds the information for the card
// This holds the information for the partition on the card
// This holds the information for the volumes root directory
// This object represents the WAV file
// Only wave (audio) object - only one file played at a time
308 | Chapter 9:ಗAudio Output
const int buttonPin = 15;
const int potPin = 0; // analog input pin 0
char * wavFiles[] = {
"1.WAV","2.WAV","3.WAV","4.WAV","5.WAV","6.WAV","7.WAV","8.WAV","9.WAV"};
void setup()
{
Serial.begin(9600);
pinMode(buttonPin, INPUT);
digitalWrite(buttonPin, HIGH); // turn on pull-up resistor
if (!card.init())
{
// Something went wrong, sdErrorCheck prints an error number
putstring_nl("Card init. failed!");
sdErrorCheck();
while(1);
// then 'halt' - do nothing!
}
// enable optimized read - some cards may time out
card.partialBlockRead(true);
// find a FAT partition!
uint8_t part;
for (part = 0; part < 5; part++)
// we have up to 5 slots to look in
{
if (vol.init(card, part))
break;
// found one so break out of this for loop
}
if (part == 5)
// valid parts are 0 to 4, more not valid
{
putstring_nl("No valid FAT partition!");
sdErrorCheck();
// Something went wrong, print the error
while(1);
// then 'halt' - do nothing!
}
// tell the user about what we found
putstring("Using partition ");
Serial.print(part, DEC);
putstring(", type is FAT");
Serial.println(vol.fatType(),DEC);
// FAT16 or FAT32?
// Try to open the root directory
if (!root.openRoot(vol))
{
putstring_nl("Can't open root dir!"); // Something went wrong,
while(1);
// then 'halt' - do nothing!
}
// if here then all the file prep succeeded.
putstring_nl("Ready!");
}
9.5 Playing a WAV File | 309
void loop()
{
if(digitalRead(buttonPin) == LOW)
{
int value = analogRead(potPin);
int index = map(value,0,1023,0,8); // index into one of the 9 files
playcomplete(wavFiles[index]);
Serial.println(value);
}
}
// Plays a full file from beginning to end with no pause.
void playcomplete(char *name)
{
// call playfile find and play this name
playfile(name);
while (wave.isplaying) {
// do nothing while it's playing
}
// now it's done playing
}
void playfile(char *name) {
// see if the wave object is currently doing something
if (wave.isplaying) {
// already playing something, so stop it!
wave.stop(); // stop it
}
// look in the root directory and open the file
if (!file.open(root, name)) {
putstring("Couldn't open file ");
Serial.print(name);
return;
}
// read the file and turn it into a wave object
if (!wave.create(file)) {
putstring_nl("Not a valid WAV");
return;
}
// start playback
wave.play();
}
void sdErrorCheck(void)
{
if (!card.errorCode()) return;
putstring("\n\rSD I/O error: ");
310 | Chapter 9:ಗAudio Output
}
Serial.print(card.errorCode(), HEX);
putstring(", ");
Serial.println(card.errorData(), HEX);
while(1)
; // stay here if there is an error
Discussion
7KHZDYHVKLHOGUHDGVGDWDVWRUHGRQDQ6'FDUG,WXVHVLWVRZQOLEUDU\WKDWLVDYDLODEOH
IURPWKH/DG\DGDZHEVLWH KWWSZZZODG\DGDQHWPDNHZDYHVKLHOG 7KH:$9ILOHV
WR EH SOD\HG QHHG WR EH SXW RQ WKH PHPRU\ FDUG XVLQJ D FRPSXWHU 7KH\ PXVW EH
.+]ELWXQFRPSUHVVHGPRQRILOHVDQGWKHILOHQDPHVPXVWEHLQIRUPDW7KH
RSHQVRXUFHDXGLRXWLOLW\$XGDFLW\FDQEHXVHGWRHGLWRUFRQYHUWDXGLRILOHVWRWKH
FRUUHFWIRUPDW7KHZDYHVKLHOGDFFHVVHVWKHDXGLRILOHIURPWKH6'FDUGVRWKHOHQJWK
RIWKHDXGLRLVRQO\OLPLWHGE\WKHVL]HRIWKHPHPRU\FDUG
See Also
7KH/DG\DGDZDYHVKLHOGOLEUDU\DQGGRFXPHQWDWLRQKWWSZZZODG\DGDQHWPDNH
ZDYHVKLHOG
$XGDFLW\DXGLRHGLWLQJDQGFRQYHUVLRQVRIWZDUHKWWSDXGDFLW\VRXUFHIRUJHQHW
6SDUN)XQRIIHUVDUDQJHRIDXGLRPRGXOHVLQFOXGLQJDQ$XGLR6RXQG0RGXOH KWWS
ZZZVSDUNIXQFRPSURGXFWV DQG 03 EUHDNRXW ERDUG KWWSZZZVSDUNIXQ
FRPSURGXFWV 9.6 Controlling MIDI
Problem
<RXZDQWWRJHWD0,',V\QWKHVL]HUWRSOD\PXVLFXVLQJ$UGXLQR
Solution
7RFRQQHFWWRD0,',GHYLFH\RXQHHGDILYHSLQ',1SOXJRUVRFNHW,I\RXXVHD
VRFNHW\RXZLOODOVRQHHGDOHDGWRFRQQHFWWRWKHGHYLFH&RQQHFWWKH0,',FRQQHFWRU
WR$UGXLQRXVLQJDRKPUHVLVWRUDVVKRZQLQ)LJXUH
9.6 Controlling MIDI | 311
)LJXUH0,',FRQQHFWLRQV
7RXSORDGWKHFRGHRQWR$UGXLQR\RXVKRXOGGLVFRQQHFWWKH0,',GHYLFHDVLWPD\
LQWHUIHUHZLWKWKHXSORDG$IWHUWKHVNHWFKLVXSORDGHGFRQQHFWD0,',VRXQGGHYLFH
WRWKH$UGXLQRRXWSXW$PXVLFDOVFDOHZLOOSOD\HDFKWLPH\RXSUHVVWKHEXWWRQFRQ
QHFWHGWRSLQ
/*
midiOut sketch
sends MIDI messages to play a scale on a MIDI instrument
each time the switch on pin 2 is pressed
*/
//these numbers specify which note
const byte notes[8] = {60, 62, 64, 65, 67, 69, 71, 72};
//they are part of the MIDI specification
const int length = 8;
const int switchPin = 2;
const int ledPin = 13;
void setup() {
Serial.begin(31250);
pinMode(switchPin, INPUT);
digitalWrite(switchPin, HIGH);
pinMode(ledPin, OUTPUT);
}
void loop() {
if (digitalRead(switchPin == LOW))
{
for (byte noteNumber = 0; noteNumber < 8; noteNumber++)
312 | Chapter 9:ಗAudio Output
{
playMidiNote(1, notes[noteNumber], 127);
digitalWrite(ledPin, HIGH);
delay(70);
playMidiNote(1, notes[noteNumber], 0);
digitalWrite(ledPin, HIGH);
delay(30);
}
}
}
void playMidiNote(byte channel, byte note, byte velocity)
{
byte midiMessage= 0x90 + (channel - 1);
Serial.print(midiMessage, BYTE);
Serial.print(note, BYTE);
Serial.print(velocity, BYTE);
}
Discussion
7KLVVNHWFKXVHVWKHVHULDOSRUWWRVHQG0,',LQIRUPDWLRQ7KHFLUFXLWFRQQHFWHGWR
SLQPD\LQWHUIHUHZLWKXSORDGLQJFRGHWRWKHERDUG5HPRYHWKHZLUHIURPSLQZKLOH
\RXXSORDGDQGSOXJLWEDFNLQDIWHUZDUG
0,',ZDVRULJLQDOO\XVHGWRFRQQHFWGLJLWDOPXVLFDOLQVWUXPHQWVWRJHWKHUVRWKDWRQH
FRXOGFRQWURODQRWKHU7KH0,',VSHFLILFDWLRQGHVFULEHVWKHHOHFWULFDOFRQQHFWLRQVDQG
WKHPHVVDJHV\RXQHHGWRVHQG
0,',LVDFWXDOO\DVHULDOFRQQHFWLRQ DWDQRQVWDQGDUGVHULDOVSHHGEDXG VR
$UGXLQRFDQVHQG0,',PHVVDJHVXVLQJLWVVHULDOSRUWKDUGZDUHIURPSLQVDQG
%HFDXVHWKHVHULDOSRUWLVRFFXSLHGE\0,',PHVVDJHV\RXFDQ¦WSULQWPHVVDJHVWRWKH
6HULDO0RQLWRUVRWKHVNHWFKIODVKHVWKH/('RQSLQHDFKWLPHLWVHQGVDQRWH
(DFK0,',PHVVDJHFRQVLVWVRIDWOHDVWRQHE\WH7KLVE\WHVSHFLILHVZKDWLVWREHGRQH
6RPHFRPPDQGVQHHGQRRWKHULQIRUPDWLRQEXWRWKHUFRPPDQGVQHHGGDWDWRPDNH
VHQVH7KHPHVVDJHLQWKLVVNHWFKLVQRWHRQZKLFKQHHGVWZRSLHFHVRILQIRUPDWLRQ
ZKLFKQRWHDQGKRZORXG%RWKRIWKHVHELWVRIGDWDDUHLQWKHUDQJHRI]HURWR
7KHVNHWFKLQLWLDOL]HVWKHVHULDOSRUWWRDVSHHGRIEDXGWKHRWKHU0,',VSHFLILF
FRGHLVLQWKHIXQFWLRQplayMidiNote
void playMidiNote(byte channel, byte note, byte velocity)
{
byte midiMessage= 0x90 + (channel - 1);
Serial.print(midiMessage, BYTE);
Serial.print(note, BYTE);
Serial.print(velocity, BYTE);
}
7KLVIXQFWLRQ WDNHVWKUHHSDUDPHWHUV DQG FDOFXODWHV WKH ILUVWE\WHWRVHQGXVLQJWKH
FKDQQHOLQIRUPDWLRQ
9.6 Controlling MIDI | 313
0,',LQIRUPDWLRQLVVHQWRQGLIIHUHQWFKDQQHOVEHWZHHQDQG(DFKFKDQQHOFDQEH
VHWWREHDGLIIHUHQWLQVWUXPHQWVRPXOWLFKDQQHOPXVLFFDQEHSOD\HG7KHFRPPDQG
IRUQRWHRQ WRSOD\DVRXQG LVDFRPELQDWLRQRI[ WKHWRSIRXUELWVDWE ZLWK
WKHERWWRPIRXUELWVVHWWRWKHQXPEHUVEHWZHHQEDQGEWRUHSUHVHQWWKH
0,',FKDQQHOV7KHE\WHUHSUHVHQWVFKDQQHOVXVLQJ]HURWRIRUFKDQQHOVWRVR
LVVXEWUDFWHGILUVW
7KHQWKHQRWHYDOXHDQGWKHYROXPH UHIHUUHGWRDVYHORFLW\LQ0,',DVLWRULJLQDOO\
UHODWHGWRKRZIDVWWKHNH\ZDVPRYLQJRQDNH\ERDUG DUHVHQW
7KHVHULDOprintVWDWHPHQWVVSHFLI\WKDWWKHYDOXHVPXVWEHVHQWDVE\WHV UDWKHUWKDQD
VHULHVRI$6&,,FKDUDFWHUV VSHOOLQJRXWWKHQXPHUDOVprintlnLVQRWXVHGEHFDXVHDOLQH
UHWXUQFKDUDFWHUZRXOGLQVHUWDGGLWLRQDOE\WHVLQWRWKHVLJQDOWKDWDUHQRWZDQWHG
7KHVRXQGLVWXUQHGRIIE\VHQGLQJDVLPLODUPHVVDJHEXWZLWKYHORFLW\VHWWR
7KLVUHFLSHZRUNVZLWK0,',GHYLFHVKDYLQJILYHSLQ',10,',LQFRQQHFWRUV,I\RXU
0,',GHYLFHRQO\KDVD86%FRQQHFWRUWKLVZLOOQRWZRUN,WZLOOQRWHQDEOHWKH$UGXLQR
WRFRQWURO0,',PXVLFSURJUDPVUXQQLQJRQ\RXUFRPSXWHUZLWKRXWDGGLWLRQDOKDUG
ZDUH D0,',WR86%DGDSWHU $OWKRXJK$UGXLQRKDVD86%FRQQHFWRU\RXUFRPSXWHU
UHFRJQL]HVLWDVDVHULDOGHYLFHQRWD0,',GHYLFH
See Also
7R VHQG DQG UHFHLYH 0,', KDYH D ORRN DW WKH 0,', OLEUDU\ DYDLODEOH DW KWWSZZZ
DUGXLQRFFSOD\JURXQG0DLQ0,',/LEUDU\
0,',PHVVDJHVDUHGHVFULEHGLQGHWDLODWKWWSZZZPLGLRUJWHFKVSHFVPLGLPHVVDJHV
SKS
)RUPRUHLQIRUPDWLRQRQWKH6SDUN)XQ0,',EUHDNRXWVKLHOG %2% VHHKWWS
ZZZVSDUNIXQFRPSURGXFWV
9.7 Making an Audio Synthesizer
Problem
<RX ZDQW WR JHQHUDWH FRPSOH[ VRXQGV VLPLODU WR WKRVH XVHG WR SURGXFH HOHFWURQLF
PXVLF
Solution
7KHVLPXODWLRQRIDXGLRRVFLOODWRUVXVHGLQDVRXQGV\QWKHVL]HULVFRPSOH[EXW7LQNHU
/RQGRQHQJLQHHU3HWHU.QLJKWKDVFUHDWHGDVNHWFKFDOOHG$XGXLQRWKDWHQDEOHV$UGXLQR
WRSURGXFHPRUHFRPSOH[DQGLQWHUHVWLQJVRXQGV
'RZQORDGWKHVNHWFKE\IROORZLQJWKHOLQNRQKWWSFRGHJRRJOHFRPSWLQNHULWZLNL
$XGXLQR
314 | Chapter 9:ಗAudio Output
&RQQHFWILYH.RKPOLQHDUSRWHQWLRPHWHUVWRDQDORJSLQVWKURXJKDVVKRZQLQ
)LJXUH3RWHQWLRPHWHUVZLWKIXOOVL]HVKDIWVDUHEHWWHUWKDQVPDOOSUHVHWVEHFDXVH
\RXFDQHDVLO\WZLGGOHWKHVHWWLQJV3LQLVXVHGIRUDXGLRRXWSXWDQGLVFRQQHFWHGWR
DQDPSOLILHUXVLQJDMDFNSOXJ
)LJXUH$XGXLQR
Discussion
7KH 6NHWFK FRGH LV FRPSOH[ EHFDXVH LW LV GLUHFWO\ PDQLSXODWLQJ KDUGZDUH WLPHUV WR
JHQHUDWHWKHGHVLUHGIUHTXHQFLHVZKLFKDUHWUDQVIRUPHGLQVRIWZDUHWRSURGXFHWKH
DXGLRHIIHFWV,WLVQRWLQFOXGHGLQWKHWH[WEHFDXVH\RXGRQRWQHHGWRXQGHUVWDQGWKH
FRGHWRXVH$XGXLQR
$XGXLQRXVHVDWHFKQLTXHFDOOHGJUDQXODUV\QWKHVLVWRJHQHUDWHWKHVRXQG,WXVHVWZR
HOHFWURQLFDOO\SURGXFHGVRXQGVRXUFHV FDOOHGJUDLQV 7KHYDULDEOHUHVLVWRUVFRQWUROWKH
IUHTXHQF\DQGGHFD\RIHDFKJUDLQ LQSXWVDQGIRURQHJUDLQDQGLQSXWVDQGIRU
WKHRWKHU ,QSXWFRQWUROVWKHV\QFKURQL]DWLRQEHWZHHQWKHJUDLQV
,I\RXZDQWWRWZHDNWKHFRGH\RXFDQFKDQJHWKHVFDOHXVHGWRFDOFXODWHWKHIUHTXHQF\
7KHGHIDXOWVHWWLQJLVSHQWDWRQLFEXW\RXFDQFRPPHQWWKDWRXWDQGXQFRPPHQWDQ
RWKHURSWLRQWRXVHDGLIIHUHQWVFDOH
%HFDUHIXOZKHQDGGLQJFRGHWRWKHPDLQORRSEHFDXVHWKHVNHWFKLVKLJKO\RSWLPL]HG
DQGDGGLWLRQDOFRGHFRXOGVORZWKLQJVGRZQWRRPXFKFDXVLQJWKHDXGLRV\QWKHVLVWR
QRWZRUNZHOO
9.7 Making an Audio Synthesizer | 315
<RXFDQUHSODFHDQ\RIWKHSRWVZLWKVHQVRUVWKDWFDQSURGXFHDQDQDORJYROWDJHVLJQDO
VHH&KDSWHU )RUH[DPSOHDOLJKWGHSHQGHQWUHVLVWRU VHH5HFLSH RUDGLVWDQFH
VHQVRU WKHDQDORJRXWSXWGHVFULEHGWRZDUGWKHHQGRI5HFLSH FRQQHFWHGWRRQHRI
WKHIUHTXHQF\LQSXWV SLQRU ZRXOGHQDEOH\RXWRFRQWUROWKHSLWFKE\PRYLQJ\RXU
KDQGFORVHUWRRUIDUWKHUIURPWKHVHQVRU ORRNXS£WKHUHPLQ¤LQ:LNLSHGLDRU*RRJOH
WRUHDGPRUHDERXWWKLVPXVLFDOLQVWUXPHQWWKDWLVSOD\HGE\VHQVLQJKDQGPRYHPHQW See Also
9LGHRGHPRQVWUDWLRQRI$XGXLQRKWWSZZZYLPHRFRP
:LNLSHGLDDUWLFOHH[SODLQLQJJUDQXODUV\QWKHVLVKWWSHQZLNLSHGLDRUJZLNL*UDQXODU
BV\QWKHVLV
:LNLSHGLDDUWLFOHRQWKHWKHUHPLQKWWSHQZLNLSHGLDRUJZLNL7KHUHPLQ
316 | Chapter 9:ಗAudio Output
CHAPTER 10
Remotely Controlling External Devices
10.0 Introduction
7KH$UGXLQRFDQLQWHUDFWZLWKDOPRVWDQ\GHYLFHWKDWXVHVVRPHIRUPRIUHPRWHFRQWURO
LQFOXGLQJ79VDXGLRHTXLSPHQWFDPHUDVJDUDJHGRRUVDSSOLDQFHVDQGWR\V0RVW
UHPRWHFRQWUROVZRUNE\VHQGLQJGLJLWDOGDWDIURPDWUDQVPLWWHUWRDUHFHLYHUXVLQJ
LQIUDUHGOLJKW ,5 RUZLUHOHVVUDGLRWHFKQRORJ\'LIIHUHQWSURWRFROV VLJQDOSDWWHUQV DUH
XVHGWRWUDQVODWHNH\SUHVVHVLQWRDGLJLWDOVLJQDODQGWKHUHFLSHVLQWKLVFKDSWHUVKRZ
\RXKRZWRXVHFRPPRQO\IRXQGUHPRWHFRQWUROVDQGSURWRFROV
$Q,5UHPRWHZRUNVE\WXUQLQJDQ/('RQDQGRIILQSDWWHUQVWRSURGXFHXQLTXHFRGHV
7KHFRGHVDUHW\SLFDOO\WRELWV SLHFHVRIGDWD (DFKNH\RQWKHUHPRWHLVDVVR
FLDWHGZLWKDVSHFLILFFRGHWKDWLVWUDQVPLWWHGZKHQWKHNH\LVSUHVVHG,IWKHNH\LVKHOG
GRZQWKHUHPRWHXVXDOO\VHQGVWKHVDPHFRGHUHSHDWHGO\DOWKRXJKVRPHUHPRWHV HJ
1(& VHQGDVSHFLDOUHSHDWFRGHZKHQDNH\LVKHOGGRZQ)RU3KLOLSV5&RU5&
UHPRWHVDELWLQWKHFRGHLVWRJJOHGHDFKWLPHDNH\LVSUHVVHGWKHUHFHLYHUXVHVWKLV
WRJJOHELWWRGHWHUPLQHZKHQDNH\LVSUHVVHGDVHFRQGWLPH<RXFDQUHDGPRUHDERXW
WKHWHFKQRORJLHVXVHGLQ,5UHPRWHFRQWUROVDWKWWSZZZVESURMHFWVFRPNQRZOHGJH
LULUKWP
7KHUHFLSHVKHUHXVHDORZFRVW,5UHFHLYHUPRGXOHWRGHWHFWWKHVLJQDODQGSURYLGHD
GLJLWDORXWSXWWKDWWKH$UGXLQRFDQUHDG7KHGLJLWDORXWSXWLVWKHQGHFRGHGE\DOLEUDU\
FDOOHG,5UHPRWHZKLFKZDVZULWWHQE\.HQ6KLUULIIDQGFDQEHGRZQORDGHGIURPKWWS
ZZZDUFIQFRPPXOWLSURWRFROLQIUDUHGUHPRWHOLEUDU\KWPO
7KHVDPHOLEUDU\LVXVHGLQWKHUHFLSHVLQZKLFK$UGXLQRVHQGVFRPPDQGVWRDFWOLNH
DUHPRWHFRQWURO
7RLQVWDOOWKHOLEUDU\SODFHLWLQWKHIROGHUQDPHGOLEUDULHVLQ\RXU$UGXLQRVNHWFKIROGHU
,I\RXQHHGKHOSLQVWDOOLQJOLEUDULHVVHH&KDSWHU
5HPRWHFRQWUROVXVLQJZLUHOHVVUDGLRWHFKQRORJ\DUHPRUHGLIILFXOWWRHPXODWHWKDQ,5
FRQWUROV+RZHYHUWKHEXWWRQFRQWDFWVRQWKHVHFRQWUROVFDQEHDFWLYDWHGE\$UGXLQR
7KH UHFLSHV XVLQJ ZLUHOHVV UHPRWHV VLPXODWH EXWWRQ SUHVVHV E\ FORVLQJ WKH EXWWRQ
317
FRQWDFWVFLUFXLWLQVLGHWKHUHPRWHFRQWURO:LWKZLUHOHVVUHPRWHV\RXPD\QHHGWRWDNH
DSDUWWKHUHPRWHFRQWURODQGFRQQHFWZLUHVIURPWKHFRQWDFWVWR$UGXLQRWREHDEOHWR
XVHWKHVHGHYLFHV&RPSRQHQWVFDOOHGRSWRFRXSOHUVDUHXVHGWRSURYLGHHOHFWULFDOVHS
DUDWLRQEHWZHHQ$UGXLQRDQGWKHUHPRWHFRQWURO7KLVLVRODWLRQSUHYHQWVYROWDJHVIURP
$UGXLQRIURPKDUPLQJWKHUHPRWHFRQWURODQGYLFHYHUVD
2SWRFRXSOHUV DOVRFDOOHGRSWRLVRODWRUV HQDEOH\RXWRVDIHO\FRQWURODQRWKHUFLUFXLW
WKDWPD\EHRSHUDWLQJDWGLIIHUHQWYROWDJHOHYHOVIURP$UGXLQR$VWKH£LVRODWRU¤SDUW
RIWKHQDPHLPSOLHVRSWRLVRODWRUVSURYLGHDZD\WRNHHSWKLQJVHOHFWULFDOO\VHSDUDWHG
7KHVHGHYLFHVFRQWDLQDQ/('ZKLFKFDQEHFRQWUROOHGE\DQ$UGXLQRGLJLWDOSLQ7KH
OLJKWIURPWKH/('LQWKHRSWRFRXSOHUVKLQHVRQWRDOLJKWVHQVLWLYHWUDQVLVWRU7XUQLQJ
RQ WKH /(' FDXVHV WKH WUDQVLVWRU WR FRQGXFW FORVLQJ WKH FLUFXLW EHWZHHQ LWV WZR
FRQQHFWLRQV¢WKHHTXLYDOHQWRISUHVVLQJDVZLWFK
10.1 Responding to an Infrared Remote Control
Problem
<RXZDQWWRUHVSRQGWRDQ\NH\SUHVVHGRQD79RURWKHUUHPRWHFRQWURO
Solution
$UGXLQRUHVSRQGVWR,5UHPRWHVLJQDOVXVLQJDGHYLFHFDOOHGDQ ,5UHFHLYHUPRGXOH
&RPPRQGHYLFHVDUHWKH762331$DQG76237KHILUVWWZRKDYHWKH
VDPHFRQQHFWLRQVVRWKHFLUFXLWLVWKHVDPHWKH7623KDVWKH9DQG*QGSLQV
UHYHUVHG&KHFNWKHGDWDVKHHWIRU\RXUGHYLFHWRHQVXUHWKDW\RXFRQQHFWLWFRUUHFWO\
7KLVUHFLSHXVHVWKH,5UHPRWHOLEUDU\IURPKWWSZZZDUFIQFRPPXOWLSURWR
FROLQIUDUHGUHPRWHOLEUDU\KWPO &RQQHFW WKH ,5 UHFHLYHU PRGXOH DFFRUGLQJ WR \RXU
GDWDVKHHW7KH$UGXLQRZLULQJLQ)LJXUHLVIRUWKH762331$GHYLFHV
7KLV VNHWFK ZLOO WRJJOH DQ /(' ZKHQ DQ\ EXWWRQ RQ DQ LQIUDUHG UHPRWH FRQWURO LV
SUHVVHG
/*
IR_remote_detector sketch
An IR remote receiver is connected to pin 2.
The LED on pin 13 toggles each time a button on the remote is pressed.
*/
#include <IRremote.h>
//adds the library code to the sketch
const int irReceiverPin = 2;
const int ledPin = 13;
//pin the receiver is connected to
IRrecv irrecv(irReceiverPin);
decode_results decodedSignal;
//create an IRrecv object
//stores results from IR detector
318 | Chapter 10:ಗRemotely Controlling External Devices
)LJXUH&RQQHFWLQJDQLQIUDUHGUHFHLYHUPRGXOH
void setup()
{
pinMode(ledPin, OUTPUT);
irrecv.enableIRIn();
}
boolean lightState = false;
unsigned long last = millis();
message
// Start the receiver object
//keep track of whether the LED is on
//remember when we last received an IR
void loop()
{
if (irrecv.decode(&decodedSignal) == true) //this is true if a message has
been received
10.1 Responding to an Infrared Remote Control | 319
{
if (millis() - last > 250) {
//has it been 1/4 sec since last message
lightState = !lightState;
//toggle the LED
digitalWrite(ledPin, lightState);
}
last = millis();
irrecv.resume();
// watch out for another message
}
}
Discussion
7KH,5UHFHLYHUFRQYHUWVWKH,5VLJQDOWRGLJLWDOSXOVHV7KHVHDUHDVHTXHQFHRIRQHV
DQG]HURVWKDWFRUUHVSRQGWREXWWRQVRQWKHUHPRWH7KH,5UHPRWHOLEUDU\GHFRGHV
WKHVHSXOVHVDQGSURYLGHVDQXPHULFYDOXHIRUHDFKNH\ WKHDFWXDOYDOXHVWKDW\RXU
VNHWFKZLOOUHFHLYHDUHGHSHQGHQWRQWKHVSHFLILFUHPRWHFRQWURO\RXXVH #include <IRremote.h>DWWKHWRSRIWKHVNHWFKPDNHVWKHOLEUDU\FRGHDYDLODEOHWR\RXU
VNHWFKDQGWKHOLQH IRrecv irrecv(irReceiverPin);FUHDWHVDQ IRrecvREMHFWQDPHG
irrecvWRUHFHLYHVLJQDOVIURPDQ,5UHFHLYHUPRGXOHFRQQHFWHGWRirReceiverPin SLQ
LQWKHVNHWFK &KDSWHUKDVPRUHRQXVLQJOLEUDULHV
<RXXVHWKH irrecvREMHFWWRDFFHVVWKHVLJQDOIURPWKH,5UHFHLYHU<RXFDQJLYHLW
FRPPDQGVWRORRNIRUDQGGHFRGHVLJQDOV7KHGHFRGHGUHVSRQVHVSURYLGHGE\WKH
OLEUDU\DUHVWRUHGLQDYDULDEOHQDPHGdecode_results7KHreceiverREMHFWLVVWDUWHGLQ
setupZLWKWKHOLQHirrecv.enableIRIn();7KHUHVXOWVDUHFKHFNHGLQloopE\FDOOLQJWKH
IXQFWLRQirrecv.decode(&decodedSignal)
7KH decodeIXQFWLRQUHWXUQV trueLIWKHUHLVGDWDZKLFKZLOOEHSODFHGLQWKH decoded
SignalYDULDEOH5HFLSHH[SODLQVKRZWKHDPSHUVDQGV\PEROLVXVHGLQIXQFWLRQ
FDOOVZKHUHSDUDPHWHUVDUHPRGLILHGVRWKDWLQIRUPDWLRQFDQEHSDVVHGEDFN
,IDUHPRWHPHVVDJHKDVEHHQUHFHLYHGWKHFRGHWRJJOHVWKH/(' IOLSVLWVVWDWH LILWLV
PRUHWKDQRQHTXDUWHURIDVHFRQGVLQFHWKHODVWWLPHLWZDVWRJJOHG RWKHUZLVHWKH
/('ZLOOJHWWXUQHGRQDQGRIITXLFNO\E\UHPRWHVWKDWVHQGFRGHVPRUHWKDQRQFH
ZKHQ\RXSUHVVWKHEXWWRQDQGPD\DSSHDUWREHIODVKLQJUDQGRPO\ 7KH decodedSignalYDULDEOHZLOOFRQWDLQDYDOXHDVVRFLDWHGZLWKDNH\7KLVYDOXHLV
LJQRUHGLQWKLVUHFLSH DOWKRXJKLWLVXVHGLQWKHQH[WUHFLSH ¢\RXFDQSULQWWKHYDOXH
E\DGGLQJWRWKHVNHWFKWKHSerial.printlnOLQHKLJKOLJKWHGLQWKHIROORZLQJFRGH
if (irrecv.decode(&decodedSignal) == true) //this is true if a message has been
received
Serial.println(results.value); // add this line to see decoded results
7KHOLEUDU\QHHGVWREHWROGWRFRQWLQXHPRQLWRULQJIRUVLJQDOVDQGWKLVLVDFKLHYHG
ZLWKWKHOLQHirrecv.resume();
7KLVVNHWFKIODVKHVDQ/('ZKHQDQ\EXWWRQRQWKHUHPRWHFRQWUROLVSUHVVHGEXW\RX
FDQFRQWURORWKHUWKLQJV¢IRUH[DPSOH\RXFDQXVHDVHUYRPRWRUWRGLPDODPS IRU
PRUHRQFRQWUROOLQJSK\VLFDOGHYLFHVVHH&KDSWHU 320 | Chapter 10:ಗRemotely Controlling External Devices
10.2 Decoding Infrared Remote Control Signals
Problem
<RXZDQWWRGHWHFWDVSHFLILFNH\SUHVVHGRQD79RURWKHUUHPRWHFRQWURO
Solution
7KLVVNHWFKXVHVUHPRWHFRQWURONH\SUHVVHVWRDGMXVWWKHEULJKWQHVVRIDQ/('7KH
FRGHSURPSWVIRUUHPRWHFRQWURONH\VWKURXJKZKHQWKHVNHWFKVWDUWV7KHVHFRGHV
DUHVWRUHGLQ$UGXLQRPHPRU\ 5$0 DQGWKHVNHWFKWKHQUHVSRQGVWRWKHVHNH\VE\
VHWWLQJWKHEULJKWQHVVRIDQ/('WRFRUUHVSRQGZLWKWKHEXWWRQSUHVVHGZLWKWXUQLQJ
WKH/('RIIDQGWKURXJKSURYLGLQJLQFUHDVHGEULJKWQHVV
/*
RemoteDecode sketch
Infrared remote control signals are decoded to control LED brightness
The values for keys 0 through 4 are detected and stored when the sketch starts
key 0 turns the LED off, the brightness increases in steps with keys 1 through 4
*/
#include <IRremote.h>
// IR remote control library
const int irReceivePin = 2;
detector
const int ledPin
= 9;
// pin connected to the output of the IR
const int numberOfKeys = 5;
long irKeyCodes[numberOfKeys];
// 5 keys are learned (0 through 4)
// holds the codes for each key
IRrecv irrecv(irReceivePin);
decode_results results;
// create the IR library
// IR data goes here
// LED is connected to a PWM pin
void setup()
{
Serial.begin(9600);
pinMode(irReceivePin, INPUT);
pinMode(ledPin, OUTPUT);
irrecv.enableIRIn();
// Start the IR receiver
learnKeycodes();
// learn remote control key
Serial.println("Press a remote key");
}
codes
void loop()
{
long key;
int brightness;
if (irrecv.decode(&results))
{
// here if data is received
irrecv.resume();
key = convertCodeToKey(results.value);
10.2 Decoding Infrared Remote Control Signals | 321
if(key >= 0)
{
Serial.print("Got key ");
Serial.println(key);
brightness = map(key, 0,numberOfKeys-1, 0, 255);
analogWrite(ledPin, brightness);
}
}
}
/*
* get remote control codes
*/
void learnKeycodes()
{
while(irrecv.decode(&results))
// empty the buffer
irrecv.resume();
Serial.println("Ready to learn remote codes");
long prevValue = -1;
int i=0;
while( i < numberOfKeys)
{
Serial.print("press remote key ");
Serial.print(i);
while(true)
{
if( irrecv.decode(&results) )
{
if(results.value != -1 && results.value != prevValue)
{
showReceivedData();
irKeyCodes[i] = results.value;
i = i + 1;
prevValue = results.value;
irrecv.resume(); // Receive the next value
break;
}
irrecv.resume(); // Receive the next value
}
}
}
Serial.println("Learning complete");
}
/*
* converts a remote protocol code to a logical key code (or -1 if no digit
received)
*/
int convertCodeToKey(long code)
{
for( int i=0; i < numberOfKeys; i++)
{
if( code == irKeyCodes[i])
{
return i; // found the key so return it
322 | Chapter 10:ಗRemotely Controlling External Devices
Download from Wow! eBook <www.wowebook.com>
}
}
}
return -1;
/*
* display the protocol type and value
*/
void showReceivedData()
{
if (results.decode_type == UNKNOWN)
{
Serial.println("-Could not decode message");
}
else
{
if (results.decode_type == NEC) {
Serial.print("- decoded NEC: ");
}
else if (results.decode_type == SONY) {
Serial.print("- decoded SONY: ");
}
else if (results.decode_type == RC5) {
Serial.print("- decoded RC5: ");
}
else if (results.decode_type == RC6) {
Serial.print("- decoded RC6: ");
}
Serial.print("hex value = ");
Serial.println( results.value, HEX);
}
}
Discussion
7KLV VROXWLRQ LV EDVHG RQ WKH ,5UHPRWH OLEUDU\ VHH WKLV FKDSWHU¦V LQWURGXFWLRQ IRU
GHWDLOV
7KHVNHWFKVWDUWVWKHUHPRWHFRQWUROOLEUDU\ZLWKWKHIROORZLQJFRGH
irrecv.enableIRIn(); // Start the IR receiver
,WWKHQFDOOVWKHlearnKeyCodesIXQFWLRQWRSURPSWWKHXVHUWRSUHVVNH\VWKURXJK
7KHFRGHIRUHDFKNH\LVVWRUHGLQDQDUUD\QDPHG irKeyCodes$IWHUDOOWKHNH\VDUH
GHWHFWHGDQGVWRUHGWKHORRSFRGHZDLWVIRUDNH\SUHVVDQGFKHFNVLIWKLVZDVRQHRI
WKHGLJLWVVWRUHGLQWKHirKeyCodesDUUD\,IVRWKHYDOXHLVXVHGWRFRQWUROWKHEULJKWQHVV
RIDQ/('XVLQJanalogWrite
6HH5HFLSHIRUPRUHRQXVLQJWKH mapIXQFWLRQDQG analogWriteWR
FRQWUROWKHEULJKWQHVVRIDQ/('
10.2 Decoding Infrared Remote Control Signals | 323
7KH OLEUDU\ VKRXOG EH FDSDEOH RI ZRUNLQJ ZLWK PRVW DQ\ ,5 UHPRWH FRQWURO LW FDQ
GLVFRYHUDQGUHPHPEHUWKHWLPLQJVDQGUHSHDWWKHVLJQDORQFRPPDQG
<RXFDQSHUPDQHQWO\VWRUHWKHNH\FRGHYDOXHVVRWKDW\RXGRQ¦WQHHGWROHDUQWKHP
HDFKWLPH\RXVWDUWWKHVNHWFK5HSODFHWKHGHFODUDWLRQRIirKeyCodesZLWKWKHIROORZLQJ
OLQHVWRLQLWLDOL]HWKHYDOXHVIRUHDFKNH\&KDQJHWKHYDOXHVWRFRLQFLGHZLWKWKHRQHV
IRU\RXUUHPRWH WKHVHZLOOEHGLVSOD\HGLQWKH6HULDO0RQLWRUZKHQ\RXSUHVVNH\VLQ
WKHlearnKeycodesIXQFWLRQ long irKeyCodes[numberOfKeys] = {
0x18E758A7, //0 key
0x18E708F7, //1 key
0x18E78877, //2 key
0x18E748B7, //3 key
0x18E7C837, //4 key
};
See Also
5HFLSH H[SODLQV KRZ \RX FDQ VWRUH OHDUQHG GDWD LQ ((3520 QRQYRODWLOH
PHPRU\ 10.3 Imitating Remote Control Signals
Problem
<RXZDQWWRXVH$UGXLQRWRFRQWUROD79RURWKHUUHPRWHO\FRQWUROOHGDSSOLDQFHE\
HPXODWLQJWKHLQIUDUHGVLJQDO7KLVLVWKHLQYHUVHRI5HFLSH¢LWVHQGVFRPPDQGV
LQVWHDGRIUHFHLYLQJWKHP
Solution
7KLVVNHWFKXVHVWKHUHPRWHFRQWUROFRGHVIURP5HFLSHWRFRQWURODGHYLFH)LYH
EXWWRQVVHOHFWDQGVHQGRQHRIILYHFRGHV&RQQHFWDQLQIUDUHG/('WRVHQGWKHVLJQDO
DVVKRZQLQ)LJXUH
/*
irSend sketch
this code needs an IR LED connected to pin 3
and 5 switches connected to pins 4 - 8
*/
#include <IRremote.h>
// IR remote control library
const int numberOfKeys = 5;
const int firstKey = 4;
// the first pin of the 5 sequential pins connected to
buttons
boolean buttonState[numberOfKeys];
boolean lastButtonState[numberOfKeys];
324 | Chapter 10:ಗRemotely Controlling External Devices
long irKeyCodes[numberOfKeys] = {
0x18E758A7, //0 key
0x18E708F7, //1 key
0x18E78877, //2 key
0x18E748B7, //3 key
0x18E7C837, //4 key
};
IRsend irsend;
void setup()
{
for (int i = 0; i < numberOfKeys; i++){
buttonState[i]=true;
lastButtonState[i]=true;
int physicalPin=i + firstKey;
pinMode(physicalPin, INPUT);
digitalWrite(physicalPin, HIGH); // turn on pull-ups
}
Serial.begin(9600);
}
void loop() {
for (int keyNumber=0; keyNumber<numberOfKeys; keyNumber++)
{
int physicalPinToRead=keyNumber+4;
buttonState[keyNumber] = digitalRead(physicalPinToRead);
if (buttonState[keyNumber] != lastButtonState[keyNumber])
{
if (buttonState[keyNumber] == LOW)
{
irsend.sendSony(irKeyCodes[keyNumber], 32);
Serial.println("Sending");
}
lastButtonState[keyNumber] = buttonState[keyNumber];
}
}
}
<RXZRQ¦WVHHDQ\WKLQJZKHQWKHFRGHVDUHVHQWEHFDXVHWKHOLJKWIURP
WKHLQIUDUHG/('LVQ¦WYLVLEOHWRWKHQDNHGH\H
10.3 Imitating Remote Control Signals | 325
)LJXUH%XWWRQVDQG/('IRU,5VHQGHU
Discussion
+HUH$UGXLQRFRQWUROVWKHGHYLFHE\IODVKLQJDQ,5/('WRGXSOLFDWHWKHVLJQDOWKDW
ZRXOGEHVHQWIURP\RXUUHPRWHFRQWURO7KLVUHTXLUHVDQ,5/('7KHVSHFLILFDWLRQV
DUHQRWFULWLFDOVHH$SSHQGL[$IRUVXLWDEOHFRPSRQHQWV
7KH,5OLEUDU\KDQGOHVWKHWUDQVODWLRQIURPQXPHULFFRGHWR,5/('IODVKHV<RXQHHG
WRFUHDWHDQREMHFWIRUVHQGLQJ,5PHVVDJHV7KHIROORZLQJOLQHFUHDWHVDQIRsendREMHFW
WKDWZLOOFRQWUROWKH/('RQSLQ \RXDUHQRWDEOHWRVSHFLI\ZKLFKSLQWRXVHWKLVLV
KDUGFRGHGZLWKLQWKHOLEUDU\ IRsend irsend;
7KHFRGHXVHVDQDUUD\ VHH5HFLSH FDOOHG irKeyCodesWRKROGWKHUDQJHRIYDOXHV
WKDWFDQEHVHQW,WPRQLWRUVILYHVZLWFKHVWRVHHZKLFKRQHKDVEHHQSUHVVHGDQGVHQGV
WKHUHOHYDQWFRGHLQWKHIROORZLQJOLQH
irsend.sendSony(irKeyCodes[keyNumber], 32);
7KHirSendREMHFWKDVGLIIHUHQWIXQFWLRQVIRUYDULRXVSRSXODULQIUDUHGFRGHIRUPDWVVR
FKHFNWKHOLEUDU\GRFXPHQWDWLRQLI\RXDUHXVLQJRQHRIWKHRWKHUUHPRWHFRQWUROIRU
PDWV<RXFDQXVH5HFLSHLI\RXZDQWWRGLVSOD\WKHIRUPDWXVHGLQ\RXUUHPRWH
FRQWURO
7KHVNHWFKSDVVHVWKHFRGHIURPWKHDUUD\DQGWKHQXPEHUDIWHULWWHOOVWKHIXQFWLRQ
KRZPDQ\ELWVORQJWKDWQXPEHULV7KH[DWWKHEHJLQQLQJRIWKHQXPEHUVLQWKH
GHILQLWLRQRIirKeyCodesDWWKHWRSRIWKHVNHWFKPHDQVWKHFRGHVDUHZULWWHQLQKH[ VHH
326 | Chapter 10:ಗRemotely Controlling External Devices
&KDSWHUIRUGHWDLOVDERXWKH[QXPEHUV (DFKFKDUDFWHULQKH[UHSUHVHQWVDELWYDOXH
7KHFRGHVKHUHXVHHLJKWFKDUDFWHUVVRWKH\DUHELWVORQJ
7KH/('LVFRQQHFWHGZLWKDFXUUHQWOLPLWLQJUHVLVWRU VHHWKH5HFLSHVHFWLRQLQ
&KDSWHU <RXFDQYHULI\WKDWDQLQIUDUHGGLRGHLVZRUNLQJZLWKDGLJLWDOFDPHUD¢
\RXVKRXOGEHDEOHWRVHHLWIODVKLQJLQWKHFDPHUD¦V/&'YLHZILQGHU
,I\RXQHHGWRLQFUHDVHWKHVHQGLQJUDQJH\RXFDQXVHPXOWLSOH/('VRUVHOHFWRQHZLWK
JUHDWHURXWSXW
See Also
&KDSWHUSURYLGHVPRUHLQIRUPDWLRQRQFRQWUROOLQJ/('V
10.4 Controlling a Digital Camera
Problem
<RXZDQW$UGXLQRWRFRQWURODGLJLWDOFDPHUDWRWDNHSLFWXUHVXQGHUSURJUDPFRQWURO
<RXPD\ZDQWWRGRWLPHODSVHSKRWRJUDSK\RUWDNHSLFWXUHVWULJJHUHGE\DQHYHQW
GHWHFWHGE\WKH$UGXLQR
Solution
7KHUH DUH D IHZ ZD\V WR GR WKLV ,I \RXU FDPHUD KDV DQ LQIUDUHG UHPRWH XVH 5HF
LSHWROHDUQWKHUHOHYDQWUHPRWHFRGHVDQG5HFLSHWRJHW$UGXLQRWRVHQGWKRVH
FRGHVWRWKHFDPHUD
,I \RXU FDPHUD GRHVQ¦W KDYH DQ LQIUDUHG UHPRWH EXW GRHV KDYH D VRFNHW IRU D ZLUHG
UHPRWH\RXFDQXVHWKLVUHFLSHWRFRQWUROWKHFDPHUD
$FDPHUDVKXWWHUFRQQHFWRUXVXDOO\FDOOHGD756 WLSULQJVOHHYH FRQ
QHFWRUW\SLFDOO\FRPHVLQPPRUPPVL]HVEXWWKHOHQJWKDQG
VKDSHRIWKHWLSPD\EHQRQVWDQGDUG7KHVDIHVWZD\WRJHWWKHFRUUHFW
SOXJLVWREX\DFKHDSZLUHGUHPRWHVZLWFKIRU\RXUPRGHORIFDPHUD
DQGPRGLI\WKDWRUEX\DQDGDSWHUFDEOHIURPDVSHFLDOLVWVXSSOLHU *RR
JOH£756FDPHUDVKXWWHU¤ 10.4 Controlling a Digital Camera | 327
<RXFRQQHFWWKH$UGXLQRWRDVXLWDEOHFDEOHIRU\RXUFDPHUDXVLQJRSWRFRXSOHUVDV
VKRZQLQ)LJXUH
7KLVVNHWFKWDNHVDSLFWXUHHYHU\VHFRQGV
/*
camera sketch
takes 20 pictures with a digital camera
using pin 4 to trigger focus
pin 3 to trigger the shutter
*/
int focus = 4;
int shutter = 3;
long exposure = 250;
long interval = 10000;
//optocoupler attached to focus
//optocoupler attached to shutter
//exposure time in milliseconds
//time between shots, in milliseconds
void setup()
{
pinMode(focus, OUTPUT);
pinMode(shutter, OUTPUT);
for (int i=0; i<20; i++)
{
takePicture(exposure);
delay(interval);
}
}
//camera will take 20 pictures
//takes picture
//wait to take the next picture
void loop()
{
so loop is empty
sketch won't compile
}
//once it's taken 20 pictures it is done,
//but loop still needs to be here or the
void takePicture(long exposureTime)
{
int wakeup = 10;
and focus
digitalWrite(focus, HIGH);
delay(wakeup);
digitalWrite(shutter, HIGH);
delay(exposureTime);
digitalWrite(shutter, LOW);
digitalWrite(focus, LOW);
}
328 | Chapter 10:ಗRemotely Controlling External Devices
//camera will take some time to wake up
//adjust this to suit your camera
//wake the camera and focus
//wait for it to wake up and focus
//open the shutter
//wait for the exposure time
//release shutter
//release the focus
)LJXUH8VLQJRSWRFRXSOHUVZLWKD756FDPHUDFRQQHFWRU
Discussion
,W¦VQRWDGYLVDEOHWRFRQQHFW$UGXLQRSLQVGLUHFWO\WRDFDPHUD¢WKHYROWDJHVPD\QRW
EHFRPSDWLEOHDQG\RXULVNGDPDJLQJ\RXU$UGXLQRRU\RXUFDPHUD2SWRFRXSOHUVDUH
XVHGWRLVRODWH$UGXLQRIURP\RXUFDPHUDVHHWKHLQWURGXFWLRQRIWKLVFKDSWHUIRUPRUH
DERXWWKHVHGHYLFHV
<RXZLOOQHHGWRFKHFNWKHXVHUPDQXDOIRU\RXUFDPHUDWRLGHQWLI\WKHFRUUHFW756
FRQQHFWRUWRXVH
<RXPD\QHHGWRFKDQJHWKHRUGHURIWKHSLQVWXUQLQJRQDQGRIILQWKH takePicture
IXQFWLRQWRJHWWKHEHKDYLRU\RXZDQW)RUD&DQRQFDPHUDWRGREXOEH[SRVXUHV\RX
QHHGWRWXUQRQWKHIRFXVWKHQRSHQWKHVKXWWHUZLWKRXWUHOHDVLQJWKHIRFXVWKHQUHOHDVH
WKHVKXWWHUDQGWKHQUHOHDVHWKHIRFXV DVLQWKHVNHWFK 7RWDNHDSLFWXUHDQGKDYHWKH
FDPHUDFDOFXODWHWKHH[SRVXUHSUHVVWKHIRFXVEXWWRQUHOHDVHLWDQGWKHQSUHVVWKH
VKXWWHU
See Also
,I\RXZDQWWRFRQWURODVSHFWVRIDFDPHUD¦VRSHUDWLRQKDYHDORRNDWWKH&DQRQ+DFN
'HYHORSPHQW.LWDWKWWSFKGNZLNLDFRPZLNL&+'.
$OVRVHH7KH&DQRQ&DPHUD+DFNHUV0DQXDO7HDFK<RXU&DPHUD1HZ7ULFNVE\%HUW
KROG'DXP 5RFN\1RRN ,WLVDOVRSRVVLEOHWRFRQWUROYLGHRFDPHUDVLQDVLPLODUIDVKLRQXVLQJ/$1&<RXFDQ
ILQGGHWDLOVRQWKLVE\VHDUFKLQJIRU£/$1&¤LQWKH$UGXLQR3OD\JURXQG
10.4 Controlling a Digital Camera | 329
10.5 Controlling AC Devices by Hacking a Remote Controlled
Switch
Problem
<RXZDQWWRVDIHO\VZLWFK$&OLQHFXUUHQWVRQDQGRIIWRFRQWUROOLJKWVDQGDSSOLDQFHV
XVLQJDUHPRWHFRQWUROOHGVZLWFK
Solution
$UGXLQRFDQWULJJHUWKHEXWWRQVRIDUHPRWHFRQWUROOHGVZLWFKXVLQJDQRSWRFRXSOHU
7KLVPD\EHQHFHVVDU\IRUUHPRWHVWKDWXVHZLUHOHVVLQVWHDGRILQIUDUHGWHFKQRORJ\7KLV
WHFKQLTXHFDQEHXVHGIRUDOPRVWDQ\UHPRWHFRQWURO+DFNLQJDUHPRWHLVSDUWLFXODUO\
XVHIXOWRLVRODWHSRWHQWLDOO\GDQJHURXV$&YROWDJHVIURP\RXDQG$UGXLQREHFDXVHRQO\
WKHEDWWHU\RSHUDWHGFRQWUROOHULVPRGLILHG
2SHQLQJWKHUHPRWHFRQWUROZLOOYRLGWKHZDUUDQW\DQGFDQSRWHQWLDOO\
GDPDJHWKHGHYLFH7KHLQIUDUHGUHFLSHVLQWKLVFKDSWHUDUHSUHIHUDEOH
EHFDXVHWKH\DYRLGPRGLI\LQJWKHUHPRWHFRQWURO
2SHQWKHUHPRWHFRQWURODQGFRQQHFWWKHRSWRFRXSOHUVRWKDWWKHSKRWRHPLWWHU SLQV
DQGLQ)LJXUH LVFRQQHFWHGWR$UGXLQRDQGWKHSKRWRWUDQVLVWRU SLQVDQG
LVFRQQHFWHGDFURVVWKHUHPRWHFRQWUROFRQWDFWV
)LJXUH2SWRFRXSOHUVFRQQHFWHGWRUHPRWHFRQWUROFRQWDFWV
330 | Chapter 10:ಗRemotely Controlling External Devices
7KLVVNHWFKXVHVDVZLWFKFRQQHFWHGWR$UGXLQRWR£SXVK¤WKHUHPRWH21DQG2))
EXWWRQV
/*
OptoRemote sketch
A switch connected to pin 2 turns a device on and off using optocouplers
The outputs are pulsed for half a second when the switch is pressed or released
*/
const int inputPin
= 2;
// input pin for the switch
const int remoteOnPin = 3;
// output pin to turn the remote on
const int remoteOffPin = 4;
// output pin to turn the remote off
const int PUSHED
= LOW;
// value when button is pressed
boolean isOn;
// variable stores the last command
void setup() {
Serial.begin(9600);
pinMode(remoteOnPin, OUTPUT);
pinMode(remoteOffPin, OUTPUT);
pinMode(inputPin, INPUT);
digitalWrite(inputPin,HIGH); // turn on internal pull-up on the inputPin
}
void loop(){
int val = digitalRead(inputPin); // read input value
// if the switch is pushed then switch on if not already on
if( val == PUSHED)
{
if(isOn != true)
// if it's not already on, turn the remote button on
{
pulseRemote(remoteOnPin);
isOn = true;
// remember that the remote is now on
}
}
// if the switch is not pushed then switch off if not already off
else
{
// here if the button is not pushed
if(isOn == true)
// if it's on, turn the remote button off
{
pulseRemote(remoteOffPin);
isOn = false;
// remember that the remote is now off
}
}
}
// turn the optocoupler on for half a second to blip the remote control button
void pulseRemote(int pin )
{
digitalWrite(pin, HIGH);
// turn the optocoupler on
delay(500);
// wait half a second
digitalWrite(pin, LOW);
// turn the optocoupler off
}
Discussion
2SWRFRXSOHUVDUHH[SODLQHGLQ5HFLSHVRFKHFNWKDWRXWLI\RXDUHXQIDPLOLDUZLWK
RSWRFRXSOHUV
10.5 Controlling AC Devices by Hacking a Remote Controlled Switch | 331
7KHVZLWFKHVLQPRVWUHPRWHFRQWUROVFRQVLVWRILQWHUOHDYHGEDUHFRSSHUWUDFHVZLWKD
FRQGXFWLYHEXWWRQWKDWFORVHVDFRQQHFWLRQDFURVVWKHWUDFHVZKHQSUHVVHG/HVVFRP
PRQDUHFRQWUROVWKDWFRQWDLQFRQYHQWLRQDOSXVKVZLWFKHVWKHVHDUHHDVLHUWRXVHDV
WKHOHJVRIWKHVZLWFKHVSURYLGHDFRQYHQLHQWFRQQHFWLRQSRLQW
7KHRULJLQDOUHPRWHEXWWRQDQGWKHRSWRFRXSOHUFDQEHXVHGWRJHWKHU¢WKHVZLWFKLQJ
DFWLRQZLOOEHSHUIRUPHGLIHLWKHUPHWKRGLVDFWLYDWHG SUHVVLQJWKHEXWWRQRUWXUQLQJ
RQWKHRSWRFRXSOHU 7KHWUDQVLVWRULQWKHRSWRFRXSOHUZLOORQO\DOORZHOHFWULFLW\WRIORZLQRQHGLUHFWLRQVR
LILWGRHVQ¦WZRUNWKHILUVWWLPHWU\VZLWFKLQJWKHWUDQVLVWRUVLGHFRQQHFWLRQVRYHUDQG
VHHLIWKDWIL[HVLW
6RPHUHPRWHVKDYHRQHVLGHRIDOORIWKHVZLWFKHVFRQQHFWHGWRJHWKHU XVXDOO\WRWKH
JURXQGRIWKDWFLUFXLW <RXFDQWUDFHWKHFRQQHFWLRQVRQWKHERDUGWRFKHFNIRUWKLVRU
XVHDPXOWLPHWHUWRVHHZKDWWKHUHVLVWDQFHLVEHWZHHQWKHWUDFHVRQGLIIHUHQWVZLWFKHV
,IWUDFHVKDYHFRPPRQFRQQHFWLRQVLWLVRQO\QHFHVVDU\WRFRQQHFWRQHZLUHWRHDFK
FRPPRQJURXS)HZHUWUDFHVDUHHDVLHUEHFDXVHFRQQHFWLQJWKHZLUHVFDQEHILGGO\LI
WKHUHPRWHLVVPDOO
7KHUHPRWHFRQWUROPD\KDYHPXOWLSOHFRQWDFWVFRUUHVSRQGLQJWRHDFKEXWWRQ<RX
PD\QHHGPRUHWKDQRQHRSWRFRXSOHUIRUHDFKEXWWRQSRVLWLRQWRFRQQHFWWKHFRQWDFWV
)LJXUHVKRZVWKUHHRSWRFRXSOHUVWKDWDUHFRQWUROOHGIURPDVLQJOH$UGXLQRSLQ
)LJXUH0XOWLSOHRSWRFRXSOHUVFRQQHFWHGWRDVLQJOHUHPRWHFRQWUROEXWWRQ
332 | Chapter 10:ಗRemotely Controlling External Devices
CHAPTER 11
Using Displays
11.0 Introduction
/LTXLGFU\VWDOGLVSOD\V /&'V RIIHUDFRQYHQLHQWDQGLQH[SHQVLYHZD\WRSURYLGHDXVHU
LQWHUIDFHIRUDSURMHFW7KLVFKDSWHUH[SODLQVKRZWRFRQQHFWDQGXVHFRPPRQWH[WDQG
JUDSKLFDO/&'SDQHOVZLWK$UGXLQR%\IDUWKHPRVWSRSXODU/&'LVWKHWH[WSDQHO
EDVHGRQWKH+LWDFKL+'FKLS7KLVGLVSOD\VWZRRUIRXUOLQHVRIWH[WZLWKRU
FKDUDFWHUVSHUOLQH DQGFKDUDFWHUYHUVLRQVDUHDYDLODEOHEXWXVXDOO\DWPXFK
KLJKHUSULFHV $OLEUDU\IRUGULYLQJWH[W/&'GLVSOD\VLVSURYLGHGZLWK$UGXLQRDQG
\RX FDQ SULQW WH[W RQ \RXU /&' DV HDVLO\ DV RQ WKH 6HULDO 0RQLWRU VHH &KDSWHU EHFDXVH/&'DQGVHULDOVKDUHWKHVDPHXQGHUO\LQJprintIXQFWLRQV
/&'VFDQGRPRUHWKDQGLVSOD\VLPSOHWH[WZRUGVFDQEHVFUROOHGRUKLJKOLJKWHGDQG
\RXFDQGLVSOD\DVHOHFWLRQRIVSHFLDOV\PEROVDQGQRQ(QJOLVKFKDUDFWHUV
<RXFDQFUHDWH\RXURZQV\PEROVDQGEORFNJUDSKLFVZLWKDWH[W/&'EXWLI\RXZDQW
ILQHJUDSKLFDOGHWDLO\RXQHHGDJUDSKLFDOGLVSOD\*UDSKLFDO/&' */&' GLVSOD\V
DUHDYDLODEOHDWDVPDOOSULFHSUHPLXPRYHUWH[WGLVSOD\VDQGPDQ\SRSXODU*/&'
SDQHOVFDQGLVSOD\XSWRHLJKWOLQHVRIWH[WFKDUDFWHUVLQDGGLWLRQWRJUDSKLFV
/&'GLVSOD\VKDYHPRUHZLUHVFRQQHFWLQJWR$UGXLQRWKDQPRVWRWKHUUHFLSHVLQWKLV
ERRN,QFRUUHFWFRQQHFWLRQVDUHWKHPDMRUFDXVHRISUREOHPVZLWK/&'VVRWDNH\RXU
WLPHZLULQJWKLQJVXSDQGWULSOHFKHFNWKDWWKLQJVDUHFRQQHFWHGFRUUHFWO\$QLQH[
SHQVLYHPXOWLPHWHUFDSDEOHRIPHDVXULQJYROWDJHDQGUHVLVWDQFHLVDELJKHOSIRUYHUL
I\LQJWKDW\RXUZLULQJLVFRUUHFW,WFDQVDYH\RXDORWRIKHDGVFUDWFKLQJLIQRWKLQJLV
EHLQJGLVSOD\HG<RXGRQ¦WQHHGDQ\WKLQJIDQF\DVHYHQWKHFKHDSHVWPXOWLPHWHUZLOO
KHOS\RXYHULI\WKDWWKHFRUUHFWSLQVDUHFRQQHFWHGDQGWKDWWKHYROWDJHVDUHFRUUHFW
<RXFDQHYHQILQGDYLGHRWXWRULDODQG3')H[SODLQLQJKRZWRXVHDPXOWLPHWHUDWKWWS
EORJPDNH]LQHFRPDUFKLYHPXOWLPHWHUBWXWRULDOBPDNHBKWPO
)RUSURMHFWVWKDWUHTXLUHDELJJHUGLVSOD\WKDQDYDLODEOHLQLQH[SHQVLYH/&'SDQHOV
5HFLSHVKRZVKRZ\RXFDQXVHDWHOHYLVLRQDVDQRXWSXWGHYLFHIRU$UGXLQR
333
11.1 Connecting and Using a Text LCD Display
Problem
<RXKDYHDWH[W/&'EDVHGRQWKHLQGXVWU\VWDQGDUG+'RUDFRPSDWLEOHFRQ
WUROOHUFKLSDQG\RXZDQWWRGLVSOD\WH[WDQGQXPHULFYDOXHV
Solution
7KH$UGXLQRVRIWZDUHLQFOXGHVWKH/LTXLG&U\VWDOOLEUDU\IRUGULYLQJ/&'GLVSOD\VEDVHG
RQWKH+'FKLS
0RVWWH[W/&'VVXSSOLHGIRUXVHZLWK$UGXLQRZLOOEHFRPSDWLEOHZLWK
WKH+LWDFKL+'FRQWUROOHU,I\RXDUHQRWVXUHDERXW\RXUFRQ
WUROOHUFKHFNWKHGDWDVKHHWWRVHHLILWLVDRUFRPSDWLEOH
7RJHWWKHGLVSOD\ZRUNLQJ\RXQHHGWRZLUHWKHSRZHUGDWDDQGFRQWUROSLQV&RQQHFW
WKHGDWDDQGVWDWXVOLQHVWRGLJLWDORXWSXWSLQVDQGZLUHXSDFRQWUDVWSRWHQWLRPHWHU
DQGFRQQHFWWKHSRZHUOLQHV,I\RXUGLVSOD\KDVDEDFNOLJKWWKLVQHHGVFRQQHFWLQJ
XVXDOO\WKURXJKDUHVLVWRU
)LJXUHVKRZVWKHPRVWFRPPRQ/&'FRQQHFWLRQV,W¦VLPSRUWDQWWRFKHFNWKH
GDWD VKHHW IRU \RXU /&' WR YHULI\ WKH SLQ FRQQHFWLRQV 7DEOH VKRZV WKH PRVW
FRPPRQSLQFRQQHFWLRQVEXWLI\RXU/&'XVHVGLIIHUHQWSLQVPDNHVXUHLWLVFRPSDW
LEOHZLWKWKH+LWDFKL+'¢WKLVUHFLSHZLOORQO\ZRUNRQ/&'GLVSOD\VWKDWDUH
FRPSDWLEOH ZLWK WKDW FKLS 7KH /&' ZLOO KDYH SLQV RU SLQV LI WKHUH LV QR
EDFNOLJKW ¢PDNHVXUH\RXLGHQWLI\SLQRQ\RXUSDQHOLWPD\EHLQDGLIIHUHQWSRVLWLRQ
WKDQVKRZQLQWKHILJXUH
<RXPD\ZRQGHUZK\/&'SLQVWKURXJKDUHQRWFRQQHFWHG7KH
/&'GLVSOD\FDQEHFRQQHFWHGXVLQJHLWKHUIRXUSLQVRUHLJKWSLQVIRU
GDWDWUDQVIHU7KLVUHFLSHXVHVWKHIRXUSLQPRGHEHFDXVHWKLVIUHHVXS
WKHRWKHUIRXU$UGXLQRSLQVIRURWKHUXVHV7KHUHLVDWKHRUHWLFDOSHU
IRUPDQFHLPSURYHPHQWXVLQJHLJKWSLQVEXWLW¦VLQVLJQLILFDQWDQGQRW
ZRUWKWKHORVVRIIRXU$UGXLQRSLQV
334 | Chapter 11:ಗUsing Displays
)LJXUH&RQQHFWLRQVIRUDWH[W/&'
7DEOH/&'SLQFRQQHFWLRQV
LCD pin
Function
Arduino pin
1
Gnd or 0V or Vss
Gnd
2
+5V or Vdd
5V
3
Vo or contrast
4
RS
5
R/W
6
E
7
D0
8
D1
9
D2
10
D3
11
D4
5
12
D5
4
13
D6
3
14
D7
2
15
A or analog
16
K or cathode
12
11
11.1 Connecting and Using a Text LCD Display | 335
<RXZLOOQHHGWRFRQQHFWD.SRWHQWLRPHWHUWRSURYLGHWKHFRQWUDVWYROWDJHWR/&'
SLQ:LWKRXWWKHFRUUHFWYROWDJHRQWKLVSLQ\RXPD\QRWVHHDQ\WKLQJGLVSOD\HG,Q
)LJXUHRQHVLGHRIWKHSRWFRQQHFWVWR*QG JURXQG WKHRWKHUVLGHFRQQHFWVWR
$UGXLQR9DQGWKHFHQWHURIWKHSRWJRHVWR/&'SLQ7KH/&'LVSRZHUHGE\
FRQQHFWLQJ*QGDQG9IURP$UGXLQRWR/&'SLQVDQG
0DQ\/&'SDQHOVKDYHDQLQWHUQDOODPSFDOOHGDEDFNOLJKWWRLOOXPLQDWHWKHGLVSOD\
<RXUGDWDVKHHWVKRXOGLQGLFDWHZKHWKHUWKHUHLVDEDFNOLJKWDQGLILWUHTXLUHVDQH[WHUQDO
UHVLVWRU¢PDQ\GRQHHGWKLVWRSUHYHQWEXUQLQJRXWWKHEDFNOLJKW/('DVVHPEO\ LI\RX
DUHQRWVXUH\RXFDQEHVDIHE\XVLQJDRKPUHVLVWRU 7KHEDFNOLJKWLVSRODUL]HG
VRPDNHVXUHSLQLVFRQQHFWHGWR9DQGSLQWR*QG 7KHUHVLVWRULVVKRZQ
FRQQHFWHGEHWZHHQSLQDQG*QGEXWLWFDQDOVREHFRQQHFWHGEHWZHHQSLQDQG
9
'RXEOHFKHFNWKHZLULQJEHIRUH\RXDSSO\SRZHUDV\RXFDQGDPDJHWKH/&'LI\RX
FRQQHFW WKH SRZHU SLQV LQFRUUHFWO\ 7R UXQ WKH +HOOR:RUOG VNHWFK SURYLGHG ZLWK
$UGXLQR FOLFN WKH ,'( )LOHV PHQX LWHP DQG QDYLJDWH WR ([DP
SOHVൺ/LEUDU\ൺ/LTXLG&U\VWDOൺ+HOOR:RUOG
7KHIROORZLQJFRGHLVPRGLILHGVOLJKWO\WRSULQWQXPEHUVLQDGGLWLRQWR£KHOORZRUOG¤
&KDQJHnumRowsDQGnumColsWRPDWFKWKHURZVDQGFROXPQVLQ\RXU/&'
/*
LiquidCrystal Library - Hello World
Demonstrates the use of a 16 × 2 LCD display.
http://www.arduino.cc/en/Tutorial/LiquidCrystal
*/
#include <LiquidCrystal.h> // include the library code
//constants for the number of rows and columns in the LCD
const int numRows = 2;
const int numCols = 16;
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup()
{
lcd.begin(numCols, numRows);
lcd.print("hello, world!"); // Print a message to the LCD.
}
void loop()
{
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
// print the number of seconds since reset:
336 | Chapter 11:ಗUsing Displays
}
lcd.print(millis()/1000);
5XQWKHVNHWFK\RXVKRXOGVHH£KHOORZRUOG¤GLVSOD\HGRQWKHILUVWOLQHRI\RXU/&'
7KHVHFRQGOLQHZLOOGLVSOD\DQXPEHUWKDWLQFUHDVHVE\RQHHYHU\VHFRQG
Discussion
,I\RXGRQ¦WVHHDQ\WH[WDQG\RXKDYHGRXEOHFKHFNHGWKDWDOOZLUHVDUHFRQQHFWHG
FRUUHFWO\\RXPD\QHHGWRDGMXVWWKHFRQWUDVWSRW:LWKWKHSRWVKDIWURWDWHGWRRQH
VLGH XVXDOO\WKHVLGHFRQQHFWHGWR*QG \RXZLOOKDYHPD[LPXPFRQWUDVWDQGVKRXOG
VHHEORFNVDSSHDULQDOOWKHFKDUDFWHUSRVLWLRQV:LWKWKHSRWURWDWHGWRWKHRWKHUH[
WUHPH\RXSUREDEO\ZRQ¦WVHHDQ\WKLQJDWDOO7KHFRUUHFWVHWWLQJZLOOGHSHQGRQPDQ\
IDFWRUVLQFOXGLQJYLHZLQJDQJOHDQGWHPSHUDWXUH¢WXUQWKHSRWXQWLO\RXJHWWKHEHVW
ORRNLQJGLVSOD\
,I\RXFDQ¦WVHHEORFNVRISL[HOVDSSHDUDWDQ\VHWWLQJRIWKHSRWFKHFNWKDWWKH/&'LV
EHLQJGULYHQRQWKHFRUUHFWSLQV
2QFH\RXFDQVHHWH[WRQWKHVFUHHQXVLQJWKH/&'LQDVNHWFKLVHDV\<RXXVHVLPLODU
SULQW FRPPDQGV WR WKRVH IRU VHULDO SULQWLQJ FRYHUHG LQ &KDSWHU 7KH QH[W UHFLSH
UHYLHZVWKHSULQWFRPPDQGVDQGH[SODLQVKRZWRFRQWUROWH[WSRVLWLRQ
See Also
/LTXLG&U\VWDOUHIHUHQFHKWWSDUGXLQRFFHQ5HIHUHQFH/LTXLG&U\VWDO3ULQW
6HH&KDSWHUIRUGHWDLOVRQprintFRPPDQGV
7KHGDWDVKHHWIRUWKH+LWDFKL+'/&'FRQWUROOHULVWKHGHILQLWLYHUHIHUHQFHIRU
GHWDLOHGORZOHYHOIXQFWLRQDOLW\7KH$UGXLQROLEUDU\LQVXODWHV\RXIURPPRVWRIWKH
FRPSOH[LW\EXWLI\RXZDQWWRUHDGDERXWWKHUDZFDSDELOLWLHVRIWKHFKLS\RXFDQ
GRZQORDG WKH GDWD VKHHW IURP KWWSZZZVSDUNIXQFRPGDWDVKHHWV/&'+'
SGI
7KH/&'SDJHLQWKH$UGXLQR3OD\JURXQGFRQWDLQVVRIWZDUHDQGKDUGZDUHWLSVDQG
OLQNVKWWSZZZDUGXLQRFFSOD\JURXQG&RGH/&'
11.2 Formatting Text
Problem
<RXZDQWWRFRQWUROWKHSRVLWLRQRIWH[WGLVSOD\HGRQWKH/&'VFUHHQIRUH[DPSOHWR
GLVSOD\YDOXHVLQVSHFLILFSRVLWLRQV
11.2 Formatting Text | 337
Download from Wow! eBook <www.wowebook.com>
Solution
7KLVVNHWFKGLVSOD\VDFRXQWGRZQIURPWR,WWKHQGLVSOD\VDVHTXHQFHRIGLJLWVLQ
WKUHHFROXPQVRIIRXUFKDUDFWHUV&KDQJHnumRowsDQGnumColsWRPDWFKWKHURZVDQG
FROXPQVLQ\RXU/&'
/*
LiquidCrystal Library - FormatText
*/
#include <LiquidCrystal.h> // include the library code:
//constants for the number of rows and columns in the LCD
const int numRows = 2;
const int numCols = 16;
int count;
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup()
{
lcd.begin(numCols, numRows);
lcd.print("Starting in "); // this string is 12 characters long
for(int i=9; i > 0; i--)
// count down from 9
{
// the top line is row 0
lcd.setCursor(12,0); // move the cursor to the end of the string
printed above
lcd.print(i);
delay(1000);
}
}
void loop()
{
int columnWidth = 4;
int displayColumns = 3;
}
//spacing for the columns
//how many columns of numbers
lcd.clear();
for( int col=0; col < displayColumns; col++)
{
lcd.setCursor(col * columnWidth, 0);
count = count+ 1;
lcd.print(count);
}
delay(1000);
338 | Chapter 11:ಗUsing Displays
Discussion
7KHlcd.printIXQFWLRQVDUHVLPLODUWRSerial.print,QDGGLWLRQWKH/&'OLEUDU\KDV
FRPPDQGVWKDWFRQWUROWKHFXUVRUORFDWLRQ WKHURZDQGFROXPQZKHUHWH[WZLOOEH
SULQWHG 7KHlcd.printVWDWHPHQWGLVSOD\VHDFKQHZFKDUDFWHUDIWHUWKHSUHYLRXVRQH7H[WSULQ
WHGEH\RQGWKHHQGRIDOLQHPD\QRWEHGLVSOD\HGRUPD\EHGLVSOD\HGRQDQRWKHUOLQH
7KH lcd.setCursor()FRPPDQGHQDEOHV\RXWRVSHFLI\ZKHUHWKHQH[W lcd.printZLOO
VWDUW<RXVSHFLI\WKHFROXPQDQGURZSRVLWLRQ WKHWRSOHIWFRUQHULV 2QFHWKH
FXUVRULVSRVLWLRQHGWKHQH[Wlcd.printZLOOVWDUWIURPWKDWSRLQWDQGLWZLOORYHUZULWH
H[LVWLQJWH[W7KHVNHWFKLQWKLVUHFLSH¦V6ROXWLRQXVHVWKLVWRSULQWQXPEHUVLQIL[HG
ORFDWLRQV
)RUH[DPSOHLQsetup
lcd.setCursor(12,0); // move the cursor to the 13th position
lcd.print(i);
lcd.setCursor(12,0) HQVXUHV WKDW HDFK QXPEHU LV SULQWHG LQ WKH VDPH SRVLWLRQ WKH
WKLUWHHQWKFROXPQILUVWURZSURGXFLQJWKHGLJLWVKRZQDWDIL[HGSRVLWLRQUDWKHUWKDQ
HDFKQXPEHUEHLQJGLVSOD\HGDIWHUWKHSUHYLRXVQXPEHU
5RZV DQG FROXPQV VWDUW IURP ]HUR VR setCursor(4,0) ZRXOG VHW WKH
FXUVRUWRWKHILIWKFROXPQRQWKHILUVWURZ7KLVLVEHFDXVHWKHUHDUHILYH
FKDUDFWHUVORFDWHGLQSRVLWLRQVWKURXJK,IWKDWLVQRWFOHDULWPD\
KHOS\RXLI\RXFRXQWWKLVRXWRQ\RXUILQJHUVVWDUWLQJIURP]HUR
7KH IROORZLQJ OLQHV XVH setCursor WR VSDFH RXW WKH VWDUW RI HDFK FROXPQ WR SURYLGH
columnwidthVSDFHVIURPWKHVWDUWRIWKHSUHYLRXVFROXPQ
lcd.setCursor(col * columnWidth, 0);
count = count+ 1;
lcd.print(count);
lcd.clear();
lcd.clearFOHDUVWKHVFUHHQDQGPRYHVWKHFXUVRUEDFNWRWKHWRSOHIWFRUQHU
+HUH LV D YDULDWLRQ RQ loop WKDW GLVSOD\V QXPEHUV XVLQJ DOO WKH URZV RI \RXU /&'
5HSODFH\RXU loopFRGHZLWKWKHIROORZLQJ PDNHVXUH\RXVHWnumRowsDQG numColsDW
WKHWRSRIWKHVNHWFKWRPDWFKWKHURZVDQGFROXPQVLQ\RXU/&' void loop()
{
int columnWidth = 4;
int displayColumns = 3;
lcd.clear();
for(int row=0; row < numRows; row++)
{
for( int col=0; col < displayColumns; col++)
11.2 Formatting Text | 339
{
lcd.setCursor(col * columnWidth, row);
count = count+ 1;
lcd.print(count);
}
}
delay(1000);
}
7KH ILUVW for ORRS VWHSV WKURXJK WKH DYDLODEOH URZV DQG WKH VHFRQG for ORRS VWHSV
WKURXJKWKHFROXPQV
7R DGMXVW KRZ PDQ\ QXPEHUV DUH GLVSOD\HG LQ D URZ WR ILW WKH /&' FDOFXODWH WKH
displayColumnsYDOXHUDWKHUWKDQVHWWLQJLW&KDQJH
int displayColumns = 3;
WR
int displayColumns = numCols / columnWidth;
See Also
7KH/LTXLG&U\VWDOOLEUDU\WXWRULDOKWWSDUGXLQRFFHQ5HIHUHQFH/LTXLG&U\VWDO"IURP
7XWRULDO/&'/LEUDU\
11.3 Turning the Cursor and Display On or Off
Problem
<RXZDQWWREOLQNWKHFXUVRUDQGWXUQWKHGLVSOD\RQRURII<RXPD\DOVRZDQWWRGUDZ
DWWHQWLRQWRDVSHFLILFDUHDRIWKHGLVSOD\
Solution
7KLVVNHWFKVKRZVKRZ\RXFDQFDXVHWKHFXUVRU DIODVKLQJEORFNDWWKHSRVLWLRQZKHUH
WKHQH[WFKDUDFWHUZLOOEHGLVSOD\HG WREOLQN,WDOVRLOOXVWUDWHVKRZWRWXUQWKHGLVSOD\
RQDQGRIIIRUH[DPSOHWRGUDZDWWHQWLRQE\EOLQNLQJWKHHQWLUHGLVSOD\
/*
blink
*/
// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup()
{
// set up the LCD's number of columns and rows and:
lcd.begin(16, 2);
340 | Chapter 11:ಗUsing Displays
}
// Print a message to the LCD.
lcd.print("hello, world!");
void loop()
{
lcd.setCursor(0, 1);
lcd.print("cursor blink");
lcd.blink();
delay(2000);
lcd.noBlink();
lcd.print(" noBlink");
delay(2000);
lcd.clear();
lcd.print("Display off ...");
delay(1000);
lcd.noDisplay();
delay(2000);
lcd.display();
// turn the display back on
lcd.setCursor(0, 0);
lcd.print(" display flash !");
displayBlink(2, 250); // blink twice
displayBlink(2, 500); // and again for twice as long
lcd.clear();
}
void displayBlink(int blinks, int duration)
{
while(blinks--)
{
lcd.noDisplay();
delay(duration);
lcd.display();
delay(duration);
}
}
Discussion
7KHVNHWFKFDOOVblinkDQGnoBlinkIXQFWLRQVWRWRJJOHFXUVRUEOLQNLQJRQDQGRII
7KHFRGHWREOLQNWKHHQWLUHGLVSOD\LVLQDIXQFWLRQQDPHG displayBlinkWKDWPDNHV
WKHGLVSOD\IODVKDVSHFLILHGQXPEHURIWLPHV7KHIXQFWLRQXVHV lcd.display()DQG
lcd.noDisplay()WRWXUQWKHGLVSOD\WH[WRQDQGRII ZLWKRXWFOHDULQJLWIURPWKHVFUHHQ¦V
LQWHUQDOPHPRU\ 11.3 Turning the Cursor and Display On or Off | 341
11.4 Scrolling Text
Problem
<RXZDQWWRVFUROOWH[WIRUH[DPSOHWRFUHDWHDPDUTXHHWKDWGLVSOD\VPRUHFKDUDFWHUV
WKDQFDQILWRQRQHOLQHRIWKH/&'GLVSOD\
Solution
7KLVVNHWFKGHPRQVWUDWHVERWKlcd.ScrollDisplayLeftDQGlcd.ScrollDisplayRight
,WVFUROOVDOLQHRIWH[WWRWKHOHIWZKHQWLOWHGDQGWRWKHULJKWZKHQQRWWLOWHG&RQQHFW
RQHVLGHRIDWLOWVHQVRUWRSLQDQGWKHRWKHUSLQWR*QG VHH5HFLSHLI\RXDUHQRW
IDPLOLDUZLWKWLOWVHQVRUV /*
Scroll
* this sketch scrolls text left when tilted
* text scrolls right when not tilted.
*/
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int numRows = 2;
const int numCols = 16;
const int tiltPin = 7; // pin connected to tilt sensor
const char textString[] = "tilt to scroll";
const int textLen = sizeof(textString) -1; // the number of characters
boolean isTilted = false;
void setup()
{
// set up the LCD's number of columns and rows:
lcd.begin(numCols, numRows);
digitalWrite(tiltPin, HIGH); // turn on pull-ups for the tilt sensor
lcd.print(textString);
}
void loop()
{
if(digitalRead(tiltPin) == LOW && isTilted == false )
{
// here if tilted left so scroll text left
isTilted = true;
for (int position = 0; position < textLen; position++)
{
lcd.scrollDisplayLeft();
delay(150);
}
342 | Chapter 11:ಗUsing Displays
}
if(digitalRead(tiltPin) == HIGH && isTilted == true )
{
// here if previously tilted but now flat, so scroll text right
isTilted = false;
for (int position = 0; position < textLen; position++)
{
lcd.scrollDisplayRight();
delay(150);
}
}
}
Discussion
7KHILUVWKDOIRIWKH loopFRGHKDQGOHVWKHFKDQJHIURPQRWWLOWHGWRWLOWHG7KHFRGH
FKHFNVWRVHHLIWKHWLOWVZLWFKLVFORVHG LOW RURSHQ HIGH ,ILW¦VLOWDQGWKHFXUUHQW
VWDWH VWRUHGLQWKHisTiltedYDULDEOH LVQRWWLOWHGWKHWH[WLVVFUROOHGOHIW7KHGHOD\LQ
WKHforORRSFRQWUROVWKHVSHHGRIWKHVFUROODGMXVWWKHGHOD\LIWKHWH[WPRYHVWRRIDVW
RUWRRVORZ
7KHVHFRQGKDOIRIWKHFRGHXVHVVLPLODUORJLFWRKDQGOHWKHFKDQJHIURPWLOWHGWRQRW
WLOWHG
$VFUROOLQJFDSDELOLW\LVSDUWLFXODUO\XVHIXOZKHQ\RXQHHGWRGLVSOD\PRUHWH[WWKDQ
FDQILWRQDQ/&'OLQH
7KLVVNHWFKKDVDmarqueeIXQFWLRQWKDWZLOOVFUROOWH[WXSWRFKDUDFWHUVLQOHQJWK
/*
Marquee
* this sketch scrolls a long line of text
*/
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int numRows = 2;
const int numCols = 16;
void setup()
{
// set up the LCD's number of columns and rows:
lcd.begin(numCols, numRows);
}
void loop()
{
marquee("A message too long to fit !");
delay(1000);
lcd.clear();
}
11.4 Scrolling Text | 343
// this function uses scrolling to display a message up to 32 bytes long
void marquee( char *text)
{
int length = strlen(text); // the number of characters in the text
if(length < numCols)
lcd.print(text);
else
{
int pos;
for( pos = 0; pos < numCols; pos++)
lcd.print(text[pos]);
delay(1000); // allow time to read the first line before scrolling
while(pos < length)
{
lcd.scrollDisplayLeft();
lcd.print(text[pos]);
pos = pos + 1;
delay(300);
}
}
}
7KHVNHWFKXVHVWKHlcd.scrollDisplayLeftIXQFWLRQWRVFUROOWKHGLVSOD\ZKHQWKHWH[W
LVORQJHUWKDQWKHZLGWKRIWKHVFUHHQ
7KH/&'FKLSKDVLQWHUQDOPHPRU\WKDWVWRUHVWKHWH[W7KLVPHPRU\LVOLPLWHG E\WHVRQPRVWIRXUOLQHGLVSOD\V ,I\RXWU\WRXVHORQJHUPHVVDJHVWKH\PD\VWDUWWR
ZUDSRYHUWKHPVHOYHV,I\RXZDQWWRVFUROOORQJHUPHVVDJHV HJDWZHHW RUFRQWURO
VFUROOLQJPRUHSUHFLVHO\\RXQHHGDGLIIHUHQWWHFKQLTXH7KHIROORZLQJIXQFWLRQVWRUHV
WKHWH[WLQ5$0RQ$UGXLQRDQGVHQGVVHFWLRQVWRWKHVFUHHQWRFUHDWHWKHVFUROOLQJ
HIIHFW7KHVHPHVVDJHVFDQEHDQ\OHQJWKWKDWFDQILWLQWR$UGXLQRPHPRU\
// this version of marquee uses manual scrolling for very long messages
void marquee( char *text)
{
int length = strlen(text); // the number of characters in the text
if(length < numCols)
lcd.print(text);
else
{
int pos;
for( pos = 0; pos < numCols; pos++)
lcd.print(text[pos]);
delay(1000); // allow time to read the first line before scrolling
while(pos <= length - numCols)
{
lcd.setCursor(0,0);
for( int i=0; i < numCols; i++)
lcd.print(text[pos+i]);
delay(300);
pos = pos + 1;
}
344 | Chapter 11:ಗUsing Displays
}
}
11.5 Displaying Special Symbols
Problem
<RXZDQWWRGLVSOD\VSHFLDOV\PEROV GHJUHHV ÷π SL RUDQ\RWKHUV\PEROVWRUHG
LQWKH/&'FKDUDFWHUPHPRU\
Solution
,GHQWLI\WKHFKDUDFWHUFRGH\RXZDQWWRGLVSOD\E\ORFDWLQJWKHV\PEROLQWKHFKDUDFWHU
SDWWHUQ WDEOH LQ WKH /&' GDWD VKHHW 7KLV VNHWFK SULQWV VRPH FRPPRQ V\PEROV LQ
setup,WWKHQVKRZVDOOGLVSOD\DEOHV\PEROVLQloop
/*
LiquidCrystal Library - Special Chars
*/
#include <LiquidCrystal.h>
//set constants for number of rows and columns to match your LCD
const int numRows = 2;
const int numCols = 16;
// defines for some useful symbols
const byte degreeSymbol = B11011111;
const byte piSymbol
= B11110111;
const byte centsSymbol = B11101100;
const byte sqrtSymbol
= B11101000;
const byte omegaSymbol = B11110100;
// the symbol used for ohms
byte charCode = 32; // the first printable ascii character
int col;
int row;
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup()
{
lcd.begin(numRows, numCols);
showSymbol(degreeSymbol, "degrees");
showSymbol (piSymbol, "pi");
showSymbol(centsSymbol, "cents");
showSymbol(sqrtSymbol, "sqrt");
showSymbol(omegaSymbol, "ohms");
lcd.clear();
}
11.5 Displaying Special Symbols | 345
void loop()
{
lcd.print(charCode);
calculatePosition();
if(charCode == 255)
{
// finished all characters so wait another few seconds and start over
delay(2000);
lcd.clear();
row = col = 0;
charCode = 32;
}
charCode = charCode + 1;
}
void calculatePosition()
{
col = col + 1;
if( col == numCols)
{
col = 0;
row = row + 1;
if( row == numRows)
{
row = 0;
delay(2000); // pause
lcd.clear();
}
lcd.setCursor(col, row);
}
}
// function to display a symbol and its description
void showSymbol( byte symbol, char * description)
{
lcd.clear();
lcd.print(symbol);
lcd.print(' '); // add a space before the description
lcd.print(description);
delay(3000);
}
Discussion
$WDEOHVKRZLQJWKHDYDLODEOHFKDUDFWHUSDWWHUQVLVLQWKHGDWDVKHHWIRUWKH/&'FRQ
WUROOHUFKLS \RXFDQILQGLWRQSDJHRIWKHGDWDVKHHWDWKWWSZZZVSDUNIXQFRP
GDWDVKHHWV/&'+'SGI 7RXVHWKHWDEOHORFDWHWKHV\PERO\RXZDQWWRGLVSOD\7KHFRGHIRUWKDWFKDUDFWHULV
GHWHUPLQHGE\FRPELQLQJWKHELQDU\YDOXHVIRUWKHFROXPQDQGURZIRUWKHGHVLUHG
V\PERO VHH)LJXUH 346 | Chapter 11:ಗUsing Displays
)LJXUH8VLQJGDWDVKHHWWRGHULYHFKDUDFWHUFRGHV
)RUH[DPSOHWKHGHJUHHV\PEROLVWKHWKLUGIURPODVWHQWU\DWWKHERWWRPURZRIWKH
WDEOHVKRZQLQ)LJXUH,WVFROXPQLQGLFDWHVWKHXSSHUIRXUELWVDUHDQGLWV
URZLQGLFDWHVWKHORZHUIRXUELWVDUH&RPELQLQJWKHVHJLYHVWKHFRGHIRUWKLV
V\PERO % <RX FDQ XVH WKLV ELQDU\ YDOXH RU FRQYHUW WKLV WR LWV KH[ YDOXH
[') RUGHFLPDOYDOXH 1RWHWKDW)LJXUHVKRZVRQO\RIWKHDFWXDO
URZVLQWKHGDWDVKHHW
7KH/&'VFUHHQFDQDOVRVKRZDQ\RIWKHGLVSOD\DEOH$6&,,FKDUDFWHUVE\XVLQJWKH
$6&,,YDOXHLQlcd.print
7KHVNHWFKXVHVDIXQFWLRQQDPHGshowSymbolWRSULQWWKHV\PERODQGLWVGHVFULSWLRQ
void showSymbol( byte symbol, char * description)
6HH5HFLSHLI\RXQHHGDUHIUHVKHURQXVLQJFKDUDFWHUVWULQJVDQGSDVVLQJWKHPWR
IXQFWLRQV
See Also
'DWD VKHHW IRU +LWDFKL +' GLVSOD\ KWWSZZZVSDUNIXQFRPGDWDVKHHWV/&'
+'SGI
11.6 Creating Custom Characters
Problem
<RXZDQWWRGHILQHDQGGLVSOD\FKDUDFWHUVRUV\PEROV JO\SKV WKDW\RXKDYHFUHDWHG
7KHV\PEROV\RXZDQWDUHQRWSUHGHILQHGLQWKH/&'FKDUDFWHUPHPRU\
11.6 Creating Custom Characters | 347
Solution
8SORDGLQJWKHIROORZLQJFRGHZLOOFUHDWHDQDQLPDWLRQRIDIDFHVZLWFKLQJEHWZHHQ
VPLOLQJDQGIURZQLQJ
/*
custom_char sketch
creates an animated face using custom characters
*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
byte happy[8] =
{
B00000,
B10001,
B00000,
B00000,
B10001,
B01110,
B00000,
B00000
};
byte saddy[8] =
{
B00000,
B10001,
B00000,
B00000,
B01110,
B10001,
B00000,
B00000
};
void setup() {
lcd.createChar(0, happy);
lcd.createChar(1, saddy);
lcd.begin(16, 2);
}
void loop() {
for (int i=0; i<2; i++)
{
lcd.setCursor(0,0);
lcd.write(i);
delay(500);
}
}
348 | Chapter 11:ಗUsing Displays
Discussion
7KH/LTXLG&U\VWDOOLEUDU\HQDEOHV\RXWRFUHDWHXSWRHLJKWFXVWRPFKDUDFWHUVZKLFK
FDQEHSULQWHGDVFKDUDFWHUFRGHVWKURXJK(DFKFKDUDFWHURQWKHVFUHHQLVGUDZQ
RQDJULGRIÜSL[HOV7RGHILQHDFKDUDFWHU\RXQHHGWRFUHDWHDQDUUD\RIHLJKW
E\WHV(DFKE\WHGHILQHVRQHRIWKHURZVLQWKHFKDUDFWHU:KHQZULWWHQDVDELQDU\
QXPEHUWKHLQGLFDWHVDSL[HOLVRQLVRII DQ\YDOXHVDIWHUWKHILIWKELWDUHLJQRUHG 7KHVNHWFKH[DPSOHFUHDWHVWZRFKDUDFWHUVQDPHGhappyDQGsaddy VHH)LJXUH )LJXUH'HILQLQJFXVWRPFKDUDFWHUV
7KHIROORZLQJOLQHLQsetupFUHDWHVWKHFKDUDFWHUXVLQJGDWDGHILQHGLQWKHhappyDUUD\
WKDWLVDVVLJQHGWRFKDUDFWHU
lcd.createChar(0, happy);
7RSULQWWKHFXVWRPFKDUDFWHUWRWKHVFUHHQ\RXZRXOGXVHWKLVOLQH
lcd.write(0);
1RWH WKH GLIIHUHQFH EHWZHHQ ZULWLQJ D FKDUDFWHU ZLWK RU ZLWKRXW DQ
DSRVWURSKH7KHIROORZLQJZLOOSULQWD]HURQRWWKHKDSS\V\PERO
lcd.write('0'); // this prints a zero
&RGH LQ WKH for ORRS VZLWFKHV EHWZHHQ FKDUDFWHU DQG FKDUDFWHU WR SURGXFH DQ
DQLPDWLRQ
11.7 Displaying Symbols Larger Than a Single Character
Problem
<RXZDQWWRFRPELQHWZRRUPRUHFXVWRPFKDUDFWHUVWRSULQWV\PEROVODUJHUWKDQD
VLQJOHFKDUDFWHUIRUH[DPSOHGRXEOHKHLJKWQXPEHUVRQWKHVFUHHQ
11.7 Displaying Symbols Larger Than a Single Character | 349
Solution
7KHIROORZLQJVNHWFKZULWHVGRXEOHKHLJKWQXPEHUVXVLQJFXVWRPFKDUDFWHUV
/*
* customChars
*
* This sketch displays double-height digits
* the bigDigit arrays were inspired by Arduino forum member dcb
*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
byte glyphs[5][8] = {
{ B11111,B11111,B00000,B00000,B00000,B00000,B00000,B00000
{ B00000,B00000,B00000,B00000,B00000,B00000,B11111,B11111
{ B11111,B11111,B00000,B00000,B00000,B00000,B11111,B11111
{ B11111,B11111,B11111,B11111,B11111,B11111,B11111,B11111
{ B00000,B00000,B00000,B00000,B00000,B01110,B01110,B01110
} ,
} ,
} ,
} ,
} };
const int digitWidth = 3; // the width in characters of a big digit (excludes
space between characters)
//arrays to index into custom characters that will comprise the big numbers
// digits 0 - 4
0
1
2
3
4
const char bigDigitsTop[10][digitWidth]={ 3,0,3, 0,3,32, 2,2,3, 0,2,3, 3,1,3,
// digits 5-9
5
6
7
8
9
3,2,2, 3,2,2, 0,0,3,
3,2,3, 3,2,3};
const char bigDigitsBot[10][ digitWidth]={ 3,1,3, 1,3,1, 3,1,1, 1,1,3, 32,32,3,
1,1,3, 3,1,3, 32,32,3, 3,1,3, 1,1,3};
char buffer[12]; // used to convert a number into a string
void setup ()
{
lcd.begin(20,4);
// create the custom glyphs
for(int i=0; i < 5; i++)
lcd.createChar(i, glyphs[i]);
// create the 5 custom glyphs
// show a countdown timer
for(int digit = 9; digit >= 0; digit--)
{
showDigit(digit, 2); // show the digit
delay(1000);
}
lcd.clear();
}
350 | Chapter 11:ಗUsing Displays
void loop ()
{
// now show the number of seconds since the sketch started
int number = millis() / 1000;
showNumber( number, 0);
delay(1000);
}
void showDigit(int digit, int position)
{
lcd.setCursor(position * (digitWidth + 1), 0);
for(int i=0; i < digitWidth; i++)
lcd.print(bigDigitsTop[digit][i]);
lcd.setCursor(position * (digitWidth + 1), 1);
for(int i=0; i < digitWidth; i++)
lcd.print(bigDigitsBot[digit][i]);
}
void showNumber(int value, int position)
{
int index; // index to the digit being printed, 0 is the leftmost digit
itoa(value, buffer, 10); // see Recipe 2.8 for more on using itoa
// dislay each digit in sequence
for(index = 0; index < 10; index++) // display up to ten digits
{
char c = buffer[index];
if( c == 0) // check for null (not the same as '0')
return; // the end of string character is a null, see Chapter 2
c = c - 48; // convert ascii value to a numeric value (see Recipe 2.9)
showDigit(c, position + index);
}
}
Discussion
7KH/&'GLVSOD\KDVIL[HGVL]HFKDUDFWHUVEXW\RXFDQFUHDWHODUJHUV\PEROVE\FRP
ELQLQJFKDUDFWHUV7KLVUHFLSHFUHDWHVILYHFXVWRPFKDUDFWHUVXVLQJWKHWHFKQLTXHGH
VFULEHGLQ5HFLSH7KHVHV\PEROV VHH)LJXUH FDQEHFRPELQHGWRFUHDWH
GRXEOHVL]HGGLJLWV VHH)LJXUH 7KHVNHWFKGLVSOD\VDFRXQWGRZQIURPWRRQ
WKH/&'XVLQJWKHELJGLJLWV,WWKHQGLVSOD\VWKHQXPEHURIVHFRQGVVLQFHWKHVNHWFK
VWDUWHG
7KH glyphsDUUD\GHILQHVSL[HOVIRUWKHILYHFXVWRPFKDUDFWHUV7KHDUUD\KDVWZRGL
PHQVLRQVJLYHQLQWKHVTXDUHEUDFNHWV
byte glyphs[5][8] = {
[5]LVWKHQXPEHURIJO\SKVDQG[8]LVWKHQXPEHURIURZVLQHDFKJO\SK(DFKHOHPHQW
FRQWDLQVVDQGVWRLQGLFDWHZKHWKHUDSL[HOLVRQRURIILQWKDWURZ,I\RXFRPSDUH
11.7 Displaying Symbols Larger Than a Single Character | 351
)LJXUH&XVWRPFKDUDFWHUVXVHGWRIRUPELJGLJLWV
)LJXUH7HQELJGLJLWVFRPSRVHGRIFXVWRPJO\SKV
WKHYDOXHVLQglyph[0] WKHILUVWJO\SK ZLWK)LJXUH\RXFDQVHHWKDWWKHVFRUUH
VSRQGWRGDUNSL[HOV
{ B11111,B11111,B00000,B00000,B00000,B00000,B00000,B00000
} ,
(DFKELJQXPEHULVEXLOWIURPVL[RIWKHVHJO\SKVWKUHHIRUPLQJWKHXSSHUKDOIRIWKH
ELJGLJLWDQGWKUHHIRUPLQJWKHORZHUKDOI bigDigitsTopDQG bigDigitsBotDUHDUUD\V
GHILQLQJZKLFKFXVWRPJO\SKLVXVHGIRUWKHWRSDQGERWWRPURZVRQWKH/&'VFUHHQ
See Also
6HH&KDSWHUIRULQIRUPDWLRQRQVHJPHQW/('GLVSOD\VLI\RXQHHGUHDOO\ELJQX
PHUDOV1RWHWKDWVHJPHQWGLVSOD\VFDQJLYH\RXGLJLWVL]HVIURPRQHKDOILQFKWRWZR
LQFKHVRUPRUH7KH\FDQXVHPXFKPRUHSRZHUWKDQ/&'GLVSOD\VDQGGRQ¦WSUHVHQW
OHWWHUVDQGV\PEROVYHU\ZHOOEXWWKH\DUHDJRRGFKRLFHLI\RXQHHGVRPHWKLQJELJ
11.8 Displaying Pixels Smaller Than a Single Character
Problem
<RXZDQWWRGLVSOD\LQIRUPDWLRQZLWKILQHUUHVROXWLRQWKDQDQLQGLYLGXDOFKDUDFWHUIRU
H[DPSOHWRGLVSOD\DEDUFKDUW
352 | Chapter 11:ಗUsing Displays
Solution
5HFLSHGHVFULEHVKRZWREXLOGELJV\PEROVFRPSRVHGRIPRUHWKDQRQHFKDUDFWHU
7KLVUHFLSHXVHVFXVWRPFKDUDFWHUVWRGRWKHRSSRVLWHLWFUHDWHVHLJKWVPDOOV\PEROV
HDFKDVLQJOHSL[HOKLJKHUWKDQWKHSUHYLRXVRQH VHH)LJXUH )LJXUH(LJKWFXVWRPFKDUDFWHUVXVHGWRIRUPYHUWLFDOEDUV
7KHVHV\PEROVDUHXVHGWRGUDZEDUFKDUWVDVVKRZQLQWKHVNHWFKWKDWIROORZV
/*
* customCharPixels
*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
//set constants for number of rows and columns to match your LCD
const int numRows = 2;
const int numCols = 16;
// array of bits defining pixels for 8 custom characters
// ones and zeros indicate if a pixel is on or off
byte glyphs[8][8] = {
{B00000,B00000,B00000,B00000,B00000,B00000,B00000,B11111},
{B00000,B00000,B00000,B00000,B00000,B00000,B11111,B11111},
{B00000,B00000,B00000,B00000,B00000,B11111,B11111,B11111},
{B00000,B00000,B00000,B00000,B11111,B11111,B11111,B11111},
{B00000,B00000,B00000,B11111,B11111,B11111,B11111,B11111},
{B00000,B00000,B11111,B11111,B11111,B11111,B11111,B11111},
{B00000,B11111,B11111,B11111,B11111,B11111,B11111,B11111},
{B11111,B11111,B11111,B11111,B11111,B11111,B11111,B11111}};
void setup ()
{
lcd.begin(numCols, numRows);
for(int i=0; i < 8; i++)
lcd.createChar(i, glyphs[i]);
lcd.clear();
}
// 0
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// create the custom glyphs
11.8 Displaying Pixels Smaller Than a Single Character | 353
void loop ()
{
for( byte i=0; i < 8; i++)
lcd.print(i);
// show all eight single height bars
delay(2000);
lcd.clear();
}
Discussion
7KHVNHWFKFUHDWHVHLJKWFKDUDFWHUVHDFKDVLQJOHSL[HOKLJKHUWKDQWKHSUHYLRXVRQH
VHH)LJXUH7KHVHDUHGLVSOD\HGLQVHTXHQFHRQWKHWRSURZRIWKH/&'7KHVH
£EDUFKDUW¤FKDUDFWHUVFDQEHXVHGWRGLVSOD\YDOXHVLQ\RXUVNHWFKWKDWFDQEHPDSSHG
WRDUDQJHIURPWR)RUH[DPSOHWKHIROORZLQJZLOOGLVSOD\DYDOXHUHDGIURPDQDORJ
LQSXW
int value = analogRead(0);
byte glyph = map(value, 0, 1023,0,8);// returns a proportional value
from 0 through 7
lcd.print(glyph);
<RXFDQVWDFNWKHEDUVIRUJUHDWHUUHVROXWLRQ7KHdoubleHeightBarsIXQFWLRQVKRZQLQ
WKHIROORZLQJFRGHGLVSOD\VDYDOXHIURPWRZLWKDUHVROXWLRQRISL[HOVXVLQJ
WZROLQHVRIWKHGLVSOD\
void doubleHeightBars(int value, int column)
{
char upperGlyph;
char lowerGlyph;
if(value < 8)
{
upperGlyph = ' '; // no pixels lit
lowerGlyph = value;
}
else
{
upperGlyph = value - 8;
lowerGlyph = 7; // all pixels lit
}
}
lcd.setCursor(column, 0); // do the upper half
lcd.print(upperGlyph);
lcd.setCursor(column, 1); // now to the lower half
lcd.print(lowerGlyph);
7KHdoubleHeightBarsIXQFWLRQFDQEHXVHGDVIROORZVWRGLVSOD\WKHYDOXHRIDQDQDORJ
LQSXW
for( int i=0; i < 16; i++)
{
354 | Chapter 11:ಗUsing Displays
}
int value = analogRead(0);
value = map(value, 0, 1023,0,16);
doubleHeightBars(value, i); // show a value from 0 to 15
delay(1000); // one second interval between readings
,I\RXZDQWKRUL]RQWDOEDUV\RXFDQGHILQHILYHFKDUDFWHUVHDFKDVLQJOHSL[HOZLGHU
WKDQWKHSUHYLRXVRQHDQGXVHVLPLODUORJLFWRWKHYHUWLFDOEDUVWRFDOFXODWHWKHFKDUDFWHU
WRVKRZ
$PRUHFRPSOH[H[DPSOHRIWKLVWHFKQLTXHFDQEHIRXQGLQDVNHWFKLPSOHPHQWLQJWKH
ZHOONQRZQFRPSXWHUVLPXODWLRQNQRZQDV-RKQ&RQZD\¦V*DPHRI/LIH7KHVNHWFK
FDQEHGRZQORDGHGIURPWKLVERRN¦VZHEVLWH
11.9 Connecting and Using a Graphical LCD Display
Problem
<RXZDQWWRGLVSOD\JUDSKLFVDQGWH[WRQDQ/&'WKDWXVHVWKH.6RUFRPSDWLEOH
/&'GULYHUFKLS
Solution
7KLV6ROXWLRQXVHVWKH$UGXLQR*/&'OLEUDU\WRFRQWUROWKHGLVSOD\<RXFDQGRZQORDG
LWIURPKWWSZZZDUGXLQRFFSOD\JURXQG&RGH*/&'NV VHH&KDSWHULI\RX
QHHGKHOSLQVWDOOLQJOLEUDULHV 7KHUHDUHPDQ\GLIIHUHQWW\SHVRI*/&'FRQWUROOHUVVRFKHFNWKDW\RXUV
LVD.6RUFRPSDWLEOH
7KHSLQFRQQHFWLRQVIRU*/&'GLVSOD\VDUHQRWVWDQGDUGL]HGDQGLWLVLPSRUWDQWWR
FKHFNWKHGDWDVKHHWIRU\RXUSDQHOWRFRQILUPKRZLWVKRXOGEHZLUHG,QFRUUHFWFRQ
QHFWLRQVRIWKHVLJQDOOLQHVDUHWKHPRVWFRPPRQFDXVHRISUREOHPVDQGSDUWLFXODUFDUH
VKRXOGEHWDNHQZLWKWKHSRZHUOHDGVDVZLULQJWKHVHLQFRUUHFWO\FDQGHVWUR\DSDQHO
0RVW*/&'SDQHOVUHTXLUHDQH[WHUQDOYDULDEOHUHVLVWRUWRVHWWKH/&'ZRUNLQJYROWDJH
FRQWUDVW DQGPD\UHTXLUHDIL[HGUHVLVWRUWROLPLWWKHFXUUHQWLQWKHEDFNOLJKW7KH
GDWDVKHHWIRU\RXUSDQHOVKRXOGSURYLGHVSHFLILFLQIRUPDWLRQRQWKHZLULQJDQGFKRLFH
RIFRPSRQHQWVIRUWKLV
11.9 Connecting and Using a Graphical LCD Display | 355
7DEOHLQGLFDWHVWKHGHIDXOWFRQQHFWLRQVIURPD.6SDQHOWRDQ$UGXLQR RU
0HJD <RXZLOOQHHGWRFKHFNWKHGRFXPHQWDWLRQIRU\RXUSDUWLFXODUSDQHOWRILQG
ZKHUH HDFK IXQFWLRQ LV FRQQHFWHG RQ \RXU GLVSOD\ 7KH WDEOH VKRZV WKH WKUHH PRVW
FRPPRQSDQHOOD\RXWVWKHILUVWODEHOHG£3DQHO$¤LQWKHWDEOHLVWKHRQHLOOXVWUDWHG
LQ)LJXUH7KHGRFXPHQWDWLRQZLWKWKH*/&'OLEUDU\GRZQORDGLQFOXGHVFRORU
ZLULQJGLDJUDPVIRUWKHPRUHFRPPRQGLVSOD\V
7DEOH'HIDXOWFRQQHFWLRQVIURPD.6SDQHOWRDQ$UGXLQRRU0HJD
Arduino pins
Mega pins
GLCD function
Panel A
Panel B
Panel C
5V
5V
+5 volts
1
2
13
Gnd
Gnd
Gnd
2
1
14
N/A
N/A
Contrast in
3
3
12
8
22
D0
4
7
1
9
23
D1
5
8
2
10
24
D2
6
9
3
11
25
D3
7
10
4
4
26
D4
8
11
5
5
27
D5
9
12
6
6
28
D6
10
13
7
7
29
D7
11
14
8
14 (analog 0)
33
CSEL1
12
15
15
Chip 1 select
15 (analog 1)
34
CSEL2
13
16
16
Chip 2 select
Reset
14
17
18
Connect to reset
Reset
Comments
Wiper of contrast pot
16 (analog 2)
35
R_W
15
5
10
Read/write
17 (analog 3)
36
D_I
16
4
11
Data/instruction (RS)
18 (analog 4)
37
EN
17
6
9
Enable
N/A
N/A
Contrast out
18
18
17
10K or 20K preset
N/A
N/A
Backlight +5
19
19
19
See data sheet
Gnd
Gnd
Backlight Gnd
20
20
20
See data sheet
7KHQXPEHUVXQGHUWKH$UGXLQRDQG0HJDFROXPQVDUHWKH$UGXLQR RU0HJD SLQV
XVHGLQWKHFRQILJXUDWLRQILOHSURYLGHGLQWKHOLEUDU\,WLVSRVVLEOHWRXVHRWKHUSLQVLI
WKHVH SLQV FRQIOLFW ZLWK VRPHWKLQJ HOVH \RX ZDQW WR FRQQHFW ,I \RX GR FKDQJH WKH
FRQQHFWLRQV\RXZLOODOVRQHHGWRFKDQJHWKHSLQDVVLJQPHQWVLQWKHFRQILJXUDWLRQILOH
DQGVKRXOGVWXG\WKHOLEUDU\GRFXPHQWDWLRQWROHDUQKRZWRHGLWWKHFRQILJXUDWLRQILOH
356 | Chapter 11:ಗUsing Displays
Download from Wow! eBook <www.wowebook.com>
)LJXUH*/&'ZLULQJIRUW\SH£$¤SDQHOVFKHFN\RXUGDWDVKHHWIRUSLQRXW
:LULQJWKHSDQHOXVLQJWKHGHIDXOWFRQILJXUDWLRQDQGUXQQLQJWKHVNHWFK
LQWKLVUHFLSHHQDEOHV\RXWRWHVWWKDWHYHU\WKLQJLVZRUNLQJEHIRUH\RX
PRGLI\WKHFRQILJXUDWLRQ$FRQILJXUDWLRQWKDWGRHVQRWPDWFKWKHZLU
LQJLVWKHPRVWFRPPRQVRXUFHRISUREOHPVVRWHVWLQJZLWKPLQLPDO
FKDQJHVPDNHVLWPRUHOLNHO\WKDWWKLQJVZLOOZRUNWKHILUVWWLPH
7KHIROORZLQJVNHWFKSULQWVVRPHWH[WDQGWKHQGUDZVVRPHJUDSKLFDOREMHFWV
/*
glcd
*/
#include <glcd.h>
#include "fonts/allFonts.h"
available to your sketch
// this makes all the distributed fonts
int count = 0;
void setup()
{
GLCD.Init(NON_INVERTED);
GLCD.ClearScreen();
GLCD.SelectFont(System5x7);
GLCD.print("hello world");
delay(3000);
}
// initialize the library
// select fixed width system font
// print a message
11.9 Connecting and Using a Graphical LCD Display | 357
void loop()
{
}
GLCD.ClearScreen();
GLCD.DrawRect(0, 0, 64, 61, BLACK); // rectangle in left side of screen
// rounded rectangle around text area
GLCD.DrawRoundRect(68, 0, 58, 61, 5, BLACK);
for(int i=0; i < 62; i += 4)
{
// draw lines from upper left down right side of rectangle
GLCD.DrawLine(1,1,63,i, BLACK);
}
GLCD.DrawCircle(32,31,30,BLACK);
// circle centered on left side of screen
GLCD.FillRect(92,40,16,16, WHITE); // clear previous spinner position
GLCD.CursorTo(5,5);
// locate cursor for printing text
GLCD.PrintNumber(count);
// print a number at current cursor position
count = count + 1;
delay(1000);
Discussion
7KHOLEUDU\SURYLGHVDZLGHUDQJHRIEDVLFKLJKOHYHOJUDSKLFDOGUDZLQJIXQFWLRQVVRPH
RIZKLFKDUHGHPRQVWUDWHGLQWKLVVNHWFK$OOWKHIXQFWLRQVDUHGHVFULEHGLQWKHGRFX
PHQWDWLRQSURYLGHGZLWKWKHOLEUDU\
*UDSKLFDQGWH[WVFUHHQFRRUGLQDWHVVWDUWDWLQWKHWRSOHIWKDQGFRUQHU0RVWSRS
XODU*/&'SDQHOVDUHÜSL[HOVDQGWKHOLEUDU\XVHVWKLVUHVROXWLRQE\GHIDXOW
,I\RXUVFUHHQLVDGLIIHUHQWUHVROXWLRQ\RXZLOOQHHGWRHGLWWKHFRQILJXUDWLRQILOHLQWKH
OLEUDU\WRPDWFK\RXUSDQHO XSWRÜSL[HOSDQHOVDUHFXUUHQWO\VXSSRUWHG */&'HQDEOHVSULQWLQJWH[WWRWKHVFUHHQXVLQJVWDWHPHQWVVLPLODUWR$UGXLQRSULQW
FRPPDQGVXVHGIRUSULQWLQJWRWKHVHULDOSRUW,QDGGLWLRQ\RXFDQVSHFLI\WKHW\SHDQG
VL]HRIIRQW<RXFDQDOVRVSHFLI\DQDUHDRIWKHVFUHHQWKDWFDQEHXVHGDVDWH[WZLQGRZ
7KLVHQDEOHV\RXWRGHILQHDQDUHDRQWKHVFUHHQDQGWKHQVHQGWH[WWRWKDWDUHDSUR
YLGLQJ\RXZLWKD£YLUWXDOWHUPLQDO¤WKDWZLOOFRQWDLQDQGVFUROOWH[WZLWKLQWKHERXQGV
\RXGHILQH)RULQVWDQFHWKHIROORZLQJFRGHFUHDWHVDQDUHDSL[HOVVTXDUHLQWKH
FHQWHURIWKHVFUHHQ
gText myTextArea = gText(GLCD.CenterX-16, GLCD.CenterY -16, GLCD.CenterX +16,
GLCD.CenterY+16);
<RXFDQVHOHFWDIRQWDQGSULQWWRWKHWH[WDUHDXVLQJFRGHVXFKDVWKHIROORZLQJ
myTextArea.SelectFont(System5x7); // select the system font for the text area
name textTop
myTextArea.println("Go");
// print a line of text to the text area.
7KHH[DPSOHVNHWFKVXSSOLHGZLWKWKHOLEUDU\GRZQORDGKDVDGHPRWKDWVKRZVKRZ
PXOWLSOHWH[WDUHDVFDQEHXVHGDORQJZLWKJUDSKLFDOGUDZLQJV
358 | Chapter 11:ಗUsing Displays
7KHVHJUDSKLFDOGLVSOD\VKDYHPDQ\PRUHFRQQHFWLRQVWKDQWKHWH[W/&'GLVSOD\VDQG
FDUHVKRXOGEHWDNHQWRHQVXUHWKDW\RXUSDQHOLVFRQQHFWHGFRUUHFWO\
,IWKHUHDUHQRSL[HOVYLVLEOHRQWKHGLVSOD\RUWKHSL[HOVDUHJDUEOHGGRWKHIROORZLQJ
&KHFN9DQG*QGFRQQHFWLRQVEHWZHHQ$UGXLQRDQGWKH*/&'SDQHO
&KHFNWKDWDOOGDWDDQGFRPPDQGSLQVDUHZLUHGDFFRUGLQJWRWKHGDWDVKHHWDQG
PDWFKWKHFRQILJXUDWLRQVHWWLQJV7KLVLVWKHPRVWFRPPRQFXUHIRUWKLVSUREOHP
&KHFNWKHGDWDVKHHWIRU\RXUSDQHOWRYHULI\WKDWDSSURSULDWHWLPLQJYDOXHVDUHVHW
LQWKHFRQILJXUDWLRQILOH
&KHFNWKHFRQWUDVWYROWDJH W\SLFDOO\EHWZHHQDQGYROWV RQWKHFRQWUDVWLQ
SLQRIWKH/&'SDQHO:KLOHWKHVNHWFKLVRSHUDWLQJWU\JUDGXDOO\DGMXVWLQJWKH
SRWWKURXJKLWVUDQJH6RPHGLVSOD\VDUHYHU\VHQVLWLYHWRWKLVVHWWLQJ
&KHFNWKDWWKHVNHWFKKDVFRPSLOHGFRUUHFWO\DQGKDVGRZQORDGHGWR$UGXLQR
5XQ WKH */&'GLDJV WHVW VNHWFK 7KH WHVW VNHWFK LV DYDLODEOH IURP WKH PHQX
([DPSOHVൺ*/&'ൺ*/&'GLDJV
,IWKHOHIWDQGULJKWVLGHVRIWKHLPDJHDUHUHYHUVHGVZDSWKH&6(/DQG&6(/ZLUHV
\RXFDQDOVRVZDSSLQDVVLJQPHQWVLQWKHFRQILJXUDWLRQILOH 11.10 Creating Bitmaps for Use with a Graphical Display
Problem
<RXZDQWWRFUHDWHDQGXVH\RXURZQJUDSKLFDOLPDJHV ELWPDSV ZLWKWKH*/&'GLV
SOD\GLVFXVVHGLQ5HFLSH<RXZDQWWKHIRQWGHILQLWLRQDQGWH[WVWRUHGLQSURJUDP
PHPRU\WRPLQLPL]H5$0XVDJH
Solution
<RXFDQXVHELWPDSVGLVWULEXWHGZLWKWKHOLEUDU\RUFUHDWH\RXURZQ%LWPDSVDUHGH
ILQHG LQ KHDGHU ILOHV ZLWK DQ H[WHQVLRQ RI K IRU H[DPSOH DQ $UGXLQR LFRQ LPDJH
QDPHG$UGXLQL,FRQKLVVWRUHGLQWKHELWPDSIROGHURIWKH*/&'OLEUDU\GLUHFWRU\7KLV
IROGHU DOVR FRQWDLQV D ILOH QDPHG DOO%LWPDSVK WKDW KDV GHWDLOV RI DOO WKH GLVWULEXWHG
ELWPDSVVR\RXFDQLQFOXGHWKLVWRPDNHDOOWKHVXSSOLHG RUQHZO\FUHDWHG ELWPDSV
DYDLODEOH
#include "bitmaps/allBitmaps.h"
// this line includes all distributed bitmaps
1RWHWKDWLQFOXGLQJDOOWKHELWPDSVZLOOQRWFRQVXPHDQ\PHPRU\LIWKH\DUHQRWH[
SOLFLWO\UHIHUHQFHGLQ\RXUVNHWFKZLWKWKHDrawBitmapIXQFWLRQ
7RHQDEOH\RXWRDGG\RXURZQELWPDSVWKH*/&'OLEUDU\LQFOXGHVDXWLOLW\FDOOHG
JOFG0DNH%LWPDSZKLFKFRQYHUWVDJLIMSJEPSWJDRUSQJILOHWRDKHDGHUILOHWKDW
FDQEHXVHGE\WKH*/&'OLEUDU\7KHILOHJOFG0DNH%LWPDSSGHLVD3URFHVVLQJVNHWFK
WKDWFDQEHUXQXVLQJWKH3URFHVVLQJHQYLURQPHQW7KHVNHWFKLVORFDWHGLQWKHELWPDSV
11.10 Creating Bitmaps for Use with a Graphical Display | 359
XWLOVJOFG0DNH%LWPDSGLUHFWRU\)RUPRUHLQIRUPDWLRQRQ3URFHVVLQJVHHKWWSSURFHVV
LQJRUJ
7KHUHLVDOVRDMDYD -DYD UXQWLPHILOH JOFG0DNH%LWPDSMDU DQGDMDYD -DYD VRXUFH
JOFG0DNH%LWPDSMDYD LQWKHELWPDSVXWLOV-DYDGLUHFWRU\
5XQWKHXWLOLW\E\ORDGLQJWKHVNHWFKLQWR3URFHVVLQJ RUFOLFNRQWKHMDUILOH DQGGUDJ
DQGGURSWKHLPDJHILOHWREHFRQYHUWHGLQWRWKHZLQGRZ7KHXWLOLW\ZLOOFUHDWHDKHDGHU
ILOHZLWKWKHVDPHQDPHDVWKHLPDJHILOHGURSSHGLQWRWKHZLQGRZ7KHILOHLVVDYHGLQ
WKHELWPDSVGLUHFWRU\DQGDQHQWU\LVDXWRPDWLFDOO\DGGHGWRWKHDOO%LW0DSVKILOHVR
WKDWWKHQHZLPDJHFDQEHXVHGLQ\RXUVNHWFK
7R GHPRQVWUDWH WKLV UHQDPH DQ LPDJH RQ \RXU FRPSXWHU DV PHMSJ 7KHQ UXQ
JOFG0DNH%LWPDSDQGGURSWKHLPDJHLQWRWKHZLQGRZWKDWDSSHDUV
&RPSLOHDQGXSORDGWKHIROORZLQJVNHWFKWRVKRZWKHVXSSOLHG$UGXLQRLFRQIROORZHG
E\WKHLPDJH\RXFUHDWHG
/*
* GLCDImage
* Display an image defined in me.h
*/
#include <glcd.h>
#include "bitmaps/allBitmaps.h"
// all images in the bitmap folder
void setup()
{
GLCD.Init();
// initialize the library
GLCD.ClearScreen();
GLCD.DrawBitmap(ArduinoIcon, 0,0); //draw the supplied bitmap
delay(5000);
GLCD.ClearScreen();
GLCD.DrawBitmap(me, 0,0); //draw your bitmap
}
void
{
loop()
}
7KHIROORZLQJOLQHGUDZVWKHLPDJHGHILQHGLQWKHILOH$UGXLQR,FRQKWKDWLVVXSSOLHG
ZLWKWKHOLEUDU\
GLCD.DrawBitmap(ArduinoIcon, 0,0); //draw the supplied bitmap
$IWHUDGHOD\WKHIROORZLQJOLQHGUDZVWKHLPDJH\RXFUHDWHGWKDWLVVWRUHGLQWKHILOH
PHK
GLCD.DrawBitmap(me, 0,0);
360 | Chapter 11:ಗUsing Displays
See Also
6HHWKHGRFXPHQWDWLRQVXSSOLHGZLWKWKHOLEUDU\IRUPRUHRQFUHDWLQJDQGXVLQJJUDSK
LFDOLPDJHV
7KHGRFXPHQWDWLRQDOVRGHVFULEHVKRZ\RXFDQFUHDWH\RXURZQIRQWV
11.11 Displaying Text on a TV
Problem
<RXZDQWWRGLVSOD\WH[WRQDWHOHYLVLRQRUPRQLWRUZLWKDYLGHRLQSXW
Solution
7KLVUHFLSHXVHVDVKLHOGFDOOHG7HOO\0DWHWRSULQWWH[WRUEORFNJUDSKLFVWRDWHOHYLVLRQ
7KHVKLHOGSOXJVLQWR$UGXLQRDQGKDVDQRXWSXWMDFNWKDWFRQQHFWVWRWKHYLGHRLQSXW
RIDWHOHYLVLRQ
7KHVNHWFKSULQWVDOOWKHFKDUDFWHUVWKH7HOO\0DWHFDQGLVSOD\RQD79VFUHHQ
/*
TellyMate
Simple demo for TellMmate Shield
*/
const byte ESC = 0x1B;
// ASCII escape character used in TellyMate commands
void setup()
{
Serial.begin(57600); //57k6 baud is default TellyMate speed
clear(); // clear the screen
Serial.print("
TellyMate Character Set"); // write some text
delay(2000);
}
void loop()
{
byte charCode = 32;
// characters 0 through 31 are control codes
for(int row=0; row < 7; row++) // show 7 rows
{
setCursor(2, row + 8); // center the display
for(int col= 0; col < 32; col++) // 32 characters per row
{
Serial.print(charCode);
charCode = charCode + 1;
delay(20);
}
}
delay(5000);
clear();
11.11 Displaying Text on a TV | 361
}
// TellyMate helper functions
void clear( ) // clear the screen
{ // <ESC>E
Serial.print(ESC);
Serial.print('E');
}
void setCursor( int col, int row) // set the cursor
{ // <ESC>Yrc
Serial.print(ESC);
Serial.print('Y' ) ;
Serial.print((unsigned char)(32 + row)) ;
Serial.print((unsigned char)(32 + col)) ;
}
Discussion
$UGXLQRFRQWUROVWKH7HOO\0DWHGLVSOD\E\VHQGLQJFRPPDQGVWRWKHVHULDOSRUW
7HOO\0DWHFRPPXQLFDWHVZLWKWKH$UGXLQRWKURXJKWKHVHULDOSRUWVR
\RXPD\QHHGWRXQSOXJWKHVKLHOGWRXSORDGVNHWFKHV
)LJXUHVKRZVWKHFKDUDFWHUVWKDWFDQEHGLVSOD\HG<RXFDQILQGDWDEOHRIYDOXHV
IRUHDFKFKDUDFWHUDWKWWSHQZLNLSHGLDRUJZLNL&RGHBSDJHB
)LJXUH7HOO\0DWHFKDUDFWHUVHW FRGHSDJH
&KDUDFWHUVWKURXJKDUHLQWHUSUHWHGDVVFUHHQFRQWUROFRPPDQGV
VRRQO\FKDUDFWHUVWRFDQEHGLVSOD\HG
362 | Chapter 11:ಗUsing Displays
7KHVNHWFKXVHVQRQSULQWDEOHFRGHVFDOOHGHVFDSHFRGHVWRGLIIHUHQWLDWHSULQWDEOHFKDU
DFWHUVIURPFRPPDQGVWRFRQWUROWKHVFUHHQ&RQWUROFRGHVFRQVLVWRIWKH(6& VKRUW
IRUHVFDSH FKDUDFWHU KH[YDOXH[E IROORZHGE\RQHRUPRUHFKDUDFWHUVLQGLFDWLQJ
WKHQDWXUHRIWKHFRQWUROIXQFWLRQ'HWDLOVRIDOOWKHFRQWUROFRGHVDUHFRYHUHGLQWKH
7HOO\0DWHGRFXPHQWDWLRQ
7KHVNHWFKKDVDQXPEHURIKHOSHUIXQFWLRQVWKDWVHQGWKHDSSURSULDWHVHTXHQFHRI
FKDUDFWHUVWRDFKLHYHWKHGHVLUHGUHVXOWVHQDEOLQJ\RXWRFRQFHQWUDWHRQWKHKLJKHUOHYHO
DFWLYLW\RIWKHVNHWFK¢ZKDW\RXZDQWLWWRGRUDWKHUWKDQWKHGHWDLOVRIKRZLWZLOO
GRLW
7KH VFUHHQ ZLOO VKRZ D IODVKLQJ FXUVRU \RX FDQ WXUQ WKLV RII XVLQJ D FRQWURO FRGH
$GGLQJWKHcursorHideIXQFWLRQZLOOWXUQRIIWKHFXUVRUZKHQWKHIXQFWLRQLVFDOOHG
void cursorHide()
{ // <ESC>f
Serial.print(ESC) ;
Serial.print('f' ) ;
}
// the escape character
// ... followed by the letter f will turn off the cursor.
7RDGGDER[DURXQGWKHHGJHRIWKHVFUHHQDGGWKHdrawBoxDQGshowXYIXQFWLRQVDW
WKHERWWRPRIWKHSUHYLRXVVNHWFK7RJHWWKHVNHWFKWRXVHWKHPDGGWKLVOLQHMXVW
LQVLGHWKHRSHQLQJEUDFNHWRIWKHORRS
drawBox(1,0, 38, 24);
// the screen is 38 characters wide and 25 high
7KH drawBoxIXQFWLRQSULQWVFKDUDFWHUVIRUWKHIRXUFRUQHUVDQGWKHWRSERWWRPDQG
VLGHHGJHVXVLQJWKHOLQHGUDZLQJFKDUDFWHUFRGHV
// characters that form the box outline
// see http://en.wikipedia.org/wiki/Code_page_437
const byte boxUL = 201;
const byte boxUR = 187;
const byte boxLL = 200;
const byte boxLR = 188;
const byte HLINE = 205; // horizontal line
const byte VLINE = 186; // vertical line
void drawBox( int startRow, int startCol, int width, int height)
{
//draw top line
showXY(boxUL, startCol,startRow); // the upper-left corner
for(int col = startCol + 1; col < startCol + width-1; col++)
Serial.print(HLINE); // the line characters
Serial.print(boxUR); // upper-right character
// draw left and right edges
for(int row = startRow + 1; row < startRow + height -1; row++)
{
showXY(VLINE, startCol,row); // left edge
showXY(VLINE, startCol + width-1,row); // right edge
}
11.11 Displaying Text on a TV | 363
// draw bottom line
showXY(boxLL, 0, startRow+height-1); // the lower-left corner character
for(int col = startCol + 1; col < startCol + width-1; col++)
Serial.print(HLINE);
Serial.print(boxLR);
}
$FRQYHQLHQFHIXQFWLRQXVHGE\drawBoxQDPHGshowXYFRPELQHVFXUVRUSRVLWLRQLQJ
DQGSULQWLQJ
void showXY( char ch, int x, int y){
// display the given character at the screen x and y location
setCursor(x,y);
Serial.print(ch);
}
+HUHLVDQDGGLWLRQDOVNHWFKWKDWXVHVWKHFXUVRUFRQWUROFRPPDQGVWRDQLPDWHDEDOO
ERXQFLQJDURXQGWKHVFUHHQ
/*
TellyBounce
*/
// define the edges of the screen:
const int HEIGHT = 25;
// the number of text rows
const int WIDTH = 38;
// the number of characters in a row
const int LEFT
= 0;
// useful constants derived from the above
const int RIGHT = WIDTH -1;
const int TOP
= 0;
const int BOTTOM = HEIGHT-1;
const byte BALL = 'o';
const byte ESC = 0x1B;
// character code for ball
// ASCII escape character used in TellyMate commands
int ballX = WIDTH/2;
int ballY = HEIGHT/2;
int ballDirectionY = 1;
int ballDirectionX = 1;
// X position of the ball
// Y position of the ball
// X direction of the ball
// Y direction of the ball
// this delay moves ball across the 38-character screen in just under 4 seconds
long interval = 100;
void setup()
{
Serial.begin(57600);
clear();
cursorHide();
}
void loop()
{
moveBall();
delay(interval);
}
364 | Chapter 11:ಗUsing Displays
// 57k6 baud is default TellyMate speed
// clear the screen
// turn cursor off
Download from Wow! eBook <www.wowebook.com>
void moveBall() {
// if the ball goes off the top or bottom, reverse its Y direction
if (ballY == BOTTOM || ballY == TOP)
ballDirectionY = -ballDirectionY;
// if the ball goes off the left or right, reverse its X direction
if ((ballX == LEFT) || (ballX == RIGHT))
ballDirectionX = -ballDirectionX;
// clear the ball's previous position
showXY(' ', ballX, ballY);
// increment the ball's position in both directions
ballX = ballX + ballDirectionX;
ballY = ballY + ballDirectionY;
}
// show the new position
showXY(BALL, ballX, ballY);
// TellyMate helper functions
void clear( ) // clear the screen
{ // <ESC>E
Serial.print(ESC);
Serial.print('E');
}
void setCursor( int col, int row) // set the cursor
{ // <ESC>Yrc
Serial.print(ESC);
Serial.print('Y' ) ;
Serial.print((unsigned char)(32 + row)) ;
Serial.print((unsigned char)(32 + col)) ;
}
void cursorShow( )
{ // <ESC>e
Serial.print(ESC) ;
Serial.print('e') ;
}
void cursorHide()
{ // <ESC>f
Serial.print(ESC) ;
Serial.print('f' ) ;
}
void showXY( char ch, int x, int y){
// display the given character at the screen x and y location
setCursor(x,y);
Serial.print(ch);
}
11.11 Displaying Text on a TV | 365
See Also
'HWDLOHGLQIRUPDWLRQRQWKH7HOO\0DWHVKLHOGLVDYDLODEOHDWKWWSZZZEDWVRFNVFRXN
SURGXFWV6KLHOGVLQGH[B6KLHOGVKWP
0XFKPRUHLQIRUPDWLRQRQFRGHSDJHLQFOXGLQJDWDEOHRIFKDUDFWHUVLVDYDLODEOH
DWKWWSHQZLNLSHGLDRUJZLNL&RGHBSDJHB
366 | Chapter 11:ಗUsing Displays
CHAPTER 12
Using Time and Dates
12.0 Introduction
0DQDJLQJWLPHLVDIXQGDPHQWDOHOHPHQWRILQWHUDFWLYHFRPSXWLQJ7KLVFKDSWHUFRYHUV
EXLOWLQ$UGXLQRIXQFWLRQVDQGLQWURGXFHVPDQ\DGGLWLRQDOWHFKQLTXHVIRUKDQGOLQJ
WLPHGHOD\VWLPHPHDVXUHPHQWDQGUHDOZRUOGWLPHVDQGGDWHV
12.1 Creating Delays
Problem
<RXZDQW\RXUVNHWFKWRSDXVHIRUVRPHSHULRGRIWLPH7KLVPD\EHVRPHQXPEHURI
PLOOLVHFRQGVRUDWLPHJLYHQLQVHFRQGVPLQXWHVKRXUVRUGD\V
Solution
7KH $UGXLQR delay IXQFWLRQ LV XVHG LQ PDQ\ VNHWFKHV WKURXJKRXW WKLV ERRN delay
SDXVHVDVNHWFKIRUWKHQXPEHURIPLOOLVHFRQGVVSHFLILHGDVDSDUDPHWHU 7KHUHDUH
PLOOLVHFRQGVLQRQHVHFRQG 7KHVNHWFKWKDWIROORZVVKRZVKRZ\RXFDQXVH
delayWRJHWDOPRVWDQ\LQWHUYDO
/*
* delay sketch
*/
const long oneSecond = 1000; // a second is a thousand milliseconds
const long oneMinute = oneSecond * 60;
const long oneHour
= oneMinute * 60;
const long oneDay
= oneHour * 24;
void setup()
{
Serial.begin(9600);
}
367
void loop()
{
Serial.println("delay for 1 millisecond");
delay(1);
Serial.println("delay for 1 second");
delay(oneSecond);
Serial.println("delay for 1 minute");
delay(oneMinute);
Serial.println("delay for 1 hour");
delay(oneHour);
Serial.println("delay for 1 day");
delay(oneDay);
Serial.println("Ready to start over");
}
Discussion
7KHdelayIXQFWLRQKDVDUDQJHIURPRQHRQHWKRXVDQGWKRIDVHFRQGWRDURXQGGD\V
MXVWOHVVWKDQGD\VLIXVLQJDQXQVLJQHGORQJYDULDEOHW\SHVHH&KDSWHUIRUPRUH
RQYDULDEOHW\SHV 7KHdelayIXQFWLRQSDXVHVWKHH[HFXWLRQRI\RXUVNHWFKIRUWKHGXUDWLRQRIWKHGHOD\
,I\RXQHHGWRSHUIRUPRWKHUWDVNVZLWKLQWKHGHOD\SHULRGXVLQJmillisDVH[SODLQHG
LQ5HFLSHLVPRUHVXLWDEOH
<RXFDQXVHdelayMicrosecondsWRGHOD\VKRUWSHULRGV7KHUHDUHPLFURVHFRQGV
LQRQHPLOOLVHFRQGDQGPLOOLRQPLFURVHFRQGVLQRQHVHFRQGdelayMicrosecondsZLOO
SDXVHIURPRQHPLFURVHFRQGWRDURXQGPLOOLVHFRQGVEXWIRUGHOD\VORQJHUWKDQD
IHZWKRXVDQGPLFURVHFRQGV\RXVKRXOGXVHdelayLQVWHDG
delayMicroseconds(10);
// delay for 10 microseconds
delayDQG delayMicrosecondsZLOOGHOD\IRUDWOHDVWWKHDPRXQWRIWLPH
JLYHQDVWKHSDUDPHWHUEXWWKH\FRXOGGHOD\DOLWWOHORQJHULILQWHUUXSWV
RFFXUZLWKLQWKHGHOD\WLPH
See Also
7KH$UGXLQRUHIHUHQFHIRUdelayKWWSZZZDUGXLQRFFHQ5HIHUHQFH'HOD\
12.2 Using millis to Determine Duration
Problem
<RXZDQWWRNQRZKRZPXFKWLPHKDVHODSVHGVLQFHDQHYHQWKDSSHQHGIRUH[DPSOH
KRZORQJDVZLWFKKDVEHHQKHOGGRZQ
368 | Chapter 12:ಗUsing Time and Dates
Solution
$UGXLQRKDVDIXQFWLRQQDPHG millis VKRUWIRUPLOOLVHFRQGV WKDWLVXVHGLQWKHIRO
ORZLQJVNHWFKWRSULQWKRZORQJDEXWWRQZDVSUHVVHG VHH5HFLSHIRUGHWDLOVRQ
KRZWRFRQQHFWWKHVZLWFK /*
millisDuration sketch
returns the number of milliseconds that a button has been pressed
*/
const int switchPin = 2;
// the number of the input pin
long startTime; // the value returned from millis when the switch is pressed
long duration; // variable to store the duration
void setup()
{
pinMode(switchPin, INPUT);
digitalWrite(switchPin, HIGH); // turn on pull-up resistor
Serial.begin(9600);
}
void loop()
{
if(digitalRead(switchPin) == LOW)
{
// here if the switch is pressed
startTime = millis();
while(digitalRead(switchPin) == LOW)
; // wait while the switch is still pressed
long duration = millis() - startTime;
Serial.println(duration);
}
}
Discussion
7KHmillisIXQFWLRQUHWXUQVWKHQXPEHURIPLOOLVHFRQGVVLQFHWKHFXUUHQWVNHWFKVWDUWHG
UXQQLQJ7KLVQXPEHUZLOORYHUIORZ JREDFNWR]HUR LQDSSUR[LPDWHO\GD\V
%\VWRULQJWKHVWDUWWLPHIRUDQHYHQW\RXFDQGHWHUPLQHWKHGXUDWLRQRIWKHHYHQWE\
VXEWUDFWLQJWKHVWDUWWLPHIURPWKHFXUUHQWWLPHDVVKRZQKHUH
long duration = millis() - startTime;
<RXFDQFUHDWH\RXURZQGHOD\IXQFWLRQXVLQJ millisWKDWFDQFRQWLQXHWRGRRWKHU
WKLQJVZKLOHFKHFNLQJUHSHDWHGO\WRVHHLIWKHGHOD\SHULRGKDVSDVVHG2QHH[DPSOHRI
WKLVFDQEHIRXQGLQWKH%OLQN:LWKRXW'HOD\VNHWFKSURYLGHGZLWKWKH$UGXLQRGLVWUL
EXWLRQ+HUHLVWKHORRSFRGHLQWKDWVNHWFK
12.2 Using millis to Determine Duration | 369
void loop()
{
// here is where you'd put code that needs to be running all the time...
7KHQH[WOLQHFKHFNVWRVHHLIWKHGHVLUHGLQWHUYDOKDVSDVVHG
if (millis() - previousMillis > interval)
{
// save the last time you blinked the LED
,I WKH LQWHUYDO KDV SDVVHG WKH FXUUHQW millis YDOXH LV VDYHG LQ WKH YDULDEOH
previousMillis
previousMillis = millis();
// if the LED is off turn it on and vice versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
+HUHLVDZD\WRSDFNDJHWKLVORJLFLQWRDIXQFWLRQQDPHG myDelayWKDWZLOOGHOD\WKH
FRGHLQloopEXWFDQSHUIRUPVRPHDFWLRQGXULQJWKHGHOD\SHULRG<RXFDQFXVWRPL]H
WKHIXQFWLRQDOLW\IRU\RXUDSSOLFDWLRQEXWLQWKLVH[DPSOHDQ/('LVIODVKHGILYHWLPHV
SHUVHFRQGHYHQZKLOHWKHSULQWVWDWHPHQWLQloopLVGHOD\HGIRUIRXUVHFRQGLQWHUYDOV
// blink an LED for a set amount of time
const int ledPin = 13;
// the number of the LED pin
int ledState = LOW;
long previousMillis = 0;
// ledState used to set the LED
// will store last time LED was updated
void setup()
{
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop()
{
Serial.println(millis() / 1000); // print the number of elapsed seconds every
four seconds
// wait four seconds (but at the same time, quickly blink an LED)
myDelay(4000);
}
// duration is delay time in milliseconds
void myDelay(unsigned long duration)
{
unsigned long start = millis();
370 | Chapter 12:ಗUsing Time and Dates
}
while (millis() - start <= duration)
{
blink(100); // blink the LED inside the while loop
}
// interval is the time that the LED is on and off
void blink(long interval)
{
if (millis() - previousMillis > interval)
{
// save the last time you blinked the LED
previousMillis = millis();
// if the LED is off turn it on and vice versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
digitalWrite(ledPin, ledState);
}
}
<RXFDQSXWFRGHLQWKH myDelayIXQFWLRQIRUDQDFWLRQWKDW\RXZDQWWRKDSSHQUH
SHDWHGO\ZKLOHWKHIXQFWLRQZDLWVIRUWKHVSHFLILHGWLPHWRHODSVH
$QRWKHUDSSURDFKLVWRXVHDWKLUGSDUW\OLEUDU\DYDLODEOHIURPWKH$UGXLQR3OD\JURXQG
FDOOHG7LPHG$FWLRQ KWWSZZZDUGXLQRFFSOD\JURXQG&RGH7LPHG$FWLRQ #include <TimedAction.h>
//this initializes a TimedAction class that will change the state of an LED
every second.
TimedAction timedAction = TimedAction(NO_PREDELAY,1000,blink);
const int ledPin = 13;
boolean ledState = false;
// the number of the LED pin
void setup()
{
pinMode(ledPin,OUTPUT);
digitalWrite(ledPin,ledState);
}
void loop()
{
timedAction.check();
}
void blink()
{
if (ledState == LOW)
ledState = HIGH;
else
12.2 Using millis to Determine Duration | 371
ledState = LOW;
}
ledState ? ledState=false : ledState=true;
digitalWrite(ledPin,ledState);
See Also
7KH$UGXLQRUHIHUHQFHIRUmillisKWWSZZZDUGXLQRFFHQ5HIHUHQFH0LOOLV
12.3 More Precisely Measuring the Duration of a Pulse
Problem
<RXZDQWWRGHWHUPLQHWKHGXUDWLRQRIDSXOVHZLWKPLFURVHFRQGDFFXUDF\IRUH[DPSOH
WRPHDVXUHWKHH[DFWWLPHEHWZHHQWZREXWWRQSUHVVHV
Solution
7KHpulseInIXQFWLRQUHWXUQVWKHGXUDWLRQLQPLFURVHFRQGVIRUDFKDQJLQJVLJQDORQD
GLJLWDOSLQ7KLVVNHWFKSULQWVWKHWLPHWKDWWKHYROWDJHRQDGLJLWDOSLQLVKHOGLOWE\D
EXWWRQSUHVV$VLQ5HFLSHWKLVXVHVWKHZLULQJVKRZQLQ5HFLSH
/*
PulseIn sketch
uses pulseIn to display how long a switch is pressed and released
*/
const int inputPin = 2;
// input pin for the switch
long val;
void setup()
{
pinMode(inputPin, INPUT);
digitalWrite(inputPin,HIGH); // turn on internal pull-up on the inputPin
Serial.begin(9600);
Serial.println("Press and release switch");
}
void loop()
{
val = pulseIn(inputPin, LOW);
if( val != 0) // timeout returns 0
{
Serial.print("switch pressed for ");
Serial.print(val);
Serial.println(" microseconds");
}
}
372 | Chapter 12:ಗUsing Time and Dates
Discussion
pulseInFDQPHDVXUHKRZORQJDSXOVHLVHLWKHUHIGHRULOW
pulseIn(pin, HIGH); // returns microseconds that pulse is HIGH
pulseIn(pin, LOW)
// returns microseconds that pulse is LOW
7KHpulseInIXQFWLRQZDLWVIRUWKHSXOVHWRVWDUW RUIRUDWLPHRXWLIWKHUHLVQRSXOVH %\GHIDXOWLWZLOOVWRSZDLWLQJDIWHURQHVHFRQGEXW\RXFDQFKDQJHWKDWE\VSHFLI\LQJ
WKHWLPHWRZDLWLQPLFURVHFRQGVDVDWKLUGSDUDPHWHU QRWHWKDWPLFURVHFRQGV
HTXDOVPLOOLVHFRQG pulseIn(pin, HIGH, 5000); // wait 5 milliseconds for the pulse to start
7KHWLPHRXWYDOXHRQO\PDWWHUVLIWKHSXOVHGRHVQRWVWDUWZLWKLQWKH
JLYHQSHULRG2QFHWKHVWDUWRIDSXOVHLVGHWHFWHGWKHIXQFWLRQZLOOVWDUW
WLPLQJDQGZLOOQRWUHWXUQXQWLOWKHSXOVHHQGV
pulseInFDQPHDVXUHYDOXHVEHWZHHQDURXQGPLFURVHFRQGVWRWKUHHPLQXWHVLQGX
UDWLRQEXWWKHYDOXHRIORQJSXOVHVPD\QRWEHYHU\DFFXUDWH
See Also
7KH$UGXLQRUHIHUHQFHIRUpulseInKWWSZZZDUGXLQRFFHQ5HIHUHQFH3XOVH,Q
5HFLSHVKRZV pulseInXVHGWRPHDVXUHWKHSXOVHZLGWKRIDQXOWUDVRQLFGLVWDQFH
VHQVRU
5HFLSHSURYLGHVPRUHLQIRUPDWLRQRQXVLQJKDUGZDUHLQWHUUXSWV
12.4 Using Arduino As a Clock
Problem
<RXZDQWWRXVHWKHWLPHRIGD\ KRXUVPLQXWHVDQGVHFRQGV LQDVNHWFKDQG\RX
GRQ¦WZDQWWRFRQQHFWH[WHUQDOKDUGZDUH
Solution
7KLVVNHWFKXVHVWKH7LPHOLEUDU\WRGLVSOD\WKHWLPHRIGD\
/*
* Time sketch
*
*/
#include <Time.h>
12.4 Using Arduino As a Clock | 373
void setup()
{
Serial.begin(9600);
setTime(12,0,0,1,1,11); // set time to noon Jan 1 2011
}
void loop()
{
digitalClockDisplay();
delay(1000);
}
void digitalClockDisplay(){
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.print(year());
Serial.println();
}
void printDigits(int digits){
// utility function for clock display: prints preceding colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
Discussion
7KH7LPHOLEUDU\HQDEOHV\RXWRNHHSWUDFNRIWKHGDWHDQGWLPH$VWDQGDUG$UGXLQR
ERDUGXVHVDTXDUW]FU\VWDOIRUWLPLQJDQGWKLVLVDFFXUDWHWRDFRXSOHRIVHFRQGVSHU
GD\EXWLWGRHVQRWKDYHDEDWWHU\WRUHPHPEHUWKHWLPHZKHQSRZHULVVZLWFKHGRII
7KHUHIRUHWLPHZLOOUHVWDUWIURPHDFKWLPHDVNHWFKVWDUWVVR\RXQHHGWRVHWWKHWLPH
XVLQJWKHsetTimeIXQFWLRQ7KHVNHWFKVHWVWKHWLPHWRQRRQRQ-DQXDU\HDFKWLPHLW
VWDUWV
7KH7LPHOLEUDU\XVHVDVWDQGDUGNQRZQDV8QL[ DOVRFDOOHG326,;
WLPH7KHYDOXHVUHSUHVHQWWKHQXPEHURIHODSVHGVHFRQGVVLQFH-DQXDU\
([SHULHQFHG&SURJUDPPHUVPD\UHFRJQL]HWKDWWKLVLVWKHVDPH
DVWKHtime_tXVHGLQWKH,62VWDQGDUG&OLEUDU\IRUVWRULQJWLPHYDOXHV
2IFRXUVHLW¦VPRUHXVHIXOWRVHWWKHWLPHWR\RXUFXUUHQWORFDOWLPHLQVWHDGRIDIL[HG
YDOXH 7KH IROORZLQJ VNHWFK JHWV WKH QXPHULFDO WLPH YDOXH WKH QXPEHU RI HODSVHG
VHFRQGVVLQFH-DQXDU\ IURPWKHVHULDOSRUWWRVHWWKHWLPH<RXFDQHQWHUD
374 | Chapter 12:ಗUsing Time and Dates
YDOXHXVLQJWKH6HULDO0RQLWRU WKHFXUUHQW8QL[WLPHFDQEHIRXQGRQDQXPEHURI
ZHEVLWHVXVLQJWKH*RRJOHVHDUFKWHUPV£8QL[WLPHFRQYHUW¤ /*
* TimeSerial sketch
* example code illustrating Time library set through serial port messages.
*
* Messages consist of the letter T followed by ten digit time (as seconds since
Jan 1 1970)
* You can send the text on the next line using Serial Monitor to set the clock
to noon Jan 1 2011
T 1293883200
*
* A Processing example sketch to automatically send the messages is included in
the download
*/
#include <Time.h>
#define TIME_MSG_LEN 11
ascii digits
#define TIME_HEADER 'T'
// time sync consists of a HEADER followed by ten
// Header tag for serial time sync message
void setup() {
Serial.begin(9600);
Serial.println("Waiting for time sync message");
}
void loop(){
if(Serial.available() )
{
processSyncMessage();
}
if(timeStatus()!= timeNotSet)
{
// here if the time has been set
digitalClockDisplay();
}
delay(1000);
}
void digitalClockDisplay(){
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.print(year());
Serial.println();
}
12.4 Using Arduino As a Clock | 375
void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and
leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
void processSyncMessage() {
// if time sync available from serial port, update time and return true
// time message consists of a header and ten ascii digits
while(Serial.available() >= TIME_MSG_LEN ){
char c = Serial.read() ;
Serial.print(c);
if( c == TIME_HEADER ) {
time_t pctime = 0;
for(int i=0; i < TIME_MSG_LEN -1; i++){
c = Serial.read();
if( c >= '0' && c <= '9'){
pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
}
}
setTime(pctime);
// Sync clock to the time received on serial port
}
}
}
7KHFRGHWRGLVSOD\WKHWLPHDQGGDWHLVWKHVDPHDVEHIRUHEXWQRZWKHVNHWFKZDLWV
WRUHFHLYHWKHWLPHIURPWKHVHULDOSRUW6HHWKH'LVFXVVLRQLQ5HFLSHLI\RXDUHQRW
IDPLOLDUZLWKKRZWRUHFHLYHQXPHULFGDWDXVLQJWKHVHULDOSRUW
$SURFHVVLQJVNHWFKQDPHG6\QF$UGXLQR&ORFNLVLQFOXGHGZLWKWKH7LPHOLEUDU\H[
DPSOHV LW¦VLQWKH7LPH([DPSOHV3URFHVVLQJ6\QF$UGXLQR&ORFNIROGHU 7KLV3URFHVV
LQJVNHWFKZLOOVHQGWKHFXUUHQWWLPHIURP\RXUFRPSXWHUWR$UGXLQRDWWKHFOLFNRID
PRXVH5XQ6\QF$UGXLQR&ORFNLQ3URFHVVLQJHQVXULQJWKDWWKHVHULDOSRUWLVWKHRQH
FRQQHFWHGWR$UGXLQR &KDSWHUGHVFULEHVKRZWRUXQD3URFHVVLQJVNHWFKWKDWWDONV
WR $UGXLQR <RX VKRXOG VHH WKH PHVVDJH Waiting for time sync message VHQW E\
$UGXLQRDQGGLVSOD\HGLQWKH3URFHVVLQJWH[WDUHD WKHEODFNDUHDIRUWH[WPHVVDJHVDW
WKHERWWRPRIWKH3URFHVVLQJ,'( &OLFNWKH3URFHVVLQJDSSOLFDWLRQZLQGRZ LW¦VD
SL[HOJUD\VTXDUH DQG\RXVKRXOGVHHWKHWH[WDUHDGLVSOD\WKHWLPHDVSULQWHGE\WKH
$UGXLQRVNHWFK
<RXFDQDOVRVHWWKHFORFNIURPWKH6HULDO0RQLWRULI\RXFDQJHWWKHFXUUHQW8QL[WLPH
KWWSZZZHSRFKFRQYHUWHUFRPLVRQHRIPDQ\ZHEVLWHVWKDWSURYLGHWKHWLPHLQWKLV
IRUPDW&RS\WKHGLJLWQXPEHULQGLFDWHGDVWKHFXUUHQW8QL[WLPHDQGSDVWHWKLV
LQWRWKH6HULDO0RQLWRU6HQGZLQGRZ3UHFHGHWKHQXPEHUZLWKWKHOHWWHU7DQGFOLFN
6HQG)RUH[DPSOHLI\RXVHQGWKLV
T1282041639
376 | Chapter 12:ಗUsing Time and Dates
$UGXLQRVKRXOGUHVSRQGE\GLVSOD\LQJWKHWLPHHYHU\VHFRQG
10:40:49 17 8 2010
10:40:50 17 8 2010
10:40:51 17 8 2010
10:40:52 17 8 2010
10:40:53 17 8 2010
10:40:54 17 8 2010
. . .
<RXFDQDOVRVHWWKHWLPHXVLQJEXWWRQVRURWKHULQSXWGHYLFHVVXFKDVWLOWVHQVRUVD
MR\VWLFNRUDURWDU\HQFRGHU
7KHIROORZLQJVNHWFKXVHVWZREXWWRQVWRPRYHWKHFORFN£KDQGV¤IRUZDUGRUEDFNZDUG
)LJXUHVKRZVWKHFRQQHFWLRQV VHH5HFLSHLI\RXQHHGKHOSXVLQJVZLWFKHV /*
AdjustClockTime sketch
buttons on pins 2 and 3 adjust the time
*/
#include <Time.h>
const int
const int
btnForward = 2;
btnBack = 3;
unsigned long
prevtime;
// button to move time forward
// button to move time back
// when the clock was last displayed
void setup()
{
digitalWrite(btnForward, HIGH); // enable internal pull-up resistors
digitalWrite(btnBack, HIGH);
setTime(12,0,0,1,1,11); // start with the time set to noon Jan 1 2011
Serial.begin(9600);
Serial.println("ready");
}
void loop()
{
prevtime = now();
// note the time
while( prevtime == now() )
// stay in this loop till the second changes
{
// check if the set button pressed while waiting for second to roll over
if(checkSetTime())
prevtime = now();
// time changed so reset start time
}
digitalClockDisplay();
}
7KH VNHWFK XVHV WKH VDPH digitalClockDisplay DQG printDigits IXQFWLRQV IURP
5HFLSHVRFRS\WKRVHSULRUWRUXQQLQJWKHVNHWFK
12.4 Using Arduino As a Clock | 377
)LJXUH7ZREXWWRQVXVHGWRDGMXVWWKHWLPH
+HUHLVDYDULDWLRQRQWKLVVNHWFKWKDWXVHVWKHSRVLWLRQRIDYDULDEOHUHVLVWRUWRGHWHUPLQH
WKHGLUHFWLRQDQGUDWHRIDGMXVWPHQWZKHQDVZLWFKLVSUHVVHG
#include <Time.h>
const int
const int
potPin = 0;
buttonPin = 2;
unsigned long
prevtime;
// pot to determine direction and speed
// button enables time adjustment
// when the clock was last displayed
void setup()
{
digitalWrite(buttonPin, HIGH); // enable internal pull-up resistors
setTime(12,0,0,1,1,11); // start with the time set to noon Jan 1 2011
Serial.begin(9600);
}
void loop()
{
prevtime = now();
// note the time
while( prevtime == now() )
// stay in this loop till the second changes
{
// check if the set button pressed while waiting for second to roll over
if(checkSetTime())
prevtime = now(); // time changed so reset start time
}
digitalClockDisplay();
}
// functions checks to see if the time should be adjusted
// returns true if time was changed
boolean checkSetTime()
378 | Chapter 12:ಗUsing Time and Dates
{
int value; // a value read from the pot
int step;
// the number of seconds to move (backwards if negative)
boolean isTimeAdjusted = false; // set to true if the time is adjusted
}
while(digitalRead(buttonPin)== LOW)
{
// here while button is pressed
value = analogRead(potPin); // read the pot value
step = map(value, 0,1023, 10, -10); // map value to the desired range
if( step != 0)
{
adjustTime(step);
isTimeAdjusted = true; // to tell the user that the time has changed
digitalClockDisplay(); // update clock
delay(100);
}
}
return isTimeAdjusted;
7KHSUHFHGLQJVNHWFKXVHVWKHVDPH digitalClockDisplayDQG printDigitsIXQFWLRQV
IURP5HFLSHVRFRS\WKRVHSULRUWRUXQQLQJWKHVNHWFK)LJXUHVKRZVKRZ
WKHYDULDEOHUHVLVWRUDQGVZLWFKDUHFRQQHFWHG
)LJXUH$YDULDEOHUHVLVWRUXVHGWRDGMXVWWKHWLPH
12.4 Using Arduino As a Clock | 379
$OOWKHVHH[DPSOHVSULQWWRWKHVHULDOSRUWEXW\RXFDQSULQWWKHRXWSXWWR/('VRU
/&'V7KHGRZQORDGIRUWKH*UDSKLFDO/&'FRYHUHGLQ5HFLSHFRQWDLQVH[DPSOH
VNHWFKHVIRUGLVSOD\LQJDQGVHWWLQJWLPHXVLQJDQDQDORJFORFNGLVSOD\GUDZQRQWKH
/&'
7KH7LPHOLEUDU\LQFOXGHVFRQYHQLHQFHIXQFWLRQVIRUFRQYHUWLQJWRDQGIURPYDULRXV
WLPHIRUPDWV)RUH[DPSOH\RXFDQILQGRXWKRZPXFKWLPHKDVHODSVHGVLQFHWKHVWDUW
RIWKHGD\DQGKRZPXFKWLPHUHPDLQVXQWLOWKHGD\¦VHQG<RXFDQORRNLQ7LPHKLQ
WKHOLEUDULHVIROGHUIRUWKHFRPSOHWHOLVW0RUHGHWDLOVDUHDYDLODEOHLQ&KDSWHU
dayOfWeek( now() );
//the day of the week (Sunday is day 1)
elapsedSecsToday( now() );
// returns the number of seconds since the start
of today
nextMidnight( now() );
// how much time to the end of the day
elapsedSecsThisWeek( now() ); // how much time has elapsed since the start of
the week
<RXFDQDOVRSULQWWH[WVWULQJVIRUWKHGD\VDQGPRQWKVKHUHLVDYDULDWLRQRQWKHGLJLWDO
FORFNGLVSOD\FRGHWKDWSULQWVWKHQDPHVRIWKHGD\DQGPRQWK
void digitalClockDisplay(){
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(dayStr(weekday())); // print the day of the week
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(monthShortStr(month())); // print the month (abbreviated)
Serial.print(" ");
Serial.print(year());
Serial.println();
}
See Also
$UGXLQR7LPHOLEUDU\UHIHUHQFHKWWSZZZDUGXLQRFFSOD\JURXQG&RGH7LPH
:LNLSHGLDDUWLFOHRQ8QL[WLPHKWWSHQZLNLSHGLDRUJZLNL8QL[BWLPH
KWWSZZZHSRFKFRQYHUWHUFRP DQG KWWSZZZRQOLQHFRQYHUVLRQFRPXQL[BWLPHKWP
DUHWZRSRSXODU8QL[WLPHFRQYHUVLRQWRROV
12.5 Creating an Alarm to Periodically Call a Function
Problem
<RXZDQWWRSHUIRUPVRPHDFWLRQRQVSHFLILFGD\VDQGDWVSHFLILFWLPHVRIWKHGD\
380 | Chapter 12:ಗUsing Time and Dates
Solution
7LPH$ODUPVLVDFRPSDQLRQOLEUDU\LQFOXGHGLQWKH7LPHOLEUDU\GRZQORDGGLVFXVVHG
LQ5HFLSH LQVWDOOLQJWKH7LPHOLEUDU\ZLOODOVRLQVWDOOWKH7LPH$ODUPVOLEUDU\ 7LPH$ODUPVPDNHVLWHDV\WRFUHDWHWLPHDQGGDWHDODUPV
/*
* TimeAlarmExample sketch
*
* This example calls alarm functions at 8:30 am and at 5:45 pm (17:45)
* and simulates turning lights on at night and off in the morning
*
* A timer is called every 15 seconds
* Another timer is called once only after 10 seconds
*
* At startup the time is set to Jan 1 2010 8:29 am
*/
#include <Time.h>
#include <TimeAlarms.h>
void setup()
{
Serial.begin(9600);
Serial.println("TimeAlarms Example");
Serial.println("Alarms are triggered daily at 8:30 am and 17:45 pm");
Serial.println("One timer is triggered every 15 seconds");
Serial.println("Another timer is set to trigger only once after 10 seconds");
Serial.println();
setTime(8,29,40,1,1,10); // set time to 8:29:40am Jan 1 2010
Alarm.alarmRepeat(8,30,0, MorningAlarm);
Alarm.alarmRepeat(17,45,0,EveningAlarm);
// 8:30am every day
// 5:45pm every day
Alarm.timerRepeat(15, RepeatTask);
Alarm.timerOnce(10, OnceOnlyTask);
// timer for every 15 seconds
// called once after 10 seconds
}
void MorningAlarm()
{
Serial.println("Alarm: - turn lights off");
}
void EveningAlarm()
{
Serial.println("Alarm: - turn lights on");
}
void RepeatTask()
{
Serial.println("15 second timer");
}
void OnceOnlyTask()
12.5 Creating an Alarm to Periodically Call a Function | 381
{
}
Serial.println("This timer only triggers once");
void loop()
{
digitalClockDisplay();
Alarm.delay(1000); // wait one second between clock display
}
void digitalClockDisplay()
{
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.println();
}
void printDigits(int digits)
{
// utility function for digital clock display: prints preceding colon and
leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
Discussion
<RXFDQVFKHGXOHWDVNVWRWULJJHUDWDSDUWLFXODUWLPHRIGD\ WKHVHDUHFDOOHGDODUPV
RUVFKHGXOHWDVNVWRRFFXUDIWHUDQLQWHUYDORIWLPHKDVHODSVHG FDOOHGWLPHUV (DFKRI
WKHVHWDVNVFDQEHFUHDWHGWRFRQWLQXRXVO\UHSHDWRUWRRFFXURQO\RQFH
7RVSHFLI\DQDODUPWRWULJJHUDWDVNUHSHDWHGO\DWDSDUWLFXODUWLPHRIGD\XVH
Alarm.alarmRepeat(8,30,0, MorningAlarm);
7KLVFDOOVWKHIXQFWLRQMorningAlarmDWDPHYHU\GD\
,I\RXZDQWWKHDODUPWRWULJJHURQO\RQFH\RXFDQXVHWKHalarmOncePHWKRG
Alarm.alarmOnce(8,30,0, MorningAlarm);
7KLVFDOOVWKHIXQFWLRQ MorningAlarmDVLQJOHWLPHRQO\ WKHQH[WWLPHLWLVDP
DQGZLOOQRWWULJJHUDJDLQ
7LPHUVWULJJHUWDVNVWKDWRFFXUDIWHUDVSHFLILHGLQWHUYDORIWLPHKDVSDVVHGUDWKHUWKDQ
DWDVSHFLILFWLPHRIGD\7KHWLPHULQWHUYDOFDQEHVSHFLILHGLQDQ\QXPEHURIVHFRQGV
RULQKRXUPLQXWHVDQGVHFRQGV
Alarm.timerRepeat(15, Repeats);
// timer task every 15 seconds
7KLVFDOOVWKHRepeatsIXQFWLRQLQ\RXUVNHWFKHYHU\VHFRQGV
382 | Chapter 12:ಗUsing Time and Dates
,I\RXZDQWDWLPHUWRWULJJHURQFHRQO\XVHWKHtimerOncePHWKRG
Alarm.timerOnce(10, OnceOnly);
// called once after 10 seconds
7KLVFDOOVWKHonceOnlyIXQFWLRQLQDVNHWFKVHFRQGVDIWHUWKHWLPHULVFUHDWHG
<RXU FRGH QHHGV WR FDOO Alarm.delay UHJXODUO\ EHFDXVH WKLV IXQFWLRQ
FKHFNV WKH VWDWH RI DOO WKH VFKHGXOHG HYHQWV )DLOLQJ WR UHJXODUO\ FDOO
Alarm.delayZLOOUHVXOWLQWKHDODUPVQRWEHLQJWULJJHUHG<RXFDQFDOO
Alarm.delay(0) LI \RX QHHG WR VHUYLFH WKH VFKHGXOHU ZLWKRXW D GHOD\
$OZD\VXVH Alarm.delayLQVWHDGRI delayZKHQXVLQJ7LPH$ODUPVLQD
VNHWFK
7KH7LPH$ODUPVOLEUDU\UHTXLUHVWKH7LPHOLEUDU\WREHLQVWDOOHG¢VHH5HFLSH1R
LQWHUQDORUH[WHUQDOKDUGZDUHLVUHTXLUHGWRXVHWKH7LPH$ODUPVOLEUDU\7KHVFKHGXOHU
GRHVQRWXVHLQWHUUXSWVVRWKHWDVNKDQGOLQJIXQFWLRQLVWKHVDPHDVDQ\RWKHUIXQFWLRQV
\RXFUHDWHLQ\RXUVNHWFK FRGHLQDQLQWHUUXSWKDQGOHUKDVUHVWULFWLRQVWKDWDUHGLV
FXVVHGLQ&KDSWHUEXWWKHVHGRQRWDSSO\WR7LPH$ODUPVIXQFWLRQV 7LPHULQWHUYDOVFDQUDQJHIURPRQHVHFRQGWRVHYHUDO\HDUV ,I\RXQHHGWLPHULQWHUYDOV
VKRUWHUWKDQRQHVHFRQGWKH7LPHG$FWLRQOLEUDU\E\$OH[DQGHU%UHYLJPD\EHPRUH
VXLWDEOHVHHKWWSZZZDUGXLQRFFSOD\JURXQG&RGH7LPHG$FWLRQ
7DVNVDUHVFKHGXOHGIRUVSHFLILFWLPHVGHVLJQDWHGE\WKHV\VWHPFORFNLQWKH7LPHOLEUDU\
VHH5HFLSHIRUPRUHGHWDLOV ,I\RXFKDQJHWKHV\VWHPWLPH HJE\FDOOLQJ set
Time WKHWULJJHUWLPHVDUHQRWDGMXVWHG)RUH[DPSOHLI\RXXVHsetTimeWRPRYHRQH
KRXUDKHDGDOODODUPVDQGWLPHUVZLOORFFXURQHKRXUVRRQHU,QRWKHUZRUGVLILW¦V
DQGDWDVNLVVHWWRWULJJHULQWZRKRXUV DW DQGWKHQ\RXFKDQJHWKHFXUUHQW
WLPHWRWKHWDVNZLOOWULJJHULQRQHKRXU,IWKHV\VWHPWLPHLVVHWEDFNZDUG¢IRU
H[DPSOH WR ¢WKH WDVN ZLOO WULJJHU LQ WKUHH KRXUV LH ZKHQ WKH V\VWHP WLPH
LQGLFDWHV ,IWKHWLPHLVUHVHWWRHDUOLHUWKDQWKHWLPHDWZKLFKDWDVNZDVVFKHGXOHG
WKHWDVNZLOOEHWULJJHUHGLPPHGLDWHO\ DFWXDOO\RQWKHQH[WFDOOWRAlarm.delay 7KLVLVWKHH[SHFWHGEHKDYLRUIRUDODUPV¢WDVNVDUHVFKHGXOHGIRUDVSHFLILFWLPHRIGD\
DQGZLOOWULJJHUDWWKDWWLPH¢EXWWKHHIIHFWRQWLPHUVPD\EHOHVVFOHDU,IDWLPHULV
VFKHGXOHGWRWULJJHULQILYHPLQXWHV¦WLPHDQGWKHQWKHFORFNLVVHWEDFNE\RQHKRXU
WKDWWLPHUZLOOQRWWULJJHUXQWLORQHKRXUDQGILYHPLQXWHVKDYHHODSVHG HYHQLILWLVD
UHSHDWLQJWLPHU¢DUHSHDWGRHVQRWJHWUHVFKHGXOHGXQWLODIWHULWWULJJHUV 8SWRVL[DODUPVDQGWLPHUVFDQEHVFKHGXOHGWRUXQDWWKHVDPHWLPH<RXFDQPRGLI\
WKHOLEUDU\WRHQDEOHPRUHWDVNVWREHVFKHGXOHG5HFLSHVKRZV\RXKRZWRGRWKLV
onceOnlyDODUPVDQGWLPHUVDUHIUHHGZKHQWKH\DUHWULJJHUHGDQG\RXFDQUHVFKHGXOH
WKHVHDVRIWHQDV\RXZDQWVRORQJDVWKHUHDUHQRPRUHWKDQVL[SHQGLQJDWRQHWLPH
7KHIROORZLQJFRGHJLYHVRQHH[DPSOHRIKRZDtimerOnceWDVNFDQEHUHVFKHGXOHG
Alarm.timerOnce(random(10), randomTimer);
seconds
// trigger after random number of
12.5 Creating an Alarm to Periodically Call a Function | 383
void randomTimer(){
int period = random(2,10);
Alarm.timerOnce(period, randomTimer);
}
// get a new random period
// trigger for another random period
12.6 Using a Real-Time Clock
Problem
<RXZDQWWRXVHWKHWLPHRIGD\SURYLGHGE\DUHDOWLPHFORFN 57& ([WHUQDOERDUGV
XVXDOO\KDYHEDWWHU\EDFNXSVRWKHWLPHZLOOEHFRUUHFWHYHQZKHQ$UGXLQRLVUHVHWRU
WXUQHGRII
Solution
7KHVLPSOHVWZD\WRXVHDQ57&LVZLWKDFRPSDQLRQOLEUDU\IRUWKH7LPHOLEUDU\QDPHG
'657&K7KLVUHFLSHLVIRUWKHZLGHO\XVHG'6DQG'657&FKLSV
/*
* TimeRTC sketch
* example code illustrating Time library with real-time clock.
*
*/
#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>
// a basic DS1307 library that returns time as a time_t
void setup() {
Serial.begin(9600);
setSyncProvider(RTC.get); // the function to get the time from the RTC
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
}
void loop()
{
digitalClockDisplay();
delay(1000);
}
void digitalClockDisplay(){
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
384 | Chapter 12:ಗUsing Time and Dates
Serial.print(" ");
Serial.print(year());
Serial.println();
}
void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and
leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
0RVW57&ERDUGVIRU$UGXLQRXVHWKH,&SURWRFROIRUFRPPXQLFDWLQJ VHH&KDS
WHUIRUPRUHRQ,& &RQQHFWWKHOLQHPDUNHG£6&/¤ RU£&ORFN¤ WR$UGXLQRDQDORJ
SLQDQG£6'$¤ RU£'DWD¤ WRDQDORJSLQDVVKRZQLQ)LJXUH $QDORJSLQV
DQGDUHXVHGIRU,&VHH&KDSWHU 7DNHFDUHWRHQVXUHWKDW\RXFRQQHFWWKH9
SRZHUOLQHDQG*QGSLQVFRUUHFWO\
)LJXUH&RQQHFWLQJDUHDOWLPHFORFN
Discussion
7KHFRGHLVVLPLODUWRRWKHUUHFLSHVXVLQJWKH7LPHOLEUDU\EXWLWJHWVLWVYDOXHIURPWKH
57& UDWKHU WKDQ IURP WKH VHULDO SRUW RU KDUGFRGHG YDOXH 7KH RQO\ DGGLWLRQDO OLQH
QHHGHGLVWKLV
setSyncProvider(RTC.get);
// the function to get the time from the RTC
7KHsetSyncProviderIXQFWLRQWHOOVWKH7LPHOLEUDU\KRZLWVKRXOGJHWLQIRUPDWLRQIRU
VHWWLQJ DQGXSGDWLQJ WKHWLPHRTC.getLVDPHWKRGZLWKLQWKH57&OLEUDU\WKDWUHWXUQV
WKHFXUUHQWWLPHLQWKHIRUPDWXVHGE\WKH7LPHOLEUDU\ 8QL[WLPH 12.6 Using a Real-Time Clock | 385
(DFKWLPH$UGXLQRVWDUWVWKHsetupIXQFWLRQZLOOFDOORTC.getWRVHWWKHWLPHIURPWKH
57&KDUGZDUH
%HIRUH\RXFDQJHWWKHFRUUHFWWLPHIURPWKHPRGXOH\RXQHHGWRVHWLWVWLPH+HUHLV
DVNHWFKWKDWHQDEOHV\RXWRVHWWKHWLPHRQWKH57&KDUGZDUH¢\RXRQO\QHHGWRGR
WKLVZKHQ\RXILUVWDWWDFKWKHEDWWHU\WRWKH57&ZKHQUHSODFLQJWKHEDWWHU\RULIWKH
WLPHQHHGVWREHFKDQJHG
/*
* TimeRTCSet sketch
* example code illustrating Time library with real-time clock.
*
* RTC is set in response to serial port time message
* A Processing example sketch to set the time is included in the download
*/
#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>
// a basic DS1307 library that returns time as a time_t
void setup() {
Serial.begin(9600);
setSyncProvider(RTC.get); // the function to get the time from the RTC
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
}
void loop()
{
if(Serial.available())
{
time_t t = processSyncMessage();
if(t >0)
{
RTC.set(t);
// set the RTC and the system time to the received value
setTime(t);
}
}
digitalClockDisplay();
delay(1000);
}
void digitalClockDisplay(){
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
386 | Chapter 12:ಗUsing Time and Dates
}
Serial.print(year());
Serial.println();
void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and
leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
/* code to process time sync messages from the serial port */
#define TIME_MSG_LEN 11
// time sync to PC is HEADER followed by unix time_t
as ten ascii digits
#define TIME_HEADER 'T'
// Header tag for serial time sync message
time_t processSyncMessage() {
// return the time if a valid sync message is received on the serial port.
// time message consists of a header and ten ascii digits
while(Serial.available() >= TIME_MSG_LEN ){
char c = Serial.read() ;
Serial.print(c);
if( c == TIME_HEADER ) {
time_t pctime = 0;
for(int i=0; i < TIME_MSG_LEN -1; i++){
c = Serial.read();
if( c >= '0' && c <= '9'){
pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
}
}
return pctime;
}
}
return 0;
}
7KLVVNHWFKLVDOPRVWWKHVDPHDVWKH7LPH6HULDOVNHWFKLQ5HFLSHIRUVHWWLQJWKH
WLPHIURPWKHVHULDOSRUWEXWKHUHWKHIROORZLQJIXQFWLRQLVFDOOHGZKHQDWLPHPHVVDJH
LVUHFHLYHGIURPWKHFRPSXWHUWRVHWWKH57&
RTC.set(t);
// set the RTC and the system time to the received value
setTime(t);
7KH 57& FKLS XVHV ,& WR FRPPXQLFDWH ZLWK $UGXLQR ,& LV H[SODLQHG LQ &KDS
WHUVHH5HFLSHLI\RXDUHLQWHUHVWHGLQPRUHGHWDLOVRQ,&FRPPXQLFDWLRQZLWK
WKH57&FKLS
See Also
7KH6SDUN)XQ%2%GDWDVKHHWKWWSVWRUHJUDYLWHFKXVLFUHFOKWPO
12.6 Using a Real-Time Clock | 387
Download from Wow! eBook <www.wowebook.com>
CHAPTER 13
Communicating Using I2C and SPI
13.0 Introduction
7KH,& ,QWHU,QWHJUDWHG&LUFXLW DQG63, 6HULDO3HULSKHUDO,QWHUIDFH VWDQGDUGVZHUH
FUHDWHGWRSURYLGHVLPSOHZD\VIRUGLJLWDOLQIRUPDWLRQWREHWUDQVIHUUHGEHWZHHQVHQVRUV
DQGPLFURFRQWUROOHUVVXFKDV$UGXLQR$UGXLQROLEUDULHVIRUERWK,&DQG63,PDNHLW
HDV\IRU\RXWRXVHERWKRIWKHVHSURWRFROV
7KH FKRLFH EHWZHHQ ,& DQG 63, LV XVXDOO\ GHWHUPLQHG E\ WKH GHYLFHV \RX ZDQW WR
FRQQHFW6RPHGHYLFHVSURYLGHERWKVWDQGDUGVEXWXVXDOO\DGHYLFHRUFKLSVXSSRUWV
RQHRUWKHRWKHU
,&KDVWKHDGYDQWDJHWKDWLWRQO\QHHGVWZRVLJQDOFRQQHFWLRQVWR$UGXLQR¢XVLQJ
PXOWLSOHGHYLFHVRQWKHWZRFRQQHFWLRQVLVIDLUO\HDV\DQG\RXJHWDFNQRZOHGJPHQW
WKDWVLJQDOVKDYHEHHQFRUUHFWO\UHFHLYHG7KHGLVDGYDQWDJHVDUHWKDWWKHGDWDUDWHLV
VORZHUWKDQ63,DQGGDWDFDQRQO\EHWUDYHOLQJLQRQHGLUHFWLRQDWDWLPHORZHULQJWKH
GDWDUDWHHYHQPRUHLIWZRZD\FRPPXQLFDWLRQLVQHHGHG,WLVDOVRQHFHVVDU\WRFRQQHFW
SXOOXSUHVLVWRUVWRWKHFRQQHFWLRQVWRHQVXUHUHOLDEOHWUDQVPLVVLRQRIVLJQDOV VHHWKH
LQWURGXFWLRQWR&KDSWHUIRUPRUHRQSXOOXSV 7KHDGYDQWDJHVRI63,DUHWKDWLWUXQVDWDKLJKHUGDWDUDWHDQGLWKDVVHSDUDWHLQSXW
DQGRXWSXWFRQQHFWLRQVVRLWFDQVHQGDQGUHFHLYHDWWKHVDPHWLPH,WXVHVRQHDGGL
WLRQDOOLQHSHUGHYLFHWRVHOHFWWKHDFWLYHGHYLFHVRPRUHFRQQHFWLRQVDUHUHTXLUHGLI
\RXKDYHPDQ\GHYLFHVWRFRQQHFW
0RVW$UGXLQRSURMHFWVXVH63,GHYLFHVIRUKLJKGDWDUDWHDSSOLFDWLRQVVXFKDV(WKHUQHW
DQGPHPRU\FDUGVZLWKMXVWDVLQJOHGHYLFHDWWDFKHG,&LVPRUHW\SLFDOO\XVHGZLWK
VHQVRUVWKDWGRQ¦WQHHGWRVHQGDORWRIGDWD
7KLVFKDSWHUVKRZVKRZWRXVH,&DQG63,WRFRQQHFWWRFRPPRQGHYLFHV,WDOVR
VKRZVKRZWRFRQQHFWWZRRUPRUH$UGXLQRERDUGVWRJHWKHUXVLQJ,&IRUPXOWLERDUG
DSSOLFDWLRQV
389
I2C
7KHWZRFRQQHFWLRQVIRUWKH,&EXVDUHFDOOHG6&/DQG6'$7KHVHDUHDYDLODEOHRQ
DVWDQGDUG$UGXLQRERDUGXVLQJDQDORJSLQIRU6&/ZKLFKSURYLGHVDFORFNVLJQDO
DQGDQDORJSLQIRU6'/ZKLFKLVIRUWUDQVIHURIGDWD RQWKH0HJDXVHGLJLWDOSLQ
IRU6'$DQGSLQIRU6&/ 2QHGHYLFHRQWKH,&EXVLVFRQVLGHUHGWKHPDVWHUGHYLFH
,WVMRELVWRFRRUGLQDWHWKHWUDQVIHURILQIRUPDWLRQEHWZHHQWKHRWKHUGHYLFHV VODYHV WKDWDUHDWWDFKHG7KHUHPXVWEHRQO\RQHPDVWHUDQGLQPRVWFDVHVWKH$UGXLQRLVWKH
PDVWHUFRQWUROOLQJWKHRWKHUFKLSVDWWDFKHGWRLW)LJXUHGHSLFWVDQ,&PDVWHU
ZLWKPXOWLSOH,&VODYHV
)LJXUH$Q,&PDVWHUZLWKRQHRUPRUH,&VODYHV
,&GHYLFHVQHHGDFRPPRQJURXQGWRFRPPXQLFDWH7KH$UGXLQR*QG
SLQPXVWEHFRQQHFWHGWRJURXQGRQHDFK,&GHYLFH
6ODYHGHYLFHVDUHLGHQWLILHGE\WKHLUDGGUHVVQXPEHU(DFKVODYHPXVWKDYHDXQLTXH
DGGUHVV6RPH,&GHYLFHVKDYHDIL[HGDGGUHVV DQH[DPSOHLVWKHQXQFKXFNLQ5HF
LSH ZKLOHRWKHUVDOORZ\RXWRFRQILJXUHWKHLUDGGUHVVE\VHWWLQJSLQVKLJKRUORZ
VHH5HFLSH RUE\VHQGLQJLQLWLDOL]DWLRQFRPPDQGV
$UGXLQRXVHVELWYDOXHVWRVSHFLI\,&DGGUHVVHV6RPHGHYLFHGDWD
VKHHWVXVHELWDGGUHVVYDOXHV,I\RXUVGRHVGLYLGHWKDWYDOXHE\WR
JHWWKHFRUUHFWELWYDOXH
,&DQG63,RQO\GHILQHKRZFRPPXQLFDWLRQWDNHVSODFHEHWZHHQGHYLFHV¢WKHPHV
VDJHVWKDWQHHGWREHVHQWGHSHQGRQHDFKLQGLYLGXDOGHYLFHDQGZKDWLWGRHV<RXZLOO
QHHGWRFRQVXOWWKHGDWDVKHHWIRU\RXUGHYLFHWRGHWHUPLQHZKDWFRPPDQGVDUHUHTXLUHG
WRJHWLWWRIXQFWLRQDQGZKDWGDWDLVUHTXLUHGRUUHWXUQHG
390 | Chapter 13:ಗCommunicating Using I2C and SPI
7KH$UGXLQR:LUHOLEUDU\KLGHVDOOWKHORZOHYHOIXQFWLRQDOLW\IRU,&DQGHQDEOHVVLP
SOH FRPPDQGV WR EH XVHG WR LQLWLDOL]H DQG FRPPXQLFDWH ZLWK GHYLFHV 5HFLSH SURYLGHVDEDVLFLQWURGXFWLRQWRWKHOLEUDU\DQGLWVXVH
SPI
5HFHQW$UGXLQRUHOHDVHV IURPUHOHDVH LQFOXGHDOLEUDU\WKDWDOORZVFRPPXQLFD
WLRQZLWK63,GHYLFHV63,KDVVHSDUDWHLQSXW ODEHOHG£026,¤ DQGRXWSXW ODEHOHG
£0,62¤ OLQHVDQGDFORFNOLQH7KHVHWKUHHOLQHVDUHFRQQHFWHGWRWKHUHVSHFWLYHOLQHV
RQRQHRUPRUHVODYHV6ODYHVDUHLGHQWLILHGE\VLJQDOLQJZLWKWKH6ODYH6HOHFW 66 OLQH
)LJXUHVKRZVWKH63,FRQQHFWLRQV
)LJXUH6LJQDOFRQQHFWLRQVIRU63,PDVWHUDQGVODYHV
7KHSLQQXPEHUVWRXVHIRUWKH63,SLQVDUHVKRZQLQ7DEOH
7DEOH$UGXLQRGLJLWDOSLQVXVHGIRU63,
SPI signal
Standard Arduino board
Arduino Mega
SCLK (clock)
13
52
MISO (data out)
12
50
MOSI (data in)
11
51
SS (slave select)
10
53
See Also
$SSOLFDWLRQV QRWH FRPSDULQJ ,& WR 63, KWWSZZZPD[LPLFFRPDSSQRWHVLQGH[
PYSLG
$UGXLQR:LUHOLEUDU\UHIHUHQFHKWWSZZZDUGXLQRFFHQ5HIHUHQFH:LUH
$UGXLQR63,OLEUDU\UHIHUHQFHKWWSZZZDUGXLQRFFSOD\JURXQG&RGH6SL
13.0 Introduction | 391
13.1 Controlling an RGB LED Using the BlinkM Module
Problem
<RXZDQWWRFRQWURO,&HQDEOHG/('VVXFKDVWKH%OLQN0PRGXOH
Solution
%OLQN0LVDSUHDVVHPEOHGFRORU/('PRGXOHWKDWJHWV\RXVWDUWHGZLWK,&ZLWKPLQ
LPDOIXVV
,QVHUWWKH%OLQN0SLQVRQWRDQDORJSLQVWKURXJKDVVKRZQLQ)LJXUH
)LJXUH%OLQN0PRGXOHSOXJJHGLQWRDQDORJSLQV
7KHIROORZLQJVNHWFKLVEDVHGRQ5HFLSHEXWLQVWHDGRIGLUHFWO\FRQWUROOLQJWKH
YROWDJHRQWKHUHGJUHHQDQGEOXH/('HOHPHQWV,&FRPPDQGVDUHVHQWWRWKH%OLQN0
PRGXOHZLWKLQVWUXFWLRQVWRSURGXFHDFRORUEDVHGRQWKHUHGJUHHQDQGEOXHOHYHOV
7KH hueToRGBIXQFWLRQLVWKHVDPHDVZKDWZHXVHGLQ5HFLSHDQGLVQRWUHSHDWHG
KHUHVRFRS\WKHIXQFWLRQLQWRWKHERWWRPRI\RXUVNHWFKEHIRUHFRPSLOLQJ WKLVERRN¦V
ZHEVLWHKDVWKHFRPSOHWHVNHWFK /*
* BlinkM sketch
* This sketch continuously fades through the color wheel
*/
#include <Wire.h>
const int address = 0;
//Default I2C address for BlinkM
392 | Chapter 13:ಗCommunicating Using I2C and SPI
int color = 0; // a value from 0 to 255 representing the hue
byte R, G, B; // the Red, Green, and Blue color components
void setup()
{
Wire.begin(); // set up Arduino I2C support
// turn on power pins for BlinkM
pinMode(17, OUTPUT);
// pin 17 (analog out 4) provides +5V to BlinkM
digitalWrite(17, HIGH);
pinMode(16, OUTPUT);
// pin 16 (analog out 3) provides Ground
digitalWrite(16, LOW);
}
void loop()
{
int brightness = 255; // 255 is maximum brightness
hueToRGB( color, brightness); // call function to convert hue to RGB
// write the RGB values to BlinkM
Wire.beginTransmission(address);// join I2C, talk to BlinkM
Wire.send('c');
// 'c' == fade to color
Wire.send(R);
// value for red channel
Wire.send(B);
// value for blue channel
Wire.send(G);
// value for green channel
Wire.endTransmission(); // leave I2C bus
color++;
if(color > 255)
color = 0;
delay(10);
// increment the color
//
}
7KHIROORZLQJVNHWFKXVHVDIXQFWLRQQDPHG hueToRGBWKDWZDVLQWURGXFHGLQ&KDS
WHUWRFRQYHUWDQLQWHJHUYDOXHLQWRLWVUHGJUHHQDQGEOXHFRPSRQHQWV
// function to convert a color to its Red, Green, and Blue components.
void hueToRGB( int hue, int brightness)
{
unsigned int scaledHue = (hue * 6);
unsigned int segment = scaledHue / 256; // segment 0 to 5 around color wheel
unsigned int segmentOffset = scaledHue - (segment * 256); // position within
the segment
unsigned int complement = 0;
unsigned int prev = (brightness * ( 255 - segmentOffset)) / 256;
unsigned int next = (brightness * segmentOffset) / 256;
switch(segment ) {
case 0:
// red
R = brightness;
G = next;
B = complement;
break;
13.1 Controlling an RGB LED Using the BlinkM Module | 393
}
case 1:
// yellow
R = prev;
G = brightness;
B = complement;
break;
case 2:
// green
R = complement;
G = brightness;
B = next;
break;
case 3:
// cyan
R = complement;
G = prev;
B = brightness;
break;
case 4:
// blue
R = next;
G = complement;
B = brightness;
break;
case 5:
// magenta
default:
R = brightness;
G = complement;
B = prev;
break;
}
Discussion
7KH:LUHOLEUDU\LVDGGHGWRWKHVNHWFKXVLQJWKHIROORZLQJ
#include <Wire.h>
)RUPRUHGHWDLOVDERXWXVLQJOLEUDULHVVHH&KDSWHU
7KHFRGHLQsetupLQLWLDOL]HVWKH:LUHOLEUDU\DQGWKHKDUGZDUHLQWKH$UGXLQRWRGULYH
6&$DQG6'/RQDQDORJSLQVDQGDQGWXUQVRQWKHSLQVXVHGWRSRZHUWKH%OLQN0
PRGXOH
7KHloopFRGHFDOOVWKHIXQFWLRQhueToRGBWRFDOFXODWHWKHUHGJUHHQDQGEOXHYDOXHV
IRUWKHFRORU
7KH5*DQG%YDOXHVDUHVHQWWR%OLQN0XVLQJWKLVVHTXHQFH
Wire.beginTransmission(address); // start an I2C message to the BlinkM address
Wire.send('c');
// 'c' is a command to fade to the color that follows
Wire.send(R);
// value for red
Wire.send(B);
// value for blue
Wire.send(G);
// value for green
Wire.endTransmission();
// complete the I2C message
$OOGDWDWUDQVPLVVLRQWR,&GHYLFHVIROORZVWKLVSDWWHUQbeginTransmissionDQXPEHU
RIsendPHVVDJHVDQGendTransmission
394 | Chapter 13:ಗCommunicating Using I2C and SPI
,&VXSSRUWVXSWRGHYLFHVFRQQHFWHGWRWKHFORFNDQGGDWDSLQVDQGWKHDGGUHVV
GHWHUPLQHVZKLFKGHYLFHZLOOUHVSRQG7KHGHIDXOWDGGUHVVIRU%OLQN0LVEXWWKLVFDQ
EHDOWHUHGE\VHQGLQJDFRPPDQGWRFKDQJHWKHDGGUHVV¢VHHWKH%OLQN0XVHUPDQXDO
IRULQIRUPDWLRQRQDOOFRPPDQGV
7RFRQQHFWPXOWLSOH%OLQN0VFRQQHFWDOOWKHFORFNSLQV PDUNHG£F¤RQ%OLQN0DQDORJ
SLQRQ$UGXLQR DQGDOOWKHGDWDSLQV PDUNHG£G¤RQ%OLQN0DQDORJSLQRQ$U
GXLQR DVVKRZQLQ)LJXUH7KHSRZHUSLQVVKRXOGEHFRQQHFWHGWR9DQG*QG
RQ$UGXLQRRUDQH[WHUQDOSRZHUVRXUFHDVWKHDQDORJSLQVFDQQRWSURYLGHHQRXJK
FXUUHQWIRUPRUHWKDQDFRXSOHRIPRGXOHV
)LJXUH0XOWLSOH%OLQN0PRGXOHVFRQQHFWHGWRJHWKHU
(DFK %OLQN0 FDQ GUDZ XS WR P$ VR LI \RX¦UH XVLQJ PRUH WKDQ D
KDQGIXOWKH\VKRXOGEHSRZHUHGXVLQJDQH[WHUQDOVXSSO\
<RXQHHGWRVHWHDFK%OLQN0WRDGLIIHUHQW,&DGGUHVVDQG\RXFDQXVHWKH%OLQN0
7HVWHUVNHWFKWKDWFRPHVZLWKWKH%OLQN0H[DPSOHVGRZQORDGDEOHIURPKWWSWKLQJP
FRPILOHDGPLQWKLQJPGRZQORDGV%OLQN0B([DPSOHV]LS
&RPSLOHDQGXSORDGWKH%OLQN07HVWHUVNHWFK3OXJHDFK%OLQN0PRGXOHLQWR$UGXLQR
RQHDWDWLPH VZLWFKRIISRZHUZKHQFRQQHFWLQJDQGGLVFRQQHFWLQJWKHPRGXOHV 8VH
WKH%OLQN07HVWHUVFDQFRPPDQGsWRGLVSOD\WKHFXUUHQWDGGUHVVDQGXVHWKHAFRP
PDQGWRVHWHDFKPRGXOHWRDGLIIHUHQWDGGUHVV
13.1 Controlling an RGB LED Using the BlinkM Module | 395
%OLQN07HVWHUXVHVEDXGVR\RXPD\QHHGWRVHWWKHEDXGUDWH
LQWKH6HULDO0RQLWRUWRWKLVVSHHGWRJHWDUHDGDEOHGLVSOD\
$IWHUDOOWKH%OLQN0VKDYHDXQLTXHDGGUHVV\RXFDQVHWWKH addressYDULDEOHLQWKH
SUHFHGLQJVNHWFKWRWKHDGGUHVVRIWKH%OLQN0\RXZDQWWRFRQWURO7KLVH[DPSOHDV
VXPHVDGGUHVVHVIURPWR
#include <Wire.h>
int addressA = 9; //I2C address for BlinkM
int addressB = 10;
int addressC = 11;
int color = 0; // a value from 0 to 255 representing the hue
byte R, G, B; // the red, green, and blue color components
void setup()
{
Wire.begin(); // set up Arduino I2C support
}
// turn on power pins for BlinkM
pinMode(17, OUTPUT);
// pin 17 (analog out 4) provides +5V to BlinkM
digitalWrite(17, HIGH);
pinMode(16, OUTPUT); // pin 16 (analog out 3) provides Ground
digitalWrite(16, LOW);
void loop()
{
int brightness = 255; // 255 is maximum brightness
hueToRGB( color, brightness); // call function to convert hue to RGB
// write the RGB values to each BlinkM
setColor(addressA, R,G,B);
setColor(addressB, G,B,R);
setColor(addressA, B,R,G);
color++;
if(color > 255)
color = 0;
delay(10);
// increment the color
// ensure valid value
}
void setColor(int address, byte R, byte G, byte B)
{
Wire.beginTransmission(address);// join I2C, talk to BlinkM
Wire.send('c');
// 'c' == fade to color
Wire.send(R);
// value for red channel
Wire.send(B);
// value for blue channel
Wire.send(G);
// value for green channel
Wire.endTransmission();
// leave I2C bus
}
396 | Chapter 13:ಗCommunicating Using I2C and SPI
7KHsetColorIXQFWLRQZULWHVWKHJLYHQ5*%YDOXHVWRWKH%OLQN0DWWKHJLYHQDGGUHVV
7KHFRGHXVHVWKH hueToRGBIXQFWLRQIURPHDUOLHULQWKLVUHFLSHWRFRQYHUWDQLQWHJHU
YDOXHLQWRLWVUHGJUHHQDQGEOXHFRPSRQHQWV
See Also
7KH%OLQN08VHU0DQXDOKWWSWKLQJPFRPILOHDGPLQWKLQJPGRZQORDGV%OLQN0BGD
WDVKHHWSGI
([DPSOH$UGXLQRVNHWFKHVKWWSWKLQJPFRPILOHDGPLQWKLQJPGRZQORDGV%OLQN0B([
DPSOHV]LS
13.2 Using the Wii Nunchuck Accelerometer
Problem
<RXZDQWWRFRQQHFWD:LLQXQFKXFNWR\RXU$UGXLQRDVDQLQH[SHQVLYHZD\WRXVH
DFFHOHURPHWHUV7KHQXQFKXFNLVDSRSXODUORZFRVWJDPHGHYLFHWKDWFDQEHXVHGWR
LQGLFDWHWKHRULHQWDWLRQRIWKHGHYLFHE\PHDVXULQJWKHHIIHFWVRIJUDYLW\
Solution
7KHQXQFKXFNXVHVDSURSULHWDU\SOXJ,I\RXGRQ¦WZDQWWRXVH\RXUQXQFKXFNZLWK
\RXU:LLDJDLQ\RXFDQFXWWKHOHDGWRFRQQHFWLW$OWHUQDWLYHO\LWLVSRVVLEOHWRXVHD
VPDOOSLHFHRIPDWUL[ERDUGWRPDNHWKHFRQQHFWLRQVLQWKHSOXJLI\RXDUHFDUHIXO WKH
SLQRXWVDUHVKRZQLQ)LJXUH RU\RXFDQEX\DQDGDSWHUPDGHE\7RGERW KWWS
WRGERWFRPEORJZLLFKXFNZLLQXQFKXFNDGDSWHUDYDLODEOH )LJXUH&RQQHFWLQJDQXQFKXFNWR$UGXLQR
13.2 Using the Wii Nunchuck Accelerometer | 397
7KHOLEUDU\VXSSRUWLQJWKHQXQFKXFNIXQFWLRQVLVDYDLODEOHIURPKWWSWRGERWFRPEORJ
ZLLFKXFNZLLQXQFKXFNDGDSWHUDYDLODEOH
/*
* nunchuck_lines sketch
* sends data to Processing to draw line that follows nunchuk movement
*/
#include <Wire.h> // initialize wire
#include "nunchuck_funcs.h"
byte accx;
void setup()
{
Serial.begin(9600);
nunchuck_setpowerpins();
nunchuck_init();
}
void loop()
{
nunchuck_get_data();
accx = nunchuck_accelx();
if( accx >= 75 && accx <= 185)
{
// map returns a value from 0 to 63 for values from 75 to 185
byte y = map(accx, 75, 185, 0, 63);
Serial.print(y);
}
delay(100); // the time in milliseconds between redraws
}
Discussion
,&LVRIWHQXVHGLQFRPPHUFLDOSURGXFWVVXFKDVWKHQXQFKXFNIRUFRPPXQLFDWLRQ
EHWZHHQGHYLFHV7KHUHDUHQRRIILFLDOGDWDVKHHWVIRUWKLVGHYLFHEXWWKHQXQFKXFN
VLJQDOLQJ ZDV DQDO\]HG UHYHUVH HQJLQHHUHG WR GHWHUPLQH WKH FRPPDQGV QHHGHG WR
FRPPXQLFDWHZLWKLW
<RXFDQXVHWKHIROORZLQJ3URFHVVLQJVNHWFKWRGLVSOD\DOLQHWKDWIROORZVWKHQXQFKXFN
PRYHPHQWDVVKRZQLQ)LJXUH VHH&KDSWHUIRUPRUHRQXVLQJ3URFHVVLQJWR
UHFHLYH$UGXLQRVHULDOGDWDDOVRVHH&KDSWHUIRUDGYLFHRQVHWWLQJXSDQGXVLQJ3UR
FHVVLQJZLWK$UGXLQR // Processing sketch to draw line that follows nunchuck data
import processing.serial.*;
Serial myPort; // Create object from Serial class
public static final short portIndex = 1;
void setup()
{
398 | Chapter 13:ಗCommunicating Using I2C and SPI
size(200, 200);
// Open whatever port is the one you're using - See Chapter 4
myPort = new Serial(this,Serial.list()[portIndex], 9600);
}
void draw()
{
if ( myPort.available() > 0) {
int y = myPort.read();
background(255);
line(0,63-y,127,y);
}
}
// If data is available,
// read it and store it in val
// Set background to white
// draw the line
)LJXUH1XQFKXFNPRYHPHQWUHSUHVHQWHGE\WLOWHGOLQHLQ3URFHVVLQJ
7KHVNHWFKLQFOXGHVWKH:LUHOLEUDU\IRU,&FRPPXQLFDWLRQDQGWKH nunchuck_funcs
FRGHIURPWKHHDUOLHUOLQN
#include <Wire.h> // initialize wire
#include "nunchuck_funcs.h"
:LUHKLVWKH,&OLEUDU\WKDWLVLQFOXGHGZLWKWKH$UGXLQRUHOHDVH
QXQFKXFNBIXQFVKLVWKHQDPHRIWKHOLEUDU\IRUFRPPXQLFDWLQJZLWKWKHQXQFKXFN
XVLQJ,&
7KHOLEUDU\KLGHVWKH,&LQWHUIDFHEXWKHUHLVDQRYHUYLHZRIKRZWKLVOLEUDU\XVHV,&
7KH nunchuck_setpowerpinsIXQFWLRQLVXVHGWRSURYLGHSRZHUWKURXJKDQDORJSLQV
DQG7KLVLVRQO\QHHGHGLIWKHQXQFKXFNDGDSWHULVSURYLGLQJWKHSRZHUVRXUFH7KH
FRGHVHWVWKHVHSLQVDVRXWSXWVZLWKSLQ LOWDQGSLQHIGH8VLQJGLJLWDOSLQVDVD
SRZHUVRXUFHLVQRWXVXDOO\UHFRPPHQGHGXQOHVV\RXDUHFHUWDLQDVZLWKWKHQXQ
FKXFNWKDWWKHGHYLFHEHLQJSRZHUHGZLOOQRWH[FHHGDSLQ¦VPD[LPXPFXUUHQWFDSD
ELOLW\ P$VHH&KDSWHU 13.2 Using the Wii Nunchuck Accelerometer | 399
nunchuck_initHVWDEOLVKHV,&FRPPXQLFDWLRQZLWKWKHQXQFKXFNKHUHLVWKHFRGHIRU
WKLVIXQFWLRQ
// initialize the I2C system, join the I2C bus,
// and tell the nunchuck we're talking to it
static void nunchuck_init()
{
Wire.begin();
// join I2C bus as master
Wire.beginTransmission(0x52);// transmit to device 0x52
Wire.send(0x40);
// sends memory address
Wire.send(0x00);
// sends a zero.
Wire.endTransmission();
}
,&FRPPXQLFDWLRQVWDUWVZLWKWire.begin(),QWKLVH[DPSOH$UGXLQRDVWKHPDVWHU
LVUHVSRQVLEOHIRULQLWLDOL]LQJWKHGHVLUHGVODYHGHYLFHWKHQXQFKXFNRQDGGUHVV[
7KHIROORZLQJOLQHWHOOVWKH:LUHOLEUDU\WRSUHSDUHWRVHQGDPHVVDJHWRWKHGHYLFHDW
KH[DGHFLPDODGGUHVV [ beginTransmission(0x52);
,& GRFXPHQWDWLRQ W\SLFDOO\ KDV DGGUHVVHV VKRZQ XVLQJ WKHLU
KH[DGHFLPDO YDOXHV VR LW¦V FRQYHQLHQW WR XVH WKLV QRWDWLRQ LQ \RXU
VNHWFK
Wire.sendSXWVWKHJLYHQYDOXHVLQWRDEXIIHUZLWKLQWKH:LUHOLEUDU\ZKHUHGDWDLVVWRUHG
XQWLOWire.endTransmissionLVFDOOHGWRDFWXDOO\GRWKHVHQGLQJ
nunchuck_get_dataLVXVHGWRUHFHLYHGDWDIURPWKHQXQFKXFN
// returns 1 on successful read. returns 0 on failure
int nunchuck_get_data()
{
int cnt=0;
Wire.requestFrom (0x52, 6);// request data from nunchuck
while (Wire.available ()) {
// receive byte as an integer
nunchuck_buf[cnt] = nunchuck_decode_byte(Wire.receive());
cnt++;
}
nunchuck_send_request(); // send request for next data payload
// If we received the 6 bytes, then go print them
if (cnt >= 5) {
return 1;
// success
}
return 0;
//failure
}
7KLVXVHVWKH:LUHOLEUDU\ requestFromIXQFWLRQWRJHWVL[E\WHVRIGDWDIURPGHYLFH
[ WKHQXQFKXFN 400 | Chapter 13:ಗCommunicating Using I2C and SPI
7KHQXQFKXFNUHWXUQVLWVGDWDXVLQJVL[E\WHVDVIROORZV
Byte number
Description
Byte 1
X-axis analog joystick value
Byte 2
Y-axis analog joystick value
Byte 3
X-axis acceleration value
Byte 4
Y-axis acceleration value
Byte 5
Z-axis acceleration value
Byte 6
Button states and least significant bits of acceleration
Wire.available ZRUNV OLNH Serial.available VHH &KDSWHU WR LQGLFDWH KRZ PDQ\
E\WHVKDYHEHHQUHFHLYHGEXWRYHUWKH,&LQWHUIDFHUDWKHUWKDQWKHVHULDOLQWHUIDFH
,I GDWD LV DYDLODEOH LW LV UHDG XVLQJ Wire.receive DQG WKHQ GHFRGHG XVLQJ
nunchuck_decode_byte'HFRGLQJLVUHTXLUHGWRFRQYHUWWKHYDOXHVVHQWLQWRQXPEHUV
WKDWDUHXVDEOHE\\RXUVNHWFKDQGWKHVHDUHVWRUHGLQDEXIIHU QDPHGnunchuck_buf $UHTXHVWLVVHQWIRUWKHQH[WVL[E\WHVRIGDWDVRWKDWLWZLOOEHUHDG\DQGZDLWLQJIRU
WKHQH[WFDOOWRJHWGDWD
accx
= nunchuck_accelx();
7KHIXQFWLRQnunchuck_accelxLVXVHGWRJHWWKHYDOXHRIDFFHOHUDWLRQLQWKH[D[LVIURP
WKHQXQFKXFNDQGVWRUHLWLQWKHYDULDEOHaccx
13.3 Interfacing to an External Real-Time Clock
Problem
<RXZDQWWRXVHWKHWLPHRIGD\SURYLGHGE\DQH[WHUQDOUHDOWLPHFORFN 57& Solution
7KLVVROXWLRQXVHVWKH:LUHOLEUDU\WRDFFHVVDQ57&,WXVHVWKHVDPHKDUGZDUHDVLQ
5HFLSH)LJXUHVKRZVWKHFRQQHFWLRQV
/*
* I2C_RTC sketch
* example code for using Wire library to access real-time clock
*
*/
#include <Wire.h>
const byte DS1307_CTRL_ID = 0x68; // address of the DS1307 real-time clock
const byte NumberOfFields = 7; // the number of fields (bytes) to request from
the RTC
13.3 Interfacing to an External Real-Time Clock | 401
int Second ;
int Minute;
int Hour;
int Day;
int Wday;
int Month;
int Year;
void setup() {
Serial.begin(9600);
Wire.begin();
}
void loop()
{
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x00);
Wire.endTransmission();
// request the 7 data fields
(secs, min, hr, dow, date, mth, yr)
Wire.requestFrom(DS1307_CTRL_ID, NumberOfFields);
Second = bcd2dec(Wire.receive() & 0x7f);
Minute = bcd2dec(Wire.receive() );
Hour
= bcd2dec(Wire.receive() & 0x3f); // mask assumes 24hr clock
Wday
= bcd2dec(Wire.receive() );
Day
= bcd2dec(Wire.receive() );
Month = bcd2dec(Wire.receive() );
Year
= bcd2dec(Wire.receive() );
Year
= Year + 2000; // RTC year 0 is year 2000
}
digitalClockDisplay(); // display the time
delay(1000);
// Convert Binary Coded Decimal (BCD) to Decimal
byte bcd2dec(byte num)
{
return ((num/16 * 10) + (num % 16));
}
void digitalClockDisplay(){
// digital clock display of the time
Serial.print(Hour);
printDigits(Minute);
printDigits(Second);
Serial.print(" ");
Serial.print(Day);
Serial.print(" ");
Serial.print(Month);
Serial.print(" ");
Serial.print(Year);
Serial.println();
402 | Chapter 13:ಗCommunicating Using I2C and SPI
}
// utility function for clock display: prints preceding colon and leading 0
void printDigits(int digits){
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
)LJXUH&RQQHFWLQJDUHDOWLPHFORFN
Discussion
$OWKRXJKWKLVUHFLSHXVHVWKHVDPHKDUGZDUHDVLQ5HFLSHLWDFFHVVHVWKHKDUGZDUH
WKURXJKH[SOLFLW,&FDOOVLQVWHDGRIWKURXJKDOLEUDU\VRWKDWWKHLQWHUDFWLRQEHWZHHQ
$UGXLQRDQGWKH,&FORFNFDQEHFOHDUO\VHHQ
7KHIROORZLQJOLQHLQLWLDOL]HVWKH57&
Wire.beginTransmission(DS1307_CTRL_ID);
Wire.send(0x00);
Wire.endTransmission();
7KHrequestFromPHWKRGRIWKH:LUHOLEUDU\LVXVHGWRUHTXHVWVHYHQWLPHILHOGVIURP
WKHFORFN DS1307_CTRL_IDLVWKHDGGUHVVLGHQWLILHURIWKHFORFN Wire.requestFrom(DS1307_CTRL_ID, NumberOfFields);
7KH GDWH DQG WLPH YDOXHV DUH REWDLQHG E\ PDNLQJ VHYHQ FDOOV WR WKH Wire.receive
PHWKRG
bcd2dec(Wire.receive()
13.3 Interfacing to an External Real-Time Clock | 403
7KHYDOXHVUHWXUQHGE\WKHPRGXOHDUH%LQDU\&RGHG'HFLPDO %&' YDOXHVVRWKH
IXQFWLRQ bcd2decLVXVHGWRFRQYHUWHDFKYDOXHDVLWLVUHFHLYHG %&'LVDPHWKRGIRU
VWRULQJGHFLPDOYDOXHVLQIRXUELWVRIGDWD
See Also
5HFLSHSURYLGHVGHWDLOVRQKRZWRVHWWKHWLPHRQWKHFORFN
13.4 Adding External EEPROM Memory
Problem
<RXQHHGPRUHSHUPDQHQWGDWDVWRUDJHWKDQ$UGXLQRKDVRQERDUGDQG\RXZDQWWR
XVHDQH[WHUQDOPHPRU\FKLSWRLQFUHDVHWKHFDSDFLW\
Solution
7KLV UHFLSH XVHV WKH /& ,&HQDEOHG VHULDO ((3520 IURP 0LFURFKLS )LJ
XUHVKRZVWKHFRQQHFWLRQV
)LJXUH,&((3520FRQQHFWLRQV
7KLVUHFLSHSURYLGHVIXQFWLRQDOLW\VLPLODUWRWKH$UGXLQR((3520OLEUDU\ VHH5HF
LSH EXW LW XVHV DQ H[WHUQDO ((3520 FRQQHFWHG XVLQJ ,& WR SURYLGH JUHDWO\
LQFUHDVHGVWRUDJHFDSDFLW\
404 | Chapter 13:ಗCommunicating Using I2C and SPI
/*
* I2C EEPROM sketch
* this version for 24LC128
*/
#include <Wire.h>
const byte EEPROM_ID = 0x50;
// I2C address for 24LC128 EEPROM
// first visible ASCII character '!' is number 33:
int thisByte = 33;
void setup()
{
Serial.begin(9600);
Wire.begin();
Serial.println("Writing 1024 bytes to EEPROM");
for(int i=0; i < 1024; i++)
{
I2CEEPROM_Write(i, thisByte);
// go on to the next character
thisByte++;
if(thisByte == 126)
// you could also use if (thisByte == '~')
thisByte = 33;
// start over
}
Serial.println("Reading 1024 bytes from EEPROM");
int thisByte = 33;
for(int i=0; i < 1024; i++)
{
char c = I2CEEPROM_Read(i);
if( c != thisByte)
{
Serial.println("read error");
break;
}
else
{
Serial.print(c);
}
thisByte++;
if(thisByte == 126)
{
Serial.println();
thisByte = 33;
// start over on a new line
}
}
Serial.println();
}
void loop()
{
}
13.4 Adding External EEPROM Memory | 405
// This function is similar to EEPROM.write()
void I2CEEPROM_Write( unsigned int address, byte data )
{
Wire.beginTransmission(EEPROM_ID);
Wire.send((int)highByte(address) );
Wire.send((int)lowByte(address) );
Wire.send(data);
Wire.endTransmission();
delay(5); // wait for the I2C EEPROM to complete the write cycle
}
// This function is similar to EEPROM.read()
byte I2CEEPROM_Read(unsigned int address )
{
byte data;
Wire.beginTransmission(EEPROM_ID);
Wire.send((int)highByte(address) );
Wire.send((int)lowByte(address) );
Wire.endTransmission();
Wire.requestFrom(EEPROM_ID,(byte)1);
while(Wire.available() == 0) // wait for data
;
data = Wire.receive();
return data;
}
Discussion
7KLVUHFLSHVKRZVWKH/&ZKLFKKDV.RIPHPRU\DOWKRXJKWKHUHDUHVLPLODU
FKLSV ZLWK KLJKHU DQG ORZHU FDSDFLWLHV WKH PLFURFKLS OLQN LQ WKLV UHFLSH¦V 6HH $OVR
VHFWLRQKDVDFURVVUHIHUHQFH 7KHFKLS¦VDGGUHVVLVVHWXVLQJWKHWKUHHSLQVPDUNHG
£$¤WKURXJK£$¤DQGLVLQWKHUDQJH[WR[DVVKRZQLQ7DEOH
7DEOH$GGUHVVYDOXHVIRU/&
A0
A1
A2
Address
Gnd
Gnd
Gnd
0x50
+5V
Gnd
Gnd
0x51
Gnd
+5V
Gnd
0x52
+5V
+5V
Gnd
0x53
Gnd
Gnd
+5V
0x54
+5V
Gnd
+5V
0x55
+5V
+5V
Gnd
0x56
+5V
+5V
+5V
0x57
8VHRIWKH:LUHOLEUDU\LQWKLVUHFLSHLVVLPLODUWRLWVXVHLQ5HFLSHVDQGVR
UHDGWKURXJKWKRVHIRUDQH[SODQDWLRQRIWKHFRGHWKDWLQLWLDOL]HVDQGUHTXHVWVGDWDIURP
DQ,&GHYLFH
406 | Chapter 13:ಗCommunicating Using I2C and SPI
7KHZULWHDQGUHDGRSHUDWLRQVWKDWDUHVSHFLILFWRWKH((3520DUHFRQWDLQHGLQWKH
IXQFWLRQV i2cEEPROM_Write DQG i2cEEPROM_Read 7KHVH RSHUDWLRQV VWDUW ZLWK D
Wire.beginTransmissionWRWKHGHYLFH¦V,&DGGUHVV7KLVLVIROORZHGE\DE\WHYDOXH
LQGLFDWLQJWKHPHPRU\ORFDWLRQIRUWKHUHDGRUZULWHRSHUDWLRQ,QWKHZULWHIXQFWLRQ
WKHDGGUHVVLVIROORZHGE\WKHGDWDWREHZULWWHQ¢LQWKLVH[DPSOHRQHE\WHLVZULWWHQ
WRWKHPHPRU\ORFDWLRQ
7KH UHDG RSHUDWLRQ VHQGV D PHPRU\ ORFDWLRQ WR WKH ((3520 IROORZHG E\
Wire.requestFrom(EEPROM_ID,(byte)1);7KLVUHWXUQVRQHE\WHRIGDWDIURPWKHPHPRU\
DWWKHDGGUHVVMXVWVHW
,I\RXQHHGWRVSHHGXSZULWHV\RXFDQUHSODFHWKHPVGHOD\ZLWKDVWDWXVFKHFNWR
GHWHUPLQHLIWKH((3520LVUHDG\WRZULWHDQHZE\WH6HHWKH£$FNQRZOHGJH3ROOLQJ¤
WHFKQLTXHGHVFULEHGLQ6HFWLRQRIWKHGDWDVKHHW<RXFDQDOVRZULWHGDWDLQSDJHVRI
E\WHVUDWKHUWKDQLQGLYLGXDOO\GHWDLOVDUHLQ6HFWLRQRIWKHGDWDVKHHW
7KHFKLSUHPHPEHUVWKHDGGUHVVLWLVJLYHQDQGZLOOPRYHWRWKHQH[WVHTXHQWLDODGGUHVV
HDFKWLPHDUHDGRUZULWHLVSHUIRUPHG,I\RXDUHUHDGLQJPRUHWKDQDVLQJOHE\WH\RX
FDQVHWWKHVWDUWDGGUHVVDQGWKHQSHUIRUPPXOWLSOHUHTXHVWVDQGUHFHLYHV
7KH:LUHOLEUDU\FDQUHDGRUZULWHXSWRE\WHVLQDVLQJOHUHTXHVW
$WWHPSWLQJ WRUHDG RU ZULWH PRUHWKDQ WKLV FDQUHVXOWLQE\WHVEHLQJ
GLVFDUGHG
7KHSLQPDUNHG£:3¤LVIRUVHWWLQJZULWHSURWHFWLRQ,WLVFRQQHFWHGWRJURXQGLQWKH
FLUFXLWKHUHWRHQDEOHWKH$UGXLQRWRZULWHWRPHPRU\&RQQHFWLQJLWWR9SUHYHQWV
DQ\ZULWHVIURPWDNLQJSODFH7KLVFRXOGEHXVHGWRZULWHSHUVLVWHQWGDWDWRPHPRU\
DQGWKHQSUHYHQWLWIURPEHLQJRYHUZULWWHQDFFLGHQWDOO\
See Also
7KH /& GDWD VKHHW KWWSZZPLFURFKLSFRPGRZQORDGVHQGHYLFHGRFQ
SGI
,I\RXQHHGWRVSHHGXSZULWHV\RXFDQUHSODFHWKHPVGHOD\ZLWKDVWDWXVFKHFNWR
GHWHUPLQHLIWKH((3520LVUHDG\WRZULWHDQHZE\WH6HHWKH£$FNQRZOHGJH3ROOLQJ¤
WHFKQLTXHGHVFULEHGLQ6HFWLRQRIWKHGDWDVKHHW
$FURVVUHIHUHQFHRIVLPLODU,&((3520VZLWKDZLGHUDQJHRIFDSDFLWLHVLVDYDLODEOH
DWKWWSZZPLFURFKLSFRPGRZQORDGVHQ'HYLFH'RFGSGI
$VKLHOGLVDYDLODEOHWKDWFRPELQHVUHDGLQJWHPSHUDWXUHVWRULQJLQ((3520DQG
VHJPHQWGLVSOD\KWWSVWRUHJUDYLWHFKXVVHJPHQWVKLHOGKWPO
13.4 Adding External EEPROM Memory | 407
13.5 Reading Temperature with a Digital Thermometer
Problem
<RXZDQWWRPHDVXUHWHPSHUDWXUHSHUKDSVXVLQJPRUHWKDQRQHGHYLFHVR\RXFDQ
WDNHUHDGLQJVLQGLIIHUHQWORFDWLRQV
Solution
7KLVUHFLSHXVHVWKH703WHPSHUDWXUHVHQVRUIURP7H[DV,QVWUXPHQWV<RXFRQQHFW
DVLQJOH703DVVKRZQLQ)LJXUH
/*
* I2C_Temperature sketch
* I2C access the TMP75 digital Thermometer
*
*/
#include <Wire.h>
const byte TMP75_ID = 0x49; // address of the TMP75
const byte NumberOfFields = 2; // the number of fields (bytes) to request
// high byte of temperature (this is the signed integer value in degrees c)
char tempHighByte;
// low byte of temperature (this is the fractional temperature)
char tempLowByte;
float temperature;
// this will hold the floating-point temperature
void setup() {
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(TMP75_ID);
Wire.send(1);
// 1 is the configuration register
// set default configuration, see data sheet for significance of config bits
Wire.send(0);
Wire.endTransmission();
Wire.beginTransmission(TMP75_ID);
Wire.send(0);
// set pointer register to 0 (this is the 12-bit temperature)
Wire.endTransmission();
}
void loop()
{
Wire.requestFrom(TMP75_ID, NumberOfFields);
tempHighByte = Wire.receive();
tempLowByte = Wire.receive();
Serial.print("Integer temperature is ");
408 | Chapter 13:ಗCommunicating Using I2C and SPI
Download from Wow! eBook <www.wowebook.com>
Serial.print(tempHighByte, DEC);
Serial.print(",");
}
// least significant 4 bits of LowByte is the fractional temperature
int t = word( tempHighByte, tempLowByte) / 16 ;
temperature = t / 16.0; // convert the value to a float
Serial.println(temperature);
delay(1000);
)LJXUH703,&WKHUPRPHWHU
Discussion
$VZLWKDOOWKH,&GHYLFHVLQWKLVFKDSWHUVLJQDOLQJLVWKURXJKWKHWZRZLUH6&/DQG
6'$SLQV3RZHUDQGJURXQGQHHGWREHFRQQHFWHGWRWKHGHYLFHDVZHOOWRSRZHULW
SetupVHQGVGDWDWRFRQILJXUHWKHGHYLFHIRUQRUPDORSHUDWLRQ¢WKHUHDUHDQXPEHURI
RSWLRQVIRUVSHFLDOL]HGDSSOLFDWLRQV LQWHUUXSWVSRZHUGRZQHWF EXWWKHYDOXHXVHG
KHUHLVIRUQRUPDOPRGHZLWKDSUHFLVLRQRI&
7RJHWWKHGHYLFHWRVHQGWKHWHPSHUDWXUHZLWKWKH$UGXLQR DVWKHPDVWHU WKHFRGH
LQloopWHOOVWKHVODYH DWWKHDGGUHVVJLYHQE\WKHFRQVWDQWTMP75_ID WKDWLWZDQWVWZR
E\WHVRIGDWD
Wire.requestFrom(TMP75_ID, NumberOfFields);
13.5 Reading Temperature with a Digital Thermometer | 409
Wire.receiveJHWVWKHWZRE\WHVRILQIRUPDWLRQ WKHGDWDVKHHWKDVPRUHGHWDLORQKRZ
GDWDLVUHTXHVWHGIURPWKLVGHYLFH tempHighByte = Wire.receive();
tempLowByte = Wire.receive();
7KHILUVWE\WHLVWKHLQWHJHUYDOXHRIWKHWHPSHUDWXUHLQGHJUHHV&HOVLXV7KHVHFRQG
E\WHFRQWDLQVIRXUVLJQLILFDQWELWVLQGLFDWLQJWKHIUDFWLRQDOWHPSHUDWXUH
7KHWZRE\WHVDUHFRQYHUWHGWRDELWZRUG VHH&KDSWHU DQGWKHQVKLIWHGE\IRXU
WRIRUPWKHELWQXPEHU$VWKHILUVWIRXUELWVDUHWKHIUDFWLRQDOWHPSHUDWXUHWKHYDOXH
LVDJDLQVKLIWHGE\IRXUWRJHWWKHIORDWLQJSRLQWYDOXH
7KH713FDQEHFRQILJXUHGIRUHLJKWGLIIHUHQWDGGUHVVHVDOORZLQJHLJKWGHYLFHVWR
EHFRQQHFWHGWRWKHVDPHEXV VHH)LJXUH 7KLVVNHWFKXVHV,&DGGUHVV[
WKH703DGGUHVVSLQVODEHOHG£$¤ FRQQHFWHGWR9DQG$DQG$FRQQHFWHGWR
*QG 7DEOHVKRZVWKHFRQQHFWLRQVIRUWKHHLJKWDGGUHVVHV
)LJXUH0XOWLSOHGHYLFHVZLWK6'$DQG6&/FRQQHFWHGLQSDUDOOHOZLWKGLIIHUHQWDGGUHVVHV
7DEOH$GGUHVVYDOXHVIRU703
A0
A1
A2
Address
Gnd
Gnd
Gnd
0x48
+5V
Gnd
Gnd
0x49
Gnd
+5V
Gnd
0x4A
+5V
+5V
Gnd
0x4B
Gnd
Gnd
+5V
0x4C
+5V
Gnd
+5V
0x4D
+5V
+5V
Gnd
0x4E
+5V
+5V
+5V
0x4F
410 | Chapter 13:ಗCommunicating Using I2C and SPI
:KHQFRQQHFWLQJPRUHWKDQRQH,&GHYLFH\RXZLUHDOOWKH6'$OLQHVWRJHWKHUDQG
DOOWKH6&/OLQHVWRJHWKHU(DFKGHYLFHFRQQHFWVWRSRZHUDQGVKRXOGKDYHE\SDVV
FDSDFLWRUV7KH*QGOLQHVPXVWEHFRQQHFWHGWRJHWKHUHYHQLIWKHGHYLFHVXVHVHSDUDWH
SRZHUVXSSOLHV HJEDWWHULHV 7KLVVNHWFKSULQWVWKHWHPSHUDWXUHRIWZRGHYLFHVZLWKFRQVHFXWLYHDGGUHVVHVVWDUWLQJ
IURP[
#include <Wire.h>
const byte TMP75_ID = 0x49; // address of the first TMP75
const byte NumberOfFields = 2; // the number of fields (bytes) to request
const byte NumberOfDevices = 2; // the number of TMP75 devices (with consecutive
addresses)
char tempHighByte; // high byte of temperature (this is the signed integer
value in degrees c)
char tempLowByte;
// low byte of temperature (this is the fractional
temperature)
float temperature;
// this will hold the floating-point temperature
void setup() {
Serial.begin(9600);
Wire.begin();
for(int i=0; i < NumberOfDevices; i++)
{
Wire.beginTransmission(TMP75_ID+i);
Wire.send(1);
// set default configuration, see data sheet for significance of config bits
Wire.send(0);
Wire.endTransmission();
Wire.beginTransmission(TMP75_ID+i);
Wire.send(0);
// set pointer register to 0 (this is the 12-bit temperature)
Wire.endTransmission();
}
}
void loop()
{
for(int i=0; i < NumberOfDevices; i++)
{
byte id = TMP75_ID + i; // address IDs are consecutive
Wire.requestFrom(id, NumberOfFields);
tempHighByte = Wire.receive();
tempLowByte = Wire.receive();
Serial.print(id,HEX); // print the device address
Serial.print(": integer temperature is ");
Serial.print(tempHighByte, DEC);
13.5 Reading Temperature with a Digital Thermometer | 411
Serial.print(",");
// least significant 4 bits of LowByte is the fractional temperature
int t = word( tempHighByte, tempLowByte) / 16 ;
temperature = t / 16.0; // convert the value to a float
Serial.println(temperature);
}
delay(1000);
}
<RXFDQDGGPRUHGHYLFHVE\FKDQJLQJWKHFRQVWDQW NumberOfDevicesDQGZLULQJWKH
GHYLFHVWRXVHDGGUHVVHVWKDWDUHFRQVHFXWLYHLQWKLVH[DPSOHVWDUWLQJIURP[
7KH$OHUWOLQH SLQ FDQEHSURJUDPPHGWRSURYLGHDVLJQDOZKHQWKH
WHPSHUDWXUHUHDFKHVDWKUHVKROG6HHWKHGDWDVKHHWIRUGHWDLOVLI\RX
ZDQWWRXVHWKLVIHDWXUH
See Also
7KH703GDWDVKHHWKWWSIRFXVWLFRPGRFVSURGIROGHUVSULQWWPSKWPO
6HH5HFLSHIRUPRUHRQWKHwordIXQFWLRQ
13.6 Driving Four 7-Segment LEDs Using Only Two Wires
Problem
<RXZDQWWRXVHDPXOWLGLJLWVHJPHQWGLVSOD\DQG\RXQHHGWRPLQLPL]HWKHQXPEHU
RI$UGXLQRSLQVUHTXLUHGIRUWKHFRQQHFWLRQV
Solution
7KLVUHFLSHXVHVWKH*UDYLWHFKVHJPHQWGLVSOD\VKLHOGWKDWKDVWKH6$$,&WR
VHJPHQWGULYHUIURP3KLOLSV VHH)LJXUH )LJXUH*UDYLWHFK,&VKLHOG
412 | Chapter 13:ಗCommunicating Using I2C and SPI
7KLVVLPSOHVNHWFKOLJKWVHDFKVHJPHQWLQVHTXHQFHRQDOOWKHGLJLWV
/*
* I2C_7Segment sketch
*/
#include <Wire.h>
const byte LedDrive = 0x38;
/* I2C address for 7-Segment */
int segment,decade;
void setup() {
Serial.begin(9600);
Wire.begin();
/* Join I2C bus */
Wire.beginTransmission(LedDrive);
Wire.send(0);
Wire.send(B01000111); // show digits 1 through 4, use maximum drive current
Wire.endTransmission();
}
void loop()
{
for (segment = 0; segment < 8; segment++)
{
Wire.beginTransmission(LedDrive);
Wire.send(1);
for (decade = 0 ; decade < 4; decade++)
{
byte bitValue = bit(segment);
Wire.send(bitValue);
}
Wire.endTransmission();
delay (250);
}
}
Discussion
7KH6$$FKLS XVLQJDGGUHVV[ LVLQLWLDOL]HGLQsetup7KHYDOXHXVHGFRQILJ
XUHVWKHFKLSWRGLVSOD\IRXUGLJLWVXVLQJPD[LPXPGULYHFXUUHQW VHHWKHGDWDVKHHW
VHFWLRQRQFRQWUROELWVIRUFRQILJXUDWLRQGHWDLOV 7KH loopFRGHOLJKWVHDFKVHJPHQWLQVHTXHQFHRQDOOWKHGLJLWV7KH Wire.send(1);
FRPPDQGWHOOVWKHFKLSWKDWWKHQH[WUHFHLYHGE\WHZLOOGULYHWKHILUVWGLJLWDQGVXEVH
TXHQWE\WHVZLOOGULYHVHTXHQWLDOGLJLWV
,QLWLDOO\DYDOXHRI1LVVHQWIRXUWLPHVDQGWKHFKLSOLJKWVWKH£$¤ WRS VHJPHQWRQDOO
IRXUGLJLWV 6HH&KDSWHUIRUPRUHRQXVLQJWKHbitIXQFWLRQ
7KHYDOXHRIsegmentLVLQFUHPHQWHGLQWKHforORRSDQGWKLVVKLIWVWKHbitValueWROLJKW
WKHQH[W/('VHJPHQWLQVHTXHQFH
13.6 Driving Four 7-Segment LEDs Using Only Two Wires | 413
(DFKELWSRVLWLRQFRUUHVSRQGVWRDVHJPHQWRIWKHGLJLW7KHVHELWSRVLWLRQYDOXHVFDQ
EHFRPELQHGWRFUHDWHDQXPEHUWKDWZLOOWXUQRQPRUHWKDQRQHVHJPHQW
7KH IROORZLQJ VNHWFK ZLOO GLVSOD\ D FRXQW IURP WR 7KH DUUD\ FDOOHG
lookup[10]FRQWDLQVWKHYDOXHVQHHGHGWRFUHDWHWKHQXPHUDOVIURPWRLQDVHJPHQW
#include <Wire.h>
const byte LedDrive = 0x38;
/* I2C address for 7-Segment */
// lookup array containing segments to light for each digit
const int lookup[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
int count;
void setup()
{
Wire.begin();
// delay(500);
}
// join I2C bus (address optional for master)
void loop()
{
Wire.beginTransmission(LedDrive);
Wire.send(0);
Wire.send(B01000111); // init the 7-segment driver - see data sheet
Wire.endTransmission();
// show numbers from 0 to 9999
for (count = 0; count <= 9999; count++)
{
displayNumber(count);
delay(10);
}
}
// function to display up to four digits on a 7-segment I2C display
void displayNumber( int number)
{
number = constrain(number, 0, 9999);
Wire.beginTransmission(LedDrive);
Wire.send(1);
for(int i =0; i < 4; i++)
{
byte digit = number % 10;
{
Wire.send(lookup[digit]);
}
number = number / 10;
}
Wire.endTransmission();
}
414 | Chapter 13:ಗCommunicating Using I2C and SPI
7KHIXQFWLRQdisplayNumberLVJLYHQDQXPEHUWREHGLVSOD\HG7KHYDOXHWREHVHQWIRU
HDFKVHJPHQWLQWKHforORRSLVKDQGOHGLQWZRVWHSV)LUVWWKHGLJLWLVGHWHUPLQHGE\
WDNLQJWKHUHPDLQGHUDIWHUGLYLGLQJWKHQXPEHUE\7KLVYDOXH DGLJLWIURPWKURXJK
LVXVHGWRJHWWKHELWSDWWHUQIURPWKHlookup[]DUUD\WROLJKWWKHVHJPHQWVQHHGHGWR
GLVSOD\WKHGLJLW
(DFKVXFFHVVLYHGLJLWLVREWDLQHGE\ORRNLQJDWWKHUHPDLQGHUDIWHUGLYLGLQJWKHQXPEHU
E\:KHQWKHUHPDLQGHUEHFRPHVDOOGLJLWVKDYHEHHQVHQW
<RXFDQVXSSUHVVOHDGLQJ]HURV XQQHFHVVDU\]HURVLQIURQWRIGLJLWV E\FKDQJLQJWKH
displayNumberIXQFWLRQDVIROORZV
// function to display up to four digits on a 7-segment I2C display
void displayNumber( int number)
{
number = constrain(number, 0, 9999);
Wire.beginTransmission(LedDrive);
Wire.send(1);
for(int i =0; i < 4; i++)
{
byte digit = number % 10;
// this check will suppress leading zeros
if(number == 0 && i > 0)
{
Wire.send(0); // this suppresses leading zeros, it turns off all segments
}
else
{
Wire.send(lookup[digit]);
}
number = number / 10;
}
Wire.endTransmission();
}
7KHIROORZLQJVWDWHPHQWFKHFNVLIWKHYDOXHLV0DQGLW¦VQRWWKHILUVW OHDVWVLJQLILFDQW
GLJLW
if(number == 0 && i > 0)
,IVRLWVHQGVDYDOXHRI0ZKLFKWXUQVRIIDOOVHJPHQWVIRUWKDWGLJLW7KLVVXSSUHVVHV
OHDGLQJ]HURVEXWLWGLVSOD\VDVLQJOH]HURLIWKHQXPEHUSDVVHGWRWKHIXQFWLRQZDV0
See Also
6$$GDWDVKHHWKWWSZZZQ[SFRPGRFXPHQWVGDWDBVKHHW6$$B&19SGI
$VKLHOGLVDYDLODEOHWKDWFRPELQHVUHDGLQJWHPSHUDWXUHVWRULQJLQ((3520DQG
VHJPHQWGLVSOD\KWWSVWRUHJUDYLWHFKXVVHJPHQWVKLHOGKWPO
13.6 Driving Four 7-Segment LEDs Using Only Two Wires | 415
13.7 Integrating an I2C Port Expander
Problem
<RXZDQWWRXVHPRUHLQSXWRXWSXWSRUWVWKDQ\RXUERDUGSURYLGHV
Solution
<RXFDQXVHDQH[WHUQDOSRUWH[SDQGHUVXFKDVWKH3&)$ZKLFKKDVHLJKWLQSXW
RXWSXWSLQVWKDWFDQEHFRQWUROOHGXVLQJ,&7KHVNHWFKFUHDWHVDEDUJUDSKZLWKHLJKW
/('V)LJXUHVKRZVWKHFRQQHFWLRQV
)LJXUH3&)$SRUWH[SDQGHUGULYLQJHLJKW/('V
7KHVNHWFKKDVWKHVDPHIXQFWLRQDOLW\DVGHVFULEHGLQ5HFLSHEXWLWXVHVWKH,&
SRUWH[SDQGHUWRGULYHWKH/('VVRWKDWRQO\WZRSLQVDUHUHTXLUHG
/*
* I2C_7segment
* Uses I2C port to drive a bar graph
* Turns on a series of LEDs proportional to a value of an analog sensor.
* see Recipe 7.5
*/
#include <Wire.h>
//address for PCF8574 with pins connected as shown in Figure 13-12
const int address = 0x38;
const int NbrLEDs = 8;
416 | Chapter 13:ಗCommunicating Using I2C and SPI
const int analogInPin = 0;
resistor
int sensorValue = 0;
int ledLevel = 0;
int ledBits = 0;
// Analog input pin connected to the variable
// value read from the sensor
// sensor value converted into LED 'bars'
// bits for each LED will be set to 1 to turn on LED
void setup()
{
Wire.begin(); // set up Arduino I2C support
Serial.begin(9600);
}
void loop() {
sensorValue = analogRead(analogInPin);
// read the analog in value
ledLevel = map(sensorValue, 0, 1023, 0, NbrLEDs); // map to number of LEDs
for (int led = 0; led < NbrLEDs; led++)
{
if (led < ledLevel ) {
bitWrite(ledBits,led, HIGH);
// turn on LED if less than the level
}
else {
bitWrite(ledBits,led, LOW);
// turn off LED if higher than the level
}
// send the value to I2C
Wire.beginTransmission(address);
Wire.send(ledBits);
Wire.endTransmission();
}
delay(100);
}
Discussion
7KHUHVLVWRUVVKRXOGEHRKPVRUPRUH VHH&KDSWHUIRULQIRUPDWLRQRQVHOHFWLQJ
UHVLVWRUV 7KH3&)$KDVDORZHUFDSDFLW\IRUGULYLQJ/('VWKDQ$UGXLQR,I
\RX QHHG PRUH FDSDFLW\ UHIHU WR WKH GDWD VKHHW IRU GHWDLOV VHH 5HF
LSHIRUDPRUHDSSURSULDWHGHYLFH
<RXFDQFKDQJHWKHDGGUHVVE\FKDQJLQJWKHFRQQHFWLRQVRIWKHSLQVPDUNHG£$¤
£$¤DQG£$¤DVVKRZQLQ7DEOH
13.7 Integrating an I2C Port Expander | 417
7DEOH$GGUHVVYDOXHVIRU3&)$
A0
A1
A2
Address
Gnd
Gnd
Gnd
0x38
+5V
Gnd
Gnd
0x39
Gnd
+5V
Gnd
0x3A
+5V
+5V
Gnd
0x3B
Gnd
Gnd
+5V
0x3C
+5V
Gnd
+5V
0x3D
+5V
+5V
Gnd
0x3E
+5V
+5V
+5V
0x3F
7RXVHWKHSRUWH[SDQGHUIRULQSXWUHDGDE\WHIURPWKHH[SDQGHUDVIROORZV
Wire.requestFrom(address, 1);
if(Wire.available())
{
data = Wire.receive();
Serial.println(data,BIN);
}
See Also
3&)GDWDVKHHWKWWSZZZQ[SFRPGRFXPHQWVGDWDBVKHHW3&)SGI
13.8 Driving Multidigit, 7-Segment Displays Using SPI
Problem
<RXZDQWWRFRQWUROVHJPHQWGLVSOD\VEXW\RXGRQ¦WZDQWWRXVHPDQ\SLQV
Solution
7KLV UHFLSH SURYLGHV VLPLODU IXQFWLRQDOLW\ WR 5HFLSH EXW LW RQO\ UHTXLUHV WKUHH
RXWSXWSLQV7KHWH[WKHUHH[SODLQVWKH63,FRPPDQGVXVHGWRFRPPXQLFDWHZLWKWKH
0$;GHYLFH)LJXUHVKRZVWKHFRQQHFWLRQV
*
SPI_Max7221_0019
*/
#include <SPI.h>
const int slaveSelect = 10; //pin used to enable the active slave
418 | Chapter 13:ಗCommunicating Using I2C and SPI
const int numberOfDigits = 2; // change to match the number of digits wired up
const int maxCount
= 99;
int count = 0;
void setup()
{
SPI.begin();
// initialize SPI
pinMode(slaveSelect, OUTPUT);
digitalWrite(slaveSelect,LOW); //select slave
// prepare the 7221 to display 7-segment data - see data sheet
sendCommand(12,1); // normal mode (default is shutdown mode);
sendCommand(15,0); // Display test off
sendCommand(10,8); // set medium intensity (range is 0-15)
sendCommand(11,numberOfDigits); // 7221 digit scan limit command
sendCommand(9,255); // decode command, use standard 7-segment digits
digitalWrite(slaveSelect,HIGH); //deselect slave
}
void loop()
{
displayNumber(count);
count = count + 1;
if( count > maxCount)
count = 0;
delay(100);
}
// function to display up to four digits on a 7-segment display
void displayNumber( int number)
{
for(int i = 0; i < numberOfDigits; i++)
{
byte character = number % 10; // get the value of the rightmost decade
// send digit number as command, first digit is command 1
sendCommand(numberOfDigits-i, character);
number = number / 10;
}
}
void sendCommand( int command, int value)
{
digitalWrite(slaveSelect,LOW); //chip select is active low
//2 byte data transfer to the 7221
SPI.transfer(command);
SPI.transfer(value);
digitalWrite(slaveSelect,HIGH); //release chip, signal end transfer
}
13.8 Driving Multidigit, 7-Segment Displays Using SPI | 419
)LJXUH&RQQHFWLRQVIRU0$;ZLWK/LWH2Q/7'*
Discussion
7KH0$;QHHGVDFRPPRQFDWKRGH/('7KHSLQRXWVLQ)LJXUHDUHIRUD
/LWH2Q/7'* -DPHFR 7KLVLVDWZRGLJLWVHJPHQW/('DQGWKH
FRUUHVSRQGLQJVHJPHQWVIRUHDFKGLJLWPXVWEHFRQQHFWHGWRJHWKHU)RUH[DPSOHWKH
GHFLPDOSRLQWLVRQSLQIRUGLJLWDQGSLQIRUGLJLW7KHILJXUHLQGLFDWHVWKDWSLQV
DQGDUHFRQQHFWHGWRJHWKHUDQGZLUHGWRWKH0$;SLQ
7KH0$;FDQGLVSOD\XSWRHLJKWGLJLWV RUDQ[PDWUL[ DQGLVFRQWUROOHGE\
VHQGLQJFRPPDQGVWKDWGHWHUPLQHZKLFK/('VHJPHQWLVOLW
$IWHULQLWLDOL]LQJWKHOLEUDU\WKH63,FRGHLVFRQWDLQHGZLWKLQWKHsendCommandIXQFWLRQ
%HFDXVH63,XVHVWKHVHOHFWVODYHZLUHFRQQHFWHGWRWKHFKLSWKHFKLSLVVHOHFWHGE\
VHWWLQJWKDWSLQLOW$OO63,FRPPDQGVDUHWKHQUHFHLYHGE\WKDWFKLSXQWLOLWLVVHWHIGH
SPI.transferLVWKHOLEUDU\IXQFWLRQIRUVHQGLQJDQ63,PHVVDJH7KLVFRQVLVWVRIWZR
SDUWVDQXPHULFDOFRGHWRVSHFLI\ZKLFKUHJLVWHUVKRXOGUHFHLYHWKHPHVVDJHIROORZHG
E\WKHDFWXDOGDWD7KHGHWDLOVIRUHDFK63,GHYLFHFDQEHIRXQGLQWKHGDWDVKHHW
SetupLQLWLDOL]HVWKHE\VHQGLQJFRPPDQGVWRZDNHXSWKHFKLS LWVWDUWVXSLQD
ORZSRZHUPRGH DGMXVWWKHGLVSOD\LQWHQVLW\VHWWKHQXPEHURIGLJLWVDQGHQDEOH
GHFRGLQJIRUVHJPHQWGLVSOD\V(DFKFRPPDQGFRQVLVWVRIDFRPPDQGLGHQWLILHU UH
IHUUHGWRDVDUHJLVWHULQWKHGDWDVKHHW DQGDYDOXHIRUWKDWFRPPDQG
420 | Chapter 13:ಗCommunicating Using I2C and SPI
Download from Wow! eBook <www.wowebook.com>
)RUH[DPSOHFRPPDQG UHJLVWHU LVIRULQWHQVLW\VRLWVHWVPHGLXPLQWHQVLW\ WKH
LQWHQVLW\UDQJHLVIURPWR sendCommand(10,8);
// set medium intensity (range is 0-15)
&RPPDQGQXPEHUVWKURXJKDUHXVHGWRFRQWUROWKHGLJLWV7KHIROORZLQJFRGH
ZRXOGOLJKWWKHVHJPHQWVWRGLVSOD\WKHQXPEHULQWKHILUVW OHIWPRVW GLJLW1RWHWKDW
GLJLWQXPEHUVVKRZQLQWKHGDWDVKHHW DQG)LJXUH VWDUWIURPVR\RXPXVW
UHPHPEHUWKDW\RXFRQWUROGLJLWZLWKFRPPDQGGLJLWZLWKFRPPDQGDQGVRRQ
sendCommand(1, 5); // display 5 on the first digit
<RXFDQVXSSUHVVOHDGLQJ]HURVE\DGGLQJWZROLQHVRIFRGHLQdisplayNumberWKDWVHQG
[IWRWKHWREODQNWKHVHJPHQWVLIWKHUHVLGXDOYDOXHLV
void displayNumber( int number)
{
for(int i = 0; i < numberOfDigits; i++)
{
byte character = number % 10;
7KHQH[WWZROLQHVDUHDGGHGWRVXSSUHVVOHDGLQJ]HURV
}
}
if(number == 0 && i > 0)
character = 0xf; // value to blank the 7221 segments
sendCommand(numberOfDigits-i, character);
number = number / 10;
13.9 Communicating Between Two or More Arduino Boards
Problem
<RXZDQWWRKDYHWZRRUPRUH$UGXLQRERDUGVZRUNLQJWRJHWKHU<RXPD\ZDQWWR
LQFUHDVHWKH,2FDSDELOLW\RUSHUIRUPPRUHSURFHVVLQJWKDQFDQEHDFKLHYHGRQDVLQJOH
ERDUG <RX FDQ XVH ,& WR SDVV GDWD EHWZHHQ ERDUGV VR WKDW WKH\ FDQ VKDUH WKH
ZRUNORDG
Solution
7KHWZRVNHWFKHVLQWKLVUHFLSHVKRZKRZ,&FDQEHXVHGDVDFRPPXQLFDWLRQVOLQN
EHWZHHQWZRRUPRUH$UGXLQRERDUGV)LJXUHVKRZVWKHFRQQHFWLRQV
13.9 Communicating Between Two or More Arduino Boards | 421
Download from Wow! eBook <www.wowebook.com>
)LJXUH$UGXLQRDV,&PDVWHUDQGVODYH
7KHPDVWHUVHQGVFKDUDFWHUVUHFHLYHGRQWKHVHULDOSRUWWRDQ$UGXLQRVODYHXVLQJ,&
/*
* I2C_Master
* Echo Serial data to an I2C slave
*/
#include <Wire.h>
const int address = 4;
//the address to be used by the communicating devices
void setup()
{
Wire.begin();
}
void loop()
{
char c;
}
if(Serial.available() > 0 )
{
// send the data
Wire.beginTransmission(address); // transmit to device
Wire.send(c);
Wire.endTransmission();
}
7KHVODYHSULQWVFKDUDFWHUVUHFHLYHGRYHU,&WRLWVVHULDOSRUW
/*
* I2C_Slave
* monitors I2C requests and echoes these to the serial port
*
*/
422 | Chapter 13:ಗCommunicating Using I2C and SPI
#include <Wire.h>
const int address = 4;
//the address to be used by the communicating devices
void setup()
{
Wire.begin(address); // join I2C bus using this address
Wire.onReceive(receiveEvent); // register event to handle requests
}
void loop()
{
// nothing here, all the work is done in receiveEvent
}
void receiveEvent(int howMany)
{
while(Wire.available() > 0)
{
char c = Wire.receive(); // receive byte as a character
Serial.print(c); // echo
}
}
Discussion
7KLVFKDSWHUIRFXVHGRQ$UGXLQRDVWKH,&PDVWHUDFFHVVLQJYDULRXV,&VODYHV+HUH
DVHFRQG$UGXLQRDFWVDVDQ,&VODYHWKDWUHVSRQGVWRUHTXHVWVIURPDQRWKHU$UGXLQR
7HFKQLTXHVFRYHUHGLQ&KDSWHUIRUVHQGLQJE\WHVRIGDWDFDQEHDSSOLHGKHUH7KH
:LUHOLEUDU\GRHVQRWKDYHDSULQWPHWKRGEXWLW¦VQRWGLIILFXOWWRDGGWKLV
7KHIROORZLQJVNHWFKFUHDWHVDQREMHFWQDPHGI2CDebugWKDWVHQGVLWVRXWSXWRYHU,&
8VLQJWKLVZLWKWKH,&VODYHVNHWFKVKRZQSUHYLRXVO\HQDEOHV\RXWRSULQWGDWDRQWKH
PDVWHUZLWKRXWXVLQJWKHVHULDOSRUW WKHVODYH¦VVHULDOSRUWLVXVHGWRGLVSOD\WKHRXWSXW /*
* I2C_Master
* Sends serial data to an I2C slave
*/
#include <Wire.h>
const int address = 4;
const int sensorPin = 0;
int val;
//the address to be used by the communicating devices
// select the analog input pin for the sensor
// variable to store the sensor value
class I2CDebugClass : public Print
{
private:
int I2CAddress;
byte count;
void write(byte c);
13.9 Communicating Between Two or More Arduino Boards | 423
public:
I2CDebugClass();
boolean begin(int id);
};
I2CDebugClass::I2CDebugClass()
{
}
boolean I2CDebugClass::begin(int id)
{
I2CAddress = id; // save the slave's address
Wire.begin(); // join I2C bus (address optional for master)
return true;
}
void I2CDebugClass::write(byte c)
{
if( count == 0)
{
// here if the first char in the transmission
Wire.beginTransmission(I2CAddress); // transmit to device
}
Wire.send(c);
// if the I2C buffer is full or an end of line is reached, send the data
// BUFFER_LENGTH is defined in the Wire library
if(++count >= BUFFER_LENGTH || c == '\n')
{
// send data if buffer full or newline character
Wire.endTransmission();
count = 0;
}
}
I2CDebugClass I2CDebug;
// the I2C print object
void setup()
{
Wire.begin();
Serial.begin(9600);
}
void loop()
{
val = analogRead(sensorPin);
from 0 to 1023)
Serial.println(val);
I2CDebug.println(val);
}
// read the voltage on the pot (val ranges
See Also
&KDSWHUKDVPRUHLQIRUPDWLRQRQXVLQJWKH$UGXLQRSULQWIXQFWLRQDOLW\
424 | Chapter 13:ಗCommunicating Using I2C and SPI
CHAPTER 14
Wireless Communication
14.0 Introduction
$UGXLQR¦VDELOLW\WRLQWHUDFWZLWKWKHZRUOGLVIDQWDVWLFEXWVRPHWLPHV\RXPLJKWZDQW
WRFRPPXQLFDWHZLWK\RXU$UGXLQRIURPDGLVWDQFHZLWKRXWZLUHVDQGZLWKRXWWKH
RYHUKHDGRIDIXOO7&3,3QHWZRUNFRQQHFWLRQ7KLVFKDSWHUEHJLQVZLWKDUHFLSHIRU
VLPSOHZLUHOHVVPRGXOHVIRUDSSOLFDWLRQVZKHUHORZFRVWLVWKHSULPDU\UHTXLUHPHQW
EXWPRVWRIWKHUHFLSHVIRFXVRQWKHYHUVDWLOH;%HHZLUHOHVVPRGXOHV
;%HHSURYLGHVIOH[LEOHZLUHOHVVFDSDELOLW\WRWKH$UGXLQREXWWKDWYHU\IOH[LELOLW\FDQ
EHFRQIXVLQJ7KLVFKDSWHUSURYLGHVH[DPSOHVUDQJLQJIURPVLPSOH£ZLUHOHVVVHULDOSRUW
UHSODFHPHQWV¤ WKURXJK WR PHVK QHWZRUNV FRQQHFWLQJ PXOWLSOH ERDUGV WR PXOWLSOH
VHQVRUV
$ QXPEHU RI GLIIHUHQW ;%HH PRGXOHV DUH DYDLODEOH 7KH PRVW SRSXODU DUH WKH ;%HH
DOVRNQRZQDV;%HH6HULHV DQG;%HH=%6HULHV6HULHVLVHDVLHUWRXVH
WKDQ6HULHVEXWLWGRHVQRWVXSSRUWPHVKQHWZRUNV6HHKWWSZZZGLJLFRPVXSSRUW
NEDVHNEDVHUHVXOWGHWOMVS"LG 14.1 Sending Messages Using Low-Cost Wireless Modules
Problem
<RXZDQWWRWUDQVPLWGDWDEHWZHHQWZR$UGXLQRERDUGVXVLQJVLPSOHORZFRVWZLUHOHVV
PRGXOHV
Solution
7KLV UHFLSH XVHV VLPSOH WUDQVPLW DQG UHFHLYH PRGXOHV VXFK DV WKH 6SDUN)XQ
:5/DQG:5/
:LUHWKHWUDQVPLWWHUDVVKRZQLQ)LJXUHDQGWKHUHFHLYHUDVLQ)LJXUH
425
)LJXUH6LPSOHZLUHOHVVWUDQVPLWWHUXVLQJ9LUWXDO:LUH
)LJXUH6LPSOHZLUHOHVVUHFHLYHUXVLQJ9LUWXDO:LUH
426 | Chapter 14:ಗWireless Communication
7KHWUDQVPLWVNHWFKVHQGVDVLPSOHWH[WPHVVDJHWRWKHUHFHLYHVNHWFKZKLFKHFKRHV
WKHWH[WWRWKH6HULDO0RQLWRU7KHWUDQVPLWDQGUHFHLYHVNHWFKHVXVHWKH9LUWXDO:LUH
OLEUDU\ZULWWHQE\0LNH0F&DXOH\WRSURYLGHWKHLQWHUIDFHWRWKHZLUHOHVVKDUGZDUH
7KHOLEUDU\FDQEHGRZQORDGHGIURPKWWSZZZRSHQFRPDXPLNHPDUGXLQR9LUWXDO
:LUH]LS
/*
SimpleSend
This sketch transmits a short text message using the VirtualWire library
connect the Transmitter data pin to Arduino pin 12
*/
#include <VirtualWire.h>
void setup()
{
// Initialize the IO and ISR
vw_setup(2000);
// Bits per sec
}
void loop()
{
send("hello");
delay(1000);
}
void send (char *message)
{
vw_send((uint8_t *)message, strlen(message));
vw_wait_tx(); // Wait until the whole message is gone
}
7KHUHFHLYHVNHWFKDOVRXVHVWKH9LUWXDO:LUHOLEUDU\
/*
SimpleReceive
This sketch displays text strings received using VirtualWire
Connect the Receiver data pin to Arduino pin 11
*/
#include <VirtualWire.h>
byte message[VW_MAX_MESSAGE_LEN];
// a buffer to hold the incoming messages
byte msgLength = VW_MAX_MESSAGE_LEN; // the size of the message
void setup()
{
Serial.begin(9600);
Serial.println("Ready");
// Initialize the IO and ISR
vw_setup(2000);
// Bits per sec
vw_rx_start();
// Start the receiver
}
14.1 Sending Messages Using Low-Cost Wireless Modules | 427
void loop()
{
if (vw_get_message(message, &msgLength)) // Non-blocking
{
Serial.print("Got: ");
for (int i = 0; i < msgLength; i++)
{
Serial.write(message[i]);
}
Serial.println();
}
}
Discussion
7KH9LUWXDO:LUHOLEUDU\GHIDXOWVWRSLQIRUWUDQVPLWDQGSLQIRUUHFHLYHEXWVHH
WKH GRFXPHQWDWLRQ OLQN DW WKH HQG RI WKLV UHFLSH LI \RX ZDQW WR XVH GLIIHUHQW SLQV
SetupLQLWLDOL]HVWKHOLEUDU\7KH loopFRGHVLPSO\FDOOVD sendIXQFWLRQWKDWFDOOVWKH
OLEUDU\vw_sendDQGZDLWVIRUWKHPHVVDJHWREHWUDQVPLWWHG
7KHUHFHLYHVLGHLQLWLDOL]HVWKHOLEUDU\UHFHLYHORJLFDQGWKHQZDLWVLQloopIRUWKHPHV
VDJHvw_get_messageZLOOUHWXUQtrueLIDPHVVDJHLVDYDLODEOHDQGLIVRHDFKFKDUDFWHU
LQWKHPHVVDJHLVSULQWHGWRWKH6HULDO0RQLWRU
7KH9LUWXDO:LUHOLEUDU\KDQGOHVWKHDVVHPEO\RIPXOWLSOHE\WHVLQWRSDFNHWVVRVHQGLQJ
ELQDU\GDWDFRQVLVWVRISDVVLQJWKHDGGUHVVRIWKHGDWDDQGWKHQXPEHURIE\WHVWRVHQG
7KHVHQGLQJVNHWFKWKDWIROORZVLVVLPLODUWRWKHWUDQVPLWVNHWFKLQWKLVUHFLSH¦V6ROXWLRQ
EXWLWILOOVWKHPHVVDJHEXIIHUZLWKELQDU\YDOXHVIURPUHDGLQJWKHDQDORJLQSXWSRUWV
XVLQJanalogRead7KHVL]HRIWKHEXIIHULVWKHQXPEHURILQWHJHUVWREHVHQWPXOWLSOLHG
E\WKHQXPEHURIE\WHVLQDQLQWHJHU WKHVL[DQDORJLQWHJHUYDOXHVWDNHE\WHVEHFDXVH
HDFKintLVWZRE\WHV /*
SendBinary
Sends digital and analog pin values as binary data using VirtualWire library
See SendBinary in Chapter 4
*/
#include <VirtualWire.h>
const int numberOfAnalogPins = 6; // how many analog pins to read
int data[numberOfAnalogPins];
// the data buffer
const int dataBytes = numberOfAnalogPins * sizeof(int); // the number of bytes
in the data buffer
void setup()
{
// Initialize the IO and ISR
vw_setup(2000);
// Bits per sec
}
428 | Chapter 14:ಗWireless Communication
void loop()
{
int values = 0;
for(int i=0; i <= numberOfAnalogPins; i++)
{
// read the analog ports
data[i] = analogRead(i); // store the values into the data buffer
}
send((byte*)data, dataBytes);
delay(1000); //send every second
}
void send (byte *data, int nbrOfBytes)
{
vw_send(data, nbrOfBytes);
vw_wait_tx(); // Wait until the whole message is gone
}
7KHsizeofRSHUDWRULVXVHGWRGHWHUPLQHWKHQXPEHURIE\WHVLQDQint
7KHUHFHLYHVLGHZDLWVIRUPHVVDJHVFKHFNVWKDWWKH\DUHWKHH[SHFWHGOHQJWKDQGFRQ
YHUWVWKHEXIIHUEDFNLQWRWKHVL[LQWHJHUYDOXHVIRUGLVSOD\RQWKH6HULDO0RQLWRU
/*
ReceiveBinary
This sketch receives six integer values as binary data
Connect the Receiver data pin to Arduino pin 11
*/
#include <VirtualWire.h>
/*
SendBinary
Sends digital and analog pin values as binary data using VirtualWire library
See SendBinary in Chapter 4
*/
#include <VirtualWire.h>
const int numberOfAnalogPins = 6; // how many analog integer values to receive
int data[numberOfAnalogPins]; // the data buffer
// the number of bytes in the data buffer
const int dataBytes = numberOfAnalogPins * sizeof(int);
byte msgLength = dataBytes;
void setup()
{
14.1 Sending Messages Using Low-Cost Wireless Modules | 429
Serial.begin(9600);
Serial.println("Ready");
// Initialize the IO and ISR
vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(2000);
// Bits per sec
vw_rx_start();
// Start the receiver
}
void loop()
{
if (vw_get_message((byte*)data, &msgLength)) // Non-blocking
{
Serial.println("Got: ");
if(msgLength == dataBytes)
{
for (int i = 0; i < numberOfAnalogPins; i++)
{
Serial.print("pin ");
Serial.print(i);
Serial.print("=");
Serial.println(data[i]);
}
}
else
{
Serial.print("unexpected msg length of ");
Serial.println(msgLength);
}
Serial.println();
}
}
7KH6HULDO0RQLWRUZLOOGLVSOD\WKHDQDORJYDOXHVRQWKHVHQGLQJ$UGXLQR
Got:
pin 0=1023
pin 1=100
pin 2=227
pin 3=303
pin 4=331
pin 5=358
%HDULQPLQGWKDWWKHPD[LPXPEXIIHUVL]HIRU9LUWXDO:LUHLVE\WHVORQJ WKHFRQ
VWDQWVW_MAX_MESSAGE_LENLVGHILQHGLQWKHOLEUDU\KHDGHUILOH :LUHOHVVUDQJHFDQEHXSWRPHWHUVRUVRGHSHQGLQJRQVXSSO\YROWDJHDQGDQWHQQD
DQGLVUHGXFHGLIWKHUHDUHREVWDFOHVEHWZHHQWKHWUDQVPLWWHUDQGWKHUHFHLYHU
$OVRQRWHWKDWWKHPHVVDJHVDUHQRWJXDUDQWHHGWREHGHOLYHUHGDQGLI\RXJHWRXWRI
UDQJHRUWKHUHLVH[FHVVLYHUDGLRLQWHUIHUHQFHVRPHPHVVDJHVFRXOGJHWORVW,I\RXQHHG
DJXDUDQWHHGZLUHOHVVGHOLYHU\PHFKDQLVPWKH=LJ%HH$3,XVHGLQUHFLSHVDWWKHHQGRI
WKLVFKDSWHULVDEHWWHUFKRLFHEXWWKHVHLQH[SHQVLYHPRGXOHVZRUNZHOOIRUWDVNVVXFK
430 | Chapter 14:ಗWireless Communication
DVGLVSOD\LQJWKHVWDWXVRI$UGXLQRVHQVRUV¢HDFKPHVVDJHFRQWDLQVWKHFXUUHQWVHQVRU
YDOXHWRGLVSOD\DQGDQ\ORVWPHVVDJHVJHWUHSODFHGE\PHVVDJHVWKDWIROORZ
See Also
$WHFKQLFDOGRFXPHQWRQWKH9LUWXDO:LUH/LEUDU\FDQEHGRZQORDGHGIURPKWWSZZZ
RSHQFRPDXPLNHPDUGXLQR9LUWXDO:LUHSGI
'DWDVKHHWVIRUWKHWUDQVPLWWHUDQGUHFHLYHUPRGXOHVFDQEHIRXQGDWKWWSZZZVSDUN
IXQFRPGDWDVKHHWV:LUHOHVV*HQHUDO026$:5SGIDQGKWWSZZZVSDUNIXQFRPGD
WDVKHHWV:LUHOHVV*HQHUDO025;SGI
14.2 Connecting Arduino to a ZigBee or 802.15.4 Network
Problem
<RX¦GOLNH\RXU$UGXLQRWRSDUWLFLSDWHLQD=LJ%HHRUQHWZRUN
LV DQ ,((( VWDQGDUG IRU ORZSRZHU GLJLWDO UDGLRV WKDW DUH LPSOHPHQWHG LQ
SURGXFWVVXFKDVWKHLQH[SHQVLYH;%HHPRGXOHVIURP'LJL,QWHUQDWLRQDO=LJ%HHLVDQ
DOOLDQFHRIFRPSDQLHVDQGDOVRWKHQDPHRIDVWDQGDUGPDLQWDLQHGE\WKDWDOOLDQFH
=LJ%HHLVEDVHGRQ,(((DQGLVDVXSHUVHWRILW=LJ%HHLVLPSOHPHQWHGLQPDQ\
SURGXFWVLQFOXGLQJFHUWDLQ;%HHPRGXOHVIURP'LJL
2QO\;%HHPRGXOHVWKDWDUHOLVWHGDV=LJ%HHFRPSDWLEOHVXFKDVWKH
;%HH=%PRGXOHVDUHJXDUDQWHHGWREH=LJ%HHFRPSOLDQW7KDWEHLQJ
VDLG\RXFDQXVHDVXEVHWRIWKHIHDWXUHV ,((( RI=LJ%HHHYHQ
ZLWKWKHROGHU;%HH6HULHVPRGXOHV,QIDFWDOOWKHUHFLSHVKHUHZLOO
ZRUNZLWKWKH6HULHVPRGXOHV
Troubleshooting XBee
,I\RXKDYHWURXEOHJHWWLQJ\RXU;%HHVWRWDONPDNHVXUHWKH\ERWKKDYHWKHVDPHW\SH
RIILUPZDUH HJ;%=%XQGHUWKH0RGHP;%((VHWWLQJVKRZQLQ)LJXUH DQGWKDWWKH\DUHERWKUXQQLQJWKHPRVWFXUUHQWYHUVLRQRIWKHILUPZDUH WKH9HUVLRQ
VHWWLQJVKRZQLQ)LJXUH )RUDFRPSUHKHQVLYHVHWRI;%HHWURXEOHVKRRWLQJWLSV
VHH5REHUW)DOXGL¦V£&RPPRQ;%HH0LVWDNHV¤DWKWWSZZZIDOXGLFRPSURMHFWVFRP
PRQ[EHHPLVWDNHV)RUH[WHQVLYHGHWDLOVRQZRUNLQJZLWK;%HHVVHHKLVERRN%XLOGLQJ
:LUHOHVV6HQVRU1HWZRUNVSXEOLVKHGE\2¦5HLOO\
Solution
2EWDLQWZRRUPRUH;%HHPRGXOHVFRQILJXUHWKHPWRFRPPXQLFDWHZLWKRQHDQRWKHU
DQGKRRNWKHPXSWRDWOHDVWRQH$UGXLQR<RXFDQFRQQHFWWKHRWKHU;%HHPRGXOHV
WRDQRWKHU$UGXLQRDFRPSXWHURUDQDQDORJVHQVRU VHH5HFLSH 14.2 Connecting Arduino to a ZigBee or 802.15.4 Network | 431
,I\RXFRQQHFWWKH$UGXLQRWRWKH;%HHDQGUXQWKLVVLPSOHVNHWFKWKH$UGXLQRZLOO
UHSO\WRDQ\PHVVDJHLWUHFHLYHVE\VLPSO\HFKRLQJZKDWWKHRWKHU;%HHVHQGVLW
/*
XBeeEcho
Reply with whatever you receive over the serial port
*/
void setup()
{
Serial.begin(9600);
}
void loop()
{
while (Serial.available() ) {
Serial.write(Serial.read()); // reply with whatever you receive
}
}
)LJXUHVKRZVWKHFRQQHFWLRQEHWZHHQDQ$GDIUXLW;%HH$GDSWHUDQG$UGXLQR
1RWLFHWKDWWKH$UGXLQR¦V5;LVFRQQHFWHGWRWKH;%HH¦V7;DQGYLFHYHUVD
)LJXUH&RQQHFWLQJDQ$UGXLQRWRDQ;%HHXVLQJWKH$GDIUXLW;%HH$GDSWHU
,I\RXDUHXVLQJDGLIIHUHQWDGDSWHUWKDWGRHVQRWKDYHDQRQERDUGYROW
DJHUHJXODWRULWZLOOEHVHQGLQJYROWDJHGLUHFWO\LQWRWKH;%HH,IWKLVLV
WKHFDVH\RXPXVWFRQQHFWWKH9SLQIURPWKH$UGXLQRWRWKHDGDSW
HU¦VSRZHUVXSSO\RU\RXULVNEXUQLQJRXW\RXU;%HH
432 | Chapter 14:ಗWireless Communication
:LWKWKH;%HHVFRQILJXUHGDQGFRQQHFWHGWRDFRPSXWHUDQGRU$UGXLQR\RXFDQVHQG
PHVVDJHVEDFNDQGIRUWK
<RXPXVWGLVFRQQHFWWKH$UGXLQRIURPWKH;%HHEHIRUH\RXDWWHPSWWR
SURJUDPWKH$UGXLQR7KLVLVEHFDXVH$UGXLQRXVHVSLQVDQGIRU
SURJUDPPLQJDQGWKHVLJQDOVZLOOJHWFURVVHGLIDQ\WKLQJHOVHVXFKDV
DQ;%HHLVFRQQHFWHGWRWKRVHSLQV
Discussion
7RFRQILJXUH\RXU;%HHVSOXJWKHPLQWRDQ;%HHDGDSWHUVXFKDVWKH$GDIUXLW;%HH
$GDSWHUNLW 0DNHU6KHGSDUWQXPEHU0.$'$GDIUXLW DQGXVHD86%WR
77/VHULDODGDSWHUVXFKDVWKH77/5 0DNHU6KHG77/5$GDIUXLW WR
FRQQHFWWKHDGDSWHUWRDFRPSXWHU
<RXVKRXOGSXUFKDVHDWOHDVWWZRDGDSWHUV DQGLIQHHGHGWZRFDEOHV ZKLFKZLOODOORZ\RXWRKDYHWZR;%HHVFRQQHFWHGWR\RXUFRPSXWHUDW
WKHVDPHWLPH7KHVHVDPHDGDSWHUVFDQEHXVHGWRFRQQHFWDQ;%HHWR
DQ$UGXLQR
<RXFRXOGDOVRXVHDQDOOLQRQH;%HH86%DGDSWHUVXFKDVWKH3DUDOOD[;%HH86%
$GDSWHU $GDIUXLW3DUDOOD[ RUWKH6SDUN)XQ;%HH([SORUHU86% 6SDUN)XQ:5/ )LJXUHVKRZVWKH$GDIUXLW;%HH$GDSWHUDQGWKH6SDUN)XQ;%HH([SORUHU86%
ZLWK6HULHV;%HHPRGXOHVFRQQHFWHG
Series 2 configuration
)RUWKHLQLWLDOFRQILJXUDWLRQRI6HULHV;%HHV\RXZLOOQHHGWRSOXJ\RXU;%HHVLQWRD
:LQGRZVFRPSXWHU WKHFRQILJXUDWLRQXWLOLW\LVQRWDYDLODEOHIRU0DFRU/LQX[ 3OXJ
RQO\RQHLQWRD86%SRUWIRUQRZ7KH77/5DQG3DUDOOD[;%HH86%$GDSWHUERWK
XVHWKHVDPH86%WRVHULDOGULYHUDVWKH$UGXLQRLWVHOIVR\RXVKRXOGQRWQHHGWRLQVWDOO
DQDGGLWLRQDOGULYHU
2SHQ'HYLFH0DQDJHU SUHVV:LQGRZV5W\SHdevmgmt.mscDQGSUHVV(QWHU H[
SDQGWKH3RUWV &20 /37 VHFWLRQDQGWDNHQRWHRIWKHQXPEHURIWKH86%
6HULDO3RUWWKH;%HH\RXMXVWSOXJJHGLQLVFRQQHFWHGWR([LW'HYLFH0DQDJHU
5XQ WKH ;&78 DSSOLFDWLRQ KWWSZZZGLJLFRPVXSSRUWSURGXFWGHWOMVS"SLG
WKHQVHOHFW\RXUVHULDOSRUWDQGSUHVV7HVW4XHU\WRHQVXUHWKDW;&78
UHFRJQL]HV\RXU;%HH ,IQRWVHHWKHVXSSRUWGRFXPHQWDWKWWSZZZGLJLFRP
VXSSRUWNEDVHNEDVHUHVXOWGHWOMVS"LG 6ZLWFKWRWKH0RGHP&RQILJXUDWLRQWDEDQGFOLFN5HDG;&78ZLOOGHWHUPLQH
ZKLFKPRGHORI;%HH\RXDUHXVLQJDVZHOODVWKHFXUUHQWFRQILJXUDWLRQ
14.2 Connecting Arduino to a ZigBee or 802.15.4 Network | 433
)LJXUH7ZR;%HHVRQHFRQQHFWHGWRDQ$GDIUXLWDGDSWHUDQGWKHRWKHUFRQQHFWHGWRD6SDUN)XQ
DGDSWHU
8QGHU)XQFWLRQ6HWFKRRVH=,*%((&225',1$725$7 QRW$3, &OLFN6KRZ'HIDXOWV
&KDQJHWKH3$1,'VHWWLQJIURPWR RUDQ\KH[DGHFLPDOQXPEHU\RXZDQW
DVORQJDV\RXXVHWKHVDPH3$1,'IRUDOOGHYLFHVRQWKHVDPHQHWZRUN DVVKRZQ
LQ)LJXUH
&OLFN:ULWH
&OLFNWKH7HUPLQDOWDE
1H[WOHDYH;&78UXQQLQJDQGOHDYHWKDW;%HHSOXJJHGLQ3OXJ\RXUVHFRQG;%HH
LQWRDGLIIHUHQWVHULDOSRUW5HSHDWWKHSUHFHGLQJVWHSV LQVWHS\RXZLOOEHVWDUWLQJ
XSDVHFRQGFRS\RI;&78 EXWLQVWHDGRIFKRRVLQJ=,*%((&225',1$725$7
LQVWHSFKRRVH=,*%((5287(5$72QWKLV;%HH\RXVKRXOGDOVRVHW&KDQQHO
9HULILFDWLRQ -9 WRWRPDNHVXUHLWZLOOFRQILUPWKDWLW¦VRQWKHULJKWFKDQQHOZKLFK
PDNHVLWVFRQQHFWLRQWRWKHFRRUGLQDWRUPRUHUHOLDEOH
,I\RXKDYHWZRFRPSXWHUVUXQQLQJ:LQGRZV\RXFDQFRQQHFWHDFK
;%HHLQWRDVHSDUDWHFRPSXWHU
:LWKERWK;%HHVFRQQHFWHGDQGWZRFRSLHVRI;&78VKRZLQJWKHLU7HUPLQDOWDEW\SH
LQWRHLWKHU7HUPLQDOZLQGRZ<RX¦OOVHHZKDWHYHU\RXW\SHLQWRRQH;%HHDSSHDURQ
434 | Chapter 14:ಗWireless Communication
)LJXUH&RQILJXULQJWKH;%HH
WKH 7HUPLQDO RI WKH RWKHU RQH <RX¦YH VHW XS \RXU ILUVW VLPSOH ;%HH 3HUVRQDO $UHD
1HWZRUN 3$1 Series 1 configuration
)RU6HULHV;%HHV\RXFDQXVHD0DFRUD3&UXQQLQJ/LQX[RU:LQGRZV+RZHYHU
LI\RXZLVKWRXSGDWHWKHILUPZDUHRQWKH;%HHV\RXZLOOQHHGWRXVHWKH;&78XWLOLW\
GHVFULEHGLQ£6HULHVFRQILJXUDWLRQ¤RQSDJH
8VLQJDVHULDOWHUPLQDOSURJUDPVXFKDV&RRO7HUPRU3X77<FRQQHFWWRWKH;%HH¦V
86%VHULDOSRUWDWELWVSHUVHFRQG
14.2 Connecting Arduino to a ZigBee or 802.15.4 Network | 435
<RXFDQGRZQORDG&RRO7HUPIRU:LQGRZVDQG0DFDWKWWSIUHHZDUH
WKHPHLHUVRUJ3X77<LVDYDLODEOHIRU:LQGRZVDQG/LQX[DWKWWS
ZZZFKLDUNJUHHQHQGRUJXNaVJWDWKDPSXWW\GRZQORDGKWPO<RXPD\
DOVREHDEOHWRLQVWDOO3X77<XQGHU/LQX[XVLQJ\RXU/LQX[V\VWHP¦V
SDFNDJHPDQDJHU)RUH[DPSOHRQ8EXQWX3X77<LVDYDLODEOHLQWKH
8QLYHUVHUHSRVLWRU\ZLWKapt-get install putty
7R GHWHUPLQH WKH VHULDO SRUW DVVLJQHG WR \RXU ;%HH XQGHU :LQGRZV VHH VWHS LQ
£6HULHVFRQILJXUDWLRQ¤RQSDJH7RGHWHUPLQHWKHVHULDOSRUWXQGHU0DF26;
RSHQWKH0DF26;7HUPLQDOZLQGRZ ORFDWHGLQ$SSOLFDWLRQV8WLOLWLHV DQGW\SHWKLV
FRPPDQGls/dev/tty.usbserial-*2Q/LQX[RSHQDQ[WHUPRUVLPLODUFRQVROHWHU
PLQDODQGW\SHls/dev/ttyUSB*
,I\RXVHHPRUHWKDQRQHUHVXOWKHUHXQSOXJDOO86%VHULDOGHYLFHVH[FHSWWKH;%HH\RX
ZLVKWRFRQILJXUHDQGW\SHWKHFRPPDQGDJDLQ<RXVKRXOGRQO\VHHRQHUHVXOW
<RX¦OOVHHRXWSXWOLNHWKLVRQWKH0DF
/dev/tty.usbserial-A700eYw1
$QGOLNHWKLVRQ/LQX[
/dev/ttyUSB0
7KHUHVXOW\RXVHHLVWKHILOHQDPHWKDWFRUUHVSRQGVWR\RXU;%HH¦V86%VHULDOSRUW
&RQQHFWWRWKLVSRUWLQ\RXUVHULDOWHUPLQDOSURJUDP7RFRQQHFWWR\RXU;%HHXVLQJ
&RRO7HUP :LQGRZVRU0DF IROORZWKHVHVWHSV
5XQ&RRO7HUP
&OLFNWKH2SWLRQVEXWWRQLQWKHWRROEDU
6HOHFWWKH86%VHULDOSRUW VXFKDVWW\XVEVHULDO$H<ZRQD0DFRU&20RQ
D3& 0DNHVXUHLWLVVHWWRDEDXGUDWHRIGDWDELWVQRSDULW\VWRSELW
WKHVHDUHWKHGHIDXOWV &KHFNWKHER[ODEHOHG/RFDO(FKR
&OLFN2.
&OLFNWKH6DYHEXWWRQLQWKHWRROEDUDQGVDYH\RXUVHVVLRQVHWWLQJV
,QIXWXUHVHVVLRQV\RXFDQVNLSVWHSVWKURXJKE\FOLFNLQJ2SHQDQGVHOHFWLQJ
WKHVHWWLQJVILOH\RXVDYHG
&OLFNWKH&RQQHFWEXWWRQLQWKHWRROEDU
7RFRQQHFWWR\RXU;%HHXVLQJ3X77< :LQGRZVRU/LQX[ IROORZWKHVHVWHSV
5XQ3X77<
&OLFN6HULDOXQGHU&RQQHFWLRQ7\SH
7\SHWKHQDPHRI\RXUVHULDOSRUWLQWKH6HULDO/LQHILHOG VXFKDVGHYWW\86%RQ
/LQX[RU&20RQ:LQGRZV 0DNHVXUH6SHHGLVVHWWR WKHGHIDXOW 436 | Chapter 14:ಗWireless Communication
2QWKHOHIWVLGHRIWKHZLQGRZXQGHU&DWHJRU\FOLFN7HUPLQDO
8QGHU/RFDO(FKRFKRRVH)RUFH2Q
8QGHU£6HWYDULRXVWHUPLQDORSWLRQV¤FKRRVH,PSOLFLW/)LQ(YHU\&5
2QWKHOHIWVLGHRIWKHZLQGRZXQGHU&DWHJRU\FOLFN6HVVLRQ
7\SHDQDPHIRUWKHVHVVLRQVXFKDV£;%HH¤WKHQFOLFN6DYH
,QIXWXUHVHVVLRQV\RXFDQVNLSVWHSVWKURXJKE\GRXEOHFOLFNLQJWKHVDYHG
VHVVLRQQDPH7KLVZLOORSHQWKHVHULDOFRQQHFWLRQ
1RZWKDW\RX¦UHFRQQHFWHGFRQILJXUHWKHILUVW;%HHZLWKWKHIROORZLQJ$7FRPPDQGV
<RXZLOOQHHGWRW\SH+++DQGZDLWDVHFRQGWRJHWWKH;%HH¦VDWWHQWLRQ LWZLOOUHVSRQG
ZLWK£2.¤ ATMY1234
ATDL5678
ATDH0
ATID0
ATWR
.HHS\RXUVHULDOWHUPLQDOXSDQGUXQQLQJVRWKDW\RXFDQFRQWLQXHWRW\SHFRPPDQGV
LQWRLW1H[WSOXJLQWKHVHFRQG;%HHDQGIROORZWKHHDUOLHULQVWUXFWLRQVWRFRQQHFWWR
LWZLWK3X77<RU&RRO7HUP WRRSHQDQHZ3X77<ZLQGRZ\RXFDQVLPSO\ODXQFK
WKHSURJUDPDJDLQ\RXFDQVWDUWDQHZ&RRO7HUPZLQGRZZLWK)LOHൺ1HZ 7KHQ
FRQILJXUHWKHVHFRQG;%HHZLWKWKHVHFRPPDQGV
ATMY5678
ATDL1234
ATDH0
ATID0
ATWR
1RZ\RXFDQW\SHFRPPDQGVLQWRWKH6HULDO7HUPLQDOZLQGRZIRURQH;%HHDQGWKH\
ZLOODSSHDULQWKH6HULDO7HUPLQDOZLQGRZIRUWKHRWKHU;%HH DQGYLFHYHUVD 7KHATMYFRPPDQGVHWVWKHLGHQWLILHUIRUDQ;%HHATDLDQGATDHVHWWKHORZE\WHDQG
WKHKLJKE\WHRIWKHGHVWLQDWLRQ;%HHATIDVHWVWKHQHWZRUN,' LWQHHGVWREHWKHVDPH
IRU;%HHVWRWDONWRRQHDQRWKHU DQG ATWRVDYHVWKHVHWWLQJVLQWRWKH;%HHVRWKDWLW
UHPHPEHUVWKHVHWWLQJVHYHQLI\RXSRZHULWGRZQDQGEDFNXS
Talking to the Arduino
1RZWKDW\RX¦YHJRW\RXU;%HHPRGXOHVFRQILJXUHGFORVHWKHVHULDOWHUPLQDOWKDWZDV
FRQQHFWHGWRLWDQGGLVFRQQHFWWKH;%HHIURP\RXUFRPSXWHU1H[WSURJUDP\RXU
$UGXLQRZLWKWKHFRGHVKRZQLQWKLVUHFLSH¦V6ROXWLRQDQGFRQQHFWWKH;%HHWR\RXU
$UGXLQRDVVKRZQLQ)LJXUH:KHQ\RXW\SHFKDUDFWHUVLQWRWKHVHULDOWHUPLQDO
SURJUDPFRQQHFWHGWR\RXURWKHU;%HH\RX¦OOVHHWKHFKDUDFWHUVHFKRHGEDFN LI\RX
W\SHa\RX¦OOVHHaa 14.2 Connecting Arduino to a ZigBee or 802.15.4 Network | 437
See Also
5HFLSH5HFLSH5HFLSH
14.3 Sending a Message to a Particular XBee
Problem
<RXZDQWWRFRQILJXUHZKLFKQRGH\RXUPHVVDJHJRHVWRIURP\RXU$UGXLQRVNHWFK
Solution
6HQGWKH$7FRPPDQGVGLUHFWO\IURP\RXU$UGXLQRVNHWFK
/*
XBeeMessage
Send a message to an XBee using its address
*/
boolean configured = false;
boolean configureRadio() {
// put the radio in command mode:
Serial.print("+++");
String ok_response = "OK\r"; // the response we expect.
// Read the text of the response into the response variable
String response = String("");
while (response.length() < ok_response.length()) {
if (Serial.available() > 0) {
response += (char) Serial.read();
}
}
}
// If we got the right response, configure the radio and return true.
if (response.equals(ok_response)) {
Serial.print("ATDH0013A200\r"); // destination high-REPLACE THIS
Serial.print("ATDL403B9E1E\r"); // destination low-REPLACE THIS
Serial.print("ATCN\r");
// back to data mode
return true;
} else {
return false; // This indicates the response was incorrect.
}
void setup () {
Serial.begin(9600); // Begin serial
configured = configureRadio();
}
void loop () {
438 | Chapter 14:ಗWireless Communication
if (configured) {
Serial.print("Hello!");
delay(3000);
}
else {
delay(30000);
// Wait 30 seconds
configureRadio(); // try again
}
}
Discussion
$OWKRXJKWKHFRQILJXUDWLRQVLQ5HFLSHZRUNIRUWZR;%HHVWKH\DUHQRWDVIOH[LEOH
ZKHQXVHGZLWKPRUHWKDQWZR
)RUH[DPSOHFRQVLGHUDWKUHHQRGHQHWZRUNRI6HULHV;%HHVZLWKRQH;%HHFRQILJ
XUHGZLWKWKH&225',1$725$7ILUPZDUHDQGWKHRWKHUWZRZLWKWKH5287(5
$7ILUPZDUH0HVVDJHV\RXVHQGIURPWKHFRRUGLQDWRUZLOOEHEURDGFDVWWRWKHWZR
URXWHUV0HVVDJHV\RXVHQGIURPHDFKURXWHUDUHVHQWWRWKHFRRUGLQDWRU
7KH6HULHVFRQILJXUDWLRQLQWKDWUHFLSHLVDELWPRUHIOH[LEOHLQWKDWLWVSHFLILHVH[SOLFLW
GHVWLQDWLRQV%XWE\FRQILJXULQJWKHGHYLFHVZLWK$7FRPPDQGVDQGWKHQZULWLQJWKH
FRQILJXUDWLRQ\RXHIIHFWLYHO\KDUGFRGHWKHGHVWLQDWLRQDGGUHVVHVLQWKHILUPZDUH
7KLVVROXWLRQLQVWHDGOHWVWKH$UGXLQRFRGHVHQGWKH$7FRPPDQGVWRFRQILJXUHWKH
;%HHVRQWKHIO\7KHKHDUWRIWKHVROXWLRQLVWKH configureRadio()IXQFWLRQ,WVHQGV
WKH +++HVFDSHVHTXHQFHWRSXWWKH;%HHLQFRPPDQGPRGHMXVWDVWKH6HULHVFRQ
ILJXUDWLRQGLGDWWKHHQGRI5HFLSH$IWHUVHQGLQJWKLVHVFDSHVHTXHQFHWKH$UGXLQR
VNHWFKZDLWVIRUWKH2.UHVSRQVHEHIRUHVHQGLQJWKHVH$7FRPPDQGV
ATDH0013A200
ATDL403B9E1E
ATCN
,Q\RXUFRGH\RXPXVWUHSODFH0013A200DQG403B9E1EZLWKWKHKLJKDQG
ORZDGGUHVVHVRIWKHGHVWLQDWLRQUDGLR
7KHILUVWWZRFRPPDQGVDUHVLPLODUWRZKDWLVVKRZQLQWKH6HULHVFRQILJXUDWLRQDW
WKHHQGRI5HFLSHEXWWKHQXPEHUVDUHORQJHU7KDW¦VEHFDXVHWKHH[DPSOHVKRZQ
LQWKDWUHFLSH¦V6ROXWLRQXVHV6HULHV¡VW\OHDGGUHVVHV$V\RXVDZLQ5HFLSH\RX
FDQVSHFLI\WKHDGGUHVVRID6HULHV;%HHZLWKWKH ATMYFRPPDQGEXWLQD6HULHV
;%HHHDFKPRGXOHKDVDXQLTXHDGGUHVVWKDWLVHPEHGGHGLQHDFKFKLS<RXFDQORRN
XSWKHKLJK ATDH DQGORZ ATDL SRUWLRQVRIWKHVHULDOQXPEHUXVLQJ;&78DVVKRZQ
LQ)LJXUH7KHQXPEHUVDUHDOVRSULQWHGRQWKHODEHOXQGHUQHDWKWKH;%HH
7KH ATCNFRPPDQGH[LWVFRPPDQGPRGHWKLQNRILWDVWKHUHYHUVHRIZKDWWKH +++
VHTXHQFHDFFRPSOLVKHV
14.3 Sending a Message to a Particular XBee | 439
)LJXUH/RRNLQJXSWKHKLJKDQGORZVHULDOQXPEHUVLQ;&78
See Also
5HFLSH
14.4 Sending Sensor Data Between XBees
Problem
<RXZDQWWRVHQGWKHVWDWXVRIGLJLWDODQGDQDORJSLQVRUFRQWUROSLQVEDVHGRQFRP
PDQGVUHFHLYHGIURP;%HH
440 | Chapter 14:ಗWireless Communication
Solution
+RRNRQHRIWKH;%HHV WKHWUDQVPLWWLQJ;%HH XSWRDQDQDORJVHQVRUDQGFRQILJXUH
LWWRUHDGWKHVHQVRUDQGWUDQVPLWWKHYDOXHSHULRGLFDOO\&RQQHFWWKH$UGXLQRWRDQ
;%HH WKHUHFHLYLQJ;%HH FRQILJXUHGLQ$3,PRGHDQGUHDGWKHYDOXHRIWKH$3,IUDPHV
WKDWLWUHFHLYHVIURPWKHRWKHU;%HH
Discussion
;%HHVKDYHDEXLOWLQDQDORJWRGLJLWDOFRQYHUWHU $'& WKDWFDQEHSROOHGRQDUHJXODU
EDVLV7KH;%HHFDQEHFRQILJXUHGWRWUDQVPLWWKHYDOXHV EHWZHHQDQG WRRWKHU
;%HHVLQWKHQHWZRUN7KHFRQILJXUDWLRQDQGFRGHGLIIHUTXLWHDELWEHWZHHQ6HULHV
DQG6HULHV;%HHV
Series 2 XBees
8VLQJ;&78 VHH£6HULHVFRQILJXUDWLRQ¤RQSDJHLQ5HFLSH FRQILJXUHWKH
WUDQVPLWWLQJ;%HHZLWKWKH=,*%((5287(5$7 QRW$3, IXQFWLRQVHWDQGWKHIRO
ORZLQJVHWWLQJV
3$1,' 1234 RUDQXPEHU\RXSLFNDVORQJDV\RXXVHWKHVDPHRQHIRUERWK
;%HHV
&KDQQHO9HULILFDWLRQ -9 1 WKLVPDNHVVXUHWKHURXWHUZLOOFRQILUPWKDWLW¦VRQ
WKHULJKWFKDQQHOZKHQWDONLQJWRWKHFRRUGLQDWRU
'HVWLQDWLRQ$GGUHVV+LJK '+ WKHKLJKDGGUHVV 6+ RIWKHRWKHU;%HHXVXDOO\
$
'HVWLQDWLRQ$GGUHVV/RZ '/ WKHORZDGGUHVV 6/ RIWKHRWKHU;%HH
8QGHU,26HWWLQJV$'',2&RQILJXUDWLRQ ' 2
8QGHU,26HWWLQJVൺ6DPSOLQJ5DWH ,5 64 PLOOLVHFRQGVLQKH[
<RXFDQORRNXSWKHKLJK ATDH DQGORZ ATDL SRUWLRQVRIWKHVHULDO
QXPEHUXVLQJ;&78DVVKRZQHDUOLHULQ)LJXUH7KHQXPEHUVDUH
DOVRSULQWHGRQWKHODEHOXQGHUQHDWKWKH;%HH
&RQILJXUHWKHUHFHLYLQJ;%HHZLWKWKH=,*%((&225',1$725$3, QRW$7 IXQF
WLRQVHWZLWKWKHIROORZLQJVHWWLQJV
3$1,' 1234 RUDQXPEHU\RXSLFNDVORQJDV\RXXVHWKHVDPHRQHIRUERWK
;%HHV
'HVWLQDWLRQ$GGUHVV+LJK '+ WKHKLJKDGGUHVV 6+ RIWKHRWKHU;%HHXVXDOO\
$
'HVWLQDWLRQ$GGUHVV/RZ '/ WKHORZDGGUHVV 6/ RIWKHRWKHU;%HH
:LUHXSWKHWUDQVPLWWLQJ;%HHWRWKHVHQVRUDVVKRZQLQ)LJXUH7KHYDOXHRI5
VKRXOGEHGRXEOHZKDWHYHU\RXUSRWHQWLRPHWHULV LI\RXDUHXVLQJD.SRWXVHD.
14.4 Sending Sensor Data Between XBees | 441
UHVLVWRU 7KLVLVEHFDXVHWKH6HULHV;%HHV¦DQDORJWRGLJLWDOFRQYHUWHUVUHDGDUDQJH
RIWRYROWVDQG5UHGXFHVWKH9WRVWD\EHORZYROWV
)LJXUH&RQQHFWLQJD6HULHV;%HHWRDQDQDORJVHQVRU
1H[WORDGWKHIROORZLQJVNHWFKRQWRWKH$UGXLQRDQGZLUHWKHWUDQVPLWWLQJ;%HHWR
WKH$UGXLQRDVVKRZQLQ5HFLSH,I\RXQHHGWRUHSURJUDPWKH$UGXLQRUHPHPEHU
WRGLVFRQQHFWLWIURPWKH;%HHILUVW
/*
XBeeAnalogReceive
Read an analog value from an XBee API frame and set the brightness
of an LED accordingly.
*/
#define LEDPIN 9
void setup() {
Serial.begin(9600);
pinMode(LEDPIN, OUTPUT);
}
void loop() {
if (Serial.available() >= 21) { // Wait until we have a mouthful of data
if (Serial.read() == 0x7E) { // Start delimiter of a frame
// Skip over the bytes in the API frame we don't care about
for (int i = 0; i < 18; i++) {
Serial.read();
442 | Chapter 14:ಗWireless Communication
}
// The next two bytes are the high and low bytes of the sensor reading
int analogHigh = Serial.read();
int analogLow = Serial.read();
int analogValue = analogLow + (analogHigh * 256);
// Scale the brightness to the Arduino PWM range
int brightness = map(analogValue, 0, 1023, 0, 255);
// Light the LED
analogWrite(LEDPIN, brightness);
}
}
}
Series 1 XBees
8VLQJ D WHUPLQDO SURJUDP DV GHVFULEHG LQ £6HULHV FRQILJXUDWLRQ¤ RQ SDJH LQ
5HFLSHVHQGWKHIROORZLQJFRQILJXUDWLRQFRPPDQGVWRWKHWUDQVPLWWLQJ;%HH
ATRE
ATMY1234
ATDL5678
ATDH0
ATID0
ATD02
ATIR64
ATWR
1H[WVHQGWKHIROORZLQJFRQILJXUDWLRQFRPPDQGVWRWKHUHFHLYLQJ;%HH
ATRE
ATMY5678
ATDL1234
ATDH0
ATID0
ATWR
%RWK;%HHV
ATREUHVHWVWKH;%HHWRIDFWRU\GHIDXOWV7KHATMYFRPPDQGVHWVWKHLGHQWLILHUIRU
DQ;%HHATDLDQGATDHVHWWKHORZE\WHDQGWKHKLJKE\WHRIWKHGHVWLQDWLRQ;%HH
ATIDVHWVWKHQHWZRUN,' LWQHHGVWREHWKHVDPHIRU;%HHVWRWDONWRRQHDQRWKHU ATWRVDYHVWKHVHWWLQJVLQWRWKH;%HHVRWKDWLWUHPHPEHUVWKHVHWWLQJVHYHQLI\RX
SRZHULWGRZQDQGEDFNXS
7UDQVPLWWLQJ;%HH
ATD02FRQILJXUHVSLQ DQDORJRUGLJLWDOLQSXW DVDQDQDORJLQSXWATIR64WHOOV
WKH;%HHWRVDPSOHHYHU\ KH[ PLOOLVHFRQGVDQGVHQGWKHYDOXHWRWKH;%HH
VSHFLILHGE\ATDLDQGATDH
14.4 Sending Sensor Data Between XBees | 443
:LUHXSWKHWUDQVPLWWLQJ;%HHWRWKHVHQVRUDVVKRZQLQ)LJXUH
)LJXUH6HULHV;%HHFRQQHFWHGWRDQDQDORJVHQVRU
1H[WORDGWKHIROORZLQJVNHWFKRQWRWKH$UGXLQRDQGZLUHWKHWUDQVPLWWLQJ;%HHWR
WKH$UGXLQRDVVKRZQLQ5HFLSH,I\RXQHHGWRUHSURJUDPWKH$UGXLQRGLVFRQQHFW
LWIURPWKH;%HHILUVW
/*
XBeeAnalogReceiveSeries1
Read an analog value from an XBee API frame and set the brightness
of an LED accordingly.
*/
const int ledPin = 9;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
configureRadio(); // check the return value if you need error handling
}
boolean configureRadio() {
// put the radio in command mode:
Serial.flush();
Serial.print("+++");
444 | Chapter 14:ಗWireless Communication
delay(100);
String ok_response = "OK\r"; // the response we expect.
// Read the text of the response into the response variable
String response = String("");
while (response.length() < ok_response.length()) {
if (Serial.available() > 0) {
response += (char) Serial.read();
}
}
// If we got the right response, configure the radio and return true.
if (response.equals(ok_response)) {
Serial.print("ATAP1\r"); // Enter API mode
delay(100);
Serial.print("ATCN\r"); // back to data mode
return true;
} else {
return false; // This indicates the response was incorrect.
}
}
void loop() {
if (Serial.available() >= 14) { // Wait until we have a mouthful of data
if (Serial.read() == 0x7E) { // Start delimiter of a frame
// Skip over the bytes in the API frame we don't care about
for (int i = 0; i < 10; i++) {
Serial.read();
}
// The next two bytes are the high and low bytes of the sensor reading
int analogHigh = Serial.read();
int analogLow = Serial.read();
int analogValue = analogLow + (analogHigh * 256);
// Scale the brightness to the Arduino PWM range
int brightness = map(analogValue, 0, 1023, 0, 255);
// Light the LED
analogWrite(ledPin, brightness);
}
}
}
See Also
5HFLSH
14.4 Sending Sensor Data Between XBees | 445
14.5 Activating an Actuator Connected to an XBee
Problem
<RXZDQWWRWHOODQ;%HHWRDFWLYDWHDSLQZKLFKFRXOGEHXVHGWRWXUQRQDQDFWXDWRU
FRQQHFWHGWRLWVXFKDVDUHOD\RU/('
Solution
&RQILJXUHWKH;%HHFRQQHFWHGWRWKHDFWXDWRUVRWKDWLWZLOODFFHSWLQVWUXFWLRQVIURP
DQRWKHU;%HH&RQQHFWWKHRWKHU;%HHWRDQ$UGXLQRWRVHQGWKHFRPPDQGVQHHGHG
WRDFWLYDWHWKHGLJLWDO,2SLQWKDWWKHDFWXDWRULVFRQQHFWHGWR
Discussion
7KH;%HHGLJLWDODQDORJ,2SLQVFDQEHFRQILJXUHGIRUGLJLWDORXWSXW$GGLWLRQDOO\
;%HHVFDQEHFRQILJXUHGWRDFFHSWLQVWUXFWLRQVIURPRWKHU;%HHVWRWDNHWKRVHSLQV
KLJKRUORZ,Q6HULHV;%HHV\RX¦OOEHXVLQJWKH5HPRWH$7&RPPDQGIHDWXUH,Q
6HULHV;%HHV\RXFDQXVHWKHGLUHFW,2ZKLFKFUHDWHVDYLUWXDOZLUHEHWZHHQ;%HHV
Series 2 XBees
8VLQJ;&78 VHH£6HULHVFRQILJXUDWLRQ¤RQSDJH FRQILJXUHWKHUHFHLYLQJ;%HH
ZLWKWKH=,*%((5287(5$7 QRW$3, IXQFWLRQVHWDQGWKHIROORZLQJVHWWLQJV
3$1,' 1234 RUDQXPEHU\RXSLFNDVORQJDV\RXXVHWKHVDPHRQHIRUERWK
;%HHV
&KDQQHO9HULILFDWLRQ -9 1 WKLVPDNHVVXUHWKHURXWHUZLOOFRQILUPWKDWLW¦VRQ
WKHULJKWFKDQQHOZKHQWDONLQJWRWKHFRRUGLQDWRU
'HVWLQDWLRQ$GGUHVV+LJK '+ WKHKLJKDGGUHVV 6+ RIWKHRWKHU;%HHXVXDOO\
$
'HVWLQDWLRQ$GGUHVV/RZ '/ WKHORZDGGUHVV 6/ RIWKHRWKHU;%HH
8QGHU,26HWWLQJV$'',2&RQILJXUDWLRQ ' 4 GLJLWDORXWSXWORZ
<RXFDQORRNXSWKHKLJK ATDH DQGORZ ATDL SRUWLRQVRIWKHVHULDO
QXPEHUXVLQJ;&78DVVKRZQHDUOLHULQ)LJXUH7KHQXPEHUVDUH
DOVRSULQWHGRQWKHODEHOXQGHUQHDWKWKH;%HH
&RQILJXUH WKH WUDQVPLWWLQJ ;%HH ZLWK WKH =,*%(( &225',1$725 $3, QRW $7
IXQFWLRQVHWZLWKWKHIROORZLQJVHWWLQJV
3$1,' 1234 RUDQXPEHU\RXSLFNDVORQJDV\RXXVHWKHVDPHRQHIRUERWK
;%HHV
'HVWLQDWLRQ$GGUHVV+LJK '+ WKHKLJKDGGUHVV 6+ RIWKHRWKHU;%HHXVXDOO\
$
446 | Chapter 14:ಗWireless Communication
'HVWLQDWLRQ$GGUHVV/RZ '/ WKHORZDGGUHVV 6/ RIWKHRWKHU;%HH
:LUHXSWKHUHFHLYLQJ;%HHWRDQ/('DVVKRZQLQ)LJXUH
)LJXUH&RQQHFWLQJDQ/('WRDQ;%HH¦VGLJLWDO,2SLQ
1H[WORDGWKHIROORZLQJVNHWFKRQWRWKH$UGXLQRDQGZLUHWKHWUDQVPLWWLQJ;%HHWR
WKH$UGXLQRDVVKRZQLQ5HFLSH,I\RXQHHGWRUHSURJUDPWKH$UGXLQRUHPHPEHU
WRGLVFRQQHFWLWIURPWKH;%HHILUVW7KLVVNHWFKVHQGVD5HPRWH$7FRPPDQG ATD14
RUATD15 WKDWVHWVWKHVWDWHRISLQ ATD1 DOWHUQDWLQJO\RQ GLJLWDORXWKLJK DQGRII
GLJLWDORXWORZ /*
XBeeActuate
Send a Remote AT command to activate a digital pin on another XBee.
*/
const byte frameStartByte = 0x7E;
const byte frameTypeRemoteAT = 0x17;
const byte remoteATOptionApplyChanges = 0x02;
void setup() {
Serial.begin(9600);
}
void loop()
{
toggleRemotePin(1);
delay(3000);
toggleRemotePin(0);
delay(2000);
}
14.5 Activating an Actuator Connected to an XBee | 447
byte sendByte(byte value) {
Serial.print(value, BYTE);
return value;
}
void toggleRemotePin(int value) {
// 0 = off, nonzero = on
byte pin_state;
if (value) {
pin_state = 0x5;
} else {
pin_state = 0x4;
}
sendByte(frameStartByte); // Begin the API frame
// High and low parts of the frame length (not counting checksum)
sendByte(0x0);
sendByte(0x10);
long sum = 0; // Accumulate the checksum
sum += sendByte(frameTypeRemoteAT); // Indicate this frame contains a
Remote AT command
sum += sendByte(0x0);
// frame ID set to zero for no reply
// The following 8 bytes indicate the ID of the recipient.
// Use 0xFFFF to broadcast to all nodes.
sum += sendByte(0x0);
sum += sendByte(0x0);
sum += sendByte(0x0);
sum += sendByte(0x0);
sum += sendByte(0x0);
sum += sendByte(0x0);
sum += sendByte(0xFF);
sum += sendByte(0xFF);
// The following 2 bytes indicate the 16-bit address of the recipient.
// Use 0xFFFE to broadcast to all nodes.
sum += sendByte(0xFF);
sum += sendByte(0xFF);
sum += sendByte(remoteATOptionApplyChanges); // send Remote AT options
// The text of the AT command
sum += sendByte('D');
sum += sendByte('1');
// The value (0x4 for off, 0x5 for on)
sum += sendByte(pin_state);
// Send the checksum
sendByte( 0xFF - ( sum & 0xFF));
448 | Chapter 14:ಗWireless Communication
}
delay(10); // Pause to let the microcontroller settle down if needed
Series 1 XBees
8VLQJDWHUPLQDOSURJUDPDVGHVFULEHGLQ£6HULHVFRQILJXUDWLRQ¤RQSDJHVHQG
WKHIROORZLQJFRQILJXUDWLRQFRPPDQGVWRWKHWUDQVPLWWLQJ;%HH WKHRQH\RX¦OOFRQQHFW
WRWKH$UGXLQR ATRE
ATMY1234
ATDL5678
ATDH0
ATID0
ATD13
ATICFF
ATWR
1H[WVHQGWKHIROORZLQJFRQILJXUDWLRQFRPPDQGVWRWKHUHFHLYLQJ;%HH
ATRE
ATMY5678
ATDL1234
ATDH0
ATID0
ATD14
ATIU0
ATIA1234
ATWR
%RWK;%HHV
ATREUHVHWVWKH;%HHWRIDFWRU\GHIDXOWV7KHATMYFRPPDQGVHWVWKHLGHQWLILHUIRU
DQ;%HHATDLDQGATDHVHWWKHORZE\WHDQGWKHKLJKE\WHRIWKHGHVWLQDWLRQ;%HH
ATIDVHWVWKHQHWZRUN,' LWQHHGVWREHWKHVDPHIRU;%HHVWRWDONWRRQHDQRWKHU ATWRVDYHVWKHVHWWLQJVLQWRWKH;%HHVRWKDWLWUHPHPEHUVWKHVHWWLQJVHYHQLI\RX
SRZHULWGRZQDQGEDFNXS
7UDQVPLWWLQJ;%HH
ATICFFWHOOVWKH;%HHWRFKHFNHYHU\GLJLWDOLQSXWSLQDQGVHQGWKHLUYDOXHVWRWKH
;%HHVSHFLILHGE\ ATDLDQG ATDH ATD13FRQILJXUHVSLQ DQDORJRUGLJLWDOLQSXW
WREHLQGLJLWDOLQSXWPRGH7KHVWDWHRIWKLVSLQZLOOEHUHOD\HGIURPWKHWUDQV
PLWWLQJ;%HHWRWKHUHFHLYLQJ;%HH
5HFHLYLQJ;%HH
ATIU1WHOOVWKH;%HHWRQRWVHQGWKHIUDPHVLWUHFHLYHVWRWKHVHULDOSRUW ATIA1234
WHOOV LW WR DFFHSW FRPPDQGV IURP WKH RWKHU ;%HH ZKRVH 0< DGGUHVV LV ATD14FRQILJXUHVSLQ DQDORJRUGLJLWDOLQSXW WREHLQORZGLJLWDORXWSXWPRGH
RIIE\GHIDXOW :LUHXSWKHWUDQVPLWWLQJ;%HHWRWKH$UGXLQRDVVKRZQLQ)LJXUH
1H[WZLUHWKHUHFHLYLQJ;%HHWRDQ$UGXLQRDVVKRZQLQ5HFLSH1RWHWKDWLQVWHDG
RIVHQGLQJ$7FRPPDQGVRYHUWKHVHULDOSRUWZH¦UHXVLQJDQHOHFWULFDOFRQQHFWLRQWR
14.5 Activating an Actuator Connected to an XBee | 449
WDNHWKH;%HH¦VSLQKLJK7KHWZR.UHVLVWRUVIRUPDYROWDJHGLYLGHUWKDWGURSVWKH
$UGXLQR¦V9ORJLFWRDERXWYROWV KLJKHQRXJKIRUWKH;%HHWRUHFRJQL]HEXWORZ
HQRXJKWRDYRLGGDPDJLQJWKH;%HH¦V9ORJLFSLQV )LJXUH&RQQHFWLQJWKH$UGXLQRWR;%HH¦VGLJLWDO,2SLQ
1H[WORDGWKHIROORZLQJVNHWFKRQWRWKH$UGXLQR7KLVVNHWFKWDNHVWKH;%HH¦VGLJLWDO
,2SLQDOWHUQDWLQJO\RQ GLJLWDORXWKLJK DQGRII GLJLWDORXWORZ %HFDXVHWKH
WUDQVPLWWLQJ;%HHLVFRQILJXUHGWRUHOD\LWVSLQVWDWHVWRWKHUHFHLYLQJ;%HHZKHQLWV
SLQFKDQJHVVWDWHWKHUHFHLYLQJ;%HH¦VSLQFKDQJHVDVZHOO
/*
XBeeActuateSeries1
Activate a digital pin on another XBee.
*/
const int ledPin = 9;
const int xbeePin = 2;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(xbeePin, OUTPUT);
}
void loop()
{
}
digitalWrite(xbeePin, HIGH);
delay(3000);
digitalWrite(xbeePin, LOW);
delay(3000);
See Also
5HFLSH
450 | Chapter 14:ಗWireless Communication
CHAPTER 15
Ethernet and Networking
15.0 Introduction
:DQWWRVKDUH\RXUVHQVRUGDWD"/HWRWKHUSHRSOHWDNHFRQWURORI\RXU$UGXLQR¦VDF
WLRQV"<RXU$UGXLQRFDQFRPPXQLFDWHZLWKDEURDGHUZRUOGRYHU(WKHUQHWDQGQHW
ZRUNV7KLVFKDSWHUGHVFULEHVWKHPDQ\ZD\V\RXFDQXVH$UGXLQRZLWKWKH,QWHUQHW
,WKDVH[DPSOHVWKDWGHPRQVWUDWHKRZWREXLOGDQGXVHZHEFOLHQWVDQGVHUYHUVDQGLW
VKRZV KRZ WR XVH WKH PRVW FRPPRQ ,QWHUQHW FRPPXQLFDWLRQ SURWRFROV ZLWK
$UGXLQR
7KH,QWHUQHWDOORZVDFOLHQW HJ\RXUZHEEURZVHU WRUHTXHVWLQIRUPDWLRQIURPD
VHUYHU DZHEVHUYHURURWKHU,QWHUQHWVHUYLFHSURYLGHU 7KLVFKDSWHUFRQWDLQVUHFLSHV
VKRZLQJKRZWRPDNHDQ,QWHUQHWFOLHQWWKDWUHWULHYHVLQIRUPDWLRQIURPDVHUYLFHVXFK
DV*RRJOHRU<DKRR2WKHUUHFLSHVLQWKLVFKDSWHUVKRZKRZ$UGXLQRFDQEHDQ,QWHUQHW
VHUYHUWKDWSURYLGHVLQIRUPDWLRQWRFOLHQWVXVLQJ,QWHUQHWSURWRFROVDQGDFWDVDZHE
VHUYHUWKDWFUHDWHVSDJHVIRUYLHZLQJLQZHEEURZVHUV
7KH$UGXLQR(WKHUQHWOLEUDU\VXSSRUWVDUDQJHRIPHWKRGV SURWRFROV WKDWHQDEOH\RXU
VNHWFKHV WR EH DQ ,QWHUQHW FOLHQW RU D VHUYHU 7KH (WKHUQHW OLEUDU\ XVHV WKH VXLWH RI
VWDQGDUG,QWHUQHWSURWRFROVDQGPRVWRIWKHORZOHYHOSOXPELQJLVKLGGHQ*HWWLQJ
\RXUFOLHQWVRUVHUYHUVXSDQGUXQQLQJDQGGRLQJXVHIXOWDVNVZLOOUHTXLUHVRPHXQGHU
VWDQGLQJRIWKHEDVLFVRIQHWZRUNDGGUHVVLQJDQGSURWRFROVDQG\RXPD\ZDQWWRFRQ
VXOWRQHRIWKHPDQ\UHIHUHQFHVDYDLODEOHRQOLQHRURQHRIWKHVHLQWURGXFWRU\ERRNV
+HDG)LUVW1HWZRUNLQJE\$O$QGHUVRQDQG5\DQ%HQHGHWWL 2¦5HLOO\
1HWZRUN.QRZ+RZ$Q(VVHQWLDO*XLGHIRUWKH$FFLGHQWDO$GPLQE\-RKQ5RVV
1R6WDUFK3UHVV
:LQGRZV177&3,31HWZRUN$GPLQLVWUDWLRQE\&UDLJ+XQWDQG5REHUW%UXFH
7KRPSVRQ 2¦5HLOO\
0DNLQJ7KLQJV7DONE\7RP,JRH 2¦5HLOO\
451
Download from Wow! eBook <www.wowebook.com>
+HUHDUHVRPHRIWKHNH\FRQFHSWVLQWKLVFKDSWHU<RXPD\ZDQWWRH[SORUHWKHPLQ
PRUHGHSWKWKDQLVSRVVLEOHKHUH
(WKHUQHW
7KLVLVWKHORZOHYHOVLJQDOLQJOD\HUSURYLGLQJEDVLFSK\VLFDOPHVVDJHSDVVLQJFD
SDELOLW\6RXUFHDQGGHVWLQDWLRQDGGUHVVHVIRUWKHVHPHVVDJHVDUHLGHQWLILHGE\D
0HGLD$FFHVV&RQWURO 0$& DGGUHVV<RXU$UGXLQRVNHWFKGHILQHVD0$&DG
GUHVVYDOXHWKDWPXVWEHXQLTXHRQ\RXUQHWZRUN
7&3DQG,3
7UDQVPLVVLRQ&RQWURO3URWRFRO 7&3 DQG,QWHUQHW3URWRFRO ,3 DUHFRUH,QWHUQHW
SURWRFROV EXLOW DERYH (WKHUQHW 7KH\ SURYLGH D PHVVDJHSDVVLQJ FDSDELOLW\ WKDW
RSHUDWHVRYHUWKHJOREDO,QWHUQHW7&3,3PHVVDJHVDUHGHOLYHUHGWKURXJKXQLTXH
,3DGGUHVVHVIRUWKHVHQGHUDQGUHFHLYHU$VHUYHURQWKH,QWHUQHWXVHVDQXPHULF
ODEHO DGGUHVV WKDWQRRWKHUVHUYHUZLOOKDYHVRWKDWLWFDQEHXQLTXHO\LGHQWLILHG
7KLVDGGUHVVFRQVLVWVRIIRXUE\WHVXVXDOO\UHSUHVHQWHGZLWKGRWVVHSDUDWLQJWKH
E\WHV HJLVDQ,3DGGUHVVXVHGE\*RRJOH 7KH,QWHUQHWXVHVWKH
'LUHFWRU\1DPH6\VWHP '16 VHUYLFHWRWUDQVODWHWKHFRPPRQVHUYLFHQDPH KWWS
ZZZJRRJOHFRP WRWKHQXPHULF,3DGGUHVVEXWWKHVWDQGDUG$UGXLQR(WKHUQHW
OLEUDU\GRHVQRWLQFOXGHWKH'16FDSDELOLW\5HFLSHVKRZVKRZWRXVHDWKLUG
SDUW\'16OLEUDU\WRDGGWKLVFDSDELOLW\WR\RXUVNHWFKHV
/RFDO,3DGGUHVVHV
,I\RXKDYHPRUHWKDQRQHFRPSXWHUFRQQHFWHGWRWKH,QWHUQHWRQ\RXUKRPHQHW
ZRUNXVLQJDEURDGEDQGURXWHURUJDWHZD\HDFKFRPSXWHUSUREDEO\XVHVDORFDO
,3DGGUHVVWKDWLVSURYLGHGE\\RXUURXWHU7KHORFDODGGUHVVLVFUHDWHGXVLQJD
'\QDPLF+RVW&RQILJXUDWLRQ3URWRFRO '+&3 VHUYLFHLQ\RXUURXWHU7KH$UGXLQR
(WKHUQHWOLEUDU\GRHVQRWLQFOXGHD'+&3VHUYLFHVR\RXHLWKHUQHHGWRVHOHFWD
ORFDO,3DGGUHVVRUXVHDWKLUGSDUW\OLEUDU\WKDWDGGV'+&30RVWRIWKHUHFLSHV
LQWKLVFKDSWHUVKRZDXVHUVHOHFWHG,3DGGUHVVWKDW\RXPD\QHHGWRPRGLI\WRVXLW
\RXUQHWZRUN5HFLSHVKRZVKRZWKH,3DGGUHVVFDQEHREWDLQHGDXWRPDWLFDOO\
XVLQJ'+&3
:HEUHTXHVWVIURPDZHEEURZVHUDQGWKHUHVXOWDQWUHVSRQVHVXVH+\SHUWH[W7UDQVIHU
3URWRFRO +773 PHVVDJHV)RUDZHEFOLHQWRUVHUYHUWRUHVSRQGFRUUHFWO\LWPXVW
XQGHUVWDQGDQGUHVSRQGWR+773UHTXHVWVDQGUHVSRQVHV0DQ\RIWKHUHFLSHVLQWKLV
FKDSWHUXVHWKLVSURWRFRODQGUHIHUULQJWRRQHRIWKHUHIHUHQFHVOLVWHGHDUOLHUIRUPRUH
GHWDLOVZLOOKHOSZLWKXQGHUVWDQGLQJKRZWKHVHUHFLSHVZRUNLQGHWDLO
:HE SDJHV DUH XVXDOO\ IRUPDWWHG XVLQJ +\SHUWH[W 0DUNXS /DQJXDJH +70/ $O
WKRXJKLW¦VQRWHVVHQWLDOWRXVH+70/LI\RXDUHPDNLQJDQ$UGXLQRZHEVHUYHUDV
5HFLSHLOOXVWUDWHVWKHZHESDJHV\RXVHUYHFDQXVHWKLVFDSDELOLW\
([WUDFWLQJGDWDIURPDZHEVHUYHUSDJHLQWHQGHGWREHYLHZHGE\SHRSOHXVLQJDZHE
EURZVHUFDQEHDOLWWOHOLNHILQGLQJDQHHGOHLQDKD\VWDFNEHFDXVHRIDOOWKHH[WUDQHRXV
WH[WLPDJHVDQGIRUPDWWLQJWDJVXVHGRQDW\SLFDOSDJH7KLVWDVNLVVLPSOLILHGLQWKH
UHFLSHVKHUHZLWKDOLEUDU\ZULWWHQIRUWKLVERRNFDOOHG7H[W)LQGHU,WLVDYDLODEOHIURP
452 | Chapter 15:ಗEthernet and Networking
WKH$UGXLQR3OD\JURXQGDQGRQWKHZHEVLWHIRUWKLVERRN7H[W)LQGHUH[WUDFWVLQIRU
PDWLRQ IURP D VWUHDP RI GDWD ,W LV XVHG ZLWK WKH $UGXLQR (WKHUQHW OLEUDU\ WR ILQG
SDUWLFXODUVHTXHQFHVRIFKDUDFWHUVDQGWRJHWVWULQJVDQGQXPHULFYDOXHV
:HELQWHUFKDQJHIRUPDWVKDYHEHHQGHYHORSHGWRHQDEOHUHOLDEOHH[WUDFWLRQRIZHEGDWD
E\ FRPSXWHU VRIWZDUH ;0/ DQG -621 DUH WZR RI WKH PRVW SRSXODU IRUPDWV DQG
5HFLSHVKRZVDQH[DPSOHRIKRZWRGRWKLVXVLQJ$UGXLQR
15.1 Setting Up the Ethernet Shield
Problem
<RXZDQWWRVHWXSWKH(WKHUQHWVKLHOGWRXVHDKDUGFRGHG,3DGGUHVV
Solution
7KLVVNHWFKLVEDVHGRQWKH(WKHUQHWFOLHQWH[DPSOHVNHWFKGLVWULEXWHGZLWK$UGXLQR
&KHFNWKHGRFXPHQWDWLRQIRU\RXUQHWZRUNWRHQVXUHWKDWWKH$UGXLQR,3DGGUHVV WKH
YDOXHRIWKHipYDULDEOH LVYDOLGIRU\RXUQHWZRUN
#if ARDUINO > 18
#include <SPI.h>
#endif
// needed for Arduino versions later than 0018
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168 1, 177 };
// change to a valid address for your network
byte server[] = { 64, 233, 187, 99 }; // Google
// see text for more on IP addressing
Client client(server, 80);
void setup()
{
Ethernet.begin(mac, ip); // start ethernet using the mac and IP address
Serial.begin(9600);
// start the serial library:
delay(1000);
// give the ethernet hardware a second to initialize
Serial.println("connecting...");
if (client.connect()) {
Serial.println("connected");
client.println("GET /search?q=arduino HTTP/1.0"); // the HTTP request
client.println();
} else {
Serial.println("connection failed");
}
}
15.1 Setting Up the Ethernet Shield | 453
void loop()
{
if (client.available()) {
char c = client.read();
Serial.print(c); // echo all data received to the Serial Monitor
}
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
for(;;)
;
}
}
Discussion
7KLVVNHWFKSHUIRUPVD*RRJOHVHDUFKXVLQJWKHZRUG£DUGXLQR¤,WVSXUSRVHLVWRSUR
YLGHZRUNLQJFRGHWKDW\RXFDQXVHWRYHULI\WKDW\RXUQHWZRUNFRQILJXUDWLRQLVVXLWDEOH
IRUWKH$UGXLQR(WKHUQHWVKLHOG
7KHUHDUHIRXUDGGUHVVHVWKDWPXVWEHVHWXSFRUUHFWO\IRUWKHVNHWFKWRVXFFHVVIXOO\
FRQQHFWDQGGLVSOD\WKHUHVXOWVRIWKHVHDUFKRQWKH6HULDO0RQLWRU
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
7KH0$&DGGUHVVXQLTXHO\LGHQWLILHV\RXU(WKHUQHWVKLHOG(YHU\QHWZRUNGHYLFHPXVW
KDYHDGLIIHUHQW0$&DGGUHVVDQGLI\RXXVHPRUHWKDQRQH$UGXLQRVKLHOGRQ\RXU
QHWZRUNHDFKPXVWXVHDGLIIHUHQWDGGUHVV,I\RXKDYHDVLQJOH(WKHUQHWVKLHOG\RX
GRQ¦WQHHGWRFKDQJHWKLV
byte ip[] = { 192, 168 1, 177 };
network
// change this to a valid address for your
7KH,3DGGUHVVLVXVHGWRLGHQWLI\VRPHWKLQJWKDWLVFRPPXQLFDWLQJRQWKH,QWHUQHWDQG
PXVWDOVREHXQLTXHRQ\RXUQHWZRUN7KHDGGUHVVFRQVLVWVRIIRXUE\WHVDQGWKHUDQJH
RIYDOLGYDOXHVIRUHDFKE\WHGHSHQGVRQKRZ\RXUQHWZRUNLVFRQILJXUHG,3DGGUHVVHV
DUHXVXDOO\H[SUHVVHGZLWKGRWVVHSDUDWLQJWKHE\WHV¢IRUH[DPSOH,Q
DOOWKH$UGXLQRVNHWFKHVFRPPDVDUHXVHGLQVWHDGRIGRWVEHFDXVHWKHE\WHVDUHVWRUHG
LQDQDUUD\ VHH5HFLSH ,I\RXUQHWZRUNLVFRQQHFWHGWRWKH,QWHUQHWXVLQJDURXWHURUJDWHZD\\RXPD\QHHG
WRSURYLGHWKH,3DGGUHVVRIWKHJDWHZD\ZKHQ\RXFDOOWKH ethernet.beginIXQFWLRQ
<RXFDQILQGWKHDGGUHVVRIWKHJDWHZD\LQWKHGRFXPHQWDWLRQIRU\RXUURXWHUJDWHZD\
$GGDOLQHDIWHUWKH,3DQGVHUYHUDGGUHVVHVDWWKHWRSRIWKHVNHWFKZLWKWKHDGGUHVVRI
\RXUJDWHZD\
byte gateway[] ={ 192, 168, 1, 254 };
gateway
454 | Chapter 15:ಗEthernet and Networking
// add this if needed by your router or
$QGFKDQJHWKHILUVWOLQHLQsetupWRLQFOXGHWKHJDWHZD\DGGUHVVLQWKHVWDUWXSYDOXHV
IRU(WKHUQHW
Ethernet.begin(mac, ip, gateway);
7KHVHUYHUDGGUHVVFRQVLVWVRIWKHE\WH,3DGGUHVVRIWKHVHUYHU\RXZDQWWRFRQQHFW
WR¢LQWKLVFDVH*RRJOH6HUYHU,3DGGUHVVHVFKDQJHIURPWLPHWRWLPHVR\RXPD\
QHHGWRXVHWKHSLQJXWLOLW\RI\RXURSHUDWLQJV\VWHPWRILQGDFXUUHQW,3DGGUHVVIRUWKH
VHUYHU\RXZLVKWRFRQQHFWWR
byte server[] = { 64, 233, 187, 99 }; // Google
7KHOLQHDWWKHWRSRIWKHVNHWFKWKDWLQFOXGHV <SPI.h>LVUHTXLUHGIRU
$UGXLQRUHOHDVHVVWDUWLQJDWEXWQRWIRUHDUOLHUYHUVLRQV7KHFRGH
LQWKHVNHWFKKHUHXVHVDFRQGLWLRQDOFKHFNWRHQDEOHLWWRZRUNLQDQ\
YHUVLRQ6HH5HFLSHIRUPRUHRQFRQGLWLRQDOGHILQHV
See Also
7KH ZHE UHIHUHQFH IRU JHWWLQJ VWDUWHG ZLWK WKH $UGXLQR (WKHUQHW VKLHOG LV DW KWWS
DUGXLQRFFHQ*XLGH$UGXLQR(WKHUQHW6KLHOG
15.2 Obtaining Your IP Address Automatically
Problem
7KH,3DGGUHVV\RXXVHIRUWKH(WKHUQHWVKLHOGPXVWEHXQLTXHRQ\RXUQHWZRUNDQG
\RX ZRXOG OLNH WKLV WR EH DOORFDWHG DXWRPDWLFDOO\ <RX ZDQW WKH (WKHUQHW VKLHOG WR
REWDLQDQ,3DGGUHVVIURPD'+&3VHUYHU
Solution
7KLVLVWKHVNHWFKIURP5HFLSHZLWKWKHEROGHGOLQHVDGGHGWRXVHWKH'+&3OLEUDU\
#if ARDUINO > 18
#include <SPI.h>
#endif
// needed for Arduino versions later than 0018
#include <Ethernet.h>
#include "Dhcp.h"
// add this for the DHCP library
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// IP addressing lines removed
byte server[] = { 209,85,229,104 }; // Google
Client client(server, 80);
15.2 Obtaining Your IP Address Automatically | 455
void setup()
{
Serial.begin(9600);
if(Dhcp.beginWithDHCP(mac) == 1)
// begin method returns 1 if successful
{
Serial.println("got IP address, connecting...");
delay(5000);
}
else
{
Serial.println("unable to acquire ip address!");
while(true)
; // do nothing
}
}
if (client.connect()) {
Serial.println("connected");
client.println("GET /search?q=arduino HTTP/1.0");
client.println();
} else {
Serial.println("connection failed");
}
void loop()
{
if (client.available()) {
char c = client.read();
Serial.print(c);
}
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
for(;;)
;
}
}
Discussion
7KHOLEUDU\GLVWULEXWHGZLWKWKH$UGXLQRUHOHDVHGRHVQRWVXSSRUW'+&3 DWWKHWLPH
RIWKLVZULWLQJ EXW\RXFDQREWDLQDWKLUGSDUW\OLEUDU\IURPWKLVERRN¦VZHEVLWHRU
IURPKWWSEORJMRUGDQWHUUHOOFRPSRVW$UGXLQR'+&3/LEUDU\9HUVLRQDVS[&RS\
WKHFRQWHQWVRIWKHGRZQORDGLQWRWKH$UGXLQR?KDUGZDUH?OLEUDULHV?(WKHUQHWIROGHU
7KHKLJKOLJKWHGOLQHVVKRZWKHGLIIHUHQFHVIURPWKHVNHWFKLQ5HFLSH7KHUHLVQR
,3RUJDWHZD\DGGUHVVYDULDEOHWKHVHDUHDFTXLUHGIURP\RXU'+&3VHUYHUZKHQWKH
VNHWFKVWDUWV
456 | Chapter 15:ಗEthernet and Networking
,I\RXZDQWWRVHHWKHYDOXHVUHWXUQHGIURPWKH'+&3VHUYHURQWKH6HULDO0RQLWRUXVH
WKHIROORZLQJsetupIXQFWLRQ
void setup()
{
Serial.begin(9600);
if(Dhcp.beginWithDHCP(mac) == 1)
// begin method returns 1 if successful
{
byte buffer[6];
Serial.println("ip acquired...");
// show the values returned from the DHCP server
Dhcp.getLocalIp(buffer);
Serial.print("ip address: ");
printArray(&Serial, ".", buffer, 4, 10);
Dhcp.getSubnetMask(buffer);
Serial.print("subnet mask: ");
printArray(&Serial, ".", buffer, 4, 10);
Dhcp.getGatewayIp(buffer);
Serial.print("gateway ip: ");
printArray(&Serial, ".", buffer, 4, 10);
Dhcp.getDhcpServerIp(buffer);
Serial.print("dhcp server ip: ");
printArray(&Serial, ".", buffer, 4, 10);
Dhcp.getDnsServerIp(buffer);
Serial.print("dns server ip: ");
printArray(&Serial, ".", buffer, 4, 10);
}
delay(5000);
}
else
{
Serial.println("unable to acquire ip address!");
while(true)
; // do nothing
}
if (client.connect()) {
Serial.println("connected");
client.println("GET /search?q=arduino HTTP/1.0");
client.println();
} else {
Serial.println("connection failed");
}
$QGDGGWKLVIXQFWLRQWRWKHHQGRIWKHVNHWFKWRSURGXFHWKHIRUPDWWHGRXWSXWWKDWLV
VHQWWRWKH6HULDO0RQLWRU
void printArray(Print *output, char* delimeter, byte* data, int len, int base)
{
char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
15.2 Obtaining Your IP Address Automatically | 457
Download from Wow! eBook <www.wowebook.com>
for(int i = 0; i < len; i++)
{
if(i != 0)
output->print(delimeter);
}
}
output->print(itoa(data[i], buf, base));
output->println();
5XQQLQJWKLVVNHWFKZLOOGLVSOD\WKH,3FRQILJXUDWLRQLQIRUPDWLRQUHFHLYHGIURP\RXU
'+&3VHUYHURQWKH6HULDO0RQLWRU
IP address: 192.168.1.177
subnet mask: 255.255.255.0
gateway IP: 192.168.1.254
DHCP server IP: 192.168.1.254
DNS server IP: 192.168.1.254
15.3 Resolving Hostnames to IP Addresses (DNS)
Problem
<RXZDQWWRXVHDVHUYHUQDPH¢IRUH[DPSOH\DKRRFRP¢UDWKHUWKDQDVSHFLILF,3
DGGUHVV:HESURYLGHUVRIWHQKDYHDUDQJHRI,3DGGUHVVHVXVHGIRUWKHLUVHUYHUVDQGD
VSHFLILFDGGUHVVPD\QRWEHLQVHUYLFHZKHQ\RXQHHGWRFRQQHFW
Solution
<RXFDQXVH'16WRORRNXSDYDOLG,3DGGUHVVIRUWKHQDPH\RXSURYLGH7KLVH[DPSOH
XVHV'16FRGHIURP0DWW5REHUWVRQDWKWWSNHJJHUJRRJOHFRGHFRPILOHV(WKHUQHW]LS
/*
* WebClientDNS sketch
*/
#if ARDUINO > 18
#include <SPI.h>
#endif
// needed for Arduino versions later than 0018
#include "Ethernet_dns.h"
#include "Dns.h"
// uses DNS library from Matt Robertson
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = {192, 168, 1, 177 };
// change to a valid address for your network
byte gateway[] ={192, 168, 1, 254 }; // add this if you use a router or gateway
// see text for more on IP addressing
byte subnet[] ={255, 255, 255, 0 };
// this defines the subnet address
458 | Chapter 15:ಗEthernet and Networking
byte ipBuffer[6];
// this will get the server IP address from DNS
Client client(ipBuffer, 80);
DnsClass Dns;
//Client client(ipBuffer, server, 80);
void setup()
{
Serial.begin(9600);
Ethernet.begin(mac, ip, gateway, subnet);
//// Do DNS Lookup
Serial.println("getting server address");
Dns.init("google.com", ipBuffer); //Buffer has IP address of the DNS server
Dns.resolve();
int results;
while(!(results=Dns.finished())) ;
//wait for DNS to resolve the name
if(results != 1){
Serial.print("DNS Error code: ");
Serial.print(results,DEC);
while(true)
; // do nothing
}
delay(5000);
if (client.connect()) {
Serial.println("connected");
client.println("GET /search?q=arduino HTTP/1.0");
client.println();
}
else {
Serial.println("connection failed");
}
}
void loop()
{
if (client.available()) {
char c = client.read();
Serial.print(c);
}
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
for(;;)
;
}
}
15.3 Resolving Hostnames to IP Addresses (DNS) | 459
Discussion
7KLVFRGHLVVLPLODUWRWKHFRGHLQ5HFLSHLWGRHVD*RRJOHVHDUFKIRU£DUGXLQR¤
%XWLQWKLVYHUVLRQLWLVQRWQHFHVVDU\WRSURYLGHWKH*RRJOH,3DGGUHVV¢LWLVREWDLQHG
WKURXJKDUHTXHVWWRWKH,QWHUQHW'16VHUYLFH
7KHUHTXHVWLVDFKLHYHGWKURXJKWKHVHIXQFWLRQFDOOV
Dns.init("google.com", ipBuffer); //Buffer contains the IP address of the DNS
server
Dns.resolve();
while(!(results=Dns.finished())) ; //wait for DNS to resolve the name
7KHDns.InitIXQFWLRQLVFDOOHGZLWKWZRSDUDPHWHUVWKHVHUYHU KRVW QDPHWRORRNXS
DQGWKHFKDUDFWHUDUUD\WRKROGWKH,3DGGUHVVLIWKHORRNXSLVVXFFHVVIXODns.resolve
VHQGVWKHUHTXHVWDQGDns.finishedUHWXUQVWKHVWDWXVRIWKHUHSO\+HUHDUHWKHYDOXHV
WKDWFDQEHUHWXUQHGIURPDns.finished
1 = success
2 = No DNS records found
3 = timeout
greater than 16 is an error code provided by the DNS server
7KH VNHWFK FKHFNV WKH YDOXH UHWXUQHG IURP Dns.finished¢LI LW LV 1 WKH YDULDEOH
ipBufferZLOOFRQWDLQDYDOLG,3DGGUHVVRWKHUZLVHLWLVDQHUURUWKDWLVSULQWHGWRWKH
6HULDO0RQLWRU
<RXFDQYLHZWKH,3DGGUHVVXVLQJWKHIROORZLQJFRGH
Dns.getIP(ipBuffer); //buffer now contains the IP address for server given in
Dns.Init()
Serial.print("Google address: ");
printIp(ipBuffer);
7KHprintIpIXQFWLRQLV
void printIp(byte *rawData)
{
for(int i=0; i < 4; i++){
Serial.print(rawData[i],DEC);
if(i < 3)
Serial.print('.');
}
Serial.println();
}
<RXFDQXVH'16DQG'+&3WRJHWKHU+HUHLVWKHVNHWFKZLWK'+&3IXQFWLRQDOLW\
DGGHG VHH5HFLSH /*
* WebClientDHCP_DNS sketch
*/
#if ARDUINO > 18
#include <SPI.h>
// needed for Arduino versions later than 0018
#endif
460 | Chapter 15:ಗEthernet and Networking
#include "Ethernet_dns.h"
#include "Dhcp.h"
// add this for the DHCP library
#include "Dns.h"
// uses DNS library from Matt Robertson
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ipBuffer[6];
Client client(ipBuffer, 80);
DnsClass Dns;
//Client client(ipBuffer, server, 80);
void setup()
{
Serial.begin(9600);
if(Dhcp.beginWithDHCP(mac) == 1)
// begin method returns 1 if successful
{
Serial.println("got IP address");
//// Do DNS Lookup
Serial.println("getting server address");
Dns.init("google.com", ipBuffer); //Buffer has IP address of the DNS server
Dns.resolve();
int results;
while(!(results=Dns.finished())) ;
//wait for DNS to resolve the name
if(results != 1){
Serial.print("DNS Error code: ");
Serial.print(results,DEC);
while(true)
; // do nothing
}
delay(5000);
}
}
else
{
Serial.println("unable to acquire ip address!");
while(true)
; // do nothing
}
if (client.connect()) {
Serial.println("connected");
client.println("GET /search?q=arduino HTTP/1.0");
client.println();
} else {
Serial.println("connection failed");
}
void loop()
{
if (client.available()) {
char c = client.read();
Serial.print(c);
}
15.3 Resolving Hostnames to IP Addresses (DNS) | 461
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
for(;;)
;
}
}
15.4 Requesting Data from a Web Server
Problem
<RXZDQW$UGXLQRWRJHWGDWDIURPDZHEVHUYHU)RUH[DPSOH\RXZDQWWRILQGDQG
XVHVSHFLILFYDOXHVUHWXUQHGIURPDZHEVHUYHU
Solution
7KLVVNHWFKXVHV*RRJOH&DOFXODWRUWRFRQYHUWNLORPHWHUVWRPLOHV,WVHQGVWKHTXHU\
£ZKDWLVNPLQPL¤DQGSULQWVWKHUHVXOWWRWKH6HULDO0RQLWRU
/*
* SimpleClientwFinder sketch
*
*/
#if ARDUINO > 18
#include <SPI.h>
#endif
// needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <TextFinder.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1,177 };
//byte gateway[] ={ 192, 168, 1, 254 };
//byte subnet[] ={ 255, 255, 255, 0 };
byte server[] = { 173,194,33,104 }; // Google
Client client(server, 80);
TextFinder finder( client);
int result; // the result of the google calculation
void setup()
{
Ethernet.begin(mac, ip);
Serial.begin(9600);
delay(2000);
Serial.println("connecting...");
462 | Chapter 15:ಗEthernet and Networking
}
void loop()
{
if (client.connect()) {
Serial.print("connected... ");
client.println("GET /search?hl=en&q=what+is+50+km+in+mi HTTP/1.1");
client.println();
} else {
Serial.println("connection failed");
}
if (client.connected()) {
if(finder.find("<b>50 kilometers")){
if(finder.find("=")){
result = finder.getValue();
Serial.println(result);
}
}
else
Serial.println("result not found");
client.stop();
delay(10000); // check again in 10 seconds
}
else {
Serial.println();
Serial.println("not connected");
client.stop();
delay(1000);
}
}
Discussion
7KH VNHWFK DVVXPHV WKH UHVXOWV ZLOO EH UHWXUQHG LQ EROG XVLQJ WKH +70/ <b> WDJ
IROORZHGE\WKHYDOXHJLYHQLQWKHTXHU\DQGWKHZRUGNLORPHWHUV
7KHVHDUFKLQJLVGRQHXVLQJWKH7H[W)LQGHUOLEUDU\GHVFULEHGLQWKLVFKDSWHU¦VLQWUR
GXFWLRQ7KHfindPHWKRGVHDUFKHVWKURXJKWKHUHFHLYHGGDWDDQGUHWXUQVtrueLILWILQGV
WKHWDUJHWVWULQJ7KHFRGHORRNVIRUWH[WDVVRFLDWHGZLWKWKHUHSO\,QWKLVH[DPSOHLW
WULHVWRILQG£E!NLORPHWHUV¤XVLQJWKLVOLQH
if(finder.find("<b>50 kilometers")){
finderLVXVHGDJDLQWRILQGWKHHTXDOVVLJQ = WKDWSUHFHGHVWKHQXPHULFDOYDOXHRIWKH
UHVXOW
7KHUHVXOWLVREWDLQHGXVLQJWKHgetvaluePHWKRGDQGLVSULQWHGWRWKH6HULDO0RQLWRU
getValueUHWXUQVDQLQWHJHUYDOXHLI\RXZDQWWRJHWDIORDWLQJSRLQWYDOXHXVH get
FloatLQVWHDG
Float floatResult = finder.getFloat();
Serial.println(floatResult);
15.4 Requesting Data from a Web Server | 463
,I\RXZDQW\RXUVHDUFKHVWREHUREXVW\RXQHHGWRORRNIRUDXQLTXHWDJWKDWZLOORQO\
EHIRXQGSUHFHGLQJWKHGDWD\RXZDQW7KLVLVHDVLHUWRDFKLHYHRQSDJHVWKDWXVHXQLTXH
WDJVIRUHDFKILHOGVXFKDVWKLVH[DPSOHWKDWJHWVWKH*RRJOHVWRFNSULFHIURP*RRJOH
)LQDQFHDQGZULWHVWKHYDOXHWRDQDORJRXWSXWSLQDQGWRWKH6HULDO0RQLWRU
/*
* WebClientGoogleFinance sketch
* get the stock value for google and write to analog pin.
*/
#if ARDUINO > 18
#include <SPI.h>
// needed for Arduino versions later than 0018
#endif
#include <Ethernet.h>
#include <TextFinder.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168,1,177 };
byte gateway[] ={ 192, 168, 1, 254 };
byte subnet[] ={ 255, 255, 255, 0 };
byte server[] = {209,85,229,147 };
Client client(server, 80);
// google
TextFinder finder( client );
float value;
void setup()
{
Ethernet.begin(mac, ip, gateway, subnet);
Serial.begin(9600);
delay(2000);
}
void loop()
{
Serial.print("Connecting...");
if (client.connect()) {
client.println("GET //finance?q=google HTTP/1.0"); // todo
client.println("User-Agent: AVR ethernet");
client.println();
}
else
{
Serial.println("connection failed");
}
if (client.connected()) {
if(finder.find("<span class=\"pr\">"))
{
finder.find(">"); // seek past the next '>'
value = finder.getFloat();
Serial.println(value);
analogWrite(0, value);
}
464 | Chapter 15:ಗEthernet and Networking
else
Serial.print("Could not find field");
}
else {
Serial.println("Disconnected");
}
client.stop();
client.flush();
delay(5000); // 5 seconds between each connect attempt
}
7KHVHH[DPSOHVXVHWKH GETFRPPDQGWRUHTXHVWDVSHFLILFSDJH6RPHZHEUHTXHVWV
QHHGGDWDWREHVHQWWRWKHVHUYHUZLWKLQWKHERG\RIWKHPHVVDJHEHFDXVHWKHUHLVPRUH
GDWDWREHVHQWWKDQFDQEHKDQGOHGE\WKHGETFRPPDQG7KHVHUHTXHVWVDUHKDQGOHG
XVLQJWKHPOSTFRPPDQG+HUHLVDQH[DPSOHRIPOSTWKDWXVHVWKH%DEHO)LVKODQJXDJH
WUDQVODWLRQVHUYLFHWRWUDQVODWHWH[WIURP,WDOLDQLQWR(QJOLVK
/*
* WebClient_Babelfish sketch
* Uses Post to get data from a web server
*
*/
#if ARDUINO > 18
#include <SPI.h>
// needed for Arduino versions later than 0018
#endif
#include <Ethernet.h>
#include <TextFinder.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168,1,177 };
byte gateway[] ={ 192, 168, 1, 254 };
byte subnet[] ={ 255, 255, 255, 0 };
byte server[] = {66,196,80,202 }; //babelfish.yahoo.com
Client client(server, 80);
// the text to translate
char * transText = "trtext=Ciao+mondo+da+Arduino.&lp=it_en";
char buffer [31];
TextFinder
// room for 30 characters and the terminating null
finder(client);
void setup()
{
Ethernet.begin(mac, ip, gateway, subnet);
Serial.begin(9600);
delay(3000);
}
void loop()
{
postPage( "/translate_txt", transText);
15.4 Requesting Data from a Web Server | 465
}
delay(5000);
void postPage(char *webPage, char *parameter){
if (client.connect()) {
client.print("POST ");
client.print(webPage);
client.println(" HTTP/1.0");
client.println("Content-Type: application/x-www-form-urlencoded");
client.println("Host: babelfish.yahoo.com");
client.print("Content-Length: ");
client.println(strlen(parameter));
client.println();
client.println(parameter);
}
else {
Serial.println(" connection failed");
}
if (client.connected()) {
finder.find("<div id=\"result\">");
finder.getString( ">", "<" ,buffer, sizeof(buffer));
Serial.println(buffer);
}
else {
Serial.println("Disconnected");
}
client.stop();
client.flush();
}
6LWHV VXFK DV *RRJOH :HDWKHU DQG *RRJOH )LQDQFH JHQHUDOO\ NHHS WKH WDJV XVHG WR
LGHQWLI\ILHOGVXQFKDQJHG%XWLIVRPHIXWXUHXSGDWHWRDVLWHGRHVFKDQJHWKHWDJV\RX
DUHVHDUFKLQJIRU\RXUVNHWFKZLOOQRWIXQFWLRQFRUUHFWO\XQWLO\RXFRUUHFWWKHVHDUFK
FRGH$PRUHUHOLDEOHZD\WRH[WUDFWGDWDIURPDZHEVHUYHULVWRXVHDIRUPDOSURWRFRO
VXFKDV;0/RU-6217KHQH[WUHFLSHVKRZVKRZWRH[WUDFWLQIRUPDWLRQIURPDVLWH
WKDWXVHV;0/
15.5 Requesting Data from a Web Server Using XML
Problem
<RXZDQWWRUHWULHYHGDWDIURPDVLWHWKDWSXEOLVKHVLQIRUPDWLRQLQ;0/IRUPDW)RU
H[DPSOH\RXZDQWWRXVHYDOXHVIURPVSHFLILFILHOGVLQRQHRIWKH*RRJOH$3,VHUYLFHV
Solution
7KLVVNHWFKUHWULHYHVWKHZHDWKHULQ/RQGRQIURPWKH*RRJOH:HDWKHUVLWH,WXVHVWKH
*RRJOH;0/$3,
/*
* SimpleClientGoogleWeatherDHCP
466 | Chapter 15:ಗEthernet and Networking
* gets xml data from http://www.google.com/ig/api?weather=london,uk
* reads temperature from field: <temp_f data="66" />
* writes temperature to analog output port.
*/
#if ARDUINO > 18
#include <SPI.h>
#endif
// needed for Arduino versions later than 0018
#include <Ethernet.h>
#include "Dhcp.h" //from: http://blog.jordanterrell.com/post/
Arduino-DHCP-Library-Version-04.aspx
#include <TextFinder.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte server[] = {209,85,229,104 }; // Google
Client client(server, 80);
TextFinder
finder( client );
void setup()
{
Serial.begin(9600);
if(Dhcp.beginWithDHCP(mac) == 1) { // begin method returns 1 if successful
Serial.println("got IP address, connecting...");
delay(5000);
}
else {
Serial.println("unable to acquire ip address!");
while(true)
; // do nothing
}
}
void loop()
{
if (client.connect()) {
// get google weather for London
client.println("GET /ig/api?weather=london,uk HTTP/1.0");
client.println();
}
else {
Serial.println(" connection failed");
}
if (client.connected()) {
// get temperature in fahrenheit (use field "<temp_c data=\"" for Celsius)
if(finder.find("<temp_f data=") )
{
int temperature = finder.getValue();
analogWrite(3, temperature);
// write value to analog port
Serial.print("Temperature is "); // and echo it to the serial port
Serial.println(temperature);
}
15.5 Requesting Data from a Web Server Using XML | 467
else
Serial.print("Could not find temperature field");
}
else {
Serial.println("Disconnected");
}
client.stop();
client.flush();
delay(60000); // wait a minute before next update
}
(DFKILHOGLVSUHFHGHGE\DWDJDQGWKHRQHLQGLFDWLQJWKHWHPSHUDWXUHLQ)DKUHQKHLW
RQ*RRJOH:HDWKHULV"<temp_f data="
2QWKLVVLWHLI\RXZDQWWKHWHPSHUDWXUHLQ&HOVLXV\RXZRXOGORRNIRUWKHWDJ"<temp_c
data="
<RXZLOOQHHGWRFRQVXOWWKHGRFXPHQWDWLRQIRUWKHSDJH\RXDUHLQWHUHVWHGLQWRILQG
WKHUHOHYDQWWDJIRUWKHGDWD\RXZDQW
<RXVHOHFWWKHSDJHWKURXJKWKHLQIRUPDWLRQVHQWLQ\RXUGETVWDWHPHQW7KLVDOVRGH
SHQGVRQWKHSDUWLFXODUVLWHEXWLQWKHSUHFHGLQJH[DPSOHWKHFLW\LVVHOHFWHGE\WKH
WH[WDIWHUWKHHTXDOVVLJQIROORZLQJWKH GETVWDWHPHQW)RUH[DPSOHWRFKDQJHWKHOR
FDWLRQIURP/RQGRQWR1HZ<RUNFKDQJH
client.println("GET /ig/api?weather=london,uk HTTP/1.0");
// weather for London
WR
client.println("GET /ig/api?weather=New York,NY HTTP/1.0"); // weather for
New York
<RXFDQXVHDYDULDEOHLI\RXZDQWWKHORFDWLRQWREHVHOHFWHGXQGHUSURJUDPFRQWURO
char *cityString[4] = { "London", "New%20York", "Rome", "Tokyo"};
int
city;
void loop()
{
city = random(4); // get a random city
if (client.connect()) {
client.print("GET /ig/api?weather=");
client.print(cityString[city]); // print one of 4 random cities
client.println(" HTTP/1.0");
client.println();
}
else {
Serial.println(" connection failed");
}
if (client.connected()) {
// get temperature in fahrenheit (use field "<temp_c data=\"" for Celsius)
if(finder.find("<temp_f data=") )
{
int temperature = finder.getValue();
analogWrite(3, temperature);
// write value to the analog port
Serial.print(cityString[city]);
468 | Chapter 15:ಗEthernet and Networking
Serial.print(" temperature is ");
Serial.println(temperature);
// and echo it to the serial port
}
else
Serial.println("Could not find temperature field");
}
// the remainder of the code is the same as the previous sketch
,QIRUPDWLRQVHQWLQ85/VFDQQRWFRQWDLQVSDFHVZKLFKLVZK\1HZ
<RUNLVZULWWHQDV£1HZ<RUN¤7KHHQFRGLQJWRLQGLFDWHDVSDFHLV
<RXUEURZVHUGRHVWKHHQFRGLQJEHIRUHLWVHQGVDUHTXHVWEXWRQ
$UGXLQR\RXPXVWWUDQVODWHVSDFHVWR\RXUVHOI
15.6 Setting Up an Arduino to Be a Web Server
Problem
<RXZDQW$UGXLQRWRVHUYHZHESDJHV)RUH[DPSOH\RXZDQWWRXVH\RXUZHEEURZVHU
WRYLHZWKHYDOXHVRIVHQVRUVFRQQHFWHGWR$UGXLQRDQDORJSLQV
Solution
7KLVLVWKHVWDQGDUG$UGXLQR:HE6HUYHUH[DPSOHVNHWFKGLVWULEXWHGZLWK$UGXLQRWKDW
VKRZVWKHYDOXHRIWKHDQDORJLQSXWSLQV7KLVUHFLSHH[SODLQVKRZWKLVVNHWFKZRUNV
DQGKRZLWFDQEHH[WHQGHG
/*
* Web Server
*
* A simple web server that shows the value of the analog input pins.
*/
#if ARDUINO > 18
#include <SPI.h>
// needed for Arduino versions later than 0018
#endif
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 177};
Server server(80);
void setup()
{
Ethernet.begin(mac, ip);
server.begin();
}
void loop()
{
Client client = server.available();
15.6 Setting Up an Arduino to Be a Web Server | 469
if (client) {
// an http request ends with a blank line
boolean current_line_is_blank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if we've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so we can send a reply
if (c == '\n' && current_line_is_blank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
// output the value of each analog input pin
for (int i = 0; i < 6; i++) {
client.print("analog input ");
client.print(i);
client.print(" is ");
client.print(analogRead(i));
client.println("<br />");
}
break;
}
if (c == '\n') {
// we're starting a new line
current_line_is_blank = true;
} else if (c != '\r') {
// we've gotten a character on the current line
current_line_is_blank = false;
}
}
}
}
// give the web browser time to receive the data
delay(1);
client.stop();
}
Discussion
$VGLVFXVVHGLQ5HFLSHDOORIWKHVNHWFKHVXVLQJWKH(WKHUQHWOLEUDU\QHHGDXQLTXH
0$&DGGUHVVDQG,3DGGUHVV7KH,3DGGUHVV\RXDVVLJQLQWKLVVNHWFKGHWHUPLQHVWKH
DGGUHVVRIWKHZHEVHUYHU,QWKLVH[DPSOHW\SLQJLQWR\RXUEURZVHU¦V
DGGUHVVEDUVKRXOGGLVSOD\DSDJHVKRZLQJWKHYDOXHVRQDQDORJLQSXWSLQVWKURXJK
VHH&KDSWHUIRUPRUHRQWKHDQDORJSRUWV $VGHVFULEHGLQWKLVFKDSWHU¦VLQWURGXFWLRQLVDORFDODGGUHVVWKDWLVRQO\
YLVLEOH RQ \RXU ORFDO QHWZRUN ,I \RX ZDQW WR H[SRVH \RXU ZHE VHUYHU WR WKH HQWLUH
,QWHUQHW \RX ZLOO QHHG WR FRQILJXUH \RXU URXWHU WR IRUZDUG LQFRPLQJ PHVVDJHV WR
$UGXLQR 7KH WHFKQLTXH LV FDOOHG SRUW IRUZDUGLQJ DQG \RX ZLOO QHHG WR FRQVXOW WKH
GRFXPHQWDWLRQIRU\RXUURXWHUWRVHHKRZWRVHWWKLVXS )RUPRUHRQSRUWIRUZDUGLQJ
470 | Chapter 15:ಗEthernet and Networking
LQJHQHUDOVHH66+7KH6HFXUH6KHOO7KH'HILQLWLYH*XLGHE\'DQLHO-%DUUHWW5LFKDUG
(6LOYHUPDQDQG5REHUW*%\UQHV>2¦5HLOO\@
&RQILJXULQJ\RXU$UGXLQR(WKHUQHWERDUGWREHYLVLEOHRQWKH,QWHUQHW
PDNHVWKHERDUGDFFHVVLEOHWRDQ\RQHZLWKWKH,3DGGUHVV7KH$UGXLQR
(WKHUQHWOLEUDU\GRHVQRWRIIHUVHFXUHFRQQHFWLRQVVREHFDUHIXODERXW
WKHLQIRUPDWLRQ\RXH[SRVH
7KHWZROLQHVLQsetupLQLWLDOL]HWKH(WKHUQHWOLEUDU\DQGFRQILJXUH\RXUZHEVHUYHUWR
WKH,3DGGUHVV\RXSURYLGH7KHloopZDLWVIRUDQGWKHQSURFHVVHVHDFKUHTXHVWUHFHLYHG
E\WKHZHEVHUYHU
Client client = server.available();
7KHclientFODVVKHUHLVDFWXDOO\WKHZHEVHUYHU¢LWSURFHVVHVPHVVDJHVIRUWKH,3DGGUHVV
\RXJDYHWKHVHUYHU
if (client)WHVWVWKDWWKHFOLHQWKDVEHHQVXFFHVVIXOO\VWDUWHG
while (client.connected())WHVWVLIWKHZHEVHUYHULVFRQQHFWHGWRDFOLHQWPDNLQJD
UHTXHVW
client.available()DQG client.read()FKHFNLIGDWDLVDYDLODEOHDQGUHDGDE\WHLILW
LV7KLVLVVLPLODUWR Serial.available()GLVFXVVHGLQ&KDSWHUH[FHSWWKHGDWDLV
FRPLQJIURPWKH,QWHUQHWUDWKHUWKDQWKHVHULDOSRUW7KHFRGHUHDGVGDWDXQWLOLWILQGV
WKHILUVWOLQHZLWKQRGDWDVLJQLI\LQJWKHHQGRIDUHTXHVW$Q+773KHDGHULVVHQWXVLQJ
WKH client.printlnFRPPDQGVIROORZHGE\WKHSULQWLQJRIWKHYDOXHVRIWKHDQDORJ
SRUWV
15.7 Handling Incoming Web Requests
Problem
<RXZDQWWRFRQWUROGLJLWDODQGDQDORJRXWSXWVZLWK$UGXLQRDFWLQJDVDZHEVHUYHU
)RUH[DPSOH\RXZDQWWRFRQWUROWKHYDOXHVRIVSHFLILFSLQVWKURXJKSDUDPHWHUVVHQW
IURP\RXUZHEEURZVHU
Solution
7KLVVNHWFKUHDGVUHTXHVWVVHQWIURPDEURZVHUDQGFKDQJHVWKHYDOXHVRIGLJLWDODQG
DQDORJRXWSXWSRUWVDVUHTXHVWHG
7KH 85/ EURZVHU UHTXHVW FRQWDLQV RQH RU PRUH ILHOGV VWDUWLQJ ZLWK WKH ZRUG SLQ
IROORZHGE\D'IRUGLJLWDORU$IRUDQDORJDQGWKHSLQQXPEHU7KHYDOXHIRUWKHSLQ
IROORZVDQHTXDOVVLJQ
15.7 Handling Incoming Web Requests | 471
)RUH[DPSOHVHQGLQJKWWS"SLQ' IURP\RXUEURZVHU¦VDGGUHVVEDU
WXUQVGLJLWDOSLQRQKWWS"SLQ' WXUQVSLQRII 6HH&KDSWHULI
\RXQHHGLQIRUPDWLRQRQFRQQHFWLQJ/('VWR$UGXLQRSLQV
)LJXUHVKRZVZKDW\RXZLOOVHHRQ\RXUZHEEURZVHUZKHQFRQQHFWHGWRWKHZHE
VHUYHUFRGHWKDWIROORZV
/*
* WebServerParsing
*
* Respond to requests in the URL to change digital and analog output ports
* show the number of ports changed and the value of the analog input pins.
*
*/
#if ARDUINO > 18
#include <SPI.h>
// needed for Arduino versions later than 0018
#endif
##include <Ethernet.h>
#include <TextFinder.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1,177 };
Server server(80);
void setup()
{
Serial.begin(9600);
Ethernet.begin(mac, ip);
server.begin();
Serial.println("ready");
}
void loop()
{
Client client = server.available();
if (client) {
TextFinder finder(client );
while (client.connected()) {
if (client.available()) {
// counters to show the number of pin change requests
int digitalRequests = 0;
int analogRequests = 0;
if( finder.find("GET /") ) {
// find tokens starting with "pin" and stop on the first blank line
while(finder.findUntil("pin", "\n\r")){
char type = client.read(); // D or A
int pin = finder.getValue();
int val = finder.getValue();
if( type == 'D') {
Serial.print("Digital pin ");
pinMode(pin, OUTPUT);
digitalWrite(pin, val);
digitalRequests++;
472 | Chapter 15:ಗEthernet and Networking
}
else if( type == 'A'){
Serial.print("Analog pin ");
analogWrite(pin, val);
analogRequests++;
}
else {
Serial.print("Unexpected type ");
Serial.print(type);
}
Serial.print(pin);
Serial.print("=");
Serial.println(val);
}
}
Serial.println();
// the findUntil has detected the blank line (a lf followed by cr)
// so the http request has ended and we can send a reply
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
// output the number of pins handled by the request
client.print(digitalRequests);
client.print(" digital pin(s) written");
client.println("<br />");
client.print(analogRequests);
client.print(" analog pin(s) written");
client.println("<br />");
client.println("<br />");
// output the value of each analog input pin
for (int i = 0; i < 6; i++) {
client.print("analog input ");
client.print(i);
client.print(" is ");
client.print(analogRead(i));
client.println("<br />");
}
break;
}
}
// give the web browser time to receive the data
delay(1);
client.stop();
}
}
15.7 Handling Incoming Web Requests | 473
)LJXUH%URZVHUSDJHGLVSOD\LQJRXWSXWFUHDWHGE\WKLVUHFLSH¦V6ROXWLRQ
Discussion
7KLVLVZKDWZDVVHQWKWWS"SLQ' +HUHLVKRZWKHLQIRUPDWLRQLV
EURNHQGRZQ(YHU\WKLQJEHIRUHWKHTXHVWLRQPDUNLVWUHDWHGDVWKHDGGUHVVRIWKHZHE
VHUYHU LQWKLVH[DPSOHWKLVDGGUHVVLVWKH,3DGGUHVVVHWDWWKHWRSRI
WKHVNHWFKIRUWKH$UGXLQRERDUG 7KHUHPDLQLQJGDWDLVDOLVWRIILHOGVHDFKEHJLQQLQJ
ZLWKWKHZRUGSLQIROORZHGE\D'LQGLFDWLQJDGLJLWDOSLQRU$LQGLFDWLQJDQDQDORJ
SLQ7KHQXPHULFYDOXHIROORZLQJWKH'RU$LVWKHSLQQXPEHU7KLVLVIROORZHGE\DQ
HTXDOVVLJQDQGILQDOO\WKHYDOXH\RXZDQWWRVHWWKHSLQWR pinD2=1VHWVGLJLWDOSLQ
HIGH7KHUHLVRQHILHOGSHUSLQDQGVXEVHTXHQWILHOGVDUHVHSDUDWHGE\DQDPSHUVDQG
<RXFDQKDYHDVPDQ\ILHOGVDVWKHUHDUH$UGXLQRSLQV\RXZDQWWRFKDQJH
7KHVNHWFKFDQEHH[WHQGHGWRKDQGOHPXOWLSOHSDUDPHWHUVE\XVLQJDPSHUVDQGVWR
VHSDUDWHPXOWLSOHILHOGV)RUH[DPSOHKWWS"SLQ' SLQ' SL
Q$ SLQ$ (DFKILHOGZLWKLQWKHDPSHUVDQGLVKDQGOHGDVGHVFULEHGHDUOLHU<RXFDQKDYHDVPDQ\
ILHOGVDVWKHUHDUH$UGXLQRSLQV\RXZDQWWRFKDQJH
15.8 Handling Incoming Requests for Specific Pages
Problem
<RXZDQWWRKDYHPRUHWKDQRQHSDJHRQ\RXUZHEVHUYHUIRUH[DPSOHWRVKRZWKH
VWDWXVRIGLIIHUHQWVHQVRUVRQGLIIHUHQWSDJHV
474 | Chapter 15:ಗEthernet and Networking
Solution
7KLVVNHWFKORRNVIRUUHTXHVWVIRUSDJHVQDPHG£DQDORJ¤RU£GLJLWDO¤DQGGLVSOD\VWKH
SLQYDOXHVDFFRUGLQJO\
/*
* WebServerMultiPage
*
* Respond to requests in the URL to view digital and analog output ports
*
* http://192.168.1.177/analog/
displays analog pin data
* http://192.168.1.177/digital/ displays digital pin data
*/
#if ARDUINO > 18
#include <SPI.h>
// needed for Arduino versions later than 0018
#endif
#include <Ethernet.h>
#include <TextFinder.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1,177 };
char buffer[8]; // make this buffer big enough to hold requested page names
Server server(80);
void setup()
{
Serial.begin(9600);
Ethernet.begin(mac, ip);
server.begin();
Serial.println("Ready");
}
void loop()
{
Client client = server.available();
if (client) {
TextFinder finder(client );
while (client.connected()) {
if (client.available()) {
if( finder.find("GET ") ) {
// look for the page name
if(finder.getString( "/", "/", buffer, sizeof(buffer) ))
{
if(strcmp(buffer, "analog") == 0)
showAnalog(client);
else if(strcmp(buffer, "digital") == 0)
showDigital(client);
else
unknownPage(client, buffer);
}
}
15.8 Handling Incoming Requests for Specific Pages | 475
Serial.println();
break;
}
}
// give the web browser time to receive the data
delay(1);
client.stop();
}
}
void showAnalog(Client client)
{
Serial.println("analog");
sendHeader(client);
client.println("<h1>Analog Pins</h1>");
// output the value of each analog input pin
}
for (int i = 0; i < 6; i++) {
client.print("analog pin ");
client.print(i);
client.print(" = ");
client.print(analogRead(i));
client.println("<br />");
}
void showDigital(Client client)
{
Serial.println("digital");
sendHeader(client);
client.println("<h1>Digital Pins</h1>");
// show the value of digital pins
for (int i = 2; i < 8; i++) {
pinMode(i, INPUT);
client.print("digital pin ");
client.print(i);
client.print(" is ");
if(digitalRead(i) == LOW)
client.print("LOW");
else
client.print("HIGH");
client.println("<br />");
}
client.println("</body></html>");
}
void unknownPage(Client client, char *page)
{
Serial.print("Unknown : ");
Serial.println("page");
sendHeader(client);
client.println("<h1>Unknown Page</h1>");
client.println(page);
client.println("</body></html>");
476 | Chapter 15:ಗEthernet and Networking
Download from Wow! eBook <www.wowebook.com>
}
void sendHeader(Client client)
{
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println("<html><head><title>Web server multi-page Example</title>");
client.println("<body>");
}
Discussion
<RX FDQ WHVW WKLV IURP \RXU ZHE EURZVHU E\ W\SLQJ KWWSDQDORJ RU
KWWSGLJLWDO LI \RX DUH XVLQJ D GLIIHUHQW ,3 DGGUHVV IRU \RXU VHUYHU
FKDQJHWKH85/WRPDWFK )LJXUHVKRZVWKHH[SHFWHGRXWSXW
)LJXUH%URZVHURXWSXWVKRZLQJGLJLWDOSLQYDOXHV
7KHVNHWFKORRNVIRUWKH£¤FKDUDFWHUWRGHWHUPLQHWKHHQGRIWKHSDJHQDPH7KH
VHUYHUZLOOUHSRUWDQXQNQRZQSDJHLIWKH£¤FKDUDFWHUGRHVQRWWHUPLQDWHWKHSDJH
QDPH
+HUHLVDQHQKDQFHPHQWWKDWLQFOXGHVVRPHFRGHIURP5HFLSHWRDOORZFRQWURORI
$UGXLQRSLQVIURPDSULYDWHSDJH+HUHLVWKHQHZloopFRGH
void loop()
{
Client client = server.available();
if (client) {
TextFinder finder(client );
while (client.connected()) {
15.8 Handling Incoming Requests for Specific Pages | 477
if (client.available()) {
if( finder.find("GET ") ) {
if(finder.getString( "/", "/", buffer, sizeof(buffer) )) // look for
the page name
{
if(strcmp(buffer, "analog") == 0)
showAnalog(client);
else if(strcmp(buffer, "digital") == 0)
showDigital(client);
else if(strcmp(buffer, "private") == 0) // add this check
showPrivate(client);
// and this function call
else
unknownPage(client, buffer);
}
}
Serial.println();
break;
}
}
// give the web browser time to receive the data
delay(1);
client.stop();
}
}
+HUHLVWKHshowPrivateIXQFWLRQ
void showPrivate(Client client, TextFinder finder)
{
Serial.println("private");
sendHeader(client);
// find tokens starting with "pin" and stop on the first blank line
while(finder.findUntil("pin", "\n\r")){
char type = client.read(); // D or A
int pin = finder.getValue();
int val = finder.getValue();
if( type == 'D') {
Serial.print("Digital pin ");
pinMode(pin, OUTPUT);
digitalWrite(pin, val);
}
else if( type == 'A'){
Serial.print("Analog pin ");
analogWrite(pin, val);
}
else {
Serial.print("Unexpected type ");
Serial.print(type);
}
Serial.print(pin);
Serial.print("=");
Serial.println(val);
478 | Chapter 15:ಗEthernet and Networking
}
}
6HQGLQJ KWWSSULYDWH"SLQ$ IURP \RXU EURZVHU¦V DGGUHVV EDU
ZULWHVWKHYDOXH128WRDQDORJRXWSXWSLQ
15.9 Using HTML to Format Web Server Responses
Problem
<RXZDQWWRXVH+70/HOHPHQWVVXFKDVWDEOHVDQGLPDJHVWRLPSURYHWKHORRNRIZHE
SDJHVVHUYHGE\$UGXLQR)RUH[DPSOH\RXZDQWWKHRXWSXWIURP5HFLSHWREH
UHQGHUHGLQDQ+70/WDEOH
Solution
)LJXUHVKRZVKRZWKHZHEVHUYHULQWKLVUHFLSH¦V6ROXWLRQIRUPDWVWKHEURZVHU
SDJHWRGLVSOD\SLQYDOXHV <RXFDQFRPSDUHWKLVWRWKHXQIRUPDWWHGYDOXHVVKRZQLQ
)LJXUH
)LJXUH%URZVHUSDJHVXVLQJ+70/IRUPDWWLQJ
7KLV VNHWFK VKRZV WKH IXQFWLRQDOLW\ IURP 5HFLSH ZLWK RXWSXW IRUPDWWHG XVLQJ
+70/
/*
* WebServerMultiPageHTML
*
* Display analog and digital pin values using HTML formatting
*/
#if ARDUINO > 18
#include <SPI.h>
// needed for Arduino versions later than 0018
#endif
#include <Ethernet.h>
15.9 Using HTML to Format Web Server Responses | 479
#include <TextFinder.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1,177 };
char buffer[8]; // make this buffer big enough to hold requested page names
Server server(80);
void setup()
{
Ethernet.begin(mac, ip);
server.begin();
pinMode(13,OUTPUT);
for(int i=0; i < 3; i++)
{
digitalWrite(13,HIGH);
delay(500);
digitalWrite(13,LOW);
delay(500);
}
}
void loop()
{
Client client = server.available();
if (client) {
TextFinder finder(client );
while (client.connected()) {
if (client.available()) {
if( finder.find("GET ") ) {
// look for the page name
if(finder.getString( "/", "/", buffer, sizeof(buffer) ))
{
if(strcasecmp(buffer, "analog") == 0)
showAnalog(client);
else if(strcasecmp(buffer, "digital") == 0)
showDigital(client);
else if(strcmp(buffer, "private")== 0)
showPrivate(client, finder);
else
unknownPage(client, buffer);
}
}
break;
}
}
// give the web browser time to receive the data
delay(1);
client.stop();
}
}
480 | Chapter 15:ಗEthernet and Networking
void showAnalog(Client client)
{
sendHeader(client,"Multi-page: Analog");
client.println("<h2>Analog Pins</h2>");
client.println("<table border='1' >");
for (int i = 0; i < 6; i++) {
// output the value of each analog input pin
client.print("<tr><td>analog pin ");
client.print(i);
client.print(" </td><td>");
client.print(analogRead(i));
client.println("</td></tr>");
}
client.println("</table>");
client.println("</body></html>");
}
void showDigital(Client client)
{
sendHeader(client,"Multi-page: Digital");
client.println("<h2>Digital Pins</h2>");
client.println("<table border='1'>");
for (int i = 2; i < 8; i++) {
// show the value of digital pins
pinMode(i, INPUT);
digitalWrite(i, HIGH); // turn on pull-ups
client.print("<tr><td>digital pin ");
client.print(i);
client.print(" </td><td>");
if(digitalRead(i) == LOW)
client.print("Low");
else
client.print("High");
client.println("</td></tr>");
}
client.println("</table>");
client.println("</body></html>");
}
void showPrivate(Client client, TextFinder finder)
{
sendHeader(client,"Multi-page: Private");
// find tokens starting with "pin" and stop on the first blank line
while(finder.findUntil("pin", "\n\r")){
char type = client.read(); // D or A
int pin = finder.getValue();
int val = finder.getValue();
if( type == 'D') {
pinMode(pin, OUTPUT);
digitalWrite(pin, val);
}
else if( type == 'A'){
analogWrite(pin, val);
}
15.9 Using HTML to Format Web Server Responses | 481
}
}
else {
client.print(Serial.print("Unexpected type ");
client.println(type);
}
void unknownPage(Client client, char *page)
{
sendHeader(client, "Unknown Page");
client.println("<h1>Unknown Page</h1>");
client.println(page);
client.println("</body></html>");
}
void sendHeader(Client client, char *title)
{
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.print("<html><head><title>");
client.println(title);
client.println("</title><body>");
}
Discussion
7KHVDPHLQIRUPDWLRQLVSURYLGHGDVLQ5HFLSHEXWKHUHWKHGDWDLVIRUPDWWHG
XVLQJDQ+70/WDEOH7KHIROORZLQJFRGHLQGLFDWHVWKDWWKHZHEEURZVHUVKRXOGFUHDWH
DWDEOHZLWKDERUGHUZLGWKRI
client.println("<table border='1' >");
7KH forORRSGHILQHVWKHWDEOHGDWDFHOOVZLWKWKH <td>WDJDQGWKHURZHQWULHVZLWK
WKH <tr>WDJ7KHIROORZLQJFRGHSODFHVWKHVWULQJ "analog pin"LQDFHOOVWDUWLQJRQD
QHZURZ
client.print("<tr><td>analog pin ");
7KLVLVIROORZHGE\WKHYDOXHRIWKHYDULDEOHi
client.print(i);
7KHQH[WOLQHFRQWDLQVWKHWDJWKDWFORVHVWKHFHOODQGEHJLQVDQHZFHOO
client.print(" </td><td>");
7KLVZULWHVWKHYDOXHUHWXUQHGIURPanalogReadLQWRWKHFHOO
client.print(analogRead(i));
7KHWDJVWRHQGWKHFHOODQGHQGWKHURZDUHZULWWHQDVIROORZV
client.println("</td></tr>");
482 | Chapter 15:ಗEthernet and Networking
7KHforORRSUHSHDWVWKLVXQWLODOOVL[DQDORJYDOXHVDUHZULWWHQ$Q\RIWKHERRNVPHQ
WLRQHGLQ£6HULHVFRQILJXUDWLRQ¤RQSDJHRURQHRIWKHPDQ\+70/UHIHUHQFH
VLWHVFDQSURYLGHPRUHGHWDLOVRQ+70/WDJV
See Also
/HDUQLQJ:HE'HVLJQE\-HQQLIHU1LHGHUVW5REELQV 2¦5HLOO\
:HE'HVLJQLQD1XWVKHOOE\-HQQLIHU1LHGHUVW5REELQV 2¦5HLOO\
+70/ ;+70/7KH'HILQLWLYH*XLGHE\&KXFN0XVFLDQRDQG%LOO.HQQHG\ 2¦5H
LOO\
15.10 Serving Web Pages Using Forms (POST)
Problem
<RXZDQWWRFUHDWHZHESDJHVZLWKIRUPVWKDWDOORZXVHUVWRVHOHFWDQDFWLRQWREH
SHUIRUPHG E\ $UGXLQR )LJXUH VKRZV WKH ZHE SDJH FUHDWHG E\ WKLV UHFLSH¦V
6ROXWLRQ
)LJXUH:HEIRUPZLWKEXWWRQV
Solution
7KLVVNHWFKFUHDWHVDZHESDJHWKDWKDVDIRUPZLWKEXWWRQV8VHUVQDYLJDWLQJWRWKLV
SDJHZLOOVHHWKHEXWWRQVLQWKHZHEEURZVHUDQGWKH$UGXLQRZHEVHUYHUZLOOUHVSRQG
WRWKHEXWWRQFOLFNV,QWKLVH[DPSOHWKHVNHWFKWXUQVDSLQRQDQGRIIGHSHQGLQJRQ
ZKLFKEXWWRQLVSUHVVHG
/*
* WebServerPost sketch
*
15.10 Serving Web Pages Using Forms (POST) | 483
*/
#if ARDUINO > 18
#include <SPI.h>
#endif
// needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <TextFinder.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1,177 };
char buffer[8]; // buffer holding the requested page name
Server server(80);
void setup()
{
Serial.begin(9600);
Ethernet.begin(mac, ip);
server.begin();
delay(3000);
Serial.println("Ready");
}
void loop()
{
Client client = server.available();
if (client) {
TextFinder finder(client );
int type = 0;
while (client.connected()) {
if (client.available()) {
// GET, POST, or HEAD
if(finder.getString("","/", buffer,sizeof(buffer))){
if(strcmp(buffer,"POST ") == 0){
finder.find("\n\r"); // skip to the body
// find string starting with "pin", stop on first blank line
// the POST parameters expected in the form pinDx=Y
// where x is the pin number and Y is 0 for LOW and 1 for HIGH
while(finder.findUntil("pinD", "\n\r")){
int pin = finder.getValue();
// the pin number
int val = finder.getValue();
// 0 or 1
pinMode(pin, OUTPUT);
digitalWrite(pin, val);
}
}
sendHeader(client,"Post example");
//create HTML button to control pin 8
client.println("<h2>Click buttons to turn pin 8 on or off</h2>");
client.print("<form action='/' method='POST'><p><input type='hidden'
name='pinD8'");
client.println(" value='0'><input type='submit' value='Off'/></form>");
//create HTML button to turn on pin 8
client.print("<form action='/' method='POST'><p><input type='hidden'
name='pinD8'");
484 | Chapter 15:ಗEthernet and Networking
client.print(" value='1'><input type='submit' value='On'/></form>");
client.println("</body></html>");
client.stop();
}
break;
}
}
}
// give the web browser time to receive the data
delay(1);
client.stop();
}
void sendHeader(Client client, char *title)
{
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.print("<html><head><title>");
client.print(title);
client.println("</title><body>");
}
Discussion
$ZHESDJHZLWKDXVHULQWHUIDFHIRUPFRQVLVWVRI+70/WDJVWKDWLGHQWLI\WKHFRQWUROV
EXWWRQVFKHFNER[HVODEHOVHWF WKDWFRPSULVHWKHXVHULQWHUIDFH7KLVUHFLSHXVHV
EXWWRQVWRSURYLGHWKHXVHULQWHUIDFH
7KHVHOLQHVFUHDWHDIRUPZLWKDEXWWRQQDPHGpinD8WKDWLVODEHOHG£2))¤ZKLFKZLOO
VHQGEDFNDYDOXHRI0 ]HUR ZKHQFOLFNHG
client.print("<form action='/' method='POST'><p><input type='hidden'
name='pinD8'");
client.println(" value='0'><input type='submit' value='Off'/></form>");
:KHQWKHVHUYHUUHFHLYHVDUHTXHVWIURPDEURZVHULWORRNVIRUWKH "POST "VWULQJWR
LGHQWLI\WKHVWDUWRIWKHSRVWHGIRUP
if(strcmp(buffer,"POST ") == 0) // find the start of the posted form
finder.find("\n\r"); // skip to the body
// find parameters starting with "pin" and stop on the first blank line
// the POST parameters expected in the form pinDx=Y
// where x is the pin number and Y is 0 for LOW and 1 for HIGH
,IWKH2))EXWWRQZDVSUHVVHGWKHUHFHLYHGSDJHZLOOFRQWDLQWKHVWULQJ pinD8=0RU
pinD8=1IRUWKH21EXWWRQ
7KHVNHWFKVHDUFKHVXQWLOLWILQGVWKHEXWWRQQDPH pinD while(finder.findUntil("pinD", "\n\r"))
15.10 Serving Web Pages Using Forms (POST) | 485
7KHfindUntilPHWKRGLQWKHSUHFHGLQJFRGHZLOOVHDUFKIRU£SLQ'¤DQGVWRSVHDUFKLQJ
DWWKHHQGRIDOLQH \n\rLVWKHQHZOLQHFDUULDJHUHWXUQVHQWE\WKHZHEEURZVHUDWWKH
HQGRIDIRUP 7KHQXPEHUIROORZLQJWKHQDPHpinDLVWKHSLQQXPEHU
int pin = finder.getValue();
// the pin number
$QGWKHYDOXHIROORZLQJWKHSLQQXPEHUZLOOEH 0LIEXWWRQ2))ZDVSUHVVHGRU 1LI
EXWWRQ21ZDVSUHVVHG
int val = finder.getValue();
// 0 or 1
7KHYDOXHUHFHLYHGLVZULWWHQWRWKHSLQDIWHUVHWWLQJWKHSLQPRGHWRRXWSXW
pinMode(pin, OUTPUT);
digitalWrite(pin, val);
0RUHEXWWRQVFDQEHDGGHGE\LQVHUWLQJWDJVIRUWKHDGGLWLRQDOFRQWUROV7KHIROORZLQJ
OLQHVDGGDQRWKHUEXWWRQWRWXUQRQGLJLWDOSLQ
//create HTML button to turn on pin 9
client.print("<form action='/' method='POST'><p><input type='hidden'
name='pinD9'");
client.print(" value='1'><input type='submit' value='On'/></form>");
15.11 Serving Web Pages Containing Large Amounts of Data
Problem
<RXUZHESDJHVUHTXLUHPRUHPHPRU\WKDQ\RXKDYHDYDLODEOHVR\RXZDQWWRXVH
SURJUDP PHPRU\ DOVR NQRZQ DV SURJPHP RU IODVK PHPRU\ WR VWRUH GDWD VHH
5HFLSH Solution
7KLV VNHWFK FRPELQHV WKH POST FRGH IURP 5HFLSH ZLWK WKH +70/ FRGH IURP
5HFLSHDQGDGGVQHZFRGHWRDFFHVVWH[WVWRUHGLQSURJPHP$VLQ5HFLSH
WKHVHUYHUFDQGLVSOD\DQDORJDQGGLJLWDOSLQVWDWXVDQGWXUQGLJLWDOSLQVRQDQGRII VHH
)LJXUH /*
* WebServerMultiPageHTMLProgmem sketch
*
* Respond to requests in the URL to change digital and analog output ports
* show the number of ports changed and the value of the analog input pins.
*
* http://192.168.1.177/analog/
displays analog pin data
* http://192.168.1.177/digital/ displays digital pin data
* http://192.168.1.177/private/ allows changing digital pin data
*
* Progmem code derived from webduino library by Ben Combee and Ran Talbott
*/
486 | Chapter 15:ಗEthernet and Networking
)LJXUH:HESDJHZLWK/('LPDJHV
#if ARDUINO > 18
#include <SPI.h>
#endif
// needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <TextFinder.h>
#include <avr/pgmspace.h> // for progmem
#define P(name)
static const prog_uchar name[] PROGMEM
string
// declare a static
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1,177 };
char buffer[8]; // make this buffer big enough to hold requested page names
Server server(80);
void setup()
{
Serial.begin(9600);
15.11 Serving Web Pages Containing Large Amounts of Data | 487
}
Ethernet.begin(mac, ip);
server.begin();
delay(3000);
Serial.println("Ready");
void loop()
{
Client client = server.available();
if (client) {
TextFinder finder(client );
int type = 0;
while (client.connected()) {
if (client.available()) {
// GET, POST, or HEAD
if(finder.getString("","/", buffer,sizeof(buffer))){
if(strcmp(buffer, "GET ") == 0 )
type = 1;
else if(strcmp(buffer,"POST ") == 0)
type = 2;
Serial.print("Type = ");
Serial.println(type);
// look for the page name
if(finder.getString( "", "/", buffer, sizeof(buffer) ))
{
Serial.print(buffer);
Serial.print("|");
if(strcasecmp(buffer, "analog") == 0)
showAnalog(client);
else if(strcasecmp(buffer, "digital") == 0)
showDigital(client);
else if(strcmp(buffer, "private")== 0)
showPrivate(client, finder, type == 2);
else
unknownPage(client, buffer);
}
}
Serial.println();
break;
}
}
// give the web browser time to receive the data
delay(1);
client.stop();
}
}
void showAnalog(Client client)
{
Serial.println("analog");
sendHeader(client,"Multi-page example-Analog");
client.println("<h1>Analog Pins</h1>");
// output the value of each analog input pin
488 | Chapter 15:ಗEthernet and Networking
}
client.println("<table border='1' >");
for (int i = 0; i < 6; i++) {
client.print("<tr><td>analog pin ");
client.print(i);
client.print(" </td><td>");
client.print(analogRead(i));
client.println("</td></tr>");
}
client.println("</table>");
client.println("</body></html>");
// mime encoded data for the led on and off images:
// see: http://www.motobit.com/util/base64-decoder-encoder.asp
P(led_on) = "<img src=\"data:image/jpg;base64,"
"/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAHgAA/+4ADkFkb2JlAGTAAAAAAf/b"
"AIQAEAsLCwwLEAwMEBcPDQ8XGxQQEBQbHxcXFxcXHx4XGhoaGhceHiMlJyUjHi8vMzMvL0BAQEBA"
"QEBAQEBAQEBAQAERDw8RExEVEhIVFBEUERQaFBYWFBomGhocGhomMCMeHh4eIzArLicnJy4rNTUw"
"MDU1QEA/QEBAQEBAQEBAQEBA/8AAEQgAGwAZAwEiAAIRAQMRAf/EAIIAAAICAwAAAAAAAAAAAAAA"
"AAUGAAcCAwQBAAMBAAAAAAAAAAAAAAAAAAACBAUQAAECBAQBCgcAAAAAAAAAAAECAwARMRIhQQQF"
"UWFxkaHRMoITUwYiQnKSIxQ1EQAAAwYEBwAAAAAAAAAAAAAAARECEgMTBBQhQWEiMVGBMkJiJP/a"
"AAwDAQACEQMRAD8AcNz3BGibKie0nhC0v3A+teKJt8JmZEdHuZalOitgUoHnEpQEWtSyLqgACWFI"
"nixWiaQhsUFFBiQSbiMvvrmeCBp27eLnG7lFTDxs+Kra8oOyium3ltJUAcDIy4EUMN/7Dnq9cPMO"
"W90E9kxeyF2d3HFOQ175olKudUm7TqlfKqDQEDOFR1sNqtC7k5ERYjndNPFSArtvnI/nV+ed9coI"
"ktd2BgozrSZO3J5jVEXRcwD2bbXNdq0zT+BohTyjgPp5SYdPJZ9NP2jsiIz7vhjLohtjnqJ/ouPK"
"co//2Q=="
"\"/>";
P(led_off) = "<img src=\"data:image/jpg;base64,"
"/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAHgAA/+4ADkFkb2JlAGTAAAAAAf/b"
"AIQAEAsLCwwLEAwMEBcPDQ8XGxQQEBQbHxcXFxcXHx4XGhoaGhceHiMlJyUjHi8vMzMvL0BAQEBA"
"QEBAQEBAQEBAQAERDw8RExEVEhIVFBEUERQaFBYWFBomGhocGhomMCMeHh4eIzArLicnJy4rNTUw"
"MDU1QEA/QEBAQEBAQEBAQEBA/8AAEQgAHAAZAwEiAAIRAQMRAf/EAHgAAQEAAwAAAAAAAAAAAAAA"
"AAYFAgQHAQEBAQAAAAAAAAAAAAAAAAACAQQQAAECBQAHBQkAAAAAAAAAAAECAwAREhMEITFhoSIF"
"FUFR0UIGgZHBMlIjM1MWEQABAwQDAQEAAAAAAAAAAAABABECIWESA1ETIyIE/9oADAMBAAIRAxEA"
"PwBvl5SWEkkylpJMGsj1XjXSE1kCQuJ8Iy9W5DoxradFa6VDf8IJZAQ6loNtBooTJaqp3DP5oBlV"
"nWrTpEouQS/Cf4PO0uKbqWHGXTSlztSvuVFiZjmfLH3GUuMkzSoTMu8aiNsXet5/17hFyo6PR64V"
"ZnuqfqDDDySFpNpYH3E6aFjzGBr2DkMuFBSFDsWkilUdLftW13pWpcdWqnbBzI/l6hVXKZlROUSe"
"L1KX5zvAPXESjdHsTFWpxLKOJ54hIA1DZCj+Vx/3r96fCNrkvRaT0+V3zV/llplr9sVeHZui/ONk"
"H3dzt6cL/9k="
"\"/>";
;
void showDigital(Client client)
{
Serial.println("digital");
sendHeader(client,"Multi-page example-Digital");
client.println("<h2>Digital Pins</h2>");
// show the value of digital pins
client.println("<table border='1'>");
for (int i = 2; i < 8; i++) {
pinMode(i, INPUT);
digitalWrite(i, HIGH); // turn on pull-ups
client.print("<tr><td>digital pin ");
client.print(i);
15.11 Serving Web Pages Containing Large Amounts of Data | 489
client.print(" </td><td>");
if(digitalRead(i) == LOW)
printP(client, led_off);
else
printP(client, led_on);
client.println("</td></tr>");
}
client.println("</table>");
}
client.println("</body></html>");
void showPrivate(Client client, TextFinder finder, boolean isPost)
{
Serial.println("private");
if(isPost)
{
Serial.println("isPost");
finder.find("\n\r"); // skip to the body
// find parameters starting with "pin" and stop on the first blank line
Serial.println("searching for parms");
while(finder.findUntil("pinD", "\n\r")){
int pin = finder.getValue();
// the pin number
int val = finder.getValue();
// 0 or 1
Serial.print(pin);
Serial.print("=");
Serial.println(val);
pinMode(pin, OUTPUT);
digitalWrite(pin, val);
}
}
sendHeader(client,"Multi-page example-Private");
// table with buttons from 2 through 9
// 2 to 5 are inputs, the other buttons are outputs
client.println("<table border='1'>");
// show the input pins
for (int i = 2; i < 6; i++) { // pins 2-5 are inputs
pinMode(i, INPUT);
digitalWrite(i, HIGH); // turn on pull-ups
client.print("<tr><td>digital input ");
client.print(i);
client.print(" </td><td>");
client.print("&nbsp </td><td>");
client.print(" </td><td>");
client.print("&nbsp </td><td>");
if(digitalRead(i) == LOW)
//client.print("Low");
printP(client, led_off);
else
490 | Chapter 15:ಗEthernet and Networking
//client.print("high");
printP(client, led_on);
client.println("</td></tr>");
}
// show output pins 6-9
// note pins 10-13 are used by the ethernet shield
for (int i = 6; i < 10; i++) {
client.print("<tr><td>digital output ");
client.print(i);
client.print(" </td><td>");
htmlButton(client, "On", "pinD", i, "1");
client.print(" </td><td>");
client.print(" </td><td>");
htmlButton(client, "Off", "pinD", i, "0");
client.print(" </td><td>");
if(digitalRead(i) == LOW)
//client.print("Low");
printP(client, led_off);
else
//client.print("high");
printP(client, led_on);
client.println("</td></tr>");
}
client.println("</table>");
}
// create an HTML button
void htmlButton( Client client, char * label, char *name, int nameId, char *value)
{
P(buttonBegin) = "<form action='/private' method='POST'><p><input type='hidden'
name='";
printP(client, buttonBegin);
client.print(name);
client.print(nameId);
client.print("' value='");
client.print(value);
P(buttonType) = "'><input type='submit' value='";
printP(client, buttonType);
client.print(label);
P(buttonEnd) = "'/></form>";
printP(client, buttonEnd);
}
void unknownPage(Client client, char *page)
{
Serial.print("Unknown : ");
Serial.println("page");
sendHeader(client,"Unknown Page");
client.println("<h1>Unknown Page</h1>");
client.println(page);
client.println("</body></html>");
}
15.11 Serving Web Pages Containing Large Amounts of Data | 491
void sendHeader(Client client, char *title)
{
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.print("<html><head><title>");
client.println(title);
client.println("</title><body>");
}
void printP(Client client, const prog_uchar *str)
{
// copy data out of program memory into local storage, write out in
// chunks of 32 bytes to avoid extra short TCP/IP packets
// from webduino library Copyright 2009 Ben Combee, Ran Talbott
uint8_t buffer[32];
size_t bufferEnd = 0;
while (buffer[bufferEnd++] = pgm_read_byte(str++))
{
if (bufferEnd == 32)
{
client.write(buffer, 32);
bufferEnd = 0;
}
}
}
// write out everything left but trailing NUL
if (bufferEnd > 1)
client.write(buffer, bufferEnd - 1);
Discussion
7KHORJLFXVHGWRFUHDWHWKHZHESDJHLVVLPLODUWRWKDWXVHGLQWKHSUHYLRXVUHFLSHV
7KHIRUPKHUHLVEDVHGRQ5HFLSHEXWLWKDVPRUHHOHPHQWVLQWKHWDEOHDQGXVHV
HPEHGGHGJUDSKLFDOREMHFWVWRUHSUHVHQWWKHVWDWHRIWKHSLQV,I\RXKDYHHYHUFUHDWHG
DZHESDJH\RXPD\EHIDPLOLDUZLWKWKHXVHRI-3(*LPDJHVZLWKLQWKHSDJH$UGXLQR
GRHVQRWKDYHWKHFDSDELOLW\WRVWRUHLPDJHVDVMSJILOHV
,PDJHVQHHGWREHHQFRGHGXVLQJRQHRIWKH,QWHUQHWVWDQGDUGVVXFKDV0XOWLSXUSRVH
,QWHUQHW0DLO([WHQVLRQV 0,0( 7KLVSURYLGHVDZD\WRUHSUHVHQWJUDSKLFDO RURWKHU
PHGLDXVLQJWH[W7KHVNHWFKLQWKLVUHFLSH¦V6ROXWLRQVKRZVZKDWWKH/('LPDJHVORRN
OLNHZKHQWKH\DUH0,0(HQFRGHG0DQ\ZHEEDVHGVHUYLFHVZLOO0,0(HQFRGH\RXU
LPDJHVWKHRQHVLQWKLVUHFLSHZHUHFUHDWHGXVLQJWKHVHUYLFHDW KWWSZZZPRWRELW
FRPXWLOEDVHGHFRGHUHQFRGHUDVS
(YHQWKHVPDOO/('LPDJHVXVHGLQWKLVH[DPSOHDUHWRRODUJHWRILWLQWR$UGXLQR5$0
3URJUDP PHPRU\ IODVK LV XVHG VHH 5HFLSH IRU DQ H[SODQDWLRQ RI WKH P(name)
H[SUHVVLRQ
492 | Chapter 15:ಗEthernet and Networking
7KHLPDJHVUHSUHVHQWLQJWKH/('RQDQGRIIVWDWHVDUHVWRUHGLQDVHTXHQFHRIFKDUDF
WHUVWKH/('RQDUUD\EHJLQVOLNHWKLV
P(led_on) =
"<img src=\"data:image/jpg;base64,"
P(led_on) = GHILQHV led_onDVWKHQDPHRIWKLVDUUD\7KHFKDUDFWHUVDUHWKH+70/
WDJVLGHQWLI\LQJDQLPDJHIROORZHGE\WKH0,0(HQFRGHGGDWDFRPSULVLQJWKHLPDJH
7KLVH[DPSOHLVEDVHGRQFRGHSURGXFHGIRUWKH:HEGXLQRZHEVHUYHU:HEGXLQRLV
KLJKO\UHFRPPHQGHGIRUEXLOGLQJZHESDJHVLI\RXUDSSOLFDWLRQLVPRUHFRPSOLFDWHG
WKDQWKHH[DPSOHVVKRZQLQWKLVFKDSWHU
See Also
:HEGXLQRZHESDJHKWWSFRGHJRRJOHFRPSZHEGXLQR
15.12 Sending Twitter Messages
Problem
<RXZDQW$UGXLQRWRVHQGPHVVDJHVWR7ZLWWHUIRUH[DPSOHZKHQDVHQVRUGHWHFWV
VRPHDFWLYLW\WKDW\RXZDQWWRPRQLWRUYLD7ZLWWHU
Solution
7KLVVNHWFKVHQGVD7ZLWWHUPHVVDJHZKHQDVZLWFKLVFORVHG,WXVHVWKH7ZLWWHUOL
EUDU\GHYHORSHGE\QHRFDWZKLFK\RXFDQGRZQORDGIURPKWWSZZZDUGXLQRFFSOD\
JURXQG&RGH7ZLWWHU/LEUDU\
#if ARDUINO > 18
#include <SPI.h>
#endif
// needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <Twitter.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 177 };
byte gateway[] = { 192, 168, 1, 254 };
byte subnet[] = { 255, 255, 255, 0 };
Twitter twitter("YourID:Password");
boolean MsgSent = false;
const int Sensor = 2;
void setup()
{
Ethernet.begin(mac, ip, gateway, subnet);
Serial.begin(9600);
15.12 Sending Twitter Messages | 493
Download from Wow! eBook <www.wowebook.com>
}
pinMode(Sensor, INPUT);
digitalWrite(Sensor, HIGH);
delay(1000);
//turn on
pull-up resistors
void loop()
{
if(digitalRead(Sensor) == LOW)
{ // here if mailbox is open
if(MsgSent == false){ // check if message already sent
MsgSent = sendMessage("Mail has been delivered");
}
}
else{
MsgSent = false; // door closed so reset the state
}
delay(100);
}
boolean sendMessage( char *message)
{
boolean isSent = false;
}
Serial.println("connecting ...");
if (twitter.post(message)) {
int status = twitter.wait();
if (status == 200) {
Serial.println("OK.");
isSent = true;
} else {
Serial.print("failed : code ");
Serial.println(status);
}
} else {
Serial.println("connection failed.");
}
delay(100);
return isSent;
Discussion
7KH 7ZLWWHU LQWHUIDFH LV HQFDSVXODWHG LQ WKH 7ZLWWHU OLEUDU\ 7KLV SRVWV WR 7ZLWWHU
WKURXJK DQ LQWHUPHGLDU\ KWWSDUGXLQRWZHHWDSSVSRWFRP ZKLFK VSDUHV \RX WKH
SUREOHPRINHHSLQJXSZLWKFKDQJHVWR7ZLWWHUPRVWQRWDEO\LWVDXWKHQWLFDWLRQ
Twitter twitter("YourID:Password");LQLWLDOL]HVWKH7ZLWWHUOLEUDU\\RXZLOOQHHGWR
VXEVWLWXWH\RXU,'DQGSDVVZRUGLQWKDWVWULQJLQRUGHUWRORJRQWR7ZLWWHU
twitter.post(message);DWWHPSWVWRVHQGWKHPHVVDJHVWULQJ£0DLOKDVEHHQGHOLYHUHG¤
WR7ZLWWHUDQGUHWXUQVtrueLILWLVDEOHWRFRQQHFW
twitter.wait();JHWVWKHUHVXOWDQWVWDWXV$YDOXHRI200 LVWKH,QWHUQHWVWDQGDUG
UHSO\IRUVXFFHVV SULQWVOKRWKHUZLVHWKHHUURUFRGHLVSULQWHG6HHWKHGRFXPHQWDWLRQ
494 | Chapter 15:ಗEthernet and Networking
IRUWKH7ZLWWHUOLEUDU\ RUWKH7ZLWWHU$3,GRFXPHQWDWLRQ IRUPRUHGHWDLOVRQWKHHUURU
FRGHV
7KHIROORZLQJYHUVLRQXVHVWKHVDPHsendMessageIXQFWLRQEXWFDQPRQLWRUDQDUUD\RI
VHQVRUV
#if ARDUINO > 18
#include <SPI.h>
#endif
// needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <Twitter.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 177 };
byte gateway[] = { 192, 168, 1, 254 };
byte subnet[] = { 255, 255, 255, 0 };
Twitter twitter("YourID:Password");
char frontOpen[] = "The front door was opened";
char backOpen[] = "The back door was opened";
const int frontSensor = 2;
const int backSensor = 3;
boolean frontMsgSent = false;
boolean backMsgSent = false;
void setup()
{
Ethernet.begin(mac, ip, gateway, subnet);
Serial.begin(9600);
pinMode(frontSensor, INPUT);
pinMode(backSensor, INPUT);
digitalWrite(frontSensor, HIGH);
digitalWrite(backSensor, HIGH);
}
// pull-ups
delay(1000);
void loop()
{
if(digitalRead(frontSensor) == LOW)
{ // here if door is open
if(frontMsgSent == false){ // check if message already sent
frontMsgSent = sendMessage(frontOpen);
}
}
else{
frontMsgSent = false; // door closed so reset the state
}
if(digitalRead(backSensor) == LOW)
{
15.12 Sending Twitter Messages | 495
if(frontMsgSent == false) {
backMsgSent = sendMessage(backOpen);
}
}
else {
backMsgSent = false;
}
delay(100);
}
// add in the sendMessage function from the sketch above
7KHFRGHWKDWFRPPXQLFDWHVZLWK7ZLWWHULVWKHVDPHEXWWKHPHVVDJHVWULQJKHUHLV
FRQVWUXFWHGIURPWKHYDOXHVUHDGIURPVHQVRUVFRQQHFWHGWRWZR$UGXLQRGLJLWDOSLQV
15.13 Sending and Receiving Simple Messages (UDP)
Problem
<RXZDQWWRVHQGDQGUHFHLYHVLPSOHPHVVDJHVRYHUWKH,QWHUQHW
Solution
7KLVVNHWFKXVHVWKH$UGXLQR8'3 8VHU'DWDJUDP3URWRFRO OLEUDU\WRVHQGDQGUHFHLYH
VWULQJV,QWKLVVLPSOHH[DPSOH$UGXLQRSULQWVWKHUHFHLYHGVWULQJWRWKH6HULDO0RQLWRU
DQGDVWULQJLVVHQWEDFNWRWKHVHQGHUVD\LQJ£DFNQRZOHGJHG¤
*
* UDPSendReceiveStrings
* This sketch receives UDP message strings, prints them to the serial port
* and sends an "acknowledge" string back to the sender
*
*/
#if ARDUINO > 18
#include <SPI.h>
#endif
// needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <Udp.h> // UDP library from: bjoern@cs.stanford.edu 12/30/2008
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC address to use
byte ip[] = {192, 168, 1, 177 };
// Arduino's IP address
unsigned int localPort = 8888;
// local port to listen on
// the next two variables are set when a packet is received
byte remoteIp[4];
// holds received packet's originating IP
unsigned int remotePort; // holds received packet's originating port
// buffers for receiving and sending data
byte packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
char replyBuffer[] = "acknowledged";
// a string to send back
496 | Chapter 15:ಗEthernet and Networking
void setup() {
// start the Ethernet and UDP:
Ethernet.begin(mac,ip);
Udp.begin(localPort);
Serial.begin(9600);
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.available(); // note that this includes the UDP header
if(packetSize)
{
packetSize = packetSize - 8;
// subtract the 8 byte header
Serial.print("Received packet of size ");
Serial.println(packetSize);
// read packet into packetBuffer and get sender's IP addr and port number
Udp.readPacket(packetBuffer,UDP_TX_PACKET_MAX_SIZE, remoteIp, &remotePort);
Serial.println("Contents:");
Serial.println((char*)packetBuffer);
// send a string back to the sender
Udp.sendPacket((byte*)replyBuffer,strlen(replyBuffer),remoteIp,remotePort);
}
}
delay(10);
<RXFDQWHVWWKLVE\UXQQLQJWKHIROORZLQJ3URFHVVLQJVNHWFKRQ\RXUFRPSXWHU VHH
&KDSWHUIRUJXLGDQFHRQLQVWDOOLQJDQGUXQQLQJ3URFHVVLQJ // Processing UDP example to send and receive string data from Arduino
// press any key to send the "Hello Arduino" message
import hypermedia.net.*;
UDP udp;
// define the UDP object
void setup() {
udp = new UDP( this, 6000 );
//udp.log( true );
udp.listen( true );
}
// create a new datagram connection on port 6000
// <-- print out the connection activity
// and wait for incoming message
void draw()
{
}
void keyPressed() {
String ip
= "192.168.1.177";
// the remote IP address
int port
= 8888;
// the destination port
15.13 Sending and Receiving Simple Messages (UDP) | 497
udp.send("Hello World", ip, port );
// the message to send
}
void receive( byte[] data ) {
// <-- default handler
//void receive( byte[] data, String ip, int port ) {
// <-- extended handler
for(int i=0; i < data.length; i++)
print(char(data[i]));
println();
}
Discussion
3OXJWKH(WKHUQHWVKLHOGLQWR$UGXLQRDQGFRQQHFWWKH(WKHUQHWFDEOHWR\RXUFRPSXWHU
8SORDGWKH$UGXLQRVNHWFKDQGUXQWKH3URFHVVLQJVNHWFKRQ\RXUFRPSXWHU+LWDQ\
NH\WRVHQGWKH£KHOOR$UGXLQR¤PHVVDJH$UGXLQRVHQGVEDFN£DFNQRZOHGJHG¤ZKLFK
LVGLVSOD\HGLQWKH3URFHVVLQJWH[WZLQGRZ6WULQJOHQJWKLVOLPLWHGE\DFRQVWDQWVHWLQ
WKH8GSKOLEUDU\ILOHWKHGHIDXOWYDOXHLVE\WHVEXW\RXFDQLQFUHDVHWKLVE\HGLWLQJ
WKHIROORZLQJOLQHLQ8GSKLI\RXZDQWWRVHQGORQJHUVWULQJV
#define UDP_TX_PACKET_MAX_SIZE 24
8'3LVDVLPSOHDQGIDVWZD\WRVHQGDQGUHFHLYHPHVVDJHVRYHU(WKHUQHW%XWLWGRHV
KDYHOLPLWDWLRQV¢WKHPHVVDJHVDUHQRWJXDUDQWHHGWREHGHOLYHUHGDQGRQDYHU\EXV\
QHWZRUNVRPHPHVVDJHVFRXOGJHWORVWRUJHWGHOLYHUHGLQDGLIIHUHQWRUGHUWKDQWKDWLQ
ZKLFKWKH\ZHUHVHQW%XW8'3ZRUNVZHOOIRUWKLQJVVXFKDVGLVSOD\LQJWKHVWDWXVRI
$UGXLQRVHQVRUV¢HDFKPHVVDJHFRQWDLQVWKHFXUUHQWVHQVRUYDOXHWRGLVSOD\DQGDQ\
ORVWPHVVDJHVJHWUHSODFHGE\PHVVDJHVWKDWIROORZ
7KLVVNHWFKGHPRQVWUDWHVVHQGLQJDQGUHFHLYLQJVHQVRUPHVVDJHV,WUHFHLYHVPHVVDJHV
FRQWDLQLQJYDOXHVWREHZULWWHQWRWKHDQDORJRXWSXWSRUWVDQGUHSOLHVEDFNWRWKHVHQGHU
ZLWKWKHYDOXHVRQWKHDQDORJLQSXWSLQV
/*
* UDPSendReceive sketch:
*/
#if ARDUINO > 18
#include <SPI.h>
// needed for Arduino versions later than 0018
#endif
#include <Ethernet.h>
#include <Udp.h> // UDP library from: bjoern@cs.stanford.edu 12/30/2008
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC address to use
byte ip[] = {192, 168, 1, 177 };
// Arduino's IP address
byte gw[] = {192, 168, 1, 254 };
// Gateway IP address
unsigned int localPort = 8888;
// local port to listen on
byte packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
int packetSize; // holds received packet size
byte remoteIp[4]; // holds received packet's originating IP
498 | Chapter 15:ಗEthernet and Networking
unsigned int remotePort; // holds received packet's originating port
const int analogOutPins[] = { 3,5,6,9};
// pins 10 and 11 used by ethernet shield
void setup() {
Ethernet.begin(mac,ip);
Udp.begin(localPort);
Serial.begin(9600);
Serial.println("Ready");
}
void loop() {
// if there's data available, read a packet
packetSize = Udp.available();
if(packetSize > 0 )
{
packetSize = packetSize - 8; // 8 byte UDP header so subtract 8 bytes
Serial.print("Received packet of size ");
Serial.print(packetSize);
Serial.println(" with contents:");
// read packet into packetBuffer and get sender's IP addr and port number
packetSize = min(packetSize,UDP_TX_PACKET_MAX_SIZE);
Udp.readPacket(packetBuffer,UDP_TX_PACKET_MAX_SIZE, remoteIp, &remotePort);
for( int i=0; i < packetSize; i++)
{
byte value = packetBuffer[i];
if( i < 4)
{
// only write to the first four analog out pins
analogWrite(analogOutPins[i], value);
}
Serial.println(value, DEC);
}
Serial.println();
// tell the sender the values of our analog ports
sendAnalogValues(remoteIp, remotePort);
}
//wait a bit
delay(10);
}
void sendAnalogValues( byte targetIp[], int targetPort )
{
int index = 0;
for(int i=0; i < 6; i++)
{
int value = analogRead(i);
packetBuffer[index++] = lowByte(value); // the low byte);
packetBuffer[index++] = highByte(value); // the high byte);
}
}
//send a packet to specified peer
Udp.sendPacket(packetBuffer, index, targetIp, targetPort);
}
15.13 Sending and Receiving Simple Messages (UDP) | 499
7KHVNHWFKVHQGVDQGUHFHLYHVWKHYDOXHVRQDQDORJSRUWVWKURXJKXVLQJELQDU\GDWD
,I\RXDUHQRWIDPLOLDUZLWKPHVVDJHVFRQWDLQLQJELQDU\GDWDVHHWKHLQWURGXFWLRQWR
&KDSWHUDVZHOODV5HFLSHVDQGIRUDGHWDLOHGGLVFXVVLRQRQKRZWKLVLVGRQH
RQ$UGXLQR
7KHGLIIHUHQFHKHUHLVWKDWWKHGDWDLVVHQWXVLQJUdpSendPacketLQVWHDGRISerial.print
+HUHLVD3URFHVVLQJVNHWFK\RXFDQXVHZLWKWKHSUHFHGLQJVNHWFK,WKDVVL[VFUROOEDUV
WKDWFDQEHGUDJJHGZLWKDPRXVHWRVHWWKHVL[analogWriteOHYHOVLWSULQWVWKHUHFHLYHG
VHQVRUGDWDWRWKH3URFHVVLQJWH[WZLQGRZ
/*
* UDPTest
*
* Demo to send and receive data from Arduino using UDP
*/
import hypermedia.net.*;
UDP udp;
// define the UDP object
HScrollbar[] scroll = new HScrollbar[6];
//see: topics/gui/scrollbar
void setup() {
size(256, 200);
noStroke();
for(int i=0; i < 6; i++) // create the scroll bars
scroll[i] = new HScrollbar(0, 10 + (height / 6) * i, width, 10, 3*5+1);
}
udp = new UDP( this, 6000 );
//udp.log( true );
udp.listen( true );
// create a new datagram connection on port 6000
// <-- print out the connection activity
// and wait for incoming message
void draw()
{
background(255);
fill(255);
for(int i=0; i < 6; i++) {
scroll[i].update();
scroll[i].display();
}
}
void keyPressed() {
String ip
= "192.168.1.177";
int port
= 8888;
// the remote IP address
// the destination port
byte[] message = new byte[6] ;
for(int i=0; i < 6; i++){
message[i] = byte(scroll[i].getPos());
println(int(message[i]) );
}
println();
udp.send( message, ip, port );
500 | Chapter 15:ಗEthernet and Networking
}
void receive( byte[] data ) {
//void receive( byte[] data, String ip, int port ) {
// <-- default handler
// <-- extended handler
println("incoming data is:");
for(int i=0; i < 6; i++){
scroll[i].setPos(data[i]);
println((int)data[i]);
}
}
class HScrollbar
{
int swidth, sheight;
int xpos, ypos;
float spos, newspos;
int sposMin, sposMax;
int loose;
boolean over;
boolean locked;
float ratio;
// width and height of bar
// x and y position of bar
// x position of slider
// max and min values of slider
// how loose/heavy
// is the mouse over the slider?
HScrollbar (int xp, int yp, int sw, int sh, int l) {
swidth = sw;
sheight = sh;
int widthtoheight = sw - sh;
ratio = (float)sw / (float)widthtoheight;
xpos = xp;
ypos = yp-sheight/2;
spos = xpos + swidth/2 - sheight/2;
newspos = spos;
sposMin = xpos;
sposMax = xpos + swidth - sheight;
loose = l;
}
void update() {
if(over()) {
over = true;
} else {
over = false;
}
if(mousePressed && over) {
locked = true;
}
if(!mousePressed) {
locked = false;
}
if(locked) {
newspos = constrain(mouseX-sheight/2, sposMin, sposMax);
}
if(abs(newspos - spos) > 1) {
15.13 Sending and Receiving Simple Messages (UDP) | 501
}
}
spos = spos + (newspos-spos)/loose;
int constrain(int val, int minv, int maxv) {
return min(max(val, minv), maxv);
}
boolean over() {
if(mouseX > xpos && mouseX < xpos+swidth &&
mouseY > ypos && mouseY < ypos+sheight) {
return true;
} else {
return false;
}
}
void display() {
fill(255);
rect(xpos, ypos, swidth, sheight);
if(over || locked) {
fill(153, 102, 0);
} else {
fill(102, 102, 102);
}
rect(spos, ypos, sheight, sheight);
}
float getPos() {
return spos * ratio;
}
void setPos(int value) {
spos = value / ratio;
}
}
15.14 Getting the Time from an Internet Time Server
Problem
<RXZDQWWRJHWWKHFXUUHQWWLPHIURPDQ,QWHUQHWWLPHVHUYHUIRUH[DPSOHWRV\Q
FKURQL]HFORFNVRIWZDUHUXQQLQJRQ$UGXLQR
Solution
7KLVVNHWFKJHWVWKHWLPHIURPD1HWZRUN7LPH3URWRFRO 173 VHUYHUDQGSULQWVWKH
UHVXOWVDVVHFRQGVVLQFH-DQXDU\ 173WLPH DQGVHFRQGVVLQFH-DQXDU\
/*
* UdpNtp sketch
*
* Get the time from an NTP time server
502 | Chapter 15:ಗEthernet and Networking
* Demonstrates use of UDP sendPacket and ReceivePacket
*/
#if ARDUINO > 18
#include <SPI.h>
#endif
// needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <Udp.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 44 };
unsigned int localPort = 8888;
// MAC address to use
// Arduino's IP address
// local port to listen for UDP packets
byte time_dot_nist_dot_gov[] = { 192, 43, 244, 18}; // time.nist.gov NTP server
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the
message
byte packetBuffer[ NTP_PACKET_SIZE]; // buffer to hold incoming/outgoing packets
void setup()
{
// start Ethernet and UDP
Ethernet.begin(mac,ip);
Udp.begin(localPort);
Serial.begin(9600);
}
void loop()
{
sendNTPpacket(time_dot_nist_dot_gov); // send an NTP packet to a time server
// wait to see if a reply is available
delay(1000);
if ( Udp.available() ) {
Udp.readPacket(packetBuffer,NTP_PACKET_SIZE); // read packet into buffer
//the timestamp starts at byte 40, convert four bytes into a long integer
unsigned long hi = word(packetBuffer[40], packetBuffer[41]);
unsigned long low = word(packetBuffer[42], packetBuffer[43]);
unsigned long secsSince1900 = hi << 16 | low; // this is NTP time (seconds
since Jan 1 1900)
Serial.print("Seconds since Jan 1 1900 = " );
Serial.println(secsSince1900);
Serial.print("Unix time = ");
// Unix time starts on Jan 1 1970
const unsigned long seventyYears = 2208988800UL;
unsigned long epoch = secsSince1900 - seventyYears; // subtract 70 years
Serial.println(epoch);
// print Unix time
15.14 Getting the Time from an Internet Time Server | 503
// print the hour, minute and second:
// UTC is the time at Greenwich Meridian (GMT)
Serial.print("The UTC time is ");
// print the hour (86400 equals secs per day)
Serial.print((epoch % 86400L) / 3600);
Serial.print(':');
// print the minute (3600 equals secs per minute)
Serial.print((epoch % 3600) / 60);
Serial.print(':');
Serial.println(epoch %60); // print the second
}
}
// wait ten seconds before asking for the time again
delay(10000);
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(byte *address)
{
memset(packetBuffer, 0, NTP_PACKET_SIZE); // set all bytes in the buffer to 0
// Initialize values needed to form NTP request
packetBuffer[0] = B11100011;
// LI, Version, Mode
packetBuffer[1] = 0;
// Stratum
packetBuffer[2] = 6;
// Max Interval between messages in seconds
packetBuffer[3] = 0xEC; // Clock Precision
// bytes 4 - 11 are for Root Delay and Dispersion and were set to 0 by memset
packetBuffer[12] = 49; // four byte reference ID identifying
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// send the packet requesting a timestamp:
Udp.sendPacket( packetBuffer,NTP_PACKET_SIZE, address, 123); //NTP requests
are to port 123
}
Discussion
173LVDSURWRFROXVHGWRV\QFKURQL]HWLPHWKURXJK,QWHUQHWPHVVDJHV173VHUYHUV
SURYLGHWLPHDVDYDOXHRIWKHQXPEHURIVHFRQGVWKDWKDYHHODSVHGVLQFH-DQXDU\
173 WLPH LV 87& &RRUGLQDWHG 8QLYHUVDO 7LPH VLPLODU WR *UHHQZLFK 0HDQ
7LPH DQGGRHVQRWWDNHWLPH]RQHVRUGD\OLJKWVDYLQJWLPHLQWRDFFRXQW
173VHUYHUVXVH8'3PHVVDJHVVHH5HFLSHIRUDQLQWURGXFWLRQWR8'3$Q173
PHVVDJHLVFRQVWUXFWHGLQWKHIXQFWLRQQDPHG sendNTPpacketDQG\RXDUHXQOLNHO\WR
QHHGWRFKDQJHWKHFRGHLQWKDWIXQFWLRQ7KHIXQFWLRQWDNHVWKHDGGUHVVRIDQ173
VHUYHU\RXFDQXVHWKH,3DGGUHVVLQWKHSUHFHGLQJH[DPSOHRUILQGDOLVWRIPDQ\PRUH
XVLQJ£173DGGUHVV¤DVDVHDUFKWHUPLQ*RRJOH,I\RXZDQWPRUHLQIRUPDWLRQDERXW
WKHSXUSRVHRIWKH173ILHOGVVHHWKHGRFXPHQWDWLRQDWKWWSZZZQWSRUJ
7KHUHSO\IURP173LVDPHVVDJHZLWKDIL[HGIRUPDWWKHWLPHLQIRUPDWLRQFRQVLVWVRI
IRXUE\WHVVWDUWLQJDWE\WH7KHVHIRXUE\WHVDUHDELWYDOXH DQXQVLJQHGORQJ
504 | Chapter 15:ಗEthernet and Networking
LQWHJHU ZKLFKLVWKHQXPEHURIVHFRQGVVLQFH-DQXDU\7KLVYDOXH DQGWKH
WLPHFRQYHUWHGLQWR8QL[WLPH LVSULQWHG,I\RXZDQWWRFRQYHUWWKHWLPHIURPDQ173
VHUYHUWRWKHIULHQGOLHUIRUPDWXVLQJKRXUVPLQXWHVDQGVHFRQGVDQGGD\VPRQWKV
DQG\HDUV\RXFDQXVHWKH$UGXLQR7LPHOLEUDU\ VHH&KDSWHU +HUHLVDYDULDWLRQ
RQWKHSUHFHGLQJFRGHWKDWSULQWVWKHWLPHDV14:32:56 Monday 18 Jan 2010
/*
* Time_NTP sketch
* Example showing time sync to NTP time source
*
* This sketch uses the Time library
* and the Arduino Ethernet library
*/
#include <Time.h>
#if ARDUINO > 18
#include <SPI.h>
#endif
// needed for Arduino versions later than 0018
#include <Udp.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 44 };
unsigned int localPort = 8888;
// local port to listen for UDP packets
byte time_dot_nist_dot_gov[] = { 192, 43, 244, 18}; // time.nist.gov
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in first 48 bytes of message
byte packetBuffer[ NTP_PACKET_SIZE]; // buffer to hold incoming/outgoing packets
time_t prevDisplay = 0;
// when the digital clock was displayed
void setup()
{
Serial.begin(9600);
Ethernet.begin(mac,ip);
Udp.begin(localPort);
Serial.println("waiting for sync");
setSyncProvider(getNtpTime);
while(timeStatus()== timeNotSet)
; // wait until the time is set by the sync provider
}
void loop()
{
if( now() != prevDisplay)
{
prevDisplay = now();
digitalClockDisplay();
}
}
//update the display only if the time has changed
15.14 Getting the Time from an Internet Time Server | 505
void digitalClockDisplay(){
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(dayStr(weekday()));
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(monthShortStr(month()));
Serial.print(" ");
Serial.print(year());
Serial.println();
}
void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and
leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
/*-------- NTP code ----------*/
unsigned long getNtpTime()
{
sendNTPpacket(time_dot_nist_dot_gov);
delay(1000);
if ( Udp.available() ) {
Udp.readPacket(packetBuffer,NTP_PACKET_SIZE);
// read packet into the buffer
//the timestamp starts at byte 40, convert four bytes into a long integer
unsigned long hi = word(packetBuffer[40], packetBuffer[41]);
unsigned long low = word(packetBuffer[42], packetBuffer[43]);
// this is NTP time (seconds since Jan 1 1900
unsigned long secsSince1900 = hi << 16 | low;
// Unix time starts on Jan 1 1970
const unsigned long seventyYears = 2208988800UL;
unsigned long epoch = secsSince1900 - seventyYears; // subtract 70 years
return epoch;
}
return 0; // return 0 if unable to get the time
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(byte *address)
{
memset(packetBuffer, 0, NTP_PACKET_SIZE); // set all bytes in the buffer to 0
// Initialize values needed to form NTP request
packetBuffer[0] = B11100011;
// LI, Version, Mode
506 | Chapter 15:ಗEthernet and Networking
packetBuffer[1] = 0;
// Stratum
packetBuffer[2] = 6;
// Max Interval between messages in seconds
packetBuffer[3] = 0xEC; // Clock Precision
// bytes 4 - 11 are for Root Delay and Dispersion and were set to 0 by memset
packetBuffer[12] = 49; // four-byte reference ID identifying
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// send the packet requesting a timestamp:
// NTP requests are to port 123
Udp.sendPacket( packetBuffer,NTP_PACKET_SIZE, address, 123);
}
See Also
&KDSWHUSURYLGHVPRUHLQIRUPDWLRQRQXVLQJWKH$UGXLQR7LPHOLEUDU\
'HWDLOVRQ173DUHDYDLODEOHDWKWWSZZZQWSRUJ
173FRGHE\-HVVH-DJJDUVWKDWLQVSLUHGWKHVNHWFKXVHGLQWKLVUHFLSHLVDYDLODEOHDW
KWWSJLWKXEFRPF\QVKDUGDUGXLQRQWS
15.15 Monitoring Pachube Feeds
Problem
<RXZDQW$UGXLQRWRUHVSRQGWRLQIRUPDWLRQRQDZHEVHUYLFHWKDWRIIHUVVHFXULW\DQG
GDWDEDFNXS3HUKDSV\RXZDQWWRDFWLYDWHDGHYLFHRUUDLVHDQDODUPEDVHGRQWKHYDOXH
RIGDWDRQ3DFKXEH
Solution
7KLVVNHWFKJHWVWKHILUVWIRXUGDWDILHOGVIURPIHHGQXPEHUDQGSULQWVWKHUHVXOWV
RQWKH6HULDO0RQLWRU
#if ARDUINO > 18
#include <SPI.h>
#endif
// needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <TextFinder.h>
const int feedID
=
504; // this is the ID of the
remote Pachube feed that you want to connect to
const int streamCount
=
4; // Number of data streams to get
const long REFRESH_INTERVAL = 600000; // Update every 10 minutes
const long RETRY_INTERVAL
= 10000; // if connection fails/resets
wait 10 seconds before trying again - should not be less than 5
#define PACHUBE_API_KEY
"your key here . . ." // fill in your API key
15.15 Monitoring Pachube Feeds | 507
// mac address, make sure this is unique on your network
byte mac[] = { 0xCC, 0xAC, 0xBE, 0xEF, 0xFE, 0x91 };
byte remoteServer[] = { 209,40,205,190 };
// pachube.com
byte ip[] = { 192, 168, 1, 144 };
byte gateway[] ={ 192, 168, 1, 254 };
byte subnet[] ={ 255, 255, 255, 0 };
// no DHCP so set IP address
float streamData[streamCount];
// change float to long if needed for your data
char findBuffer
[11]; // holds one numeric field - room for 10 characters
and the terminating null
Client client(remoteServer, 80);
TextFinder finder( client );
void setup()
{
Serial.begin(9600);
Ethernet.begin(mac, ip, gateway, subnet);
}
void loop()
{
if( getFeed(feedID, streamCount) == true)
{
for(int id = 0; id < streamCount; id++){
Serial.println( streamData[id]);
}
Serial.println("--");
delay(REFRESH_INTERVAL);
}
else
{
Serial.println("Unable to get feed");
delay(RETRY_INTERVAL);
}
}
// returns true if able to connect and get data for all requested streams
in this feed
boolean getFeed(int feedId, int streamCount )
{
boolean result = false;
Serial.print("Connecting feed "); Serial.print(feedId); Serial.print(" ... ");
if (client.connect()) {
client.print("GET /api/feeds/");
client.print(feedId);
// client.print(".csv HTTP/1.1\nHost: pachube.com\nX-PachubeApiKey: ");
client.print(".xml HTTP/1.1\nHost: pachube.com\nX-PachubeApiKey: ");
client.print(PACHUBE_API_KEY);
client.print("\nUser-Agent: Arduino");
client.println("\n");
}
508 | Chapter 15:ಗEthernet and Networking
}
else {
Serial.println("Connection failed");
}
if (client.connected()) {
Serial.println("Connected");
if( finder.find("HTTP/1.1") && finder.find("200 OK") )
result = processFeed(streamCount);
else
Serial.println("Dropping connection - no 200 OK");
}
else {
Serial.println("Disconnected");
}
client.stop();
client.flush();
return result;
int processFeed(int streamCount)
{
finder.find("<environment updated=");
finder.getString("T", "\"",findBuffer, sizeof(findBuffer));
Serial.print("Values updated at ");
Serial.println(findBuffer);
// get the time
int processed = 0;
for(int id = 0; id < streamCount; id++)
{
if( finder.find( "<data id=" ) ) //find next data field
{
if(finder.find("<value ") )
{
finder.find(">"); // seek to the angle brackets
streamData[id] = finder.getValue();
processed++;
}
}
else {
Serial.print("unable to find Id field ");
Serial.println(id);
}
}
return(processed == streamCount ); // return true iff got all data
}
Discussion
7RVWDUWXVLQJ3DFKXEH\RXKDYHWRVLJQXSIRUDQDFFRXQWDQGWKH3DFKXEH4XLFNVWDUW
SDJHH[SODLQVKRZKWWSFRPPXQLW\SDFKXEHFRP"T QRGH2QFH\RX¦UHVLJQHGXS
\RXZLOOEHHPDLOHGDXVHUQDPHDQG$3,NH\$GG\RXUNH\WRWKHIROORZLQJOLQHLQWKH
VNHWFK
#define PACHUBE_API_KEY
"your key here . . ." // fill in your API key
15.15 Monitoring Pachube Feeds | 509
(YHU\3DFKXEHIHHG GDWDVRXUFH KDVDQLGHQWLI\LQJ,'WKLVH[DPSOHVNHWFKXVHVIHHG
HQYLURQPHQWDOGDWDIURPWKH3DFKXEHRIILFH )HHGVDUHDFFHVVHGXVLQJWKH get
Feed PHWKRG ZLWK WKH IHHG ,' DQG WKH QXPEHU RI LWHPV RI GDWD WR JHW SDVVHG DV
DUJXPHQWV,IWKLVLVVXFFHVVIXOgetFeedUHWXUQVtrueDQG\RXFDQSURFHVVWKHGDWDXVLQJ
WKHprocessFeedPHWKRG7KLVUHWXUQVWKHYDOXHIRUWKHGDWDLWHP\RXDUHLQWHUHVWHGLQ
HDFKGDWDLWHPLVFDOOHGDVWUHDPLQ3DFKXEH 15.16 Sending Information to Pachube
Problem
<RXZDQW$UGXLQRWRXSGDWHIHHGVRQ3DFKXEH)RUH[DPSOH\RXZDQWWKHYDOXHVRI
VHQVRUVFRQQHFWHGWR$UGXLQRWREHSXEOLVKHGRQD3DFKXEHIHHG
Solution
7KLV VNHWFK UHDGV WHPSHUDWXUH VHQVRUV FRQQHFWHG WR WKH DQDORJ LQSXW SRUWV VHH
5HFLSH DQGVHQGVWKHGDWDWR3DFKXEH
#if ARDUINO > 18
#include <SPI.h>
#endif
// needed for Arduino versions later than 0018
#include <Ethernet.h>
#include "Dhcp.h" // uses DHCP code from: http://blog.jordanterrell.com
#include <TextFinder.h>
const int feedID
=
2955; // this is the ID of my float test feed
const int streamCount
=
6; // Number of data streams to send
const long REFRESH_INTERVAL = 60000;
// Update every minute
// if connection fails/resets wait 10 seconds before trying again
// should not be less than 5
const long RETRY_INTERVAL
= 10000;
#define PACHUBE_API_KEY
"Your key here . . . " // fill in your API key
// make sure this is unique on your network
byte mac[] = { 0xCC, 0xAC, 0xBE, 0xEF, 0xFE, 0x91 };
byte remoteServer[] = { 209,40,205,190 };
// pachube.com
//used to store csv output and response strings (date is 26 chars)
char buffer[32];
Client
TextFinder
client(remoteServer, 80);
finder( client );
void setup()
{
Serial.begin(9600);
Serial.println("Getting ip address");
510 | Chapter 15:ಗEthernet and Networking
if(Dhcp.beginWithDHCP(mac) == 1) { // begin method returns 1 if successful
delay(4000);
}
else {
Serial.println("unable to acquire ip address!");
while(true)
; // do nothing
}
}
void loop()
{
int data[streamCount];
buffer[0] = 0;
char * bufPointer = buffer;
for(int id = 0; id < streamCount; id++)
{
float temperature = getTemperature(id)
;
formatFloat( temperature, 1, &buffer[strlen(buffer)]); // format as xx.y
if( id < streamCount-1)
strcat(buffer, ",");
// commas between all but last value
}
if( putFeed(feedID, streamCount) == true)
{
Serial.print("Feed updated: ");
Serial.println(buffer);
delay(REFRESH_INTERVAL);
}
else
{
Serial.println("Unable to update feed");
delay(RETRY_INTERVAL);
}
}
// returns true if able to connect and send data
boolean putFeed(int feedId, int streamCount )
{
boolean result = false;
Serial.print("Connecting feed "); Serial.print(feedId); Serial.print(" ... ");
if (client.connect()) {
client.print("PUT /api/feeds/");
client.print(feedId);
client.print(".csv HTTP/1.1\nHost: pachube.com\nX-PachubeApiKey: ");
//client.print(".xml HTTP/1.1\nHost: pachube.com\nX-PachubeApiKey: ");
client.print(PACHUBE_API_KEY);
client.print("\nUser-Agent: Arduino");
client.print("\nContent-Type: text/csv\nContent-Length: ");
client.print(strlen(buffer));
client.print("\nConnection: close\n\n");
client.print(buffer);
client.println("\n");
}
15.16 Sending Information to Pachube | 511
else {
Serial.println("Connection failed");
}
if (client.connected()) {
Serial.println("Connected");
if( finder.find("HTTP/1.1") && finder.find("200 OK") ){
finder.getString("Date: ", "\r",buffer, sizeof(buffer));
result = true;
}
else
Serial.println("Dropping connection - no 200 OK");
}
else {
Serial.println("Disconnected");
}
client.stop();
client.flush();
return result;
}
float getTemperature(int pin)
{
const int nbrSamples = 8; // take the average of 8 samples
int samples = 0;
for(int i=0; i < nbrSamples; i++)
samples = samples + analogRead(pin);
float t = samples / nbrSamples; // get the average value
t = (t /1024.0) * 500; // each degree C is 10mv
return t;
}
// returns the number of characters added to the buffer
int formatFloat(float number, byte digits, char *buf)
{
if (!buf )
return 0;
char * bufStart = buf; // store the start of the buffer
// Handle negative numbers
if (number < 0.0)
{
*buf++ = '-';
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
ultoa(int_part, buf, 10 );
512 | Chapter 15:ಗEthernet and Networking
// store time
buf = &buf[strlen(buf)];
// Print the decimal point, but only if there are digits
if (digits > 0 )
*buf++ = '.';
}
// Extract digits from the remainder one at a time
while (digits-- > 0 )
{
remainder *= 10.0;
int toPrint = int(remainder);
*buf++ = toPrint + '0';
remainder -= toPrint;
}
*buf = 0;
return buf-bufStart; // the number of characters added
Discussion
7KLV LV VLPLODU WR 5HFLSH EXW KHUH \RX XVH WKH putFeed PHWKRG WR VHQG \RXU
LQIRUPDWLRQWR3DFKXEH7KLVH[DPSOHVHQGVLQIRUPDWLRQIURPWHPSHUDWXUHVHQVRUV
DQGDOPRVWKDOIWKHFRGHLVXVHGWRJHWDQGIRUPDWWKLVLQIRUPDWLRQLQDIRUPVXLWDEOH
IRUGLVSOD\6HHWKHFKDSWHUFRYHULQJWKHW\SHRIVHQVRU\RXZDQWWRXVHWRILQGFRGH
VXLWDEOHIRU\RXUDSSOLFDWLRQ
15.16 Sending Information to Pachube | 513
CHAPTER 16
Using, Modifying, and
Creating Libraries
16.0 Introduction
/LEUDULHVDGGIXQFWLRQDOLW\WRWKH$UGXLQRHQYLURQPHQW7KH\H[WHQGWKHFRPPDQGV
DYDLODEOHWRSURYLGHFDSDELOLWLHVQRWDYDLODEOHLQWKHFRUH$UGXLQRODQJXDJH/LEUDULHV
SURYLGHDZD\WRDGGIHDWXUHVWKDWFDQEHDFFHVVHGIURPDQ\RI\RXUVNHWFKHVRQFH\RX
KDYHLQVWDOOHGWKHOLEUDU\
7KH$UGXLQRVRIWZDUHGLVWULEXWLRQLQFOXGHVEXLOWLQOLEUDULHVWKDWFRYHUFRPPRQWDVNV
7KHVHOLEUDULHVDUHGLVFXVVHGLQ5HFLSH
/LEUDULHVDUHDOVRDJRRGZD\IRUSHRSOHWRVKDUHFRGHWKDWPD\EHXVHIXOWRRWKHUV
0DQ\WKLUGSDUW\OLEUDULHVSURYLGHVSHFLDOL]HGFDSDELOLWLHVWKHVHFDQEHGRZQORDGHG
IURPWKH$UGXLQR3OD\JURXQGDQGRWKHUVLWHV/LEUDULHVDUHRIWHQZULWWHQWRVLPSOLI\WKH
XVHRIDSDUWLFXODUSLHFHRIKDUGZDUH0DQ\RIWKHGHYLFHVFRYHUHGLQHDUOLHUFKDSWHUV
XVHOLEUDULHVWRPDNHLWHDVLHUWRFRQQHFWWRWKHGHYLFHV
/LEUDULHVFDQDOVRSURYLGHDIULHQGO\ZUDSSHUDURXQGFRPSOH[FRGHWRPDNHLWHDVLHUWR
XVH$QH[DPSOHLVWKH:LUHOLEUDU\GLVWULEXWHGZLWK$UGXLQRZKLFKKLGHVPXFKRIWKH
FRPSOH[LW\RIORZOHYHOKDUGZDUHFRPPXQLFDWLRQV VHH&KDSWHU 7KLVFKDSWHUH[SODLQVKRZWRXVHDQGPRGLI\OLEUDULHV,WDOVRJLYHVH[DPSOHVRIKRZ
WRFUHDWH\RXURZQOLEUDULHV
16.1 Using the Built-in Libraries
Problem
<RXZDQWWRXVHWKHOLEUDULHVSURYLGHGZLWKWKH$UGXLQRGLVWULEXWLRQLQ\RXUVNHWFK
515
Solution
7KLVUHFLSHVKRZV\RXKRZWRXVH$UGXLQROLEUDU\IXQFWLRQDOLW\LQ\RXUVNHWFK
7RVHHWKHOLVWRIDYDLODEOHOLEUDULHVIURPWKH,'(PHQXFOLFN6NHWFKൺ,PSRUW/LEUDU\
$OLVWZLOOGURSGRZQVKRZLQJDOOWKHDYDLODEOHOLEUDULHV7KHILUVWGR]HQRUVRDUHWKH
OLEUDULHVGLVWULEXWHGZLWK$UGXLQR$KRUL]RQWDOOLQHVHSDUDWHVWKDWOLVWIURPWKHOLEUDULHV
WKDW\RXGRZQORDGDQGLQVWDOO\RXUVHOI
&OLFNLQJRQDOLEUDU\ZLOODGGWKDWOLEUDU\WRWKHFXUUHQWVNHWFKE\DGGLQJWKHIROORZLQJ
OLQHWRWKHWRSRIWKHVNHWFK
#include <nameOfTheLibrarySelected.h>
7KLVUHVXOWVLQWKHIXQFWLRQVZLWKLQWKHOLEUDU\EHFRPLQJDYDLODEOHWRXVHLQ\RXUVNHWFK
7KH$UGXLQR,'(XSGDWHVLWVOLVWRIDYDLODEOHOLEUDULHVRQO\ZKHQWKH,'(
LVILUVWVWDUWHGRQ\RXUFRPSXWHU,I\RXLQVWDOODOLEUDU\DIWHUWKH,'(LV
UXQQLQJ\RXQHHGWRFORVHWKH,'(DQGUHVWDUWIRUWKDWQHZOLEUDU\WREH
UHFRJQL]HG
7KH$UGXLQROLEUDULHVDUHGRFXPHQWHGLQWKHUHIHUHQFHDWKWWSDUGXLQRFFHQ5HIHUHQFH
/LEUDULHVDQGHDFKOLEUDU\LQFOXGHVH[DPSOHVNHWFKHVGHPRQVWUDWLQJWKHLUXVH&KDS
WHUKDVGHWDLOVRQKRZWRQDYLJDWHWRWKHH[DPSOHVLQWKH,'(
7KHOLEUDULHVWKDWDUHLQFOXGHGZLWK$UGXLQRDVRIYHUVLRQDUH
((3520
8VHGWRVWRUHDQGUHDGLQIRUPDWLRQLQPHPRU\WKDWLVSUHVHUYHGZKHQSRZHULV
UHPRYHGVHH&KDSWHU
(WKHUQHW
8VHGWRFRPPXQLFDWHZLWKWKH$UGXLQR(WKHUQHWVKLHOGVHH&KDSWHU
)LUPDWD
$SURWRFROXVHGWRVLPSOLI\VHULDOFRPPXQLFDWLRQDQGFRQWURORIWKHERDUG
/LTXLG&U\VWDO
)RUFRQWUROOLQJFRPSDWLEOH/&'GLVSOD\VVHH&KDSWHU
0DWUL[
+HOSVPDQDJHDPDWUL[RI/('VVHH&KDSWHU
6'
6XSSRUWVUHDGLQJDQGZULWLQJILOHVWRDQ6'FDUGXVLQJH[WHUQDOKDUGZDUH
6HUYR
8VHGWRFRQWUROVHUYRPRWRUVVHH&KDSWHU
6RIWZDUH6HULDO
(QDEOHVDGGLWLRQDOVHULDOSRUWV
516 | Chapter 16:ಗUsing, Modifying, and Creating Libraries
63,
8VHGIRU(WKHUQHWDQG63,KDUGZDUHVHH&KDSWHU
6SULWH
(QDEOHVWKHXVHRIVSULWHVZLWKDQ/('PDWUL[
6WHSSHU
)RUZRUNLQJZLWKVWHSSHUPRWRUVVHH&KDSWHU
:LUH
:RUNVZLWK,&GHYLFHVDWWDFKHGWRWKH$UGXLQRVHH&KDSWHU
Discussion
/LEUDULHV WKDW ZRUN ZLWK VSHFLILF KDUGZDUH ZLWKLQ WKH $UGXLQR FRQWUROOHU FKLS RQO\
ZRUNRQSUHGHILQHGSLQV7KH:LUHDQG63,OLEUDULHVDUHH[DPSOHVRIWKLVNLQGRIOLEUDU\
/LEUDULHVWKDWDOORZXVHUVHOHFWLRQRISLQVXVXDOO\KDYHWKLVVSHFLILHGLQ setup6HUYR
/LTXLG&U\VWDODQG6WHSSHUDUHH[DPSOHVRIWKLVNLQGRIOLEUDU\6HHWKHOLEUDU\GRFX
PHQWDWLRQIRUVSHFLILFLQIRUPDWLRQRQKRZWRFRQILJXUHWKHOLEUDU\
,QFOXGLQJDOLEUDU\DGGVWKHOLEUDU\FRGHWR\RXUVNHWFKEHKLQGWKHVFHQHV7KLVPHDQV
WKHVL]HRI\RXUVNHWFKDVUHSRUWHGDWWKHHQGRIWKHFRPSLODWLRQSURFHVVZLOOLQFUHDVH
EXWWKH$UGXLQREXLOGSURFHVVLVVPDUWHQRXJKWRRQO\LQFOXGHWKHFRGH\RXUVNHWFKLV
DFWXDOO\XVLQJIURPWKHOLEUDU\VR\RXGRQ¦WKDYHWRZRUU\DERXWWKHPHPRU\RYHUKHDG
IRUPHWKRGVWKDWDUHQRWEHLQJXVHG7KHUHIRUH\RXDOVRGRQ¦WKDYHWRZRUU\DERXW
XQXVHGIXQFWLRQVUHGXFLQJWKHDPRXQWRIFRGH\RXFDQSXWLQWR\RXUVNHWFK
See Also
7KH$UGXLQRUHIHUHQFHIRUOLEUDULHVKWWSDUGXLQRFFHQ5HIHUHQFH/LEUDULHV
16.2 Installing Third-Party Libraries
Problem
<RX ZDQW WR XVH D OLEUDU\ FUHDWHG IRU XVH ZLWK $UGXLQR EXW QRW LQ WKH VWDQGDUG
GLVWULEXWLRQ
Solution
'RZQORDGWKHOLEUDU\,WZLOORIWHQEHD]LSILOH8Q]LSLWDQG\RXZLOOKDYHDIROGHUWKDW
KDVWKHVDPHWLWOHDVWKHQDPHRIWKHOLEUDU\7KLVIROGHUQHHGVWREHSXWLQVLGHDIROGHU
FDOOHGOLEUDULHVLQVLGH\RXU$UGXLQRGRFXPHQWIROGHU7RILQGWKH$UGXLQRGRFXPHQW
IROGHUODXQFK$UGXLQRDQGFKRRVH6NHWFK→6KRZ6NHWFK)ROGHU*RXSWRWKHSDUHQW
GLUHFWRU\RIWKHIROGHUWKDWDSSHDUVDQG\RX¦OOEHLQWKH$UGXLQRGRFXPHQWIROGHU,I
QROLEUDULHVIROGHUH[LVWVFUHDWHRQHDQGSXWWKHOLEUDU\LQVLGHLW
16.2 Installing Third-Party Libraries | 517
Download from Wow! eBook <www.wowebook.com>
,IWKH$UGXLQR,'(LVUXQQLQJTXLWWKHSURJUDPDQGUHVWDUWLW7KH,'(VFDQVWKLVIROGHU
WRILQGOLEUDULHVRQO\ZKHQLWLVODXQFKHG,I\RXQRZJRWRWKHPHQX6NHWFKൺ,PSRUW
/LEUDU\DWWKHERWWRPEHORZWKHJUD\OLQHDQGWKHZRUG&RQWULEXWHG\RXVKRXOGVHH
WKHOLEUDU\\RXKDYHDGGHG
,IWKHOLEUDULHVSURYLGHH[DPSOHVNHWFKHV\RXFDQYLHZWKHVHIURPWKH,'(PHQXFOLFN
)LOHൺ([DPSOHVDQGWKHOLEUDULHVH[DPSOHVZLOOEHXQGHUWKHOLEUDULHVQDPHLQDVHFWLRQ
EHWZHHQWKHJHQHUDOH[DPSOHVDQGWKH$UGXLQRGLVWULEXWHGOLEUDU\H[DPSOHOLVWLQJ
Discussion
$ODUJHQXPEHURIOLEUDULHVDUHSURYLGHGE\WKLUGSDUWLHV0DQ\DUHRIYHU\KLJKTXDOLW\
DUHDFWLYHO\PDLQWDLQHGDQGSURYLGHJRRGGRFXPHQWDWLRQDQGH[DPSOHVNHWFKHV7KH
$UGXLQR3OD\JURXQGLVDJRRGSODFHWRORRNIRUOLEUDULHVKWWSZZZDUGXLQRFFSOD\
JURXQG
/RRNIRUOLEUDULHVWKDWKDYHFOHDUGRFXPHQWDWLRQDQGH[DPSOHV&KHFNRXWWKH$UGXLQR
IRUXPVWRVHHLIWKHUHDUHDQ\WKUHDGV GLVFXVVLRQWRSLFV WKDWGLVFXVVWKHOLEUDU\/L
EUDULHVWKDWZHUHGHVLJQHGWREHXVHGZLWKHDUO\$UGXLQRUHOHDVHVPD\KDYHSUREOHPV
ZKHQXVHGZLWKWKHODWHVW$UGXLQRYHUVLRQVR\RXPD\QHHGWRUHDGWKURXJKDORWRI
PDWHULDO VRPHWKUHDGVIRUSRSXODUOLEUDULHVFRQWDLQKXQGUHGVRISRVWV WRILQGLQIRU
PDWLRQRQXVLQJDQROGHUOLEUDU\ZLWKWKHODWHVW$UGXLQRUHOHDVH
,IWKHOLEUDU\H[DPSOHVGRQRWDSSHDULQWKH([DPSOHVPHQXRU\RXJHWDPHVVDJHVD\LQJ
£/LEUDU\ QRW IRXQG¤ ZKHQ \RX WU\ WR XVH WKH OLEUDU\ FKHFN WKDW WKH OLEUDULHV IROGHU
LV LQ WKH FRUUHFW SODFH ZLWK WKH QDPH VSHOOHG FRUUHFWO\ $ OLEUDU\ IROGHU QDPHG
/LEUDU\1DPH! ZKHUH/LEUDU\1DPH!LVWKHQDPHIRUWKHOLEUDU\ PXVWFRQWDLQD
ILOHQDPHG/LEUDU\1DPH!KZLWKWKHVDPHVSHOOLQJDQGFDSLWDOL]DWLRQ&KHFNWKDW
DGGLWLRQDOILOHVQHHGHGE\WKHOLEUDU\DUHLQWKHIROGHU
16.3 Modifying a Library
Problem
<RXZDQWWRFKDQJHWKHEHKDYLRURIDQH[LVWLQJOLEUDU\SHUKDSVWRH[WHQGLWVFDSDELOLW\
)RUH[DPSOHWKH7LPH$ODUPVOLEUDU\LQ&KDSWHURQO\VXSSRUWVVL[DODUPVDQG\RX
QHHGPRUH VHH5HFLSH Solution
7KH 7LPH DQG 7LPH$ODUPV OLEUDULHV DUH GHVFULEHG LQ &KDSWHU VR UHIHU WR 5HF
LSH WR IDPLOLDUL]H \RXUVHOI ZLWK WKH VWDQGDUG IXQFWLRQDOLW\ 7KH OLEUDULHV FDQ
EH GRZQORDGHG IURP WKH ZHEVLWH IRU WKLV ERRN RU IURP KWWSZZZDUGXLQRFFSOD\
JURXQGXSORDGV&RGH7LPH]LS WKLVGRZQORDGLQFOXGHVERWKOLEUDULHV 518 | Chapter 16:ಗUsing, Modifying, and Creating Libraries
2QFH\RXKDYHWKH7LPHDQG7LPH$ODUPVOLEUDULHVLQVWDOOHGFRPSLOHDQGXSORDGWKH
IROORZLQJVNHWFKZKLFKZLOODWWHPSWWRFUHDWHVHYHQDODUPV¢RQHPRUHWKDQWKHOLEUD
ULHVVXSSRUW(DFKAlarmWDVNVLPSO\SULQWVLWVWDVNQXPEHU
/*
multiple_alarms sketch
has more timer repeats than the library supports out of the box you will need to edit the header file to enable more than 6 alarms
*/
#include <Time.h>
#include <TimeAlarms.h>
int currentSeconds = 0;
void setup()
{
Serial.begin(9600);
}
// create 7 alarm tasks
Alarm.timerRepeat(1, repeatTask1);
Alarm.timerRepeat(2, repeatTask2);
Alarm.timerRepeat(3, repeatTask3);
Alarm.timerRepeat(4, repeatTask4);
Alarm.timerRepeat(5, repeatTask5);
Alarm.timerRepeat(6, repeatTask6);
Alarm.timerRepeat(7, repeatTask7);
void repeatTask1()
{
Serial.print("task 1
}
void repeatTask2()
{
Serial.print("task 2
}
void repeatTask3()
{
Serial.print("task 3
}
void repeatTask4()
{
Serial.print("task 4
}
void repeatTask5()
{
Serial.print("task 5
}
//7th timer repeat
");
");
");
");
");
void repeatTask6()
16.3 Modifying a Library | 519
{
}
Serial.print("task 6
void repeatTask7()
{
Serial.print("task 7
}
");
");
void loop()
{
if(second() != currentSeconds)
{
// print the time for each new second
// the task numbers will be printed when the alarm for that task is triggered
Serial.println();
Serial.print(second());
Serial.print("->");
currentSeconds = second();
Alarm.delay(1); //Alarm.delay must be called to service the alarms
}
}
2SHQWKH6HULDO0RQLWRUDQGZDWFKWKHRXWSXWEHLQJSULQWHG$IWHUQLQHVHFRQGVRI
RXWSXW\RXVKRXOGVHHWKLV
1->task 1
2->task 1
3->task 1
4->task 1
5->task 1
6->task 1
7->task 1
8->task 1
9->task 1
task 2
task 3
task 2
task 5
task 2
task 2
task 3
task 4
task 3
task 6
task 4
7KHWDVNVFKHGXOHGIRUVHYHQVHFRQGVGLGQRWWULJJHUEHFDXVHWKHOLEUDU\RQO\SURYLGHV
VL[WLPHU£REMHFWV¤WKDW\RXFDQXVH
<RXFDQLQFUHDVHWKLVE\PRGLI\LQJWKHOLEUDU\*RWRWKHOLEUDULHVIROGHULQ\RXU$UGXLQR
'RFXPHQWVIROGHU
<RXFDQORFDWHWKHGLUHFWRU\FRQWDLQLQJWKHVNHWFKERRNIROGHUE\FOLFN
LQJRQWKHPHQXLWHP)LOHൺ3UHIHUHQFHVLQWKH,'($GLDORJER[ZLOO
RSHQVKRZLQJWKHVNHWFKERRNORFDWLRQ
,I \RX KDYH LQVWDOOHG WKH 7LPH DQG 7LPH$ODUPV OLEUDULHV ERWK OLEUDULHV DUH LQ WKH
ILOH \RX GRZQORDGHG QDYLJDWH WR WKH /LEUDULHV?7LPH$ODUPV IROGHU 2SHQ WKH
7LPH$ODUPVKKHDGHUILOH IRUPRUHGHWDLOVDERXWKHDGHUILOHVVHH5HFLSH <RX
FDQHGLWWKHILOHZLWKDQ\WH[WHGLWRUIRUH[DPSOH1RWHSDGRQ:LQGRZVRU7H[W(GLW
RQD0DF
520 | Chapter 16:ಗUsing, Modifying, and Creating Libraries
<RXVKRXOGVHHWKHIROORZLQJDWWKHWRSRIWKH7LPH$ODUPVKILOH
#ifndef TimeAlarms_h
#define TimeAlarms_h
#include <inttypes.h>
#include "Time.h"
#define dtNBR_ALARMS 6
7KHPD[LPXPQXPEHURIDODUPVLVVSHFLILHGE\WKHYDOXHGHILQHGIRUdtNbr_ALARMS
&KDQJH
#define dtNBR_ALARMS 6
WR
#define dtNMBR_ALARMS 7
DQGVDYHWKHILOH
8SORDGWKHVNHWFKWR\RXU$UGXLQRDJDLQDQGWKLVWLPHWKHVHULDORXWSXWVKRXOGUHDG
1->task 1
2->task 1
3->task 1
4->task 1
5->task 1
6->task 1
7->task 1
8->task 1
9->task 1
task 2
task 3
task 2
task 5
task 2
task 7
task 2
task 3
task 4
task 3
task 6
task 4
<RXFDQVHHWKDWWDVNQRZDFWLYDWHVDIWHUVHYHQVHFRQGV
Discussion
&DSDELOLWLHVRIIHUHGE\DOLEUDU\DUHDWUDGHRIIEHWZHHQWKHUHVRXUFHVXVHGE\WKHOLEUDU\
DQGWKHUHVRXUFHVDYDLODEOHWRWKHUHVWRI\RXUVNHWFKDQGLWLVRIWHQSRVVLEOHWRFKDQJH
WKHVHFDSDELOLWLHVLIUHTXLUHG)RUH[DPSOH\RXPD\QHHGWRGHFUHDVHWKHDPRXQWRI
PHPRU\XVHGIRUDVHULDOOLEUDU\VRWKDWRWKHUFRGHLQWKHVNHWFKKDVPRUH5$02U
\RXPD\QHHGWRLQFUHDVHWKHPHPRU\XVDJHE\DOLEUDU\IRU\RXUDSSOLFDWLRQ7KHOLEUDU\
ZULWHUJHQHUDOO\FUHDWHVWKHOLEUDU\WRPHHWW\SLFDOVFHQDULRVEXWLI\RXUDSSOLFDWLRQ
QHHGVFDSDELOLWLHVQRWFDWHUHGWRE\WKHOLEUDU\ZULWHU\RXPD\EHDEOHWRPRGLI\WKH
OLEUDU\WRDFFRPPRGDWHWKHP
,QWKLVH[DPSOHWKH7LPH$ODUPVOLEUDU\DOORFDWHVURRP LQ5$0 IRUVL[DODUPV(DFK
RIWKHVHFRQVXPHVDURXQGDGR]HQE\WHVDQGWKHVSDFHLVUHVHUYHGHYHQLIRQO\DIHZ
DUHXVHG7KHQXPEHURIDODUPVLVVHWLQWKHOLEUDU\KHDGHUILOH WKHKHDGHULVDILOHQDPHG
7LPH$ODUPVKLQWKH7LPH$ODUPVIROGHU +HUHDUHWKHILUVWIHZOLQHVRI7LPH$ODUPVK
#ifndef TimeAlarms_h
#define TimeAlarms_h
#include <inttypes.h>
16.3 Modifying a Library | 521
#include "Time.h"
#define dtNBR_ALARMS 6
,QWKH7LPH$ODUPVOLEUDU\WKHPD[LPXPQXPEHURIDODUPVLVVHWXVLQJD#defineVWDWH
PHQW%HFDXVH\RXFKDQJHGLWDQGVDYHGWKHKHDGHUILOHZKHQ\RXUHFRPSLOHGWKHVNHWFK
WRXSORDGLWLWXVHVWKHQHZXSSHUOLPLW
6RPHWLPHVFRQVWDQWVDUHXVHGWRGHILQHFKDUDFWHULVWLFVVXFKDVWKHFORFNVSHHGRIWKH
ERDUGDQGZKHQXVHGZLWKDERDUGWKDWUXQVDWDGLIIHUHQWVSHHG\RXZLOOJHWXQH[
SHFWHGUHVXOWV(GLWLQJWKLVYDOXHLQWKHKHDGHUILOHWRWKHFRUUHFWRQHIRUWKHERDUG\RX
DUHXVLQJZLOOIL[WKLVSUREOHP
,I\RXHGLWWKHKHDGHUILOHDQGWKHOLEUDU\VWRSVZRUNLQJ\RXFDQDOZD\VGRZQORDGWKH
OLEUDU\DJDLQDQGUHSODFHWKHZKROHOLEUDU\WRUHWXUQWRWKHRULJLQDOVWDWH
See Also
5HFLSHKDVPRUHGHWDLOVRQKRZ\RXFDQDGGIXQFWLRQDOLW\WROLEUDULHV
16.4 Creating Your Own Library
Problem
<RXZDQWWRFUHDWH\RXURZQOLEUDU\/LEUDULHVDUHDFRQYHQLHQWZD\WRUHXVHFRGHDFURVV
PXOWLSOHVNHWFKHVDQGDUHDJRRGZD\WRVKDUHZLWKRWKHUXVHUV
Solution
$OLEUDU\LVDFROOHFWLRQRIPHWKRGVDQGYDULDEOHVWKDWDUHFRPELQHGLQDIRUPDWWKDW
HQDEOHVXVHUVWRDFFHVVIXQFWLRQVDQGYDULDEOHVLQDVWDQGDUGL]HGZD\
0RVW$UGXLQROLEUDULHVDUHZULWWHQDVDFODVV,I\RXDUHIDPLOLDUZLWK&RU-DYD\RX
ZLOOEHIDPLOLDUZLWKFODVVHV+RZHYHU\RXFDQFUHDWHDOLEUDU\ZLWKRXWXVLQJDFODVV
DQGWKLVUHFLSHVKRZV\RXKRZ
7KLVUHFLSHH[SODLQVKRZ\RXFDQWUDQVIRUPWKHVNHWFKIURP5HFLSHWRPRYHWKH
BlinkLEDIXQFWLRQLQWRDOLEUDU\
6HH5HFLSHIRUWKHZLULQJGLDJUDPDQGDQH[SODQDWLRQRIWKHFLUFXLW+HUHLVWKH
VNHWFKWKDWZLOOEHWKHVWDUWLQJSRLQWIRUWKHOLEUDU\
/*
* blinkLibTest
*/
const int firstLedPin = 3;
const int secondLedPin = 5;
const int thirdLedPin = 6;
// choose the pin for each of the LEDs
522 | Chapter 16:ಗUsing, Modifying, and Creating Libraries
void setup()
{
pinMode(firstLedPin, OUTPUT);
pinMode(secondLedPin, OUTPUT);
pinMode(thirdLedPin, OUTPUT);
}
// declare LED pins as output
// declare LED pins as output
// declare LED pins as output
void loop()
{
// flash each of the LEDs for 1000 milliseconds (1 second)
blinkLED(firstLedPin, 1000);
blinkLED(secondLedPin, 1000);
blinkLED(thirdLedPin, 1000);
}
7KHblinkLEDIXQFWLRQIURP5HFLSHVKRXOGEHUHPRYHGIURPWKHVNHWFKDQGPRYHG
LQWR D VHSDUDWH ILOH QDPHG EOLQN/('FSS VHH WKH 'LVFXVVLRQ IRU PRUH GHWDLOV
DERXWFSSILOHV /* blinkLED.cpp
* simple library to light an LED for a duration given in milliseconds
*/
#include <WProgram.h> // Arduino includes
#include "blinkLED.h"
// blink the LED on the given pin for the duration in milliseconds
void blinkLED(int pin, int duration)
{
digitalWrite(pin, HIGH);
// turn LED on
delay(duration);
digitalWrite(pin, LOW);
// turn LED off
delay(duration);
}
&UHDWHWKHEOLQN/('KKHDGHUILOHDVIROORZV
/*
* blinkLED.h
* Library header file for BlinkLED library
*/
void blinkLED(int pin, int duration);
// function prototype
Discussion
7KH OLEUDU\ ZLOO EH QDPHG EOLQN/(' DQG ZLOO EH ORFDWHG LQ WKH OLEUDULHV IROGHU VHH
5HFLSH 7KH blinkLEDIXQFWLRQIURP5HFLSHLVPRYHGRXWRIWKHVNHWFKDQGLQWRDOLEUDU\
ILOHQDPHGEOLQN/('FSS WKHFSSH[WHQVLRQVWDQGVIRU£&SOXVSOXV¤DQGFRQWDLQVWKH
H[HFXWDEOHFRGH 16.4 Creating Your Own Library | 523
7KHWHUPVIXQFWLRQVDQGPHWKRGVDUHXVHGLQ$UGXLQROLEUDU\GRFXPHQ
WDWLRQWRUHIHUWREORFNVRIFRGHVXFKDVblinkLED7KHWHUPPHWKRGZDV
LQWURGXFHGWRUHIHUWRWKHIXQFWLRQDOEORFNVLQDFODVV%RWKWHUPVUHIHU
WRWKHQDPHGIXQFWLRQDOEORFNVWKDWDUHPDGHDFFHVVLEOHE\DOLEUDU\
7KHEOLQN/('FSSILOHFRQWDLQVD blinkLEDIXQFWLRQWKDWLVLGHQWLFDOWRWKHFRGHIURP
5HFLSHZLWKWKHIROORZLQJWZROLQHVDGGHGDWWKHWRS
#include <WProgram.h> // Arduino includes
#include "blinkLED.h"
7KH#include <WProgram.h>OLQHLVQHHGHGE\DOLEUDU\WKDWXVHVDQ\$UGXLQRIXQFWLRQV
RUFRQVWDQWV:LWKRXWWKLVWKHFRPSLOHUZLOOUHSRUWHUURUVIRUDOOWKH$UGXLQRIXQFWLRQV
XVHGLQ\RXUVNHWFK
7KHQH[WOLQH #include "blinkLED.h"FRQWDLQVWKHIXQFWLRQGHILQLWLRQV DOVRNQRZQ
DVSURWRW\SHV IRU\RXUOLEUDU\7KH$UGXLQREXLOGSURFHVVFUHDWHVSURWRW\SHVIRUDOOWKH
IXQFWLRQVZLWKLQDVNHWFKDXWRPDWLFDOO\ZKHQDVNHWFKLVFRPSLOHG¢EXWLWGRHVQRW
FUHDWHDQ\SURWRW\SHVIRUOLEUDU\FRGHVRLI\RXPDNHDOLEUDU\\RXPXVWFUHDWHDKHDGHU
ZLWKWKHVHSURWRW\SHV,WLVWKLVKHDGHUILOHWKDWLVDGGHGWRDVNHWFKZKHQ\RXLPSRUW
DOLEUDU\IURPWKH,'( VHH5HFLSH (YHU\OLEUDU\PXVWKDYHDILOHWKDWGHFODUHVWKHQDPHVRIWKHIXQFWLRQV
WR EH H[SRVHG 7KLV ILOH LV FDOOHG D KHDGHU ILOH DOVR NQRZQ DV DQ LQ
FOXGH ILOH DQG KDV WKH IRUP /LEUDU\1DPH!K ZKHUH /LEUDU\
1DPH!LVWKHQDPHIRU\RXUOLEUDU\ ,QWKLVH[DPSOHWKHKHDGHUILOHLV
QDPHGEOLQN/('KDQGLVLQWKHVDPHIROGHUDVEOLQN/('FSS
7KHKHDGHUILOHIRUWKLVOLEUDU\LVVLPSOH,WGHFODUHVWKHRQHIXQFWLRQ
void blinkLED(int pin, int duration);
// function prototype
7KLVORRNVVLPLODUWRWKHIXQFWLRQGHILQLWLRQLQWKHEOLQN/('FSSILOH
void blinkLED(int pin, int duration)
7KHGLIIHUHQFHLVVXEWOHEXWYLWDO7KHKHDGHUILOHSURWRW\SHFRQWDLQVDWUDLOLQJVHPLFR
ORQ7KLVWHOOVWKHFRPSLOHUWKDWWKLVLVMXVWDGHFODUDWLRQRIWKHIRUPIRUWKHIXQFWLRQ
EXW QRW WKH FRGH 7KH VRXUFH ILOH EOLQN/('FSS GRHV QRW FRQWDLQ WKH WUDLOLQJ
VHPLFRORQ DQG WKLV LQIRUPV WKH FRPSLOHU WKDW WKLV LV WKH DFWXDO VRXUFH FRGH IRU WKH
IXQFWLRQ
/LEUDULHVFDQKDYHPRUHWKDQRQHKHDGHUILOHDQGPRUHWKDQRQHLPSOH
PHQWDWLRQ ILOH %XW WKHUH PXVW EH DW OHDVW RQH KHDGHU DQG WKDW PXVW
PDWFKWKHOLEUDU\QDPH,WLVWKLVILOHWKDWLVLQFOXGHGDWWKHWRSRIWKH
VNHWFKZKHQ\RXLPSRUWDOLEUDU\
524 | Chapter 16:ಗUsing, Modifying, and Creating Libraries
$JRRGERRNRQ&FDQSURYLGHPRUHGHWDLOVRQXVLQJKHDGHUDQGFSSILOHVWRFUHDWH
FRGHPRGXOHV7KLVUHFLSH¦V6HH$OVRVHFWLRQOLVWVVRPHSRSXODUFKRLFHV
:LWKWKHEOLQN/('FSSDQGEOLQN/('KILOHVLQWKHFRUUHFWSODFHZLWKLQWKHOLEUDULHV
IROGHUFORVHWKH,'(DQGUHRSHQLW
7KH$UGXLQR,'(XSGDWHVLWVOLVWRIDYDLODEOHOLEUDULHVRQO\ZKHQWKH,'(
LVILUVWVWDUWHGRQ\RXUFRPSXWHU,I\RXFUHDWHDOLEUDU\DIWHUWKH,'(LV
UXQQLQJ \RX QHHG WR FORVH WKH ,'( DQG UHVWDUW IRU WKDW OLEUDU\ WR EH
UHFRJQL]HG
8SORDGWKHEOLQN/LE7HVWVNHWFKDQG\RXVKRXOGVHHWKHWKUHH/('VEOLQNLQJ
,W¦VHDV\WRDGGDGGLWLRQDOIXQFWLRQDOLW\WRWKHOLEUDU\)RUH[DPSOH\RXFDQDGGVRPH
FRQVWDQWYDOXHVIRUFRPPRQGHOD\VVRWKDWXVHUVRI\RXUOLEUDULHVFDQXVHWKHGHVFULSWLYH
FRQVWDQWVLQVWHDGRIPLOOLVHFRQGYDOXHV
$GGWKHWKUHHOLQHVZLWKFRQVWDQWYDOXHVWR\RXUKHDGHUILOHDVIROORZV
// constants for duration
const int BLINK_SHORT = 250;
const int BLINK_MEDIUM = 500;
const int BLINK_LONG = 1000;
void blinkLED(int pin, int duration);
// function prototype
&KDQJHWKHFRGHLQloopDVIROORZVDQGXSORDGWKHVNHWFKWRVHHWKHGLIIHUHQWEOLQNUDWHV
void loop()
{
blinkLED(firstLedPin, BLINK_SHORT);
blinkLED(secondLedPin, BLINK_MEDIUM);
blinkLED(thirdLedPin, BLINK_LONG);
}
<RXQHHGWRFORVHDQGUHVWDUWWKH,'(ZKHQ\RXILUVWDGGWKHOLEUDU\WR
WKHOLEUDULHVIROGHUEXWQRWDIWHUVXEVHTXHQWFKDQJHVWRWKHOLEUDU\/L
EUDULHVLQFOXGHGLQ$UGXLQRUHOHDVHDQGODWHUDUHUHFRPSLOHGHDFK
WLPHWKHVNHWFKLVFRPSLOHG$UGXLQRUHOHDVHVHDUOLHUWKDQUHTXLUHG
WKHGHOHWLRQRIWKHOLEUDU\REMHFWILOHVWRPDNHWKHOLEUDU\UHFRPSLOHDQG
IRUFKDQJHVWREHLQFOXGHG
1HZIXQFWLRQVFDQEHHDVLO\DGGHG7KLVH[DPSOHDGGVDIXQFWLRQWKDWFRQWLQXHVEOLQN
LQJIRUWKHQXPEHURIWLPHVJLYHQE\WKHVNHWFK+HUHLVWKHloopFRGH
void loop()
{
blinkLED(firstLedPin,BLINK_SHORT,5 );
blinkLED(secondLedPin,BLINK_MEDIUM,3 );
blinkLED(thirdLedPin, BLINK_LONG);
}
// blink 5 times
// blink 3 times
// blink once
16.4 Creating Your Own Library | 525
7RDGGWKLVIXQFWLRQDOLW\WRWKHOLEUDU\DGGWKHSURWRW\SHWREOLQN/('KDVIROORZV
/*
* BlinkLED.h
* Header file for BlinkLED library
*/
const int BLINK_SHORT = 250;
const int BLINK_MEDIUM = 500;
const int BLINK_LONG = 1000;
void blinkLED(int pin, int duration);
// new function for repeat count
void blinkLED(int pin, int duration, int repeats);
$GGWKHIXQFWLRQLQWREOLQN/('FSS
/*
* BlinkLED.cpp
*/
#include <WProgram.h> // Arduino includes
#include "BlinkLED.h"
// blink the LED on the given pin for the duration in milliseconds
void blinkLED(int pin, int duration)
{
digitalWrite(pin, HIGH);
// turn LED on
delay(duration);
digitalWrite(pin, LOW);
// turn LED off
delay(duration);
}
/* function to repeat blinking
void blinkLED(int pin, int duration, int repeats)
{
while(repeats)
{
blinkLED(pin, duration);
repeats = repeats -1;
}
}
<RXFDQFUHDWHDNH\ZRUGVW[WILOHLI\RXZDQWWRDGGV\QWD[KLJKOLJKWLQJ FRORULQJWKH
NH\ZRUGVXVHGLQ\RXUOLEUDU\ZKHQYLHZLQJDVNHWFKLQWKH,'( 7KLVLVDWH[WILOHWKDW
FRQWDLQVWKHQDPHRIWKHNH\ZRUGDQGWKHNH\ZRUGW\SH¢HDFKW\SHXVHVDGLIIHUHQW
FRORU7KHNH\ZRUGDQGW\SHPXVWEHVHSDUDWHGE\DWDE QRWDVSDFH )RUH[DPSOH
VDYHWKHIROORZLQJILOHDVNH\ZRUGVW[WLQWKHEOLQN/('IROGHU
#######################################
# Methods and Functions (KEYWORD2)
#######################################
blinkLED KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
526 | Chapter 16:ಗUsing, Modifying, and Creating Libraries
Download from Wow! eBook <www.wowebook.com>
BLINK_SHORT
BLINK_MEDIUM
BLINK_LONG
LITERAL1
LITERAL1
LITERAL1
See Also
£:ULWLQJD/LEUDU\IRU$UGXLQR¤UHIHUHQFHGRFXPHQWKWWSZZZDUGXLQRFFHQ+DFN
LQJ/LEUDU\7XWRULDO
$OVRVHHWKHIROORZLQJERRNVRQ&
3UDFWLFDO&3URJUDPPLQJE\6WHYH2XDOOLQH 2¦5HLOO\
&3ULPHU3OXVE\6WHSKHQ3UDWD 6DPV
&3ULPHUE\6WDQOH\%/LSSPDQ-RVpH/DMRLHDQG%DUEDUD(0RR $GGLVRQ
:HVOH\3URIHVVLRQDO
16.5 Creating a Library That Uses Other Libraries
Problem
<RXZDQWWRFUHDWHDOLEUDU\WKDWXVHVIXQFWLRQDOLW\IURPRQHRUPRUHH[LVWLQJOLEUDULHV
)RUH[DPSOH\RXZDQWWRFUHDWHDOLEUDU\WRDLGGHEXJJLQJWKDWVHQGVSULQWRXWSXWWR
DVHFRQG$UGXLQRERDUGXVLQJWKH:LUHOLEUDU\
Solution
7KLVUHFLSHXVHVWKH:LUHOLEUDU\GLVFXVVHGLQ&KDSWHUDQGWKHFRUH$UGXLQRSULQW
IXQFWLRQDOLW\WRFUHDWHDQHZOLEUDU\WKDWVHQGVSULQWHGRXWSXWWRDQRWKHU$UGXLQRERDUG
FRQQHFWHGXVLQJ,&7KHFRQQHFWLRQVDQGFRGHDUHFRYHUHGLQ5HFLSH7KLVUHFLSH
GHVFULEHVKRZWKDWFRGHFDQEHFRQYHUWHGLQWRDOLEUDU\
&UHDWHDIROGHUQDPHGLF'HEXJLQWKHOLEUDULHVGLUHFWRU\ VHH5HFLSHIRUGHWDLOV
RQWKHILOHVWUXFWXUHIRUDOLEUDU\ &UHDWHDILOHQDPHGLF'HEXJKZLWKWKHIROORZLQJ
FRGH
/*
* i2cDebug.h
*/
#include <WProgram.h>
#include <Print.h>
// the Arduino print class
class I2CDebugClass : public Print
{
private:
int I2CAddress;
byte count;
void write(byte c);
public:
I2CDebugClass();
16.5 Creating a Library That Uses Other Libraries | 527
};
boolean begin(int id);
extern I2CDebugClass i2cDebug;
// the i2c debug object
&UHDWHDILOHQDPHGLF'HEXJFSSLQWKHLF'HEXJIROGHUDVIROORZV
/*
* i2cDebug.cpp
*/
#include <i2cDebug.h>
#include <Wire.h>
// the Arduino I2C library
I2CDebugClass::I2CDebugClass()
{
}
boolean I2CDebugClass::begin(int id)
{
I2CAddress = id; // save the slave's address
Wire.begin(); // join I2C bus (address optional for master)
return true;
}
void I2CDebugClass::write(byte c)
{
if( count == 0)
{
// here if the first char in the transmission
Wire.beginTransmission(I2CAddress); // transmit to device
}
Wire.send(c);
// if the I2C buffer is full or an end of line is reached, send the data
// BUFFER_LENGTH is defined in the Wire library
if(++count >= BUFFER_LENGTH || c == '\n')
{
// send data if buffer full or newline character
Wire.endTransmission();
count = 0;
}
}
I2CDebugClass i2cDebug;
// Create an I2C debug object
/RDGWKLVH[DPSOHVNHWFKLQWRWKH,'(
/*
* i2cDebug
* example sketch for i2cDebug library
*/
#include <Wire.h>
// the Arduino I2C library
#include <i2cDebug.h>
528 | Chapter 16:ಗUsing, Modifying, and Creating Libraries
const int address = 4;
const int sensorPin = 0;
int val;
//the address to be used by the communicating devices
// select the analog input pin for the sensor
// variable to store the sensor value
void setup()
{
Serial.begin(9600);
i2cDebug.begin(address);
}
void loop()
{
// read the voltage on the pot(val ranges from 0 to 1023)
val = analogRead(sensorPin);
Serial.println(val);
i2cDebug.println(val);
}
5HPHPEHUWKDW\RXQHHGWRUHVWDUWWKH,'(DIWHUFUHDWLQJWKHOLEUDU\IROGHU6HH5HF
LSHIRUPRUHGHWDLORQFUHDWLQJDOLEUDU\
8SORDGWKHVODYH,&VNHWFKRQWRDQRWKHU$UGXLQRERDUGDVGHVFULEHGLQ5HFLSH
DQG\RXVKRXOGVHHWKHRXWSXWIURPWKH$UGXLQRERDUGUXQQLQJ\RXUOLEUDU\GLVSOD\HG
RQWKHVHFRQGERDUG
Discussion
7RLQFOXGHDQRWKHUOLEUDU\XVHLWV includeVWDWHPHQWLQ\RXUFRGHDV\RXZRXOGLQD
VNHWFK,WLVVHQVLEOHWRLQFOXGHLQIRUPDWLRQDERXWDQ\DGGLWLRQDOOLEUDULHVWKDW\RXU
OLEUDU\QHHGVLQGRFXPHQWDWLRQLI\RXPDNHLWDYDLODEOHIRURWKHUVWRXVHHVSHFLDOO\LI
LWUHTXLUHVDOLEUDU\WKDWLVQRWGLVWULEXWHGZLWK$UGXLQR
7KLVUHFLSHSURYLGHVDQH[DPSOHRIKRZWRXVHDFODVVZKHQFUHDWLQJDOLEUDU\$FODVV
LVDSURJUDPPLQJWHFKQLTXHIRUJURXSLQJIXQFWLRQVDQGYDULDEOHVWRJHWKHU7KHIRO
ORZLQJUHIHUHQFHVSURYLGHDQLQWURGXFWLRQWRFODVVHV
3URJUDPPLQJ,QWHUDFWLYLW\E\-RVKXD1REOH 2¦5HLOO\
&3ULPHUE\6WDQOH\%/LSSPDQ-RVpH/DMRLHDQG%DUEDUD(0RR $GGLVRQ
:HVOH\3URIHVVLRQDO
16.5 Creating a Library That Uses Other Libraries | 529
CHAPTER 17
Advanced Coding and
Memory Handling
17.0 Introduction
$V\RXGRPRUHZLWK\RXU$UGXLQR\RXUVNHWFKHVQHHGWREHFRPHPRUHHIILFLHQW7KH
WHFKQLTXHVLQWKLVFKDSWHUFDQKHOS\RXLPSURYHWKHSHUIRUPDQFHDQGUHGXFHWKHFRGH
VL]HRI\RXUVNHWFKHV,I\RXQHHGWRPDNH\RXUVNHWFKUXQIDVWHURUXVHOHVV5$0WKH
UHFLSHVKHUHFDQKHOS7KHUHFLSHVKHUHDUHPRUHWHFKQLFDOWKDQPRVWRIWKHRWKHUUHFLSHV
LQWKLVERRNEHFDXVHWKH\FRYHUWKLQJVWKDWDUHXVXDOO\FRQFHDOHGE\WKHIULHQGO\$UGXLQR
ZUDSSHU
7KH$UGXLQREXLOGSURFHVVZDVGHVLJQHGWRKLGHFRPSOH[DVSHFWVRI&DQG&DVZHOO
DVWKHWRROVXVHGWRFRQYHUWDVNHWFKLQWRWKHE\WHVWKDWDUHXSORDGHGDQGUXQRQDQ
$UGXLQRERDUG%XWLI\RXUSURMHFWKDVSHUIRUPDQFHDQGUHVRXUFHUHTXLUHPHQWVEH\RQG
WKHFDSDELOLW\RIWKHVWDQGDUG$UGXLQRHQYLURQPHQW\RXVKRXOGILQGWKHUHFLSHVKHUH
XVHIXO
7KH$UGXLQRERDUGXVHVPHPRU\WRVWRUHLQIRUPDWLRQ,WKDVWKUHHNLQGVRIPHPRU\
SURJUDPPHPRU\UDQGRPDFFHVVPHPRU\ 5$0 DQG((3520(DFKKDVGLIIHUHQW
FKDUDFWHULVWLFVDQGXVHV0DQ\RIWKHWHFKQLTXHVLQWKLVFKDSWHUFRYHUZKDWWRGRLI\RX
GRQRWKDYHHQRXJKRIRQHNLQGRIPHPRU\
3URJUDPPHPRU\ DOVRNQRZQDVIODVK LVZKHUHWKHH[HFXWDEOHVNHWFKFRGHLVVWRUHG
7KHFRQWHQWVRISURJUDPPHPRU\FDQRQO\EHFKDQJHGE\WKHERRWORDGHULQWKHXSORDG
SURFHVVLQLWLDWHGE\WKH$UGXLQRVRIWZDUHUXQQLQJRQ\RXUFRPSXWHU$IWHUWKHXSORDG
SURFHVVLVFRPSOHWHGWKHPHPRU\FDQQRWEHFKDQJHGXQWLOWKHQH[WXSORDG7KHUHLV
IDUPRUHSURJUDPPHPRU\RQDQ$UGXLQRERDUGWKDQ5$0VRLWFDQEHEHQHILFLDOWR
VWRUHYDOXHVWKDWGRQ¦WFKDQJHZKLOHWKHFRGHUXQV HJFRQVWDQWV LQSURJUDPPHPRU\
7KHERRWORDGHUWDNHVXSVRPHVSDFHLQSURJUDPPHPRU\,IDOORWKHUDWWHPSWVWRPLQ
LPL]HWKHFRGHWRILWLQSURJUDPPHPRU\KDYHIDLOHGWKHERRWORDGHUFDQEHUHPRYHG
WRIUHHXSVSDFHEXWDQDGGLWLRQDOKDUGZDUHSURJUDPPHULVWKHQQHHGHGWRJHWFRGH
RQWRWKHERDUG
531
,I\RXUFRGHLVODUJHUWKDQWKHSURJUDPPHPRU\VSDFHDYDLODEOHRQWKHFKLSWKHXSORDG
ZLOOQRWZRUNDQGWKH,'(ZLOOZDUQ\RXWKDWWKHVNHWFKLVWRRELJZKHQ\RXFRPSLOH
5$0LVXVHGE\WKHFRGHDVLWUXQVWRVWRUHWKHYDOXHVIRUWKHYDULDEOHVXVHGE\\RXU
VNHWFK LQFOXGLQJYDULDEOHVLQWKHOLEUDULHVXVHGE\\RXUVNHWFK 5$0LVYRODWLOHZKLFK
PHDQVLWFDQEHFKDQJHGE\FRGHLQ\RXUVNHWFK,WDOVRPHDQVDQ\WKLQJVWRUHGLQWKLV
PHPRU\LVORVWZKHQSRZHULVVZLWFKHGRII$UGXLQRKDVPXFKOHVV5$0WKDQSURJUDP
PHPRU\,I\RXUXQRXWRI5$0ZKLOH\RXUVNHWFKUXQVRQWKHERDUG DVYDULDEOHVDUH
FUHDWHGDQGGHVWUR\HGZKLOHWKHFRGHUXQV WKHERDUGZLOOPLVEHKDYH FUDVK ((3520 (OHFWULFDOO\(UDVDEOH3URJUDPPDEOH5HDG2QO\0HPRU\ LVPHPRU\WKDW
FRGHUXQQLQJRQ$UGXLQRFDQUHDGDQGZULWHEXWLWLVQRQYRODWLOHPHPRU\WKDWUHWDLQV
YDOXHVHYHQZKHQSRZHULVVZLWFKHGRII((3520DFFHVVLVVLJQLILFDQWO\VORZHUWKDQ
IRU5$0VR((3520LVXVXDOO\XVHGWRVWRUHFRQILJXUDWLRQRURWKHUGDWDWKDWLVUHDG
DWVWDUWXSWRUHVWRUHLQIRUPDWLRQIURPWKHSUHYLRXVVHVVLRQ
7RXQGHUVWDQGWKHVHLVVXHVLWLVKHOSIXOWRXQGHUVWDQGKRZWKH$UGXLQR,'(SUHSDUHV
\RXUFRGHWRJRRQWRWKHFKLSDQGKRZ\RXFDQLQVSHFWWKHUHVXOWVLWSURGXFHV
Preprocessor
6RPHRIWKHUHFLSHVKHUHXVHWKHSUHSURFHVVRUWRDFKLHYHWKHGHVLUHGUHVXOW3UHSURFHVVLQJ
LVDVWHSLQWKHILUVWVWDJHRIWKHEXLOGSURFHVVLQZKLFKWKHVRXUFHFRGH \RXUVNHWFK LV
SUHSDUHGIRUFRPSLOLQJ9DULRXVILQGDQGUHSODFHIXQFWLRQVFDQEHSHUIRUPHG3UHSUR
FHVVRUFRPPDQGVDUHLGHQWLILHGE\OLQHVWKDWVWDUWZLWK#<RXKDYHDOUHDG\VHHQWKHP
LQVNHWFKHVWKDWXVHDOLEUDU\¢#includeWHOOVWKHSUHSURFHVVRUWRLQVHUWWKHFRGHIURP
WKHQDPHGOLEUDU\ILOH6RPHWLPHVWKHSUHSURFHVVRULVWKHRQO\ZD\WRDFKLHYHZKDWLV
QHHGHGEXWLWVV\QWD[LVGLIIHUHQWIURP&DQG&FRGHDQGLWFDQLQWURGXFHEXJVWKDW
DUHVXEWOHDQGKDUGWRWUDFNGRZQVRXVHLWZLWKFDUH
See Also
$95IUHDNVLVDZHEVLWHIRUVRIWZDUHHQJLQHHUVWKDWLVDJRRGVRXUFHIRUWHFKQLFDOGHWDLO
RQWKHFRQWUROOHUFKLSVXVHGE\$UGXLQRKWWSZZZDYUIUHDNVQHW
7HFKQLFDOGHWDLOVRQWKH&SUHSURFHVVRUDUHDYDLODEOHDWKWWSJFFJQXRUJRQOLQHGRFV
JFFFSSBKWPO
17.1 Understanding the Arduino Build Process
Problem
<RXZDQWWRVHHZKDWLVKDSSHQLQJXQGHUWKHFRYHUVZKHQ\RXFRPSLOHDQGXSORDGD
VNHWFK
532 | Chapter 17:ಗAdvanced Coding and Memory Handling
Solution
7RVHHDOOWKHFRPPDQGOLQHDFWLYLW\WKDWWDNHVSODFHKROGGRZQWKH6KLIWNH\ZKHQ
\RXFOLFNRQ&RPSLOHRU8SORDG7KHFRQVROHDUHDDWWKHERWWRPRIWKH,'(ZLOOGLVSOD\
GHWDLOVRIWKHFRPSLOHSURFHVV
7R KDYH WKLV GHWDLO DOZD\V YLVLEOH \RX FDQ FKDQJH D YDOXH LQ WKH $UGXLQR SUHIHUHQ
FHVW[WILOH7KLVILOHVKRXOGEHLQWKHIROORZLQJORFDWLRQV
0DF
8VHUV86(51$0(!/LEUDU\$UGXLQRSUHIHUHQFHVW[W
:LQGRZV;3
&?'RFXPHQWV DQG 6HWWLQJV?86(51$0(!?$SSOLFDWLRQ 'DWD?$UGXLQR?SUHIHUHQ
FHVW[W
:LQGRZV9LVWD
F?8VHUV?86(51$0(!?$SS'DWD?5RDPLQJ?$UGXLQR?SUHIHUHQFHVW[W
/LQX[
aDUGXLQRSUHIHUHQFHVW[W
0DNHVXUHWKH$UGXLQR,'(LVQRWUXQQLQJ FKDQJHVPDGHWRSUHIHUHQFHVW[WZLOOQRWEH
VDYHGLIWKH,'(LVUXQQLQJ 2SHQWKHILOHDQGILQGWKHOLQHbuild.verbose=false LWLV
QHDUWKHERWWRPRIWKHILOH &KDQJHfalseWRtrueDQGVDYHWKHILOH
Discussion
:KHQ\RXFOLFNRQ&RPSLOHRU8SORDGDORWRIDFWLYLW\KDSSHQVWKDWLVQRWXVXDOO\
GLVSOD\HGRQVFUHHQ7KHFRPPDQGOLQHWRROVWKDWWKH$UGXLQR,'(ZDVEXLOWWRKLGH
DUHXVHGWRFRPSLOHOLQNDQGXSORDG\RXUFRGHWRWKHERDUG
)LUVW \RXU VNHWFK ILOH V DUH WUDQVIRUPHG LQWR D ILOH VXLWDEOH IRU WKH FRPSLOHU $95
*&& WRSURFHVV$OOVRXUFHILOHVLQWKHVNHWFKIROGHUWKDWKDYHQRILOHH[WHQVLRQDUH
MRLQHGWRJHWKHUWRPDNHRQHILOH$OOILOHVWKDWHQGLQFRUFSSDUHFRPSLOHGVHSDUDWHO\
+HDGHUILOHV ZLWKDQKH[WHQVLRQ DUHLJQRUHGXQOHVVWKH\DUHH[SOLFLWO\LQFOXGHGLQWKH
ILOHVWKDWDUHEHLQJMRLQHG
#include "WProgram.h"LVDGGHGDWWKHWRSRIWKHILOHWRLQFOXGHWKHKHDGHUILOHZLWKDOO
WKH$UGXLQRVSHFLILFFRGHGHILQLWLRQVVXFKDVdigitalWrite()DQGanalogRead(),I\RX
ZDQWWRH[DPLQHLWVFRQWHQWV\RXFDQILQGWKHILOHRQ:LQGRZVXQGHUWKHGLUHFWRU\
ZKHUH $UGXLQR ZDV LQVWDOOHG IURP WKHUH \RX FDQ QDYLJDWH WR
+DUGZDUH→$UGXLQR→&RUHVൺ$UGXLQR
2QWKH0DF&WUOFOLFNWKH$UGXLQRDSSOLFDWLRQLFRQDQGVHOHFW6KRZ3DFNDJH&RQWHQWV
IURP WKH GURSGRZQ PHQX $ IROGHU ZLOO RSHQ IURP WKH IROGHU QDYLJDWH WR &RQ
WHQWVൺ5HVRXUFHVൺ-DYDൺ+DUGZDUHൺ$UGXLQRൺ&RUHVൺ$UGXLQR
17.1 Understanding the Arduino Build Process | 533
7KH$UGXLQRGLUHFWRU\VWUXFWXUHPD\FKDQJHLQQHZUHOHDVHVVRFKHFN
WKHGRFXPHQWDWLRQIRUWKHUHOHDVH\RXDUHXVLQJ
7RPDNHWKHFRGHYDOLG&WKHSURWRW\SHVRIDQ\IXQFWLRQVGHFODUHGLQ\RXUFRGHDUH
JHQHUDWHGQH[WDQGLQVHUWHG
)LQDOO\ WKH VHWWLQJ RI WKH ERDUG PHQX LV XVHG WR LQVHUW YDOXHV REWDLQHG IURP WKH
ERDUGVW[WILOH WKDWGHILQHYDULRXVFRQVWDQWVXVHGIRUWKHFRQWUROOHUFKLSVRQWKHVHOHFWHG
ERDUG
7KLVILOHLVWKHQFRPSLOHGE\$95*&&ZKLFKLVLQFOXGHGZLWKLQWKH$UGXLQRPDLQ
GRZQORDG LWLVLQWKHWRROVIROGHU 7KHFRPSLOHUSURGXFHVDQXPEHURIREMHFWILOHV ILOHVZLWKDQH[WHQVLRQRIRWKDWZLOO
EHFRPELQHGE\WKHOLQNWRRO 7KHVHILOHVDUHVWRUHGLQWPSRQ0DFDQG/LQX[2Q
:LQGRZVWKH\DUHLQWKHDSSOHWGLUHFWRU\ DIROGHUEHORZWKH$UGXLQRLQVWDOOGLUHFWRU\ 7KHREMHFWILOHVDUHWKHQOLQNHGWRJHWKHUWRPDNHD+(;ILOHWRXSORDGWRWKHERDUG
$YUGXGHDXWLOLW\IRUWUDQVIHUULQJILOHVWRWKH$UGXLQRFRQWUROOHULVXVHGWRXSORDGWR
WKHERDUG
7KH WRROV XVHG WR LPSOHPHQW WKH EXLOG SURFHVV FDQ EH IRXQG LQ WKH KDUGZDUH?WRROV
GLUHFWRU\
$QRWKHU XVHIXO WRRO IRU H[SHULHQFHG SURJUDPPHUV LV DYUREMGXPS DOVR LQ WKH WRROV
IROGHU,WOHWV\RXVHHKRZWKHFRPSLOHUWXUQVWKHVNHWFKLQWRFRGHWKDWWKHFRQWUROOHU
FKLSUXQV7KLVWRROSURGXFHVDGLVDVVHPEO\OLVWLQJRI\RXUVNHWFKZKLFKVKRZVWKH
REMHFWFRGHLQWHUPL[HGZLWKWKHVRXUFHFRGH,WFDQDOVRGLVSOD\DPHPRU\PDSRIDOO
WKHYDULDEOHVXVHGLQ\RXUVNHWFK7RXVHWKHWRROFRPSLOHWKHVNHWFKDQGQDYLJDWHWR
WKHIROGHUFRQWDLQLQJWKH$UGXLQRGLVWULEXWLRQ7KHQQDYLJDWHWRWKHIROGHUZLWKDOOWKH
LQWHUPHGLDWH ILOHV XVHG LQ WKH EXLOG SURFHVV DV H[SODLQHG HDUOLHU 7KH ILOH XVHG E\
DYUREMGXPSLVWKHRQHZLWKWKHH[WHQVLRQHOI)RUH[DPSOHLI\RXFRPSLOHWKH%OLQN
VNHWFK\RXFRXOGYLHZWKHFRPSLOHGRXWSXW WKHPDFKLQHFRGH E\H[HFXWLQJWKHIRO
ORZLQJRQWKHFRPPDQGOLQH
..\hardware\tools\avr\bin\avr-objdump.exe -S blink.cpp.elf
,WLVFRQYHQLHQWWRGLUHFWWKHRXWSXWWRDILOHWKDWFDQEHUHDGLQDWH[WHGLWRU<RXFDQ
GRWKLVDVIROORZV
..\hardware\tools\avr\bin\avr-objdump.exe -S blink.cpp.elf > blink.txt
7KLVYHUVLRQDGGVDOLVWRIVHFWLRQKHDGHUV KHOSIXOIRUGHWHUPLQLQJPHPRU\XVDJH ..\hardware\tools\avr\bin\avr-objdump.exe -S -h blink.cpp.elf > blink.txt
534 | Chapter 17:ಗAdvanced Coding and Memory Handling
<RXFDQFUHDWHDEDWFKILOHWRGXPSWKHOLVWLQJLQWRDILOH$GGWKHSDWK
RI\RXU$UGXLQRLQVWDOODWLRQWRWKHIROORZLQJOLQHDQGVDYHLWWRDEDWFK
ILOH
KDUGZDUH?WRROV?DYU?ELQ?DYUREMGXPSH[H6K7GDWD!W[W
See Also
)RULQIRUPDWLRQRQWKH$UGXLQREXLOGSURFHVVVHHKWWSFRGHJRRJOHFRPSDUGXLQR
ZLNL%XLOG3URFHVV
7KH$95IUHDNVZHEVLWHKWWSZZZDYUIUHDNVQHWZLNLLQGH[SKS'RFXPHQWDWLRQ$95
B*&&
17.2 Determining the Amount of Free and Used RAM
Problem
<RXZDQWWREHVXUH\RXKDYHQRWUXQRXWRI5$0$VNHWFKZLOOQRWUXQFRUUHFWO\LI
WKHUHLVLQVXIILFLHQWPHPRU\DQGWKLVFDQEHGLIILFXOWWRGHWHFW
Solution
7KLVUHFLSHVKRZV\RXKRZ\RXFDQGHWHUPLQHWKHDPRXQWRIIUHHPHPRU\DYDLODEOHWR
\RXUVNHWFK7KLVVNHWFKFRQWDLQVDIXQFWLRQFDOOHGmemoryFreeWKDWUHSRUWVWKHDPRXQW
RIDYDLODEOH5$0
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.print(memoryFree());
Serial.print(' ');
delay(1000);
}
// print the free memory
// print a space
// variables created by the build process when compiling the sketch
extern int __bss_end;
extern void *__brkval;
// function to return the amount of free RAM
int memoryFree()
{
int freeValue;
17.2 Determining the Amount of Free and Used RAM | 535
if((int)__brkval == 0)
freeValue = ((int)&freeValue) - ((int)&__bss_end);
else
freeValue = ((int)&freeValue) - ((int)__brkval);
}
return freeValue;
Discussion
7KHmemoryFreeIXQFWLRQXVHVV\VWHPYDULDEOHVWRFDOFXODWHWKHDPRXQWRI5$06\VWHP
YDULDEOHVDUHQRWQRUPDOO\YLVLEOH WKH\DUHFUHDWHGE\WKHFRPSLOHUWRPDQDJHLQWHUQDO
UHVRXUFHV ,WLVQRWQHFHVVDU\WRXQGHUVWDQGKRZWKHIXQFWLRQZRUNVWRXVHLWVRXWSXW
7KHIXQFWLRQUHWXUQVWKHQXPEHURIE\WHVRIIUHHPHPRU\
7KHQXPEHURIE\WHV\RXUFRGHXVHVFKDQJHVDVWKHFRGHUXQV7KHLPSRUWDQWWKLQJLV
WRHQVXUHWKDW\RXGRQ¦WFRQVXPHPRUHPHPRU\WKDQ\RXKDYH
+HUHDUHWKHPDLQZD\V5$0PHPRU\LVFRQVXPHG
:KHQ\RXLQLWLDOL]HFRQVWDQWV
#define ERROR_MESSAGE "an error has occurred"
:KHQ\RXGHFODUHJOREDOYDULDEOHV
char myMessage[] = "Hello World";
:KHQ\RXPDNHDIXQFWLRQFDOO
void myFunction(int value)
{
int result;
result = value * 2;
return result;
}
:KHQ\RXG\QDPLFDOO\DOORFDWHPHPRU\
String stringOne = "Arduino String";
7KH$UGXLQRStringFODVVXVHVG\QDPLFPHPRU\WRDOORFDWHVSDFHIRUVWULQJV<RXFDQ
VHHWKLVE\DGGLQJWKHIROORZLQJOLQHWRWKHYHU\WRSRIWKHFRGHLQWKH6ROXWLRQ
String s = "\n";
DQGWKHIROORZLQJOLQHVMXVWEHIRUHWKHdelayLQWKHloopFRGH
s = s + "Hello I am Arduino \n";
Serial.println(s);
// print the string value
<RXZLOOVHHWKHPHPRU\YDOXHUHGXFHDVWKHVL]HRIWKHVWULQJLVLQFUHDVHGHDFKWLPH
WKURXJKWKHloop,I\RXUXQWKHVNHWFKORQJHQRXJKWKHPHPRU\ZLOOUXQRXW¢GRQ¦W
HQGOHVVO\WU\WRLQFUHDVHWKHVL]HRIDVWULQJLQDQ\WKLQJRWKHUWKDQDWHVWDSSOLFDWLRQ
:ULWLQJFRGHOLNHWKLVWKDWFUHDWHVDFRQVWDQWO\H[SDQGLQJYDOXHLVDVXUHZD\WRUXQ
RXWRIPHPRU\<RXVKRXOGDOVREHFDUHIXOQRWWRFUHDWHFRGHWKDWG\QDPLFDOO\FUHDWHV
536 | Chapter 17:ಗAdvanced Coding and Memory Handling
GLIIHUHQWQXPEHUVRIYDULDEOHVEDVHGRQVRPHSDUDPHWHUZKLOHWKHFRGHUXQVDVLWZLOO
EHYHU\GLIILFXOWWREHVXUH\RXZLOOQRWH[FHHGWKHPHPRU\FDSDELOLWLHVRIWKHERDUG
ZKHQWKHFRGHUXQV
&RQVWDQWVDQGJOREDOYDULDEOHVDUHRIWHQGHFODUHGLQOLEUDULHVDVZHOOVR\RXPD\QRW
EHDZDUHRIWKHPEXWWKH\VWLOOXVHXS5$07KH6HULDOOLEUDU\IRUH[DPSOHKDVD
E\WHJOREDODUUD\WKDWLWXVHVIRULQFRPLQJVHULDOGDWD7KLVDORQHFRQVXPHVRQHHLJKWK
RIWKHWRWDOPHPRU\RIDQROG$UGXLQRFKLS
See Also
$ WHFKQLFDO RYHUYLHZ RI PHPRU\ XVDJH LV DYDLODEOH DW KWWSZZZJQXRUJVDYDQQDK
FKHFNRXWVQRQJQXDYUOLEFXVHUPDQXDOPDOORFKWPO
17.3 Storing and Retrieving Numeric Values in
Program Memory
Problem
<RXKDYHDORWRIFRQVWDQWQXPHULFGDWDDQGGRQ¦WZDQWWRDOORFDWHWKLVWR5$0
Solution
6WRUHQXPHULFYDULDEOHVLQSURJUDPPHPRU\ WKHIODVKPHPRU\XVHGWRVWRUH$UGXLQR
SURJUDPV 7KLVVNHWFKDGMXVWVDIDGLQJ/('IRUWKHQRQOLQHDUVHQVLWLYLW\RIKXPDQYLVLRQ,WVWRUHV
WKHYDOXHVWRXVHLQDWDEOHRIYDOXHVLQSURJUDPPHPRU\UDWKHUWKDQ5$0
7KHVNHWFKLVEDVHGRQ5HFLSHVHH&KDSWHUIRUDZLULQJGLDJUDPDQGGLVFXVVLRQ
RQGULYLQJ/('V5XQQLQJWKLVVNHWFKUHVXOWVLQDVPRRWKFKDQJHLQEULJKWQHVVZLWKWKH
/('RQSLQFRPSDUHGWRWKH/('RQSLQ
/* ProgmemCurve sketch
* uses table in Progmem to convert linear to exponential output
* See Recipe 7.2 and Figure 7-2
*/
#include <avr/pgmspace.h>
// needed for PROGMEM
// table of exponential values
// generated for values of i from 0 to 255 -> x=round( pow( 2.0, i/32.0) - 1);
const byte table[]PROGMEM = {
0,
0,
0,
0,
0, 0,
0,
0,
0,
1,
1, 1,
1,
1,
1,
1,
1, 1,
2,
2,
2,
2,
2, 2,
3,
3,
3,
3,
3, 3,
0,
1,
1,
2,
4,
0,
1,
1,
2,
4,
0,
1,
1,
2,
4,
0,
1,
1,
2,
4,
0,
1,
1,
3,
4,
0,
1,
2,
3,
4,
0,
1,
2,
3,
4,
0,
1,
2,
3,
4,
0,
1,
2,
3,
4,
0,
1,
2,
3,
5,
17.3 Storing and Retrieving Numeric Values in Program Memory | 537
5,
5,
5,
5,
5, 5,
5,
6, 6,
6,
6,
6,
6,
6,
7,
7,
7,
7,
7,
8,
8, 8,
8,
8, 9,
9,
9,
9,
9, 10, 10, 10,
10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15,
15, 15, 16, 16, 16, 17, 17, 18, 18, 18, 19, 19, 20, 20, 21, 21,
22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 28, 28, 29, 30, 30,
31, 32, 32, 33, 34, 35, 35, 36, 37, 38, 39, 40, 40, 41, 42, 43,
44, 45, 46, 47, 48, 49, 51, 52, 53, 54, 55, 56, 58, 59, 60, 62,
63, 64, 66, 67, 69, 70, 72, 73, 75, 77, 78, 80, 82, 84, 86, 88,
90, 91, 94, 96, 98, 100, 102, 104, 107, 109, 111, 114, 116, 119, 122, 124,
127, 130, 133, 136, 139, 142, 145, 148, 151, 155, 158, 161, 165, 169, 172, 176,
180, 184, 188, 192, 196, 201, 205, 210, 214, 219, 224, 229, 234, 239, 244, 250
};
const int rawLedPin = 3;
const int adjustedLedPin = 5;
// this LED is fed with raw values
// this LED is driven from table
int brightness = 0;
int increment = 1;
void setup()
{
// pins driven by analogWrite do not need to be declared as outputs
}
void loop()
{
if(brightness > 255)
{
increment = -1; // count down after reaching 255
}
else if(brightness < 1)
{
increment = 1; // count up after dropping back down to 0
}
brightness = brightness + increment; // increment (or decrement sign is minus)
// write the brightness value to the LEDs
analogWrite(rawLedPin, brightness); // this is the raw value
int adjustedBrightness = pgm_read_byte(&table[brightness]); // adjusted value
analogWrite(adjustedLedPin, adjustedBrightness);
}
delay(10); // 10ms for each step change means 2.55 secs to fade up or down
Discussion
:KHQ\RXQHHGWRXVHDFRPSOH[H[SUHVVLRQWRFDOFXODWHDUDQJHRIYDOXHVWKDWUHJXODUO\
UHSHDWLWLVRIWHQEHWWHUWRSUHFDOFXODWHWKHYDOXHVDQGLQFOXGHWKHPLQDWDEOHRIYDOXHV
XVXDOO\DVDQDUUD\ LQWKHFRGH7KLVVDYHVWKHWLPHQHHGHGWRFDOFXODWHWKHYDOXHV
UHSHDWHGO\ZKHQWKHFRGHUXQV7KHGLVDGYDQWDJHFRQFHUQVWKHPHPRU\QHHGHGWRSODFH
WKHVHYDOXHVLQ5$05$0LVOLPLWHGRQ$UGXLQRDQGWKHPXFKODUJHUSURJUDPPHPRU\
VSDFHFDQEHXVHGWRVWRUHFRQVWDQWYDOXHV7KLVLVSDUWLFXODUO\KHOSIXOIRUVNHWFKHVWKDW
KDYHODUJHDUUD\VRIQXPEHUV
538 | Chapter 17:ಗAdvanced Coding and Memory Handling
$WWKHWRSRIWKHVNHWFKWKHWDEOHLVGHILQHGZLWKWKHIROORZLQJH[SUHVVLRQ
const byte table[]PROGMEM = {
0, . . .
PROGMEMWHOOVWKHFRPSLOHUWKDWWKHYDOXHVDUHWREHVWRUHGLQSURJUDPPHPRU\UDWKHU
WKDQ5$07KHUHPDLQGHURIWKHH[SUHVVLRQLVVLPLODUWRGHILQLQJDFRQYHQWLRQDODUUD\
VHH&KDSWHU 7KH ORZOHYHO GHILQLWLRQV QHHGHG WR XVH PROGMEM DUH FRQWDLQHG LQ D ILOH QDPHG
SJPVSDFHKDQGWKHVNHWFKLQFOXGHVWKLVDVIROORZV
#include <avr/pgmspace.h>
7RDGMXVWWKHEULJKWQHVVWRPDNHWKHIDGHORRNXQLIRUPWKLVUHFLSHDGGVWKHIROORZLQJ
OLQHVWRWKH/('RXWSXWFRGHXVHGLQ5HFLSH
int adjustedBrightness = pgm_read_byte(&table[brightness]);
analogWrite(adjustedLedPin, adjustedBrightness);
7KHYDULDEOH adjustedBrightnessLVVHWIURPDYDOXHUHDGIURPSURJUDPPHPRU\7KH
H[SUHVVLRQ pgm_read_byte(&table[brightness]); PHDQV WR UHWXUQ WKH DGGUHVV RI WKH
HQWU\LQWKH tableDUUD\DWWKHLQGH[SRVLWLRQJLYHQE\ brightness(DFKHQWU\LQWKH
WDEOHLVRQHE\WHVRDQRWKHUZD\WRZULWHWKLVH[SUHVVLRQLV
pgm_read_byte(table + brightness);
,ILWLVQRWFOHDUZK\ &table[brightness]LVHTXLYDOHQWWR table + brightnessGRQ¦W
ZRUU\XVHZKLFKHYHUH[SUHVVLRQPDNHVPRUHVHQVHWR\RX
$QRWKHU H[DPSOH LV IURP 5HFLSH ZKLFK XVHG D WDEOH IRU FRQYHUWLQJ DQ LQIUDUHG
VHQVRUUHDGLQJLQWRGLVWDQFH+HUHLVWKHVNHWFKIURPWKDWUHFLSHFRQYHUWHGWRXVHDWDEOH
LQSURJUDPPHPRU\LQVWHDGRI5$0
/* ir-distance_Progmem sketch
* prints distance & changes LED flash rate depending on distance from IR sensor
* uses progmem for table
*/
#include <avr/pgmspace.h> // needed when using Progmem
// table entries are distances in steps of 250 millivolts
const int TABLE_ENTRIES = 12;
const int firstElement = 250; // first entry is 250 mV
const int interval = 250; // millivolts between each element
// the following is the definition of the table in Program Memory
const int distanceP[TABLE_ENTRIES] PROGMEM = { 150,140,130,100,60,50,
40,35,30,25,20,15 };
// This function reads from Program Memory at the given index
int getTableEntry(int index)
{
int value = pgm_read_word(&distanceP[index]);
return value;
}
17.3 Storing and Retrieving Numeric Values in Program Memory | 539
7KHUHPDLQLQJFRGHLVVLPLODUWR5HFLSHH[FHSWWKDWWKHgetTableEntryIXQFWLRQLV
XVHGWRJHWWKHYDOXHIURPSURJUDPPHPRU\LQVWHDGRIDFFHVVLQJDWDEOHLQ5$0+HUH
LVWKHUHYLVHGgetDistanceIXQFWLRQIURPWKDWUHFLSH
int getDistance(int mV)
{
if( mV > interval * TABLE_ENTRIES )
return getTableEntry(TABLE_ENTRIES-1); // the minimum distance
else
{
int index = mV / interval;
float frac = (mV % 250) / (float)interval;
return getTableEntry(index) - ((getTableEntry(index) getTableEntry(index+1)) * frac);
}
}
17.4 Storing and Retrieving Strings in Program Memory
Problem
<RXKDYHORWVRIVWULQJVDQGWKH\DUHFRQVXPLQJWRRPXFK5$0<RXZDQWWRPRYH
VWULQJFRQVWDQWVVXFKDVPHQXSURPSWVRUGHEXJJLQJVWDWHPHQWVRXWRI5$0DQGLQWR
SURJUDPPHPRU\
Solution
7KLVVNHWFKFUHDWHVDVWULQJLQSURJUDPPHPRU\DQGSULQWVLWVYDOXHWRWKH6HULDO0RQ
LWRU7KHDPRXQWRIIUHH5$0LVSULQWHGXVLQJWKHIXQFWLRQGHVFULEHGLQ5HFLSH
#include <avr/pgmspace.h> // for progmem
//create a string of 20 characters in progmem
const prog_uchar myText[] = "arduino duemilanove ";
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.print(memoryFree());
Serial.print(' ');
printP(myText);
delay(1000);
// print the free memory
// print a space
// print the string
}
// function to print a PROGMEM string
void printP(const prog_uchar *str)
540 | Chapter 17:ಗAdvanced Coding and Memory Handling
{
char c;
}
while((c = pgm_read_byte(str++)))
Serial.print(c,BYTE);
// variables created by the build process when compiling the sketch
extern int __bss_end;
extern void *__brkval;
// function to return the amount of free RAM
int memoryFree()
{
int freeValue;
if((int)__brkval == 0)
freeValue = ((int)&freeValue) - ((int)&__bss_end);
else
freeValue = ((int)&freeValue) - ((int)__brkval);
}
return freeValue;
Discussion
6WULQJVDUHSDUWLFXODUO\KXQJU\ZKHQLWFRPHVWR5$0(DFKFKDUDFWHUXVHVDE\WHVR
LWLVHDV\WRFRQVXPHODUJHFKXQNVRI5$0LI\RXKDYHORWVRIZRUGVLQVWULQJVLQ\RXU
VNHWFK
7KH#includeDWWKHWRSLVUHTXLUHGIRUWKHFRGHQHHGHGWRDFFHVVSURJUDPPHPRU\
#include <avr/pgmspace.h> // for progmem
3URJUDPPHPRU\VWULQJGHFODUDWLRQVEHJLQZLWKconst prog_ucharIROORZHGE\WKHQDPH
RIWKHVWULQJYDULDEOHDQGWKHQWKHVWULQJFKDUDFWHUV
const prog_uchar myText[] = "arduino duemilanove "; //a string of 20 characters
in progmem
<RXFDQXVHWKHIROORZLQJH[SUHVVLRQWRFUHDWHDSUHSURFHVVRUPDFURWKDWPDNHV\RXU
VWULQJGHFODUDWLRQVHDVLHUWRZULWH$GGWKHIROORZLQJOLQHWRWKHWRSRIWKHVNHWFK
#define P(name)
const prog_uchar name[] PROGMEM
// declare a PROGMEM string
:KHUHYHU\RXXVHP(name)WKHH[SUHVVLRQZLOOEHUHSODFHGZLWKWKHIXOOH[SDQVLRQ6R
WKHIROORZLQJFRGHZRXOGGHFODUHWKHVDPHVWULQJDVLQWKHHDUOLHUVNHWFK
P(myTextP) = "arduino duemilanove "; //a string of 20 characters in progmem
7KLVXVHVDSUHSURFHVVLQJPDFURDVXEMHFWQRWFRYHUHGLQWKLVERRNEXW\RXFDQILQG
OLQNVWRPRUHLQIRUPDWLRQRQWKHSUHSURFHVVRULQWKLVFKDSWHU¦VLQWURGXFWLRQVHFWLRQ
17.4 Storing and Retrieving Strings in Program Memory | 541
,I\RXFKDQJHWKHVNHWFKWRXVHDFRQYHQWLRQDO5$0VWULQJ\RXZLOOVHHWKDWWKHIUHH
5$0LQFUHDVHVE\DWOHDVWE\WHV
char myText[] = "arduino duemilanove "; //a string of 20 characters
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.print(memoryFree());
Serial.print(' ');
Serial.print(myText);
delay(1000);
// print the free memory
// print a space
// print the string
}
17.5 Using #define and const Instead of Integers
Problem
<RXZDQWWRPLQLPL]H5$0XVDJHE\WHOOLQJWKHFRPSLOHUWKDWWKHYDOXHLVFRQVWDQWDQG
FDQEHRSWLPL]HG
Solution
8VHconstWRGHFODUHYDOXHVWKDWDUHFRQVWDQWWKURXJKRXWWKHVNHWFK
)RUH[DPSOHLQVWHDGRI
int ledPin=13;
XVH
const int ledPin=13;
Discussion
:HRIWHQZDQWWRXVHDFRQVWDQWYDOXHLQGLIIHUHQWDUHDVRIFRGH-XVWZULWLQJWKHQXPEHU
LVDUHDOO\EDGLGHD,I\RXODWHUZDQWWRFKDQJHWKHYDOXHXVHGLW¦VGLIILFXOWWRZRUNRXW
ZKLFKQXPEHUVVFDWWHUHGWKURXJKRXWWKHFRGHDOVRQHHGWREHFKDQJHG,WLVEHVWWRXVH
QDPHGUHIHUHQFHV
+HUHDUHWKUHHGLIIHUHQWZD\VWRGHILQHDYDOXHWKDWLVDFRQVWDQW
int ledPin = 13;
const int ledPin =
#define ledPin 13
13;
// a variable, but this wastes RAM
// a const does not use RAM
// using a #define
// the preprocessor replaces ledPin with 13
pinMode(ledPin, OUTPUT);
542 | Chapter 17:ಗAdvanced Coding and Memory Handling
$OWKRXJKWKHILUVWWZRH[SUHVVLRQVORRNVLPLODUWKHWHUP constWHOOVWKHFRPSLOHUQRW
WRWUHDWledPinDVDQRUGLQDU\YDULDEOH8QOLNHWKHRUGLQDU\intQR5$0LVUHVHUYHGWR
KROGWKHYDOXHIRUWKHconstDVLWLVJXDUDQWHHGQRWWRFKDQJH7KHFRPSLOHUZLOOSURGXFH
H[DFWO\WKHVDPHFRGHDVLI\RXKDGZULWWHQ
pinMode(13, OUTPUT);
<RXZLOOVRPHWLPHVVHH #defineXVHGWRGHILQHFRQVWDQWVLQROGHU$UGXLQRFRGHEXW
constLVDEHWWHUFKRLFHWKDQ#define7KLVLVEHFDXVHDconstYDULDEOHKDVDW\SHZKLFK
HQDEOHVWKHFRPSLOHUWRYHULI\DQGUHSRUWLIWKHYDULDEOHLVEHLQJXVHGLQZD\VQRWDS
SURSULDWHIRUWKDWW\SH7KHFRPSLOHUZLOODOVRUHVSHFW&UXOHVIRUWKHVFRSHRIDconst
YDULDEOH$#defineYDOXHZLOODIIHFWDOOWKHFRGHLQWKHVNHWFKZKLFKPD\EHPRUHWKDQ
\RXLQWHQGHG$QRWKHUEHQHILWRIconstLVWKDWLWXVHVIDPLOLDUV\QWD[¢#defineGRHVQRW
XVHWKHHTXDOVVLJQDQGQRVHPLFRORQLVXVHGDWWKHHQG
See Also
6HHWKLVFKDSWHU¦VLQWURGXFWLRQVHFWLRQIRUPRUHRQWKHSUHSURFHVVRU
17.6 Using Conditional Compilations
Problem
<RXZDQWWRKDYHGLIIHUHQWYHUVLRQVRI\RXUFRGHWKDWFDQEHVHOHFWLYHO\FRPSLOHG)RU
H[DPSOH\RXPD\QHHGFRGHWRZRUNGLIIHUHQWO\ZKHQGHEXJJLQJRUZKHQUXQQLQJ
ZLWKGLIIHUHQWERDUGV
Solution
<RXFDQXVHWKHFRQGLWLRQDOVWDWHPHQWVDLPHGDWWKHSUHSURFHVVRUWRFRQWUROKRZ\RXU
VNHWFKLVEXLOW
7KLVH[DPSOHIURPVNHWFKHVLQ&KDSWHULQFOXGHVWKH63,KOLEUDU\ILOHWKDWLVRQO\
DYDLODEOHIRUDQGQHHGHGZLWK$UGXLQRYHUVLRQVUHOHDVHGDIWHU
#if ARDUINO > 18
#include <SPI.h>
#endif
// needed for Arduino versions later than 0018
7KLVH[DPSOHXVLQJWKHVNHWFKIURP5HFLSHGLVSOD\VVRPHGHEXJVWDWHPHQWVRQO\
LIDEBUGLVGHILQHG
/*
Pot_Debug sketch
blink an LED at a rate set by the position of a potentiometer
Uses Serial port for debug if DEBUG is defined
*/
const int potPin = 0;
const int ledPin = 13;
// select the input pin for the potentiometer
// select the pin for the LED
17.6 Using Conditional Compilations | 543
int val = 0;
// variable to store the value coming from the sensor
#define DEBUG
void setup()
{
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
// declare the ledPin as an OUTPUT
void loop() {
val = analogRead(potPin);
digitalWrite(ledPin, HIGH);
delay(val);
digitalWrite(ledPin, LOW);
delay(val);
#if defined DEBUG
Serial.println(val);
#endif
}
// read the voltage on the pot
// turn the ledPin on
// blink rate set by pot value
// turn the ledPin off
// turn LED off for same period as it was turned on
Discussion
7KLVUHFLSHXVHVWKHSUHSURFHVVRUXVHGDWWKHEHJLQQLQJRIWKHFRPSLOHSURFHVVWRFKDQJH
ZKDWFRGHLVFRPSLOHG7KHILUVWH[DPSOHWHVWVLIWKHYDOXHRIWKHFRQVWDQW ARDUINOLV
JUHDWHUWKDQDQGLIVRWKHILOH63,KLVLQFOXGHG7KHYDOXHRIWKH ARDUINOFRQVWDQW
LVGHILQHGLQWKHEXLOGSURFHVVDQGFRUUHVSRQGVWRWKH$UGXLQRUHOHDVHYHUVLRQ7KH
V\QWD[IRUWKLVH[SUHVVLRQLVQRWWKHVDPHDVWKDWXVHGIRUZULWLQJDVNHWFK([SUHVVLRQV
WKDWEHJLQZLWKWKH#V\PERODUHSURFHVVHGEHIRUHWKHFRGHLVFRPSLOHG¢VHHWKLVFKDS
WHU¦VLQWURGXFWLRQVHFWLRQIRUPRUHRQWKHSUHSURFHVVRU
<RXKDYHDOUHDG\FRPHDFURVV#include
#include <library.h>
7KH < > EUDFNHWV WHOO WKH FRPSLOHU WR ORRN IRU WKH ILOH LQ WKH ORFDWLRQ IRU VWDQGDUG
OLEUDULHV
#include "header.h"
7KHFRPSLOHUZLOODOVRORRNLQWKHVNHWFKIROGHU
<RXFDQKDYHDFRQGLWLRQDOFRPSLOHEDVHGRQWKHFRQWUROOHUFKLSVHOHFWHGLQWKH,'(
)RUH[DPSOHWKHIROORZLQJFRGHZLOOSURGXFHGLIIHUHQWFRGHZKHQFRPSLOHGIRUD0HJD
ERDUGWKDWUHDGVWKHDGGLWLRQDODQDORJSLQVWKDWLWKDV
/*
* ConditionalCompile sketch
* This sketch recognizes the controller chip using conditional defines
*/
int numberOfSensors;
int val = 0;
// variable to store the value coming from the sensor
544 | Chapter 17:ಗAdvanced Coding and Memory Handling
Download from Wow! eBook <www.wowebook.com>
void setup()
{
Serial.begin(9600);
#if defined(__AVR_ATmega1280__)
numberOfSensors = 16;
#else
numberOfSensors = 6;
#endif
// defined when selecting Mega in the IDE
// the number of analog inputs on the Mega
// if not Mega then assume a standard board
// analog inputs on a standard Arduino board
Serial.print("The number of sensors is ");
Serial.println(numberOfSensors);
}
void loop() {
for(int sensor = 0; sensor < numberOfSensors; sensor++)
{
val = analogRead(sensor);
// read the sensor value
Serial.println(val);
// display the value
}
Serial.println();
delay(1000);
// delay a second between readings
}
See Also
7HFKQLFDOGHWDLOVRQWKH&SUHSURFHVVRUDUHDYDLODEOHDWKWWSJFFJQXRUJRQOLQHGRFV
JFFFSSBKWPO
17.6 Using Conditional Compilations | 545
CHAPTER 18
Using the Controller Chip Hardware
18.0 Introduction
7KH$UGXLQRSODWIRUPVLPSOLILHVSURJUDPPLQJE\SURYLGLQJHDV\WRXVHIXQFWLRQFDOOV
WRKLGHFRPSOH[ORZOHYHOKDUGZDUHIXQFWLRQV%XWVRPHDSSOLFDWLRQVQHHGWRE\SDVV
WKHIULHQGO\DFFHVVIXQFWLRQVWRJHWGLUHFWO\DWKDUGZDUHHLWKHUEHFDXVHWKDW¦VWKHRQO\
ZD\WRJHWWKHQHHGHGIXQFWLRQDOLW\RUEHFDXVHKLJKHUSHUIRUPDQFHLVUHTXLUHG7KLV
FKDSWHUVKRZVKRZWRDFFHVVDQGXVHKDUGZDUHIXQFWLRQVWKDWDUHQRWIXOO\H[SRVHG
WKURXJKWKHGRFXPHQWHG$UGXLQRODQJXDJH
&KDQJLQJ UHJLVWHU YDOXHV FDQ FKDQJH WKH EHKDYLRU RI VRPH $UGXLQR
IXQFWLRQV HJ millis 7KH ORZOHYHO FDSDELOLWLHV GHVFULEHG LQ WKLV
FKDSWHU UHTXLUH FDUH DWWHQWLRQ DQG WHVWLQJ LI \RX ZDQW \RXU FRGH WR
IXQFWLRQFRUUHFWO\
Registers
5HJLVWHUVDUHYDULDEOHVWKDWUHIHUWRKDUGZDUHPHPRU\ORFDWLRQV7KH\DUHXVHGE\WKH
FKLSWRFRQILJXUHKDUGZDUHIXQFWLRQVRUIRUVWRULQJWKHUHVXOWVRIKDUGZDUHRSHUDWLRQV
7KHFRQWHQWVRIUHJLVWHUVFDQEHUHDGDQGZULWWHQE\\RXUVNHWFK&KDQJLQJUHJLVWHU
YDOXHVZLOOFKDQJHWKHZD\WKHKDUGZDUHRSHUDWHVRUWKHVWDWHRIVRPHWKLQJ VXFKDV
WKHRXWSXWRIDSLQ 6RPHUHJLVWHUVUHSUHVHQWDQXPHULFDOYDOXH WKHQXPEHUDWLPHU
ZLOOFRXQWWR 5HJLVWHUVFDQFRQWURORUUHSRUWRQKDUGZDUHVWDWXVIRUH[DPSOHWKHVWDWH
RIDSLQRULIDQLQWHUUXSWKDVRFFXUUHG5HJLVWHUVDUHUHIHUHQFHGLQFRGHXVLQJWKHLU
QDPHV¢WKHVH DUH GRFXPHQWHG LQ WKH GDWD VKHHW IRU WKH PLFURFRQWUROOHUV 6HWWLQJ D
UHJLVWHUWRDZURQJYDOXHXVXDOO\UHVXOWVLQDVNHWFKIXQFWLRQLQJLQFRUUHFWO\VRFDUHIXOO\
FKHFNWKHGRFXPHQWDWLRQWRHQVXUHWKDW\RXDUHXVLQJUHJLVWHUVFRUUHFWO\
547
Interrupts
,QWHUUXSWVDUHVLJQDOVWKDWHQDEOHWKHFRQWUROOHUFKLSWRVWRSWKHQRUPDOIORZRIDVNHWFK
DQGKDQGOHDWDVNWKDWUHTXLUHVLPPHGLDWHDWWHQWLRQEHIRUHFRQWLQXLQJZLWKZKDWLWZDV
GRLQJ$UGXLQRFRUHVRIWZDUHXVHVLQWHUUXSWVWRKDQGOHLQFRPLQJGDWDIURPWKHVHULDO
SRUW WR PDLQWDLQ WKH WLPH IRU WKH delay DQG millis IXQFWLRQV DQG WR WULJJHU WKH
attachInterruptIXQFWLRQ/LEUDULHVVXFKDV:LUHDQG6HUYRXVHLQWHUUXSWVZKHQDQ
HYHQWRFFXUVVRWKHFRGHGRHVQ¦WKDYHWRFRQVWDQWO\FKHFNWRVHHLIWKHHYHQWKDVKDS
SHQHG7KLVFRQVWDQWFKHFNLQJFDOOHGSROOLQJFDQFRPSOLFDWHWKHORJLFRI\RXUVNHWFK
,QWHUUXSWVFDQEHDUHOLDEOHZD\WRGHWHFWVLJQDOVRIYHU\VKRUWGXUDWLRQ5HFLSH
H[SODLQVKRZWRXVHLQWHUUXSWVWRGHWHUPLQHLIDGLJLWDOSLQKDVFKDQJHGVWDWH
7ZRRUPRUHLQWHUUXSWVPD\RFFXUEHIRUHWKHKDQGOLQJRIWKHILUVWLQWHUUXSWLVFRPSOH
WHGIRUH[DPSOHLIWZRVZLWFKHVDUHSUHVVHGDWWKHVDPHWLPHDQGHDFKJHQHUDWHVD
GLIIHUHQWLQWHUUXSW7KHLQWHUUXSWKDQGOHUIRUWKHILUVWVZLWFKPXVWEHFRPSOHWHGEHIRUH
WKHVHFRQGLQWHUUXSWFDQJHWVWDUWHG,QWHUUXSWVVKRXOGEHEULHIEHFDXVHDQLQWHUUXSW
URXWLQHWKDWWDNHVWRRPXFKWLPHFDQFDXVHRWKHULQWHUUXSWKDQGOHUVWREHGHOD\HGRU
WRPLVVHYHQWV
$UGXLQRVHUYLFHVRQHLQWHUUXSWDWDWLPH,WVXVSHQGVSHQGLQJLQWHUUXSWV
ZKLOHLWGHDOVZLWKDQLQWHUUXSWWKDWKDVKDSSHQHG&RGHWRKDQGOHLQ
WHUUXSWV FDOOHGWKHLQWHUUXSWKDQGOHURULQWHUUXSWVHUYLFHURXWLQH VKRXOG
EH EULHI WR SUHYHQW XQGXH GHOD\V WR SHQGLQJ LQWHUUXSWV $Q LQWHUUXSW
URXWLQHWKDWWDNHVWRRPXFKWLPHFDQFDXVHRWKHULQWHUUXSWKDQGOHUVWR
PLVVHYHQWV$FWLYLWLHVWKDWWDNHDUHODWLYHO\ORQJWLPHVXFKDVEOLQNLQJ
DQ /(' RU HYHQ VHULDO SULQWLQJ VKRXOG EH DYRLGHG LQ DQ LQWHUUXSW
KDQGOHU
Timers
$VWDQGDUG$UGXLQRERDUGKDVWKUHHKDUGZDUHWLPHUVIRUPDQDJLQJWLPHEDVHGWDVNV
WKH0HJDKDVVL[ 7KHWLPHUVDUHXVHGLQDQXPEHURI$UGXLQRIXQFWLRQV
7LPHU
8VHGIRUmillisDQGdelayDOVRanalogWriteRQSLQVDQG
7LPHU
analogWriteIXQFWLRQVRQSLQVDQGDOVRGULYLQJVHUYRVXVLQJWKH6HUYROLEUDU\
7LPHU
analogWriteIXQFWLRQVRQSLQVDQG
7KH6HUYROLEUDU\XVHVWKHVDPHWLPHUDVanalogWriteRQSLQVDQG
VR \RX FDQ¦W XVH analogWrite ZLWK WKHVH SLQV ZKHQ XVLQJ WKH 6HUYR
OLEUDU\
548 | Chapter 18:ಗUsing the Controller Chip Hardware
7KH 0HJD KDV WKUHH DGGLWLRQDO ELW WLPHUV DQG XVHV GLIIHUHQW SLQ QXPEHUV ZLWK
analogWrite
7LPHU
analogWriteIXQFWLRQVRQSLQVDQG
7LPHU
analogWriteIXQFWLRQVRQSLQVDQG
7LPHU
analogWriteIXQFWLRQVRQSLQVDQG
7LPHU
analogWriteIXQFWLRQVRQSLQVDQG
7LPHU
analogWriteIXQFWLRQVRQSLQVDQG
7LPHU
analogWriteIXQFWLRQVRQSLQVDQG
7LPHUVDUHFRXQWHUVWKDWFRXQWSXOVHVIURPDWLPHVRXUFHFDOOHGDWLPHEDVH7KHWLPHU
KDUGZDUHFRQVLVWVRIELWRUELWGLJLWDOFRXQWHUVWKDWFDQEHSURJUDPPHGWRGHWHU
PLQHWKHPRGHWKHWLPHUXVHVWRFRXQW7KHPRVWFRPPRQPRGHLVWRFRXQWSXOVHV
IURPWKHWLPHEDVHRQWKH$UGXLQRERDUGXVXDOO\0+]GHULYHGIURPDFU\VWDO
0+]SXOVHVUHSHDWHYHU\QDQRVHFRQGVDQGWKLVLVWRRIDVWIRUPDQ\WLPLQJDSSOL
FDWLRQVVRWKHWLPHEDVHUDWHLVUHGXFHGE\DGLYLGHUFDOOHGDSUHVFDOHU'LYLGLQJWKH
WLPHEDVHE\IRUH[DPSOHLQFUHDVHVWKHGXUDWLRQRIHDFKFRXQWWRKDOIDPLFURVHFRQG
)RUDSSOLFDWLRQVLQZKLFKWKLVLVVWLOOWRRIDVWRWKHUSUHVFDOHYDOXHVFDQEHXVHG VHH
7DEOH 7LPHURSHUDWLRQLVFRQWUROOHGE\YDOXHVKHOGLQUHJLVWHUVWKDWFDQEHUHDGDQGZULWWHQ
E\$UGXLQRFRGH7KHYDOXHVLQWKHVHUHJLVWHUVVHWWKHWLPHUIUHTXHQF\ WKHQXPEHURI
V\VWHPWLPHEDVHSXOVHVEHWZHHQHDFKFRXQW DQGWKHPHWKRGRIFRXQWLQJ XSGRZQ
XSDQGGRZQRUXVLQJDQH[WHUQDOVLJQDO +HUHLVDQRYHUYLHZRIWKHWLPHUUHJLVWHUV QLVWKHWLPHUQXPEHU 7LPHU&RXQWHU&RQWURO5HJLVWHU$ 7&&5Q$
'HWHUPLQHVWKHRSHUDWLQJPRGH
7LPHU&RXQWHU&RQWURO5HJLVWHU% 7&&5Q%
'HWHUPLQHVWKHSUHVFDOHYDOXH
7LPHU&RXQWHU5HJLVWHU 7&17Q
&RQWDLQVWKHWLPHUFRXQW
2XWSXW&RPSDUH5HJLVWHU$ 2&5Q$
,QWHUUXSWFDQEHWULJJHUHGRQWKLVFRXQW
2XWSXW&RPSDUH5HJLVWHU% 2&5Q%
,QWHUUXSWFDQEHWULJJHUHGRQWKLVFRXQW
18.0 Introduction | 549
7LPHU&RXQWHU,QWHUUXSW0DVN5HJLVWHU 7,06.Q
6HWVWKHFRQGLWLRQVIRUWULJJHULQJDQLQWHUUXSW
7LPHU&RXQWHU,QWHUUXSW)ODJ5HJLVWHU 7,)5Q
,QGLFDWHVLIWKHWULJJHUFRQGLWLRQKDVRFFXUUHG
7DEOHLVDQRYHUYLHZRIWKHELWYDOXHVXVHGWRVHWWKHWLPHUSUHFLVLRQ'HWDLOVRI
WKHIXQFWLRQVRIWKHUHJLVWHUVDUHH[SODLQHGLQWKHUHFLSHVZKHUHWKH\DUHXVHG
7DEOH7LPHUSUHVFDOHYDOXHV 0+]FORFN
Prescale factor
CSx2, CSx1, CSx0
Precision
Time to overflow
8-bit timer
16-bit timer
1
B001
62.5 ns
16 µs
4.096 ms
8
B010
500 ns
128 µs
32.768 ms
64
B011
4 µs
1,024 µs
262.144 ms
256
B100
16 µs
4,096 µs
1048.576 ms
1,024
B101
64 µs
16,384 µs
4194.304 ms
B110
External clock, falling edge
B111
External clock, rising edge
$OOWLPHUVDUHLQLWLDOL]HGIRUDSUHVFDOHRI
3UHFLVLRQLQQDQRVHFRQGVLVHTXDOWRWKH&38SHULRG WLPHIRURQH&38F\FOH PXOWLSOLHG
E\WKHSUHVFDOH
Analog and Digital Pins
&KDSWHUGHVFULEHGWKHVWDQGDUG$UGXLQRIXQFWLRQVWRUHDGDQGZULWH WRIURP GLJLWDO
DQGDQDORJSLQV7KLVFKDSWHUH[SODLQVKRZ\RXFDQFRQWUROSLQVIDVWHUWKDQXVLQJWKH
$UGXLQRUHDGDQGZULWHIXQFWLRQVDQGPDNHFKDQJHVWRDQDORJPHWKRGVWRLPSURYH
SHUIRUPDQFH
6RPHRIWKHFRGHLQWKLVFKDSWHULVPRUHGLIILFXOWWRXQGHUVWDQGWKDQWKHRWKHUUHFLSHV
LQWKLVERRNDVLWLVPRYLQJEH\RQG$UGXLQRV\QWD[DQGFORVHUWRWKHXQGHUO\LQJKDUG
ZDUH7KHVHUHFLSHVZRUNGLUHFWO\ZLWKWKHWHUVHO\QDPHGUHJLVWHUVLQWKHFKLSDQGXVH
ELWVKLIWLQJDQGPDVNLQJWRPDQLSXODWHELWVLQWKHP7KHEHQHILWIURPWKLVFRPSOH[LW\
LVHQKDQFHGSHUIRUPDQFHDQGIXQFWLRQDOLW\
See Also
2YHUYLHZ RI KDUGZDUH UHVRXUFHV KWWSFRGHJRRJOHFRPSDUGXLQRZLNL+DUGZDUH5H
VRXUFH0DS
7LPHU DQG7LPHU OLEUDU\KWWSZZZDUGXLQRFFSOD\JURXQG&RGH7LPHU
7XWRULDORQWLPHUVDQG3:0KWWSDUGXLQRFFHQ7XWRULDO6HFUHWV2I$UGXLQR3:0
550 | Chapter 18:ಗUsing the Controller Chip Hardware
7KH $WPHO $7PHJD GDWD VKHHWV KWWSZZZDWPHOFRPG\QUHVRXUFHVSURG
BGRFXPHQWVGRFSGI
$WPHODSSOLFDWLRQQRWHRQKRZWRVHWXSDQGXVHWLPHUVKWWSZZZDWPHOFRPG\Q
UHVRXUFHVSURGBGRFXPHQWV'2&3')
$WKRURXJKVXPPDU\RILQIRUPDWLRQFRYHULQJELWWLPHUVKWWSZZZFVPXQFDaURG
:LQWHUQRWHVWLPHUWLPHUKWPO
'LDJUDPV VKRZLQJ UHJLVWHU VHWWLQJV IRU WLPHU PRGHV KWWSZHEDOIUHGVWDWHHGXZHL
PDQGQPLVFHOODQHRXVDWPHJDBVXEV\VWHPDWPHJDBVXEV\VWHPBLQGH[KWPO
:LNLSHGLDDUWLFOHRQLQWHUUXSWVKWWSHQZLNLSHGLDRUJZLNL,QWHUUXSWV
18.1 Storing Data in Permanent EEPROM Memory
Problem
<RXZDQWWRVWRUHYDOXHVWKDWZLOOEHUHWDLQHGHYHQZKHQSRZHULVVZLWFKHGRII
Solution
8VHWKH((3520OLEUDU\WRUHDGDQGZULWHYDOXHVLQ((3520PHPRU\7KLVVNHWFK
EOLQNVDQ/('XVLQJYDOXHVUHDGIURP((3520DQGDOORZVWKHYDOXHVWREHFKDQJHG
XVLQJWKH6HULDO0RQLWRU
/*
based on Blink without Delay
uses EEPROM to store blink values
*/
#include <EEPROM.h>
// these values are saved in EEPROM
const byte EEPROM_ID = 0x99; // used to identify if valid data in EEPROM
byte ledPin = 13;
// the number of the LED pin
int interval = 1000;
// interval at which to blink (milliseconds)
// variables that do not need to be saved
int ledState = LOW;
// ledState used to set the LED
long previousMillis = 0;
// will store last time LED was updated
//constants used to identify EEPROM addresses
const int ID_ADDR = 0;
// the EEPROM address used to store the ID
const int PIN_ADDR = 1;
// the EEPROM address used to store the pin
const int INTERVAL_ADDR = 2; // the EEPROM address used to store the interval
void setup()
{
Serial.begin(9600);
byte id = EEPROM.read(ID_ADDR); // read the first byte from the EEPROM
if( id == EEPROM_ID)
18.1 Storing Data in Permanent EEPROM Memory | 551
{
// here if the id value read matches the value saved when writing eeprom
Serial.println("Using data from EEPROM");
ledPin = EEPROM.read(PIN_ADDR);
byte hiByte = EEPROM.read(INTERVAL_ADDR);
byte lowByte = EEPROM.read(INTERVAL_ADDR+1);
interval = word(hiByte, lowByte); // see word function in Recipe 3.15
}
else
{
// here if the ID is not found, so write the default data
Serial.println("Writing default data to EEPROM");
EEPROM.write(ID_ADDR,EEPROM_ID); // write the ID to indicate valid data
EEPROM.write(PIN_ADDR, ledPin); // save the pin in eeprom
byte hiByte = highByte(interval);
byte loByte = lowByte(interval);
EEPROM.write(INTERVAL_ADDR, hiByte);
EEPROM.write(INTERVAL_ADDR+1, loByte);
}
Serial.print("Setting pin to ");
Serial.println(ledPin,DEC);
Serial.print("Setting interval to ");
Serial.println(interval);
pinMode(ledPin, OUTPUT);
}
void loop()
{
// this is the same code as the BlinkWithoutDelay example sketch
if (millis() - previousMillis > interval)
{
previousMillis = millis();
// save the last time you blinked the LED
// if the LED is off turn it on and vice versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
digitalWrite(ledPin, ledState);
// set LED using value of ledState
}
processSerial();
}
// function to get duration or pin values from Serial Monitor
// value followed by i is interval, p is pin number
int value = 0;
void processSerial()
{
if( Serial.available())
{
char ch = Serial.read();
if(ch >= '0' && ch <= '9') // is this an ascii digit between 0 and 9?
{
552 | Chapter 18:ಗUsing the Controller Chip Hardware
}
value = (value * 10) + (ch - '0'); // yes, accumulate the value
}
else if (ch == 'i') // is this the interval
{
interval = value;
Serial.print("Setting interval to ");
Serial.println(interval);
byte hiByte = highByte(interval);
byte loByte = lowByte(interval);
EEPROM.write(INTERVAL_ADDR, hiByte);
EEPROM.write(INTERVAL_ADDR+1, loByte);
value = 0; // reset to 0 ready for the next sequence of digits
}
else if (ch == 'p') // is this the pin number
{
ledPin = value;
Serial.print("Setting pin to ");
Serial.println(ledPin,DEC);
pinMode(ledPin, OUTPUT);
EEPROM.write(PIN_ADDR, ledPin); // save the pin in eeprom
value = 0; // reset to 0 ready for the next sequence of digits
}
}
2SHQWKH6HULDO0RQLWRU$VWKHVNHWFKVWDUWVLWWHOOV\RXZKHWKHULWLVXVLQJYDOXHV
SUHYLRXVO\VDYHGWR((3520RUGHIDXOWVLIWKLVLVWKHILUVWWLPHWKHVNHWFKLVVWDUWHG
<RXFDQFKDQJHYDOXHVE\W\SLQJDQXPEHUIROORZHGE\DOHWWHUWRLQGLFDWHWKHDFWLRQ
$QXPEHUIROORZHGE\WKHOHWWHULFKDQJHVWKHEOLQNLQWHUYDODQXPEHUIROORZHGE\D
SFKDQJHVWKHSLQQXPEHUIRUWKH/('
Discussion
$UGXLQRFRQWDLQV((3520PHPRU\WKDWZLOOVWRUHYDOXHVHYHQZKHQSRZHULVVZLWFKHG
RII7KHUHDUHE\WHVRI((3520LQDVWDQGDUG$UGXLQRERDUG.E\WHVLQD0HJD
7KHVNHWFKXVHVWKH((3520OLEUDU\WRUHDGDQGZULWHYDOXHVLQ((3520PHPRU\
2QFHWKHOLEUDU\LVLQFOXGHGLQWKHVNHWFKDQ((3520REMHFWLVDYDLODEOHWKDWDFFHVVHV
WKHPHPRU\7KHOLEUDU\SURYLGHVPHWKRGVWRreadwriteDQGclearEEPROM.clear()
LVQRWXVHGLQWKLVVNHWFKEHFDXVHLWHUDVHVDOOWKH((3520PHPRU\
7KH((3520OLEUDU\UHTXLUHV\RXWRVSHFLI\WKHDGGUHVVLQPHPRU\WKDW\RXZDQWWR
UHDGRUZULWH7KLVPHDQV\RXQHHGWRNHHSWUDFNRIZKHUHHDFKYDOXHLVZULWWHQVRWKDW
ZKHQ\RXDFFHVVWKHYDOXHLWLVIURPWKHFRUUHFWDGGUHVV
7RZULWHDYDOXH\RXXVHEEPROM.write(address, value)7KHDGGUHVVLVIURPWR
RQDVWDQGDUG$UGXLQRERDUG DQGWKHYDOXHLVDVLQJOHE\WH
7RUHDG\RXXVH EEPROM.read(address)7KHE\WHFRQWHQWRIWKDWPHPRU\DGGUHVVLV
UHWXUQHG
18.1 Storing Data in Permanent EEPROM Memory | 553
7KHVNHWFKVWRUHVWKUHHYDOXHVLQ((35207KHILUVWYDOXHVWRUHGLVDQIDYDOXHWKDWLV
XVHGRQO\LQ setupWRLGHQWLI\LIWKH((3520KDVEHHQSUHYLRXVO\ZULWWHQZLWKYDOLG
GDWD,IWKHYDOXHVWRUHGPDWFKHVWKHH[SHFWHGYDOXHWKHRWKHUYDULDEOHVDUHUHDGIURP
((3520DQGXVHGLQWKHVNHWFK,ILWGRHVQ¦WPDWFKWKLVVNHWFKKDVQRWEHHQUXQRQ
WKLVERDUG RWKHUZLVHWKHIDZRXOGKDYHEHHQZULWWHQ VRWKHGHIDXOWYDOXHVDUHZULWWHQ
LQFOXGLQJWKHIDYDOXH
7KHVNHWFKPRQLWRUVWKHVHULDOSRUWDQGQHZYDOXHVUHFHLYHGDUHZULWWHQWR((3520
7KHVNHWFKVWRUHVWKHIDYDOXHLQ((3520DGGUHVVWKHSLQQXPEHULQDGGUHVVDQG
WKHWZRE\WHVIRUWKHLQWHUYDOVWDUWLQDGGUHVV7KHIROORZLQJOLQHZULWHVWKHSLQQXPEHU
WR((35207KHYDULDEOHledPinLVDE\WHVRLWILWVLQWRDVLQJOH((3520DGGUHVV
EEPROM.write(PIN_ADDR, ledPin); // save the pin in eeprom
%HFDXVHLQWHUYDOLVDQintLWUHTXLUHVWZRE\WHVRIPHPRU\WRVWRUHWKHYDOXH
byte hiByte = highByte(interval);
byte loByte = lowByte(interval);
EEPROM.write(INTERVAL_ADDR, hiByte);
EEPROM.write(INTERVAL_ADDR+1, loByte);
7KHSUHFHGLQJFRGHVSOLWVWKHYDOXHLQWRWZRE\WHVWKDWDUHVWRUHGLQWZRFRQVHFXWLYH
DGGUHVVHV$Q\DGGLWLRQDOYDULDEOHVWREHDGGHGWR((3520ZRXOGQHHGWREHSODFHG
LQDGGUHVVHVWKDWIROORZWKHVHWZRE\WHV
+HUHLVWKHFRGHXVHGWRUHEXLOGWKHintYDULDEOHIURP((3520
ledPin = EEPROM.read(PIN_ADDR);
byte hiByte = EEPROM.read(INTERVAL_ADDR);
byte lowByte = EEPROM.read(INTERVAL_ADDR+1);
interval = word(hiByte, lowByte);
6HH&KDSWHUIRUPRUHRQXVLQJWKHwordH[SUHVVLRQWRFUHDWHDQLQWHJHUIURPWZRE\WHV
)RUPRUHFRPSOLFDWHGXVHRI((3520LWLVDGYLVDEOHWRGUDZRXWDPDSRIZKDWLV
EHLQJVDYHGZKHUHWRHQVXUHWKDWQRDGGUHVVLVXVHGE\PRUHWKDQRQHYDOXHDQGWKDW
PXOWLE\WHYDOXHVGRQ¦WRYHUZULWHRWKHULQIRUPDWLRQ
See Also
5HFLSHSURYLGHVPRUHLQIRUPDWLRQRQFRQYHUWLQJDQGELWYDOXHVLQWRE\WHV
18.2 Using Hardware Interrupts
Problem
<RXZDQWWRSHUIRUPVRPHDFWLRQZKHQDGLJLWDOSLQFKDQJHVYDOXHDQG\RXGRQ¦WZDQW
WRKDYHWRFRQVWDQWO\FKHFNWKHSLQVWDWH
554 | Chapter 18:ಗUsing the Controller Chip Hardware
Download from Wow! eBook <www.wowebook.com>
Solution
7KLVVNHWFKPRQLWRUVSXOVHVRQSLQDQGVWRUHVWKHGXUDWLRQLQDQDUUD\:KHQWKH
DUUD\KDVEHHQILOOHG SXOVHVKDYHEHHQUHFHLYHG WKHGXUDWLRQRIHDFKSXOVHLVGLV
SOD\HGRQWKH6HULDO0RQLWRU
/*
Interrupts sketch
see Recipe 10.1 for connection diagram
*/
const int irReceiverPin = 2;
const int numberOfEntries = 64;
//pin the receiver is connected to
volatile unsigned long microseconds;
volatile byte index = 0;
volatile unsigned long results[numberOfEntries];
void setup()
{
pinMode(irReceiverPin, INPUT);
Serial.begin(9600);
attachInterrupt(0, analyze, CHANGE);
results[0]=0;
}
// encoder pin on interrupt 0 (pin 2);
void loop()
{
if(index >= numberOfEntries)
{
Serial.println("Durations in Microseconds are:") ;
for( byte i=0; i < numberOfEntries; i++)
{
Serial.println(results[i]);
}
while(1)
;
}
delay(1000);
}
void analyze()
{
if(index < numberOfEntries )
{
if(index > 0)
{
results[index] = micros() - microseconds;
}
index = index + 1;
}
microseconds = micros();
}
18.2 Using Hardware Interrupts | 555
,I\RXKDYHDQLQIUDUHGUHFHLYHUPRGXOH\RXFDQXVHWKHZLULQJLQ5HFLSHWRPHDV
XUHWKHSXOVHZLGWKIURPDQLQIUDUHGUHPRWHFRQWURO<RXFRXOGDOVRXVHWKHZLULQJLQ
5HFLSHWRPHDVXUHSXOVHVIURPDURWDU\HQFRGHURUFRQQHFWDVZLWFKWRSLQ VHH
5HFLSH WRWHVWZLWKDSXVKEXWWRQ
Discussion
,QsetupWKHattachInterrupt(0, analyze, CHANGE);FDOOHQDEOHVWKHVNHWFKWRKDQGOH
LQWHUUXSWV 7KH ILUVW QXPEHU LQ WKH FDOO VSHFLILHV ZKLFK LQWHUUXSW WR LQLWLDOL]H 2Q D
VWDQGDUG$UGXLQRERDUGWZRLQWHUUXSWVDUHDYDLODEOHQXPEHUZKLFKXVHVSLQDQG
QXPEHURQSLQ7KH0HJDKDVIRXUPRUHQXPEHUZKLFKXVHVSLQQXPEHU
RQSLQQXPEHURQSLQDQGQXPEHURQSLQ
7KHQH[WSDUDPHWHUVSHFLILHVZKDWIXQFWLRQWRFDOO VRPHWLPHVFDOOHGDQLQWHUUXSWKDQ
GOHU ZKHQWKHLQWHUUXSWHYHQWKDSSHQVanalyzeLQWKLVVNHWFK
7KHILQDOSDUDPHWHUVSHFLILHVZKDWVKRXOGWULJJHUWKHLQWHUUXSWCHANGEPHDQVZKHQHYHU
WKHSLQOHYHOFKDQJHV JRHVIURPORZWRKLJKRUKLJKWRORZ 7KHRWKHURSWLRQVDUH
LOWZKHQWKHSLQLVORZ
RISINGZKHQWKHSLQJRHVIURPORZWRKLJK
FALLINGZKHQWKHSLQJRHVIURPKLJKWRORZ
:KHQUHDGLQJFRGHWKDWXVHVLQWHUUXSWVEHDULQPLQGWKDWLWPD\QRWEHREYLRXVZKHQ
YDOXHV LQ WKH VNHWFK FKDQJH EHFDXVH WKH VNHWFK GRHV QRW GLUHFWO\ FDOO WKH LQWHUUXSW
KDQGOHULW¦VFDOOHGZKHQWKHLQWHUUXSWFRQGLWLRQVRFFXU
,QWKLVVNHWFKWKHPDLQloopFKHFNVWKHindexYDULDEOHWRVHHLIDOOWKHHQWULHVKDYHEHHQ
VHW E\ WKH LQWHUUXSW KDQGOHU 1RWKLQJ LQ loop FKDQJHV WKH YDOXH RI index index LV
FKDQJHGLQVLGHWKHanalyzeIXQFWLRQZKHQWKHLQWHUUXSWFRQGLWLRQRFFXUV SLQFKDQJ
LQJVWDWH 7KHindexYDOXHLVXVHGWRVWRUHWKHWLPHVLQFHWKHODVWVWDWHFKDQJHLQWRWKH
QH[WVORWLQWKH resultsDUUD\7KHWLPHLVFDOFXODWHGE\VXEWUDFWLQJWKHODVWWLPHWKH
VWDWHFKDQJHGIURPWKHFXUUHQWWLPHLQPLFURVHFRQGV7KHFXUUHQWWLPHLVWKHQVDYHG
DVWKHODVWWLPHDFKDQJHKDSSHQHG &KDSWHUGHVFULEHVWKLVPHWKRGIRUREWDLQLQJ
HODSVHGWLPHXVLQJWKHmillisIXQFWLRQKHUHmicrosLVXVHGWRJHWHODSVHGPLFURVHFRQGV
LQVWHDGRIPLOOLVHFRQGV
7KHYDULDEOHVWKDWDUHFKDQJHGLQDQLQWHUUXSWIXQFWLRQDUHGHFODUHGDV volatileWKLV
OHWVWKHFRPSLOHUNQRZWKDWWKHYDOXHVFRXOGFKDQJHDWDQ\WLPH E\DQLQWHUUXSWKDQ
GOHU :LWKRXWXVLQJWKHvolatileNH\ZRUGWKHFRPSLOHUZRXOGWKLQNWKHVHYDULDEOHV
DUHQRWEHLQJFKDQJHGE\DQ\FRGHJHWWLQJFDOOHGDQGZRXOGUHSODFHWKHVHYDULDEOHVZLWK
FRQVWDQWYDOXHV
(DFKWLPHDQLQWHUUXSWLVWULJJHUHGindexLVLQFUHPHQWHGDQGWKHFXUUHQWWLPHLVVDYHG
7KHWLPHGLIIHUHQFHLVFDOFXODWHGDQGVDYHGLQWKHDUUD\ H[FHSWIRUWKHILUVWWLPHWKH
LQWHUUXSWLVWULJJHUHGZKHQ indexLV 0 :KHQWKHPD[LPXPQXPEHURIHQWULHVKDV
RFFXUUHGWKHLQQHUEORFNLQloopUXQVDQGLWSULQWVRXWDOOWKHYDOXHVWRWKHVHULDOSRUW
556 | Chapter 18:ಗUsing the Controller Chip Hardware
7KHFRGHVWD\VLQWKHwhileORRSDWWKHHQGRIWKHLQQHUEORFNVR\RXQHHGWRUHVHWWKH
ERDUGZKHQ\RXZDQWWRGRDQRWKHUUXQ
See Also
5HFLSHKDVDQH[DPSOHRIH[WHUQDOLQWHUUXSWVXVHGWRGHWHFWPRYHPHQWLQDURWDU\
HQFRGHU
18.3 Setting Timer Duration
Problem
<RXZDQWWRGRVRPHWKLQJDWSHULRGLFLQWHUYDOVDQG\RXGRQ¦WZDQWWRKDYH\RXUFRGH
FRQVWDQWO\FKHFNLQJLIWKHLQWHUYDOKDVHODSVHG<RXZRXOGOLNHWRKDYHDVLPSOHLQWHUIDFH
IRUVHWWLQJWKHSHULRG
Solution
7KH HDVLHVW ZD\ WR XVH D WLPHU LV WKURXJK D OLEUDU\ 7KH IROORZLQJ VNHWFK XVHV WKH
0V7LPHU OLEUDU\ KWWSZZZDUGXLQRFFSOD\JURXQG0DLQ0V7LPHU WR JHQHUDWH D
SXOVHZLWKDSHULRGWKDWFDQEHVHWXVLQJWKH6HULDO0RQLWRU7KLVVNHWFKIODVKHVSLQ
DWDUDWHWKDWFDQEHVHWXVLQJWKH6HULDO0RQLWRU
/*
pulseTimer2
pulse a pin at a rate set from serial input
*/
#include <MsTimer2.h>
const int pulsePin = 13;
int period = 100; // 10 milliseconds
boolean output = HIGH; // the state of the pulse pin
void setup()
{
pinMode(pulsePin, OUTPUT);
Serial.begin(9600);
MsTimer2::set(period/2, flash);
MsTimer2::start();
}
period= 0; // reset to zero ready for serial input
void loop()
{
if( Serial.available())
{
char ch = Serial.read();
18.3 Setting Timer Duration | 557
if(ch >= '0' && ch <= '9') // is this an ascii digit between 0 and 9?
{
period = (period * 10) + (ch - '0'); // yes, accumulate the value
}
else if (ch == 10) // is the character the newline character
{
Serial.println(period);
MsTimer2::set(period/2, flash);
MsTimer2::start();
period = 0; // reset to 0 ready for the next sequence of digits
}
}
}
void flash()
{
digitalWrite(pulsePin, output);
output = !output; // invert the output
}
Discussion
(QWHUGLJLWVIRUWKHGHVLUHGSHULRGLQPLOOLVHFRQGVXVLQJWKH6HULDO0RQLWRU7KHVNHWFK
DFFXPXODWHVWKHGLJLWVDQGGLYLGHVWKHUHFHLYHGYDOXHE\WRFDOFXODWHWKHGXUDWLRQRI
WKHRQDQGRIIVWDWHV WKHSHULRGLVWKHVXPRIWKHRQWLPHDQGRIIWLPHVRWKHVPDOOHVW
YDOXH\RXFDQXVHLV %HDULQPLQGWKDWDQ/('IODVKLQJYHU\TXLFNO\PD\QRWDSSHDU
WREHIODVKLQJWRWKHKXPDQH\H
7KLVOLEUDU\XVHV7LPHUVRLWZLOOSUHYHQWRSHUDWLRQRIanalogWriteRQ
SLQVDQG
7KLVOLEUDU\HQDEOHV\RXWRXVH7LPHUE\SURYLGLQJWKHWLPLQJLQWHUYDODQGWKHQDPH
RIWKHIXQFWLRQWRFDOOZKHQWKHLQWHUYDOKDVHODSVHG
MsTimer2::set(period/2, flash);
7KLVVHWVXSWKHWLPHU7KHILUVWSDUDPHWHULVWKHWLPHIRUWKHWLPHUWRUXQLQPLOOLVHFRQGV
7KHVHFRQGSDUDPHWHULVWKHIXQFWLRQWRFDOOZKHQWKHWLPHUJHWVWRWKHHQGRIWKDWWLPH
WKHIXQFWLRQLVQDPHGflashLQWKLVUHFLSH MsTimer2::start();
$VWKHQDPHLPSOLHV startVWDUWVWKHWLPHUUXQQLQJ$QRWKHUPHWKRGQDPHG stop
VWRSVWKHWLPHU
$VLQ5HFLSHWKHVNHWFKFRGHGRHVQRWGLUHFWO\FDOOWKHIXQFWLRQWRSHUIRUPWKH
DFWLRQ7KH/('LVWXUQHGRQDQGRIILQWKHflashIXQFWLRQWKDWLVFDOOHGE\0V7LPHU
558 | Chapter 18:ಗUsing the Controller Chip Hardware
HDFKWLPHLWJHWVWRWKHHQGRILWVWLPHVHWWLQJ7KHFRGHLQ loopGHDOVZLWKDQ\VHULDO
PHVVDJHVDQGFKDQJHVWKHWLPHUVHWWLQJVEDVHGRQLW
8VLQJDOLEUDU\WRFRQWUROWLPHUVLVPXFKHDVLHUWKDQDFFHVVLQJWKHUHJLVWHUVGLUHFWO\
+HUHLVDQRYHUYLHZRIWKHLQQHUZRUNLQJVRIWKLVOLEUDU\7LPHUVZRUNE\FRQVWDQWO\
FRXQWLQJWRDYDOXHVLJQDOLQJWKDWWKH\KDYHUHDFKHGWKHYDOXHWKHQVWDUWLQJDJDLQ
(DFKWLPHUKDVDSUHVFDOHUWKDWGHWHUPLQHVWKHFRXQWLQJIUHTXHQF\7KHSUHVFDOHUGLYLGHV
WKHV\VWHPWLPHEDVHE\DIDFWRUVXFKDVRU7KHORZHUWKHSUHVFDOH
IDFWRU WKH KLJKHU WKH FRXQWLQJ IUHTXHQF\ DQG WKH TXLFNHU WKH WLPHEDVH UHDFKHV LWV
PD[LPXPFRXQW7KHFRPELQDWLRQRIKRZIDVWWRFRXQWDQGZKDWYDOXHWRFRXQWWR
JLYHVWKHWLPHIRUWKHWLPHU7LPHULVDQELWWLPHUWKLVPHDQVLWFDQFRXQWXSWR
EHIRUHVWDUWLQJDJDLQIURP]HUR 7LPHUDQG7LPHUVDQGRQWKH0HJDXVH
ELWVDQGFDQFRXQWXSWR
7KH0V7LPHUOLEUDU\XVHVDSUHVFDOHIDFWRURI2QD0+]$UGXLQRERDUGHDFK
&38F\FOHLVQDQRVHFRQGVORQJDQGZKHQWKLVLVGLYLGHGE\WKHSUHVFDOHIDFWRURI
HDFKFRXQWRIWKHWLPHUZLOOEHQDQRVHFRQGV ZKLFKLV
IRXUPLFURVHFRQGV 5HPHPEHUWKDWZKHQ\RXGLUHFWO\XVHDWLPHULQ\RXUVNHWFKEXLOWLQ
IXQFWLRQVWKDWXVHWKDWWLPHUVXFKDVanalogWritePD\QRORQJHUZRUN
FRUUHFWO\
See Also
$QHDV\WRXVHOLEUDU\IRULQWHUIDFLQJZLWK7LPHUKWWSZZZDUGXLQRFFSOD\JURXQG
0DLQ0V7LPHU
$FROOHFWLRQRIURXWLQHVIRULQWHUIDFLQJZLWK7LPHU DOVR7LPHURQWKH0HJD KWWS
ZZZDUGXLQRFFSOD\JURXQG&RGH7LPHU
18.4 Setting Timer Pulse Width and Duration
Problem
<RXZDQW$UGXLQRWRJHQHUDWHSXOVHVZLWKDGXUDWLRQDQGZLGWKWKDW\RXVSHFLI\
Solution
7KLVVNHWFKJHQHUDWHVSXOVHVZLWKLQWKHIUHTXHQF\UDQJHRI0+]WR+]XVLQJ7LPHU
3:0RQSLQ
#include <TimerOne.h>
#define pwmRegister OCR1A
const int
outPin = 9;
// the logical pin, can be set to OCR1B
// the physical pin
18.4 Setting Timer Pulse Width and Duration | 559
long period = 10000;
long pulseWidth = 1000;
// the period in microseconds
// width of a pulse in microseconds
int prescale[] = {0,1,8,64,256,1024}; // the range of prescale values
void setup()
{
Serial.begin(9600);
pinMode(outPin, OUTPUT);
Timer1.initialize(period);
setPulseWidth(pulseWidth);
}
// initialize timer1, 1000 microseconds
void loop()
{
}
bool setPulseWidth(long microseconds)
{
bool ret = false;
}
int prescaleValue = prescale[Timer1.clockSelectBits];
// calculate time per counter tick in nanoseconds
long precision = (F_CPU / 128000) * prescaleValue ;
period = precision * ICR1 / 1000; // period in microseconds
if( microseconds < period)
{
int duty = map(microseconds, 0,period, 0,1024);
if( duty < 1)
duty = 1;
if(microseconds > 0 && duty < RESOLUTION)
{
Timer1.pwm(outPin, duty);
ret = true;
}
}
return ret;
Discussion
<RXVHWWKHSXOVHSHULRGWRDYDOXHIURPWRPLOOLRQPLFURVHFRQGVE\VHWWLQJWKH
YDOXHRIWKHSHULRGDWWKHWRSRIWKHVNHWFK<RXFDQVHWWKHSXOVHZLGWKWRDQ\YDOXHLQ
PLFURVHFRQGVWKDWLVOHVVWKDQWKHSHULRGE\VHWWLQJWKHYDOXHRIpulseWidth
7KHVNHWFKXVHVWKH7LPHUOLEUDU\IURPKWWSZZZDUGXLQRFFSOD\JURXQG&RGH7LP
HU
7LPHULVDELWWLPHU LWFRXQWVIURP]HURWR ,W¦VWKHVDPHWLPHUXVHGE\
analogWriteWRFRQWUROSLQVDQG VR\RXFDQ¦WXVHWKLVOLEUDU\DQGanalogWriteRQ
WKRVHSLQVDWWKHVDPHWLPH 7KHVNHWFKJHQHUDWHVDSXOVHRQSLQZLWKDSHULRGDQG
560 | Chapter 18:ಗUsing the Controller Chip Hardware
SXOVHZLGWKJLYHQE\WKHYDOXHVRIWKHYDULDEOHVQDPHGperiodDQGpulseWidth,I\RX
ZDQWWRXVHSLQLQVWHDGRISLQ\RXFDQPDNHWKHIROORZLQJFKDQJH
#define pwmRegister OCR1B
const int
outPin = 10;
// the logical pin
// the physical pin - OCRIB is pin 10
OCR1ADQGOCR1BDUHFRQVWDQWVWKDWDUHGHILQHGLQWKHFRGHLQFOXGHGE\WKH$UGXLQRFRUH
VRIWZDUH 2&5VWDQGVIRU2XWSXW&RPSDUH5HJLVWHU 0DQ\GLIIHUHQWKDUGZDUHUHJLV
WHUVLQWKH$UGXLQRKDUGZDUHDUHQRWXVXDOO\QHHGHGE\DVNHWFK WKHIULHQGO\$UGXLQR
FRPPDQGVKLGHWKHDFWXDOUHJLVWHUQDPHV %XWZKHQ\RXQHHGWRDFFHVVWKHKDUGZDUH
GLUHFWO\WRJHWDWIXQFWLRQDOLW\QRWSURYLGHGE\$UGXLQRFRPPDQGVWKHVHUHJLVWHUVQHHG
WREHDFFHVVHG)XOOGHWDLOVRQWKHUHJLVWHUVDUHLQWKH$WPHOGDWDVKHHWIRUWKHFKLS
7KHVNHWFKLQWKLVUHFLSH¦V6ROXWLRQXVHVWKHIROORZLQJUHJLVWHUV
ICR1 ,QSXW&RPSDUH5HJLVWHUIRU7LPHU GHWHUPLQHVWKHSHULRGRIWKHSXOVH7KLV
UHJLVWHUFRQWDLQVDELWYDOXHZKLFKLVXVHGDVWKHPD[LPXPFRXQWIRUWKHWLPHU
:KHQWKHWLPHUFRXQWUHDFKHVWKLVYDOXHLWZLOOEHUHVHWDQGVWDUWFRXQWLQJDJDLQIURP
]HUR,QWKHVNHWFKLQWKLVUHFLSH¦V6ROXWLRQLIHDFKFRXQWWDNHVRQHPLFURVHFRQGDQG
WKHICR1YDOXHLVVHWWR1000WKHGXUDWLRQRIHDFKFRXQWF\FOHLVPLFURVHFRQGV
OCR1A RU OCR1B GHSHQGLQJ RQ ZKLFK SLQ \RX ZDQW WR XVH LV WKH 2XWSXW &RPSDUH
5HJLVWHUIRU7LPHU:KHQWKHWLPHUFRXQWUHDFKHVWKLVYDOXH DQGWKHWLPHULVLQ3:0
PRGHDVLWLVKHUH WKHRXWSXWSLQZLOOEHVHWORZ¢WKLVGHWHUPLQHVWKHSXOVHZLGWK
)RUH[DPSOHLIHDFKFRXQWWDNHVRQHPLFURVHFRQGDQGWKHICR1YDOXHLVVHWWR1000DQG
OCR1ALVVHWWR 100WKHRXWSXWSLQZLOOEH HIGHIRUPLFURVHFRQGVDQG LOWIRU
PLFURVHFRQGV WKHWRWDOSHULRGLVPLFURVHFRQGV 7KHGXUDWLRQRIHDFKFRXQWLVGHWHUPLQHGE\WKH$UGXLQRFRQWUROOHUWLPHEDVHIUHTXHQF\
W\SLFDOO\0+] DQGWKHSUHVFDOHYDOXH7KHSUHVFDOHLVWKHYDOXHWKDWWKHWLPHEDVH
LVGLYLGHGE\)RUH[DPSOHZLWKDSUHVFDOHRIWKHWLPHEDVHZLOOEHIRXUPLFURVHF
RQGV
7KH7LPHUOLEUDU\KDVPDQ\XVHIXOFDSDELOLWLHV¢VHHWKH3OD\JURXQGDUWLFOHIRUGHWDLOV
¢EXWLWGRHVQRWSURYLGHIRUWKHVHWWLQJRIDVSHFLILFSXOVHZLGWK7KLVIXQFWLRQDOLW\LV
DGGHGE\WKHIXQFWLRQQDPHGsetPulseWidth
7KLVIXQFWLRQXVHVDYDOXHRIICR1WRGHWHUPLQHWKHSHULRG
int prescaleValue = prescale[Timer1.clockSelectBits];
7KHSUHVFDOHYDOXHLVVHWE\DYDULDEOHLQWKHOLEUDU\QDPHGclockSelectBits7KLVYDU
LDEOHFRQWDLQVDYDOXHEHWZHHQDQG¢WKLVLVXVHGDVDQLQGH[LQWRWKHprescaleDUUD\
WRJHWWKHFXUUHQWSUHVFDOHIDFWRU
7KHGXUDWLRQIRUHDFKFRXQW precision LVFDOFXODWHGE\PXOWLSO\LQJWKHSUHVFDOHYDOXH
E\WKHGXUDWLRQRIDWLPHEDVHF\FOH
long precision = (F_CPU / 128000)
counter tick in ns
* prescaleValue ;
// time per
18.4 Setting Timer Pulse Width and Duration | 561
7KHSHULRGLVWKHSUHFLVLRQWLPHVWKHYDOXHRIWKHICR1UHJLVWHULW¦VGLYLGHGE\WR
JLYHWKHGXUDWLRQLQPLFURVHFRQGV
period = precision * ICR1 / 1000; // period in microseconds
7KH7LPHUOLEUDU\KDVDIXQFWLRQQDPHGpwmWKDWH[SHFWVWKHGXW\F\FOHWREHHQWHUHG
DVDUDWLRH[SUHVVHGE\DYDOXHIURPWR ZKHUHLVWKHVKRUWHVWSXOVHDQG
LV WKH ORQJHVW 7KLV YDOXH LV FDOFXODWHG XVLQJ WKH $UGXLQR map IXQFWLRQ WR VFDOH WKH
PLFURVHFRQGVJLYHQIRUWKHSHULRGLQWRDSURSRUWLRQDOYDOXHRIWKHSHULRGWKDWUDQJHV
IURPWR
int duty = map(microseconds, 0,period, 1,1023);
18.5 Creating a Pulse Generator
Problem
<RXZDQWWRJHQHUDWHSXOVHVIURP$UGXLQRDQGFRQWUROWKHFKDUDFWHULVWLFVIURPWKH
6HULDO0RQLWRU
Solution
7KLVLVDQHQKDQFHGYHUVLRQRI5HFLSHWKDWHQDEOHVWKHIUHTXHQF\SHULRGSXOVH
ZLGWKDQGGXW\F\FOHWREHVHWIURPWKHVHULDOSRUW
#include <TimerOne.h>
const char SET_PERIOD_HEADER
= 'p';
const char SET_FREQUENCY_HEADER
= 'f';
const char SET_PULSE_WIDTH_HEADER = 'w';
const char SET_DUTY_CYCLE_HEADER = 'c';
#define pwmRegister OCR1A
const int
outPin = 9;
long period = 1000;
int duty = 512;
// the logical pin, can be set to OCR1B
// the physical pin
// the period in microseconds
// duty as a range from 0 to 1024, 512 is 50% duty cycle
int prescale[] = {0,1,8,64,256,1024}; // the range of prescale values
void setup()
{
Serial.begin(9600);
pinMode(outPin, OUTPUT);
Timer1.initialize(period);
Timer1.pwm(9, duty);
}
// initialize timer1, 1000 microseconds
// setup pwm on pin 9, 50% duty cycle
void loop()
{
562 | Chapter 18:ಗUsing the Controller Chip Hardware
}
processSerial();
void processSerial()
{
static long val = 0;
if ( Serial.available())
{
char ch = Serial.read();
if(ch >= '0' && ch <= '9')
// is ch a number?
{
val = val * 10 + ch - '0';
// yes, accumulate the value
}
else if(ch == SET_PERIOD_HEADER)
{
period = val;
Serial.print("Setting period to ");
Serial.println(period);
Timer1.setPeriod(period);
Timer1.setPwmDuty(outPin, duty); // don't change the duty cycle
show();
val = 0;
}
else if(ch == SET_FREQUENCY_HEADER)
{
if(val > 0)
{
Serial.print("Setting frequency to ");
Serial.println(val);
period = 1000000 / val;
Timer1.setPeriod(period);
Timer1.setPwmDuty(outPin, duty); // don't change the duty cycle
}
show();
val = 0;
}
else if(ch == SET_PULSE_WIDTH_HEADER)
{
if( setPulseWidth(val) ) {
Serial.print("Setting Pulse width to ");
Serial.println(val);
}
else
Serial.println("Pulse width too long for current period");
show();
val = 0;
}
else if(ch == SET_DUTY_CYCLE_HEADER)
{
if( val >0 && val < 100)
{
Serial.print("Setting Duty Cycle to ");
Serial.println(val);
18.5 Creating a Pulse Generator | 563
duty = map(val,1,99, 1, ICR1);
pwmRegister = duty;
show();
}
val = 0;
}
}
}
bool setPulseWidth(long microseconds)
{
bool ret = false;
}
int prescaleValue = prescale[Timer1.clockSelectBits];
// calculate time per tick in ns
long precision = (F_CPU / 128000) * prescaleValue ;
period = precision * ICR1 / 1000; // period in microseconds
if( microseconds < period)
{
duty = map(microseconds, 0,period, 0,1024);
if( duty < 1)
duty = 1;
if(microseconds > 0 && duty < RESOLUTION)
{
Timer1.pwm(outPin, duty);
ret = true;
}
}
return ret;
void show()
{
Serial.print("The period is ");
Serial.println(period);
Serial.print("Duty cycle is ");
// pwmRegister is ICR1A or ICR1B
Serial.print( map( pwmRegister, 0,ICR1, 1,99));
Serial.println("%");
Serial.println();
}
Discussion
7KLVVNHWFKLVEDVHGRQ5HFLSHZLWKWKHDGGLWLRQRIVHULDOFRGHWRLQWHUSUHWFRP
PDQGVWRUHFHLYHDQGVHWWKHIUHTXHQF\SHULRGSXOVHZLGWKDQGGXW\F\FOHSHUFHQW
&KDSWHUH[SODLQVWKHWHFKQLTXHXVHGWRDFFXPXODWHWKHYDULDEOHvalWKDWLVWKHQXVHG
IRUWKHGHVLUHGSDUDPHWHUEDVHGRQWKHFRPPDQGOHWWHU
<RXFDQDGGWKLVIXQFWLRQLI\RXZDQWWRSULQWLQVWUXFWLRQVWRWKHVHULDOSRUW
void instructions()
{
564 | Chapter 18:ಗUsing the Controller Chip Hardware
}
Serial.println("Send values followed by one of the following tags:");
Serial.println(" p - sets period in microseconds");
Serial.println(" f - sets frequency in Hz");
Serial.println(" w - sets pulse width in microseconds");
Serial.println(" c - sets duty cycle in %");
Serial.println("\n(duty cycle can have one decimal place)\n");
See Also
5HFLSH
18.6 Changing a Timer’s PWM Frequency
Problem
<RXQHHGWRLQFUHDVHRUGHFUHDVHWKH3XOVH:LGWK0RGXODWLRQ 3:0 IUHTXHQF\XVHG
ZLWKanalogWrite VHH&KDSWHU )RUH[DPSOH\RXDUHXVLQJanalogWriteWRFRQWUROD
PRWRUVSHHGDQGWKHUHLVDQDXGLEOHKXPEHFDXVHWKH3:0IUHTXHQF\LVWRRKLJKRU
\RXDUHPXOWLSOH[LQJ/('VDQGWKHOLJKWLVXQHYHQEHFDXVH3:0IUHTXHQF\LVWRRORZ
Solution
<RXFDQDGMXVWWKH3:0IUHTXHQF\E\FKDQJLQJDUHJLVWHUYDOXH7KHUHJLVWHUYDOXHV
DQGDVVRFLDWHGIUHTXHQFLHVDUHVKRZQLQ7DEOH
7DEOH$GMXVWPHQWYDOXHVIRU3:0
Timer0 (pins 5 and 6)
TCCR0B value
Prescale factor
(divisor)
Frequency
32 (1)
1
62500
33 (2)
8
7812.5
34
64
976.5625
35
256
244.140625
36
1,024
61.03515625
TCCR1B prescale
value
Prescale factor
(divisor)
Frequency
1
1
312500
2
8
3906.25
3
64
488.28125
4
256
122.0703125
5
1,024
30.517578125
Timer1 (pins 9 and 10)
18.6 Changing a Timer’s PWM Frequency | 565
Timer2 (pins 11 and 3)
TCCR2B value
Prescale factor
(divisor)
Frequency
1
1
312500
2
8
3906.25
3
64
488.28125
4
256
122.0703125
5
1,024
30.517578125
$OOIUHTXHQFLHVDUHLQKHUW]DQGDVVXPHD0+]V\VWHPWLPHEDVH7KHGHIDXOWSUHVFDOH
IDFWRURILVVKRZQLQEROG
7KLVVNHWFKHQDEOHV\RXWRVHOHFWDWLPHUIUHTXHQF\IURPWKH6HULDO0RQLWRU(QWHUD
GLJLWIURPWRXVLQJWKHYDOXHLQWKHOHIWKDQGFROXPQRI7DEOHDQGIROORZWKLV
ZLWKFKDUDFWHUDIRU7LPHUEIRU7LPHUDQGFIRU7LPHU
const byte mask = B11111000; // mask bits that are not prescale values
int prescale = 0;
void setup()
{
Serial.begin(9600);
analogWrite(3,128);
analogWrite(5,128);
analogWrite(6,128);
analogWrite(9,128);
analogWrite(10,128);
analogWrite(11,128);
}
void loop()
{
if ( Serial.available())
{
char ch = Serial.read();
if(ch >= '0' && ch <= '9')
// is ch a number?
{
prescale = ch - '0';
}
else if(ch == 'a') // timer 0;
{
TCCR0B = (TCCR0B & mask) | prescale;
}
else if(ch == 'b') // timer 1;
{
TCCR1B = (TCCR1B & mask) | prescale;
}
566 | Chapter 18:ಗUsing the Controller Chip Hardware
}
}
else if(ch == 'c') // timer 2;
{
TCCR2B = (TCCR2B & mask) | prescale;
}
$YRLGFKDQJLQJWKHIUHTXHQF\RI7LPHU XVHGIRU analogWriteSLQV
DQG EHFDXVHLWZLOOUHVXOWLQLQFRUUHFWWLPLQJXVLQJdelayDQGmillis
Discussion
,I\RXMXVWKDYH/('VFRQQHFWHGWRWKHDQDORJSLQVLQWKLVVNHWFK\RXZLOOQRWVHHDQ\
QRWLFHDEOHFKDQJHWRWKHEULJKWQHVVDV\RXFKDQJHWKH3:0VSHHG<RXDUHFKDQJLQJ
WKHVSHHGDVWKH\DUHWXUQLQJRQDQGRIIQRWWKHUDWLRRIWKHRQRIIWLPH,IWKLVLVXQFOHDU
VHHWKHLQWURGXFWLRQWR&KDSWHUIRUPRUHRQ3:0
<RXFKDQJHWKH3:0IUHTXHQF\RIDWLPHUE\VHWWLQJWKHTCCRnBUHJLVWHUZKHUHnLVWKH
UHJLVWHUQXPEHU2QD0HJDERDUG\RXDOVRKDYHTCCR3BTCCR4BDQGTCCR5BIRUWLPHUV
WKURXJK
$OODQDORJRXWSXW 3:0 SLQVRQDWLPHUXVHWKHVDPHIUHTXHQF\VR
FKDQJLQJWLPHUIUHTXHQF\ZLOODIIHFWDOORXWSXWSLQVIRUWKDWWLPHU
18.7 Counting Pulses
Problem
<RXZDQWWRFRXQWWKHQXPEHURISXOVHVRFFXUULQJRQDSLQ<RXZDQWWKLVFRXQWWREH
GRQHFRPSOHWHO\LQKDUGZDUHZLWKRXWDQ\VRIWZDUHSURFHVVLQJWLPHEHLQJFRQVXPHG
Solution
8VHWKHSXOVHFRXQWHUEXLOWLQWRWKH7LPHUKDUGZDUH
/*
* HardwareCounting sketch
*
* uses pin 5 on 168/328, pin 47 on Mega
*/
unsigned int count;
unsigned int getCount()
18.7 Counting Pulses | 567
{
}
TCCR1B= 0 ;
count = TCNT1;
TCNT1 = 0;
// Gate Off
/ Counter Tn stopped
bitSet(TCCR1B ,CS12);
bitSet(TCCR1B ,CS11);
bitSet(TCCR1B ,CS10);
// Counter Clock source is external pin
// Clock on rising edge
// you can clear this bit for falling edge
return count;
void setup()
{
Serial.begin(9600);
digitalWrite(5, HIGH);
// hardware counter setup (see ATmega data sheet for details)
TCCR1A=0;
// reset timer/counter control register A
getCount();
// this will start the clock
}
void loop()
{
delay(1000);
Serial.println(getCount());
}
)RUWKH0HJDFKDQJH TCCR1AWR TCCR5ADQG TCCR1BWR TCCR5BDQGFRQQHFWLQSXWWR
SLQ
Discussion
<RXFDQWHVWWKLVVNHWFKE\FRQQHFWLQJWKHVHULDOUHFHLYHSLQ SLQ WRWKHLQSXWSLQ SLQ
RQDVWDQGDUG$UGXLQRERDUG (DFKFKDUDFWHUVHQWVKRXOGVKRZDQLQFUHDVHLQWKH
FRXQW,I\RXKDYHWZR$UGXLQRERDUGV\RXFDQUXQRQHRIWKHSXOVHJHQHUDWRUVNHWFKHV
IURPSUHYLRXVUHFLSHVLQWKLVFKDSWHUDQGFRQQHFWWKHSXOVHRXWSXW SLQ WRWKHLQSXW
+DUGZDUHSXOVHFRXQWLQJXVHVDSLQWKDWLVLQWHUQDOO\ZLUHGZLWKLQWKH
KDUGZDUH DQG FDQQRW EH FKDQJHG 8VH SLQ RQ D VWDQGDUG $UGXLQR
ERDUGSLQRQWKH0HJD
7KHOLQHTCCR1A=0;LQsetupFOHDUVWKHUHJLVWHUTCCR1AVRWKDWLWLVUHDG\WRVWDUWFRXQWLQJ
&DOOLQJ getCount() UHWXUQV WKH FXUUHQW FRXQW UHVHWV WKH FRXQW DQG VWDUWV FRXQWLQJ
DJDLQ
,Q loop WKH FXUUHQW FRXQW LV SULQWHG RQFH SHU VHFRQG ,I QR SXOVHV DUH GHWHFWHG RQ
SLQWKHYDOXHVZLOOEH0
568 | Chapter 18:ಗUsing the Controller Chip Hardware
See Also
7KH)UHTXHQF\&RXQWHUOLEUDU\XVLQJWKHPHWKRGGLVFXVVHGLQWKLVUHFLSHKWWSLQWHU
IDFHNKPGHLQGH[SKSODEH[SHULPHQWVDUGXLQRIUHTXHQF\FRXQWHUOLEUDU\
18.8 Measuring Pulses More Accurately
Problem
<RXZDQWWRPHDVXUHWKHSHULRGEHWZHHQSXOVHVRUWKHGXUDWLRQRIWKHRQRURIIWLPH
RIDSXOVH<RXQHHGWKLVDVDFFXUDWHDVSRVVLEOHVR\RXGRQ¦WZDQWDQ\GHOD\GXHWR
FDOOLQJDQLQWHUUXSWKDQGOHU DVLQ5HFLSH DVWKLVZLOODIIHFWWKHPHDVXUHPHQWV
Solution
8VHWKHKDUGZDUHSXOVHPHDVXULQJFDSDELOLW\EXLOWLQWRWKH7LPHUKDUGZDUH
/*
* InputCapture
* uses timer hardware to measure pulses on pin 8
*/
const int inputCapturePin = 8;
// input pin cannot be changed
const int prescale = 8;
// prescale factor (each tick 0.5 us @16MHz)
const byte prescaleBits = B010;
// see Table 18-1 or Datasheet
// calculate time per counter tick in ns
const long precision = (1000000/(F_CPU/1000)) * prescale ;
const int numberOfEntries = 64;
// the number of pulses to measure
volatile byte index = 0;
volatile unsigned int results[numberOfEntries]; // note this is 16 bit value
/* ICR interrupt vector */
ISR(TIMER1_CAPT_vect)
{
TCNT1 = 0;
// reset the counter
if( index != 0 || bitRead(TCCR1B ,ICES1) == true)
// wait for rising edge
{
// falling edge was detected
results[index] = ICR1;
// save the input capture value
index = index + 1;
}
TCCR1B ^= _BV(ICES1);
// toggle bit to trigger on the other edge
}
void setup() {
Serial.begin(9600);
pinMode(inputCapturePin, INPUT); // ICP pin (digital pin 8 on Arduino) as input
TCCR1A = 0 ;
TCCR1B = prescaleBits ;
// Normal counting mode
// set prescale bits
18.8 Measuring Pulses More Accurately | 569
}
TCCR1B |= _BV(ICES1);
// enable input capture
bitSet(TIMSK1,ICIE1);
Serial.println( precision);
// enable input capture interrupt for timer 1
// report duration of each tick in microseconds
// this loop prints the number of pulses in the last second, showing min and max
pulse widths
void loop() {
if(index >= numberOfEntries)
{
Serial.println("Durations in Microseconds are:") ;
for( byte i=0; i < numberOfEntries; i++)
{
long duration;
duration = results[i] * precision; // pulse duration in nanoseconds
Serial.println(duration / 1000);
// duration in microseconds
}
while(1)
// loop so the print statements are executed once only
;
}
}
Discussion
7KLVVNHWFKXVHVDWLPHUIDFLOLW\FDOOHG,QSXW&DSWXUHWRPHDVXUHWKHGXUDWLRQRIDSXOVH
2QO\ELWWLPHUVVXSSRUWWKLVFDSDELOLW\DQGWKLVRQO\ZRUNVZLWKSLQRQDVWDQGDUG
$UGXLQRERDUG
,QSXW&DSWXUHXVHVDSLQWKDWLVLQWHUQDOO\ZLUHGZLWKLQWKHKDUGZDUH
DQGFDQQRWEHFKDQJHG8VHSLQRQDVWDQGDUG$UGXLQRERDUGDQGSLQ
RQD0HJD XVLQJ7LPHU %HFDXVH,QSXW&DSWXUHLVLPSOHPHQWHGHQWLUHO\LQWKHFRQWUROOHUFKLSKDUGZDUHQRWLPH
LVZDVWHGLQLQWHUUXSWKDQGOLQJVRWKLVWHFKQLTXHLVPRUHDFFXUDWHIRUYHU\VKRUWSXOVHV
OHVVWKDQWHQVRIPLFURVHFRQGV ,IWKHFRXQWJRHVKLJKHUWKDQWKHPD[LPXPYDOXHIRUWKHWLPHU\RXFDQPRQLWRURYHU
IORZWRLQFUHPHQWDYDULDEOHWRH[WHQGWKHFRXQWLQJUDQJH7KHIROORZLQJFRGHLQFUH
PHQWVDYDULDEOHQDPHGoverflowHDFKWLPHWKHFRXQWHURYHUIORZV
volatile int overflows = 0;
/* Overflow interrupt vector */
ISR(TIMER1_OVF_vect)
{
overflows++;
}
// here if no input pulse detected
// increment overflow count
570 | Chapter 18:ಗUsing the Controller Chip Hardware
Download from Wow! eBook <www.wowebook.com>
&KDQJHWKHFRGHLQsetupDVIROORZV
TIMSK1 = _BV(ICIE1);
TIMSK1 |= _BV(TOIE1);
// enable input capture interrupt for timer 1
// Add this line to enable overflow interrupt
18.9 Measuring Analog Values Quickly
Problem
<RX ZDQW WR UHDG DQ DQDORJ YDOXH DV TXLFNO\ DV SRVVLEOH ZLWKRXW GHFUHDVLQJ WKH
DFFXUDF\
Solution
<RXFDQLQFUHDVHWKHanalogReadVDPSOLQJUDWHE\FKDQJLQJUHJLVWHUYDOXHVWKDWGHWHU
PLQHWKHVDPSOLQJIUHTXHQF\
const int sensorPin = 0;
const int numberOfEntries = 100;
//pin the receiver is connected to
unsigned long microseconds;
unsigned long duration;
int results[numberOfEntries];
void setup()
{
Serial.begin(9600);
// standard analogRead performance (prescale = 128)
microseconds = micros();
for(int i = 0; i < numberOfEntries; i++)
{
results[i] = analogRead(sensorPin);
}
duration = micros() - microseconds;
Serial.print(numberOfEntries);
Serial.print(" readings took ");
Serial.println(duration);
// running with high speed clock (set prescale to 16)
bitClear(ADCSRA,ADPS0) ;
bitClear(ADCSRA,ADPS1) ;
bitSet(ADCSRA,ADPS2) ;
microseconds = micros();
for(int i = 0; i < numberOfEntries; i++)
{
results[i] = analogRead(sensorPin);
}
duration = micros() - microseconds;
Serial.print(numberOfEntries);
Serial.print(" readings took ");
Serial.println(duration);
18.9 Measuring Analog Values Quickly | 571
}
void loop()
{
}
5XQQLQJWKHVNHWFKRQD0+]$UGXLQRZLOOSURGXFHRXWSXWVLPLODUWRWKHIROORZLQJ
100 readings took 11308
100 readings took 1704
Discussion
analogReadWDNHVDURXQGPLFURVHFRQGVWRFRPSOHWHDUHDGLQJ7KLVPD\QRWEHIDVW
HQRXJKIRUUDSLGO\FKDQJLQJYDOXHVVXFKDVFDSWXULQJWKHKLJKHUUDQJHRIDXGLRIUH
TXHQFLHV7KHVNHWFKPHDVXUHVWKHWLPHLQPLFURVHFRQGVIRUWKHVWDQGDUG analogRead
DQGWKHQDGMXVWVWKHWLPHEDVHXVHGE\WKHDQDORJWRGLJLWDOFRQYHUWHU $'& WRSHUIRUP
WKH FRQYHUVLRQ IDVWHU :LWK D 0+] ERDUG WKH WLPHEDVH UDWH LV LQFUHDVHG IURP
.+]WR0+]7KHDFWXDOSHUIRUPDQFHLPSURYHPHQWLVVOLJKWO\OHVVWKDQHLJKW
WLPHVEHFDXVHWKHUHLVVRPHRYHUKHDGLQWKH$UGXLQR analogReadIXQFWLRQWKDWLVQRW
LPSURYHGE\WKHWLPHEDVHFKDQJH7KHUHGXFWLRQRIWLPHIURPPLFURVHFRQGVWR
PLFURVHFRQGVLVDVLJQLILFDQWLPSURYHPHQW
7KH ADCSRA UHJLVWHU LV XVHG WR FRQILJXUH WKH $'& DQG WKH ELWV VHW LQ WKH VNHWFK
ADPS0ADPS1DQGADPS2 VHWWKH$'&FORFNGLYLVRUWR
See Also
$WPHO KDV DQ DSSOLFDWLRQ QRWH WKDW SURYLGHV D GHWDLOHG H[SODQDWLRQ RI SHUIRUPDQFH
DVSHFWV RI WKH $'& KWWSZZZDWPHOFRPG\QUHVRXUFHVSURGBGRFXPHQWV'2&
3')
18.10 Reducing Battery Drain
Problem
<RXZDQWWRUHGXFHWKHSRZHUXVHGE\\RXUDSSOLFDWLRQE\VKXWWLQJGRZQ$UGXLQR
XQWLODSHULRGRIWLPHKDVHODSVHGRUXQWLODQH[WHUQDOHYHQWWDNHVSODFH
Solution
7KLVVROXWLRQXVHVDOLEUDU\E\$UGXLQRJXUX3HWHU.QLJKW<RXFDQGRZQORDGWKHOLEUDU\
IURPKWWSFRGHJRRJOHFRPSQDUFROHSWLF
#include <Narcoleptic.h>
void setup() {
pinMode(2,INPUT);
digitalWrite(2,HIGH);
pinMode(13,OUTPUT);
572 | Chapter 18:ಗUsing the Controller Chip Hardware
}
digitalWrite(13,LOW);
void loop() {
int a;
// Merlin the cat is snoozing... Connect digital pin 2 to ground to wake him up.
Narcoleptic.delay(500); // During this time power consumption is minimized
while (digitalRead(2) == LOW) {
// Wake up CPU. Unfortunately, Merlin does not like waking up.
// Swipe claws left
digitalWrite(13,HIGH);
delay(50);
}
}
// Swipe claws right
digitalWrite(13,LOW);
delay(50);
// Merlin the cat goes to sleep...
Discussion
$VWDQGDUG$UGXLQRERDUGZRXOGUXQGRZQDYROWDONDOLQHEDWWHU\LQDIHZZHHNV
WKH'XHPLODQRYHW\SLFDOO\GUDZVPRUHWKDQPLOOLDPSHUHV>P$@H[FOXGLQJDQ\H[
WHUQDOGHYLFHVWKDWPD\EHFRQQHFWHG <RXFDQUHGXFHWKLVFRQVXPSWLRQE\KDOILI\RX
XVHDERDUGWKDWGRHVQRWKDYHDEXLOWLQ86%LQWHUIDFHFKLSVXFKDVWKH$UGXLQR0LQL
/LO\3DG)LRRURQHRIWKH0RGHUQ'HYLFH%DUH%RQHV%RDUGVWKDWUHTXLUHWKHXVHRI
DQH[WHUQDO86%LQWHUIDFHIRUXSORDGLQJVNHWFKHV6LJQLILFDQWO\JUHDWHUSRZHUVDYLQJV
FDQ EH DFKLHYHG LI \RXU DSSOLFDWLRQ FDQ VXVSHQG RSHUDWLRQ IRU D SHULRG RI WLPH¢
$UGXLQRKDUGZDUHFDQEHSXWWRVOHHSIRUDSUHVHWSHULRGRIWLPHRUXQWLODSLQFKDQJHV
VWDWH DQG WKLV UHGXFHV WKH SRZHU FRQVXPSWLRQ RI WKH FKLS WR OHVV WKDQ RQH RQH
KXQGUHGWKRISHUFHQW IURPDURXQGP$WRDURXQGP$ GXULQJVOHHS
7KHOLEUDU\XVHGLQWKLVUHFLSHSURYLGHVHDV\DFFHVVWRWKHKDUGZDUHVOHHSIXQFWLRQ7KH
VOHHSWLPHFDQUDQJHIURPWRPLOOLVHFRQGV HLJKWVHFRQGV 7RVOHHSIRUORQJHU
SHULRGV\RXFDQUHSHDWWKHGHOD\LQWHUYDOVXQWLO\RXJHWWKHSHULRG\RXZDQW
void longDelay(long milliseconds)
{
while(milliseconds > 0)
{
if(milliseconds > 8000)
{
milliseconds -= 8000;
Narcoleptic.delay(8000);
}
else
{
Narcoleptic.delay(milliseconds);
18.10 Reducing Battery Drain | 573
}
}
break;
}
6OHHSPRGHFDQUHGXFHWKHSRZHUFRQVXPSWLRQRIWKHFRQWUROOHUFKLSEXWLI\RXDUH
ORRNLQJWRUXQIRUDVORQJDVSRVVLEOHRQDEDWWHU\\RXVKRXOGPLQLPL]HFXUUHQWGUDLQ
WKURXJKH[WHUQDOFRPSRQHQWVVXFKDVLQHIILFLHQWYROWDJHUHJXODWRUVSXOOXSRUSXOO
GRZQUHVLVWRUV/('VDQGRWKHUFRPSRQHQWVWKDWGUDZFXUUHQWZKHQWKHFKLSLVLQ
VOHHSPRGH
See Also
6HHWKH$UGXLQRKDUGZDUHSDJHIRUOLQNVWRLQIRUPDWLRQRQWKH/LO\3DGDQG)LRERDUGV
KWWSZZZDUGXLQRFFHQ0DLQ+DUGZDUH
)RUDQH[DPSOHRIYHU\ORZSRZHURSHUDWLRQVHHKWWSLQWHUIDFHNKPGHLQGH[SKSODE
H[SHULPHQWVVOHHSBZDWFKGRJBEDWWHU\
18.11 Setting Digital Pins Quickly
Problem
<RXQHHGWRVHWRUFOHDUGLJLWDOSLQVPXFKIDVWHUWKDQHQDEOHGE\WKH$UGXLQR digital
WriteFRPPDQG
Solution
$UGXLQR digitalWriteSURYLGHVDVDIHDQGHDV\WRXVHPHWKRGRIVHWWLQJDQGFOHDULQJ
SLQVEXWLWLVPRUHWKDQWLPHVVORZHUWKDQGLUHFWO\DFFHVVLQJWKHFRQWUROOHUKDUGZDUH
<RXFDQVHWDQGFOHDUSLQVE\GLUHFWO\VHWWLQJELWVRQWKHKDUGZDUHUHJLVWHUVWKDWDUH
FRQWUROOLQJGLJLWDOSLQV
7KLVVNHWFKXVHVGLUHFWKDUGZDUH,2WRVHQG0RUVHFRGH WKHZRUGDUGXLQR WRDQ$0
UDGLRWXQHGWRDSSUR[LPDWHO\0+]7KHWHFKQLTXHXVHGKHUHLVWLPHVIDVWHUWKDQ
$UGXLQRdigitalWrite
/*
* Morse sketch
*
* Direct port I/O used to send AM radio carrier at 1MHz
*/
const int sendPin = 2;
const byte WPM = 12;
// sending speed in words per minute
const long repeatCount = 1200000 / WPM; // count used to determine
the duration of dots and dashes
const byte dot = 1;
574 | Chapter 18:ಗUsing the Controller Chip Hardware
const byte dash = 3;
const byte gap = 3;
const byte wordGap = 7;
byte letter = 0; // the letter to send
char *arduino = ".- .-. -.. ..- .. -. ---";
void setup()
{
pinMode(sendPin, OUTPUT);
Serial.begin(9600);
}
void loop()
{
sendMorse(arduino);
delay(2000);
}
void sendMorse(char * string)
{
letter = 0 ;
while(string[letter]!= 0)
{
if(string[letter] == '.')
{
sendDot();
}
else if(string[letter] == '-')
{
sendDash();
}
else if(string[letter] == ' ')
{
sendGap();
}
else if(string[letter] == 0)
{
sendWordGap();
}
letter = letter+1;
}
}
void sendDot()
{
transmitCarrier( dot *
sendGap();
}
void
{
repeatCount);
sendDash()
18.11 Setting Digital Pins Quickly | 575
}
transmitCarrier( dash *
sendGap();
repeatCount);
void sendGap()
{
transmitNoCarrier( gap * repeatCount);
}
void sendWordGap()
{
transmitNoCarrier( wordGap *
}
repeatCount);
void transmitCarrier(long count)
{
while(count--)
{
bitSet(PORTD, sendPin);
bitSet(PORTD, sendPin);
bitSet(PORTD, sendPin);
bitSet(PORTD, sendPin);
bitClear(PORTD, sendPin);
}
}
void transmitNoCarrier(long count)
{
while(count--)
{
bitClear(PORTD, sendPin);
bitClear(PORTD, sendPin);
bitClear(PORTD, sendPin);
bitClear(PORTD, sendPin);
bitClear(PORTD, sendPin);
}
}
&RQQHFWRQHHQGRIDSLHFHRIZLUHWRSLQDQGSODFHWKHRWKHUHQGQHDUWKHDQWHQQD
RIDPHGLXPZDYH$0UDGLRWXQHGWR0+] .+] Discussion
7KH VNHWFK JHQHUDWHV D 0+] VLJQDO WR SURGXFH GRW DQG GDVK VRXQGV WKDW FDQ EH
UHFHLYHGE\DQ$0UDGLRWXQHGWRWKLVIUHTXHQF\7KHIUHTXHQF\LVGHWHUPLQHGE\WKH
GXUDWLRQRIWKHbitSetDQGbitClearFRPPDQGVWKDWVHWWKHSLQHIGHDQGLOWWRJHQHUDWH
WKHUDGLRVLJQDObitSetDQGbitClearDUHQRWIXQFWLRQVWKH\DUHPDFURV0DFURVVXE
VWLWXWHDQH[SUHVVLRQIRUH[HFXWDEOHFRGH¢LQWKLVFDVHFRGHWKDWFKDQJHVDVLQJOHELW
LQUHJLVWHUPORTDJLYHQE\WKHYDOXHRIsendPin
'LJLWDOSLQVWKURXJKDUHFRQWUROOHGE\WKHUHJLVWHUQDPHGPORTD(DFKELWLQPORTD
FRUUHVSRQGVWRDGLJLWDOSLQ3LQVWKURXJKDUHRQUHJLVWHUPORTBDQGSLQVWKURXJK
576 | Chapter 18:ಗUsing the Controller Chip Hardware
DUHRQPORTA7KHVNHWFKXVHVWKHbitSetDQGbitClearFRPPDQGVWRVHWDQGFOHDU
ELWVRQWKHSRUW VHH5HFLSH (DFKUHJLVWHUVXSSRUWVXSWRHLJKWELWV DOWKRXJKQRW
DOOELWVFRUUHVSRQGWR$UGXLQRSLQV ,I\RXZDQWWRXVH$UGXLQRSLQLQVWHDGRISLQ
\RXQHHGWRVHWDQGFOHDUPORTBDVIROORZV
const int sendPin = 13;
bitSet(PORTB, sendPin - 8);
bitClear(PORTB, sendPin - 8);
<RXVXEWUDFWIURPWKHYDOXHRIWKHSLQEHFDXVHELWRIWKHPORTBUHJLVWHULVSLQELW
LVSLQDQGVRRQWRELWFRQWUROOLQJSLQ
6HWWLQJDQGFOHDULQJELWVXVLQJ bitSetLVGRQHLQDVLQJOHLQVWUXFWLRQRIWKH$UGXLQR
FRQWUROOHU2QD0+]$UGXLQRWKDWLVQDQRVHFRQGV7KLVLVDURXQGWLPHV
IDVWHUWKDQXVLQJdigitalWrite
7KHWUDQVPLWIXQFWLRQVLQWKHVNHWFKDFWXDOO\QHHGPRUHWLPHXSGDWLQJDQGFKHFNLQJ
WKH count YDULDEOH WKDQ LW WDNHV WR VHW DQG FOHDU WKH UHJLVWHU ELWV ZKLFK LV ZK\ WKH
transmitCarrier IXQFWLRQ KDV IRXU bitSet FRPPDQGV DQG RQO\ RQH bitClear
FRPPDQG¢WKHDGGLWLRQDObitClearFRPPDQGVDUHQRWQHHGHGEHFDXVHRIWKHWLPHLW
WDNHVWRXSGDWHDQGFKHFNWKHcountYDULDEOH
18.11 Setting Digital Pins Quickly | 577
APPENDIX A
Electronic Components
,I\RXDUHMXVWVWDUWLQJRXWZLWKHOHFWURQLFFRPSRQHQWV\RXPD\ZDQWWRSXUFKDVHD
EHJLQQHU¦VVWDUWHUNLWWKDWFRQWDLQVWKHEDVLFFRPSRQHQWVQHHGHGIRUPDQ\RIWKHUHFLSHV
LQWKLVERRN7KHVHXVXDOO\LQFOXGHWKHPRVWFRPPRQUHVLVWRUVFDSDFLWRUVWUDQVLVWRUV
GLRGHV/('VDQGVZLWFKHV
+HUHDUHVRPHSRSXODUFKRLFHV
0DNHU6KHG$UGXLQRVWDUWHUNLW
KWWSZZZPDNHUVKHGFRP3URGXFW'HWDLOVDVS"3URGXFW&RGH 06*6$
6WDUWHU.LWIRU$UGXLQR)OH[ 6.8'(9
KWWSZZZVSDUNIXQFRPFRPPHUFHSURGXFWBLQIRSKS"SURGXFWVBLG $GDIUXLW6WDUWHU3DFNIRU$UGXLQR SURGXFW,'
KWWSZZZDGDIUXLWFRPLQGH[SKS"PDLQBSDJH SURGXFWBLQIR SURGXFWVBLG 2RPORXW6WDUWHU.LWIRU$UGXLQR $5';
KWWSRRPORXWFRXNDUGXLQRH[SHULPHQWDWLRQNLWDUG[SKWPO
6HHHGXLQR&DWDO\VW3DFN
KWWSZZZVHHHGVWXGLRFRPGHSRWVXSHUVHHHGXLQRFDWDO\VWSDFNSKWPO
<RXFDQDOVRSXUFKDVHWKHLQGLYLGXDOFRPSRQHQWVIRU\RXUSURMHFWDVVKRZQLQ)LJ
XUH $ 7KH IROORZLQJ VHFWLRQV SURYLGH DQ RYHUYLHZ RI FRPPRQ HOHFWURQLF
FRPSRQHQWV¢SDUWQXPEHUVFDQEHIRXQGRQWKLVERRN¦VZHEVLWH
Capacitor
&DSDFLWRUVVWRUHDQHOHFWULFDOFKDUJHIRUDVKRUWWLPHDQGDUHXVHGLQGLJLWDOFLUFXLWVWR
ILOWHU VPRRWKRXW GLSVDQGVSLNHVLQHOHFWULFDOVLJQDOV7KHPRVWFRPPRQO\XVHGFD
SDFLWRULVWKHQRQSRODUL]HGFHUDPLFFDSDFLWRUIRUH[DPSOHDQ)GLVFFDSDFLWRUXVHG
IRUGHFRXSOLQJ UHGXFLQJQRLVHVSLNHV (OHFWURO\WLFFDSDFLWRUVFDQJHQHUDOO\VWRUHPRUH
FKDUJH WKDQ FHUDPLF FDSV DQG DUH XVHG IRU KLJKHU FXUUHQW FLUFXLWV VXFK DV SRZHU
VXSSOLHVDQGPRWRUFLUFXLWV(OHFWURO\WLFFDSDFLWRUVDUHXVXDOO\SRODUL]HGDQGWKHQHJ
579
)LJXUH$6FKHPDWLFUHSUHVHQWDWLRQRIFRPPRQFRPSRQHQWV
DWLYHOHJ PDUNHGZLWKDPLQXVVLJQ PXVWEHFRQQHFWHGWRJURXQG RUWRDSRLQWZLWK
ORZHUYROWDJHWKDQWKHSRVLWLYHOHJ &KDSWHUFRQWDLQVH[DPSOHVVKRZLQJKRZFDSDF
LWRUVDUHXVHGLQPRWRUFLUFXLWV
Diode
'LRGHVSHUPLWFXUUHQWWRIORZLQRQHGLUHFWLRQDQGEORFNLWLQWKHRWKHUGLUHFWLRQ0RVW
GLRGHVKDYHDEDQG VHH)LJXUH$ WRLQGLFDWHWKHFDWKRGH QHJDWLYH HQG
'LRGHVVXFKDVWKH1FDQEHXVHGIRUORZFXUUHQWDSSOLFDWLRQVVXFKDVWKHOHYHOV
XVHGRQ$UGXLQRGLJLWDOSLQV7KH1GLRGHLVDJRRGFKRLFHIRUKLJKHUFXUUHQWV
XSWRDPS 580 | Appendix A:ಗElectronic Components
Integrated Circuit
,QWHJUDWHGFLUFXLWVFRQWDLQHOHFWURQLFFRPSRQHQWVSDFNDJHGWRJHWKHULQDFRQYHQLHQW
FKLS7KHVHFDQEHFRPSOH[OLNHWKH$UGXLQRFRQWUROOHUFKLSWKDWFRQWDLQVWKRXVDQGV
RIWUDQVLVWRUVRUDVVLPSOHDVWKHRSWLFDOLVRODWRUFRPSRQHQWXVHGLQ&KDSWHUWKDW
FRQWDLQVMXVWWZRVHPLFRQGXFWRUV6RPHLQWHJUDWHGFLUFXLWV VXFKDVWKH$UGXLQRFKLS
DUHVHQVLWLYHWRVWDWLFHOHFWULFLW\DQGVKRXOGEHKDQGOHGZLWKFDUH
Keypad
$NH\SDGLVDPDWUL[RIVZLWFKHVXVHGWRSURYLGHLQSXWIRUQXPHULFGLJLWV6HH&KDSWHU
LED
$Q/(' OLJKWHPLWWLQJGLRGH LVDGLRGHWKDWHPLWVOLJKWZKHQFXUUHQWIORZVWKURXJK
WKH GHYLFH $V WKH\ DUH GLRGHV /('V RQO\ FRQGXFW HOHFWULFLW\ LQ RQH GLUHFWLRQ 6HH
&KDSWHU
Motor (DC)
0RWRUVFRQYHUWHOHFWULFDOHQHUJ\LQWRSK\VLFDOPRYHPHQW0RVWVPDOOGLUHFWFXUUHQW
'& PRWRUVKDYHDVSHHGSURSRUWLRQDOWRWKHYROWDJHDQG\RXFDQUHYHUVHWKHGLUHFWLRQ
WKH\PRYHE\UHYHUVLQJWKHSRODULW\RIWKHYROWDJHDFURVVWKHPRWRU0RVWPRWRUVQHHG
PRUHFXUUHQWWKDQWKH$UGXLQRSLQVSURYLGHDQGDFRPSRQHQWVXFKDVDWUDQVLVWRULV
UHTXLUHGWRGULYHWKHPRWRU6HH&KDSWHU
Optocoupler
2SWRFRXSOHUV DOVRFDOOHGRSWRLVRODWRUV SURYLGHHOHFWULFDOVHSDUDWLRQEHWZHHQGHYLFHV
7KLVLVRODWLRQDOORZVGHYLFHVWKDWRSHUDWHZLWKGLIIHUHQWYROWDJHOHYHOVWRZRUNVDIHO\
WRJHWKHU6HH&KDSWHU
Photocell (Photoresistor)
3KRWRFHOOVDUHYDULDEOHUHVLVWRUVZKRVHUHVLVWDQFHFKDQJHVZLWKOLJKW6HH&KDSWHU
Piezo
$VPDOOFHUDPLFWUDQVGXFHUWKDWSURGXFHVVRXQGZKHQSXOVHGD3LH]RLVSRODUL]HGDQG
PD\KDYHDUHGZLUHLQGLFDWLQJWKHSRVLWLYHHQGDQGDEODFNZLUHLQGLFDWLQJWKHVLGHWR
EHFRQQHFWHGWRJURXQG6HH&KDSWHU
Piezo | 581
Pot (Potentiometer)
$SRWHQWLRPHWHU SRWIRUVKRUW LVDYDULDEOHUHVLVWRU7KHWZRRXWVLGHWHUPLQDOVDFWDV
DIL[HGUHVLVWRU$PRYDEOHFRQWDFWFDOOHGDZLSHU RUVOLGHU PRYHVDFURVVWKHUHVLVWRU
SURGXFLQJ D YDULDEOH UHVLVWDQFH EHWZHHQ WKH FHQWHU WHUPLQDO DQG WKH WZR VLGHV 6HH
&KDSWHU
Relay
$UHOD\LVDQHOHFWURQLFVZLWFK¢FLUFXLWVDUHRSHQHGRUFORVHGLQUHVSRQVHWRDYROWDJH
RQWKHUHOD\FRLOZKLFKLVHOHFWULFDOO\LVRODWHGIURPWKHVZLWFK0RVWUHOD\FRLOVUHTXLUH
PRUHFXUUHQWWKDQ$UGXLQRSLQVSURYLGHVRWKH\QHHGDWUDQVLVWRUWRGULYHWKHP6HH
&KDSWHU
Resistor
5HVLVWRUVUHVLVWWKHIORZRIHOHFWULFDOFXUUHQW$YROWDJHIORZLQJWKURXJKDUHVLVWRUZLOO
OLPLWWKHFXUUHQWSURSRUWLRQDOWRWKHYDOXHRIWKHUHVLVWRU VHH2KP¦VODZ 7KHEDQGV
RQDUHVLVWRULQGLFDWHWKHUHVLVWRU¦VYDOXH&KDSWHUFRQWDLQVLQIRUPDWLRQRQVHOHFWLQJ
DUHVLVWRUIRUXVHZLWK/('V
Solenoid
$VROHQRLGSURGXFHVOLQHDUPRYHPHQWZKHQSRZHUHG6ROHQRLGVKDYHDPHWDOOLFFRUH
WKDWLVPRYHGE\DPDJQHWLFILHOGFUHDWHGZKHQSDVVLQJFXUUHQWWKURXJKDFRLO6HH
&KDSWHU
Speaker
$VSHDNHUSURGXFHVVRXQGE\PRYLQJDGLDSKUDJP WKHVSHDNHUFRQH WRFUHDWHVRXQG
ZDYHV7KHGLDSKUDJPLVGULYHQE\VHQGLQJDQDXGLRIUHTXHQF\HOHFWULFDOVLJQDOWRD
FRLORIZLUHDWWDFKHGWRWKHGLDSKUDJP6HH&KDSWHU
Stepper Motor
$VWHSSHUPRWRUURWDWHVDVSHFLILFQXPEHURIGHJUHHVLQUHVSRQVHWRFRQWUROSXOVHV6HH
&KDSWHU
582 | Appendix A:ಗElectronic Components
Download from Wow! eBook <www.wowebook.com>
Switch
$VZLWFKPDNHVDQGEUHDNVDQHOHFWULFDOFLUFXLW0DQ\RIWKHUHFLSHVLQWKLVERRNXVHD
W\SHRISXVKEXWWRQVZLWFKNQRZQDVDWDFWLOHVZLWFK7DFWLOHVZLWFKHVKDYHWZRSDLUVRI
FRQWDFWVWKDWDUHFRQQHFWHGWRJHWKHUZKHQWKHEXWWRQLVSXVKHG7KHSDLUVDUHZLUHG
WRJHWKHUVR\RXFDQXVHHLWKHURQHRIWKHSDLU6ZLWFKHVWKDWPDNHFRQWDFWZKHQSUHVVHG
DUHFDOOHG1RUPDOO\2SHQ 12 VZLWFKHV6HH&KDSWHU
Transistor
7UDQVLVWRUVDUHXVHGWRVZLWFKRQKLJKFXUUHQWVRUKLJKYROWDJHVLQGLJLWDOFLUFXLWV,Q
DQDORJ FLUFXLWV WUDQVLVWRUV DUH XVHG WR DPSOLI\ VLJQDOV $ VPDOO FXUUHQW WKURXJK WKH
WUDQVLVWRUEDVHUHVXOWVLQDODUJHUFXUUHQWIORZLQJWKURXJKWKHFROOHFWRUDQGHPLWWHU
)RUFXUUHQWVXSWRDPSHUHV P$ RUVRWKH1WUDQVLVWRULVDZLGHO\DYDLODEOH
FKRLFH)RUFXUUHQWVXSWRDPSHUHV\RXFDQXVHWKH7,3WUDQVLVWRU
6HH&KDSWHUVDQGIRUH[DPSOHVRIWUDQVLVWRUVXVHGZLWK/('VDQGPRWRUV
See Also
)RUPRUHFRPSUHKHQVLYHFRYHUDJHRIEDVLFHOHFWURQLFVVHHWKHIROORZLQJ
0DNH(OHFWURQLFVE\&KDUOHV3ODWW 2¦5HLOO\
*HWWLQJ6WDUWHGLQ(OHFWURQLFVE\)RUUHVW0LPV 0DVWHU3XEOLVKLQJ
3K\VLFDO&RPSXWLQJE\7RP,JRH &HQJDJH
3UDFWLFDO(OHFWURQLFVIRU,QYHQWRUVE\3DXO6FKHU] 0F*UDZ+LOO
See Also | 583
APPENDIX B
Using Schematic Diagrams and
Data Sheets
$VFKHPDWLFGLDJUDPDOVRFDOOHGDFLUFXLWGLDJUDPLVWKHVWDQGDUGZD\RIGHVFULELQJ
WKH FRPSRQHQWV DQG FRQQHFWLRQV LQ DQ HOHFWURQLF FLUFXLW ,W XVHV LFRQLF V\PEROV WR
UHSUHVHQW FRPSRQHQWV ZLWK OLQHV UHSUHVHQWLQJ WKH FRQQHFWLRQV EHWZHHQ WKH
FRPSRQHQWV
$FLUFXLWGLDJUDPUHSUHVHQWVWKHFRQQHFWLRQVRIDFLUFXLWEXWLWLVQRWDGUDZLQJRIWKH
DFWXDOSK\VLFDOOD\RXW$OWKRXJK\RXPD\LQLWLDOO\ILQGWKDWGUDZLQJVDQGSKRWRVRIWKH
SK\VLFDOZLULQJFDQEHHDVLHUWRXQGHUVWDQGWKDQDVFKHPDWLFLQDFRPSOLFDWHGFLUFXLW
LWFDQEHGLIILFXOWWRFOHDUO\VHHZKHUHHDFKZLUHJHWVFRQQHFWHG
&LUFXLWGLDJUDPVDUHOLNHPDSV7KH\KDYHFRQYHQWLRQVWKDWKHOS\RXWRRULHQW\RXUVHOI
RQFH\RXEHFRPHIDPLOLDUZLWKWKHLUVW\OHDQGV\PEROV)RUH[DPSOHLQSXWVDUHXVXDOO\
WRWKHOHIWRXWSXWVWRWKHULJKW9RUJURXQGFRQQHFWLRQVDUHXVXDOO\VKRZQDWWKH
ERWWRPRIVLPSOHFLUFXLWVWKHSRZHUDWWKHWRS
)LJXUH $ LQ $SSHQGL[ $ VKRZV VRPH RI WKH PRVW FRPPRQ FRPSRQHQWV DQG WKH
V\PEROVXVHGIRUWKHPLQFLUFXLWGLDJUDPV )LJXUH%LVDVFKHPDWLFGLDJUDPIURP
5HFLSHWKDWLOOXVWUDWHVWKHV\PEROVXVHGLQDW\SLFDOGLDJUDP
&RPSRQHQWVVXFKDVWKHUHVLVWRUDQGFDSDFLWRUXVHGKHUHDUHQRWSRODUL]HG¢WKH\FDQ
EHFRQQHFWHGHLWKHUZD\DURXQG7UDQVLVWRUVGLRGHVDQGLQWHJUDWHGFLUFXLWVDUHSR
ODUL]HGVRLWLVLPSRUWDQWWKDW\RXLGHQWLI\HDFKOHDGDQGFRQQHFWLWDFFRUGLQJWRWKH
GLDJUDP
)LJXUH%VKRZVKRZWKHZLULQJFRXOGORRNZKHQFRQQHFWHGXVLQJDEUHDGERDUG7KLV
GUDZLQJZDVSURGXFHGXVLQJDWRROFDOOHG)ULW]LQJWKDWHQDEOHVWKHGUDZLQJRIHOHFWURQLF
FLUFXLWV6HHKWWSIULW]LQJRUJ
585
)LJXUH%7\SLFDOVFKHPDWLFGLDJUDP
)LJXUH%3K\VLFDOOD\RXWRIWKHFLUFXLWVKRZQLQ)LJXUH%
586 | Appendix B:ಗUsing Schematic Diagrams and Data Sheets
How to Read a Data Sheet
'DWDVKHHWVDUHSURGXFHGE\WKHPDQXIDFWXUHUVRIFRPSRQHQWVWRVXPPDUL]HWKHWHFK
QLFDOFKDUDFWHULVWLFVRIDGHYLFH'DWDVKHHWVFRQWDLQGHILQLWLYHLQIRUPDWLRQDERXWWKH
SHUIRUPDQFHDQGXVDJHRIWKHGHYLFHIRUH[DPSOHWKHPLQLPXPYROWDJHQHHGHGIRU
WKHGHYLFHWRIXQFWLRQDQGWKHPD[LPXPYROWDJHWKDWLWFDQUHOLDEO\WROHUDWH'DWDVKHHWV
FRQWDLQLQIRUPDWLRQRQWKHIXQFWLRQRIHDFKSLQDQGDGYLFHRQKRZWRXVHWKHGHYLFH
)RUPRUHFRPSOLFDWHGGHYLFHVVXFKDV/&'VWKHGDWDVKHHWFRYHUVKRZWRLQLWLDOL]H
DQGLQWHUDFWZLWKWKHGHYLFH9HU\FRPSOH[GHYLFHVVXFKDVWKH$UGXLQRFRQWUROOHUFKLS
UHTXLUHKXQGUHGVRISDJHVWRH[SODLQDOOWKHFDSDELOLWLHVRIWKHGHYLFH
'DWDVKHHWVDUHZULWWHQIRUGHVLJQHQJLQHHUVDQGWKH\XVXDOO\FRQWDLQPXFKPRUHLQ
IRUPDWLRQWKDQ\RXQHHGWRJHWPRVWGHYLFHVZRUNLQJLQDQ$UGXLQRSURMHFW'RQ¦WEH
LQWLPLGDWHGE\WKHYROXPHRIWHFKQLFDOLQIRUPDWLRQ\RXZLOOW\SLFDOO\ILQGWKHLPSRU
WDQWLQIRUPDWLRQLQWKHILUVWFRXSOHRISDJHV7KHUHZLOOXVXDOO\EHDFLUFXLWGLDJUDP
V\PEROODEHOHGWRVKRZKRZWKHFRQQHFWLRQVRQWKHGHYLFHFRUUHVSRQGWRWKHV\PEROV
7KLVSDJHZLOOW\SLFDOO\KDYHDJHQHUDOGHVFULSWLRQRIWKHGHYLFH RUIDPLO\RIGHYLFHV
DQGWKHNLQGVRIXVHVWKH\DUHVXLWDEOHIRU
$IWHUWKLVWKHUHLVXVXDOO\DWDEOHRIWKHHOHFWULFDOFKDUDFWHULVWLFVRIWKHGHYLFH
/RRNIRULQIRUPDWLRQDERXWWKHPD[LPXPYROWDJHDQGWKHFXUUHQWWKHGHYLFHLVGHVLJQHG
WRKDQGOHWRFKHFNWKDWLWLVLQWKHUDQJH\RXQHHG)RUFRPSRQHQWVWRFRQQHFWGLUHFWO\
WRDVWDQGDUG$UGXLQRERDUGGHYLFHVQHHGWRRSHUDWHDWYROWV7REHSRZHUHGGLUHFWO\
IURPWKHSLQRIWKH$UGXLQRWKH\QHHGWREHDEOHWRRSHUDWHZLWKDFXUUHQWRIP$
RUOHVV
6RPHFRPSRQHQWVDUHGHVLJQHGWRRSHUDWHRQYROWVDQGFDQEHGDP
DJHGLIFRQQHFWHGWRD9$UGXLQRERDUG8VHWKHVHGHYLFHVZLWKDERDUG
GHVLJQHGWRUXQIURPD9VXSSO\ HJWKH/LO\3DG)LRRU90LQL
3UR RUXVHDORJLFOHYHOFRQYHUWHUVXFKDVWKH6SDUN)XQ%2%
0RUHLQIRUPDWLRQRQORJLFOHYHOFRQYHUVLRQLVDYDLODEOHDWKWWSLFVQ[S
FRPVXSSRUWGRFXPHQWVLQWHUIDFHSGIDQSGI
Choosing and Using Transistors for Switching
7KH$UGXLQRRXWSXWSLQVDUHGHVLJQHGWRKDQGOHFXUUHQWVXSWRP$ PLOOLDPSHUHV ZKLFKLVRQO\RIDQDPS<RXFDQXVHDWUDQVLVWRUWRVZLWFKODUJHUFXUUHQWV7KLV
VHFWLRQSURYLGHVJXLGDQFHRQWUDQVLVWRUVHOHFWLRQDQGXVH
7KH PRVW FRPPRQO\ XVHG WUDQVLVWRUV ZLWK $UGXLQR SURMHFWV DUH ELSRODU WUDQVLVWRUV
7KHVH FDQ EH RI WZR W\SHV QDPHG 131 DQG 313 WKDW GHWHUPLQH WKH GLUHFWLRQ RI
FXUUHQWIORZ131LVPRUHFRPPRQIRU$UGXLQRSURMHFWVDQGLVWKHW\SHWKDWLVLOOXV
WUDWHGLQWKHUHFLSHVLQWKLVERRN)RUFXUUHQWVXSWRDPSHUHV P$ RUVRWKH
Choosing and Using Transistors for Switching | 587
1WUDQVLVWRULVDZLGHO\DYDLODEOHFKRLFHWKH7,3WUDQVLVWRULVDSRSXODUFKRLFH
IRUFXUUHQWVXSWRDPSHUHV
)LJXUH%VKRZVDQH[DPSOHRIDWUDQVLVWRUFRQQHFWHGWRDQ$UGXLQRSLQXVHGWRGULYH
DPRWRU
7UDQVLVWRUGDWDVKHHWVDUHXVXDOO\SDFNHGZLWKLQIRUPDWLRQIRUWKHGHVLJQHQJLQHHUDQG
PRVW RI WKLV LV QRW UHOHYDQW IRU FKRRVLQJ WUDQVLVWRUV IRU $UGXLQR DSSOLFDWLRQV 7D
EOH%VKRZVWKHPRVWLPSRUWDQWSDUDPHWHUV\RXVKRXOGORRNIRU WKHYDOXHVVKRZQ
DUHIRUDW\SLFDOJHQHUDOSXUSRVHWUDQVLVWRU 0DQXIDFWXULQJWROHUDQFHVUHVXOWLQYDU\LQJ
SHUIRUPDQFHIURPGLIIHUHQWEDWFKHVRIWKHVDPHSDUWVRGDWDVKHHWVXVXDOO\LQGLFDWH
WKHPLQLPXPW\SLFDODQGPD[LPXPYDOXHVIRUSDUDPHWHUVWKDWFDQYDU\IURPSDUWWR
SDUW
+HUH¦VZKDWWRORRNIRU
&ROOHFWRUHPLWWHUYROWDJH
0DNHVXUHWKHWUDQVLVWRULVUDWHGWRRSHUDWHDWDYROWDJHKLJKHUWKDQWKHYROWDJHRI
WKHSRZHUVXSSO\IRUWKHFLUFXLWWKHWUDQVLVWRULVFRQWUROOLQJ7KHUHLVQRSUREOHP
LQFKRRVLQJDWUDQVLVWRUZLWKDKLJKHUUDWLQJ
&ROOHFWRUFXUUHQW
7KLVLVWKHDEVROXWHPD[LPXPFXUUHQWWKHWUDQVLVWRULVGHVLJQHGWRKDQGOH,WLVD
JRRGSUDFWLFHWRFKRRVHDWUDQVLVWRUWKDWLVUDWHGDWOHDVWSHUFHQWKLJKHUWKDQ
ZKDW\RXQHHG
'&FXUUHQWJDLQ
7KLVGHWHUPLQHVWKHDPRXQWRIFXUUHQWQHHGHGWRIORZWKURXJKWKHEDVHRIWKH
WUDQVLVWRUWRVZLWFKWKHRXWSXWFXUUHQW'LYLGLQJWKHRXWSXWFXUUHQW WKHPD[LPXP
FXUUHQWWKDWZLOOIORZWKURXJKWKHORDGWKHWUDQVLVWRULVVZLWFKLQJ E\WKHJDLQJLYHV
WKHDPRXQWRIFXUUHQWWKDWQHHGVWRIORZWKURXJKWKHEDVH
&ROOHFWRUHPLWWHUVDWXUDWLRQYROWDJH
7KLVLVWKHYROWDJHOHYHORQWKHFROOHFWRUZKHQWKHWUDQVLVWRULVIXOO\FRQGXFWLQJ
$OWKRXJKWKLVLVXVXDOO\OHVVWKDQYROWLWFDQEHVLJQLILFDQWZKHQFDOFXODWLQJD
VHULHVUHVLVWRUIRU/('VRUIRUGULYLQJKLJKFXUUHQWGHYLFHV
588 | Appendix B:ಗUsing Schematic Diagrams and Data Sheets
7DEOH%([DPSOHRINH\WUDQVLVWRUGDWDVKHHWVSHFLILFDWLRQV
Absolute maximum ratings
Parameter
Symbol
Rating
Units
Comment
Collector-emitter voltage
Vceo
40
Volts
The maximum voltage between the collector and
emitter
Collector current
Ic
600
mA or A
The maximum current that the transistor is designed
to handle
Ic
90 @ 10 mA
Gain with 10 mA current flowing
Ic
50 @ 500
mA
Gain with 500 mA current flowing
Vce
0.3 @ 100
mA
Electrical characteristics
DC current gain
Collector-emitter
saturation voltage
(sat)
Volts
Volts
Voltage drop across collector and emitter at various
currents
1.0 @ 500
mA
Choosing and Using Transistors for Switching | 589
APPENDIX C
Building and Connecting the Circuit
Using a Breadboard
$EUHDGERDUGHQDEOHV\RXWRSURWRW\SHFLUFXLWVTXLFNO\ZLWKRXWKDYLQJWRVROGHUWKH
FRQQHFWLRQV)LJXUH&VKRZVDQH[DPSOHRIDEUHDGERDUG
)LJXUH&%UHDGERDUGIRUSURWRW\SLQJFLUFXLWV
%UHDGERDUGVFRPHLQYDULRXVVL]HVDQGFRQILJXUDWLRQV7KHVLPSOHVWNLQGLVMXVWDJULG
RIKROHVLQDSODVWLFEORFN,QVLGHDUHVWULSVRIPHWDOWKDWSURYLGHHOHFWULFDOFRQQHFWLRQ
EHWZHHQKROHVLQWKHVKRUWHUURZV3XVKLQJWKHOHJVRIWZRGLIIHUHQWFRPSRQHQWVLQWR
WKHVDPHURZMRLQVWKHPWRJHWKHUHOHFWULFDOO\$GHHSFKDQQHOUXQQLQJGRZQWKHPLGGOH
LQGLFDWHVWKDWWKHUHLVDEUHDNLQFRQQHFWLRQVWKHUHPHDQLQJ\RXFDQSXVKDFKLSLQ
ZLWKWKHOHJVDWHLWKHUVLGHRIWKHFKDQQHOZLWKRXWFRQQHFWLQJWKHPWRJHWKHU
6RPHEUHDGERDUGVKDYHWZRVWULSVRIKROHVUXQQLQJDORQJWKHORQJHGJHVRIWKHERDUG
WKDWDUHVHSDUDWHGIURPWKHPDLQJULG7KHVHKDYHVWULSVUXQQLQJGRZQWKHOHQJWKRI
WKHERDUGLQVLGHDQGSURYLGHDZD\WRFRQQHFWDFRPPRQYROWDJH7KH\DUHXVXDOO\LQ
SDLUVIRUYROWVDQGJURXQG7KHVHVWULSVDUHUHIHUUHGWRDVUDLOVDQGWKH\HQDEOH\RX
WRFRQQHFWSRZHUWRPDQ\FRPSRQHQWVRUSRLQWVLQWKHERDUG
591
Download from Wow! eBook <www.wowebook.com>
:KLOHEUHDGERDUGVDUHJUHDWIRUSURWRW\SLQJWKH\KDYHVRPHOLPLWDWLRQV%HFDXVHWKH
FRQQHFWLRQV DUH SXVKILW DQG WHPSRUDU\ WKH\ DUH QRW DV UHOLDEOH DV VROGHUHG
FRQQHFWLRQV,I\RXDUHKDYLQJLQWHUPLWWHQWSUREOHPVZLWKDFLUFXLWLWFRXOGEHGXHWR
DSRRUFRQQHFWLRQRQDEUHDGERDUG
Connecting and Using External Power Supplies and Batteries
7KH$UGXLQRFDQEHSRZHUHGIURPDQH[WHUQDOSRZHUVRXUFHUDWKHUWKDQWKURXJKWKH
86% OHDG <RX PD\ QHHG PRUH FXUUHQW WKDQ WKH 86% FRQQHFWLRQ FDQ SURYLGH WKH
PD[LPXP86%FXUUHQWLVP$VRPH86%KXEVRQO\VXSSO\P$ RU\RXPD\
ZDQWWRUXQWKHERDUGZLWKRXWFRQQHFWLRQWRWKHFRPSXWHUDIWHUWKHVNHWFKLVXSORDGHG
7KHVWDQGDUG$UGXLQRERDUGKDVDVRFNHWIRUFRQQHFWLQJH[WHUQDOSRZHU7KLVFDQEH
DQ$&SRZHUHGSRZHUVXSSO\RUDEDWWHU\SDFN
7KHVHGHWDLOVUHODWHWRWKH8QR'XHPLODQRYHDQG0HJDERDUGV2WKHU
$UGXLQRDQGFRPSDWLEOHERDUGVPD\QRWSURWHFWWKHERDUGIURPUHYHUVH
FRQQHFWLRQVRUWKH\PD\DXWRPDWLFDOO\VZLWFKWRXVHH[WHUQDOSRZHU
DQGPD\QRWDFFHSWKLJKHUYROWDJHV,I\RXDUHXVLQJDGLIIHUHQWERDUG
FKHFNEHIRUH\RXFRQQHFWSRZHURU\RXPD\GDPDJHWKHERDUG
,I\RXDUHXVLQJDQ$&SRZHUVXSSO\\RXQHHGRQHWKDWSURGXFHVD'&YROWDJHEHWZHHQ
DQGYROWV&KRRVHDSRZHUVXSSO\WKDWSURYLGHVDWOHDVWDVPXFKFXUUHQWDV\RX
QHHG WKHUHLVQRSUREOHPLQXVLQJDSRZHUVXSSO\ZLWKDKLJKHUFXUUHQWWKDQ\RXQHHG :DOOZDUW¡VW\OHSRZHUVXSSOLHVFRPHLQWZREURDGW\SHVUHJXODWHGDQGXQUHJXODWHG
$UHJXODWHGSRZHUVXSSO\KDVDFLUFXLWWKDWPDLQWDLQVWKHVSHFLILHGYROWDJHDQGWKLVLV
DJRRGFKRLFHWRXVHZLWK$UGXLQR$QXQUHJXODWHGSRZHUVXSSO\ZLOOSURGXFHDKLJKHU
YROWDJHZKHQUXQDWDORZHUFXUUHQWDQGFDQVRPHWLPHVSURGXFHWZLFHWKHUDWHGYROWDJH
ZKHQGULYLQJORZFXUUHQWGHYLFHVVXFKDV$UGXLQR9ROWDJHVKLJKHUWKDQYROWVFDQ
RYHUKHDWWKHUHJXODWRURQWKH$UGXLQRDQGWKLVFDQFDXVHLQWHUPLWWHQWRSHUDWLRQRU
HYHQGDPDJHWKHERDUG
%DWWHU\YROWDJHVKRXOGDOVREHLQWKHUDQJHRIWRYROWV%DWWHU\FXUUHQWLVUDWHGLQ
P$K WKHDPRXQWRIPLOOLDPSHUHVWKHEDWWHU\FDQVXSSO\LQRQHKRXU $EDWWHU\ZLWK
DUDWLQJRIP$K DW\SLFDODONDOLQH9EDWWHU\ VKRXOGODVWDURXQGKRXUVZLWK
DQ$UGXLQRERDUGGUDZLQJP$K,I\RXUSURMHFWGUDZVP$WKHEDWWHU\OLIHZLOO
EHKDOYHGWRDURXQGKRXUV+RZPXFKFXUUHQW\RXUERDUGXVHVGHSHQGVPRVWO\RQ
WKHGHYLFHV VXFKDV/('VDQGRWKHUH[WHUQDOFRPSRQHQWV WKDW\RXXVH%HDULQPLQG
WKDWWKH8QRDQG'XHPLODQRYHERDUGVDUHGHVLJQHGWREHHDV\WRXVHDQGUREXVWEXW
WKH\DUHQRWRSWLPL]HGIRUORZSRZHUXVHZLWKDEDWWHU\6HH5HFLSHIRUDGYLFH
RQUHGXFLQJEDWWHU\GUDLQ
592 | Appendix C:ಗBuilding and Connecting the Circuit
7KHSRVLWLYH FRQQHFWLRQIURPWKHSRZHUVXSSO\VKRXOGEHFRQQHFWHGWRWKHFHQWHU
SLQRIWKH$UGXLQRSRZHUSOXJ,I\RXFRQQHFWLWWKHZURQJZD\DURXQGRQDQ8QR
'XHPLODQRYHRU0HJDWKHERDUGZLOOQRWEUHDNEXWLWZLOOQRWZRUNXQWLOWKHFRQ
QHFWLRQLVUHYHUVHG7KHVHERDUGVDXWRPDWLFDOO\GHWHFWWKDWDQH[WHUQDOSRZHUVXSSO\
LVFRQQHFWHGDQGXVHWKDWWRSRZHUWKHERDUG<RXFDQVWLOOKDYHWKH86%OHDGSOXJJHG
LQVRVHULDOFRPPXQLFDWLRQDQGFRGHXSORDGLQJZLOOVWLOOZRUN
Using Capacitors for Decoupling
'LJLWDOFLUFXLWVVZLWFKVLJQDOVRQDQGRIITXLFNO\DQGWKLVFDQFDXVHIOXFWXDWLRQVLQWKH
SRZHUVXSSO\YROWDJHWKDWFDQGLVUXSWSURSHURSHUDWLRQRIWKHFLUFXLW3URSHUO\GHVLJQHG
GLJLWDOFLUFXLWVXVHGHFRXSOLQJFDSDFLWRUVWRILOWHUWKHVHIOXFWXDWLRQV'HFRXSOLQJFD
SDFLWRUVVKRXOGEHFRQQHFWHGDFURVVWKHSRZHUSLQVRIHDFK,&LQ\RXUFLUFXLWZLWKWKH
FDSDFLWRUOHDGVNHSWDVVKRUWDVSRVVLEOH$FHUDPLFFDSDFLWRURIX)LVDJRRGFKRLFH
IRUGHFRXSOLQJ¢WKDWYDOXHLVQRWFULWLFDO SHUFHQWWROHUDQFHLV2. Using Snubber Diodes with Inductive Loads
,QGXFWLYHORDGVDUHGHYLFHVWKDWKDYHDFRLORIZLUHLQVLGH7KLVLQFOXGHVPRWRUVVROH
QRLGVDQGUHOD\V7KHLQWHUUXSWLRQRIFXUUHQWIORZLQDFRLORIZLUHJHQHUDWHVDVSLNHRI
HOHFWULFLW\7KLVYROWDJHFDQEHKLJKHUWKDQYROWVDQGFDQGDPDJHVHQVLWLYHHOHFWURQLF
FLUFXLWVVXFKDV$UGXLQRSLQV6QXEEHUGLRGHVDUHXVHGWRSUHYHQWWKDWE\FRQGXFWLQJ
WKHYROWDJHVSLNHVWRJURXQG)LJXUH$LQ$SSHQGL[$VKRZVDQH[DPSOHRIDVQXEEHU
GLRGHXVHGWRVXSSUHVVYROWDJHVSLNHVZKHQGULYLQJDPRWRU
Working with AC Line Voltages
:KHQZRUNLQJZLWKDQ$&OLQHYROWDJHIURPDZDOOVRFNHWWKHILUVWWKLQJ\RXVKRXOG
FRQVLGHU LV ZKHWKHU \RX FDQ DYRLG ZRUNLQJ ZLWK LW (OHFWULFLW\ DW WKLV YROWDJH LV
GDQJHURXVHQRXJKWRNLOO\RXQRWMXVW\RXUFLUFXLWLILWLVXVHGLQFRUUHFWO\,WLVDOVR
GDQJHURXVIRUSHRSOHXVLQJZKDWHYHU\RXKDYHPDGHLIWKH$&OLQHYROWDJHLVQRWLVRODWHG
SURSHUO\
+DFNLQJFRQWUROOHUVIRUGHYLFHVWKDWDUHPDQXIDFWXUHGWRZRUNZLWKPDLQVYROWDJHRU
XVLQJGHYLFHVGHVLJQHGWREHXVHGZLWKPLFURFRQWUROOHUVWRFRQWURO$&OLQHYROWDJHVLV
VDIHU DQG RIWHQ HDVLHU WKDQ ZRUNLQJ ZLWK PDLQV YROWDJH LWVHOI 6HH &KDSWHU IRU
UHFLSHVRQFRQWUROOLQJH[WHUQDOGHYLFHVIRUH[DPSOHVRIKRZWRGRWKLV
Working with AC Line Voltages | 593
APPENDIX D
Tips on Troubleshooting
Software Problems
$V\RXZULWHDQGPRGLI\FRGH\RXZLOOJHWFRGHWKDWGRHVQ¦WZRUN XVXDOO\UHIHUUHGWR
DVDEXJ 7KHUHDUHWZREURDGDUHDVRIVRIWZDUHSUREOHPVFRGHWKDWZRQ¦WFRPSLOH
DQGFRGHWKDWFRPSLOHVDQGXSORDGVWRWKHERDUGEXWGRHVQ¦WEHKDYHDV\RXZDQW
Code That Won’t Compile
<RXUFRGHPLJKWIDLOWRFRPSLOHZKHQ\RXFOLFNRQWKH£YHULI\¤WULDQJOHRUWKH£XSORDG¤
EXWWRQ VHH&KDSWHU 7KLVLVLQGLFDWHGE\UHGHUURUPHVVDJHVLQWKHEODFNFRQVROH
DUHDDWWKHERWWRPRIWKH$UGXLQRVRIWZDUHZLQGRZDQGD\HOORZKLJKOLJKWLQWKHFRGH
LIWKHUHLVDVSHFLILFSRLQWZKHUHWKHFRPSLODWLRQIDLOHG2IWHQWKHSUREOHPLQWKHFRGH
LVLQWKHOLQHLPPHGLDWHO\EHIRUHWKHKLJKOLJKWHGOLQH7KHHUURUPHVVDJHVLQWKHFRQVROH
ZLQGRZDUHJHQHUDWHGE\WKHFRPPDQGOLQHSURJUDPVXVHGWRFRPSLOHDQGOLQNWKH
FRGH VHH5HFLSHIRUGHWDLOVRQWKHEXLOGSURFHVV 7KLVPHVVDJHPD\EHGLIILFXOW
WRXQGHUVWDQGZKHQ\RXILUVWVWDUW
2QH RI WKH PRVW FRPPRQ HUURUV PDGH E\ SHRSOH QHZ WR $UGXLQR SURJUDPPLQJ LV
RPLVVLRQRIWKHVHPLFRORQDWWKHHQGRIDOLQH7KLVFDQSURGXFHYDULRXVGLIIHUHQWHUURU
PHVVDJHVGHSHQGLQJRQWKHQH[WOLQH)RUH[DPSOHWKLVFRGHIUDJPHQW
void loop()
{
digitalWrite(ledPin, HIGH)
delay(1000);
}
// <- ERROR: missing semicolon
SURGXFHVWKHIROORZLQJHUURUPHVVDJH
In function 'void loop()':
error: expected `;' before 'delay
$OHVVREYLRXVHUURUPHVVDJHLV
expected unqualified-id before numeric constant
595
$OWKRXJKWKHFDXVHLVVLPLODUDPLVVLQJVHPLFRORQDIWHUDFRQVWDQWUHVXOWVLQDGLIIHUHQW
HUURUPHVVDJHDVLQWKLVIUDJPHQW
const int ledPin =
13
// <- ERROR: missing semicolon after constant
7KHFRPELQDWLRQRIWKHHUURUPHVVDJHDQGWKHOLQHKLJKOLJKWLQJSURYLGHVDJRRGVWDUWLQJ
SRLQWIRUFORVHUH[DPLQDWLRQRIWKHDUHDZKHUHWKHHUURUKDVRFFXUUHG
$QRWKHUFRPPRQHUURULVPLVVSHOOHGZRUGVUHVXOWLQJLQWKHZRUGVQRWEHLQJUHFRJ
QL]HG 7KLV LQFOXGHV LQFRUUHFW FDSLWDOL]DWLRQ¢LedPin LV GLIIHUHQW IURP ledPin 7KLV
IUDJPHQW
const int ledPin =
13
digitalWrite(LedPin, HIGH);
// <- ERROR: the capitalization is different
UHVXOWVLQWKHIROORZLQJHUURUPHVVDJH
In function 'void loop()':
error: 'LedPin' was not declared in this scope
7KHIL[LVWRXVHH[DFWO\WKHVDPHVSHOOLQJDQGFDSLWDOL]DWLRQDVWKHYDULDEOHGHFODUDWLRQ
<RXPXVWXVHWKHFRUUHFWQXPEHUDQGW\SHRISDUDPHWHUVIRUIXQFWLRQFDOOV VHH5HF
LSH 7KHIROORZLQJIUDJPHQW
digitalWrite(ledPin);
// <- ERROR: this is missing the second parameter
JHQHUDWHVWKLVHUURUPHVVDJH
error: too few arguments to function 'void digitalWrite(uint8_t, uint8_t)'
error: at this point in file
7KHFXUVRULQWKH,'(ZLOOSRLQWWRWKHOLQHLQWKHVNHWFKWKDWFRQWDLQVWKHHUURU
)XQFWLRQV LQ VNHWFKHV WKDW DUH PLVVLQJ WKH UHWXUQ W\SH ZLOO JHQHUDWH DQ HUURU
7KLVIUDJPHQW
loop()
{
}
// <- ERROR: loop is missing the return type
SURGXFHVWKLVHUURU
error: ISO C++ forbids declaration of 'loop' with no type
7KHHUURULVIL[HGE\DGGLQJWKHPLVVLQJUHWXUQW\SH
void loop()
{
}
// <- return type precedes function name
,QFRUUHFWO\IRUPHGFRPPHQWVVXFKDVWKLVIUDJPHQWWKDWLVPLVVLQJWKHVHFRQG£¤
digitalWrite(ledPin, HIGH);
/ set the LED on (ERROR: missing //)
UHVXOWLQWKLVHUURU
error: expected primary-expression before '/' token
596 | Appendix D:ಗTips on Troubleshooting Software Problems
,WLVJRRGWRZRUNRQDVPDOODUHDRIFRGHDQGUHJXODUO\YHULI\FRPSLOHWRFKHFNWKH
FRGH<RXGRQ¦WQHHGWRXSORDGWRFKHFNWKDWWKHVNHWFKFRPSLOHV7KHHDUOLHU\RX
EHFRPHDZDUHRIDSUREOHPWKHHDVLHULWLVWRIL[LWDQGWKHOHVVLPSDFWLWZLOOKDYHRQ
RWKHUFRGH,WLVPXFKHDVLHUWRIL[FRGHWKDWKDVRQHSUREOHPWKDQLWLVWRIL[DODUJH
VHFWLRQRIFRGHWKDWKDVPXOWLSOHHUURUVLQLW
Code That Compiles but Does Not Work As Expected
7KHUH LV DOZD\V D IHHOLQJ RI DFFRPSOLVKPHQW ZKHQ \RX JHW \RXU VNHWFK WR FRPSLOH
ZLWKRXWHUURUVEXWFRUUHFWV\QWD[GRHVQRWPHDQWKHFRGHZLOOGRZKDW\RXH[SHFW
7KLVLVXVXDOO\DVXEWOHUSUREOHPWRLVRODWH<RXDUHQRZLQDZRUOGZKHUHVRIWZDUHDQG
KDUGZDUHDUHLQWHUDFWLQJ,WLVLPSRUWDQWWRWU\WRVHSDUDWHSUREOHPVLQKDUGZDUHIURP
WKRVHLQVRIWZDUH&DUHIXOO\FKHFNWKHKDUGZDUH VHH$SSHQGL[( WRPDNHVXUHLWLV
ZRUNLQJFRUUHFWO\
,I\RXDUHVXUHWKHKDUGZDUHLVZLUHGDQGZRUNLQJFRUUHFWO\WKHILUVWVWHSLQGHEXJJLQJ
\RXUVNHWFKLVWRFDUHIXOO\UHDGWKURXJK\RXUFRGHWRUHYLHZWKHORJLF\RXXVHG3DXVLQJ
WRWKLQNFDUHIXOO\DERXWZKDW\RXKDYHZULWWHQLVXVXDOO\DIDVWHUDQGPRUHSURGXFWLYH
ZD\WRIL[SUREOHPVWKDQGLYLQJLQDQGDGGLQJGHEXJJLQJFRGH,WFDQEHGLIILFXOWWR
VHHIDXOW\UHDVRQLQJLQFRGH\RXKDYHMXVWZULWWHQ:DONLQJDZD\IURPWKHFRPSXWHU
QRWRQO\KHOSVSUHYHQWUHSHWLWLYHVWUDLQLQMXU\EXWLWDOVRUHIUHVKHV\RXUWURXEOHVKRRWLQJ
DELOLWLHV2Q\RXUUHWXUQ\RXZLOOEHORRNLQJDWWKHFRGHDIUHVKDQGLWLVYHU\FRPPRQ
IRUWKHFDXVHRIWKHHUURUWRMXPSRXWDW\RXZKHUH\RXFRXOGQRWVHHLWEHIRUH
,IWKLVGRHVQRWZRUNPRYHRQWRWKHQH[WWHFKQLTXHXVHWKH6HULDO0RQLWRUWRZDWFK
KRZWKHYDOXHVLQ\RXUVNHWFKDUHFKDQJHGZKHQWKHSURJUDPUXQVDQGZKHWKHUFRQ
GLWLRQDOVHFWLRQVRIFRGHUXQ&KDSWHUH[SODLQVKRZWRXVH$UGXLQRVHULDOSULQWVWDWH
PHQWVWRGLVSOD\YDOXHVRQ\RXUFRPSXWHU
7RWURXEOHVKRRW\RXQHHGWRILQGRXWZKDWLVDFWXDOO\KDSSHQLQJZKHQWKHFRGHUXQV
Serial.print()OLQHVLQ\RXUVNHWFKFDQGLVSOD\ZKDWSDUWRIWKHFRGHLVUXQQLQJDQG
WKHYDOXHVRI\RXUYDULDEOHV7KHVHVWDWHPHQWVDUHWHPSRUDU\DQGZLOOEHUHPRYHGRQFH
\RXKDYHIL[HG\RXUSUREOHP7KHIROORZLQJVNHWFKUHDGVDQDQDORJYDOXHDQGLVEDVHG
RQWKHVROXWLRQIURP5HFLSH7KHVNHWFKVKRXOGFKDQJHWKHEOLQNUDWHEDVHGRQWKH
VHWWLQJRIDYDULDEOHUHVLVWRU VHHWKH'LVFXVVLRQIRU5HFLSHIRUPRUHGHWDLOVRQKRZ
WKLVZRUNV ,IWKHVNHWFKGRHVQRWIXQFWLRQDVH[SHFWHG\RXFDQVHHLIWKHVRIWZDUHLV
ZRUNLQJFRUUHFWO\E\XVLQJDserial.print()VWDWHPHQWWRGLVSOD\WKHYDOXHUHDGIURP
WKHDQDORJSLQ
const int potPin = 0;
const int ledPin = 13;
int val = 0;
void setup()
Code That Compiles but Does Not Work As Expected | 597
{
Serial.begin(9600);
// <- add this to initialize Serial
pinMode(ledPin, OUTPUT);
}
void loop() {
val = analogRead(potPin);
Serial.println(val);
digitalWrite(ledPin, HIGH);
delay(val);
digitalWrite(ledPin, LOW);
delay(val);
}
// read the voltage on the pot
// <- add this to display the reading
,IWKHYDOXHGLVSOD\HGRQWKH6HULDO0RQLWRUGRHVQRWYDU\IURPWRZKHQWKHSRW
YDULDEOHUHVLVWRU LVFKDQJHG\RXSUREDEO\KDYHDKDUGZDUHSUREOHP¢WKHSRWPD\EH
IDXOW\RUQRWZLUHGFRUUHFWO\,IWKHYDOXHGRHVFKDQJHEXWWKH/('GRHVQRWEOLQNWKH
/('PD\QRWEHZLUHGFRUUHFWO\
Troubleshooting Interrelated Hardware/Software Problems
6RPHSUREOHPVDUHQRWGXHVWULFWO\WRVRIWZDUHRUKDUGZDUHHUURUVEXWWRWKHLQWHUSOD\
EHWZHHQWKHP
7KHPRVWFRPPRQRIWKHVHLVFRQQHFWLQJWKHFLUFXLWWRRQHSLQDQGLQVRIWZDUHUHDGLQJ
RUZULWLQJDGLIIHUHQWSLQ+DUGZDUHDQGVRIWZDUHDUHERWKFRUUHFWLQLVRODWLRQ¢EXW
WRJHWKHUWKH\GRQ¦WZRUN<RXFDQFKDQJHHLWKHUWKHKDUGZDUHRUWKHVRIWZDUHWRIL[
WKLVFKDQJHWKHSLQLQVRIWZDUHRUPRYHWKHFRQQHFWLRQWRWKHSLQQXPEHUGHFODUHGLQ
\RXUVNHWFK
598 | Appendix D:ಗTips on Troubleshooting Software Problems
APPENDIX E
Tips on Troubleshooting
Hardware Problems
+DUGZDUH SUREOHPV FDQ KDYH PRUH LPPHGLDWH VHULRXV UDPLILFDWLRQV WKDQ VRIWZDUH
SUREOHPVEHFDXVHLQFRUUHFWZLULQJFDQGDPDJHFRPSRQHQWV7KHPRVWLPSRUWDQWWLS
LVDOZD\VGLVFRQQHFWSRZHUZKHQPDNLQJRUFKDQJLQJFRQQHFWLRQVDQGGRXEOHFKHFN\RXU
ZRUNEHIRUHFRQQHFWLQJSRZHU
8QSOXJ$UGXLQRIURPSRZHUZKLOHEXLOGLQJDQGPRGLI\LQJFLUFXLWV
$SSO\LQJSRZHULVWKHODVWWKLQJ\RXGRWRWHVWDFLUFXLWQRWWKHILUVW
)RUDFRPSOLFDWHGFLUFXLWEXLOGLWDELWDWDWLPH2IWHQDFRPSOLFDWHGFLUFXLWFRQVLVWV
RIDQXPEHURIVHSDUDWHFLUFXLWHOHPHQWVHDFKFRQQHFWHGWRDSLQRQWKH$UGXLQR,I
WKLVLVWKHFDVHEXLOGRQHELWDQGWHVWLWWKHQWKHRWKHUELWVRQHDWDWLPH,I\RXFDQ
WHVWHDFKHOHPHQWXVLQJDNQRZQZRUNLQJVNHWFKVXFKDVRQHRIWKHH[DPSOHVNHWFKHV
VXSSOLHGZLWK$UGXLQRRURQWKH$UGXLQR3OD\JURXQG,WXVXDOO\WDNHVPXFKOHVVWLPH
JHWWLQJDFRPSOH[SURMHFWZRUNLQJLI\RXWHVWHDFKHOHPHQWVHSDUDWHO\
)RUVRPHRIWKHWHFKQLTXHVLQWKLVDSSHQGL[\RXZLOOQHHGDPXOWLPHWHU DQ\LQH[SHQ
VLYHGLJLWDOPHWHUWKDWFDQUHDGYROWVFXUUHQWDQGUHVLVWDQFHVKRXOGEHVXLWDEOH 7KHPRVWHIIHFWLYHWHVWLVWRFDUHIXOO\LQVSHFWWKHZLULQJDQGFKHFNWKDWLWPDWFKHVWKH
FLUFXLW\RXDUHWU\LQJWREXLOG7DNHSDUWLFXODUFDUHWKDWSRZHUFRQQHFWLRQVDUHWKH
FRUUHFWZD\DURXQGDQGWKHUHDUHQRVKRUWFLUFXLWVYROWVDFFLGHQWDOO\FRQQHFWHGWR
YROWVRUOHJVRIFRPSRQHQWVWRXFKLQJZKHUHWKH\VKRXOGQRW,I\RXDUHXQVXUHKRZ
PXFKFXUUHQWDGHYLFHFRQQHFWHGWRDQ$UGXLQRSLQZLOOGUDZWHVWLWZLWKDPXOWLPHWHU
EHIRUHFRQQHFWLQJLWWRDSLQ,IWKHFLUFXLWGUDZVPRUHWKDQP$WKHSLQRQWKH
$UGXLQRFDQJHWGDPDJHG
599
<RXFDQILQGDYLGHRWXWRULDODQG3')H[SODLQLQJKRZWRXVHDPXOWLPHWHUDWKWWSEORJ
PDNH]LQHFRPDUFKLYHPXOWLPHWHUBWXWRULDOBPDNHBKWPO
<RXPD\EHDEOHWRWHVWRXWSXWFLUFXLWV /('VRUPRWRUV E\FRQQHFWLQJWRWKHSRVLWLYH
SRZHUVXSSO\LQVWHDGRIWKH$UGXLQRSLQ,IWKHGHYLFHGRHVQRWIXQFWLRQLWPD\EH
IDXOW\RUQRWZLUHGFRUUHFWO\
,IWKHGHYLFHWHVWV2.EXWZKHQ\RXFRQQHFWWRWKHSLQDQGUXQWKHFRGH\RXGRQ¦WJHW
WKHH[SHFWHGEHKDYLRUWKHSLQPLJKWEHGDPDJHGRUWKHSUREOHPLVLQVRIWZDUH
7RWHVWDGLJLWDORXWSXWSLQKRRNXSDQ/('ZLWKDUHVLVWRU VHH&KDSWHU RUFRQQHFW
DPXOWLPHWHUWRUHDGWKHYROWDJHDQGUXQWKH%OLQNVNHWFKRQWKDWSLQ,IWKH/('GRHV
QRWIODVKRUGRHVQ¦WMXPSEHWZHHQYROWVDQGYROWVRQWKHPXOWLPHWHUWKHRXWSXW
SLQLVSUREDEO\GDPDJHG
7DNHFDUHWKDW\RXUZLULQJGRHVQRWDFFLGHQWDOO\FRQQHFWWKHSRZHUOLQHWRJURXQG,I
WKLVKDSSHQVRQDERDUGWKDWLVSRZHUHGIURP86%DOOWKHOLJKWVZLOOJRRXWDQGWKH
ERDUGZLOOEHFRPHXQUHVSRQVLYH7KHERDUGKDVDFRPSRQHQWFDOOHGDSRO\IXVHZKLFK
SURWHFWVWKHFRPSXWHUIURPH[FHVVLYHFXUUHQWEHLQJGUDZQIURPWKH86%SRUW,I\RX
GUDZWRRPXFKFXUUHQWLWZLOO£WULS¤DQGVZLWFKRIISRZHUWRWKHERDUG<RXFDQUHVHW
LWE\XQSOXJJLQJWKHERDUGIURPWKH86%KXE \RXPD\DOVRQHHGWRUHVWDUW\RXUFRP
SXWHU %HIRUHUHFRQQHFWLQJWKHSRZHUFKHFN\RXUFLUFXLWVWRILQGDQGIL[WKHIDXOW\
ZLULQJRWKHUZLVHWKHSRO\IXVHZLOOWULSDJDLQZKHQ\RXSOXJLWEDFNLQ
Still Stuck?
$IWHUWU\LQJHYHU\WKLQJ\RXFDQWKLQNRI\RXVWLOOPD\QRWEHDEOHWRJHW\RXUSURMHFW
WRZRUN,I\RXNQRZVRPHRQHZKRLVXVLQJ$UGXLQRRUVLPLODUERDUGV\RXFRXOGDVN
KLPIRUKHOS%XWLI\RXGRQ¦WXVHWKH,QWHUQHW¢SDUWLFXODUO\WKH$UGXLQRIRUXPVLWHDW
KWWSZZZDUGXLQRFF7KLVLVDSODFHZKHUHSHRSOHRIDOOH[SHULHQFHOHYHOVFDQDVN
TXHVWLRQVDQGVKDUHNQRZOHGJH8VHWKHIRUXPVHDUFKER[ LW¦VLQWKHWRSULJKWFRUQHU
WRWU\WRILQGLQIRUPDWLRQUHODWLQJWR\RXUSURMHFW$UHODWHGVLWHLVWKH$UGXLQR3OD\
JURXQGDZLNLIRUXVHUFRQWULEXWHGLQIRUPDWLRQDERXW$UGXLQR
,I D VHDUFK GRHVQ¦W \LHOG WKH LQIRUPDWLRQ \RX QHHG \RX FDQ SRVW D TXHVWLRQ WR WKH
$UGXLQRIRUXP7KHIRUXPLVYHU\DFWLYHDQGLI\RXDVN\RXUTXHVWLRQFOHDUO\\RXDUH
OLNHO\WRJHWDTXLFNDQVZHU
7RDVN\RXUTXHVWLRQZHOOLGHQWLI\ZKLFKIRUXPVHFWLRQWKHTXHVWLRQVKRXOGJRLQDQG
FKRRVHDWLWOHIRU\RXUWKUHDGWKDWUHIOHFWVWKHVSHFLILFSUREOHP\RXZDQWWRVROYH3RVW
LQRQO\RQHSODFH¢PRVWSHRSOHZKRDUHOLNHO\WRDQVZHUZLOOFKHFNDOOWKHVHFWLRQVWKDW
KDYHQHZSRVWVDQGPXOWLSOHSRVWVZLOOLUULWDWHSHRSOHDQGPDNHLWOHVVOLNHO\WKDW\RX
ZLOOJHWKHOS
600 | Appendix E:ಗTips on Troubleshooting Hardware Problems
([SODLQ\RXUSUREOHPDQGWKHVWHSV\RXKDYHWDNHQWRWU\WRIL[LW,W¦VEHWWHUWRGHVFULEH
ZKDWKDSSHQVWKDQWRH[SODLQZK\\RXWKLQNLWLVKDSSHQLQJ,QFOXGHDOOUHOHYDQWFRGH
EXWWU\WRSURGXFHDFRQFLVHWHVWVNHWFKWKDWGRHVQRWFRQWDLQFRGHWKDW\RXNQRZLV
QRWUHODWHGWRWKHSUREOHP,I\RXUSUREOHPUHODWHVWRDGHYLFHRUFRPSRQHQWWKDWLV
H[WHUQDOWRWKH$UGXLQRERDUGSRVWDOLQNWRWKHGDWDVKHHW,IWKHZLULQJLVFRPSOH[
SRVWDGLDJUDPRUSKRWRVKRZLQJKRZ\RXKDYHFRQQHFWHGWKLQJVXS
Still Stuck? | 601
APPENDIX F
Digital and Analog Pins
7DEOHV)DQG)VKRZWKHGLJLWDODQGDQDORJSLQVIRUDVWDQGDUG$UGXLQRERDUGDQG
WKH0HJDERDUG
7KH£3RUW¤FROXPQOLVWVWKHSK\VLFDOSRUWXVHGIRUWKHSLQ¢VHH5HFLSHIRULQ
IRUPDWLRQRQKRZWRVHWDSLQE\ZULWLQJGLUHFWO\WRDSRUW7KHLQWURGXFWLRQWR&KDS
WHUFRQWDLQVPRUHGHWDLOVRQWLPHUXVDJH
7DEOH)$QDORJDQGGLJLWDOSLQDVVLJQPHQWVFRPPRQWRSRSXODU$UGXLQRERDUGV
Arduino 168/328
Analog pin
Arduino Mega (pins 0–19)
Digital pin
Port
Usage
Port
0
PD 0
USART RX
PE 0
Analog pin
Usage
USART0 RX, Pin Int 8
1
PD 1
USART TX
PE 1
USART0 TX
2
PD 2
Ext Int 0
PE 4
PWM T3B, INT4
3
PD 3
PWM T2B, Ext Int 1
PE 5
PWM T3C, INT5
4
PD 4
PG 5
PWM T0B
5
PD 5
PWM T0B
PE 3
PWM T3A
6
PD 6
PWM T0A
PH 3
PWM T4A
7
PD 7
PH 4
PWM T4B
8
PB 0
Input capture
PH 5
PWM T4C
9
PB 1
PWM T1A
PH 6
PWM T2B
10
PB 2
PWM T1B, SS
PB 4
PWM T2A, Pin Int 4
11
PB 3
PWM T2A, MOSI
PB 5
PWM T1A, Pin Int 5
12
PB 4
SPI MISO
PB 6
PWM T1B, Pin Int 6
13
PB 5
SPI SCK
PB 7
PWM T0A, Pin Int 7
14
PC 0
0
PJ 1
USART3 TX, Pin Int 10
15
PC 1
1
PJ 0
USART3 RX, Pin Int 9
603
Arduino 168/328
Arduino Mega (pins 0–19)
Digital pin
Port
Analog pin
Usage
Port
Analog pin
Usage
16
PC 2
2
PH 1
USART2 TX
17
PC 3
3
PH 0
USART2 RX
18
PC 4
4
I2C SDA
PD 3
USART1 TX, Ext Int 3
19
PC 5
5
I2C SCL
PD 2
USART1 RX, Ext Int 2
7DEOH)$VVLJQPHQWVIRUDGGLWLRQDO0HJDSLQV
Arduino Mega (pins 20–44)
Arduino Mega (pins 45–69)
Digital pin
Port
Usage
Digital pin
Port
20
PD 1
I2C SDA, Ext Int 1
45
PL 4
PWM 5B
21
PD 0
I2C SCL, Ext Int 0
46
PL 3
PWM 5A
22
PA 0
Ext Memory addr bit 0
47
PL 2
T5 external counter
23
PA 1
Ext Memory bit 1
48
PL 1
ICP T5
24
PA 2
Ext Memory bit 2
49
PL 0
ICP T4
25
PA 3
Ext Memory bit 3
50
PB 3
SPI MISO
26
PA 4
Ext Memory bit 4
51
PB 2
SPI MOSI
27
PA 5
Ext Memory bit 5
52
PB 1
SPI SCK
28
PA 6
Ext Memory bit 6
53
PB 0
SPI SS
29
PA 7
Ext Memory bit 7
54
PF 0
0
30
PC 7
Ext Memory bit 15
55
PF 1
1
31
PC 6
Ext Memory bit 14
56
PF 2
2
32
PC 5
Ext Memory bit 13
57
PF 3
3
33
PC 4
Ext Memory bit 12
58
PF 4
4
34
PC 3
Ext Memory bit 11
59
PF 5
5
35
PC 2
Ext Memory bit 10
60
PF 6
6
36
PC 1
Ext Memory bit 9
61
PF 7
7
37
PC 0
Ext Memory bit 8
62
PK 0
8
Pin Int 16
38
PD 7
63
PK 1
9
Pin int 17
39
PG 2
ALE Ext Mem
64
PK 2
10
Pin Int 18
40
PG 1
RD Ext Mem
65
PK 3
11
Pin Int 19
41
PG 0
Wr Ext Mem
66
PK 4
12
Pin Int 20
42
PL 7
67
PK 5
13
Pin Int 21
43
PL 6
68
PK 6
14
Pin Int 22
44
PL 5
69
PK 7
15
Pin Int 23
PWM 5C
604 | Appendix F:ಗDigital and Analog Pins
Analog pin
Usage
7DEOH)LVDVXPPDU\RIWLPHUPRGHVVKRZLQJWKHSLQVXVHGZLWKSRSXODU$UGXLQR
FKLSV
7DEOH)7LPHUPRGHV
Timer
Arduino 168/328
Mega
Timer 0 mode (8-bit)
Fast PWM
Fast PWM
Timer0A analogWrite pin
Pin 6
Pin 13
Timer0B analogWrite pin
Pin 5
Pin 4
Timer 1 (16-bit)
Phase correct PWM
Phase correct PWM
Timer1A analogWrite pin
Pin 9
Pin 11
Timer1B analogWrite pin
Pin 10
Pin 12
Timer 2 (8-bit)
Phase correct PWM
Phase correct PWM
Timer2A analogWrite pin
Pin 11
Pin 10
Timer2B analogWrite pin
Pin 3
Pin 9
Timer 3 (16-bit)
N/A
Phase correct PWM
Timer3A analogWrite pin
Pin 5
Timer3B analogWrite pin
Pin 2
Timer3C analogWrite pin
Timer 4 (16-bit)
Pin 3
N/A
Phase correct PWM
Timer4A analogWrite pin
Pin 6
Timer4A analogWrite pin
Pin 7
Timer4A analogWrite pin
Pin 8
Timer 5 (16-bit)
N/A
Timer5A analogWrite pin
Pin 46
Timer5A analogWrite pin
Pin 45
Timer5A analogWrite pin
Pin 5
1RWHWKDWWKH$UGXLQRFROXPQLVIRUWKH$7PHJDDQGWKH0HJDFROXPQLVIRU
WKH$7PHJD
Digital and Analog Pins | 605
APPENDIX G
ASCII and Extended Character Sets
$6&,,VWDQGVIRU$PHULFDQ6WDQGDUG&RGHIRU,QIRUPDWLRQ,QWHUFKDQJH,WLVWKHPRVW
FRPPRQZD\RIUHSUHVHQWLQJOHWWHUVDQGQXPEHUVRQDFRPSXWHU(DFKFKDUDFWHULV
UHSUHVHQWHGE\DQXPEHU¢IRUH[DPSOHWKHOHWWHU$KDVWKHQXPHULFYDOXHDQGWKH
OHWWHUDKDVWKHQXPHULFYDOXH ORZHUFDVHOHWWHUVKDYHDYDOXHWKDWLVJUHDWHUWKDQ
WKHLUXSSHUFDVHYHUVLRQV 9DOXHVEHORZDUHFDOOHGFRQWUROFRGHV¢WKH\ZHUHGHILQHGDVQRQSULQWLQJFKDUDFWHUV
WR FRQWURO HDUO\ FRPSXWHU WHUPLQDO GHYLFHV 7KH PRVW FRPPRQ FRQWURO FRGHV IRU
$UGXLQRDSSOLFDWLRQVDUHOLVWHGLQ7DEOH*
7DEOH*&RPPRQ$6&,,FRQWUROFRGHV
Decimal
Hex
Escape code
Description
0
0x0
'\0'
Null character (used to terminate a C string)
9
0x9
'\t'
Tab
10
0xA
'\n'
New line
13
0xD
'\r'
Carriage return
27
0x1B
Escape
7DEOH*VKRZVWKHGHFLPDODQGKH[DGHFLPDOYDOXHVRIWKHSULQWDEOH$6&,,FKDUDFWHUV
7DEOH*$6&,,WDEOH
Dec
Hex
Dec
Hex
Space
32
20
!
33
"
#
Dec
Hex
@
64
40
`
96
60
21
A
65
41
a
97
61
34
22
B
35
23
C
66
42
b
98
62
67
43
c
99
63
$
36
24
D
68
44
d
100
64
%
37
25
E
69
45
e
101
65
607
Download from Wow! eBook <www.wowebook.com>
Dec
Hex
Dec
Hex
Dec
Hex
&
38
26
F
70
46
f
102
66
'
39
(
40
27
G
71
28
H
72
47
g
103
67
48
h
104
68
)
41
29
I
73
49
i
105
69
*
42
2A
J
74
4A
j
106
6A
+
43
2B
K
75
4B
k
107
6B
,
44
2C
L
76
4C
l
108
6C
-
45
2D
M
77
4D
m
109
6D
.
46
2E
N
78
4E
n
110
6E
/
47
2F
O
79
4F
o
111
6F
0
48
30
P
80
50
p
112
70
1
49
31
Q
81
51
q
113
71
2
50
32
R
82
52
r
114
72
3
51
33
S
83
53
s
115
73
4
52
34
T
84
54
t
116
74
5
53
35
U
85
55
u
117
75
6
54
36
V
86
56
v
118
76
7
55
37
W
87
57
w
119
77
8
56
38
X
88
58
x
120
78
9
57
39
Y
89
59
y
121
79
:
58
3A
Z
90
5A
z
122
7A
;
59
3B
[
91
5B
{
123
7B
<
60
3C
\
92
5C
|
124
7C
=
61
3D
]
93
5D
}
125
7D
>
62
3E
^
94
5E
~
126
7E
?
63
3F
_
95
5F
&KDUDFWHUVDERYHDUHQRQ(QJOLVKFKDUDFWHUVRUVSHFLDOV\PEROVDQGDUHGLVSOD\HG
LQWKH6HULDO0RQLWRUXVLQJWKH87)VWDQGDUG KWWSHQZLNLSHGLDRUJZLNL87) 7DEOH*OLVWVWKH87)H[WHQGHGFKDUDFWHUVHW
608 | Appendix G:ಗASCII and Extended Character Sets
7DEOH*87)H[WHQGHGFKDUDFWHUV
Dec
Hex
Dec
Hex
Dec
Hex
Space
160
A0
À
192
C0
à
224
E0
¡
161
A1
Á
193
C1
á
225
E1
¢
162
A2
Â
194
C2
â
226
E2
£
163
A3
Ã
195
C3
ã
227
E3
¤
164
¥
165
A4
Ä
196
C4
ä
228
E4
A5
Å
197
C5
å
229
E5
¦
166
A6
Æ
198
C6
æ
230
E6
§
167
A7
Ç
199
C7
ç
231
E7
¨
168
A8
È
200
C8
è
232
E8
©
169
A9
É
201
C9
é
233
E9
ª
170
AA
Ê
202
CA
ê
234
EA
«
171
AB
Ë
203
CB
ë
235
EB
¬
172
AC
Ì
204
CC
ì
236
EC
173
AD
Í
205
CD
í
237
ED
®
174
AE
Î
206
CE
î
238
EE
¯
175
AF
Ï
207
CF
ï
239
EF
°
176
B0
Ð
208
D0
ð
240
F0
±
177
B1
Ñ
209
D1
ñ
241
F1
2
178
B2
Ò
210
D2
ò
242
F2
3
179
B3
Ó
211
D3
ó
243
F3
´
180
B4
Ô
212
D4
ô
244
F4
µ
181
B5
Õ
213
D5
õ
245
F5
¶
182
B6
Ö
214
D6
ö
246
F6
·
183
B7
×
215
D7
÷
247
F7
¸
184
B8
Ø
216
D8
ø
248
F8
1
185
B9
Ù
217
D9
ù
249
F9
º
186
BA
Ú
218
DA
ú
250
FA
»
187
BB
Û
219
DB
û
251
FB
¼
188
BC
Ü
220
DC
ü
252
FC
½
189
BD
Ý
221
DD
ý
253
FD
¾
190
BE
Þ
222
DE
þ
254
FE
¿
191
BF
ß
223
DF
ÿ
255
FF
ASCII and Extended Character Sets | 609
<RXFDQYLHZWKHHQWLUHFKDUDFWHUVHWLQWKH6HULDO0RQLWRUXVLQJWKLVVNHWFK
/*
* display characters from 1 to 255
*/
void setup()
{
Serial.begin(9600);
for(int i=1; i < 256; i++)
{
Serial.print(i, BYTE);
Serial.print(", dec: ");
Serial.print(i,DEC);
Serial.print(", hex: ");
Serial.println(i, HEX);
}
}
void loop()
{
}
1RWH WKDW VRPH GHYLFHV VXFK DV /&' GLVSOD\V VHH &KDSWHU PD\ XVH GLIIHUHQW
V\PEROVIRUWKHFKDUDFWHUVDERYHVRFKHFNWKHGDWDVKHHWIRU\RXUGHYLFHWRVHHWKH
DFWXDOFKDUDFWHUVXSSRUWHG
610 | Appendix G:ಗASCII and Extended Character Sets
Index
Symbols
A
QRW RSHUDWRU
QRWHTXDOWR RSHUDWRU
PRGXOXV RSHUDWRU
DPSHUVDQG ELWZLVH$1' RSHUDWRU
ORJLFDO$1' RSHUDWRU
RSHUDWRU
PXOWLSOLFDWLRQ RSHUDWRU
RSHUDWRU
DGGLWLRQ RSHUDWRU
VWULQJRSHUDWRU
RSHUDWRU
VXEWUDFWLRQ RSHUDWRU
RSHUDWRU
GLYLVLRQ RSHUDWRU
RSHUDWRU
OHVVWKDQ RSHUDWRU
ELWVKLIWOHIW RSHUDWRU
RSHUDWRU
OHVVWKDQRUHTXDOWR RSHUDWRU
! DQJOHEUDFNHWV DVVLJQPHQW RSHUDWRU
HTXDOWR RSHUDWRU
! JUHDWHUWKDQ RSHUDWRU
! JUHDWHUWKDQRUHTXDOWR RSHUDWRU
!! ELWVKLIWULJKW RSHUDWRU
!! RSHUDWRU
A ELWZLVHH[FOXVLYH25 RSHUDWRU
^` FXUO\EUDFNHWV _ ELWZLVH25 RSHUDWRU
_ RSHUDWRU
__ ORJLFDO25 RSHUDWRU
a ELWZLVHQHJDWLRQ RSHUDWRU
DEVIXQFWLRQ
DEVROXWHYDOXHRIQXPEHUV
$&OLQHYROWDJH
FRQWUROOLQJGHYLFHV¡
ZRUNLQJZLWK
DFFHOVNHWFK
DFFHOHUDWLRQUHDGLQJ
DFFHOHURPHWHU:LLQXQFKXFN¡
DFWLRQV
EDVHGRQFRQGLWLRQV
EDVHGRQYDULDEOHV¡
DFWXDWRUVDFWLYDWLQJ¡
$GDIUXLW,QGXVWULHV
%RDUGXLQRERDUG
ZDYHVKLHOG¡
;%HH$GDSWHU
$'& DQDORJWRGLJLWDOFRQYHUWHU VHHDOVRDQDORJ5HDGIXQFWLRQ
$'&65$UHJLVWHU
DGGLWLRQ RSHUDWRU
$GMXVW&ORFN7LPHVNHWFK
DODUPV
FDOOLQJIXQFWLRQZLWK¡
FUHDWLQJ¡
$OOHQ&KDUOLH
DPSHUVDQG
DPSOLWXGHGHILQHG
DQDORJSDQHOPHWHUV¡
DQDORJSLQV
VHHDOVRGLJLWDO5HDGIXQFWLRQ
DERXW
DGMXVWLQJ/('EULJKWQHVV¡
FKDQJLQJUDQJHRIYDOXHV
:H¦GOLNHWRKHDU\RXUVXJJHVWLRQVIRULPSURYLQJRXULQGH[HV6HQGHPDLOWRLQGH[#RUHLOO\FRP
611
FRPPRQSLQDVVLJQPHQWV¡
GHWHFWLQJLQSXW
GHWHFWLQJURWDWLRQXVLQJJ\URVFRSH¡
GLVSOD\LQJYROWDJHV¡
LQFUHDVLQJQXPEHURIRXWSXWV¡
PHDVXULQJGLVWDQFH
PHDVXULQJWHPSHUDWXUH
PHDVXULQJYDOXHVTXLFNO\¡
PHDVXULQJYROWDJH¡
SLQDUUDQJHPHQWV
UHDGLQJPXOWLSOHLQSXWV¡
UHDGLQJYROWDJHRQ
UHVSRQGLQJWRYROWDJHFKDQJHV
VDYLQJYDOXHVWRORJILOHV¡
VHQGLQJYDOXHVRI¡
VHTXHQFLQJPXOWLSOH/('V¡
YLVXDORXWSXWDQG
DQDORJWRGLJLWDOFRQYHUWHU $'& VHHDOVRDQDORJ5HDGIXQFWLRQ
$QDORJ0HWHUVNHWFK
DQDORJ5HDGIXQFWLRQ
DGGLWLRQDOLQIRUPDWLRQ
FKDQJLQJUDQJHRIYDOXHV
FRQWUROOLQJVHUYRV
GHWHFWLQJVRXQG
GLVSOD\LQJYROWDJHV¡
/('EOLQNLQJFRGHH[DPSOH
PHDVXULQJGLVWDQFH
PHDVXULQJWHPSHUDWXUH
PHDVXULQJYDOXHVTXLFNO\¡
PHDVXULQJYROWDJHV
UHDGLQJYROWDJHV
UHVSRQGLQJWRYROWDJHFKDQJHV
VHQVRUVDQG
DQDORJ:ULWHIXQFWLRQ
DGMXVWLQJ/('EULJKWQHVV
DQDORJSDQHOPHWHUV
FRQWUROOLQJEUXVKHGPRWRUVSHHG
GHWHFWLQJPRXVHPRYHPHQW
WLPHUVDQG
YLVXDORXWSXWDQG
DQJOHEUDFNHWV ! DQLPDWLRQHIIHFWV
EHDWLQJKHDUW¡
VPLOLQJIDFH¡
DQRGHV
FRPPRQ
GHILQHG
612 | Index
$UGXLQRERDUGV
DERXW
DGGLWLRQDOLQIRUPDWLRQ
FRPPXQLFDWLQJEHWZHHQ¡
LQWHUUXSWVDQG
/LQX[HQYLURQPHQW
0DFHQYLURQPHQW
PHPRU\VXSSRUW
SLQDUUDQJHPHQWV¡¡
VHULDOFRPPXQLFDWLRQ
VHWWLQJXS
VLPXOWDQHRXVWRQHVDQG
WLPHUVDQG
XSORDGLQJUXQQLQJ%OLQNVNHWFK¡
:LQGRZVHQYLURQPHQW
$UGXLQREXLOGSURFHVV¡
$UGXLQRHQYLURQPHQW
JHWWLQJVWDUWHGZLWKSURMHFWV¡
,'(LQVWDOODWLRQ¡
LQWURGXFWLRQ
SUHSDULQJVNHWFKHV¡
VHWWLQJXS$UGXLQRERDUGV
$UGXLQR3OD\JURXQG
DERXW
WURXEOHVKRRWLQJSUREOHPV
$UGXLQRVRIWZDUH
VHHDOVRVNHWFKHV
DERXW
,'(LQVWDOODWLRQ¡
YHUVLRQFRQWURODQG
$UGXLQR0RXVHSGH 3URFHVVLQJVNHWFK DUJXPHQWV
GHILQHG
DVUHIHUHQFHV
DUUD\VNHWFK
DUUD\V
GHILQHG
RI/('V¡
LQVNHWFKHV
VWULQJVDQG¡
$6&,,FKDUDFWHUVHW
FRPPRQFRQWUROFRGHV
FRQYHUWLQJWRQXPHULFYDOXHV
QXOOYDOXH
UHDGLQJ5),'WDJV
WDEOHVRI¡
]HURYDOXH
DVVLJQPHQW RSHUDWRU
$7&1FRPPDQG
Download from Wow! eBook <www.wowebook.com>
$7'FRPPDQG
$7'FRPPDQG
$7'FRPPDQG
$7'+FRPPDQG
$7'/FRPPDQG
$7,$FRPPDQG
$7,&))FRPPDQG
$7,'FRPPDQG
$7,5FRPPDQG
$7,8FRPPDQG
$WPHO$7PHJDGDWDVKHHWV
$70<FRPPDQG
DWRLIXQFWLRQ
DWROIXQFWLRQ
$75(FRPPDQG
DWWDFK,QWHUUXSWIXQFWLRQ
$7:5FRPPDQG
$XGDFLW\XWLOLW\
DXGLRRXWSXW
DERXW¡
FRQWUROOLQJ0,',¡
GHWHFWLQJVRXQG¡
IDGLQJDQ/('¡
JHQHUDWLQJDXGLRWRQHV¡
PDNLQJV\QWKHVL]HUV¡
PXOWLSOHVLPXOWDQHRXVWRQHV¡
SOD\LQJVLPSOHPHORGLHV¡
SOD\LQJWRQHV¡
SOD\LQJ:$9ILOHV¡
$XGXLQRVNHWFK¡
$95*&&DSSOLFDWLRQ
DYUREMGXPSWRRO
$YUGXGHXWLOLW\
$95IUHDNVZHEVLWH
B
E!WDJ
%DEHO)LVKWUDQVODWLRQZHEDSS
EDFNJURXQGQRLVH
EDFNOLJKW /&'
GHILQHG
OLPLWLQJFXUUHQWWR
EDUJUDSKV¡¡¡
%DUJUDSKVNHWFK
%DVLFB6WULQJVVNHWFK
EDWWHULHV
FRQQHFWLQJWRXVLQJ
UHGXFLQJGUDLQ¡
EDWWHU\HOLPLQDWRUFLUFXLW %(& EDXGUDWH
GHILQHG
*36
6HULDO0RQLWRU
%&' %LQDU\&RGHG'HFLPDO EFGGHFIXQFWLRQ
%(& EDWWHU\HOLPLQDWRUFLUFXLW %LQDU\&RGHG'HFLPDO %&' ELQDU\IRUPDW
GLVSOD\LQJVSHFLDOV\PEROV
UHFHLYLQJGDWDLQ¡
VHQGLQJGDWDLQ¡
VHQGLQJYDOXHVIURP3URFHVVLQJ¡
ELSRODUVWHSSHUV
DERXW
GULYLQJ¡
GULYLQJXVLQJ(DV\'ULYHUERDUG¡
ELWIXQFWLRQ
ELW&OHDUIXQFWLRQ
ELW)XQFWLRQVVNHWFK
ELWPDSVIRU*/&'GLVSOD\V¡
ELW5HDGIXQFWLRQ
GULYLQJVHJPHQW/('GLVSOD\V
IXQFWLRQDOLW\
UHDGLQJPXOWLSOHDQDORJLQSXWV
VHQGLQJPXOWLSOHSLQYDOXHV
ELWV
VHQGLQJSLQYDOXHV¡
VHULDOFRPPXQLFDWLRQ
VHWWLQJUHDGLQJ¡
VKLIWLQJ
ELWVVNHWFK
ELW6HWIXQFWLRQ
ELWZLVHRSHUDWLRQV¡
ELW:ULWHIXQFWLRQ
EOLQNIXQFWLRQ
%OLQNVNHWFK
ORDGLQJ¡
UXQQLQJ¡
WXUQLQJFXUVRURQRII
EOLQNVNHWFK
%OLQN/('IXQFWLRQ¡
EOLQN/LE7HVWVNHWFK
%OLQN0PRGXOH¡
%OLQN0VNHWFK
%OLQN07HVWHUVNHWFK
%OLQN:LWKRXW'HOD\VNHWFK
%2%EUHDNRXWERDUG
ERROHDQGDWDW\SH
Index | 613
ERRWORDGHU
%UD\7HUPLQDOSURJUDP
EUHDGERDUGV
DERXW
VROGHUOHVV
EUHDNVWDWHPHQW
EUXVKHGDQGEUXVKOHVVPRWRUV
DERXW
FRQWUROOLQJGLUHFWLRQZLWK+%ULGJH¡
¡
FRQWUROOLQJGLUHFWLRQZLWKVHQVRUV¡
FRQWUROOLQJVSHHGZLWK+%ULGJH¡
FRQWUROOLQJVSHHGZLWKVHQVRUV¡
GULYLQJXVLQJVSHHGFRQWUROOHUV
GULYLQJXVLQJWUDQVLVWRUV
%UXVKHGB+B$UGXPRWRVNHWFK
%UXVKHGB+B%ULGJHVNHWFK
%UXVKHGB+B%ULGJHB'LUHFWLRQVNHWFK
%UXVKHGB+B%ULGJHBVLPSOHVNHWFK
%UXVKHGB+B%ULGJHBVLPSOHVNHWFK
EXLOGSURFHVV $UGXLQR ¡
EXLOWLQOLEUDULHV¡
E\WHGDWDW\SH
GHILQHG
VKLIWLQJELWV
%\WH2SHUDWRUVVNHWFK
C
FILOHH[WHQVLRQ
&ODQJXDJH
FRQYHUWLQJVWULQJVWRQXPEHUV
SUHSURFHVVRU
VWULQJVDQG
FDPHUDVNHWFK
&DQRQ+DFN'HYHORSPHQW.LW
FDSDFLWRUV
DERXW
FRQQHFWLQJWRVHQVRUV
GHFRXSOLQJDQG
FDUULDJHUHWXUQ ?U FDVHVWDWHPHQW
FDWKRGHV
FRPPRQ
GHILQHG
VFKHPDWLFV\PEROIRU
FHLOIXQFWLRQ
&HOVLXVWHPSHUDWXUHVFDOH
FKDUGDWDW\SH
614 | Index
FKDUDFWHUVWULQJV VHHVWULQJV
FKDUDFWHUVFKDUDFWHUYDOXHV
FRPSDULQJWRQXPHULF¡
FRQYHUWLQJWRQXPHULF
FUHDWLQJFXVWRP¡
GDWDW\SHUHSUHVHQWLQJ
GLVSOD\LQJVSHFLDOV\PEROV¡
&KDUOLHSOH[LQJ
DERXW
FRQWUROOLQJ/('PDWUL[YLD¡
&KDUOLHSOH[LQJVNHWFK
FKDVLQJOLJKWVVHTXHQFH
FLUFXLWGLDJUDPV
FODVVHVOLEUDULHVDV
FOLHQWFODVV ZHEVHUYHU
DYDLODEOHPHWKRG
FRQQHFWHGPHWKRG
SULQWOQPHWKRG
UHDGPHWKRG
FORFNV
GLVSOD\LQJWLPHRIGD\¡
UHDOWLPH¡
V\QFKURQL]LQJ¡
FRGLQJWHFKQLTXHV VHHSURJUDPPLQJ
WHFKQLTXHV
FRORUDGMXVWLQJIRU/('V¡
FRPPDVHSDUDWHGWH[WVSOLWWLQJLQWRJURXSV
¡
&RPPD'HOLPLWHG,QSXWVNHWFK
&RPPD'HOLPLWHG2XWSXWVNHWFK
FRPPRQDQRGH
FRPPRQFDWKRGH
FRPPXQLFDWLRQSURWRFROV
VHHDOVRVHULDOFRPPXQLFDWLRQVZLUHOHVV
FRPPXQLFDWLRQVSHFLILFSURWRFROV
DGGLWLRQDOLQIRUPDWLRQ
GHILQHG
FRPSDULVRQRSHUDWRUV¡
FRPSDVVHVGHWHFWLQJGLUHFWLRQ¡
FRPSLODWLRQSURFHVV
FRQGLWLRQDOFRPSLODWLRQV
GHILQHG
HUURUPHVVDJHV
FRPSRXQGRSHUDWRUV
FRQFDWIXQFWLRQ
FRQGLWLRQV
DFWLRQVEDVHGRQ
EUHDNLQJRXWRIORRSVEDVHGRQ
FRPSLODWLRQVEDVHGRQ
FRQILJXUH5DGLRIXQFWLRQ
FRQVWDQWFXUUHQWGULYHUV
FRQVWDQWV
DGGLWLRQDOLQIRUPDWLRQ
DVVLJQLQJYDOXHVWR
SURJUDPPLQJWHFKQLTXHV¡
5$0XVDJHDQG
FRQVWUDLQIXQFWLRQ
FRQWDFWERXQFH
FRQWLQXRXVURWDWLRQVHUYRV¡
FRQWUROFRGHV
FRQWUROOHUFKLSV¡
VHHDOVRVSHFLILFW\SHVRIFRQWUROOHUV
FRQYHUWLQJ
$6&,,FKDUDFWHUVWRQXPHULFYDOXHV
QXPEHUVWRVWULQJV¡
VWULQJVWRQXPEHUV
&RQZD\-RKQ
&RRO7HUPSURJUDP
&RRUGLQDWHG8QLYHUVDO7LPH 87& FRVIXQFWLRQ
FRXQWGRZQWLPHUV¡
FRXQWHUV
SXOVH
UHSHDWLQJVWDWHPHQWVZLWK¡
WLPHUVDV
FSSILOHH[WHQVLRQ
FXUO\EUDFNHWV^`
FXUVRU /&' WXUQLQJRQRII
FXUVRU PRXVH PRYLQJ¡
FXUVRU+LGHIXQFWLRQ
FXVWRP&KDU3L[HOVVNHWFK
FXVWRP&KDUVVNHWFK
FXVWRPBFKDUVNHWFK
&XWH&RPSURJUDP
D
GDWDVKHHWVUHDGLQJ
GDWDW\SHV
$UGXLQRVXSSRUWHG
ELQDU\IRUPDWFRQVLGHUDWLRQV
GDWH
DODUPVEDVHGRQ
GLVSOD\LQJ
NHHSLQJWUDFNRI
'&PRWRUV VHHEUXVKHGDQGEUXVKOHVVPRWRUV
'&RIIVHW
GHERXQFHIXQFWLRQ¡
'HERXQFHVNHWFK
GHERXQFLQJSURFHVV¡
GHEXJJLQJ
FRQGLWLRQDOFRPSLODWLRQVDQG
PHPRU\PDQDJHPHQWDQG
VHQGLQJLQIRUPDWLRQWRFRPSXWHUV¡
GHFD\UDWH /(' GHFLPDOIRUPDW
%&'DQG
GLVSOD\LQJVSHFLDOV\PEROV
VHQGLQJWH[WLQ
GHFRGLQJ,5VLJQDOV¡
GHFRXSOLQJFDSDFLWRUVDQG
GHIDXOW FDVHVWDWHPHQW GHILQHSUHSURFHVVRUFRPPDQG¡
'(*B72B5$'FRQVWDQW
GHOD\IXQFWLRQ
FUHDWLQJGHOD\V
LQWHUUXSWVDQG
SOD\LQJWRQHV
VLPXOWDQHRXVWRQHVDQG
WLPHUVDQG
GHOD\VNHWFK
GHOD\0LFURVHFRQGVIXQFWLRQ
GHOD\VWLPH VHHWLPHGHOD\V
GHOLPLWHUV
'+&3 '\QDPLF+RVW&RQILJXUDWLRQ3URWRFRO
'16DQG
,3DGGUHVVHVDQG¡
WKLUGSDUW\OLEUDU\
GLDOWUDFNLQJPRYHPHQWRI¡¡
'LJL,QWHUQDWLRQDO
'LJL.H\EUHDGERDUG
GLJLWDOFDPHUDVFRQWUROOLQJ¡
GLJLWDOSLQV
VHHDOVRGLJLWDO5HDGIXQFWLRQ
DERXW
DGGLWLRQDOLQIRUPDWLRQ
FRPPRQSLQDVVLJQPHQWV¡
FRQILJXULQJWRUHDGLQSXW
GHWHFWLQJLQSXW
GHWHFWLQJVZLWFKFORVLQJ¡
GHWHUPLQLQJKRZORQJVZLWFKLVSUHVVHG
¡
GHWHUPLQLQJVZLWFKVWDWH¡
LQWHUQDOSXOOXSUHVLVWRUV¡
/('PDWUL[H[DPSOH
PHDVXULQJSXOVHGXUDWLRQ
SLQDUUDQJHPHQWV
Index | 615
UHDGLQJNH\SDGV¡
VDYLQJYDOXHVWRORJILOHV¡
VHQGLQJYDOXHVRI¡
VHWWLQJTXLFNO\¡
63,GHYLFHV
YLVXDORXWSXWDQG
GLJLWDOWKHUPRPHWHUV¡
GLJLWDO&ORFN'LVSOD\IXQFWLRQ
GLJLWDO5HDGIXQFWLRQ
DGGLWLRQDOLQIRUPDWLRQ
GHWHUPLQLQJVZLWFKVWDWH
IXQFWLRQDOLW\
PRQLWRULQJYROWDJH
GLJLWDO:ULWHIXQFWLRQ
DGGLWLRQDOLQIRUPDWLRQ
FRQWUROOLQJVROHQRLGVDQGUHOD\V
GLJLWDORXWSXWDQG
IXQFWLRQDOLW\
LQWHUQDOSXOOXSUHVLVWRUVDQG
OLPLWDWLRQV¡
GLRGHV
GHILQHG
VQXEEHU
GLUHFWLRQ
FRQWUROOLQJIRUEUXVKHGPRWRUV¡
¡¡
GHWHFWLQJ FRPSDVV ¡
WUDFNLQJ *36 ¡
'LUHFWRU\1DPH6\VWHP VHH'16
'LVSOD\Y2UOHVVVNHWFK
GLVSOD\%OLQNIXQFWLRQ
'LVSOD\0RUH7KDQ9VNHWFK
GLVSOD\1XPEHUIXQFWLRQ
GLVSOD\V VHH/&'GLVSOD\V
GLVWDQFHPHDVXULQJ¡
GLYLVLRQ RSHUDWRU
'16 'LUHFWRU\1DPH6\VWHP
DERXW
'+&3DQG
UHVROYLQJ,3DGGUHVVHV¡
'16OLEUDU\
ILQLVKHGIXQFWLRQ
,QLWIXQFWLRQ
UHVROYHIXQFWLRQ
GRZKLOHORRS
GR(QFRGHUIXQFWLRQ
GRXEOHGDWDW\SH
GRXEOH+HLJKW%DUVIXQFWLRQ
GUDZIXQFWLRQ 3URFHVVLQJ 616 | Index
'UDZ%LWPDSIXQFWLRQ
GUDZ%R[IXQFWLRQ
'657&FKLS
'657&KOLEUDU\
'657&FKLS
'XDO7RQHVVNHWFK
GXUDWLRQ
GHWHUPLQLQJIRUGHOD\V¡
PHDVXULQJIRUSXOVHV
VHWWLQJIRUSXOVHV¡
VHWWLQJIRUWLPHUV¡
'\QDPLF+RVW&RQILJXUDWLRQ3URWRFRO VHH
'+&3
E
(DV\'ULYHUERDUG¡
((3520OLEUDU\
DERXW
DGGLQJH[WHUQDOPHPRU\
FOHDUIXQFWLRQ
UHDGIXQFWLRQ
VWRULQJGDWD¡
ZULWHIXQFWLRQ
((3520PHPRU\
DERXW
DGGLQJH[WHUQDO¡
VWRULQJGDWDLQ¡
VWDQGDUG¡
HOHFWURQLFV
DGGLWLRQDOLQIRUPDWLRQ
EDVLFFRPSRQHQWV¡
WXWRULDOVDERXW
HOHFWURQLFVVSHHGFRQWUROOHUV
GHILQHG
GULYLQJEUXVKOHVVPRWRUV
HTXDOWR
RSHUDWRU
HUURUPHVVDJHV
DVVLJQLQJYDOXHVWRFRQVWDQWV
FRPSLODWLRQSURFHVV
XSORDGLQJVNHWFKHV
(WKHUQHWOLEUDU\
DERXW
EHJLQIXQFWLRQ
VHFXULW\FRQVLGHUDWLRQV
VNHWFKHVDQG
(WKHUQHWVKLHOG
,3DGGUHVVHVDQG
VHWWLQJXS¡
(=5DQJHILQGHU'LVWDQFH6HQVRUVNHWFK
F
IDEVIXQFWLRQ
IDFHDQLPDWLRQHIIHFW¡
)DKUHQKHLWWHPSHUDWXUHVFDOH
)DOXGL5REHUW
ILQGHUILQG8WLOPHWKRG
)LUPDWDOLEUDU\
IODVKIXQFWLRQ
IODVKPHPRU\ VHHSURJUDPPHPRU\
IORDWLQJSRLQWQXPEHUV
GDWDW\SHUHSUHVHQWLQJ
PHPRU\FRQVXPSWLRQ
SUHFLVLRQRI
URXQGLQJXSGRZQ
LQVNHWFKHV
IORRUIXQFWLRQ
IORZFRQWURO
DGGLWLRQDOLQIRUPDWLRQ
ELQDU\IRUPDWFRQVLGHUDWLRQV
GHILQHG
IRUORRS
FKDVLQJOLJKWVVHTXHQFH
/('PDWUL[H[DPSOH
UHSHDWLQJVWDWHPHQWVZLWKFRXQWHUV¡
)RU/RRSVNHWFK
IRUPDWWHGWH[W
/&'GLVSOD\VDQG¡
VHQGLQJ¡
IRUPDWWLQJZHEVHUYHUUHTXHVWV¡
IRUPVFUHDWLQJZHESDJHVZLWK¡
IRUZDUGYROWDJH
PXOWLSOH[HU¡
)UHTXHQF\&RXQWHUOLEUDU\
)UHTXHQF\7LPHUOLEUDU\
IXQFWLRQERG\
IXQFWLRQGHFODUDWLRQVGHILQHG
IXQFWLRQKHDGHU
IXQFWLRQRYHUORDGLQJ
IXQFWLRQ5HIHUHQFHVVNHWFK
IXQFWLRQV
VHHDOVRVSHFLILFIXQFWLRQV
DGGLQJWRVNHWFKHV¡
$UGXLQRUHIHUHQFH
FUHDWLQJ
FUHDWLQJDODUPVWRFDOO¡
QDPLQJFRQYHQWLRQV
5$0XVDJHDQG
UHWXUQLQJPXOWLSOHYDOXHV¡
VHPLFRORQLQ
WULJRQRPHWULF
)XWXUOHF/('05
G
JDPHFRQWUROOHUV VHH3OD\6WDWLRQJDPH
FRQWUROOHU
*DPHRI/LIHVLPXODWLRQ
*(7FRPPDQG
JHW&RXQWIXQFWLRQ
JHW'LVWDQFHIXQFWLRQ
JHW)ORDWIXQFWLRQ
JHWNH\IXQFWLRQ
JHW7DEOH(QWU\IXQFWLRQ
*HWWLQJ6WDUWHGVNHWFK
JHW9DOXHIXQFWLRQ
*/&' JUDSKLFDO/&' GLVSOD\V
DERXW
FRQQHFWLQJ¡
FUHDWLQJELWPDSVIRU¡
SLQFRQQHFWLRQV
SULQWLQJRXWSXWWR
*/&'OLEUDU\
JOFGVNHWFK
*/&'GLDJVWHVWVNHWFK
*/&',PDJHVNHWFK
JOFG0DNH%LWPDSXWLOLW\
JOREDOYDULDEOHV
*18VFUHHQSURJUDP
*RRJOH&DOFXODWRU
*RRJOH(DUWK
DERXW
DGGLWLRQDOLQIRUPDWLRQ
FRQWUROOLQJPRYHPHQWLQ¡
GRZQORDGLQJ
*RRJOH)LQDQFH
*RRJOH:HDWKHU¡
*RRJOH;0/$3,
*RRJOH(DUWK)6B3VNHWFK
*RRJOH(DUWK36;VNHWFK
*36PRGXOH
FUHDWLYHSURMHFWV
JHWWLQJORFDWLRQIURP¡
UHFHLYLQJGDWDIURP¡
JUDQXODUV\QWKHVLV
JUDSKLFDO/&'GLVSOD\V VHH*/&'GLVSOD\V
*UDYLWHFKVHJPHQWGLVSOD\VKLHOG¡
JUHDWHUWKDQ ! RSHUDWRU
JUHDWHUWKDQRUHTXDOWR ! RSHUDWRU
*UHHQZLFK0HDQ7LPH
Index | 617
J\URVNHWFK
J\URVFRSHGHWHFWLQJURWDWLRQZLWK¡
H
KILOHH[WHQVLRQ
+%ULGJH
DERXW
FRQWUROOLQJEUXVKHGPRWRUGLUHFWLRQ¡
¡
FRQWUROOLQJEUXVKHGPRWRUVSHHG¡
GULYLQJELSRODUVWHSSHUPRWRUV¡
+DJPDQ%UHWW
KDUGZDUHSUREOHPVWURXEOHVKRRWLQJ¡
KDUGZDUHVOHHSIXQFWLRQ
+DUGZDUH&RXQWLQJVNHWFK
+DUW0LNDO
+HOOR0DWUL[VNHWFK
KH[DGHFLPDOIRUPDW
GLVSOD\LQJVSHFLDOV\PEROV
VHQGLQJWH[WLQ
+,' +XPDQ,QWHUIDFH'HYLFHV KLJK%\WHIXQFWLRQ
DGGLWLRQDOLQIRUPDWLRQ
IXQFWLRQDOLW\
VHQGLQJELQDU\GDWD
+LWDFKL+'FKLS¡
KL:RUGPDFURH[SUHVVLRQ
+0E&RPSDVVVNHWFK
KRVWQDPHVUHVROYLQJWR,3DGGUHVVHV¡
+70/ +\SHU7H[W0DUNXS/DQJXDJH
DERXW
E!WDJ
IRUPDWWLQJUHTXHVWV¡
*(7FRPPDQG
3267FRPPDQG¡¡
WG!WDJ
WU!WDJ
+773 +\SHUWH[W7UDQVIHU3URWRFRO KXH7R5*%IXQFWLRQ¡
+XPDQ,QWHUIDFH'HYLFHV +,' +\SHU7H[W0DUNXS/DQJXDJH VHH+70/
+\SHUWH[W7UDQVIHU3URWRFRO +773 I
,& ,QWHU,QWHJUDWHG&LUFXLW
DERXW¡
DGGLQJ((3520PHPRU\¡
618 | Index
FRPPXQLFDWLQJEHWZHHQ$UGXLQRERDUGV
¡
FRQWUROOLQJ5*%/('V¡
GULYLQJVHJPHQW/('V¡
LQWHJUDWLQJSRUWH[SDQGHUV¡
LQWHUIDFLQJWR57&V¡
PHDVXULQJWHPSHUDWXUH¡
57&FKLSVDQG
:LLQXQFKXFNDFFHOHURPHWHU¡
,&6HJPHQWVNHWFK
,&'HEXJREMHFW
,&B6HJPHQWVNHWFK
,&B((3520VNHWFK
,&B0DVWHUVNHWFK
,&B57&VNHWFK
,&B6ODYHVNHWFK
,&B7HPSHUDWXUHVNHWFK
LF((3520B5HDGIXQFWLRQ
LF((3520B:ULWHIXQFWLRQ
,&5 ,QSXW&RPSDUH5HJLVWHU ,'( LQWHJUDWHGGHYHORSPHQWHQYLURQPHQW
IXQFWLRQDOLW\
LQVWDOOLQJ¡
SUHSDULQJVNHWFKHVZLWK¡
,(((VWDQGDUG¡
LIVWDWHPHQW
LIHOVHVWDWHPHQW
LPDJHVGLVSOD\LQJRQ/('PDWUL[¡
LQFOXGHSUHSURFHVVRUFRPPDQG
LQGH[2IIXQFWLRQ
LQIUDUHGWHFKQRORJ\ VHH,5 LQIUDUHG
WHFKQRORJ\
LQLWIXQFWLRQ
,QSXW&DSWXUHWLPHUIDFLOLW\
,QSXW&RPSDUH5HJLVWHU ,&5 ,QSXW&DSWXUHVNHWFK
LQWGDWDW\SH
GHILQHG
H[WUDFWLQJKLJKORZE\WHV¡
IURPKLJKORZE\WHV¡
VKLIWLQJELWV
LQWHJUDWHGFLUFXLWV
LQWHJUDWHGGHYHORSPHQWHQYLURQPHQW VHH,'(
,QWHU,QWHJUDWHG&LUFXLW VHH,&
,QWHUQHW3URWRFRO ,3 ,QWHUQHWWLPHVHUYHU¡
LQWHUSRODWLQJWHFKQLTXH
LQWHUUXSWKDQGOHUV
LQWHUUXSWVHUYLFHURXWLQH
LQWHUUXSWV
DGGLWLRQDOLQIRUPDWLRQ
GHILQHG
XVDJHH[DPSOHV¡
,QWHUUXSWVVNHWFK
,3 ,QWHUQHW3URWRFRO ,3DGGUHVVHV
'16VHUYLFHDQG¡
KDUGFRGHG¡
ORFDO
REWDLQLQJDXWRPDWLFDOO\¡
XQLTXH
,5 LQIUDUHG WHFKQRORJ\
GHFRGLQJVLJQDOV¡
LPLWDWLQJVLJQDOV¡
UHPRWHFRQWURODQG¡
VHQVRUVDQG¡
,5UHFHLYHUPRGXOH¡
LUGLVWDQFHVNHWFK
LUGLVWDQFHB3URJPHPVNHWFK
,5HFYREMHFW
GHFRGHIXQFWLRQ
HQDEOH,5,QIXQFWLRQ
UHVXPHIXQFWLRQ
,5UHPRWHOLEUDU\¡
,5VHQGREMHFW
LU6HQGVNHWFK
,5BUHPRWHBGHWHFWRUVNHWFK
LWRDIXQFWLRQ
J
-DJJDUV-HVVH
-DPHFREUHDGERDUG
-DYDODQJXDJH
VHHDOVR3URFHVVLQJRSHQVRXUFHWRRO
FUHDWLQJELWPDSV
5RERWFODVV
VSOLWPHWKRG
MR\VWLFNV
DFFHOHURPHWHUDQG
FRQWUROOLQJ*RRJOH(DUWKYLD¡
JHWWLQJLQSXWIURP¡
MSJILOHH[WHQVLRQ
-621IRUPDW
K
.H\SDGVNHWFK
NH\SDGV
GHILQHG
UHDGLQJ¡
.QLJKW3HWHU
.QLJKW5LGHUVNHWFK
NQRFNVHQVRUV
.6SDQHO
L
/+%ULGJH¡
/'+%ULGJH¡
/DG\DGDZHEVLWH
/$1&
ODVW,QGH[2IIXQFWLRQ
/&'GLVSOD\V
VHHDOVR*/&'GLVSOD\V
DERXW
DGGLWLRQDOLQIRUPDWLRQ
FUHDWLQJFXVWRPFKDUDFWHUV¡
GLVSOD\LQJVSHFLDOV\PEROV¡
IRUPDWWLQJWH[W¡
SLQFRQQHFWLRQV
SL[HOVVPDOOHUWKDQVLQJOHFKDUDFWHU¡
SULQWLQJRXWSXWWR
VFUROOLQJWH[W¡
V\PEROVODUJHUWKDQVLQJOHFKDUDFWHU¡
WH[WEDVHG¡
WXUQLQJFXUVRURQRII
WXUQLQJGLVSOD\RQRII
/'5 OLJKWGHSHQGHQWUHVLVWRU OHDGLQJ]HURV
OHDUQ.H\&RGHVIXQFWLRQ
/('EDUJUDSK GHFD\YHUVLRQ VNHWFK
/('PDWUL[
FRQWUROOLQJYLD&KDUOLHSOH[LQJ¡
FRQWUROOLQJYLDPXOWLSOH[LQJ¡
FRQWUROOLQJYLDVKLIWUHJLVWHUV
GLVSOD\LQJLPDJHVRQ¡
/('%ULJKWQHVVVNHWFK
/('V
DERXW
DGMXVWLQJEULJKWQHVVRI¡¡
DGMXVWLQJFRORURI¡
EOLQNLQJFRGHH[DPSOH¡¡
FKDVLQJOLJKWVVHTXHQFH
FRQQHFWLQJDQGXVLQJ¡
FRQWUROOLQJDUUD\RI¡
Index | 619
FRQWUROOLQJZLWK%OLQN0PRGXOH¡
FUHDWLQJEDUJUDSKV¡¡
GHWHFWLQJPRWLRQ
GHWHFWLQJPRXVHPRYHPHQW¡
GHWHFWLQJPRYHPHQW¡
GLJLWDOSLQVDQG
GULYLQJVHJPHQWGLVSOD\V¡¡¡
¡¡
GULYLQJKLJKSRZHU¡
IDGLQJ¡
LPLWDWLQJ,5VLJQDOV¡
LQFUHDVLQJQXPEHURIDQDORJRXWSXWV¡
,5UHPRWHFRQWURODQG
NQRFNVHQVRUVDQG
OLJKWLQJZKHQVZLWFKLVSUHVVHG¡
PHDVXULQJGLVWDQFH
PXOWLSOH[LQJDQG
SULQWLQJRXWSXWWR
VHTXHQFLQJPXOWLSOH¡
VSHFLILFDWLRQV
WULJJHULQJYROWDJHDODUPV¡
ZLULQJ;%HHVWR
/('VVNHWFK
/('BLQWHQVLW\VNHWFK
/('BVWDWHVNHWFK
/HRQH$OH[
OHVVWKDQ RSHUDWRU
OHVVWKDQRUHTXDOWR RSHUDWRU
OLEUDULHV
VHHDOVRVSHFLILFOLEUDULHV
DERXW
DGGLWLRQDOLQIRUPDWLRQ
EXLOWLQ¡
DVFODVVHV
FUHDWLQJ¡¡
GHFODULQJFRQVWDQWV
GHFODULQJJOREDOYDULDEOHV
LQVWDOOLQJWKLUGSDUW\
PHPRU\XVDJHDQG
PRGLI\LQJ¡
VNHWFKHVDQG
XVLQJRWKHUOLEUDULHV¡
OLJKW
FKDVLQJOLJKWVVHTXHQFH
FRQWUROOLQJ¡
GHWHFWLQJFKDQJHVLQ
OLJKWGHSHQGHQWUHVLVWRU /'5 /LQGVD\3KLOOLS
620 | Index
OLQHIHHG ?Q /LQX[HQYLURQPHQW
$UGXLQR,'(LQVWDOODWLRQ
;%HH6HULHVFRQILJXUDWLRQ
OLTXLGFU\VWDOGLVSOD\V VHH/&'GLVSOD\V
/LTXLG&U\VWDOOLEUDU\
DERXW
DGGLWLRQDOLQIRUPDWLRQ
FOHDUIXQFWLRQ
FUHDWLQJFXVWRPFKDUDFWHUV
GLVSOD\IXQFWLRQ
)RUPDW7H[WVNHWFK
+HOOR:RUOGVNHWFK
QR'LVSOD\IXQFWLRQ
SULQWIXQFWLRQ
6FUROO'LVSOD\/HIWIXQFWLRQ¡
6FUROO'LVSOD\5LJKWIXQFWLRQ¡
VHW&XUVRUIXQFWLRQ
6SHFLDO&KDUVVNHWFK
/LWH2Q/7&-5
/LWH2Q/7'*
/0KHDWGHWHFWLRQVHQVRU¡
OPVNHWFK
ORFDO,3DGGUHVVHV
ORJILOHVVDYLQJGDWDWR¡
ORJLFDORSHUDWRUV
ORQJGDWDW\SH
GHILQHG
H[WUDFWLQJKLJKORZE\WHV¡
IURPKLJKORZE\WHV¡
VKLIWLQJELWV
ORRN$URXQGIXQFWLRQ
ORRSIXQFWLRQ
ORZ%\WHIXQFWLRQ
DGGLWLRQDOLQIRUPDWLRQ
IXQFWLRQDOLW\
VHQGLQJELQDU\GDWD
ORZ:RUGPDFURH[SUHVVLRQ
OWRDIXQFWLRQ
M
0$&DGGUHVV
DERXW
XQLTXH
0DFHQYLURQPHQW
$UGXLQR,'(LQVWDOODWLRQ
PRYLQJPRXVHFXUVRU¡
;%HH6HULHVFRQILJXUDWLRQ
PDFURH[SUHVVLRQV
PDLQIXQFWLRQ
PDNH/RQJIXQFWLRQ
PDSIXQFWLRQ
DGGLWLRQDOLQIRUPDWLRQ
FKDQJLQJUDQJHRIYDOXHV
KHDUWEHDWLQJHIIHFW
/('EOLQNLQJFRGHH[DPSOH
0DSVNHWFK
PDUTXHHIXQFWLRQ
0DUTXHHVNHWFK
PDVWHUGHYLFHV ,&
FRPPXQLFDWLQJEHWZHHQ$UGXLQRERDUGV
¡
GHILQHG
PDVWHUGHYLFHV 63, PDWKHPDWLFDORSHUDWRUV
FRQVWUDLQLQJQXPEHUVWRUDQJHRIYDOXHV
GHWHUPLQLQJDEVROXWHYDOXH
H[WUDFWLQJKLJKORZE\WHV¡
ILQGLQJUHPDLQGHUDIWHUGLYLVLRQ
LQFUHPHQWLQJGHFUHPHQWLQJYDOXHV
LQWIURPKLJKORZE\WHV¡
PLQLPXPPD[LPXPRIYDOXHV
SUHFHGHQFHFRQVLGHUDWLRQV
UDLVLQJQXPEHUVWRDSRZHU
UDQGRPQXPEHUJHQHUDWLRQ¡
URXQGLQJIORDWLQJSRLQWQXPEHUV
VHWWLQJUHDGLQJELWV¡
VKLIWLQJELWV
VLPSOHPDWKXVLQJ
VTXDUHURRWV
WULJRQRPHWULFIXQFWLRQV
0DWUL[OLEUDU\
PDWUL[0S[VNHWFK
PDWUL[0S[$QLPDWLRQVNHWFK
PD[IXQFWLRQ
0D[BGLJLWVVNHWFK
0$;[[GHYLFHV
FRQWUROOLQJDUUD\RI/('V¡
GULYLQJVHJPHQWGLVSOD\V¡¡
0D[%RWL[(=VHQVRU
0F&DXOH\0LNH
0HGLD$FFHVV&RQWURODGGUHVV VHH0$&
DGGUHVV
0HJDERDUGV
((3520PHPRU\LQ
*/&'VDQG
,&DQG
,QSXW&DSWXUHWLPHUIDFLOLW\
LQWHUUXSWVDQG
SLQDUUDQJHPHQWV¡
VHULDOSRUWV¡
VLPXOWDQHRXVWRQHVDQG
WLPHUVDQG
PHORGLHVSOD\LQJ¡
PHPRU\PDQDJHPHQW
VHHDOVRVSHFLILFW\SHVRIPHPRU\
DGGLQJH[WHUQDO¡
DGGLWLRQDOLQIRUPDWLRQ
$UGXLQRERDUGVDQG
ELWPDSVDQG
FRQVWDQWVDQG¡
GHWHUPLQLQJIUHHXVHG¡
IORDWLQJSRLQWQXPEHUVDQG
OLEUDULHVDQG
VWRULQJUHWULHYLQJQXPHULFYDOXHV¡
VWRULQJUHWULHYLQJVWULQJV¡
ZHESDJHVDQG¡
PHPRU\)UHHIXQFWLRQ
PHVKQHWZRUNV;%HHDQG
PHVVDJHV
FRPPXQLFDWLRQVSURWRFRO
0,',¡
UHFHLYLQJELQDU\GDWD¡
UHFHLYLQJPXOWLSOHWH[WILHOGV¡
VHQGLQJELQDU\GDWD¡
VHQGLQJELQDU\YDOXHVIURP3URFHVVLQJ¡
VHQGLQJPXOWLSOHWH[WILHOGV¡
VHQGLQJYLDZLUHOHVVPRGXOHV¡
VHQGLQJUHFHLYLQJZLWK8'3¡
7ZLWWHU¡
0LFURFKLS/&((3520
PLFURSKRQHVNHWFK
PLFURSKRQHVGHWHFWLQJVRXQG¡
0,', 0XVLFDO,QVWUXPHQW'LJLWDO,QWHUIDFH ¡
0,',OLEUDU\
PLGL2XWVNHWFK
PLOOLVIXQFWLRQ
DGGLWLRQDOLQIRUPDWLRQ
FUHDWLQJGHOD\V
GXUDWLRQRIGHOD\V¡
LQWHUUXSWVDQG
PDQDJLQJWLPH
VLPXOWDQHRXVWRQHVDQG
Index | 621
WLPHUVDQG
PLOOLV'XUDWLRQVNHWFK
0,0( 0XOWLSXUSRVH,QWHUQHW0DLO
([WHQVLRQV PLQIXQFWLRQ
0RGHUQ'HYLFH%DUH%RQHV%RDUGV
PRGXOXV RSHUDWRU
PRPHQWDU\WDFWLOHVZLWFKHV
0RUQLQJ$ODUPIXQFWLRQ
0RUVHVNHWFK
PRVHULDOSURJUDP
PRWLRQGHWHFWLRQ
PRWRUV
VHHDOVREUXVKHGDQGEUXVKOHVVPRWRUV
VHUYRPRWRUVVROHQRLGVDQGUHOD\VVWHSSHU
PRWRUV
PRXVH
GHWHFWLQJPRYHPHQWVRI¡
PRYLQJFXUVRU¡
0RXVHVNHWFK
PRXVH%HJLQIXQFWLRQ
0V7LPHUOLEUDU\
PXOWLPHWHUV
PXOWLSOH[HUVNHWFK
PXOWLSOH[HUVUHDGLQJPXOWLSOHLQSXWV¡
PXOWLSOH[LQJWHFKQLTXH
DERXW
FRQWUROOLQJ/('PDWUL[YLD¡
GULYLQJVHJPHQW/('GLVSOD\V¡
PXOWLSOHBDODUPVVNHWFK
PXOWLSOLFDWLRQ RSHUDWRU
0XOWLSXUSRVH,QWHUQHW0DLO([WHQVLRQV
0,0( 0XOWL5;VNHWFK
0XVLFDO,QVWUXPHQW'LJLWDO,QWHUIDFH 0,', ¡
P\'HOD\IXQFWLRQ
N
?Q OLQHIHHG QDPLQJFRQYHQWLRQVIRUIXQFWLRQV
1DUFROHSWLFOLEUDU\
QHJDWLYHQXPEHUV
QHRFDW
1HWZRUN7LPH3URWRFRO 173 1HZ6RIW6HULDOOLEUDU\
GRZQORDGLQJ
JHWWLQJORFDWLRQIURP*36
622 | Index
UHFHLYLQJGDWDIURPPXOWLSOHGHYLFHV¡
VHQGLQJGDWDWRPXOWLSOHGHYLFHV¡
1HZ6RIW6HULDO,QSXWVNHWFK
1HZ6RIW6HULDO2XWSXWVNHWFK
1.&(OHFWURQLFV
10($SURWRFRO¡
QR%OLQNIXQFWLRQ
QRW RSHUDWRU
QRWHTXDOWR RSHUDWRU
173 1HWZRUN7LPH3URWRFRO QXOOYDOXH
QXPEHUVQXPHULFGDWD
FRPSDULQJWRFKDUDFWHU¡
FRQVWUDLQLQJWRUDQJHRIYDOXHV
FRQYHUWLQJ$6&,,FKDUDFWHUVWR
FRQYHUWLQJVWULQJVWR
FRQYHUWLQJWRVWULQJV¡
GHWHUPLQLQJDEVROXWHYDOXH
/&'GLVSOD\VDQG¡
QHJDWLYH
SURJUDPPHPRU\DQG¡
UDLVLQJWRDSRZHU
VHQGLQJIURP$UGXLQR¡
VTXDUHURRWV
1XPEHU7R6WULQJVNHWFK
QXQFKXFNBDFFHO[IXQFWLRQ
QXQFKXFNBGHFRGHBE\WHIXQFWLRQ
QXQFKXFNBJHWBGDWDIXQFWLRQ
QXQFKXFNBLQLWIXQFWLRQ
QXQFKXFNBOLQHVVNHWFK
QXQFKXFNBVHWSRZHUSLQVIXQFWLRQ
O
2&5 2XWSXW&RPSDUH5HJLVWHU 2KP¦VODZ
RQFH2QO\IXQFWLRQ
RSWRFRXSOHUV RSWRLVRODWRUV
DERXW
FRQWUROOLQJGLJLWDOFDPHUDV
WULJJHULQJUHPRWHFRQWUROV¡
2SWR5HPRWHVNHWFK
2XWSXW&RPSDUH5HJLVWHU 2&5 P
3DFKXEHIHHGV
PRQLWRULQJ¡
XSGDWLQJ¡
SDFNLQJVWUXFWXUHV
SDQHOPHWHUV¡
3DUDOOD[
+0%FRPSDVVPRGXOH¡
3,1* XOWUDVRQLFGLVWDQFHVHQVRU¡
3,56HQVRU
5),'UHDGHU¡
SDUDPHWHUV
GHILQHG
DVUHIHUHQFHV
3DVVLYH,QIUDUHG 3,5 VHQVRUV
3&HQYLURQPHQW VHH:LQGRZVHQYLURQPHQW
3&)$SRUWH[SDQGHU¡
3&0 3XOVH&RGH0RGXODWLRQ SGHILOHH[WHQVLRQ
SHUVLVWHQFHRIYLVLRQ
3KLOLSV
5&UHPRWH
5&UHPRWH
6$$,&WRVHJPHQWGULYHU¡
SKRWRFHOOV
SK\VLFDORXWSXW VHHEUXVKHGDQGEUXVKOHVV
PRWRUVVHUYRPRWRUVVROHQRLGVDQG
UHOD\VVWHSSHUPRWRUV
3,FRQVWDQW
3LH]RGHYLFHV
GHILQHG
GHWHFWLQJYLEUDWLRQ
JHQHUDWLQJDXGLRWRQHV
SLH]RVNHWFK
3LQJ 6HQVRUVNHWFK
SLQ0RGHIXQFWLRQ
DGGLWLRQDOLQIRUPDWLRQ
GLJLWDORXWSXWDQG
IXQFWLRQDOLW\
LQWHUQDOSXOOXSUHVLVWRUVDQG
SLQV VHHDQDORJSLQVGLJLWDOSLQV
3,5 3DVVLYH,QIUDUHG VHQVRUV
3,5VNHWFK
SL[HOV
GHILQHG
LQ*/&'GLVSOD\V
VPDOOHUWKDQVLQJOHFKDUDFWHU¡
3-5&
SOD\0LGL1RWHIXQFWLRQ
SOD\1RWHIXQFWLRQ
3OD\6WDWLRQJDPHFRQWUROOHU
FRQWUROOLQJ*RRJOH(DUWKYLD¡
JHWWLQJLQSXWIURP¡
VHQVRUVDQG
SOD\7RQHIXQFWLRQ¡
3RFNHW3LDQRVKLHOG
SRODULW\GHILQHG
SROOLQJGHILQHG
3ROROXEUHDNRXWERDUG
SRUWH[SDQGHUVLQWHJUDWLQJ¡
SRUWIRUZDUGLQJ
326,;WLPH
3267FRPPDQG¡¡
3RWVNHWFK
SRWHQWLRPHWHUV
DERXW
FKDQJLQJUDQJHRIYDOXHV
FRQWUROOLQJVHUYRVZLWK
UHDGLQJYROWDJH
ZLSHU
3RWB'HEXJVNHWFK
SRZIXQFWLRQ
SRZHUVXSSOLHV
FRQQHFWLQJXVLQJH[WHUQDO
UHGXFLQJEDWWHU\GUDLQ¡
SUHFHGHQFHRIRSHUDWRUV
SUHSURFHVVRU
DERXW
DGGLWLRQDOLQIRUPDWLRQ
FRQVWDQWYDOXHVDQG¡
FRQWUROOLQJVNHWFKEXLOG
SUHSURFHVVRUPDFURV
SUHVFDOHUGHILQHG
SULPLWLYHW\SHVVLPSOH
SULQW'LJLWVIXQFWLRQ
3URFHVVLQJRSHQVRXUFHWRRO
DERXW
DGGLWLRQDOLQIRUPDWLRQ
FRQWUROOLQJ*RRJOH(DUWK¡
FUHDWH:ULWHUIXQFWLRQ
FUHDWLQJELWPDSV
'DWH)RUPDWIXQFWLRQ
GUDZIXQFWLRQ
PRYLQJPRXVHFXUVRU¡
UHFHLYLQJELQDU\GDWD¡
VDYLQJGDWDWRORJILOHV¡
VHQGLQJELQDU\YDOXHV¡
VHQGLQJPXOWLSOHWH[WILHOGVLQPHVVDJHV¡
VHQGLQJSLQYDOXHV¡
Index | 623
VHQGLQJUHFHLYLQJPHVVDJHVZLWK8'3
VHWWLQJXSHQYLURQPHQW
VHWXSIXQFWLRQ
6\QF$UGXLQR&ORFNVNHWFK
:LLQXQFKXFNVNHWFK
3URJPHP&XUYHVNHWFK
SURJUDPPHPRU\
DERXW
$UGXLQRERDUGVDQG
VWRULQJUHWULHYLQJQXPHULFYDOXHV¡
VWRULQJUHWULHYLQJVWULQJV¡
ZHESDJHVDQG¡
SURJUDPPLQJWHFKQLTXHV
VHHDOVRVSHFLILFVNHWFKHV
$UGXLQREXLOGSURFHVV¡
FRQGLWLRQDOFRPSLODWLRQV
FRQVWDQWVDQG¡
GHOD\LQJFRGHH[HFXWLRQ
PHPRU\XVDJHDQG¡
VWRULQJUHWULHYLQJQXPHULFYDOXHV¡
VWRULQJUHWULHYLQJVWULQJV¡
WURXEOHVKRRWLQJSUREOHPV¡
SURJUDPV VHHVNHWFKHV
SURMHFWVJHWWLQJVWDUWHGZLWK¡
SURWRW\SLQJ
EUHDGERDUGVDQG
GHILQHG
36; VHH3OD\6WDWLRQJDPHFRQWUROOHU
36;VNHWFK
SXOOGRZQUHVLVWRUV
GHILQHG
VZLWFKHGFRQQHFWHGXVLQJ
SXOOXSUHVLVWRUV
GHILQHG
HQDEOLQJLQWHUQDO¡
VZLWFKFRQQHFWHGXVLQJ
3XOOXSVNHWFK
3XOVH:LGWK0RGXODWLRQ VHH3:0
3XOVH&RGH0RGXODWLRQ 3&0 SXOVH,QIXQFWLRQ
3XOVH,QVNHWFK
SXOVHV
FRXQWLQJ¡
GLVSOD\LQJLQ6HULDO0RQLWRU¡
JHQHUDWLQJ¡
PHDVXULQJDFFXUDWHO\¡
PHDVXULQJGXUDWLRQ
VHWWLQJZLGWKGXUDWLRQ¡
SXOVH7LPHUVNHWFK
624 | Index
3XVKEXWWRQVNHWFK
3X77<SURJUDP
3:0 3XOVH:LGWK0RGXODWLRQ
DGGLWLRQDOLQIRUPDWLRQ
DGMXVWLQJ/('EULJKWQHVV
DQDORJSDQHOPHWHUV¡
FKDQJLQJIUHTXHQF\IRUWLPHUV¡
GHILQHG
H[WHQGHUFKLSV¡
SZPIXQFWLRQ
R
?U FDUULDJHUHWXUQ 5DGLR6KDFNEUHDGERDUG
5$'B72B'(*FRQVWDQW
5$0 UDQGRPDFFHVVPHPRU\ ¡
UDQGRPIXQFWLRQ¡
UDQGRPQXPEHUJHQHUDWLRQ¡
5DQGRPVNHWFK
UDQGRP6HHGIXQFWLRQ
5HDGDURWDU\HQFRGHUVNHWFK
UHDG$UGXLQR,QWIXQFWLRQ
UHDG6WDWXVIXQFWLRQ
UHDOWLPHFORFN 57& ¡¡
5HDO7HUPSURJUDP
5HFHLYH%LQDU\'DWDB3VNHWFK
5HFHLYH0XOWLSOH)LHOGV%LQDU\7R)LOHB3VNHWFK
5HFHLYH0XOWLSOH)LHOGV%LQDU\B3VNHWFK
UHIHUHQFHVSDUDPHWHUVDV
UHJLVWHUV
VHHDOVRVSHFLILFW\SHVRIUHJLVWHUV
GHILQHG
WLPHRSHUDWLRQVDQG
WLPHUPRGHVHWWLQJV
UHODWLRQDORSHUDWRUV¡
5HODWLRQDO([SUHVVLRQVVNHWFK
UHOD\V VHHVROHQRLGVDQGUHOD\V
UHPDLQGHUDIWHUGLYLVLRQ
UHPRWHFRQWURO
DERXW
FRQWUROOLQJ$&GHYLFHV¡
FRQWUROOLQJGLJLWDOFDPHUDV¡
GHFRGLQJ,5VLJQDOV¡
LPLWDWLQJVLJQDOV¡
LQIUDUHG¡
ZLUHOHVVWHFKQRORJ\DQG
5HPRWH'HFRGHVNHWFK
UHSHDWLQJ
VHTXHQFHRIVWDWHPHQWV
VWDWHPHQWVZLWKFRXQWHUV¡
5HSHDWVIXQFWLRQ
UHVHWIXQFWLRQ
UHVLVWLYHVHQVRUV
UHVLVWRUV
DERXW
FDOFXODWLQJYDOXHLQRKPV
/'5
/('PDWUL[DQG
2KP¦VODZ
SXOOGRZQ
SXOOXS
VKRUWFLUFXLWVDQG
VZLWFKHVZLWKRXWH[WHUQDO¡
YDULDEOH
5HVSRQGLQJ7R&KDQJHVVNHWFK
UHYHUVH(0)
5),'VNHWFK
5),'WDJVUHDGLQJ¡
5*%FRORUVFDOH¡¡
5*%B/('VVNHWFK
5REHUWVRQ0DWW
5RERWFODVV -DYD
DGGLWLRQDOLQIRUPDWLRQ
PRXVH0RYHPHWKRG
URWDU\HQFRGHUV
IXQFWLRQDOLW\
PHDVXULQJSXOVHVIURP
WUDFNLQJPRYHPHQWRIGLDO¡¡
WUDFNLQJPXOWLSOH¡
5RWDU\(QFRGHU,QWHUUXSWVNHWFK
5RWDU\(QFRGHU0XOWL3ROOVNHWFK
URWDWLRQ
GHWHFWLQJZLWKJ\URVFRSH¡
PHDVXULQJ¡¡
URXQGLQJIORDWLQJSRLQWQXPEHUV
56VWDQGDUG
57& UHDOWLPHFORFN ¡¡
S
VFKHPDWLFGLDJUDPV
6&/FRQQHFWLRQ ,& 6FUROOVNHWFK
VFUROOLQJWH[W¡
6'OLEUDU\
6'$FRQQHFWLRQ ,& VHFXULW\(WKHUQHWOLEUDU\DQG
6HHHG6WXGLR%D]DDU
VHPLFRORQLQIXQFWLRQV
VHQG%LQDU\IXQFWLRQ
6HQG%LQDU\VNHWFK
VHQG&RPPDQGIXQFWLRQ
6HQGLQJ%LQDU\)LHOGVVNHWFK
6HQGLQJ%LQDU\7R$UGXLQRVNHWFK
6HQG,QSXW$3,IXQFWLRQ
VHQG0HVVDJHIXQFWLRQ
VHQVRUV
DERXW
DGGLWLRQDOLQIRUPDWLRQ
FRQQHFWLQJFDSDFLWRUVWR
FRQWUROOLQJDQ/('PDWUL[¡
FRQWUROOLQJEUXVKHGPRWRUV¡
FRQWUROOLQJ*RRJOH(DUWKYLD¡
FRQWUROOLQJVHUYRVZLWK
GHWHFWLQJGLUHFWLRQ¡
GHWHFWLQJOLJKWOHYHOFKDQJHV
GHWHFWLQJPRWLRQ
GHWHFWLQJPRXVHPRYHPHQWV¡
GHWHFWLQJPRYHPHQW¡
GHWHFWLQJURWDWLRQZLWKJ\URVFRSH¡
GHWHFWLQJVRXQG¡
GHWHFWLQJYLEUDWLRQ
JHWWLQJLQSXWIURPJDPHFRQWUROSDG¡
JHWWLQJORFDWLRQIURP*36¡
PHDVXULQJGLVWDQFH¡
PHDVXULQJWHPSHUDWXUH¡¡
UHDGLQJDFFHOHUDWLRQ
UHDGLQJ5),'WDJV¡
UHDGLQJYROWDJH
UHVLVWLYH
VHQGLQJGDWDEHWZHHQ;%HHV¡
VHQGLQJ7ZLWWHUPHVVDJHV¡
VHTXHQFLQJPXOWLSOH/('V
WHPSHUDWXUH¡
WUDFNLQJPRYHPHQWRIGLDO¡¡
WUDFNLQJPXOWLSOHURWDU\HQFRGHUV¡
VHULDOFRPPXQLFDWLRQV
DERXW¡
DGGLWLRQDOLQIRUPDWLRQ
FRQWUROOLQJ*RRJOH(DUWK¡
FRQWUROOLQJVHUYRV¡
JHWWLQJORFDWLRQIURP*36
PRYLQJPRXVHFXUVRU¡
Index | 625
UHFHLYLQJELQDU\GDWD¡
UHFHLYLQJGDWD¡
UHFHLYLQJGDWDIURPPXOWLSOHGHYLFHV¡
UHFHLYLQJPXOWLSOHWH[WILHOGVLQPHVVDJHV
¡
VDYLQJGDWDWRORJILOHV¡
VHQGLQJELQDU\GDWD¡
VHQGLQJELQDU\YDOXHVIURP3URFHVVLQJ¡
VHQGLQJGDWDWRPXOWLSOHGHYLFHV¡
VHQGLQJGHEXJLQIRUPDWLRQ¡
VHQGLQJIRUPDWWHGWH[W¡
VHQGLQJPXOWLSOHWH[WILHOGVLQPHVVDJHV¡
VHQGLQJQXPHULFGDWD¡
VHQGLQJSLQYDOXHV¡
VHULDOKDUGZDUH
VHULDOOLEUDULHV
VHULDOPHVVDJHSURWRFRO
VHWWLQJXS3URFHVVLQJHQYLURQPHQW
7HOO\0DWHVKLHOGDQG
6HULDOOLEUDU\
DYDLODEOHIXQFWLRQ
EHJLQIXQFWLRQ
ELWYDOXHV
SULQWIXQFWLRQ
SULQWOQIXQFWLRQ
UHDGIXQFWLRQ
6HULDO0RQLWRU
FRQWUROOLQJEUXVKHGPRWRUV
GHSLFWHG
'+&3VHUYHUYDOXHV
GLVSOD\LQJSXOVHVLQ¡
GLVSOD\LQJYROWDJHV¡
IXQFWLRQDOLW\
JHWWLQJORFDWLRQIURP*36
PHDVXULQJGLVWDQFH
SULQWLQJVHTXHQWLDOQXPEHUV¡
SULQWLQJYDOXHVWRFRPSXWHU
VHWWLQJFORFNV
VHWWLQJSXOVHSHULRG¡
VWDUWLQJ
6HULDO3HULSKHUDO,QWHUIDFH VHH63,
6HULDO7HUPLQDOZLQGRZ
6HULDO)RUPDWWLQJVNHWFK
VHULDO,QIXQFWLRQ
6HULDO0RXVHVNHWFK
VHULDO2XWIXQFWLRQ
626 | Index
6HULDO2XWSXWVNHWFK
6HULDO5HFHLYHVNHWFK
6HULDO5HFHLYH0XOWLSOH)LHOGVVNHWFK
6HUYROLEUDU\
DERXW
DWWDFKPHWKRG
WLPHUVDQG
VHUYRPRWRUV
DERXW
FRQWUROOLQJIURPVHULDOSRUW¡
FRQWUROOLQJPXOWLSOH
FRQWUROOLQJSRVLWLRQRI¡
VSHHGRIFRQWLQXRXVURWDWLRQVHUYRV¡
VHW&RORUIXQFWLRQ
VHW3XOVH:LGWKIXQFWLRQ
VHW6SHHGIXQFWLRQ
VHW6\QF3URYLGHUIXQFWLRQ
VHW7LPHIXQFWLRQ
VHWXSIXQFWLRQ $UGXLQR VHWXSIXQFWLRQ 3URFHVVLQJ 6HYHQ6HJPHQWVNHWFK
6HYHQ6HJPHQW0S[VNHWFK
VKDNHQVNHWFK
6KDUS*3<$<.)VHQVRU¡
VKLIWUHJLVWHUV
FRQWUROOLQJ/('DUUD\V¡
GULYLQJVHJPHQWGLVSOD\V¡
6KLUULII.HQ
VKRUWFLUFXLWV
VKRZIXQFWLRQ
VKRZ'LJLWIXQFWLRQ
VKRZ3ULYDWHIXQFWLRQ
VKRZ6\PEROIXQFWLRQ
VKRZ;<IXQFWLRQ
VLJQHGNH\ZRUG
6LPSOH%UXVKHGVNHWFK
6LPSOH&OLHQW*RRJOH:HDWKHU'+&3VNHWFK
6LPSOH&OLHQWZ)LQGHUVNHWFK
6LPSOH5HDGVNHWFK
6LPSOH5HFHLYHVNHWFK
6LPSOH6HQGVNHWFK
VLQHIXQFWLRQ
VL]HRIIXQFWLRQ
6NHWFK(GLWRU
IXQFWLRQDOLW\
RSHQLQJ
VNHWFKHV
VHHDOVRVSHFLILFVNHWFKHV
DFWLRQVEDVHGRQFRQGLWLRQV
DFWLRQVEDVHGRQYDULDEOHV¡
$UGXLQREXLOGSURFHVVDQG
DUUD\VLQ¡
ELWZLVHRSHUDWLRQV¡
EUHDNLQJRXWRIORRSV
FRPSDULQJFKDUDFWHUQXPHULFYDOXHV¡
FRPSDULQJVWULQJV
FRPSRXQGRSHUDWRUV
FRQWUROOLQJEXLOGRI
FRQYHUWLQJQXPEHUVWRVWULQJV¡
FRQYHUWLQJVWULQJVWRQXPEHUV
FUHDWLQJ¡
GHILQHG
HUURUPHVVDJHV
IORDWLQJSRLQWQXPEHUVLQ
IXQFWLRQDOEORFNVLQ¡
/('EOLQNLQJFRGHH[DPSOH¡¡
OLEUDULHVDQG
ORJLFDOFRPSDULVRQV
PDQLSXODWLQJVWULQJV¡
SUHSDULQJZLWK,'(¡
UHSHDWLQJVHTXHQFHRIVWDWHPHQWV
UHSHDWLQJVWDWHPHQWVZLWKFRXQWHUV¡
UHWXUQLQJPXOWLSOHYDOXHVIURPIXQFWLRQV
¡
VDYLQJ¡
VLPSOHSULPLWLYHW\SHV
VWUXFWXULQJ
VODYHGHYLFHV
DGGUHVVQXPEHUVDQG
FRPPXQLFDWLQJEHWZHHQ$UGXLQRERDUGV
¡
GHILQHG
LGHQWLI\LQJ
VOHHSIXQFWLRQ
61+%ULGJH
VQXEEHUGLRGHV
6RIWZDUH6HULDOOLEUDU\¡
VROGHUOHVVEUHDGERDUGV
VROHQRLGVDQGUHOD\V
DERXW
FRQWUROOLQJ¡
VROLGVWDWHUHOD\ 665 VRXQG VHHDXGLRRXWSXW
6RXWKHUQ+HPLVSKHUHVNHWFK
6SDUN)XQ
EXWWRQNH\SDG¡
DFFHOHURPHWHUVHOHFWLRQJXLGH
$UGXPRWRVKLHOG
$XGLR6RXQG0RGXOH
%2%GDWDVKHHW
(OHFWUHW0LFURSKRQH
JUHHQ/('V
/,6<$/EUHDNRXWERDUG
0,',EUHDNRXWVKLHOG
03EUHDNRXWERDUG
3,50RWLRQ6HQVRU
357EUHDGERDUG
52%YLEUDWLRQPRWRU
52%EUHDNRXWERDUG
:5/
:5/
;%HH([SORUHU86%
VSHDNHUVGHILQHG
VSHHG
FRQWLQXRXVURWDWLRQVHUYRVDQG¡
FRQWUROOLQJIRUEUXVKHGPRWRUV¡¡
WUDFNLQJPRYHPHQWRIGLDO¡
VSHHGFRQWUROOHUV
GHILQHG
GULYLQJEUXVKOHVVPRWRUV
63, 6HULDO3HULSKHUDO,QWHUIDFH
DERXW¡
GULYLQJVHJPHQWGLVSOD\V¡
63,OLEUDU\
63,B0$;BVNHWFK
VSOLWPHWKRG -DYD 6SOLW6SOLWVNHWFK
6SULWHOLEUDU\
VTUWIXQFWLRQ
VTXDUHURRWV
65(* LQWHUUXSWUHJLVWHUV 665 VROLGVWDWHUHOD\ VWDUW0HDVXUHPHQWIXQFWLRQ
VWDWHPHQWV
UHSHDWLQJVHTXHQFHRI
UHSHDWLQJZLWKFRXQWHUV¡
VWDWLFYDULDEOHV
6WHSSHUOLEUDU\
VWHSSHUPRWRUV
DERXW
GULYLQJELSRODU¡¡
GULYLQJXQLSRODU¡
6WHSSHUVNHWFK
Index | 627
6WHSSHUBELSRODUVNHWFK
6WHSSHUB(DV\VWHSSHUVNHWFK
VWUFDWIXQFWLRQ
VWUFPSIXQFWLRQ
VWUFS\IXQFWLRQ
6WUHDPLQJOLEUDU\
6WULQJFODVV
VWULQJGDWDW\SH
6WULQJOLEUDU\
DGGLWLRQDOLQIRUPDWLRQ
&ODQJXDJHDQG
PDQLSXODWLQJVWULQJV¡
VWULQJV
DOORFDWLQJVSDFHIRU
DUUD\VDQG¡
&ODQJXDJHDQG
FRPSDULQJ
FRQFDWHQDWLQJ
FRQYHUWLQJQXPEHUVWR¡
FRQYHUWLQJWRQXPEHUV
FRS\LQJ
GDWDW\SHUHSUHVHQWLQJ
GHFODULQJ
GHILQHG
GHWHUPLQLQJOHQJWKRI
PDQLSXODWLQJ¡
PXOWLSOHILHOGVLQ¡
QXOOLQ
VSOLWWLQJFRPPDVHSDUDWHGWH[WLQWRJURXSV
¡
VWRULQJUHWULHYLQJLQSURJUDPPHPRU\¡
VWUOHQIXQFWLRQ
VWUQFPSIXQFWLRQ
VWUWRNBUIXQFWLRQ
VWUXFWXUHV
ELQDU\IRUPDWFRQVLGHUDWLRQV
SDFNLQJ
VXEVWULQJIXQFWLRQ
VXEWUDFWLRQ RSHUDWRU
VZDSIXQFWLRQ
VZDSVNHWFK
6ZHHSVNHWFK¡
VZLWFKVWDWHPHQW¡
6ZLWFK&DVHVNHWFK
VZLWFKHV
DERXW
GHWHFWLQJFORVLQJRI¡
GHWHFWLQJPRYHPHQWDQG¡
628 | Index
GHWHUPLQLQJVWDWHRI¡
GHWHUPLQLQJWLPHLQFXUUHQWVWDWH¡
KDFNLQJUHPRWHFRQWURO¡
LQWHUUXSWVDQG
UHDGLQJPXOWLSOHDQDORJLQSXWV¡
WDFWLOH
ZLWKRXWH[WHUQDOUHVLVWRUV¡
VZLWFK7LPHIXQFWLRQ¡
6ZLWFK7LPHVNHWFK
6ZLWFK7LPH0XOWLSOHVNHWFK
V\PEROV
FUHDWLQJFXVWRP¡
GLVSOD\LQJ¡
ODUJHUWKDQVLQJOHFKDUDFWHU¡
6\QF$UGXLQR&ORFNVNHWFK
V\QFKURQL]DWLRQ
ELQDU\GDWDDQG
FORFNVRIWZDUH¡
V\QWKHVL]HUV
PDNLQJ¡
0,',¡
T
WDFWLOHVZLWFKHV
WDNH3LFWXUHIXQFWLRQ
WDQIXQFWLRQ
7&3 7UDQVPLVVLRQ&RQWURO3URWRFRO WG!WDJ
7HOO\%RXQFHVNHWFK
7HOO\0DWHVKLHOG¡
7HOO\0DWHVNHWFK
WHPSHUDWXUHPHDVXULQJ¡¡
¡
7H[DV,QVWUXPHQW703¡
WH[WILHOGVGDWD
GLVSOD\LQJRQ79¡
IRUPDWWLQJIRU/&'GLVSOD\V¡
/&'GLVSOD\VDQG¡
UHFHLYLQJLQPHVVDJHV¡
VFUROOLQJ¡
VHQGLQJIRUPDWWHG¡
VHQGLQJLQPHVVDJHV¡
7H[W)LQGHUOLEUDU\
DERXW
ILQGPHWKRG
ILQG8WLOPHWKRG
JHW)ORDWPHWKRG
JHW6WULQJPHWKRG
JHW9DOXHPHWKRG
7H[W6WULQJOLEUDU\
WKHUHPLQ
WKHUPRPHWHUVGLJLWDO¡
WLOWVHQVRUV¡¡
WLOWVNHWFK
WLPHGHOD\V
VHHDOVRGHOD\IXQFWLRQ
DQLPDWLRQHIIHFWVDQG
FUHDWLQJ
VHWWLQJGHOD\SHULRG
WLPHODSVHSKRWRJUDSK\
7LPHOLEUDU\¡
WLPHPHDVXUHPHQW
VHHDOVRPLOOLVIXQFWLRQ
DODUPVWRFDOOIXQFWLRQV¡
GLVSOD\LQJWLPHRIGD\¡
GXUDWLRQRIGHOD\V¡
GXUDWLRQRISXOVHV
IRUSUHVVHGVZLWFKHV¡
UHDOWLPHFORFNV¡¡
UHGXFLQJEDWWHU\GUDLQ¡
V\QFKURQL]LQJFORFNVRIWZDUH¡
WLPHFRQYHUVLRQWRROV
7LPHVNHWFK
7LPH$ODUP([DPSOHVNHWFK
7LPH$ODUPVOLEUDU\¡¡
WLPHEDVHGHILQHG
7LPHG$FWLRQOLEUDU\
WLPHRXWVSHFLI\LQJ
WLPHUUHJLVWHUV
7LPHUOLEUDU\
WLPHUV
DGGLWLRQDOLQIRUPDWLRQ
FKDQJLQJ3:0IUHTXHQF\¡
FRXQWGRZQ¡
GHILQHG
VHWWLQJGXUDWLRQ¡
VHWWLQJSXOVHZLGWKGXUDWLRQ¡
W\SHVVXSSRUWHG
7LPH57&VNHWFK
7LPH57&6HWVNHWFK
7LPH6HULDOVNHWFK
7LPHB173VNHWFK
7LQ\*36OLEUDU\¡
7/&VNHWFK
7/&FKLS¡
7OFOLEUDU\
DERXW
DGGLWLRQDOLQIRUPDWLRQ
FOHDUPHWKRG
LQLWPHWKRG
180B7/&6FRQVWDQW
VHWPHWKRG
VHW$OOPHWKRG
XSGDWHPHWKRG
7RGERWDGDSWHUV
WRQHIXQFWLRQ
DERXW
PXOWLSOHVLPXOWDQHRXVWRQHV
SOD\LQJVLPSOHPHORGLHV¡
SOD\LQJWRQHV¡
7RQHOLEUDU\
7RQHVNHWFK
WRUTXHPRWRU
7RVKLED)%)1*
WU!WDJ
WUDQVGXFHUV
7UDQVLVWRU7UDQVLVWRU/RJLF 77/ WUDQVLVWRUV
DERXW
FKRRVLQJIRUVZLWFKLQJ
FRQWUROOLQJVROHQRLGVDQGUHOD\V
GULYLQJEUXVKHGPRWRUV
GULYLQJKLJKSRZHU/('V
7UDQVPLVVLRQ&RQWURO3URWRFRO 7&3 WUDQVPLW&DUULHUIXQFWLRQ
WULJRQRPHWULFIXQFWLRQV
WURXEOHVKRRWLQJ
GHYLFHFRQQHFWLRQV
KDUGZDUHSUREOHPV¡
VRIWZDUHSUREOHPV¡
;%HHPRGXOHV
756FRQQHFWRU
77/ 7UDQVLVWRU7UDQVLVWRU/RJLF 77/OHYHOGHILQHG
79GLVSOD\LQJWH[WRQ¡
7ZLQNOHVNHWFK
7ZLWWHUOLEUDU\
GRZQORDGLQJ
SRVWIXQFWLRQ
ZDLWIXQFWLRQ
7ZLWWHUPHVVDJHVVHQGLQJ¡
U
8$57V
8'3 8VHU'DWDJUDP3URWRFRO ¡
8GS1WSVNHWFK
8'36HQG5HFHLYHVNHWFK
Index | 629
8'36HQG5HFHLYH6WULQJVVNHWFK
8'37HVWVNHWFK
8/1$'DUOLQJWRQGULYHUFKLS¡
XQLSRODUVWHSSHUV
DERXW
GULYLQJ¡
8QL[WLPH
XQVLJQHGNH\ZRUG
86%SURWRFRO
ERDUGVDQG
GLJLWDOSLQVDQG
+,'DQG
0,',GHYLFHVDQG
VHULDOFRPPXQLFDWLRQVDQG
;%HHDGDSWHUV
8VHU'DWDJUDP3URWRFRO 8'3 ¡
86*OREDO6DW(0$*36PRGXOH
87& &RRUGLQDWHG8QLYHUVDO7LPH V
YDULDEOHUHVLVWRUV
YDULDEOHV
DFWLRQVEDVHGRQ¡
GHILQHG
JOREDO
VLPSOHSULPLWLYHW\SHV
VWDWLF
YRODWLOH
YHUVLRQFRQWURO
9LEUDWHVNHWFK
9LEUDWHB3KRWRFHOOVNHWFK
YLEUDWLRQ
GHWHFWLQJ
PDNLQJREMHFWVVKDNH¡
9LUWXDO:LUHOLEUDU\¡
YLVXDORXWSXW VHH/('V
YRLGGDWDW\SH
YRODWLOHYDULDEOHV
YROWDJH
FKDQJLQJUDQJHRIYDOXHV
GLJLWDOPRQLWRULQJ
GLJLWDORXWSXWDQG
GLVSOD\LQJ¡
IRUZDUG
NQRFNVHQVRUVDQG
/&'GLVSOD\VDQG
/('VSHFLILFDWLRQV
PHDVXULQJ¡
PHDVXULQJSXOVHGXUDWLRQ
630 | Index
UHDGLQJRQDQDORJSLQV
UHVSRQGLQJWRFKDQJHVLQ
UHYHUVH(0)
YROWDJHGLYLGHU
9:B0$;B0(66$*(B/(1FRQVWDQW
W
:$9ILOHVSOD\LQJ¡
:DYH6KLHOG3OD\6HOHFWLRQVNHWFK
ZHESDJHV
FUHDWLQJZLWKIRUPV¡
KDQGOLQJUHTXHVWVIRU¡
ODUJHDPRXQWVRIGDWDDQG¡
ZHEVHUYHUV
IRUPDWWLQJUHTXHVWV¡
KDQGOLQJUHTXHVWV¡
KDQGOLQJUHTXHVWVIRUVSHFLILFSDJHV¡
UHTXHVWLQJGDWDIURP¡
UHTXHVWLQJGDWDLQ;0/¡
VHWWLQJXS$UGXLQR¡
:HE&OLHQW'+&3B'16VNHWFK
:HE&OLHQW'16VNHWFK
:HE&OLHQW*RRJOH)LQDQFHVNHWFK
:HE&OLHQWB%DEHOILVKVNHWFK
:HEGXLQRZHEVHUYHU
:HE6HUYHU0XOWL3DJHVNHWFK
:HE6HUYHU0XOWL3DJH+70/VNHWFK
:HE6HUYHU0XOWL3DJH+70/3URJPHPVNHWFK
:HE6HUYHU3DUVLQJVNHWFK
:HE6HUYHU3RVWVNHWFK
:HEB6HUYHUVNHWFK
ZKLOHORRS
:LLQXQFKXFN
DFFHOHURPHWHULQ¡
FRQWUROOLQJ*RRJOH(DUWKYLD
:LLFKXFN6HULDOVNHWFK
:LQGRZVHQYLURQPHQW
$UGXLQR,'(LQVWDOODWLRQ
PRYLQJPRXVHFXUVRU¡
;%HH6HULHVFRQILJXUDWLRQ
;%HH6HULHVFRQILJXUDWLRQ
:LUHOLEUDU\
DERXW
DFFHVVLQJ57&V¡
DGGLQJ
DGGLWLRQDOLQIRUPDWLRQ
DYDLODEOHIXQFWLRQ
EHJLQIXQFWLRQ
EHJLQ7UDQVPLVVLRQIXQFWLRQ
FUHDWLQJOLEUDULHVH[DPSOH
HQG7UDQVPLVVLRQIXQFWLRQ
UHFHLYHIXQFWLRQ
UHTXHVW)URPIXQFWLRQ
VHQGIXQFWLRQ
ZLUHOHVVFRPPXQLFDWLRQ
DFWLYDWLQJDFWXDWRUV¡
FRQQHFWLQJWRQHWZRUN¡
FRQQHFWLQJWR=LJ%HHQHWZRUNV¡
UHPRWHFRQWUROVDQG
VHQGLQJPHVVDJHVWR;%HHV¡
VHQGLQJPHVVDJHVYLD¡
VHQVRUGDWDEHWZHHQ;%HHV
ZRUGIXQFWLRQ¡
FRQQHFWLQJWRQHWZRUNV¡
=7HUPSURJUDP
X
;&78DSSOLFDWLRQ
;%HH6HULHVFRQILJXUDWLRQ
;%HH6HULHVFRQILJXUDWLRQ
;%HH$FWXDWHVNHWFK
;%HHPRGXOHV
DERXW
DFWLYDWLQJDFWXDWRUV¡
FRQQHFWLQJWRQHWZRUNV¡
FRQQHFWLQJWR=LJ%HHQHWZRUNV¡
5HPRWH$7&RPPDQGIHDWXUH
VHQGLQJPHVVDJHVWR¡
VHQGLQJVHQVRUGDWDEHWZHHQ¡
WURXEOHVKRRWLQJ
=LJ%HHFRPSDWLELOLW\
;%HH$QDORJ5HFHLYHVNHWFK
;%HH$QDORJ5HFHLYH6HULHVVNHWFK
;%HH(FKRVNHWFK
;%HH0HVVDJHVNHWFK
;0/IRUPDW¡
Z
=DPEHWWL1LFKRODV
]HUR
$6&,,YDOXH
OHDGLQJ
=,*%((&225',1$725$7IXQFWLRQ
=,*%((5287(5$7IXQFWLRQ
=LJ%HHVWDQGDUG
DERXW
Index | 631
Download from Wow! eBook <www.wowebook.com>
About the Author
0LFKDHO0DUJROLVLVDWHFKQRORJLVWLQWKHILHOGRIUHDOWLPHFRPSXWLQJZLWKH[SHUWLVH
LQGHYHORSLQJDQGGHOLYHULQJKDUGZDUHDQGVRIWZDUHIRULQWHUDFWLQJZLWKWKHHQYLURQ
PHQW +H KDV RYHU \HDUV RI H[SHULHQFH LQ D ZLGH UDQJH RI UHOHYDQW WHFKQRORJLHV
ZRUNLQJZLWK6RQ\0LFURVRIW/XFHQW%HOO/DEVDQGPRVWUHFHQWO\DV&KLHI7HFKQLFDO
2IILFHUZLWK$YD\D
Colophon
7KHDQLPDORQWKHFRYHURI$UGXLQR&RRNERRNLVDWR\UDEELW0HFKDQLFDOWR\VOLNHWKLV
RQHPRYHE\PHDQVRIVSULQJVJHDUVSXOOH\VOHYHUVRURWKHUVLPSOHPDFKLQHVSRZHUHG
E\PHFKDQLFDOHQHUJ\6XFKWR\VKDYHDORQJKLVWRU\ZLWKDQFLHQWH[DPSOHVNQRZQ
IURP*UHHFH&KLQDDQGWKH$UDEZRUOG
0HFKDQLFDOWR\PDNLQJIORXULVKHGLQHDUO\PRGHUQ(XURSH,QWKHODWHV*HUPDQ
LQYHQWRU.DUHO*URGGHPRQVWUDWHGIO\LQJZLQGXSWR\V3URPLQHQWVFLHQWLVWVRIWKHGD\
LQFOXGLQJ/HRQDUGRGD9LQFL'HVFDUWHVDQG*DOLOHR*DOLOHLZHUHQRWHGIRUWKHLUZRUN
RQPHFKDQLFDOWR\V'D9LQFL¦VIDPHGPHFKDQLFDOOLRQEXLOWLQIRU/RXLV;,,
ZDONHGXSWRWKHNLQJDQGWRUHRSHQLWVFKHVWWRUHYHDODIOHXUGHOLV
7KHDUWRIPHFKDQLFDOWR\PDNLQJLVFRQVLGHUHGWRKDYHUHDFKHGLWVSLQQDFOHLQWKHODWH
HLJKWHHQWKFHQWXU\ZLWKWKHIDPHG£DXWRPDWD¤RIWKH6ZLVVZDWFKPDNHU3LHUUH-DTXHW
'UR]DQGKLVVRQ+HQUL/RXLV7KHLUKXPDQILJXUHVSHUIRUPHGVXFKOLIHOLNHDFWLRQVDV
GLSSLQJ D SHQ LQ DQ LQNZHOO ZULWLQJ IXOO VHQWHQFHV GUDZLQJ VNHWFKHV DQG EORZLQJ
HUDVHUGXVWIURPWKHSDJH,QWKHQLQHWHHQWKFHQWXU\(XURSHDQDQG$PHULFDQFRPSD
QLHVWXUQHGRXWSRSXODUFORFNZRUNWR\VWKDWUHPDLQFROOHFWLEOHWRGD\
%HFDXVHWKHVHRULJLQDOWR\VZKLFKKDGFRPSOLFDWHGZRUNVDQGHODERUDWHGHFRUDWLRQV
ZHUHFRVWO\DQGWLPHFRQVXPLQJWRPDNHWKH\ZHUHUHVHUYHGIRUWKHDPXVHPHQWRI
UR\DOW\RUWKHHQWHUWDLQPHQWRIDGXOWV2QO\VLQFHWKHODWHQLQHWHHQWKFHQWXU\ZLWKWKH
DSSHDUDQFHRIPDVVSURGXFWLRQDQGFKHDSPDWHULDOV WLQDQGODWHUSODVWLF KDYHPH
FKDQLFDOWR\VEHHQFRQVLGHUHGSOD\WKLQJVIRUFKLOGUHQ7KHVHLQH[SHQVLYHPRYLQJQRY
HOWLHVZHUHSRSXODUIRUDERXWDFHQWXU\XQWLOEDWWHU\RSHUDWHGWR\VVXSHUVHGHGWKHP
7KH FRYHU LPDJH LV IURP WKH 'RYHU 3LFWRULDO $UFKLYH 7KH FRYHU IRQW LV $GREH ,7&
*DUDPRQG7KHWH[WIRQWLV/LQRW\SH%LUNDWKHKHDGLQJIRQWLV$GREH0\ULDG&RQ
GHQVHGDQGWKHFRGHIRQWLV/XFDV)RQW¦V7KH6DQV0RQR&RQGHQVHG
0
You can add this document to your study collection(s)
Sign in Available only to authorized usersYou can add this document to your saved list
Sign in Available only to authorized users(For complaints, use another form )