Sei sulla pagina 1di 16

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
VWRUHYDOXHVWKDWGRQWFKDQJHZKLOHWKHFRGHUXQV 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()); // print the free memory
Serial.print(' '); // print a space
delay(1000);
}

// 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\RXGRQWFRQVXPHPRUHPHPRU\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\ZLOOUXQRXWGRQW
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
<RXKDYHDORWRIFRQVWDQWQXPHULFGDWDDQGGRQWZDQWWRDOORFDWHWKLVWR5$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, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 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; // this LED is fed with raw values


const int adjustedLedPin = 5; // 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 + brightnessGRQW


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()); // print the free memory
Serial.print(' '); // print a space

printP(myText); // print the string


delay(1000);
}

// 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
OLQNVWRPRUHLQIRUPDWLRQRQWKHSUHSURFHVVRULQWKLVFKDSWHUVLQWURGXFWLRQVHFWLRQ

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()); // print the free memory
Serial.print(' '); // print a space

Serial.print(myText); // print the string


delay(1000);
}

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\RXODWHUZDQWWRFKDQJHWKHYDOXHXVHGLWVGLIILFXOWWRZRUNRXW
ZKLFKQXPEHUVVFDWWHUHGWKURXJKRXWWKHFRGHDOVRQHHGWREHFKDQJHG,WLVEHVWWRXVH
QDPHGUHIHUHQFHV
+HUHDUHWKUHHGLIIHUHQWZD\VWRGHILQHDYDOXHWKDWLVDFRQVWDQW
int ledPin = 13; // a variable, but this wastes RAM
const int ledPin = 13; // a const does not use RAM
#define ledPin 13 // 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
6HHWKLVFKDSWHUVLQWURGXFWLRQVHFWLRQIRUPRUHRQWKHSUHSURFHVVRU

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> // needed for Arduino versions later than 0018
#endif

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; // select the input pin for the potentiometer
const int ledPin = 13; // 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); // read the voltage on the pot
digitalWrite(ledPin, HIGH); // turn the ledPin on
delay(val); // blink rate set by pot value
digitalWrite(ledPin, LOW); // turn the ledPin off
delay(val); // turn LED off for same period as it was turned on
#if defined DEBUG
Serial.println(val);
#endif
}

Discussion
7KLVUHFLSHXVHVWKHSUHSURFHVVRUXVHGDWWKHEHJLQQLQJRIWKHFRPSLOHSURFHVVWRFKDQJH
ZKDWFRGHLVFRPSLOHG7KHILUVWH[DPSOHWHVWVLIWKHYDOXHRIWKHFRQVWDQW ARDUINOLV
JUHDWHUWKDQDQGLIVRWKHILOH63,KLVLQFOXGHG7KHYDOXHRIWKH ARDUINOFRQVWDQW
LVGHILQHGLQWKHEXLOGSURFHVVDQGFRUUHVSRQGVWRWKH$UGXLQRUHOHDVHYHUVLRQ7KH
V\QWD[IRUWKLVH[SUHVVLRQLVQRWWKHVDPHDVWKDWXVHGIRUZULWLQJDVNHWFK([SUHVVLRQV
WKDWEHJLQZLWKWKH#V\PERODUHSURFHVVHGEHIRUHWKHFRGHLVFRPSLOHGVHHWKLVFKDS
WHUVLQWURGXFWLRQVHFWLRQIRUPRUHRQWKHSUHSURFHVVRU
<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


void setup()
{
Serial.begin(9600);

#if defined(__AVR_ATmega1280__) // defined when selecting Mega in the IDE


numberOfSensors = 16; // the number of analog inputs on the Mega
#else // if not Mega then assume a standard board
numberOfSensors = 6; // analog inputs on a standard Arduino board
#endif

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
Download from Wow! eBook <www.wowebook.com>

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

Potrebbero piacerti anche