Download Python Programming for Arduino - Pratik Desai2015-05
Transcript
PythonProgrammingforArduino TableofContents PythonProgrammingforArduino Credits AbouttheAuthor AbouttheReviewers www.PacktPub.com Supportfiles,eBooks,discountoffers,andmore Whysubscribe? FreeaccessforPacktaccountholders Preface Whatthisbookcovers Whatyouneedforthisbook Whothisbookisfor Conventions Readerfeedback Customersupport Downloadingtheexamplecode Downloadingthecolorimagesofthisbook Errata Piracy Questions 1.GettingStartedwithPythonandArduino IntroductiontoPython WhyweusePython Whendoweuseotherlanguages InstallingPythonandSetuptools InstallingPython Linux Ubuntu FedoraandRedHat Windows MacOSX InstallingSetuptools Linux Windows MacOSX Installingpip InstallingPythonpackages ThefundamentalsofPythonprogramming Pythonoperatorsandbuilt-intypes Operators Built-intypes Datastructures Lists Tuples Sets Dictionaries Controllingtheflowofyourprogram Theifstatement Theforstatement Thewhilestatement Built-infunctions Conversions Mathoperations Stringoperations IntroductiontoArduino History WhyArduino? Arduinovariants TheArduinoUnoboard InstallingtheArduinoIDE Linux MacOSX Windows GettingstartedwiththeArduinoIDE WhatisanArduinosketch? Workingwithlibraries UsingArduinoexamples Compilinganduploadingsketches UsingtheSerialMonitorwindow IntroductiontoArduinoprogramming Comments Variables Constants Datatypes Conversions Functionsandstatements Thesetup()function Theloop()function ThepinMode()function Workingwithpins Statements Summary 2.WorkingwiththeFirmataProtocolandthepySerialLibrary ConnectingtheArduinoboard Linux MacOSX Windows Troubleshooting IntroducingtheFirmataprotocol WhatisFirmata? UploadingaFirmatasketchtotheArduinoboard TestingtheFirmataprotocol GettingstartedwithpySerial InstallingpySerial PlayingwithapySerialexample BridgingpySerialandFirmata Summary 3.TheFirstProject–Motion-triggeredLEDs Motion-triggeredLEDs–theprojectdescription Theprojectgoal Thelistofcomponents Thesoftwareflowdesign Thehardwaresystemdesign IntroducingFritzing–ahardwareprototypingsoftware Workingwiththebreadboard Designingthehardwareprototype Testinghardwareconnections Method1–usingastandaloneArduinosketch Theprojectsetup TheArduinosketch Thesetup()function Theloop()function WorkingwithcustomArduinofunctions Testing Troubleshooting Method2–usingPythonandFirmata Theprojectsetup WorkingwithPythonexecutablefiles ThePythoncode WorkingwithpyFirmatamethods WorkingwithPythonfunctions Testing Troubleshooting Summary 4.DivingintoPython-ArduinoPrototyping Prototyping WorkingwithpyFirmatamethods SettinguptheArduinoboard ConfiguringArduinopins Thedirectmethod Assigningpinmodes Workingwithpins Reportingdata Manualoperations Thewrite()method Theread()method Additionalfunctions Upcomingfunctions PrototypingtemplatesusingFirmata Potentiometer–continuousobservationfromananaloginput Connections ThePythoncode Buzzer–generatingsoundalarmpattern Connections ThePythoncode DCmotor–controllingmotorspeedusingPWM Connections ThePythoncode LED–controllingLEDbrightnessusingPWM Connections ThePythoncode Servomotor–movingthemotortoacertainangle Connections ThePythoncode PrototypingwiththeI2Cprotocol ArduinoexamplesforI2Cinterfacing ArduinocodingfortheTMP102temperaturesensor ArduinocodingfortheBH1750lightsensor PyMataforquickI2Cprototyping InterfacingTMP102usingPyMata InterfacingBH1750usingPyMata UsefulpySerialcommands Connectingwiththeserialport Readingalinefromtheport Flushingtheporttoavoidbufferoverflow Closingtheport Summary 5.WorkingwiththePythonGUI LearningTkinterforGUIdesign YourfirstPythonGUIprogram TherootwidgetTk()andthetop-levelmethods TheLabel()widget ThePackgeometrymanager TheButton()widget–interfacingGUIwithArduinoandLEDs TheEntry()widget–providingmanualuserinputs TheScale()widget–adjustingthebrightnessofanLED TheGridgeometrymanager TheCheckbutton()widget–selectingLEDs TheLabel()widget–monitoringI/Opins RemakingyourfirstPython-ArduinoprojectwithaGUI Summary 6.StoringandPlottingArduinoData WorkingwithfilesinPython Theopen()method Thewrite()method Theclose()method Theread()method Thewithstatement–Pythoncontextmanager UsingCSVfilestostoredata StoringArduinodatainaCSVfile Gettingstartedwithmatplotlib ConfiguringmatplotlibonWindows ConfiguringmatplotlibonMacOSX Upgradingmatplotlib Troubleshootinginstallationerrors SettingupmatplotlibonUbuntu Plottingrandomnumbersusingmatplotlib PlottingdatafromaCSVfile Plottingreal-timeArduinodata IntegratingplotsintheTkinterwindow Summary 7.TheMidtermProject–aPortableDIYThermostat Thermostat–theprojectdescription Projectbackground Projectgoalsandstages Thelistofrequiredcomponents Hardwaredesign Softwareflowforuserexperiencedesign Stage1–prototypingthethermostat TheArduinosketchforthethermostat Interfacingthetemperaturesensor Interfacingthehumiditysensor Interfacingthelightsensor UsingArduinointerrupts DesigningtheGUIandplotinPython UsingpySerialtostreamsensordatainyourPythonprogram DesigningtheGUIusingTkinter Plottingpercentagehumidityusingmatplotlib Usingbuttoninterruptstocontroltheparameters Changingthetemperatureunitbypressingabutton SwappingbetweentheGUIandtheplotbypressingabutton Troubleshooting Stage2–usingaRaspberryPiforthedeployablethermostat WhatisaRaspberryPi? InstallingtheoperatingsystemandconfiguringtheRaspberryPi WhatdoyouneedtobeginusingtheRaspberryPi? PreparinganSDcard TheRaspberryPisetupprocess UsingaportableTFTLCDdisplaywiththeRaspberryPi ConnectingtheTFTLCDusingGPIO ConfiguringtheTFTLCDwiththeRaspberryPiOS OptimizingtheGUIfortheTFTLCDscreen Troubleshooting Summary 8.IntroductiontoArduinoNetworking Arduinoandthecomputernetworking Networkingfundamentals ObtainingtheIPaddressofyourcomputer Windows MacOSX Linux NetworkingextensionsforArduino ArduinoEthernetShield ArduinoWiFiShield ArduinoYún ArduinoEthernetlibrary TheEthernetclass TheIPAddressclass TheServerclass TheClientclass Exercise1–awebserver,yourfirstArduinonetworkprogram DevelopingwebapplicationsusingPython Pythonwebframework–web.py Installingweb.py YourfirstPythonwebapplication Essentialweb.pyconceptsfordevelopingcomplexwebapplications HandlingURLs TheGETandPOSTmethods Templates Forms Exercise2–playingwithweb.pyconceptsusingtheArduinoserialinterface RESTfulwebapplicationswithArduinoandPython DesigningREST-basedArduinoapplications WorkingwiththeGETrequestfromArduino TheArduinocodetogeneratetheGETrequest TheHTTPserverusingweb.pytohandletheGETrequest WorkingwiththePOSTrequestfromArduino TheArduinocodetogeneratethePOSTrequest TheHTTPserverusingweb.pytohandlethePOSTrequest Exercise3–aRESTfulArduinowebapplication TheArduinosketchfortheexercise Theweb.pyapplicationtosupportRESTrequests Whydoweneedaresource-constrainedmessagingprotocol? MQTT–Alightweightmessagingprotocol IntroductiontoMQTT Mosquitto–anopensourceMQTTbroker SettingupMosquitto GettingfamiliarwithMosquitto GettingstartedwithMQTTonArduinoandPython MQTTonArduinousingthePubSubClientlibrary InstallingthePubSubClientlibrary DevelopingtheArduinoMQTTclient MQTTonPythonusingpaho-mqtt Installingpaho-mqtt Usingthepaho-mqttPythonlibrary Exercise4–MQTTGatewayforArduino DevelopingArduinoastheMQTTclient DevelopingtheMQTTGatewayusingMosquitto ExtendingtheMQTTGatewayusingweb.py TestingyourMosquittoGateway Summary 9.ArduinoandtheInternetofThings GettingstartedwiththeIoT ArchitectureofIoTwebapplications Hardwaredesign TheIoTcloudplatforms Xively–acloudplatformfortheIoT SettingupanaccountonXively WorkingwithXively AlternativeIoTplatforms ThingSpeak Carriots DevelopingcloudapplicationsusingPythonandXively InterfacingArduinowithXively UploadingArduinodatatoXively DownloadingdatatoArduinofromXively AdvancedcodetouploadanddownloaddatausingArduino Python–uploadingdatatoXively Thebasicmethodforsendingdata Uploadingdatausingawebinterfacebasedonweb.py Python–downloadingdatafromXively ThebasicmethodforretrievingdatafromXively Retrievingdatafromtheweb.pywebinterface Triggers–customnotificationsfromXively YourowncloudplatformfortheIoT GettingfamiliarwiththeAmazonAWSplatform SettingupanaccountonAWS CreatingavirtualinstanceontheAWSEC2service Loggingintoyourvirtualinstance CreatinganIoTplatformontheEC2instance InstallingthenecessarypackagesonAWS Configuringthesecurityofthevirtualinstance Testingyourcloudplatform TestingtheMosquittoservice Configuringandtestingbasicsecurity Uploadingandtestingaprojectontheinstance Summary 10.TheFinalProject–aRemoteHomeMonitoringSystem ThedesignmethodologyforIoTprojects Projectoverview Theprojectgoals Theprojectrequirements Designingsystemarchitecture Themonitoringstation Thecontrolcenter Thecloudservices DefiningUXflow Thelistofrequiredcomponents Definingtheprojectdevelopmentstages Stage1–amonitoringstationusingArduino Designingthemonitoringstation TheArduinosketchforthemonitoringstation Publishingsensorinformation Subscribingtoactuatoractions Programminganinterrupttohandlethepressofabutton Testing Stage2–acontrolcenterusingPythonandtheRaspberryPi Thecontrolcenterarchitecture ThePythoncodeforthecontrolcenter CreatingtheGUIusingTkinter CommunicatingwiththeMosquittobroker Calculatingthesystem’sstatusandsituationawareness CommunicatingwithXively Checkingandupdatingthebuzzer’sstatus Testingthecontrolcenterwiththemonitoringstation SettingupthecontrolcenterontheRaspberryPi Stage3–awebapplicationusingXively,Python,andAmazoncloudservice Architectureofthecloudservices PythonwebapplicationhostedonAmazonAWS Testingthewebapplication Testingandtroubleshooting Extendingyourremotehomemonitoringsystem Utilizingmultiplemonitoringstations Extendingsensorycapabilities ImprovingUX Expandingcloud-basedfeatures Improvingintelligenceforsituationawareness Creatinganenclosureforhardwarecomponents Summary 11.Tweet-a-PowerStrip Projectoverview Projectrequirements Systemarchitecture Requiredhardwarecomponents Relays PowerSwitchTail Userexperienceflow Developmentanddeploymentstages Stage1–asmartpowerstripwithArduinoandrelays Hardwaredesign TheArduinocode Stage2–thePythoncodetoprocesstweets Pythonsoftwareflow SettinguptheTwitterapplication ThePythoncode Testingandtroubleshooting Extendingtheprojectwithadditionalfeatures Summary Index PythonProgrammingforArduino PythonProgrammingforArduino Copyright©2015PacktPublishing Allrightsreserved.Nopartofthisbookmaybereproduced,storedinaretrievalsystem, ortransmittedinanyformorbyanymeans,withoutthepriorwrittenpermissionofthe publisher,exceptinthecaseofbriefquotationsembeddedincriticalarticlesorreviews. Everyefforthasbeenmadeinthepreparationofthisbooktoensuretheaccuracyofthe informationpresented.However,theinformationcontainedinthisbookissoldwithout warranty,eitherexpressorimplied.Neithertheauthor,norPacktPublishing,andits dealersanddistributorswillbeheldliableforanydamagescausedorallegedtobecaused directlyorindirectlybythisbook. PacktPublishinghasendeavoredtoprovidetrademarkinformationaboutallofthe companiesandproductsmentionedinthisbookbytheappropriateuseofcapitals. However,PacktPublishingcannotguaranteetheaccuracyofthisinformation. Firstpublished:February2015 Productionreference:1230215 PublishedbyPacktPublishingLtd. LiveryPlace 35LiveryStreet BirminghamB32PB,UK. ISBN978-1-78328-593-8 www.packtpub.com Credits Author PratikDesai Reviewers JuanRamónGonzález MarcoSchwartz JoshVanderLinden CommissioningEditor SaleemAhmed AcquisitionEditor JamesJones ContentDevelopmentEditor PriyankaShah TechnicalEditor AnkitaThakur CopyEditors JasmineNadar VikrantPhadke ProjectCoordinator MiltonDsouza Proofreaders SafisEditing MariaGould AmeeshaGreen PaulHindle Indexer MariammalChettiyar Graphics AbhinashSahu ProductionCoordinator ManuJoseph CoverWork ManuJoseph AbouttheAuthor PratikDesai,PhD,isthePrincipalScientistandcofounderofaconnecteddevicesstartup,ImbueLabs,wherehedevelopsscalableandinteroperablearchitectureforwearable devicesandInternetofThings(IoT)platformsduringtheday.Atnight,heleadsthe developmentofanopensourceIoTinitiative,theSemanticRepositoryofThings.Pratik has8yearsofresearchanddesignexperienceinvariouslayersoftheIoTandits predecessortechnologiessuchaswirelesssensornetworks,RFID,andmachine-tomachine(M2M)communication.HisdomainsofexpertisearetheIoT,SemanticWeb, machinelearning,robotics,andartificialintelligence. PratikcompletedhisMSandPhDfromWrightStateUniversity,Ohio,andcollaborated withtheOhioCenterofExcellenceinKnowledge-enabledComputing(Kno.e.sis)during hisdoctoralresearch.Hisdoctoralresearchwasfocusedondevelopingsituation awarenessframeworksforIoTdevices,enablingsemanticweb-basedreasoningand handlingtheuncertaintyassociatedwithsensordata. Inhispersonallife,PratikisanavidDIYjunkieandlikestogethands-onexperienceon upcomingtechnologies.Heextensivelyexpresseshisviewsontechnologyandshares interestingdevelopmentsonTwitter(@chheplo). Iwouldliketodedicatethebooktomyparents,whowereresponsibleforbuildingthe foundationofwhatIamtoday.Thebookwouldnothavebeenpossiblewithoutthe patience,support,andencouragementfrommybelovedwife,Sachi.Iwouldalsoliketo thankherforlandingherphotographyskillsthatwereusedindevelopmentofsomeofthe importantimagesusedinthebook.Iwouldalsoliketoextendmysinceregratitudetothe editorsfortheirvaluablefeedbacks. AbouttheReviewers JuanRamónGonzálezisatechnicalengineerofcomputersystemsandlivesinSeville (Andalusia,Spain).Forthepast9years,hehasbeenworkingonfreesoftware-based projectsfortheregionalMinistryofEducationbyusingPython,C++,andJavaScript, amongotherprogramminglanguages. HeisoneofthemainmembersoftheCGAprojectinAndalusia(CentrodeGestión AvanzadoorAdvancedManagementCenter),whichmanagesanetworkwithmorethan 4,000serverswithDebianand500,000clientcomputersthatrunGuadalinex,a customizedUbuntu-basedoperatingsystemforAndalusianschools. Asasoftwaredeveloperwhohasapassionforelectronicsandastronomy,hestartedone ofthefirstprojectstocontrolatelescopewiththeArduinomicrocontrollerbyusinga computerwiththeStellariumsoftwareandadriverdevelopedwithPythonto communicatewiththetelescope.Thisproject’ssourcesarepublishedonthecollaborative platformGitHub.Youcanseethewholecodeandtheprototypeat https://github.com/juanrmn/Arduino-Telescope-Control. MarcoSchwartzisanelectricalengineer,entrepreneur,andblogger.Hehasamaster’s degreeinelectricalengineeringandcomputersciencefromSupélec,France,anda master’sdegreeinmicroengineeringfromEPFL,Switzerland. Marcohasmorethan5yearsofexperienceworkinginthedomainofelectrical engineering.Hisinterestsgravitatearoundelectronics,homeautomation,theArduinoand theRaspberryPiplatforms,opensourcehardwareprojects,and3Dprinting. HerunsseveralwebsitesaroundArduino,includingtheOpenHomeAutomationwebsite thatisdedicatedtobuildinghomeautomationsystemsusingopensourcehardware. MarcohaswrittenabookonhomeautomationandArduinocalledArduinoHome AutomationProjects,PacktPublishing.Hehasalsowrittenabookonhowtobuild InternetofThingsprojectswithArduinocalledInternetofThingswiththeArduinoYun, PacktPublishing. JoshVanderLindenisalifelongtechnologyenthusiastwhohasbeenprogrammingsince theageof10.Heenjoyslearningandbecomingproficientwithnewtechnologies.Hehas designedandbuiltsoftware,rangingfromsimpleshellscriptstoscalablebackendserver softwaretointeractivewebanddesktopuserinterfaces.Joshhasbeenwritingsoftware professionallyusingPythonsince2007,andhehasbeenbuildingpersonalArduino-based projectssince2010. www.PacktPub.com Supportfiles,eBooks,discountoffers,and more Forsupportfilesanddownloadsrelatedtoyourbook,pleasevisitwww.PacktPub.com. DidyouknowthatPacktofferseBookversionsofeverybookpublished,withPDFand ePubfilesavailable?YoucanupgradetotheeBookversionatwww.PacktPub.comandas aprintbookcustomer,youareentitledtoadiscountontheeBookcopy.Getintouchwith usat<service@packtpub.com>formoredetails. Atwww.PacktPub.com,youcanalsoreadacollectionoffreetechnicalarticles,signup forarangeoffreenewslettersandreceiveexclusivediscountsandoffersonPacktbooks andeBooks. https://www2.packtpub.com/books/subscription/packtlib DoyouneedinstantsolutionstoyourITquestions?PacktLibisPackt’sonlinedigital booklibrary.Here,youcansearch,access,andreadPackt’sentirelibraryofbooks. Whysubscribe? FullysearchableacrosseverybookpublishedbyPackt Copyandpaste,print,andbookmarkcontent Ondemandandaccessibleviaawebbrowser FreeaccessforPacktaccountholders IfyouhaveanaccountwithPacktatwww.PacktPub.com,youcanusethistoaccess PacktLibtodayandview9entirelyfreebooks.Simplyuseyourlogincredentialsfor immediateaccess. Preface IntheeraoftheInternetofThings(IoT),ithasbecomeveryimportanttorapidlydevelop andtestprototypesofyourhardwareproductswhilealsoaugmentingthemusingsoftware features.TheArduinomovementhasbeenthefront-runnerinthishardwarerevolution, andthroughitssimpleboarddesignsithasmadeitconvenientforanyonetodevelopDIY hardwareprojects.Thegreatamountofsupportthatisavailablethroughtheopensource communityhasmadethedifficultiesthatareassociatedwiththedevelopmentofa hardwareprototypeathingofthepast.Onthesoftwarefront,Pythonhasbeenthecrown jeweloftheopensourcesoftwarecommunityforasignificantamountoftime.Pythonis supportedbyahugeamountoflibrariestodevelopvariousfeatures,suchasgraphicaluser interfaces,plots,messaging,andcloudapplications. Thisbooktriestobringyouthebestofbothhardwareandsoftwareworldstohelpyou developexcitingprojectsusingArduinoandPython.Themaingoalofthebookistoassist thereadertosolvethedifficultproblemofinterfacingArduinohardwarewithPython libraries.Meanwhile,asasecondarygoal,thebookalsoprovidesyouwithexercisesand projectsthatcanbeusedasblueprintsforyourfutureIoTprojects. Thebookhasbeendesignedinsuchawaythateverysuccessivechapterhasincreasing complexityintermsofmaterialthatiscoveredandalsomorepracticalvalue.Thebook hasthreeconceptualsections(gettingstarted,implementingPythonfeatures,andnetwork connectivity)andeachsectionconcludeswithapracticalprojectthatintegratesthe conceptsthatyoulearnedinthatsection. ThetheoreticalconceptsandexercisescoveredinthebookaremeanttogiveyouhandsonexperiencewithPython-Arduinoprogramming,whiletheprojectsaredesignedtoteach youhardwareprototypingmethodologiesforyourfutureprojects.However,youwillstill needextensiveexpertiseineachdomaintodevelopacommercialproduct.Intheend,I hopetoprovideyouwithsufficientknowledgetojump-startyourjourneyinthisnovel domainoftheIoT. Whatthisbookcovers Chapter1,GettingStartedwithPythonandArduino,introducesthefundamentalsofthe ArduinoandPythonplatforms.Italsoprovidescomprehensiveinstallationand configurationstepstosetupthenecessarysoftwaretools. Chapter2,WorkingwiththeFirmataProtocolandthepySerialLibrary,discussesthe interfacingoftheArduinohardwarewiththePythonprogrambyexplainingtheFirmata protocolandtheserialinterfacinglibrary. Chapter3,TheFirstProject–Motion-triggeredLEDs,providescomprehensiveguidelines tocreateyourfirstPython-Arduinoproject,whichcontrolsdifferentLEDsaccordingto thedetectedmotion. Chapter4,DivingintoPython-ArduinoPrototyping,takesyoubeyondthebasic prototypingthatweperformedinthepreviousprojectandprovidesanin-depthdescription ofprototypingmethods,withappropriateexamples. Chapter5,WorkingwiththePythonGUI,beginsourtwo-chapterjourneyintodeveloping graphicalinterfacesusingPython.ThechapterintroducestheTkinterlibrary,which providesthegraphicalfrontendfortheArduinohardware. Chapter6,StoringandPlottingArduinoData,coversPythonlibraries,CSVand matplotlibthatareusedtostoreandplotthesensordatarespectively. Chapter7,TheMidtermProject–aPortableDIYThermostat,containsapracticaland deployableprojectthatutilizesthematerialthatwecoveredinpreviouschapterssuchas serialinterfacing,agraphicalfrontend,andaplotofthesensordata. Chapter8,IntroductiontoArduinoNetworking,introducescomputernetworkingfor ArduinowhileutilizingvariousprotocolstoestablishEthernetcommunicationbetween thePythonprogramandArduino.Thischapteralsoexploresamessagingprotocolcalled MQTT,withbasicexamples.ThisprotocolisspecificallydesignedforresourceconstrainedhardwaredevicessuchasArduino. Chapter9,ArduinoandtheInternetofThings,discussesthedomainoftheIoTwhile providingstep-by-stepguidelinestodevelopcloud-basedIoTapplications. Chapter10,TheFinalProject–aRemoteHomeMonitoringSystem,teachesadesign methodologyforthehardwareproduct,followedbyacomprehensiveprojectthat interfacesthecloudplatformwithArduinoandPython. Chapter11,Tweet-a-PowerStrip,containsanotherIoTprojectthatisbasedoneverything thatwelearnedinthebook.Theprojectexploresauniqueapproachtointegrateasocial network,Twitter,withthePython-Arduinoapplication. Whatyouneedforthisbook Tobeginwith,youwilljustneedacomputerwithoneofthesupportedoperatingsystems, Windows,MacOSX,orLinux.Thebookrequiresvariousadditionalhardware componentsandsoftwaretoolstoimplementprogrammingexercisesandprojects.Alist ofrequiredhardwarecomponentsandlocationstoobtainthesecomponentsareincluded ineachchapter. Intermsofsoftware,thebookitselfprovidesstep-by-stepguidelinestoinstalland configureallthenecessarysoftwarepackagesanddependentlibrariesthatareutilized throughoutthebook.Notethattheexercisesandprojectsincludedinthebookare designedforPython2.7andtheyhavenotbeentestedagainstPython3+. Whothisbookisfor Ifyouareastudent,ahobbyist,adeveloper,oradesignerwithlittleornoprogramming andhardwareprototypingexperienceandyouwanttodevelopIoTapplications,thenthis bookisforyou. Ifyouareasoftwaredeveloperandinterestedingainingexperiencewithhardware domain,thisbookwillhelpyoutogetstarted.Ifyouareahardwareengineerwhowants tolearnadvancesoftwarefeatures,thisbookcanhelpyoutobeginwith. Conventions Inthisbook,youwillfindanumberoftextstylesthatdistinguishbetweendifferentkinds ofinformation.Herearesomeexamplesofthesestylesandanexplanationoftheir meaning. Codewordsintext,databasetablenames,foldernames,filenames,fileextensions, pathnames,dummyURLs,userinput,andTwitterhandlesareshownasfollows:“While assigningthevaluetotheweightvariable,wedidn’tspecifythedatatype,butthePython interpreterassigneditasanintegertype,int.” Ablockofcodeissetasfollows: /* Blink TurnsonanLEDonforonesecond,thenoffforonesecond,repeatedly. Thisexamplecodeisinthepublicdomain. */ //Pin13hasanLEDconnectedonmostArduinoboards. //giveitaname: intled=13; //thesetuproutinerunsoncewhenyoupressreset: voidsetup(){ //initializethedigitalpinasanoutput. pinMode(led,OUTPUT); } //thelooproutinerunsoverandoveragainforever: voidloop(){ digitalWrite(led,HIGH);//turntheLEDon(HIGHisthevoltagelevel) delay(1000);//waitforasecond digitalWrite(led,LOW);//turntheLEDoffbymakingthevoltageLOW delay(1000);//waitforasecond } Anycommand-lineinputoroutputiswrittenasfollows: $sudoeasy_installpip Newtermsandimportantwordsareshowninbold.Wordsthatyouseeonthescreen, forexample,inmenusordialogboxes,appearinthetextlikethis:“IntheSystem window,clickontheAdvancedsystemsettingsintheleftnavigationbartoopena windowcalledSystemProperties.” Note Warningsorimportantnotesappearinaboxlikethis. Tip Tipsandtricksappearlikethis. Readerfeedback Feedbackfromourreadersisalwayswelcome.Letusknowwhatyouthinkaboutthis book—whatyoulikedordisliked.Readerfeedbackisimportantforusasithelpsus developtitlesthatyouwillreallygetthemostoutof. Tosendusgeneralfeedback,simplye-mail<feedback@packtpub.com>,andmentionthe book’stitleinthesubjectofyourmessage. Ifthereisatopicthatyouhaveexpertiseinandyouareinterestedineitherwritingor contributingtoabook,seeourauthorguideatwww.packtpub.com/authors. Customersupport NowthatyouaretheproudownerofaPacktbook,wehaveanumberofthingstohelp youtogetthemostfromyourpurchase. Downloadingtheexamplecode Youcandownloadtheexamplecodefilesfromyouraccountathttp://www.packtpub.com forallthePacktPublishingbooksyouhavepurchased.Ifyoupurchasedthisbook elsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilesemaileddirectlytoyou. Downloadingthecolorimagesofthisbook WealsoprovideyouwithaPDFfilethathascolorimagesofthescreenshots/diagrams usedinthisbook.Thecolorimageswillhelpyoubetterunderstandthechangesinthe output.Youcandownloadthisfilefrom: http://www.packtpub.com/sites/default/files/downloads/5938OS_ColoredImages.pdf. Errata Althoughwehavetakeneverycaretoensuretheaccuracyofourcontent,mistakesdo happen.Ifyoufindamistakeinoneofourbooks—maybeamistakeinthetextorthe code—wewouldbegratefulifyoucouldreportthistous.Bydoingso,youcansaveother readersfromfrustrationandhelpusimprovesubsequentversionsofthisbook.Ifyoufind anyerrata,pleasereportthembyvisitinghttp://www.packtpub.com/submit-errata, selectingyourbook,clickingontheErrataSubmissionFormlink,andenteringthe detailsofyourerrata.Onceyourerrataareverified,yoursubmissionwillbeacceptedand theerratawillbeuploadedtoourwebsiteoraddedtoanylistofexistingerrataunderthe Erratasectionofthattitle. Toviewthepreviouslysubmittederrata,goto https://www.packtpub.com/books/content/supportandenterthenameofthebookinthe searchfield.TherequiredinformationwillappearundertheErratasection. Piracy PiracyofcopyrightedmaterialontheInternetisanongoingproblemacrossallmedia.At Packt,wetaketheprotectionofourcopyrightandlicensesveryseriously.Ifyoucome acrossanyillegalcopiesofourworksinanyformontheInternet,pleaseprovideuswith thelocationaddressorwebsitenameimmediatelysothatwecanpursuearemedy. Pleasecontactusat<copyright@packtpub.com>withalinktothesuspectedpirated material. Weappreciateyourhelpinprotectingourauthorsandourabilitytobringyouvaluable content. Questions Ifyouhaveaproblemwithanyaspectofthisbook,youcancontactusat <questions@packtpub.com>,andwewilldoourbesttoaddresstheproblem. Chapter1.GettingStartedwithPython andArduino ThischapterintroducesthePythonprogramminglanguageandtheopensourceelectronic prototypingplatformArduino.ThefirstsectionofthechapterfocusesonPythonand brieflydescribesthebenefitsofPythonalongwithinstallationandconfigurationsteps. TheremainingpartofthechapterdescribesArduinoandArduino’sdevelopment environment. Attheendofthischapter,youwillhaveconfiguredaprogrammingenvironmentforboth PythonandArduinoforyourfavoriteoperatingsystem.Ifyouareabeginnerwitheither orbothplatforms(thatis,PythonandArduino),itisadvisablethatyoufollowthegiven stepsinthischapter,asthelaterchapterswillassumethatyouhavetheexact configurationdescribedhere.Ifyouhavepreviousexperienceofworkingwiththese platforms,youcanskiptothenextchapter. IntroductiontoPython SinceitsintroductionbyGuidovanRossumin1991,Pythonhasgrownintooneofthe mostwidelyusedgeneral-purpose,high-levelprogramminglanguages,andissupported byoneofthelargestopensourcedevelopercommunities.Pythonisanopensource programminglanguagethatincludesalotofsupportinglibraries.Theselibrariesarethe bestfeatureofPython,makingitoneofthemostextensibleplatforms.Pythonisa dynamicprogramminglanguage,anditusesaninterpretertoexecutecodeatruntime ratherthanusingacompilertocompileandcreateexecutablebytecodes. ThephilosophybehindthedevelopmentofPythonwastocreateflexible,readable,and clearcodetoeasilyexpressconcepts.Theemphasisonusingwhitespaceindentationina uniquewaydifferentiatesPythonfromotherpopularhigh-levellanguages.Python supportsfunctional,imperative,andobject-orientedprogrammingwithautomaticmemory management. WhyweusePython Pythonisconsideredtobeoneoftheeasiestlanguagestolearnforfirst-time programmers.Comparedtootherpopularobject-orientedlanguagessuchasC++and Java,Pythonhasthefollowingmajorbenefitsforprogrammers: Itiseasytoreadandunderstand Itenablesrapidprototypingandreducesdevelopmenttime Ithasahumongousamountoffreelibrarypackages Pythonhasahugeopensourcecommunitythatdrivesforththeeffortforcontinuous improvementofPythonasaprogramminglanguage.ThePythoncommunityisalso responsibleforthedevelopmentofalargeamountofopenlibrarypackages,whichcanbe usedtobuildapplicationsthatspanfromdynamicwebsitestocomplexdataanalysis applications,aswellasthedevelopmentofsimpleGUI-basedapplicationstoplotcharts fromcomplexmathfunctions.ThemajorityofPythonlibrarypackageshave systematicallymaintainedthecodethatwasobtainedfromthecommunitywithregular updates.ThedefactorepositorythatindexesthelargestnumberofPythonpackagesis PyPI(http://pypi.python.org).PyPIalsoprovidessimplewaystoinstallvariouspackages onyouroperatingsystem,whichwillbecoveredintheupcomingsection. Whileworkingwiththehardwareplatform,itisnecessarytohavesomemeansof communicationbetweenthehardwareandthecomputerthatyouareusingfor development.Amongthecommoncomputertohardwareinterfacingmethods,serial-portbasedcommunicationisthemostpopular,anditisreallysimpletoestablish,especially fortheArduinoplatform.PythonprovidesalibrarycalledpySerialthatisreallyeasyto useandquicktoimplementtointerfaceaserialport.Itisreallysimpletousesimilar librariesandPython’sinteractiveprogrammingabilitiestorapidlytestandimplementyour projectideas. Nowadays,complexInternetofThings(IoT)applicationsnotonlyrequireserial communicationsupport,buttheyalsoneedadditionalhigh-levelfeaturessuchas graphicaluserinterfaces(GUIs)foroperatingsystems,webinterfacesforremote access,plotsfordatavisualization,toolsfordataanalysis,interfacesfordatastorage,and soon.UsinganyotherprogramminglanguagesuchasC++orJava,thedevelopmentof thesefeatureswouldrequirealargeamountofprogrammingeffortduetothedistributed andunorganizednatureofthesupportingtools.Thankfully,Pythonhasbeenvery successfulatprovidingsupportforthesetypesofapplicationsforyears.Pythonhasa numberoflibrariestosupportthedevelopmentofeachofthefeaturesmentionedhere, whichareavailablethroughPyPI.Theselibrariesareopensource,easytouse,andwidely supportedbythecommunity.ThismakesPythonalanguageofchoiceforIoT applications.Additionally,Pythonalsohassupporttocreateandshipyourcustom-built applicationsaslibrariessothateveryoneelsecanalsoutilizethemintheirprojects.Thisis ahelpfulfeatureifyouaredevelopingcustomprotocols,APIs,oralgorithmsforyourown hardwareproducts. Whendoweuseotherlanguages So,whenshouldwenotusePythonforourprojects?Asmentionedearlier,Pythonisa dynamiclanguagethatreducesdevelopmenttime,butitalsomakestheexecutionofyour codeslowerascomparedtootherstatichigh-levellanguagessuchasC,C++,andJava. Thesestaticlanguagesuseacompilertocompilethecodeandcreatebinariesthatget executedduringruntime,therebyincreasingtheruntimeperformance.Whenthe performanceofthecodeismoreimportantthanalongerdevelopmenttimeandhigher cost,youshouldconsiderthesestaticlanguages.SomeotherdrawbacksofPythoninclude beingmemoryheavy,nothavingthepropersupportforthreading,andlackingdata protectionfeatures.Inshort,wecansaythateventhoughPythonprovidesquickerand easierwaysforquickprototyping,weshouldconsiderotherstatichigh-levellanguagesfor developmentafterwearedonetestingourprototypeandwearereadytoshipourproduct. Nowadays,thisscenarioischangingrapidlyandcompanieshavestartedutilizingPython fortheirindustrialproducts. Note YoucanobtainmorePython-relatedinformationfromtheofficialwebsiteat http://www.python.org. InstallingPythonandSetuptools Pythoncomesintwoversions:Pythonv2.xandPythonv3.x.(Here,xrepresentsan appropriateversionnumber.)WhilePythonv2.xisalegacybranchandhasbetterlibrary support,Pythonv3.xisthefutureofPython.MostLinuxdistributionsandMacOSX operatingsystemsareequippedwithPython,andtheyhavev2.xastheirpreferredand defaultversionofPython.WewillbeusingPythonv2.7asthedefaultversionofPython fortherestofthebookduetothefollowingreasons: ItisthemostcurrentversionofthePythonv2.xbranch Ithaslargecommunitysupportandsolutionsforitsknownissuesareavailable throughsupportforums ItissupportedbymostofthemajorPythonlibraries Eventhoughthecodesamples,exercises,andprojectsprovidedinthisbookshouldwork inanyvariantofPython2.7.x,it’sbettertohavethelatestversion. InstallingPython Yourfondnessforanoperatingsystemisdevelopedduetomultiplefactors,andyoucan neverignoresomeone’sbiastowardsaparticularOS.Thus,thisbookprovidesinstallation andconfigurationguidelinesforthreeofthemostpopularoperatingsystems:Linux,Mac OSX,andWindows.Let’sbeginbyconfiguringPythonforaLinuxcomputer. Linux ThemajorityofLinuxdistributionscomewithPythonpreinstalled.Tocheckthelatest versionoftheinstalledPython,usethefollowingcommandattheterminalwindow: $python-V MakesurethatyouareusinganuppercaseVastheoptionforthepreviouscommand. Onceyouexecuteitontheterminal,itwillprintthecompleteversionnumberofyour currentPythoninstallation.Iftheversionis2.7.x,youaregoodtogoandyourLinuxis updatedwiththelatestversionofPythonthatisrequiredforthisbook.However,ifyou haveanyversionthatislessthanorequalto2.6.x,youwillneedtofirstupgradePythonto thelatestversion.Thisprocesswillrequirerootprivileges,asPythonwillbeinstalledasa systemcomponentthatwillreplacethepreviousversions. Ubuntu IfyouareusingUbuntu11.10orlaterversions,youshouldalreadyhavePythonv2.7.x installedonyourmachine.YoucanstillupgradePythontothelatestrevisionofv2.7.x usingthefollowingcommand: $sudoapt-getupdate&&sudoapt-get--only-upgradeinstallpython IfyouarerunninganolderversionofUbuntu(suchas10.04orolder),youshouldhave 2.6asthedefaultversion.Inthiscase,youwillneedtorunthefollowingsetofcommands toinstallversion2.7: $sudoadd-apt-repositoryppa:fkrull/deadsnakes $sudoapt-getupdate $sudoapt-getinstallpython2.7 ThefirstcommandwilladdanexternalUbunturepository,whichwillallowyoutoinstall anyversionofPython.Thenextcommandwillupdateandindexthelistofavailable packages.ThelastcommandwillinstallthelatestversionofPython2.7. FedoraandRedHat FedoraandRedHatLinuxalsoshipswithPythonasanin-builtpackage.Ifyouwantto upgradetheversionofPythontothelatestone,runthefollowingcommandatthe terminal: $sudoyumupgradepython Tip Downloadingtheexamplecode Youcandownloadtheexamplecodefilesfromyouraccountathttp://www.packtpub.com forallthePacktPublishingbooksyouhavepurchased.Ifyoupurchasedthisbook elsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilesemaileddirectlytoyou. Windows InstallationandconfigurationofPythononWindowsisnotasstraightforwardasitisfor Linux.Firstofall,you’llneedtodownloadacopyofPythonfrom http://www.python.org/getit. YouneedtobecarefulabouttheversionofPythonthatyouaredownloading.Fromthe systempropertiesofyourWindowsOS,checkwhethertheoperatingsystemisof32bitor 64bit.Atthetimethisbookwasbeingwritten,thelatestversionofPythonwas2.7.6.So, downloadthelatestavailableversionofPython,butmakesurethatitis2.7.xandnot3.x. Formanythird-partyPythonlibraries,theinstallationbinaryfilesforWindowsare compiledforthe32-bitversion.Duetothisreason,wewillrecommendthatyouinstallthe 32-bitversionofPythonforyourWindowsOS. IfyouarereallyfamiliarwithPythonandknowyourwayaroundinstallinglibraries,you caninstallthe64-bitversionofPython.Selectandrunthedownloadedfiletoinstall Python.Althoughyoucaninstallittoanycustomlocation,itisadvisabletousethe defaultinstallationlocationastheupcomingconfigurationstepsusethedefaultlocation. Oncetheinstallationiscomplete,youcanfindthePythoncommand-linetoolandIDLE (PythonGUI)fromtheStartmenu. AlthoughyoucanalwaysopenthesetoolsfromtheStartmenuforbasicscripting,we willmodifytheWindowssystemparameterstomakePythonaccessiblethroughthe Windowscommandprompt.Toaccomplishthis,wewillhavetosetupPATHin environmentvariablesforthelocationofthePythoninstallationdirectory.Let’sopen SystemPropertiesbyright-clickingonMyComputerandthenselectingProperties. Otherwise,youcanalsonavigatetoStart|ControlPanel|SystemandSecurity| System. Youwillbeabletoseeawindowsimilartotheonethatisdisplayedinthefollowing screenshot.TheSystemwindowshowsyouthebasicinformationaboutyourcomputer, includingthetypeofWindowsoperatingsystemthatyouareusing(suchasthe32-bitor the64-bitversion): IntheSystemwindow,clickonAdvancedsystemsettingsintheleftnavigationbarto openawindowcalledSystemProperties.ClickontheEnvironmentVariables…button intheSystemPropertieswindow,whichislocatedatthebottomofthewindow.Thiswill openaninterfacesimilartotheoneshowninthefollowingscreenshot.InEnvironment Variables,youneedtoupdatethePATHsystemvariabletoaddPythontothedefault operatingsystem’spath. ClickonthePATHoptionasdisplayedinthefollowingscreenshot,whichwillpopupan EditSystemVariablewindow.AddC:\Python27orthefullpathofyourcustomPython installationdirectoryattheendofyourexistingPATHvariable.Itisrequiredtoputa semicolon(;)beforethePythoninstallationpath.IfyoualreadyseePython’slocationin thePathvariable,yoursystemissetupforPythonandyoudon’tneedtoperformany changes: ThemainbenefitofaddingPythontotheenvironmentvariablesistoenableaccesstothe Pythoninterpreterfromthecommandprompt.Incaseyoudon’tknow,theWindows commandpromptcanbeaccessedbynavigatingtoStart|Programs|Accessories| CommandPrompt. MacOSX MacOSXshipswithapreinstalledcopyofPython,butduetothelongreleasecycleof theoperatingsystem,thefrequencyofupdatesforthedefaultPythonapplicationisslow. ThelatestversionofMacOSX,whichis10.9Maverick,comesequippedwithPython 2.7.5,whichisthelatestversion: Tests-Mac:~test$python Python2.7.5(default,Aug252013,00:04:04) [GCC4.2.1CompatibleAppleLLVM5.0(clang-500.0.68)]ondarwin Type"help","copyright","credits"or"license"formoreinformation. >>> PreviousversionssuchasMacOSX10.8MountainLionandMacOSX10.7Lion includedPython2.7.2andPython2.7.1respectively,whicharealsocompatibleversions forthisbook.IfyouareanexperiencedPythonuserorsomeonewhowantstoworkwith thelatestversionofPython,youcandownloadthelatestversionfrom http://www.python.org/getit. OlderversionsofMacOSXsuchasSnowLeopardandlater,whichcamewithanolder versionofPython,canbeupdatedtothelatestversionbydownloadingandinstallingit fromhttp://www.python.org/getit. InstallingSetuptools Setuptoolsisalibrarycontainingacollectionofutilitiesforbuildinganddistributing Pythonpackages.Themostimportanttoolfromthiscollectioniscalledeasy_install.It allowsausertolookintoPyPI,thePythonpackagerepositorythatwementioned previously,andprovidesasimpleinterfacetoinstallanypackagebyname.The easy_installutilityautomaticallydownloads,builds,installs,andmanagespackagesfor theuser.Thisutilityhasbeenusedinthelaterpartofthisbooktoinstallthenecessary packagesrequiredfortheupcomingprojectsofPythonandArduino.Although easy_installhasbeenusedasasimplewayofinstallingPythonpackages,itmissesout onafewusefulfeaturessuchastrackingactions,supportforuninstallation,andsupport forotherversioncontrolsystems.Inrecentyears,thePythoncommunityhasstarted adoptinganothertoolcalledpipovereasy_installthatsupportsthesefeatures.Asboth easy_installandpiputilizethesamePyPIrepository,goingforward,youcanuseanyof theseutilitiestoinstalltherequiredPythonpackages. Justtonarrowdownthescope,wewillbefocusingonmethodstoinstallSetuptoolsand thedefaultutilitiesthatgetinstalledwithit,thatis,easy_install.Laterinthissection, wewillalsoinstallpip,justincaseyouwanttouseittoo.Let’sfirstbeginbyinstalling Setuptoolsforthevariousoperatingsystems. Linux InUbuntu,Setuptoolsisavailableinthedefaultrepositoryanditcanbeinstalledusingthe followingcommand: $sudoapt-getinstallpython-setuptools ForFedora,itcanbeinstalledusingthedefaultsoftwaremanageryum: $sudoyuminstallpython-setuptools ForotherLinuxdistributions,itcanbedownloadedandbuiltusingthefollowingsinglelinescript: $wgethttps://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py-O- |sudopython OnceitisinstalledonyourLinuxdistribution,easy_installcanbedirectlyaccessed fromtheterminalasabuilt-incommand. Windows InstallationofSetuptoolsisnotthatstraightforwardforWindowsascomparedtoLinux.It requirestheusertodownloadtheez_setup.pyfilefromtheWindowssectionat https://pypi.python.org/pypi/setuptools. Oncethisisdownloaded,pressShiftandright-clickinthefolderwhereyoudownloaded theez_setup.pyfile.SelectOpencommandwindowhereandexecutethefollowing command: >pythonez_setup.py ThiswillinstallSetuptoolsintheScriptsfolderofyourdefaultPythoninstallationfolder. UsingthesamemethodthatweusedwhenweaddedPythontoEnvironmentVariables, nowincludeSetuptoolsbyaddingC:\Python27\ScriptstoPATH,followedbythe semicolon(;). ThiswillenabletheinstallationofvariousPythonpackagesusingeasy_installtoyour PythonpackagesfoldercalledLibs.Onceyouhaveaddedthepackagemanagertothe environmentvariables,youneedtocloseandreopenthecommandpromptforthese changestotakeeffect. MacOSX SetuptoolscanbeinstalledinMacOSXusinganyofthefollowingmethods.Itis advisableforbeginnerstousethefirstmethod,asthesecondmethodrequirestheexternal packagemanagerHomebrew. IfyouhaveneverworkedwithHomebrewbefore,youwillneedtofollowthesestepsto installSetuptoolsonyourMac: 1. Downloadez_setup.pyfromtheUnix/Macsectionat https://pypi.python.org/pypi/setuptools. 2. Opentheterminalandnavigatetothedirectorywhereyoudownloadedthisfile.For mostbrowsers,thefilegetssavedtotheDownloadfolder. 3. RunthefollowingcommandintheterminaltobuildandsetupSetuptools: $sudopythonez_setup.py IfyouarefamiliarwithHomebrew-basedsoftwareinstallation,justfollowthesequick stepstoinstallSetuptools: 1. First,installwgetfromHomebrewifyoudon’thaveitalready: $brewinstallwget 2. Onceyouhaveinstalledwget,runthefollowingcommandintheterminal: $wgethttps://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O-|python Note MoreinformationregardingtheHomebrewutilitycanbeobtainedfrom http://brew.sh. YoucaninstallHomebrewonyourMacbyrunningthefollowingsimplescriptinthe terminal: ruby-e"$(curl-fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" Installingpip AsyouhavesuccessfullyinstalledSetuptools,let’suseittoinstallpip.ForLinuxorMac OSX,youcanrunthefollowingcommandintheterminaltoinstallpip: $sudoeasy_installpip ForWindows,openthecommandpromptandexecutethefollowingcommand: >easy_install.exepip Ifyouhavealreadyinstalledpiponyourcomputer,pleasemakesurethatyouupgradeit tothelatestversiontoovercomethefewbugsthatareassociatedwiththeupgrade.You canupgradepipusingthefollowingcommandattheterminal: $sudoeasy_install--upgradepip Sinceyouhavealreadyusedeasy_installtoinstallaPythonpackage,let’sgetourselves morefamiliarwithPythonpackagemanagement. InstallingPythonpackages Withtheinstallationofpip,youhavetwodifferentoptionstoinstallanythird-party PythonpackagelistedonthePyPirepository(http://pypi.python.org).Thefollowingare thevariousproceduresthatyouneedtoknowtoworkwiththeinstallationofPython packages.Inthefollowingexamples,thetermPackageNameisapseudonamethatisused foraPythonpackagethatyouwanttoworkwith.Foryourpackageofchoice,identifythe appropriatepackagenamefromthePyPiwebsiteandputitsnameinplaceof PackageName.Insomecases,youwillneedroot(superuser)privilegestoinstallor uninstallapackage.Youcanusesudofollowedbyanappropriatecommandforthese cases. ToinstallaPythonpackage,executethefollowingcommandattheterminal: $easy_installPackageName Otherwise,youcanalsoexecutethefollowingcommand: $pipinstallPackageName Ifyouwanttoinstallaspecificversionofapackage,youcanusethefollowingcommand: $easy_install"PackageName==version" Ifyouarenotawareoftheexactversionnumber,youcanalsousecomparisonoperators suchas>,<,>=,or<=tospecifyarangefortheversionnumber.Botheasy_installand pipwillselectthebestmatchingversionofthepackagefromtherepositoryandinstallit: $easy_install"PackageName>version" Meanwhile,forpip,youcanusethefollowingidenticalcommandstoperformsimilar operations: $pipinstallPackageName==version $pipinstall"PackageName>=version" Asanexample,ifyouwanttoinstallaversionbetween1.0and3.0,youwillneedtouse thefollowingcommand: $pipinstall"PackageName>=0.1,<=0.3" Itisreallyeasytoupgradeapackageusingeithereasy_installorpip.Thecommand optionsusedbybotharealsoverysimilar: $easy_install--upgradePackageName $pipinstall--upgradePackageName Althougheasy_installdoesn’tsupportcleanuninstallationofapackage,youcanusethe followingcommandtomakesurethatPythonstopssearchingforthespecifiedpackage. Later,carefullyremovethepackagefilesfromtheinstallationdirectory: $easy_install-mxNPackageName Amuchbetterwaytoperformacleanuninstallationofthemajorityofpackagesistouse pipinsteadofeasy_install: $pipuninstallPackageName AdetailedlistofthePythonpackagessupportedbySetuptoolscanbefoundatthePyPI websiteathttps://pypi.python.org/. ThefundamentalsofPython programming Ifyouhavepreviousexperienceofworkingwithanyotherprogramminglanguage, Pythonisveryeasytogetstartedwith.Ifyouhaveneverdoneprogrammingbefore,this sectionwillwalkyouthroughsomeofthebasicsofPython.Ifyouhavealreadyworked withPython,youshouldskipthissectionandmoveontothenextone. Assumingthatthesetupinstructionsarefollowedcorrectly,let’sopenthePython interpreterbyexecutingthePythoncommandattheterminalorthecommandprompt.You shouldgetresultssimilartothosedisplayedinthefollowingscreenshot.Ifyouhave installedPythonbydownloadingthesetupfilesfromthewebsite,youshouldhavethe Pythonintegrateddevelopmentenvironment(IDLE)installedaswell.Youcanalso startthePythoninterpreterbyopeningitsIDLEfromthelocationwhereitwasinstalled. Asyoucansee,afterprintingsomesysteminformation,theinterpreteropensaprompt withthreegreater-thansigns(>>>),whichisalsoknownastheprimaryprompt.The interpreterisnowintheinteractivemodeanditisreadytoexecutescriptsfromthe prompt. ToclosetheinteractivemodeofthePythoninterpreter,runtheeitherexit()orquit(),at theprimaryprompt.Anothermethodtoexitfromtheinteractivemodeistousethe keyboardshortcutCtrl+D. Note NotethatPython’sbuilt-infunctionsarecasesensitive.Thismeansthefollowing: exit()≠EXIT()≠Exit() TheofficialPythonwebsiteprovidescomprehensivetutorialsforbeginnerstogetstarted withPythonprogramming.ItishighlyrecommendedthatyouvisittheofficialPython tutorialsathttps://docs.python.org/2/tutorial/index.htmlifyouarelookingfordetailed programmingtutorialsascomparedtotheupcomingbriefoverviews. Pythonoperatorsandbuilt-intypes NowthatyouhaveabriefidearegardingthePythonprompt,let’sgetyoufamiliarwith someofthebasicPythoncommands.Fortheseexercises,wewillbeusingthePython IDLE,whichalsoopenswiththePythoninteractiveprompt.Youwillrequireamethodto describethecodesegments,tasks,andcommentswhenwritinglargeandcomplexcode. Non-executablecontentiscalledcommentsinanyprogramminglanguage,andinPython, theystartwiththehashtagcharacter(#).Likecomments,youwillbefrequentlyrequired tochecktheoutputbyprintingonthepromptusingtheprintcommand: >>>#FundamentalofPython >>>#Myfirstcomment >>>name="John"#Thisismyname >>>printname John Note InsteadofIDLE,youcanalsoaccessthePythoninteractivepromptfromtheterminal. WhenusingPythonfromtheterminal,makesurethatyouaretakingcareofthe indentationproperly. Operators Pythonsupportstheusageofbasicmathematicaloperatorssuchas+,-,*,and/,directly fromtheinterpreter.Usingtheseoperators,youcanperformbasiccalculationsinthe prompt,asshowninthefollowingexamples.Trytheseoperationsinyourpromptinorder tostartusingthePythoninterpreterasacalculator: >>>2+2 4 >>>(2*3)+1 7 >>>(2*3)/5 1 Note WhenworkingwiththePythoninterpreter,itisrecommendedthatyoufollowtheStyle GuideforPythonCode,whichisalsopopularlyknownasPEP-8orpep8.Formore informationaboutPEP-8,visithttps://www.python.org/dev/peps/pep-0008/. Built-intypes Pythonisadynamicallytypedlanguage,whichmeansthatyoudon’thavetoexplicitly declarethetypeofthevariableswheninitializingthem.Whenyouassignavaluetoa variable,thePythoninterpreterautomaticallydeducesthedatatype.Forexample,let’s declarethefollowingvariablesintheinteractivemodeoftheinterpreter: >>>weight=height=5 >>>weight*height 25 >>>type(weight) <type'int'> Whileassigningthevaluetotheweightvariable,wedidn’tspecifythedatatype,butthe Pythoninterpreterassigneditasanintegertype,int.Theinterpreterassignedtheinttype duetothereasonthatthenumericalvaluedidn’tcontainanydecimalpoints.Let’snow declareavariablewithavaluecontainingadecimalpoint.Thebuilt-infunctiontype() thatcanbeusedtofindoutthedatatypeofaspecifiedvariable: >>>length=6.0 >>>weight*height*length 150.0 >>>type(length) <type'float'> Asyoucansee,theinterpreterassignsthedatatypeasfloat.Theinterpretercanalso deducethetypeofcomplexnumbers,asshowninfollowingexamples.Youcanaccessthe realandimaginaryvalueofacomplexnumberusingthedot(.)operatorfollowedbyreal andimag: >>>val=2.0+3.9j >>>val.real 2.0 >>>val.imag 3.9 Justtoplaymorewithcomplexnumbers,let’strytheabs()andround()functionsas displayedinthefollowingexamples.Theyarebuilt-inPythonfunctionstoobtainthe absolutevalueandtheroundednumberrespectively: >>>abs(val) 4.382921400162225 >>>round(val.imag) 4.0 Likenumbers,thePythoninterpretercanalsoautomaticallyidentifythedeclarationof stringdatatypes.InPython,stringvaluesareassignedusingsingleordoublequotes aroundthevalue.Whentheinterpreterseesanyvalueenclosedwithinquotes,itconsiders ittobeastring.Pythonsupportstheusageofthe+operatortoconcatenatestrings: >>>s1="Hello" >>>s2="World!" >>>s1+s2 'HelloWorld!' >>>s1+""+s2 'HelloWorld!' Acharactertypeisastringofsizeoneandtheindividualcharactersofastringcanbe accessedbyusingindexnumbers.Thefirstcharacterofastringisindexedas0.Playwith thefollowingscriptstounderstandindexing(subscripting)inPython: >>>s1[0] 'H' >>>s1[:2] 'He' >>>s1+s2[5:] 'Hello!' Note Similartotheprimarypromptwithdefaultnotation>>>,thePythoninteractiveinterpreter alsohasasecondarypromptthatusesthreedots(…)whenitisbeingusedfromthe terminal.Youwon’tbeabletoseethethreedotsinIDLEwhenyouusethesecondary prompt.Thesecondarypromptisusedforamultilineconstruct,whichrequirescontinuous lines.Executethefollowingcommandsbymanuallytypingthemintheinterpreter,anddo notforgettoindentthenextlineaftertheifstatementwithatab: >>>age=14 >>>ifage>10orage<20: ...print"teen" teen Datastructures Pythonsupportsfourmaindatastructures(list,tuple,set,anddictionary)andthere areanumberofimportantbuilt-inmethodsaroundthesedatastructures. Lists Listsareusedtogrouptogethervaluesofsingleormultipledatatypes.Theliststructure canbeassignedbystatingvaluesinsquarebracketswithacomma(,)asaseparator: >>>myList=['a',2,'b',12.0,5,2] >>>myList ['a',2,'b',12.0,5,2] Likestrings,valuesinalistcanbeaccessedusingindexnumbers,whichstartsfrom0.A featurecalledslicingisusedbyPythontoobtainaspecificsubsetorelementofthedata structureusingthecolonoperator.Inastandardformat,slicingcanbespecifiedusingthe myList[start:end:increment]notation.Hereareafewexamplestobetterunderstand thenotionofslicing: Youcanaccessasingleelementinalistasfollows: >>>myList[0] 'a' Youcanaccessalltheelementsinthelistbyhavingemptystartandendvalues: >>>myList[:] ['a',2,'b',12.0,5,2] Youcanprovidestartandendindexvaluestoobtainaspecificsubsetofthelist: >>>myList[1:5] [2,'b',12.0,5] Useoftheminussymbolwithanindexnumbertellstheinterpretertousethatindex numberbackwards.Inthefollowingexample,-1backwardsactuallyrepresentsthe indexnumber5: >>>myList[1:-1] [2,'b',12.0,5] Youcanobtaineveryotherelementofthelistbyprovidingtheincrementvaluewith startandendvalues: >>>myList[0:5:2] ['a','b',5] Youcancheckthelengthofalistvariableusingthelen()method.Theusageofthis methodwillbehandyintheupcomingprojects: >>>len(myList) 6 Youcanalsoperformvariousoperationstoaddordeleteelementsintheexistinglist. Forexample,ifyouwanttoaddanelementattheendofthelist,usetheappend() methodonthelist: >>>myList.append(10) >>>myList ['a',2,'b',12.0,5,2,10] Toaddanelementataspecificlocation,youcanusetheinsert(i,x)method, whereidenotestheindexvalue,whilexistheactualvaluethatyouwanttoaddto thelist: >>>myList.insert(5,'hello') >>>myList ['a',2,'b',12.0,5,'hello',2,10] Similarly,youcanusepop()toremoveanelementfromthelist.Asimplepop() functionwillremovethelastelementofthelist,whileanelementataspecific locationcanberemovedusingpop(i),whereiistheindexnumber: >>>myList.pop() 10 >>>myList ['a',2,'b',12.0,5,'hello',2] >>>myList.pop(5) 'hello' >>>myList ['a',2,'b',12.0,5,2] Tuples TuplesareimmutabledatastructuressupportedbyPython(differentfromthemutable structuresoflists).Animmutabledatastructuremeansthatyoucannotaddorremove elementsfromthetupledatastructure.Duetotheirimmutableproperties,tuplesarefaster toaccesscomparedtolistsandaremostlyusedtostoreaconstantsetofvaluesthatnever change. Thetupledatastructureisdeclaredlikelist,butbyusingparenthesesorwithoutany brackets: >>>tupleA=1,2,3 >>>tupleA (1,2,3) >>>tupleB=(1,'a',3) >>>tupleB (1,'a',3) Justlikeinalistdatastructure,valuesintuplecanbeaccessedusingindexnumbers: >>>tupleB[1] 'a' Astuplesareimmutable,listmanipulationmethodssuchasappend(),insert(),and pop()don’tapplyfortuples. Sets ThesetdatastructureinPythonisimplementedtosupportmathematicalsetoperations. Thesetdatastructureincludesanunorderedcollectionofelementswithoutduplicates. Withitsmathematicalusecases,thisdatastructureismostlyusedtofindduplicatesin lists,asconversionofalisttoasetusingtheset()functionremovesduplicatesfromthe list: >>>listA=[1,2,3,1,5,2] >>>setA=set(listA) >>>setA set([1,2,3,5]) Dictionaries Thedictdatastructureisusedtostorekey-valuepairsindexedbykeys,whicharealso knowninotherlanguagesasassociativearrays,hashes,orhashmaps.Unlikeotherdata structures,dictvaluescanbeextractedusingassociatedkeys: >>>boards={'uno':328,'mega':2560,'lily':'128'} >>>boards['lily'] '128' >>>boards.keys() ['lily','mega','uno'] Note YoucanlearnmoreaboutPythondatastructuresandassociatedmethodsat https://docs.python.org/2/tutorial/datastructures.html. Controllingtheflowofyourprogram Justlikeanyotherlanguage,Pythonsupportscontrollingtheprogramflowusing compoundstatements.Inthissection,wewillbrieflyintroducethesestatementstoyou. YoucangetdetailedinformationaboutthemfromtheofficialPythondocumentationat https://docs.python.org/2/reference/compound_stmts.html. Theifstatement Theifstatementisthemostbasicandstandardstatementusedtosetupconditionalflow. Tobetterunderstandtheifstatement,executethefollowingcodeinthePythoninterpreter withdifferentvaluesoftheagevariable: >>>age=14 >>>ifage<18andage>12: print"Teen" elifage<13: print"Child" else: print"Adult" ThiswillresultinTeenbeingprintedontheinterpreter. Theforstatement Python’sforstatementiteratesovertheelementsofanysequenceaccordingtotheorder oftheelementsinthatsequence: >>>celsius=[13,21,23,8] >>>forcincelsius: print"Fahrenheit:"+str((c*1.8)+32) ThiswillresultinthePythoninterpretergeneratingthefollowingoutputthatwilldisplay thecalculatedFahrenheitvaluesfromthegivenCelsiusvalues: Fahrenheit:55.4 Fahrenheit:69.8 Fahrenheit:73.4 Fahrenheit:46.4 Thewhilestatement ThewhilestatementisusedtocreateacontinuousloopinaPythonprogram.Awhile loopkeepsiteratingoverthecodeblockuntiltheconditionisprovedtrue: >>>count=5 >>>while(count>0): printcount count=count-1 Thewhilestatementwillkeepiteratingandprintingthevalueofthevariablecountand alsoreduceitsvalueby1untilthecondition,thatis(count>0),becomestrue.Assoon asthevalueofcountislowerthanorequalto0,thewhileloopwillexitthecodeblock andstopiterating. TheothercompoundstatementssupportedbyPythonaretry/catchandwith.These statementswillbeexplainedindetailintheupcomingchapters.Pythonalsoprovidesloop controlstatementssuchasbreak,continue,andpassthatcanbeusedwhilealoopis beingexecutedusingthecompoundstatementsmentionedearlier.Youcanlearnmore aboutthesePythonfeaturesfromhttps://docs.python.org/2/tutorial/controlflow.html. Built-infunctions Pythonsupportsanumberofusefulbuilt-infunctionsthatdonotrequireanyexternal librariestobeimported.Wehavedescribedafewofthesefunctionsasacollectionofa respectivecategory,accordingtotheirfunctionalities. Conversions Conversionmethodssuchasint(),float(),andstr()canconvertotherdatatypesinto integer,float,orstringdatatypesrespectively: >>>a='a' >>>int(a,base=16) 10 >>>i=1 >>>str(i) '1' Similarly,list(),set(),andtuple()canbeusedtoconvertonedatastructureinto another. Mathoperations Pythonalsosupportsbuilt-inmathematicalfunctionsthatcanfindtheminimumand/or maximumvaluesfromalist.Checkoutthefollowingexamplesandplayaroundwiththe differentdatastructurestounderstandthesemethods: >>>list=[1.12,2,2.34,4.78] >>>min(list) 1.12 >>>max(list) 4.78 Thepow(x,y)functionreturnsthevalueofxtothepowerofy: >>>pow(3.14159,2) 9.869587728099999 Stringoperations Pythonprovideseasyaccesstostringmanipulationthroughbuilt-infunctionsthatare optimizedforperformance.Let’stakealookatthefollowingexamples: Codetoreplaceoccurrencesofastringorsubstringwithadifferentone: >>>str="HelloWorld!" >>>str.replace("World","Universe") 'HelloUniverse!' Codetosplitastringwithaseparatingcharacterwherethedefaultcharacterisspace: >>>str="HelloWorld!" >>>str.split() ['Hello','World!'] Codetosplitastringfromaseparatingcharacterforanyothercharacter: >>>str2="John,Merry,Tom" >>>str2.split(",") ['John','Merry','Tom'] Codetoconvertanentirestringvalueintouppercaseorlowercase: >>>str="HelloWorld!" >>>str.upper() 'HELLOWORLD!' >>>str.lower() 'helloworld!' Note ThePythondocumentationontheofficialwebsitecoverseverybuilt-infunctionin detailwithexamples.ForbetterunderstandingofPythonprogramming,visit https://docs.python.org/2/library/functions.html. IntroductiontoArduino Anyelectronicproductthatneedscomputationorinterfacingwithothercomputersfirst requiresaquickprototypingoftheconceptusingsimpletools.Arduinoisanopensource hardwareprototypingplatformdesignedaroundapopularmicrocontrollerfamily,andit includesasimplesoftwaredevelopmentenvironment.Besidesprototyping,youcanalso useArduinoforthedevelopmentofyourowndo-it-yourself(DIY)projects.Arduino bridgesthecomputationalworldwiththephysicalworldbylettingyousimplyconnectthe sensorsandactuatorswithacomputer.Basically,youcanwritecodetomonitorand controlvariouselectroniccomponentsinyourdailylifebyusingArduino’sinput/output pinsandmicrocontroller.Examplesofthesecomponentsincludemotors,thermostats, lights,switches,andmanymore. History In2005,MassimoBanzi,theItaliancofounderofArduino,developedthetechnologyfor hisstudentsatInteractionDesignInstituteIvrea(IDII).Sincethen,Arduinohas developedintooneofthelargestopensourcehardwareplatforms.Allsoftware componentsandschematicsoftheArduinodesignareopensource,andyoucanbuythe hardwareataverylowcost—approximately30dollars—oryoucanevenmakeit yourself. WhyArduino? ThemajorgoaloftheArduinocommunityistocontinuouslyimprovetheArduino platformwiththefollowingobjectivesinmind: TheArduinoplatformshouldbeanaffordableplatform Itshouldbeeasytouseandeasytocode Itshouldbeanopensourceandextensiblesoftwareplatform Itshouldbeanopensourceandextensiblehardwareplatform Itshouldhavecommunity-supportedDIYprojects ThesesimplebutpowerfulobjectiveshavemadeArduinoapopularandwidelyused prototypingplatform.ArduinousesAtmel’sATmegaseriesofmicrocontrollersthatare basedonthepopularhardwarearchitectureofAVR.Thehugesupportthatisavailablefor AVRarchitecturealsomakesArduinoahardwareplatformofchoice.Thefollowing imageshowsthebasicversionoftheArduinoboard,whichiscalledArduinoUno(Uno meansoneinItalian): Arduinovariants Likeanyotherproject,hardwarerequirementsaredrivenbyprojectspecifications.Ifyou aredevelopingaprojectthatrequiresyoutointerfacewithalargenumberofexternal components,youneedaprototypingplatformthathasasufficientnumberofinput/output (I/O)pinsforinterfacing.Ifyouareworkingonaprojectthatneedstoperformahuge amountofcomplexcalculations,yourequireaplatformwithmorecomputationcapability. Fortunately,theArduinoboardexistsin16differentofficialversions,andeachversionof Arduinodiffersfromtheothersintermsofformfactor,computationalpower,I/Opins, andotheron-boardfeatures.ArduinoUnoisthebasicandmostpopularversion,whichis sufficientenoughforsimpleDIYprojects.Forthemajorityofexercisesinthisbook,we willbeusingtheArduinoUnoboard.Youcanalsouseanotherpopularvariantcalled ArduinoMega,whichisalargerboardwithextrapinsandapowerfulmicrocontroller. Thefollowingtableshowsthecomparisonofsomeofthemorepopularandactive variantsoftheArduinoboard: Name Processor Processor frequency Digital I/O DigitalI/Owith PWM Analog I/O ArduinoUno ATmega328 16MHz 14 6 6 Arduino Leonardo ATmega32u4 16MHz 14 6 12 ArduinoMega ATmega2560 16MHz 54 14 16 ArduinoNano ATmega328 16MHz 14 6 8 ArduinoDue AT91SAM3X8E 84MHz 54 12 12 LilyPadArduino ATmega168vor ATmega328v 8MHz 14 6 6 Anyofthesevariantscanbeprogrammedusingacommonintegrateddevelopment environmentcalledArduinoIDE,whichisdescribedintheupcomingsection.Youcan selectanyoneoftheseArduinoboardsaccordingtoyourprojectrequirements,andthe ArduinoIDEshouldbeabletocompileanddownloadtheprogramtotheboard. TheArduinoUnoboard AsUnoisgoingtobethedefactoboardforthemajorityoftheprojectsinthisbook,let’s getourselvesfamiliarwiththeboard.ThelatestrevisionoftheUnoboardisbasedon Atmel’sATmega328microcontroller.TheboardextendstheI/Opinsofthe microcontrollertotheperipheral,whichcanthenbeutilizedtointerfacecomponentsusing wires.Theboardhasatotalof20pinstointerface,outofwhich14aredigitalI/Opinsand 6areanaloginputpins.Fromthe14digitalI/Opins,6pinsalsosupportpulse-width modulation(PWM),whichsupportsthecontrolleddeliveryofpowertoconnected components. Theboardoperateson5V.ThemaximumcurrentratingofthedigitalI/Opinsis40mA, whichissufficienttodrivemostoftheDIYelectroniccomponents,excludingmotorswith highcurrentrequirements. WhilethepreviousimageprovidedanoverviewoftheUnoboard,thefollowingdiagram describesthepinsontheUnoboard.Asyoucansee,thedigitalpinsarelocatedonone sideoftheboardwhiletheanalogpinsareontheoppositeside.Theboardalsohasa coupleofpowerpinsthatcanbeusedtoprovide5Vand3.3Vofpowertoexternal components.Theboardcontainsgroundpinsonbothsidesoftheboardaswell.Wewill beextensivelyusing5Vofpowerandgroundpinsforourprojects.DigitalpinsD0and D1supportserialinterfacingthroughtheTx(transmission)andRx(receiver)interfaces respectively.TheUSBportontheboardcanbeusedtoconnectArduinowithacomputer. NowthatwearefamiliarwiththeArduinohardware,let’smoveontoprogrammingthe Arduinoboard. InstallingtheArduinoIDE ThefirststeptostartgettingfamiliarwithArduinoistoinstalltheArduinointegrated developmentenvironment(IDE).Accordingtotheoperatingsystemthatyouselectedat thebeginningofthePythoninstallationsection,followtheappropriatesubsectionto installthecorrectIDE. Linux TheinstallationoftheArduinoIDEisreallysimpleinUbuntu.TheUbunturepository alreadyincludestheArduinoIDEwiththerequireddependencies. ForUbuntu12.04oranewerversion,executethefollowingcommandintheterminalto installArduino: $sudoapt-getupdate&&sudoapt-getinstallarduinoarduino-core ThelatestversionoftheArduinoIDEintheUbunturepositoryis1.0.3.Youcanobtain moreinformationregardingotherUbuntu-relatedquestionsat http://playground.arduino.cc/Linux/Ubuntu. ForFedora17oranewerversionofRedHatLinux,executethefollowingscriptinthe terminal: $sudoyuminstallarduino AnswerstoadditionalinstallationquestionsforFedoracanbeobtainedat http://playground.arduino.cc/Linux/Fedora. MacOSX ToinstalltheArduinoIDEonMacOSX(10.7ornewer),performthefollowingsteps: 1. Fromhttp://arduino.cc/en/Main/Software,downloadthelatestversionoftheArduino IDEforMacOSX,whichwas1.0.5whenthisbookwasbeingwritten. 2. UnzipanddragArduinototheapplicationfolder. TheArduinoIDEisbuiltinJavaandrequiresthatyourcomputerisequippedwiththe appropriateversionofJava.OpentheIDEfromyourapplications.Ifyoudon’thaveJava installedonyourMac,theprogramwillpromptyouwithapop-upwindowandaskyouto installJavaSE6runtime.GoaheadandinstallJava(aspertherequest)astheOSXwill automaticallyinstallitforyou. Windows InstallationofArduinoforWindowsisverysimple.Downloadthesetupfilefrom http://arduino.cc/en/Main/Software.SelectthemostrecentversionoftheArduinoIDE, thatis,1.0.xoranewerversion. MakesureyoudownloadtheappropriateversionoftheArduinoIDEaccordingtoyour operatingsystem,thatis,32bitor64bit.InstalltheIDEtothedefaultlocationas specifiedintheinstallationwizard.Onceinstalled,youcanopentheIDEbynavigatingto Start|Programs. GettingstartedwiththeArduinoIDE TheArduinoIDEisacross-platformapplicationdevelopedinJavathatcanbeusedto develop,compile,anduploadprogramstotheArduinoboard.OnlaunchingtheArduino IDE,youwillfindaninterfacesimilartotheonedisplayedinthefollowingscreenshot. TheIDEcontainsatexteditorforcoding,amenubartoaccesstheIDEcomponents,a toolbartoeasilyaccessthemostcommonfunctions,andatextconsoletocheckthe compileroutputs.AstatusbaratthebottomshowstheselectedArduinoboardandtheport namethatitisconnectedto,asshownhere: WhatisanArduinosketch? AnArduinoprogramthatisdevelopedusingtheIDEiscalledasketch.Sketchesare codedinArduinolanguage,whichisbasedonacustomversionofC/C++.Onceyouare donewithwritingthecodeinthebuilt-intexteditor,youcansaveitusingthe.ino extension.Whenyousavethesesketchfiles,theIDEautomaticallycreatesafolderto storethem.Ifyouareusinganyothersupportingfilesforasketch,suchasheaderfilesor libraryfiles,theyareallstoredatthislocation(whichisalsocalledasketchbook). Toopenanewsketchbook,opentheArduinoIDEandselectNewfromtheFilemenu,as showninthefollowingscreenshot: Youwillbepromptedwithanemptytexteditor.Thetexteditorsupportsstandardfeatures (thatis,copy/paste,select,find/replace,andsoon).BeforewegoaheadwithanArduino program,let’sexploretheothertoolsprovidedbytheIDE. Note TheArduinoIDEversionpriorto1.0usedthe.pdeextensiontosavesketchbooks. Startingfrom1.0,theyaresavedwiththe.inoextension.Youcanstillopenfileswiththe .pdeextensioninthelatestIDE.Later,theIDEwillconvertittothe.inoextensionwhen yousavethem. Workingwithlibraries TheArduinoIDEuseslibrariestoextendthefunctionalitiesofexistingsketches.Libraries areasetoffunctionscombinedtoperformtasksaroundaspecificcomponentorconcept. Themajorityofthebuilt-inArduinolibrariesprovidemethodstostartworkingwith externalhardwarecomponents.YoucanimportanylibrarybynavigatingtoSketch| ImportLibrary…,asshowninthefollowingscreenshot: Youcanalsousealibraryforyoursketchbyjustspecifyingthelibrarywiththe#include statementatthebeginningofthesketch,thatis,#include<Wire.h>. TheArduinoIDEalsoprovidesthecapabilitytoaddanexternallibrarythatsupportsa specifichardwareorprovidesadditionalfeatures.Intheupcomingchapters,wewillbe dealingwithsomeoftheseexternallibraries,andwewillgothroughtheprocessof importingthematthattime. Youcanlearnmoreaboutbuilt-inArduinolibrariesfrom http://arduino.cc/en/Reference/Libraries. UsingArduinoexamples TheArduinoIDEcontainsalargenumberofbuilt-inexamplesketches.Theseexamples aredesignedtogettheuserfamiliarwithbasicArduinoconceptsandbuilt-inArduino libraries.TheexamplesarewellmaintainedbytheArduinocommunitysincetheyhave comprehensivesupportforeachexamplethroughtheArduinowebsite (http://arduino.cc/en/Tutorial/HomePage).IntheArduinoIDE,youcanaccessthese examplesbynavigatingtoFile|Examples,asshowninthefollowingscreenshot: Let’sstartwithasimplein-builtexample.OpentheBlinkexamplebynavigatingtoFile| Examples|01.Basics|Blink.TheIDEwillopenanewwindowcontainingcodethatis similartothecodeinthefollowingprogram: /* Blink TurnsonanLEDonforonesecond,thenoffforonesecond,repeatedly. Thisexamplecodeisinthepublicdomain. */ //Pin13hasanLEDconnectedonmostArduinoboards. //giveitaname: intled=13; //thesetuproutinerunsoncewhenyoupressreset: voidsetup(){ //initializethedigitalpinasanoutput. pinMode(led,OUTPUT); } //thelooproutinerunsoverandoveragainforever: voidloop(){ digitalWrite(led,HIGH);//turntheLEDon(HIGHisthevoltagelevel) delay(1000);//waitforasecond digitalWrite(led,LOW);//turntheLEDoffbymakingthevoltageLOW delay(1000);//waitforasecond } ThisArduinosketchisdesignedtoblinkanLEDondigitalpin13.Youmustbe wonderingwhywedidn’tdiscussoraskyoutobringanyhardware.That’sbecausethe ArduinoUnoboardisequippedwithanon-boardLEDthatisconnectedtodigitalpin13. Now,insteadofdivingdeeperintotheArduinocode,wearegoingtofocusontheprocess ofdealingwiththeArduinoboardthroughtheIDE. Compilinganduploadingsketches OnceyouhaveyourcodeopenedintheIDE,thefirstthingyouneedtodoistoselectthe typeofArduinoboardonwhichyouaregoingtouploadyoursketch.TheArduinoIDE needstoknowthetypeofboardinordertocompiletheprogramfortheappropriate microcontroller,asdifferentArduinoboardscanhavedifferentAtmelmicrocontrollers. Therefore,youneedtoperformthisstepbeforeyougoaheadwiththecompilingor uploadingoftheprogramtotheboard. YoucanselecttheArduinoboardbynavigatingtoTools|Board,asdisplayedinthe followingscreenshot: SelectArduinoUnofromthelistofboards,unlessyouareusingadifferentArduino board.Onceyouhaveselectedtheboard,youcangoaheadandcompilethesketch.You cancompilethesketchbynavigatingtoSketch|Verify/Compilefromthemenubaror byusingthekeyboardshortcutCtrl+R.Ifeverythingissetupwell,youshouldbeableto compilethecodewithoutanyerror. Aftersuccessfullycompilingthesketch,itistimetouploadthecompiledcodetothe Arduinoboard.Todothis,youneedtomakesurethatyourArduinoIDEisproperly connectedtoyourcomputer.Ifitisnotalreadyconnected,connectyourArduinoboardto yourcomputerusingaUSBport.Now,itistimetoletyourIDEknowtheserialporton whichtheboardisconnected.NavigatetoTools|SerialPortsandselecttheappropriate serialport. Note InthecaseofsomeLinuxdistributions,youmaynotbeabletoseeoruploadtheArduino programtotheboardduetopermissionrestriction(s)ontheserialport.Runningthe followingcommandontheterminalshouldsolvethatproblem: $sudousermod-a-Guucp,dialout,lock<username> YoucannowuploadthecompiledsketchtoyourArduinoboardbynavigatingtoFile| Upload.Thisprocesswillusetheserialconnectiontoburnthecompiledfirmwareinthe microcontroller.PleasewaitforsometimeoruntiltheLEDs(TxandRxLEDs)onthe boardstopflashing.Now,youhaveyourArduinoboardreadywithyourfirstsketch.You canobservetheperformanceoftheblinkingLEDneardigitalpin13. UsingtheSerialMonitorwindow Inthepreviousprocess,weusedaUniversalSerialBus(USB)cabletoconnectyour ArduinoboardtoaUSBportofyourcomputer.TheUSBportisanindustrialstandardto provideaninterfaceforconnectingvariouselectroniccomponentstoacomputerusingthe serialinterface.WhenyouconnectanArduinoboardusingUSB,thecomputeractually interfacesitasaserialperipheraldevice.Throughoutthebook,wearegoingtorefertothe connectionsmadeusingaUSBasserialconnections.TheSerialMonitorwindowisa built-inutilityoftheArduinoIDE.TheSerialMonitorwindowcanbeaccessedby navigatingtoTools|SerialMonitororbyusingtheCtrl+Shift+Mkeyboardshortcut.It canbeconfiguredtoobservedatathatisbeingsentorreceivedontheserialportthatis usedtoconnecttheArduinoboardtothecomputer.Youcanalsosetthebaudrateforthe serialcommunicationusingthedrop-downmenuoption.Thisutilityisgoingtobevery useful(furtheroninthebook)whentestingyourprototypesandtheirperformances. IntroductiontoArduinoprogramming TheArduinoplatformwasintroducedtosimplifyelectronichardwareprototypingfor everyone.Forthisreason,Arduinoprogrammingwasintendedtobeeasytolearnby nonprogrammerssuchasdesigners,artists,andstudents.TheArduinolanguageis implementedinC/C++,whilethefundamentalsofthesketchandprogramstructuresare derivedfromanopensourceprogramminglanguagecalledProcessingandanopensource electronicprototypinglanguagecalledWiring. Comments ArduinofollowsacommentingformatthatisadoptedfromCanditissimilartohigherlevellanguages;however,itisdifferentfromthePythoncommentformatthatwelearned earlierinthischapter.Therearevariousmethodsofcommenting,whichareasfollows: Blockcomment:Thisisdonebycoveringthecommentedtextbetween/*and*/: /*Thisisacomment. *Arduinowillignoreanytexttillitfindsuntiltheendingcomment syntax,whichis, */ Single-lineorinlinecomment:Thisisdonebyusing//beforetheline: //Thissyntaxonlyappliestooneline. //Youhavetouseitagainforeachnextlineofcomment. intpin=13;//Selectedpin13 Usually,ablockcommentatthebeginningofthesketchismostlyusedtodescribethe programasawhole.Single-linecommentsareusedtodescribespecificfunctionsorto-do notes,suchasthefollowingone: //TODO:explainvariablesnext. Variables Likeanyotherhigh-levellanguage,avariableisusedtostoredatawiththreecomponents: aname,avalue,andatype.Forexample,considerthefollowingstatement: intpin=10; Here,pinisthevariablenamethatisdefinedwiththetypeintandholdsthevalue10. Laterinthecode,alloccurrencesofthepinvariablewillretrievedatafromthe declarationthatwejustmadehere.Youcanuseanycombinationofalpha-numeric characterstoselectthevariablenameaslongasthefirstcharacterisnotanumber. Constants IntheArduinolanguage,constantsarepredefinedvariablesthatareusedtosimplifythe program: HIGH,LOW:WhileworkingwithdigitalpinsontheArduinoboard,onlytwodistinct voltagestagesarepossibleatthesepins.Ifapinisbeingusedtoobtainaninput,any measureabove3VisconsideredaHIGHstate.Ifyouareusingapinforoutput,then theHIGHstatewillsetthepinvoltageto5V.Theoppositevoltagelevelsare consideredasLOWstates. false,true:Theseareusedtorepresentlogicaltrueandfalselevels.falseis definedas0andtrueismostlydefinedas1. INPUT,OUTPUT:TheseconstantsareusedtodefinetherolesoftheArduinopins.If yousetthemodeofanArduinopinasINPUT,theArduinoprogramwillpreparethe pintoreadsensors.Similarly,theOUTPUTsettingpreparesthepinstoprovidea sufficientamountofcurrenttotheconnectedsensors. Wewillutilizetheseconstantslaterinthebookandwewillalsoexplainthemwith examplecode. Datatypes Thedeclarationofeachcustomvariablerequirestheusertospecifythedatatypethatis associatedwiththevariable.TheArduinolanguageusesastandardsetofdatatypesthat areusedintheClanguage.Alistofthesedatatypesandtheirdescriptionsareasfollows: void:Thisisusedinthefunctiondeclarationtoindicatethatthefunctionisnotgoing toreturnanyvalue: voidsetup(){ //actions } boolean:Variablesdefinedwiththedatatypebooleancanonlyholdoneoftwo values,trueorfalse: booleanledState=false; byte:Thisisusedtostorean8-bitunsignednumber,whichisbasicallyanynumber from0to255: byteb=0xFF; int:Thisisshortforintegers.Itstores16-bit(ArduinoUno)or32-bit(ArduinoDue) numbersanditisoneoftheprimarynumberstoragedatatypesfortheArduino language.Althoughintwillbeusedtodeclarenumbersthroughoutthebook,the Arduinolanguagealsohaslongandshortnumberdatatypesforspecialcases: intvarInt=2147483647; longvarLong=varInt; shortvarShort=-32768; float:Thisdatatypeisusedfornumberswithdecimalpoints.Thesearealsoknown asfloating-pointnumbers.floatisoneofthemorewidelyuseddatatypesalong withinttorepresentnumbersintheArduinolanguage: floatvarFloat=1.111; char:Thisdatatypestoresacharactervalueandoccupies1byteofmemory.When providingavaluetochardatatypes,characterliteralsaredeclaredwithsingle quotes: charmyCharacater='P'; array:Anarraystoresacollectionofvariablesthatisaccessiblebyanindex number.IfyouarefamiliarwitharraysinC/C++,itwillbeeasierforyoutoget started,astheArduinolanguageusesthesameC/C++arrays.Thefollowingare someofthemethodstoinitializeanarray: intmyIntArray[]={1,2,3,4,5}; inttempValues[5]={32,55,72,75}; charmsgArray[10]="hello!"; Anarraycanbeaccessedusinganindexnumber(wheretheindexstartsfromnumber 0): myIntArray[0]==1 msgArray[2]=='e' Conversions Conversionfunctionsareusedtoconvertanydatatypevalueintotheprovideddatatypes. TheArduinolanguageimplementsthefollowingconversionfunctionsthatcanbeutilized duringprogramming: char():Thisconvertsthevalueofanydatatypetothecharacterdatatype byte():Thisconvertsthevalueofanydatatypetothebytedatatype int():Thisconvertsthevalueofanydatatypetotheintegerdatatype float():Thisconvertsthevalueofanydatatypetothefloating-pointnumberdata type Asademonstrationofusingthesefunctions,checkoutthefollowingexample: intmyInt=10; floatmyfloat=float(myInt); Implementationoftheprecedingcodewillcreateafloating-pointvariable,myFloat,with value10.0usingtheintegervalueinitializedbythemyIntvariable. Functionsandstatements Functions,alsocalledsubroutinesorprocedures,areapieceofcodeimplementedtodo specifictasks.TheArduinolanguagehassomepredefinedfunctionsandtheusercanalso writecustomfunctionstoimplementcertainprogramlogic.Thesecustomfunctionscan thenbecalledfromanypartofthesketchtoperformaspecifictask.Functionshelp programmerstosimplifydebugging,toreducechancesforerror,andtoorganizecoding concepts: voidblinkLED(){ //actionA; //actionB; } TheArduinolanguagehasasetoflibraryfunctionstosimplifytheprogramming experience.AlthoughnotalloftheselibraryfunctionsarerequiredbyanArduinosketch, setup()andloop()aremandatoryfunctionsandtheyarerequiredtosuccessfully compilethesketch. Thesetup()function WhenArduinorunsasketch,itfirstlooksforthesetup()function.Thesetup()function isusedtoexecuteimportantprogrammingsubroutinesbeforetherestoftheprogram,such asdeclaringconstants,settinguppins,initializingserialcommunication,orinitializing externallibraries.WhenArduinorunstheprogram,itexecutesthesetup()functionsonly once.IfyoucheckouttheBlinksketchthatweusedintheprevioussection,youcansee theinitializationofthesetup()function,asdisplayedinthefollowingcodesnippet: voidsetup(){ //initializethedigitalpinasanoutput. pinMode(led,OUTPUT); } Asyoucanseeinourexample,weusedthepinMode()functiontoassigntheroleofthe LEDpininthesetup()function. Theloop()function OnceArduinohasexecutedthesetup()function,itstartsiteratingtheloop()function continuously.Whilesetup()containstheinitializationparameters,loop()containsthe logicalparametersofyourprogram: voidloop(){ digitalWrite(led,HIGH); delay(1000); digitalWrite(led,LOW); delay(1000); } AsyoucanseeintheprecedingcodesnippetfromtheBlinksketch,theloop()function executesthemaincodethatblinkstheLEDandrepeatstheprocessiteratively. ThepinMode()function ThepinMode()functionisusedtosetthebehaviorofArduino.Aswesawinthesetup() functionoftheBlinksketch,thepinMode()functionconfigurestheLEDpinforOUTPUT: pinMode(led,OUTPUT) Here,theledvariableisassignedtodigitalpin13,whosemodewillbechangedbythe pinMode()function. Workingwithpins Onceyouaredoneconfiguringthepinsthatwillbeusedbyyourprogram,youalsoneed helpinreadingtheinputfromthesepinsorforsendingsignalstothem.Arduinoprovides afewspecificfunctionstohandlethesescenarios: digitalWrite():ThiswasdevelopedfordigitalI/Opins.Thisfunctionsetsthepin toHIGH(5V)orLOW(0V),whicharealreadyconfiguredasOUTPUTusingpinMode(). Forexample,thefollowinglineofcodesetsdigitalpin13toHIGH: digitalWrite(13,HIGH); digitalRead():SimilartodigitalWrite(),thisfunctionhelpsyoutoreadthestate ofadigitalpinthatisconfiguredasINPUT: value=digitalRead(13); analogRead():Thisfunctionreadsthevaluefromaspecificanalogpin.Thevalueis linearlymappedbetweentheintegervalueof0and1023torepresentthevoltage from0Vto5V: value=analogRead(0); analogWrite():Thisfunctionisusedtoprovideanalogoutputresultsatadigitalpin. ThetechniqueiscalledPWM,andthiswillbeexplainedinChapter4,Divinginto Python-ArduinoPrototyping.Itisstillimportanttonotethatthisfunctionisnot designedforalldigitalpins,butitisonlyforpinsthataredesignatedasPWMpins. Statements Ifyouarefamiliarwithanyotherobject-orientedprogramminglanguage,youmusthave usedstatementsextensivelyforyourprograms.TheArduinolanguageusestraditional C/C++statementssuchasif/else,while,switch/case,andfortocontroltheflowof yourprogram.Insteadofdivingdeepintothesestatementsrightnow,theyaredescribed laterinthebookwithpracticalexamples. Summary Alright!Youhavesuccessfullycompletedthecomparativelymundanetasksofinstalling andconfiguringPythonandtheArduinoIDE.Yoursystem,whetheritisaMacOSX, Linux,orWindowssystem,isnowreadyfortheupcomingchapters.Inthischapter,we wentthroughthehistoryandbuildingblocksofArduino.Wealsolearnedthebasicsof PythonprogrammingandtheArduinolanguage.Now,youarereadytogetyourhandson realhardwareandstartexploringcomputertohardwareinterfacing.Inthenextchapter, wewillgothroughthefirststepofinterfacing,thatis,connectingArduinotothecomputer usingaserialinterface. Chapter2.WorkingwiththeFirmata ProtocolandthepySerialLibrary Inthepreviouschapter,youlearnedthefundamentalsofthePythonprogramming languageandtheArduinohardwareplatformsothatyoucouldgetstarted.Ifyouare readingthischapterdirectlywithoutgoingthroughthepreviouschapter,itisassumedthat youhavesomelevelofexpertiseorworkingexperiencewiththesetechnologies.This chapterdescribestwoimportantcomponentsthatarerequiredtobridgeArduinowith Python: TheArduinoFirmataprotocol Python’sseriallibrarycalledpySerial AlthoughtheFirmataprotocolisusefultointerfaceArduinowithPython,itcanalsobe usedasanindependenttooltodevelopalargevarietyofapplications. ItistimetotakeyourArduinohardwareoutandstartgettingyourhandsdirty.Duringthe courseofthischapter,youwillrequireanLED,abreadboard,anda1kilo-ohmresistoras wellasthecomponentsthatyoualreadyusedinthepreviouschapter,thatis,ArduinoUno andaUSBcable. Note IfyouareusinganyothervariantofArduino,youcanobtainfurtherinformationaboutit fromhttp://arduino.cc/en/Guide/HomePageorthecommunity-supportedArduinoforum thatislocatedathttp://forum.arduino.cc/. ConnectingtheArduinoboard Asmentionedinthepreviouschapter,thisbooksupportsallmajoroperatingsystems,and thissectionwillprovideyouwithstepstoconnectandconfiguretheArduinoboardfor theseoperatingsystems.Inthepreviouschapter,weutilizedexamplecodetogetstarted withtheArduinoIDE.IfyouwereunabletosuccessfullycommunicatewithArduinoby followingtheinformationgiveninthepreviouschapter,followtheinstructionsprovided inthissectiontoestablishaconnectionbetweenyourcomputerandyourArduino.First, connectyourArduinoboardtoyourcomputer’sUSBportusingaUSBcableandfollow thestepsaccordingtoyouroperatingsystem. Linux IfyouareusingthelatestversionofUbuntuLinux,onceyouconnecttheArduinoboard andopentheArduinoIDE,youwillbeaskedtoaddyourusernametothedailoutgroup, asdisplayedinthefollowingscreenshot.ClickontheAddbuttonandlogoutfromthe system.Youdon’tneedtorestartthecomputerforthechangestotakeeffect.Loginwith thesameusernameandopentheArduinoIDE. Ifyoudon’tseethisdialogbox,checkwhetheryoucanseetheSerialPortoptioninthe ToolsmenuoftheArduinoIDE.Itispossiblethattheinstallationofotherprogramsmight haveaddedyourusernametothedailoutgroupalready.Ifyoudon’tgetthedialogboxand don’thaveanyoptionstoselectinSerialPort,executethefollowingscriptinthe terminal,where<username>isyourLinuxusername: $sudousermod-a-Gdialout<username> Thisscriptwilladdyourusernametothedialoutgroup,anditshouldalsoworkforother Linuxversions.InLinux,theArduinoboardmostlygetsconnectedas/dev/ttyACMx, wherexistheintegervalueanddependsonyourphysicalportaddress.Ifyouareusing anyotherdistributionofLinuxotherthanUbuntu,youmightwanttocheckouttheproper groupsassociatedwiththeArduinoserialportfromtheLinuxinstallationpage (http://playground.arduino.cc/Learning/Linux)oftheArduinowebsite. Note FortheFedoraLinuxdistribution,addtheuucpandlockgroupswiththedialoutgroup tocontroltheserialport: $sudousermod-a-Guucp,dialout,lock<username> MacOSX InMacOSX,whenyouconnectyourArduinothroughaserialport,theOSconfiguresit asanetworkinterface.InOSXMavericks,oncetheArduinoboardisconnected,open NetworkfromSystemPreferences.Adialogboxshouldappearthatstatesthatanew networkinterfacehasbeendetected.ClickonOKforThunderboltBridgeandthenclick onApply.Thefollowingscreenshotdisplaysthedialogboxtoaddanewnetwork interface: ForOSXLionorlaterversions,onconnectingtheArduinoboard,adialogboxwill appearthatwillaskyoutoaddanewnetworkinterface.Inthiscase,youwillnothaveto navigatetoyournetworkpreferences.IfyouseethenetworkinterfacewiththestatusNot connectedandhighlightedinred,don’tworryaboutitasitshouldworkjustfine. OpentheArduinoIDEandnavigatetoSerialPortfromtheToolsmenu.Youshouldbe abletoseeoptionssimilartothosedisplayedinthefollowingscreenshot.Theserialport onwhichtheArduinoboardisconnectedmightvaryaccordingtoyourOSXversionand thephysicalporttowhichitisconnected.Makesurethatyouselectattyinterfacefora USBmodem.Asdisplayedinthefollowingscreenshot,theArduinoboardisconnectedto theserialport/dev/tty.usbmodemfd121: Windows TheconfigurationoftheArduinoserialportisverystraightforwardifyouareusing Windows.WhenyouconnectyourArduinoboardtheveryfirsttime,theoperatingsystem willautomaticallyinstallthenecessarydriversbyitself.Oncethisprocessiscomplete, selectanappropriateCOMportfromtheSerialPortoptioninthemenubar.Fromthe mainmenu,navigatetoTools|SerialPortandselecttheCOMport. Troubleshooting Evenafterfollowingthestepsmentionedearlier,ifyoustilldon’tseethehighlighted SerialPortoptionasdisplayedinthefollowingscreenshot,thenyouhavegotaproblem. Therecanbetwomainreasonsforthis:theserialportisbeingusedbyanotherprogramor theArduinoUSBdriversarenotinstalledproperly. IfanyprogramotherthantheArduinoIDEisusingthespecificserialport,terminatethat programandrestarttheArduinoIDE.SometimesinLinux,thebrlttylibraryconflicts withtheArduinoserialinterface.Removethislibrary,logout,andlogbackin: $sudoapt-getremovebrltty InWindows,reinstallingtheArduinoIDEalsoworks,asthisprocessinstallsand configurestheArduinoUSBdriveragain. Tip TheArduinoboardcanbeusedbyonlyoneprogramatatime.Itisveryimporttomake surethatanypreviouslyusedprogramorotherservicesarenotusingtheserialportor ArduinowhenyoutrytousetheArduinoIDE.Thischeckwillbecomeveryimportant whenwestartusingmultipleprogramstocontrolArduinointhenextsection. AssumingthatyoucannowselecttheserialportintheArduinoIDE,wecangoahead withcompilinganduploadingsketchestoyourArduinoboard.TheArduinoIDEships withpreinstalledexamplesketcheswithwhichyoucanplayaround.However,beforewe goaheadandstartplayingwithcomplexexamples,let’sgothroughthenextsection, whichexplainstheFirmataprotocolandalsoguidesyouthroughstep-by-stepinstructions tocompileanduploadasketch. IntroducingtheFirmataprotocol BeforeArduino,thedomainofmicrocontroller-basedapplicationswaslimitedto hardwareprogrammers.Arduinomadeitsimplefordevelopersthatcamefromother softwarefieldsandevenforthenon-codingcommunitytodevelopmicrocontroller-based hardwareapplications.Arduinoconsistsofasimplehardwaredesignwitha microcontrollerandI/Opinstointerfaceexternaldevices.IfonecanwriteanArduino sketchthatcantransferthecontrolofthemicrocontrollerandthesepinstoanexternal softwaremechanism,thenitwillreduceone’seffortstouploadArduinosketchesforevery modification.ThisprocesscanbeperformedbydevelopingsuchanArduinoprogramthat canthenbecontrolledusingaserialport.ThereexistsaprotocolcalledFirmata,which doesexactlythat. WhatisFirmata? Firmataisagenericprotocolthatallowscommunicationbetweenthemicrocontrollerand thesoftwarethatishostedonacomputer.Anysoftwarefromanycomputerhostthatis capableofserialcommunicationcancommunicatewiththemicrocontrollerusingFirmata. FirmatagivescompleteaccessofArduinodirectlytothesoftwareandeliminatesthe processesofmodifyinganduploadingArduinosketches. ToutilizetheFirmataprotocol,adevelopercanuploadasketchthatsupportstheprotocol totheArduinoclientasaonetimeprocess.Afterwards,thedevelopercanwritecustom softwareonthehostcomputerandperformcomplextasks.Thissoftwarewillprovide commandsviaaserialporttotheArduinoboardthatisequippedwithFirmata.Heorshe cankeepalteringthelogiconthehostcomputerwithoutinterruptingtheArduino hardware. ThepracticeofwritingcustomArduinosketchesisstillvalidforstandaloneapplications wheretheArduinoboardhastoperformatasklocally.Wewillexploreboththeseoptions intheupcomingchapters. Note YoucanlearnmoreabouttheFirmataprotocolanditslatestversionfromtheofficial websiteathttp://www.firmata.org. UploadingaFirmatasketchtotheArduinoboard ThebestwaytostarttestingtheFirmataprotocolistouploadastandardFirmataprogram totheArduinoboardandusethetestingsoftwarefromthehost.Inthissection,weare goingtodemonstrateamethodtouploadanArduinosketch,whichhasthisstandard Firmataprogram,totheboard.Thisisgoingtobethedefaultmethodtouploadanysketch inthefuture. ImplementationoftheFirmataprotocolrequiresthelatestversionoftheFirmatafirmware andyoudon’thavetoworryaboutwritingit.ThelatestArduinoIDEshipswithastandard versionoftheFirmatafirmware,andwerecommendthatyouusethelatestIDEtoavoid anyconflict.Now,followthefollowingstepstouploadtheprogramtoyourArduino board: 1. Asshowninthefollowingscreenshot,opentheStandardFirmatasketchby navigatingtoFile|Examples|Firmata|StandardFirmataintheArduinoIDE: 2. Thisactionwillopenanothersketchbookinanewwindowwiththe StandardFirmatasketchloadedintheeditor.Donotmodifyanythinginthesketch andgoaheadwiththecompilingprocessthatisdescribedinthenextstep.Itis importantnottomodifyanythinginthecodeasthetestsoftwarethatwearegoingto usecomplieswiththelatestunchangedfirmware. 3. OncetheStandardFirmatasketchisopened,thenextstepistocompileitforyour Arduinoboard.Intheprevioussection,wealreadyconnectedtheArduinoboardto thecomputerandselectedtheproperserialport.However,ifthenewsketchbookhas adifferentconfigurationthanthat,followthestepsfromtheprevioussection,thatis, selecttheappropriateserialportandtheArduinoboardtype. 4. Tocompilethecurrentsketch,clickontheVerifyiconfromthetoolbarasdisplayed inthefollowingscreenshot.YoucanalsocompileitbynavigatingtoSketch|Verify /CompileorclickingonCtrl+R(command+RifyouareusingMacOSX): Thecompilationprocessshouldcompletewithoutanyerrorsasweareusingdefault examplecodefromtheIDEitself.Nowit’stimetouploadthesketchtotheboard. Makesurethatyouhaveconnectedtheboard. 5. Presstheuploadiconinthetoolbarasdisplayedinthefollowingscreenshot.This actionwilluploadthecompiledcodetoyourArduinoboard: Oncompletion,youshouldseetheDoneuploading.textintheIDE,asdisplayedinthe followingscreenshot: YourArduinoboardisnowreadywiththelatestFirmatafirmwareandiswaitingfora requestfromyourcomputer.Let’smoveontothenextsectionandstarttestingtheFirmata protocol. TestingtheFirmataprotocol Inthepreviouschapter,weusedanon-boardLEDatpin13totesttheBlinkprogram. Thistime,wearegoingtouseanexternalLEDtogetyoustartedwiththeassemblyof hardwarecomponentsusingyourArduinoboard.Asalltheupcomingexercisesand projectswillrequireyoutointerfacehardwarecomponentssuchassensorsandactuators toyourArduinoboardusingabreadboard,wewantyoutostartgettinghands-on experiencewithwiringthesecomponents. NowisthetimetousetheLEDthatweaskedyoutogetatthebeginningofthechapter. BeforewestartwiringtheLED,let’sfirstunderstandthephysicsofit.TheLEDthatyou obtainedshouldhavetwolegs:ashortoneandalongone.Theshortlegisconnectedto thecathodeoftheLEDanditneedstobeconnectedtothegroundviaaresistor.Asyou canseeinthefollowingfigure,weareusinga1k-ohmresistortogroundthecathodeof theLED.Thelongleg,whichisconnectedtotheanode,needstoconnecttooneofthe digitalpinsoftheArduinoboard. Asshowninthefollowingfigure,wehaveconnectedtheanodetothedigitalpinnumber 13.Lookatthefigureandwiretheconnectionasdisplayed.Makesurethatyou disconnecttheArduinoboardfromthehostcomputertoavoidanykindofdamagefrom staticelectricity. Inthisexample,wearegoingtouseanLEDtotestsomebasicfunctionalitiesofthe Firmataprotocol.WehavealreadyuploadedtheFirmatacodetotheArduinoboardand wearereadytocontroltheLEDfromthehostcomputer. Note TheprecedingwiringfigurewascreatedusinganopensourcetoolcalledFritzing.Weare goingtocovertheFritzingtoolcomprehensivelyinthenextchapter,asitwillbeour standardsoftwaretocreatethewiringdiagrambeforeweperformtheactualphysical wiring. TherearemultiplewaystocommunicatewiththeArduinoboardfromthehostcomputer usingFirmata,suchaswritingyourownprograminPythonusingthesupportedlibraryor usingtheprebuilttestingsoftware.Startingfromthenextsection,wearegoingtowrite ourownprogramstouseFirmata,butatthisstage,let’suseafreelyavailabletoolfor testingpurposes.TheofficialFirmatawebsite,http://www.firmata.org,alsoprovidestest toolsthatyoucandownloadfromtheFirmataTestProgramsectiononthemainpage. Thewebsiteincludesadifferentvariantofthetoolcalledfirmata_testfordifferent operatingsystems.Usingthefollowingsteps,youcantesttheimplementationofthe Firmataprotocol: 1. Downloadtheappropriateversionofthefirmata_testprogramtoyourcomputer. 2. Now,connectyourArduinoboardwiththeLEDtothehostcomputerusingtheUSB cableandrunthedownloadedfirmata_testprogram.Youwillbeabletoseean emptywindowonthesuccessfulexecutionoftheprogram. 3. Asdisplayedinthefollowingscreenshot,selecttheappropriateportfromthedropdownmenu.MakesuretoselectthesameportthatyouusedtouploadtheArduino sketch. Tip Atthispoint,makesurethatyourArduinoIDEisnotconnectedtotheboardusing thesameportnumber.Aswementionedearlier,theserialinterfacegrantsexclusive accesstoonlyoneapplicationatatime. 4. OnceyouselecttheArduinoserialport,theprogramwillloadmultipledrop-down boxesandbuttonswithlabelsthatcontainthepinnumber.Youcanseeinthe followingscreenshotthattheprogramisloadedwith12digitalpins(frompin2to pin13)andsixanalogpins(frompin14topin19).AsweareusingtheArduinoUno boardforourapplications,thetestprogramonlyloadspinsthatarepartofArduino Uno.IfyouareusingArduinoMegaoranyotherboard,thenumberofpinsdisplayed intheprogramwillbeaccordingtothepinssupportedbythatparticularvariantofthe Arduinoboard. Tip Workingwiththefirmata_testprogramonLinux OnaLinuxplatform,youmighthavetomodifythepropertyofthedownloadedfile andmakeitexecutable.Fromthesamedirectory,runthefollowingcommandinthe terminaltomakeitexecutable: $chmod+xfirmata_test Onceyouhavechangedthepermissions,usethefollowingcommandtorunthe programfromtheterminal: $./firmata_test 5. Asyoucanseeintheprogramwindow,youhavetwoothercolumnsaswellasthe columncontainingthelabels.Thesecondcolumnintheprogramletsyouselectthe rolefortheappropriatepins.Youcanspecifytheroleofdigitalpins(inthecaseof ArduinoUno,from2to13)asinputoroutput.Asdisplayedinthefollowing screenshot,youwillseeLowinthethirdcolumnassoonasyouselecttheroleof pins2and3asinputpins.Thisiscorrect,aswedon’thaveanyinputconnectedto thesepins.Youcanplaywiththeprogrambychangingtherolesandvaluesof multiplepins. AswehaveconnectedtheLEDtodigitalpin13,wearenotexpectinganyphysical changesontheboardwhileyouareplayingaroundwiththeotherpins. 6. Now,selectpin13asanoutputpinandpresstheLowbutton.Thiswillchangethe button’slabeltoHighandyouwillseethattheLEDisturnedon.Byperformingthis action,wehavechangedthelogicofthedigitalpin13to1,thatis,High,which translatesto+5voltsatthepin.ThispotentialwillbesufficienttolighttheLED.You canchangethelevelofpin13backto0byclickingonthebuttonagainandturningit toLow.Thiswillchangethepotentialbackto0volts. Theprogramthatweusedhereisperfecttotestthefundamentals,butitcannotbeusedto writecomplexapplicationsusingtheFirmataprotocol.Inreal-worldapplications,we reallyneedtoexecutetheFirmatamethodsusingcustomcode,whichinadditionto switchingtheLEDstatusalsoincludestheimplementationofsmartlogicandalgorithms, interfacingothercomponents,andsoon.WearegoingtousePythonforthese applications,startingfromthenextsection. GettingstartedwithpySerial YoulearnedabouttheFirmataprotocolintheprevioussection.Thisisaneasyandquick waytostartworkingwithArduino.AlthoughtheFirmataprotocolhelpsyoutodevelop complexapplicationsfromyourcomputerwithoutmodifyingtheArduinosketch,weare notreadytostartcodingtheseapplications. Thefirststeptowardswritingthesecomplexapplicationsistoprovideaninterface betweenyourprogrammingenvironmentandtheArduinoviaaserialport.Inthisbook, youwillberequiredtoestablishaconnectionbetweenthePythoninterpreterandArduino foreveryprojectthatwedevelop. Writingyourownlibrary,whichincludesimplementationoffunctionsandspecifications toenablecommunicationonaserialprotocol,isaninconvenientandtimeconsuming process.Wearegoingtoavoidthatbyusinganopensource,wellmaintainedPython librarycalledpySerial. ThepySeriallibraryenablescommunicationwithArduinobyencapsulatingtheaccess fortheserialport.ThismoduleprovidesaccesstotheserialportsettingsthroughPython propertiesandallowsyoutoconfiguretheserialportdirectlythroughtheinterpreter. pySerialwillbethebridgeforanyfuturecommunicationbetweenthePythonand Arduino.Let’sstartbyinstallingpySerial. InstallingpySerial WeinstalledthepackagemanagerSetuptoolsinChapter1,GettingStartedwithPython andArduino.Ifyouhaveskippedthatchapterandarenotsureaboutit,thenpleasego throughthatsection.IfyoualreadyknowhowtoinstallandconfigurePythonlibrary packages,skiptheseinstallationsteps. Fromthisstage,wearegoingtouseonlypip-basedinstallationcommandsduetotheir obviousadvantagesthatweredescribedinChapter1,GettingStartedwithPythonand Arduino: 1. Openaterminalorcommandpromptandexecutethefollowingcommand: >pipinstallpyserial TheWindowsoperatingsystemdoesnotrequireadministrator-leveluseraccessto executethecommand,butyoushouldhaverootprivilegestoinstallPythonpackages inUnix-basedoperatingsystems,asfollows: $sudopipinstallpyserial IfyouwanttoinstallthepySeriallibraryfromsource,downloadthearchivefrom http://pypi.python.org/pypi/pyserial,unpackit,andfromthepySerialdirectory,run thefollowingcommand: $sudopythonsetup.pyinstall 2. IfPythonandSetuptoolsareinstalledproperly,youshouldseethefollowingoutput atthecommandlineaftertheinstallationiscomplete: . . Processingdependenciesforpyserial Finishedprocessingdependenciesforpyserial ThismeansthatyouhavesuccessfullyinstalledthepySeriallibraryandyouare goodtogotothenextsection. 3. Now,tocheckwhetherornotpySerialissuccessfullyinstalled,startyourPython interpreterandimportthepySeriallibraryusingthefollowingcommand: >>>importserial PlayingwithapySerialexample YourArduinoboardhastheFirmatasketchStandardFirmatafromthepreviousexample. ToplaywithpySerial,wearenotgoingtousetheFirmataprotocolanymore.Instead,we aregoingtouseanothersimpleArduinosketchthatimplementsserialcommunicationthat canbecapturedonthePythoninterpreter. StickingwiththepromiseofnotperforminganycodingfortheArduinosketch,let’sselect anexamplesketchfromtheArduinoIDE: 1. Asdisplayedinthefollowingscreenshot,navigatetoFile|Examples|01.Basics| DigitalReadSerial. 2. CompileanduploadtheprogramtotheArduinoboardusingthesamemethodthat wasdescribedearlier.SelecttheappropriateserialportonwhichyourArduinois connectedandmakeanoteofit.Asyoucanseeinthesketch,thissimpleArduino codetransmitsthestatusofdigitalpin2thatisontheserialportwithabaudrateof 9600bps. 3. WithoutdisconnectingtheArduinoboardfromyourcomputer,openthePython interpreter.Then,executethefollowingcommandsonthePythoninterpreter.Make surethatyoureplace/dev/ttyACM0withtheportnamethatyounoteddownearlier: >>>importserial >>>s=serial.Serial('/dev/ttyACM0',9600) >>>whileTrue: prints.readline() 4. Onexecution,youshouldgetrepeated0valuesinthePythoninterpreter.PressCtrl+ Ctoterminatethiscode.Asyoucansee,theArduinocodewillkeepsending messagesduetotheloopfunctionthatwasusedinthesketch.Wedon’thave anythingconnectedtopin2,andbecauseofthis,wearegettingthestatus0,thatis, Low. 5. Ifyouknowwhatyouaredoing,youcanconnectanydigitalsensortopin2andrun thescriptagaintoseethechangedstatus. IntheprecedingPythonscript,theserial.Serialmethodinterfacesandopensthe specifiedserialport,whilethereadline()methodreadseachlinefromthisinterface, terminatedwith\n,thatis,thenewlinecharacter. Note Thenewlinecharacterisaspecialcharacterthatsignifiestheendofalineoftext.Itisalso knownasEndofLine(EOL)orLinefeed+CarriageReturn(LF+CR).Learnmore aboutthenewlinecharacterathttp://en.wikipedia.org/wiki/Newline. BridgingpySerialandFirmata IntheFirmatasection,wealreadylearnedhowusefulitistousetheFirmataprotocol insteadofconstantlymodifyingtheArduinosketchanduploadingitforsimpleprograms. pySerialisasimplelibrarythatprovidesabridgebetweenArduinoandPythonviaa serialport,butitlacksanysupportfortheFirmataprotocol.Asmentionedearlier,the biggestbenefitofPythoncanbedescribedinonesentence,“Thereisalibraryforthat.” So,thereexistsaPythonlibrarycalledpyFirmatathatisbuiltonpySerialtosupportthe Firmataprotocol.ThereareafewotherPythonlibrariesthatalsosupportFirmata,butwe willonlybefocusingonpyFirmatainthischapter.Wewillbeextensivelyusingthis libraryforvariousupcomingprojectsaswell: 1. Let’sstartbyinstallingpyFirmatajustlikeanyotherPythonpackagebyusing Setuptools: $sudopininstallpyfirmata Intheprevioussection,whiletestingpySerial,weuploadedtheDigitalSerialRead sketchtotheArduinoboard. 2. TocommunicateusingtheFirmataprotocol,youneedtouploadthe StandardFirmatasketchagain,justaswedidintheUploadingaFirmatasketchto theArduinoboardsection. 3. Onceyouhaveuploadedthissketch,openthePythoninterpreterandexecutethe followingscript.Thisscriptimportsthepyfirmatalibrarytotheinterpreter.Italso definesthepinnumberandtheport. >>>importpyfirmata >>>pin=13 >>>port='/dev/ttyACM0' 4. Afterthis,weneedtoassociatetheportwiththemicrocontrollerboardtype: >>>board=pyfirmata.Arduino(port) Whileexecutingthepreviousscript,twoLEDsontheArduinowillflickerasthe communicationlinkbetweenthePythoninterpreterandtheboardgetsestablished.In theTestingtheFirmataprotocolsection,weusedaprebuiltprogramtoturnanLED onandoff.OncetheArduinoboardisassociatedtothePythoninterpreter,these functionscanbeperformeddirectlyfromtheprompt. 5. YoucannowstartplayingwithArduinopins.TurnontheLEDbyexecutingthe followingcommand: >>>board.digital[pin].write(1) 6. YoucanturnofftheLEDbyexecutingthefollowingcommand.Here,inboth commands,wesetthestateofdigitalpin13bypassingvalues1(High)or0(Low): >>>board.digital[pin].write(0) 7. Similarly,youcanalsoreadthestatusofapinfromtheprompt: >>>board.digital[pin].read() Ifwecombinedthisscriptinanexecutablefilewitha.pyextension,wecanhavea PythonprogramthatcanberundirectlytocontroltheLEDratherthanrunningthese individualscriptsonaterminal.Later,thisprogramcanbeextendedtoperformcomplex functionswithoutwritingorchangingtheArduinosketch. Note AlthoughwearerunningindividualscriptsatthePythonprompt,wewillbegoing throughtheprocessofcreatingPythonexecutablefilesinthenextchapter. Summary ByintroducingtheFirmatalibrary,weavoidedwritinganycustomArduinosketchesin thischapter.Wewillcontinuethispracticeduringtheremainingpartofthisbookandwill onlyuseormakecustomsketcheswhenrequired.Inthischapter,youinteractedwiththe ArduinoboardbymakingtheLEDblink,whichistheeasiestwaytogetstartedona hardwareproject.Nowit’stimeforyourfirstproject,wherewearealsogoingtomake somemoreLEDsblink.Onemightaskthequestionthatifwehavealreadydoneit,then whydoweneedanotherprojecttomakeLEDsblink?Let’sfindout. Chapter3.TheFirstProject–MotiontriggeredLEDs Intheprecedingchapter,youlearnedthebasicsofPython-Arduinointerfacing.Wewent throughsomeexercisestoprovidehands-onexperiencewithausefulArduinoprotocol, Firmata,andthePythonlibrary.Now,it’stimeforyourfirst‘Python+Arduino’project. Wewillstartthischapterbydiscussingtheprojectgoalsandtherequiredcomponentsto designthesoftwareflowandthehardwarelayoutfortheproject.Justlikeanyother microcontroller-basedhardwareproject,youcanusecodeandimplementtheentirelogic ofyourprojectonArduinoitself.However,thegoalofthisbookistohelpyoutoutilize Pythoninsuchawaythatyoucansimplifyandextendyourhardwareprojects.Although wewillbeusingahybridapproachwithaPythonprogramassistedbyanArduinosketch intheupcomingchapters,wewouldlikeyoutogetfamiliarwithbothwaysof programming.Asthisisyourfirstexperienceofbuildingahardwareproject,thechapter providesyouwithtwodifferentprogrammingmethodsfortheproject:justusingan ArduinosketchandusingaPythonprogramwiththeFirmataprotocolonArduino.The methodwiththeArduinosketchisincludedsothatyougetthecompleteexperiencewith theArduinocomponentssuchasI/Opinsandserialcommunication. Motion-triggeredLEDs–theproject description Whenyoustartlearninganyprogramminglanguage,inmostcases,youwillbewriting codetoprint‘HelloWorld!’.Meanwhile,inhardwareprojects,themajorityoftutorials beginbyhelpingausertowritethecodetoblinkanLED.Theseexercisesorprojectsare usefulfordeveloperstogetstartedwiththelanguage,butmostly,theydonotcarryany importancetowardsreal-worldapplications.However,wedon’twanttooverwhelmyou withacomplexandsophisticatedprojectthatmightrequireyoutohaveagoodamountof domainknowledge. WhileworkingwiththeFirmataprotocolinthepreviouschapter,wealreadyblinkedan LEDontheArduinoboard.Tokeepthetraditionalive(ofhavingablinkingLEDasafirst majorproject)andalsobuildexcitementtowardstheproject,let’sputatwistinthe blinkingLEDproject.Inthisproject,wewillblinktwodifferentLEDs,butinsteadof performingtheseactionsinarandommanner,wewilldoitforeventsthataremeasured usingamotionsensor.Althoughthedifficultlyleveloftheprojectissimplesinceitis yourfirstproject,itcarriesreal-worldapplicationvalueandcanbeusedasasimple applicationinyourday-to-daylife. Theprojectgoal Theprojectgoalcanbedescribedinonesentenceasfollows:“Generateanalertusinga redLEDforanydetectedmotionanddisplaythenormalconditionusingagreenLED.”In comprehensivelistofgoals,youwillhavetoperformthefollowingtaskstosatisfythe mentionedprojectgoal: Detectanymotionintheenvironmentasaneventusingapassiveinfrared(PIR) sensor PerformablinkactionusingaredLEDforthisevent Otherwise,performablinkactionusingagreenLED Keepthesysteminloopaftertheactionhasbeenperformedandwaitforthenext event TheprojectcanbeimplementedasaDIYapplicationoraspartofotherprojectswith minormodifications.Thefollowingaresomeexampleswheretheconceptsfromthis projectcanbeutilized: AsaDIYsecuritysystem,tomonitormovementinaroom (http://www.instructables.com/id/PIR-Sensor-Security/) Insmarthomeapplications,itcanbeusedtoautomaticallyturnofflightsifnooneis present(http://www.instructables.com/id/Arduino-Home-Monitor-System/) Itcanbeusedinautomaticgaragedooropenerapplicationswiththesupportof additionalhardwarecomponentsandappropriatecode InDIYwildliferecordingprojects,itcanbeusedtotriggeracamerainsteadofan LEDwhenanymotionisdetected(http://www.instructables.com/id/Motiontriggered-camera/) Thelistofcomponents Inthepreviouschapter,weonlyusedanLEDforprogrammingusingArduino,an ArduinoUSBcable,andacomputer.Themajorhardwarecomponentrequiredforthis projectisaPIRmotionsensor.YouwillalsoneedanadditionalLED.Werecommendthat youhaveadifferentcoloredLEDthantheonethatyoualreadyhave.Thedescriptionof thenecessarycomponentsisasfollows: PIRsensors:ThesearewidelyusedasmotiondetectionsensorsforDIYprojects. Theyaresmall,inexpensive,consumelesspower,andarecompatiblewithhardware platformssuchasArduino.APIRsensorusesapairofpyroelectricsensorsthat detectinfraredradiation.Ifthereisnomotion,theoutputofthesesensorscancels eachotherout.Anymovementintheenvironmentwillproducedifferentlevelsof infraredradiationbythesepyroelectricsensorsandthedifferencewilltriggeran outputthatisHIGH(+5volts).WewillbeusingthePIRsensorthatissoldby SparkFun,andyoucanobtainitfromhttps://www.sparkfun.com/products/8630.The PIRsensorcomesequippedwiththerequiredprintedcircuitboard(PCB).Ithas rangeofupto20feet(6meters),whichissufficientfortheproject.Thefollowing imagedisplaysthePIRsensoravailableontheSparkFunwebsite: Source:SparkfunInc. LEDs:WerecommendthatyouusegreenandredLEDsfortheproject.Iftheyare unavailable,youcanuseanytwoLEDswithdifferentcolors. Wires,resistors,andthebreadboard:Youwillrequireabunchofwiresanda breadboardtocompletetheconnections.Asabestpractice,haveatleastthree differentcolorsofwireconnectorstorepresentpower,ground,andsignal.Youwill alsoneedtwo220ohmandone10kilo-ohmpullresistors. TheArduinoboard:TheArduinoUnoboardissufficientfortheproject requirements.YoucanalsouseArduinoMegaoranyotherArduinoboardforthis project.TheprojectrequiresonlythreeI/OpinsandanyavailableArduinoboardis equippedwithmorethanthreeI/Opins. AUSBcable:YouwillneedaUSBcabletouploadtheArduinocodeandperform serialcommunicationwiththeArduinoboard. Acomputer:WehavealreadyconfiguredacomputerwithPythonandtheArduino IDEforyourfavoriteoperatingsysteminthepreviouschapters.Youwillneedthis computerfortheproject.Makesurethatyouhaveallthesoftwarecomponentsthat weinstalledandconfiguredinthepreviouschapters. Thesoftwareflowdesign Thefirststep,beforejumpingtoworkonanyhardwaresystem,istodesigntheproject flowusinglogic.Werecommendthatyouhaveyourprojectsketchedasaflowchartto betterunderstandthelayoutofthecomponentsandtheflowofthecode.Thefollowing diagramshowstheflowoftheprojectwhereyoucanseethattheprojectrunsinloops oncemotionisdetectedandtheappropriateLEDactionsareperformed: Asyoucansee,theprogramlogicstartsbydetectingthestateofthePIRsensorand performstheappropriateactionsaccordingly.WithasingleArduinoinstruction,youcan onlyturntheLEDonoroff.Toperformtheblinkingoperation,wewillneedtorepeatedly performtheturning-onandturning-offactionswithatimedelaybetweentheactions.We willalsoinsertadelaybetweentheexecutionofeachsuccessiveloopsothatthePIR sensoroutputcansettledown.Notethatwewillusethesameflowwhenwritingthecode forboththeprogrammingmethods. Thehardwaresystemdesign Designingadiagramforyoursoftwareflowhelpsyoutowritetheprogramandalso assistsyouinidentifyingactionsandeventsfortheproject.Theprocessofhardware systemdesignincludescircuitconnections,schematicdesign,simulation,verification,and testing.Thisdesignprocessprovidesadetailedunderstandingoftheprojectandthe hardwarecomponents.Italsohelpsinpreliminaryverificationandtestingoftheproject architecture.Beforewejumptothehardwaredesignprocessofthisproject,let’sget ourselvesfamiliarwiththehelpfultools. IntroducingFritzing–ahardwareprototypingsoftware Youarenotrequiredtodesignthehardwaresystemforthisproject.Byandlarge,inthis book,thehardwaresystemdesignswillbeprovided,astheprimaryfocusofthebookis onprogrammingratherthanhardwaredesign. Ifyouareinterestedinsystemdesignorrapidprototypingofthehardwarecomponents, theopensourcesoftwaretoolusedforthispurposeiscalledFritzing.Theschematicsfor yourprojectscanbedesignedusingFritzinganditcanbeobtainedfrom http://fritzing.org/download/. Fritzingisacommunity-supportedelectronicdesignautomationsoftwareinitiativefor designers,artists,andhobbyists.Itletsyouconvertyourhardwaresketchfrompaperto softwareasacircuitdiagram.FritzingalsoprovidesyouwithatooltocreatePCBlayouts fromyourdesigns.FritzingextensivelysupportsArduinoandotherpopularopensource DIYhardwareplatforms.YoucanexploreFritzingviabuilt-inexampleprojects. InstallandrunFritzing.Thefollowingscreenshotshowsoneofthedefaultprojectsthat aredisplayedafteropeningFritzing: Asyoucansee,atoolboxcontainingvirtualhardwarecomponentsislocatedtotheright oftheopenedwindow.Themaineditingspace,locatedinthecenter,letstheuserdragand dropcomponentsfromthetoolboxandalsoallowstheusertocompleteconnections betweenthesecomponents.YoucanlearnmoreaboutthefeaturesprovidedbyFritzing andgothroughsomehands-ontutorialsathttp://fritzing.org/learning/. Workingwiththebreadboard OnceyouarefamiliarwithFritzing,youhavetheflexibilitytocreateyourowncircuits,or youcanalwaysusetheFritzingfilesprovidedwiththebook.However,thereisanother challenge,thatis,portingyourvirtualcircuittoaphysicalone.Oneofthefundamental componentsusedbyelectronicsprojectsthatletyouimplementconnectionsandbuildthe physicalcircuitisthebreadboard. Thebreadboardcontainsintelligentlyorganizedmetalrowshiddenunderanassembly containingplasticholes.Thisassemblyhelpstheusertoconnectwireswithoutgoing throughanysolderingwork.Itisreallyeasytoinsertandremovewiresorelectronics componentsthroughtheholes.Thefollowingfigureshowsasmallbreadboardwitha coupleofcomponentsandafewwireconnections: Note Findoutmoreaboutbreadboardsandthetutorialstousethemat http://learn.sparkfun.com/tutorials/how-to-use-a-breadboard. Abreadboardmostlyhastwotypesofconnectionstrips:terminalstripsandpowerrails. Asdisplayedintheprecedingfigure,terminalstripsareverticalcolumnswithelectrically shortedholes.Insimplewords,onceyouconnectanycomponenttooneoftheterminal strips,thecomponentwillbeelectricallyconnectedtoeachholeinthecolumn.The columnsofterminalstripsareseparatedbytheDualin-linePackage(DIP)supportgap. (DIPisacommonhousingforelectronicscomponents.)Inthesamecolumn,terminal stripsaboveandbelowtheDIPsupportgapareelectricallyindependent.Meanwhile,the powerrailsareshortedhorizontallythroughouttheentirerowofthebreadboard.The powerrailsaremostlyusedtoconnectpositiveandgroundconnectionsfromthepower supply,soitcanbedistributedeasilytoallcomponents. Note Historyofbreadboards Intheearlyyearsofelectronics,peopleusedactualbreadboards(thatwereusedtocut bread)toconnecttheirlargecomponentswithjustnailsandwires.Onceelectronics componentsstartedgettingsmaller,theboardtoassemblecircuitsalsobecamebetter.The termstuckthroughthisevolution,andwestillcallthemodernboardsbreadboards.Ifyou areinterested,youcancheckouthttp://www.instructables.com/id/Use-a-real-BreadBoard-for-prototyping-your-circui/,whichprovidesinstructionstoassembleacircuit usingtheoriginalbreadboards. Designingthehardwareprototype It’stimetocollectthehardwarecomponentsmentionedearlierandstartbuildingthe system.Thenextfigureshowsthecircuitfortheprojectthathasbeendevelopedusing Fritzing.Ifyouhavepriorexperienceofworkingwithcircuitassembly,goaheadand connectthecomponentsasdisplayedinthefigure: Ifthisisyourfirstexperienceofworkingwithsensorsandthebreadboard,usethe followingstepstocompletethecircuitassembly: 1. ConnectVCC(+5V)andgroundfromtheArduinotothebreadboard. 2. Connecttheanode(longlead)oftheredLEDtodigitalpin12oftheArduinoboard. Connectthecathode(shortlead)oftheredLEDtogroundwith220ohmresistors. 3. Connecttheanode(longlead)ofthegreenLEDtodigitalpin13oftheArduino board.Connectthecathode(shortlead)ofthegreenLEDtogroundwith220ohm resistors. 4. ConnectVDDofthePIRsensortoVCConthebreadboard.Usethesamewirecolor torepresentthesamecategoryofconnections.Thiswillgreatlyhelpin troubleshootingthecircuit. 5. Connectthesignal(middlepin)ofthePIRsensortoArduinodigitalpin7witha10 kilo-ohmpull-upresistor. Themajorityofexpertspreferaschematicdiagraminsteadoftheprototypediagramthat weusedpreviously.Schematicdiagramsareusefulwhenyouareusingcompatible componentsinsteadoftheexactcomponentsfromtheprototypediagram.Thefollowingis aschematicdiagramoftheelectronicscircuitthatwedesignedearlier.Thisdiagramis alsoobtainedusingFritzing: YoursystemisnowreadytoruntheArduinoprogram.Aswewillbeusingthesame hardwareforboththeprogrammingmethods,youarealmostdoneworkingwith electronicsunlessyouencounteraproblem.Justtomakesurethateverythingisconnected perfectly,let’scheckouttheseconnectionsinthenextsection. Note Notethatpull-upresistorsareusedtomakesurethattheoutputsignalfromaPIRsensor settlesattheexpectedlogiclevel. Testinghardwareconnections Oncethecircuitconnectionsarecomplete,youcangodirectlytotheprogramming sections.Asabestpractice,werecommendthatyouverifythecircuitconnectionsand checkthesensor’sstatus.WeareassumingthatyourArduinoboardisalreadyequipped withtheStandardFirmatasketchthatwediscussedinthepreviouschapter.Otherwise, refertothepreviouschapteranduploadtheStandardFirmatasketchtoyourArduino board. ThebestwaytoverifyourcircuitimplementationistousetheFirmatatestprogramthat weusedinthepreviouschapter.Accordingtotheprojectsetup,thePIRsensorprovides eventinputstoArduinopin7.Inthetestprogram,changethetypeofpin7toInputand waveyourhandoverthesensor,andyoushouldbeabletoseethestatusofthepinas High,asdisplayedinthefollowingscreenshot: ChecktheLEDconnectionsbysettinguppins12and13asoutputpinsandtogglingthe buttonstosetthestatusofthepins.IfyouseetheLEDsblinkingwhileyouaretoggling thebutton,thenyourconnectionsareworkingperfectly. Ifyoucannotsuccessfullyperformthesechecks,verifyandrepeatthedesignsteps. Method1–usingastandaloneArduino sketch Aswediscussedinthepreviouschapters,aprojectcanbeimplementedbycreating project-specificnativeArduinocodeorbyusingaPython-Arduinohybridapproach. ThenativeArduinosketchesareusefulinapplicationswherenegligibleorno communicationwithacomputersystemisrequired.Althoughthistypeofstandalone projectenablescontinuousoperationintheabsenceofserialconnectivity,itisdifficultto keepupdatinganduploadinganArduinosketchforminormodifications. Ifyoulookatthevariousapplicationsofthisproject,youwillnoticethatonlyafewof themrequiretheprojecttobeimplementedasastandalonesystemthatjustdetectsmotion andblinksLEDs.ThistypeofsystemcanbeeasilyimplementedbyasimpleArduino sketch. Theprojectsetup Beforewegoaheadwiththeproject,makesurethatyouhavethefollowingthingsin place: Thehardwarecomponentsaresetupandarefunctioningcorrectly YourArduinoisconnectedtothecomputerusingaUSBcable YourcomputerhastheArduinoIDEandyoucanaccesstheconnectedArduinoboard throughtheIDE TheArduinosketch ThissectiondescribestheArduinocodefortheproject.Beforewegetintoastep-by-step descriptionofthecode,let’sfirstfollowthesestepstoruntheproject: 1. OpentheArduinoIDE. 2. FromtheFilemenu,openanewsketchbook. 3. CopythefollowingArduinocodetothesketchandsaveit: intpirPin=7;//PinnumberforPIRsensor intredLedPin=12;//PinnumberforRedLED intgreenLedPin=13;//PinnumberforGreenLED voidsetup(){ Serial.begin(9600); pinMode(pirPin,INPUT); pinMode(redLedPin,OUTPUT); pinMode(greenLedPin,OUTPUT); } voidloop(){ intpirVal=digitalRead(pirPin); if(pirVal==LOW){//wasmotiondetected blinkLED(greenLedPin,"Nomotiondetected."); }else{ blinkLED(redLedPin,"Motiondetected."); } } //FunctionwhichblinksLEDatspecifiedpinnumber voidblinkLED(intpin,Stringmessage){ digitalWrite(pin,HIGH); Serial.println(message); delay(1000); digitalWrite(pin,LOW); delay(2000); } 4. CompileanduploadthesketchtotheArduinoboard. Now,youhavecompletedyourprojectwiththefirstprogrammingmethodand successfullydeployedittoyourhardware.Itshouldberunningthedesignedalgorithmto detectmotioneventsandperformtheblinkaction. Asyourprojectisfunctioningproperly,it’stimetounderstandthecode.Likeanyother Arduinoprogram,thecodehastwomandatoryfunctions:setup()andloop().Italsohas acustomfunction,blinkLED(),foraspecificactionthatwillbeexplainedlater. Thesetup()function Asyoucanseeintheprecedingcodesnippet,weassignedvariablestotheArduinopinat thebeginningoftheprogram.Inthesetup()function,weconfiguredthesevariablestobe definedasinputoroutputpins: pinMode(pirPin,INPUT); pinMode(redLedPin,OUTPUT); pinMode(greenLedPin,OUTPUT); Here,pirPin,redLedPin,andgreenLedPinaredigitalpins7,12,and13respectively.In thesamefunction,wealsoconfiguredtheArduinoboardtoprovideserialconnectivelyat thebaudrateof9600bps: Serial.begin(9600); Theloop()function Intheloop()function,wearerepeatedlymonitoringtheinputfromthepirPindigitalpin todetectmotion.TheoutputofthispinisHIGHwhenmotionisdetectedandLOW otherwise.Thislogicisimplementedusingasimpleif-elsestatement.Whenthis conditionissatisfied,thefunctioncallsauser-definedfunction,blinkLED(),toperform theappropriateactionontheLEDs. User-definedfunctionsareaveryimportantaspectofanyprogramminglanguage.Let’s spendsometimelearninghowyoucancreateyourownArduinofunctionstoperform variousactions. WorkingwithcustomArduinofunctions Functionsareusedwhenasegmentofcodeisrepeatedlyexecutedtoperformthesame action.Ausercancreateacustomfunctiontoorganizethecodeorperformreoccurring actions.Tosuccessfullyutilizeacustomfunction,auserneedstocallthemfrom mandatoryArduinofunctionssuchasloop(),setup(),oranyotherfunctionthatleadsto thesemandatoryfunctions: return-typefunction_name(parameters){ #Actiontobeperformed Action_1; Action_2; Returnexpression; } IntheprecedingArduinofunctionframework,return-typecanbeanyArduinodatatype suchasint,float,string,andsoon,orvoidifthecodeisnotreturninganything.The followingisthecustomfunctionthatweusedinourprojectcode: voidblinkLED(intpin,Stringmessage){ digitalWrite(pin,HIGH); Serial.println(message); delay(1000); digitalWrite(pin,LOW); delay(2000); } Inourproject,theblinkLED()functionisnotretuninganyvaluewhenitiscalledfrom theloop()function.Hence,return-typeisvoid.Whencallingthefunction,wepassthe pinnumberandamessageasparameters: blinkLED(greenLedPin,"Nomotiondetected."); Theseparametersarethenutilizedintheperformedaction(writingamessageonaserial portandsettinguptheLEDstatus)bytheblinkLED()function.Thisfunctionalso introducesadelaytoperformtheblinkactionbyusingthedelay()function. Testing WeverifiedthedesignedsystemintheTestinghardwareconnectionsectionusingmanual inputsviatheFirmatatestprogram.Aswehavenowimplementedthesoftwaredesign,we needtoverifythattheprojectisperformingobjectivetasksautonomouslyandrepeatedly. WiththeUSBportconnectedtothecomputer,opentheserialmonitoringtoolfromthe ArduinoIDEbynavigatingtoTools|SerialMonitororbypressingCtrl+Shift+M.You shouldstartseeingamessagesimilartotheonedisplayedinthefollowingscreenshoton theSerialMonitorwindow: WhilewritingtheblinkLED()functiontoperformactions,weincludedanactiontowrite astringviaaserialport.MoveyourhandoverthePIRsensorinsuchawaythatthePIR sensorcandetectmotion.ThiseventshouldtriggerthesystemtoblinktheredLEDand displayastring,Motiondetected,ontheserialmonitor.Onceyoustaysteadyandavoid anymotionforawhile,youwillbeabletoseethegreenLEDblinkinguntilthenext movementgetsdetectedviathePIRsensor. Troubleshooting Troubleshootingisanimportantprocessifanythinggoesawry.Theseareafewexample problemsandthetroubleshootingstepsforthem: Serialoutputiscorrect,buttherearenoblinkingLEDs: ChecktheLEDconnectionsonthebreadboard TheLEDblinks,butthereisnoserialoutput: Checktheportonwhichtheserialmonitorisconfigured Checkwhetherthebaudrateintheserialmonitoriscorrect(9600bps) ThereisnoserialoutputandnoblinkingLEDs: CheckthePIRsensorconnectionandmakesurethatyouaregettingsignalfrom thePIRsensor CheckyourArduinocode Checkpowerandgroundconnections Method2–usingPythonandFirmata Inthepreviouschapter,wediscussedthebenefitsofusingPythonprogrammingthatis assistedbyFirmataoverusingnativeArduinosketches.ThePython-basedprogramming approachprovidestangibleexperiencewhenperforminganyalgorithmicorparametric changes.Inthissection,wearegoingtoexplorethesebenefitsandalsolearnimportant Pythonprogrammingparadigms. Theprojectsetup Let’smakesurethatyouhavedonethefollowingbeforewegoaheadwithPython programming: Madesurethatthehardwarecomponentsaresetup,asdescribedinthesystemdesign ConnectedtheArduinotoyourcomputerusingaUSBcable UploadedtheStandardFirmatasketchbacktoArduino MadesurethatyouhavePythonandthePythonpackages(pySerialandpyFirmata) installedonyourcomputer ObtainedatexteditortowritePythoncodes WorkingwithPythonexecutablefiles Inthepreviouschapters,weexploredPythonprogrammingusingtheinteractivePython interpreter.However,whenworkingwithlargeprojects,itisverydifficulttokeepusing thePythoninteractiveinterpreterforrepetitivetasks.Likeotherprogramminglanguages, thepreferredmethodistocreatePythonexecutablefilesandrunthemfromtheterminal. Pythonexecutablefilescarrythe.pyextensionandareformattedasplaintext.Anytext editorcanbeusedtocreatethesefiles.ThepopulareditorsusedtocreateandeditPython filesareNotepad++,nano,vi,andsoon.Thislistalsoincludesthedefaulteditorthatis shippedwiththePythonsetupfilescalledIDLE.Youcanusetheeditorofyourchoice, butmakesurethatyousavethefileswiththe.pyextension.Let’scopythefollowinglines ofcodeinanewfileandsaveitastest.py: #!/usr/bin/python a="Python" b="Programming" printa+""+b Torunthisfile,executethefollowingcommandontheterminalwherethetest.pyfileis saved: $pythontest.py YoushouldbeabletoseethetextPythonProgrammingprintedontheterminal.Asyou cansee,thefilestartswith#!/usr/bin/python,whichisthedefaultPythoninstallation location.ByaddingthislineinyourPythoncode,youcandirectlyexecuteaPythonfile fromtheterminal.InUnix-basedoperatingsystems,youneedtomakethetest.pyfile executablethroughthefollowingcommand: $chmod+xtest.py Now,asyourfileisexecutable,youcandirectlyrunthefileusingthefollowing command: $./test.py Note ForUnix-basedoperatingsystems,analternativewaytoprovidethePythoninterpreter locationistousethefollowinglineofcodeinsteadoftheonethatweused: #!/usr/bin/envpython InWindowsoperatingsystems,Pythonfilesautomaticallybecomeexecutablebecauseof the.pyextension.Youcanjustruntheprogramfilesbydouble-clickingandopening them. ThePythoncode AsyounowknowhowtocreateandrunPythoncode,let’screateanewPythonfilewith thefollowingcodesnippetandrunit.Makesuretochangethevalueoftheportvariable accordingtoyouroperatingsystem,asdescribedinthepreviouschapter: #!/usr/bin/python #Importrequiredlibraries importpyfirmata fromtimeimportsleep #DefinecustomfunctiontoperformBlinkaction defblinkLED(pin,message): printmessage board.digital[pin].write(1) sleep(1) board.digital[pin].write(0) sleep(1) #AssociateportandboardwithpyFirmata port='/dev/ttyACM0' board=pyfirmata.Arduino(port) #Useiteratorthreadtoavoidbufferoverflow it=pyfirmata.util.Iterator(board) it.start() #Definepins pirPin=board.get_pin('d:7:i') redPin=12 greenPin=13 #CheckforPIRsensorinput whileTrue: #IgnorecasewhenreceivingNonevaluefrompin value=pirPin.read() whilevalueisNone: pass ifvalueisTrue: #PerformBlinkusingcustomfunction blinkLED(redPin,"MotionDetected") else: #PerformBlinkusingcustomfunction blinkLED(greenPin,"NomotionDetected") #Releasetheboard board.exit() YouhavesuccessfullycreatedandexecutedyourfirstArduinoprojectusingPython. Therearetwomainprogrammingcomponentsinthiscode:pyFirmatamethodsandthe Pythonfunctiontoperformtheblinkingaction.Theprogramrepeatedlydetectsthemotion eventsandperformstheblinkingaction.Intheprevioussection,thisproblemwassolved byusingthedefaultArduinofunctionloop().Inthismethod,wehaveimplementedthe whilestatementtokeeptheprograminloopuntilthecodeismanuallyterminatedbythe user.YoucanterminatethecodeusingthekeyboardcombinationCtrl+C. WorkingwithpyFirmatamethods AspartofworkingwiththeArduinoboardandtheFirmataprotocol,youhavetostartby initializingtheArduinoboardasavariable.ThepyFirmatamethodthatletsauserassign theboardtoaPythonvariableisasfollows: board=pyfirmata.Arduino(port) Oncethevalueofthevariableisassigned,youcanperformvariousactionssuchas readingapinorsendingasignaltothepinusingthatvariable.Toassignaroletoapin, theget_pin()methodisused.Inthefollowinglineofcode,drepresentsthedigitalpin,7 isthepinnumber,andirepresentsthatthetypeofpinisaninputpin: pirPin=board.get_pin('d:7:i') Onceapinanditsroleareassignedtoavariable,thatvariablecanbeusedtoreadorwrite valuesonthepin: Value=pirPin.read() Onecandirectlywritedatatoaspecificpin,asdescribedinfollowingcode: board.digital[pin].write(1) Here,thewrite(1)methodsendsaHIGHsignaltothepin.Wewillbelearningadditional pyFirmatamethodsintheupcomingchapters. WorkingwithPythonfunctions APythonfunctionbeginswiththedefkeywordfollowedbythefunctionnameandthe inputparametersorarguments.Thefunctiondefinitionendswithacolon(:)anditis indentedafterwards.Thereturnstatementterminatesthefunction.Italsopassesthe expressiontotheplacewherethefunctioniscalled.Ifthereturnstatementiskept withoutanexpression,itisconsideredtopassthereturnvalueNone: deffunction_name(parameters): action_1 action_2 return[expression] Theprecedingframeworkcanbeusedtocreatecustomfunctionstoperformrecurring tasks.Inourproject,wehavetheblinkLED(pin,message)functiontoperformthe blinkingLEDaction.Thisfunctionsends1(HIGH)and0(LOW)valuetothespecified digitalpinwhilealsoprintingmessageontheterminal.Italsointroducesdelaytosimulate theblinkingaction: defblinkLED(pin,message): printmessage board.digital[pin].write(1) sleep(1) board.digital[pin].write(0) sleep(1) Testing YoucanstarttestingtheprojectassoonasyourunthePythoncodeontheterminal.If everythinggoesaccordingtodesign,youshouldbeabletoseethefollowingoutputinthe terminal: YoushouldbeabletoseetheMotionDetectedstringontheterminalwhenanymotionis detectedbythePIRsensor.Ifyoufindanyabnormalbehaviorintheoutput,thenplease checkthePythoncode. AbenefitofusingPythonisthatminormodificationssuchaschangingtheblinkingspeed orswappingrolesoftheLEDscanbeperformedbyjustchangingthePythoncode, withoutdealingwiththeArduinoortheelectricalcircuit. Troubleshooting Whenyouruntheproject,youmightrequiretroubleshootingforthefollowingprobable problems: Serialoutputiscorrect,buttherearenoblinkingLEDs: ChecktheLEDconnectionsonthebreadboard TheLEDblinks,butthereisnoserialoutput: CheckwhetheryouhavesuccessfullyinstalledthestandardFirmatasketchto theboard ThereisnoserialoutputandnoblinkingLEDs: CheckwhetheranyprogramotherthanPythonisusingtheserialport.Closeany programthatmightbeusingthatserialport,includingtheArduinoIDE. Verifyallthecircuitconnections. MakesurethattheportnamespecifiedinthePythoncodeiscorrect. Summary Betweenthetwoprogrammingmethodsthatyoulearnedinthischapter,themethodthat usesjustanArduinosketchrepresentsthetraditionalparadigmofprogramminga microcontroller.Whilethismethodissimpletoimplement,itlackstheextensivenessthat isachievedbyPython-Arduinointerfacing.AlthoughwewilluseextensiveArduino codinginalltheprojectsbeginningfromnow,exercisesandprojectswillhavePythonArduinointerfacingastheprimarywayofprogramming. Startingfromthenextchapter,wearegoingtoexploretheadditionalaspectsofPython programmingthatcanextendtheusabilityofanArduino-basedhardwareprojectwhile keepingtheprogrammingdifficultylevelstoaminimum.WewillbeginwithPythonArduinoprototypingandthencreategraphicalinterfacesforuserinteraction,before stoppingforthesecondprojectthatutilizestheseconcepts. Chapter4.DivingintoPython-Arduino Prototyping Onthecompletionofthefirstproject,yousuccessfullystartedPython-Arduino interfacing.Wealsointerfacedmultiplehardwarecomponents,thatis,motionsensorand LEDswithArduinoviadigitalpins.Duringtheproject,youlearnedmoreaboutthe FirmataprotocolwhileutilizingsimplePythonmethodsthathelpedyoutoestablisha connectionbetweenyourArduinoboardandthePythonprogram.Whenyouareworking oncomplexprojects,youneedmorethanbasicmethodstoimplementthedifferent featuresthatarerequiredbytheprojectsandtheirassociatedelectronicscomponents.This chapterisdesignedtogiveyouacomprehensiveexperienceofinterfacingsothatyoucan startworkingonhardproblemsfromthenextchapteronwards.Wehavedescribedvarious interfacingprotocolsatthePython-ArduinoandArduino-to-componentslevels.This chapteralsoincludespracticalexamplesfortheseprotocolswithappropriatecodeand circuitdiagrams.Inthischapter,wearegoingtocoverthefollowingmaintopics: IntroductiontoPrototyping DetaileddescriptionofvariouspyFirmatamethodstoportArduinofunctionalities intoPython Python-ArduinointerfacingexamplesusingFirmataforbasicelectroniccomponents suchasthepotentiometer,thebuzzer,theDCmotor,andtheservomotor Introductiontotheinter-integratedcircuit(I2C)protocolandprototypingexamples fortheI2Ccomponentssuchasthetemperaturesensor(TMP102)andthelight sensor(BH1750) Prototyping Justforamoment,let’sstepbackandlookattheprojectthatwebuiltintheprevious chapter.Theprojecthadaverysimplegoalandwewereabletodevelopitquite comfortably.However,theprojectiscertainlynotreadytobeaconsumerproductsinceit doesn’thavesignificantfunctionalitiesandmostimportantly,itisnotarobustproductthat canberepeatedlyproducedasitis.Whatyoucantellaboutyourcurrentprojectisthatit isaDIYprojectforpersonaluseorjustamodelthatcanbedevelopedfurthertobeagreat product. Now,ifyouarelookingtodevelopacommercialproductorjustaDIYprojectthatis reallyrobustandscalable,youmustconsiderstartingitbymakingamodelfirst.Atthis stage,youneedtoenvisiontheproductwiththerequiredfeaturesthatneedtobe developedandthenumberofcomponentsthatarerequiredtodeploythesefeatures. Prototypingisbasicallyarapidwaytocreateaworkingmodelofyourenvisionedidea beforedevelopingitintoafullyfunctionalprojectorproduct.Theproofofconcept prototypethatisdevelopedduringthisprototypingprocessletsyoutoidentifythe feasibilityofyouridea,andinsomecases,ithelpsyoutoexplorethepotentialofyour project.Theprototypingorfunctionalmodel-makingprocessisessentialforanyindustry andnotjustforelectronics. Intheelectronicsdomain,prototypingcanbeusedattheveryfirststageofinterfacing componentstoacomputer,insteadofdirectlyspendingasignificantamountofresources fortheschematicdesign,PCBmanufacturing,anddevelopingthecompletecodebase. Thisstagehelpsyoutoidentifymajorflawsinyourcircuitdesignandcheckthemutual compatibilityoftheselectedcomponents. Fortunately,ArduinoandtheexistingsoftwaresupportaroundArduinohavereally simplifiedelectronics’prototyping.Intheupcomingsections,wewillgothroughvarious helperfunctionsandinterfacingexercisestohelpyouproceedwithyourownprojects. Theseexamplesortemplatesaredesignedinsuchafashionthattheycanbeusedasa blueprintforlargerprojects. Beforedivingintotheseprototypingexamples,let’sunderstandtwodifferentabstractions ofinterfacingthatwearegoingtoexploreinthischapter: InterfacingArduinowithPython:WehavelearnedtheeasiestmethodofPythonArduinointerfacingusingtheFirmataprotocol.OntheArduinoboard,theFirmata protocolisimplementedusingtheStandardFirmatafirmware,whileonthePython end,weusedtheFirmatalibraries,pyFirmataorpyMata,forPython.Another Python-Arduinointerfacingmethodincludestheuseofsimplebutnonstandardserial commandsusingthecustomArduinosketchandthepySeriallibraryinthePython program.Itisalsopossibletouseacomputernetworktoestablishcommunication betweenPythonandArduino,whichiscoveredlaterinthebook. InterfacingelectroniccomponentswithArduino:Thesecondinterfacing abstractionisassociatedwithArduinoandthephysicalcomponents.Aswealready did,variouselectronicscomponentscanbesimplyinterfacedwiththeArduinoboard usingdigitaloranalogpins.Thesecomponentsdealwitheitherdigitaloranalog signals.AfewdigitalpinsontheArduinoboardsupportPWMcommunicationfor specifichardwaredevices.TheotheralternativeinterfacingmethodsincludeI2Cand serialperipheralinterface(SPI)communication.TheI2Cmethodis comprehensivelyexplainedinthefinalsectionofthischapter. WorkingwithpyFirmatamethods ThepyFirmatapackageprovidesusefulmethodstobridgethegapbetweenPythonand Arduino’sFirmataprotocol.Althoughthesemethodsaredescribedwithspecific examples,youcanusetheminvariousdifferentways.Thissectionalsoprovidesa detaileddescriptionofafewadditionalmethodsthatwerenotusedinthepreviousproject andliststhemissingfeatures. SettinguptheArduinoboard TosetupyourArduinoboardinaPythonprogramusingpyFirmata,youneedto specificallyfollowthestepsthatwehavecovered.Wehavedistributedtheentirecodethat isrequiredforthesetupprocessintosmallcodesnippetsineachstep.Whilewritingyour code,youwillhavetocarefullyusethecodesnippetsthatareappropriateforyour application.YoucanalwaysrefertotheexamplePythonfilescontainingthecomplete code.Beforewegoahead,let’sfirstmakesurethatyourArduinoboardisequippedwith thelatestversionoftheStandardFirmataprogramandisconnectedtoyourcomputer: 1. DependingupontheArduinoboardthatisbeingutilized,startbyimportingthe appropriatepyFirmataclassestothePythoncode.Currently,theinbuiltpyFirmata classesonlysupporttheArduinoUnoandArduinoMegaboards: frompyfirmataimportArduino InthecaseofArduinoMega,usethefollowinglineofcode: frompyfirmataimportArduinoMega 2. Beforewestartexecutinganymethodsthatareassociatedwithhandlingpins,you needtoproperlysetuptheArduinoboard.Toperformthistask,wehavetofirst identifytheUSBporttowhichtheArduinoboardisconnectedandassignthis locationtoavariableintheformofastringobject.ForMacOSX,theportstring shouldapproximatelylooklikethis: port='/dev/cu.usbmodemfa1331' ForWindows,usethefollowingstringstructure: port='COM3' InthecaseoftheLinuxoperatingsystem,usethefollowinglineofcode: port='/dev/ttyACM0' Theport’slocationmightbedifferentaccordingtoyourcomputerconfiguration.You canidentifythecorrectlocationofyourArduinoUSBportbyusingtheArduino IDE,asdescribedinChapter2,WorkingwiththeFirmataProtocolandthepySerial Library. 3. OnceyouhaveimportedtheArduinoclassandassignedtheporttoavariableobject, it’stimetoengageArduinowithpyFirmataandassociatethisrelationshiptoanother variable: board=Arduino(port) Similarly,forArduinoMega,usethis: board=ArduinoMega(port) 4. ThesynchronizationbetweentheArduinoboardandpyFirmatarequiressometime. Addingsleeptimebetweentheprecedingassignmentandthenextsetofinstructions canhelptoavoidanyissuesthatarerelatedtoserialportbuffering.Theeasiestway toaddsleeptimeistousetheinbuiltPythonmethod,sleep(time): fromtimeimportsleep sleep(1) Thesleep()methodtakessecondsastheparameterandafloating-pointnumbercan beusedtoprovidethespecificsleeptime.Forexample,for200milliseconds,itwill besleep(0.2). Atthispoint,youhavesuccessfullysynchronizedyourArduinoUnoorArduinoMega boardtothecomputerusingpyFirmata.Whatifyouwanttouseadifferentvariant(other thanArduinoUnoorArduinoMega)oftheArduinoboard? AnyboardlayoutinpyFirmataisdefinedasadictionaryobject.Thefollowingisa sampleofthedictionaryobjectfortheArduinoboard: arduino={ 'digital':tuple(xforxinrange(14)), 'analog':tuple(xforxinrange(6)), 'pwm':(3,5,6,9,10,11), 'use_ports':True, 'disabled':(0,1)#Rx,Tx,Crystal } ForyourvariantoftheArduinoboard,youhavetofirstcreateacustomdictionary object.Tocreatethisobject,youneedtoknowthehardwarelayoutofyourboard. Forexample,anArduinoNanoboardhasalayoutsimilartoaregularArduinoboard, butithaseightinsteadofsixanalogports.Therefore,theprecedingdictionaryobject canbecustomizedasfollows: nano={ 'digital':tuple(xforxinrange(14)), 'analog':tuple(xforxinrange(8)), 'pwm':(3,5,6,9,10,11), 'use_ports':True, 'disabled':(0,1)#Rx,Tx,Crystal } AsyouhavealreadysynchronizedtheArduinoboardearlier,modifythelayoutofthe boardusingthesetup_layout(layout)method: board.setup_layout(nano) ThiscommandwillmodifythedefaultlayoutofthesynchronizedArduinoboardto theArduinoNanolayoutoranyothervariantforwhichyouhavecustomizedthe dictionaryobject. ConfiguringArduinopins OnceyourArduinoboardissynchronized,itistimetoconfigurethedigitalandanalog pinsthataregoingtobeusedaspartofyourprogram.ArduinoboardhasdigitalI/Opins andanaloginputpinsthatcanbeutilizedtoperformvariousoperations.Aswealready know,someofthesedigitalpinsarealsocapableofPWM. Thedirectmethod Nowbeforewestartwritingorreadinganydatatothesepins,wehavetofirstassign modestothesepins.IntheArduinosketch-basedapproachthatweusedintheprevious chapter,weusedthepinModefunction,thatis,pinMode(11,INPUT)forthisoperation. Similarly,inpyFirmata,thisassignmentoperationisperformedusingthemodemethodon theboardobjectasshowninthefollowingcodesnippet: frompyfirmataimportArduino frompyfirmataimportINPUT,OUTPUT,PWM #SettingupArduinoboard port='/dev/cu.usbmodemfa1331' board=Arduino(port) #Assigningmodestodigitalpins board.digital[13].mode=OUTPUT board.analog[0].mode=INPUT ThepyFirmatalibraryincludesclassesfortheINPUTandOUTPUTmodes,whichare requiredtobeimportedbeforeyouutilizedthem.Theprecedingexampleshowsthe delegationofdigitalpin13asanoutputandtheanalogpin0asaninput.Themode methodisperformedonthevariableassignedtotheconfiguredArduinoboardusingthe digital[]andanalog[]arrayindexassignment. ThepyFirmatalibraryalsosupportsadditionalmodessuchasPWMandSERVO.ThePWM modeisusedtogetanalogresultsfromdigitalpins,whiletheSERVOmodehelpsadigital pintosettheangleoftheshaftbetween0to180degrees.ThePWMandSERVOmodesare explainedwithdetailedexampleslaterinthischapter.Ifyouareusinganyofthesemodes, importtheirappropriateclassesfromthepyFirmatalibrary.Oncetheseclassesare importedfromthepyFirmatapackage,themodesfortheappropriatepinscanbeassigned usingthefollowinglinesofcode: board.digital[3].mode=PWM board.digital[10].mode=SERVO Note Inelectronics,PWMisasignalmodulationtechniquethatisgreatlyusedtoprovide controlledamountofpowertocomponents.Whiledealingwithdigitalsignals,thePWM techniqueisusedtoobtainanalogresultsbyutilizingsquarewavesandcontrollingthe widthofthesignal. Aswealreadyknow,thedigitalpinsoftheArduinoboardcanonlyhavetwostates,5V (HIGH)and0V(LOW).Onecangeneratesquarepulsesbycontrollingtheswitching patternbetweenHIGHandLOWandthusgeneratethepulse.Bychangingthewidthof thesepulses,youcansimulateanyvoltagebetween0Vand5V.Asyoucanseeinthe followingdiagram,wehaveasquarewavewith25percentwidthofthedutycycle.It meansthatwearesimulating0.25*5V=1.25Vfortheperiodofthatdutycycle: TheArduinolanguagesupportsPWMusingtheanalogWrite()function,wherethe voltagerangebetween0Vand5Vislinearlyscaledforvaluesbetween0and255.For example,50percentdutycycle(simulationof2.5V)translatestoavalueof127,which canbecodedinArduinoasanalogWrite(13,127).Here,thenumber13representsthe digitalpinthatsupportsPWMontheArduinoUnoboard.Similarly,a20percentduty cycle(1V)translatestoanalogWrite(13,64). Assigningpinmodes Thedirectmethodofconfiguringpinsismostlyusedforasinglelineofexecutioncalls.In aprojectcontainingalargecodeandcomplexlogic,itisconvenienttoassignapinwith itsroletoavariableobject.Withanassignmentlikethis,youcanlaterutilizetheassigned variablethroughouttheprogramforvariousactions,insteadofcallingthedirectmethod everytimeyouneedtousethatpin.InpyFirmata,thisassignmentcanbeperformedusing theget_pin(pin_def)method: frompyfirmataimportArduino port='/dev/cu.usbmodemfa1311' board=Arduino(port) #pinmodeassignment ledPin=board.get_pin('d:13:o') Theget_pin()methodletsyouassignpinmodesusingthepin_defstringparameter, 'd:13:o'.Thethreecomponentsofpin_defarepintype,pinnumber,andpinmode separatedbyacolon(:)operator.Thepintypes(analoganddigital)aredenotedwitha anddrespectively.Theget_pin()methodsupportsthreemodes,iforinput,oforoutput, andpforPWM.Inthepreviouscodesample,'d:13:o'specifiesthedigitalpin13asan output.Inanotherexample,ifyouwanttosetuptheanalogpin1asaninput,the parameterstringwillbe'a:1:i'. Workingwithpins NowyouhaveconfiguredyourArduinopins,it’stimetostartperformingactionsusing them.Twodifferenttypesofmethodsaresupportedwhileworkingwithpins:reporting methodsandI/Ooperationmethods. Reportingdata Whenpinsgetconfiguredinaprogramasanaloginputpins,theystartsendinginput valuestotheserialport.Iftheprogramdoesnotutilizethisincomingdata,thedatastarts gettingbufferedattheserialportandquicklyoverflows.ThepyFirmatalibraryprovides thereportinganditeratormethodstodealwiththisphenomenon. Theenable_reporting()methodisusedtosettheinputpintostartreporting.This methodneedstobeutilizedbeforeperformingareadingoperationonthepin: board.analog[3].enable_reporting() Oncethereadingoperationiscomplete,thepincanbesettodisablereporting: board.analog[3].disable_reporting() Intheprecedingexample,weassumedthatyouhadalreadysetuptheArduinoboardand configuredthemodeoftheanalogpin3asINPUT. ThepyFirmatalibraryalsoprovidestheIterator()classtoreadandhandledataoverthe serialport.Whileworkingwithanalogpins,werecommendthatyoustartaniterator threadinthemainlooptoupdatethepinvaluetothelatestone.Iftheiteratormethodis notused,thebuffereddatamightoverflowyourserialport.Thisclassisdefinedinthe utilmoduleofthepyFirmatapackageandneedstobeimportedbeforeitisutilizedin thecode: frompyfirmataimportArduino,util #SettinguptheArduinoboard port='COM3' board=Arduino(port) sleep(5) #StartIteratortoavoidserialoverflow it=util.Iterator(board) it.start() Manualoperations AswehaveconfiguredtheArduinopinstosuitablemodesandtheirreporting characteristic,wecanstartmonitoringthem.ThepyFirmatalibraryprovidesthewrite() andread()methodsfortheconfiguredpins. Thewrite()method Thewrite()methodisusedtowriteavaluetothepin.Ifthepin’smodeissettoOUTPUT, thevalueparameterisaBoolean,thatis,0or1: board.digital[pin].mode=OUTPUT board.digital[pin].write(1) Ifyouhaveusedanalternativemethodofassigningthepin’smode,youcanusethe write()methodasfollows: ledPin=board.get_pin('d:13:o') ledPin.write(1) InthecaseofthePWMsignal,theArduinoacceptsavaluebetween0and255that representsthelengthofthedutycyclebetween0and100percent.ThepyFirmatalibrary providesasimplifiedmethodtodealwiththePWMvaluesasinsteadofvaluesbetween0 and255,youcanjustprovideafloatvaluebetween0and1.0.Forexample,ifyouwanta 50percentdutycycle(2.5Vanalogvalue),youcanspecify0.5withthewrite()method. ThepyFirmatalibrarywilltakecareofthetranslationandsendtheappropriatevalue,that is,127,totheArduinoboardviatheFirmataprotocol: board.digital[pin].mode=PWM board.digital[pin].write(0.5) Similarly,fortheindirectmethodofassignment,youcanusesomecodesimilartothe followingsnippet: pwmPin=board.get_pin('d:13:p') pwmPin.write(0.5) IfyouareusingtheSERVOmode,youneedtoprovidethevalueindegreesbetween0and 180.Unfortunately,theSERVOmodeisonlyapplicablefordirectassignmentofthepins andwillbeavailableinfutureforindirectassignments: board.digital[pin].mode=SERVO board.digital[pin].write(90) Theread()method Theread()methodprovidesanoutputvalueatthespecifiedArduinopin.Whenthe Iterator()classisbeingused,thevaluereceivedusingthismethodisthelatestupdated valueattheserialport.Whenyoureadadigitalpin,youcangetonlyoneofthetwo inputs,HIGHorLOW,whichwilltranslateto1or0inPython: board.digital[pin].read() TheanalogpinsofArduinolinearlytranslatetheinputvoltagesbetween0and+5Vto0 and1023.However,inpyFirmata,thevaluesbetween0and+5Varelinearlytranslated intothefloatvaluesof0and1.0.Forexample,ifthevoltageattheanalogpinis1V,an Arduinoprogramwillmeasureavaluesomewherearound204,butyouwillreceivethe floatvalueas0.2whileusingpyFirmata’sread()methodinPython. Additionalfunctions Besidesthemethodthathasalreadybeendescribed,thepyFirmatalibraryalsoprovides someutilityfunctionsforadditionalcustomization,whichareasfollows: servo_config(pin,min_pulse=544,max_pulse=2400,angle=0):Thismethodhelps tosetuptheSERVOmodewithfurthercustomizationsuchastheminimumpulse value,maximumpulsevalue,andstartingangle.Onecansettheinitialangleofthe servomotorusingtheangleparameter. pass_time(seconds):Thismethodprovidesafunctionalitysimilartothatfoundin thedefaultPython’sdefaultmethodsleep()thatisprovidedbythetimemodule. However,thepass_timefunctionprovidesanon-blockingtimeoutinseconds. get_firmata_version():Thisfunctionreturnsatuplethatcontainstheversionof theFirmataprotocolfromtheArduinoboard: board.get_firmata_version() exit():WerecommendthatyoudisconnecttheArduinoboardfrompyFirmataonce youhavecompletedrunningyourcode.Thiswillfreetheserialport,whichcanbe thenutilizedbyotherprograms: board.exit() Upcomingfunctions ThepyFirmatalibraryiscurrentlyunderdevelopmentanditcontinuouslyreceives updatestoaddandimprovevariousmethods.AlthoughmostofthenativeArduino methodsareavailableinthepyFirmatalibraryviatheFirmataprotocol,therearefew functionsthatarestillmissingorunderdevelopmentandtheyareasfollows: pulseIn/pulseOut:ThesenativeArduinofunctionswaitfortheArduinopinto achievethespecifiedvalue.Thewaitingperiodisreturnedinmicroseconds.This methodiswidelyusedbyPing(ultrasonicdistancemeasurement)sensors. ImplementationofthismethodusingpyFirmatarequiresmajorchangestothe standardFirmataprotocol. shiftIn/shiftOut:Thesefunctionsshiftabyteofdatainorout,onebitatatime. ThepyFirmatalibrarylackssupportsforthesefunctionsandcanbeimplemented usingthevariousPythonprogrammingtricks. PrototypingtemplatesusingFirmata Thegoalofthissectionistoprovideprototypingtemplateswhilealsoexplainingvarious Pythonmethodsandprogrammingtechniques.Ittriestocoversomeofthemostpopular sensorswithcodingexamplesthatareusedbyDIYArduinoprojects.Thissectionis designedtoutilizetheFirmataprotocoltoimplementthesePythonprograms.Italso includesvariousPythonprogrammingparadigmssuchasworkingwithindefiniteloops, creatingcustomfunctions,workingwithrandomnumbers,acquiringmanualinputsfrom prompt,andsoon.Theseprototypingtemplatesaredesignedinsuchawaythattheycan beeasilyincludedinlargeprojectsortheycanbeblueprintsforalargerprojectthatcanbe developedaroundthem.YoulearnedaboutthepyFirmatapackagecomprehensivelyinthe previoussectionandwewillonlyutilizethosepyFirmatafunctionsintheupcoming examples.AnalternativePythonlibrarythatsupportstheFirmataprotocoliscoveredlater inthechapter. Potentiometer–continuousobservationfroman analoginput Apotentiometerisavariableresistorthatcanbecontrolledusingaknob.Ithasthree terminalsoutofwhichtwoofthemareVrefandground,whilethethirdoneprovidesa variableoutput.Theoutputofthepotentiometervariesbetweenthesuppliedvoltages, accordingtothepositionoftheknob.InArduino,youcanconnectthepotentiometerwith +5Vandthegroundpinsoftheboardtoprovidethesupplyvoltage.Whenthevariable terminalisinterfacedwiththeArduinoanaloginput,thisvoltagevaluestranslatesbetween 0and1023respectively.InthecaseofpyFirmata,thevalueoftheanalogobservation translatesbetween0and1. Thiscodingtemplatecontainingthepotentiometercanbeappliedtoprojectsinwhich externalmanualcontroltoasystemisrequired.Thepotentiometeroutputthattranslatesto theanaloginputofArduinocanbeusedtocontrolanactuatorsuchasamotororanLED. Insomecases,theinputcanalsobeusedtocontroltheflowoftheprogrambyapplying itsvaluestoavariable. Connections ConnecttheoutputofthepotentiometertoanalogpinA0asshowninthefollowing diagram.CompletethecircuitbyconnectingVrefandthegroundterminalsofthe potentiometersto+5VandthegroundoftheArduinoboardrespectively: ThePythoncode AssumingthatyoualreadyhavetheStandardFirmatafirmwareuploadedtotheArduino board,youarerequiredtorunaPythoncodeonyourcomputertocompleteitsinterfacing withthepotentiometer.APythoncodetemplatewiththenamepotentiometer.pytohelp yougetstartedwiththisexampleislocatedinthecodebundleofthisbook,whichcanbe downloadedfromhttps://www.packtpub.com/books/content/support/1961.Let’sopenthis filetounderstandtheprogram.Asyoucansee,weareusingthepyFirmatalibrarywith otherPythonmodulessuchastimeandos: frompyfirmataimportArduino,util fromtimeimportsleep importos Inthesecondstepoftheprogram,weareinitializingtheArduinoboardandstartingthe Iterator()functionoverit: port='COM3' board=Arduino(port) sleep(5) it=util.Iterator(board) it.start() Oncetheboardhasbeeninitialized,weneedtoassignaroletotheanalogpin,0,asitis goingtobeusedasaninputpin.Weareusingtheget_pin()methodtoassignaroleto theanalogpin,0: a0=board.get_pin('a:0:i') Now,aspartofthemainprogram,weneedtocontinuouslymonitortheoutputofthe potentiometeratthepin,a0,thatwejustdefined.Weareusingthewhilestatementto createanindefiniteloopforthescriptthatwillreadandprinttheanaloginput.The problemwiththisindefinitewhileloopisthattheprogramwillnotcloseproperlywhenit isinterruptedanditwillnotreleasetheboardbyexecutingtheboard.exit()method.To avoidthis,wewilluseanothercontrolstatementfromthePythonprogrammingparadigm, calledtry/except: try: whileTrue: p=a0.read() printp exceptKeyboardInterrupt: board.exit() os._exit() Usingthisstatement,theprogramwillkeeprunningthewhileloopuntilthekeyboard interruptionoccurs,whichisCtrl+C,andtheprogramwillexecutethescriptunderthe exceptstatement.Thisincludesreleasingtheboardusingboard.exit()andexistingthe programusingtheos._exit()method.Insummary,theprogramwillkeepprintingthe outputofthepotentiometeruntilsomeonepressesCtrl+Ctointerrupttheprogram. Note Thetry/exceptstatementprovidesaveryefficientwaytocaptureexceptionsinPython. Itisadvisabletoutilizethisstatementthroughoutthedevelopmentprocesstocleverly debugyourprograms.YoucanlearnaboutPythonerrorsandexceptionsfromthe followinglinks: https://docs.python.org/2/reference/compound_stmts.html#try https://docs.python.org/2/tutorial/errors.html Buzzer–generatingsoundalarmpattern Digitalbuzzersensorsareusedinvariousapplicationsthatrequirealarmnotifications. ThesesensorsproducesoundwhentheyaresuppliedwithadigitalHIGHvalue(thatis, +5V),whichcanbeprovidedbyusingArduinodigitalpins.SimilartotheLEDexample inthepreviouschapter,theyareveryeasytointerfacewithArduino.However,ratherthan performingasimpledigitaloutput,weareimplementingPythonprogrammingtricksto generatedifferentsoundpatternsandproducevarioussoundeffects.Thesamecode templatecanbealsousedtoproducedifferentLEDblinkpatterns. Note Ananalogdigitalbuzzercanbefoundathttp://www.amazon.com/Arduino-CompatibleSpeaker-arduino-sensors/dp/B0090X0634. Connections Asdisplayedinthefollowingcircuitdiagram,connecttheVCCandthegroundofthe sensorboardto5VandthegroundpinoftheArduinoboardrespectively.Connectthe signalpinofthesensortothedigitalpin2viathe220-ohmresistor.Youcanuseany digitalpintoconnectthebuzzer.JustmakesurethatyouupdatethePythoncodetoreflect thepinthatyouhaveselected. ThePythoncode Inthecodeexample,twodifferentsoundpatternsaregeneratedusingarraysoftime delays.Toperformtheseactions,wearegoingtoimplementacustomPythonfunction thatwilltakethepinnumber,therecurrencetime,andthepatternnumberasinput.Before wejumptoexplainthecode,let’sopentheprogramfile,buzzerPattern.py,fromthe codefolder.Inthebeginningofthecode,youcanfindthePythonfunction, buzzerPattern()thatwillbecalledfromthemainprogramwithappropriateoptions.As thisfunctionisthecoreoftheentireprogram,let’strytounderstandit.Thefunction containstwohardcodedpatternarrays,pattern1andpattern2.Eachcontainstheonand offtimeforthebuzzerforasecond,whichisthedutycycleofthepattern.Forexample,in pattern1,0.8representsthetimethebuzzerneedstobeonand0.2representsthe opposite.Thefunctionwillrepeatthisbuzzerpatternforrecurrencetimesthatis specifiedbythefunctionargument.Oncetheforloopwiththevalueofrecurrenceis started,thefunctionwillcheckforthepatternnumberfromthefunctionargumentand executethepattern.Weareusingtheflagvariabletoalternativelyuseelementsofthe patternarraytocontrolthebuzzer.Oncetheentirerecurrenceloopiscomplete,wewill turnoffthebuzzercompletelyagain,ifitison,andsafelydisengagetheboardusingthe exit()method: defbuzzerPattern(pin,recurrence,pattern): pattern1=[0.8,0.2] pattern2=[0.2,0.8] flag=True foriinrange(recurrence): ifpattern==1: p=pattern1 elifpattern==2: p=pattern2 else: print"Pleaseentervalidpattern.1or2." exit fordelayinp: ifflagisTrue: board.digital[pin].write(1) flag=False sleep(delay) else: board.digital[pin].write(0) flag=True sleep(delay) board.digital[pin].write(0) board.exit() Tip Ifyouwanttochangethetimedelaysorimplementatotallydifferentpattern,youcan playaroundwiththepatternarrays. Theremainingpartoftheprogramisrelativelysimpleasitcontainscodeforimporting librariesandinitializingtheArduinoboard.Oncetheboardisinitialized,wewillexecute thebuzzerPattern()functionwiththeinputargument,(2,10,1).Thisargumentwill askthefunctiontoplaypattern110timesonthepinnumber2: frompyfirmataimportArduino fromtimeimportsleep port='/dev/cu.usbmodemfa1331' board=Arduino(port) sleep(5) buzzerPattern(2,10,1) DCmotor–controllingmotorspeedusingPWM DCmotorsarewidelyusedinroboticsapplications.Theyareavailableinawiderangeof voltagespecifications,dependingupontheapplication.Inthisexample,weareutilizinga 5VDCmotorbecausewewanttosupplythepowerusingtheArduinoboarditself.Asthe Arduinodigitalpincanonlyhavetwostates,thatis,HIGH(+5V)orLOW(0V),itis impossibletocontrolthespeedofthemotorusingjusttheOUTPUTmode.Asasolution,we aregoingtoimplementthePWMmodeviadigitalpinsthatarecapableofsupportingPWM. WhileusingpyFirmata,pinsconfiguredwiththePWMmodetakeanyfloatinputvalues between0and1.0,whichrepresent0Vand5Vrespectively. Connections Dependingupontheload,DCmotorscansometimesdrawlargeamountsofcurrentand harmtheArduinoboard.ToavoidanydamagetotheArduinoboardduetoanylarge accidentalcurrentdraw,wewilluseatransistorasaswitch,whichonlyusesasmall amountofcurrenttocontrolthelargeamountofcurrentintheDCmotor.Tocompletethe circuitconnectionasdisplayedinthefollowingdiagram,youwillneedanNPNtransistor (TIP120,N2222,orasimilarone),onediode(1N4001orsimilarone)anda220-ohm resistorwithyourDCmotor.Connectthebaseofthetransistortothedigitalpin3thatalso supportsthePWMmode.Connecttheremainingcomponentsasdisplayedinthediagram: Note Tofindoutmoreabouttransistorterminals(collector,emitter,andbase)andtoassociate transistorpinswiththeirrespectiveterminals,youcanrefertotheirdatasheetsorthe followingwebsites: http://en.wikipedia.org/wiki/Transistor http://www.onsemi.com/pub/Collateral/TIP120-D.PDF http://www.mouser.com/ds/2/68/PN2221-2222A-11964.pdf ThePythoncode ThePythonrecipewiththenamedcMotorPWM.pyforaDCmotorislocatedinthecode bundleofthisbook,whichcanbedownloadedfrom https://www.packtpub.com/books/content/support/1961.OpenthePythonfiletofurther understandtheusageofPWMtocontrolthespeedoftheDCmotor.Thecustomfunction, dcMotorControl(),takesmotorspeedandtimedurationasinputparametersasdescribed inthefollowingcodesnippet: defdcMotorControl(r,deltaT): pwmPin.write(r/100.00) sleep(deltaT) pwmPin.write(0) Justlikethepreviousexamples,weareusingasimilarcodetoimportthenecessary libraryandinitializetheArduinoboard.Afterinitialization,weareassigningthemodeof thedigitalpin3asPWM,whichcanbeseenfromtheutilizationoftheget_pin('d:3:p') method.Thiscodereflectstheindirectmodeofpinmodeassignmentthatwelearnedin theprevioussection: #Setmodeofpin3asPWM pwmPin=board.get_pin('d:3:p') Aspartofcollectingmanualinputsfromtheuser,wearerunningacombinationofthe try/exceptstatement(toreleasetheboardonexit)andthewhilestatement(toobtain continuousinputsfromtheuser).Thecodetemplateintroducestheinput()methodto obtaincustomvalues(motorspeedanddurationtorunthemotor)fromPython’s interactiveterminal.Oncethesevaluesareobtainedfromtheuser,theprogramcallsthe dcMotorControl()functiontoperformthemotoraction: try: whileTrue: r=input("Entervaluetosetmotorspeed:") if(r>100)or(r<=0): print"Enterappropriatevalue." board.exit() break t=input("Howlong?(seconds)") dcMotorControl(r,t) exceptKeyboardInterrupt: board.exit() os._exit LED–controllingLEDbrightnessusingPWM Intheprevioustemplate,wecontrolledthespeedofDCmotorusingPWM.Onecanalso controlthebrightnessoftheLEDusingthesamemethod.Insteadofaskingtheuserto inputbrightness,wearegoingtousethePythonmodulerandominthistemplate.Wewill usethismoduletogeneratearandomnumberbetween1and100,whichwillbelaterused towritethatvalueonthepinandrandomlychangethebrightnessoftheLED.This randint()functionisareallyusefulfeatureprovidedbytherandommoduleanditis widelyusedintestingprototypesbyrapidlysendingrandomsignals. Note Therandint()functiontakestherandint(startValue,endValue)syntaxandreturns therandomintegerbetweentherangeestablishedbystartValueandendValue. Connections Likeweusedinthepreviouschapter’sproject,wewillneedapull-upresistortoconnect theLEDwiththeArduinopin.Asdisplayedinthefollowingdiagram,simplyconnectthe anodeoftheLED(longerleg)tothedigitalpin11viaone220-ohmresistorandconnect thecathode(shorterleg)totheground: Itisimportanttonotethatthedigitalpin11onArduinoUnoisalsocapableofperforming PWMalongwithdigitalpins3,5,6,9,and10. ThePythoncode ThePythoncodewiththetitleledBrightnessPWM.pyforthisexerciseislocatedinthe codebundleofthisbook,whichcanbedownloadedfrom https://www.packtpub.com/books/content/support/1961.Openthefiletoexplorethecode. Asyoucanseeinthiscodetemplate,afloatvaluebetween0and1.0israndomlyselected beforepassingittothePWMpin.ThismethodgeneratesrandomLEDbrightnessfora givenamountoftime.Thispracticecanbeusedtogeneraterandominputsamplesfor variousothertestingprojects. Asyoucansee,thefirstfewlinesofthecodeimportthenecessarylibrariesandinitialize theboard.Althoughtheboardvariable,/dev/cu.usbmodemfa1311,isselectedforMacOS X,youcanuseyouroperatingsystem’sspecificvariablenameinthefollowingcode snippet.Youcanobtainmoreinformationaboutchoosingthisvariablenamefromthe SettinguptheArduinoboardsectionatthebeginningofthischapter. frompyfirmataimportArduino,INPUT,PWM fromtimeimportsleep importrandom port='/dev/cu.usbmodemfa1311' board=Arduino(port) sleep(5) Inthisexample,weareutilizingthedirectmethodofpinmodeassignment.Asyoucan seeinthefollowingcodesnippet,thedigitalpin11isbeingassignedtothePWMmode: pin=11 board.digital[pin].mode=PWM Oncethepinmodeisassigned,theprogramwillrunaloopusingtheforstatementwhile randomlygeneratinganintegernumberbetween0and100,andthensendtheappropriate PWMvaluetothepinaccordingtothegeneratednumber.Withtheexecutionofthis,you willbeabletoseetheLEDrandomlychangingitsbrightnessforapproximately10 seconds: foriinrange(0,99): r=random.randint(1,100) board.digital[pin].write(r/100.00) sleep(0.1) Onceyouaredonewiththeloop,youneedtosafelydisengagetheArduinoboardafter turningofftheLEDonelasttime.ItisagoodpracticetoturnofftheLEDorany connectedsensorattheendoftheprogrambeforeexitingtheboard,topreventanysensor fromrunningaccidentally: board.digital[pin].write(0) board.exit() Note IfyouwanttohomogenouslyglowtheLEDinsteadofrandomlychangingitsbrightness, replacethecodeintheforloopwiththefollowingcodesnippet.Here,wearechanging thePWMinputtotheincrementingvariable,i,insteadoftherandomvariable,r: foriinrange(0,99): board.digital[pin].write(i/100.00) sleep(0.1) Servomotor–movingthemotortoacertainangle Servomotorsarewidelyusedelectroniccomponentsinapplicationssuchaspan-tilt cameracontrol,roboticarms,mobilerobotmovements,andsoonwhereprecise movementofthemotorshaftisrequired.Thisprecisecontrolofthemotorshaftis possiblebecauseofthepositionsensingdecoder,whichisanintegralpartofthe servomotorassembly.Astandardservomotorallowstheangleoftheshafttobeset between0and180degrees.ThepyFirmatalibraryprovidestheSERVOmodethatcanbe implementedoneverydigitalpin.Thisprototypingexerciseprovidesatemplateand guidelinestointerfaceaservomotorwithPython. Connections Typically,aservomotorhaswiresthatarecolor-codedred,black,andyellowrespectively toconnectwiththepower,ground,andsignaloftheArduinoboard.Connectthepower andthegroundoftheservomotorto5VandthegroundoftheArduinoboard.As displayedinthefollowingdiagram,connecttheyellowsignalwiretothedigitalpin13: Ifyouwanttouseanyotherdigitalpin,makesurethatyouchangethepinnumberinthe Pythonprograminthenextsection.Onceyouhavemadetheappropriateconnections, let’smoveontothePythonprogram. ThePythoncode ThePythonfileconsistingofthiscodeisnamedservoCustomAngle.pyandislocatedin thecodebundleofthisbook,whichcanbedownloadedfrom https://www.packtpub.com/books/content/support/19610.OpenthisfileinyourPython editor.Likeotherexamples,thestartingsectionoftheprogramcontainsthecodetoimport thelibrariesandsetuptheArduinoboard: frompyfirmataimportArduino,SERVO fromtimeimportsleep #SettinguptheArduinoboard port='COM5' board=Arduino(port) #NeedtogivesometimetopyFirmataandArduinotosynchronize sleep(5) NowthatyouhavePythonreadytocommunicatewiththeArduinoboard,let’sconfigure thedigitalpinthatisgoingtobeusedtoconnecttheservomotortotheArduinoboard.We willcompletethistaskbysettingthemodeofpin13toSERVO: #Setmodeofthepin13asSERVO pin=13 board.digital[pin].mode=SERVO ThesetServoAngle(pin,angle)customfunctiontakesthepinsonwhichtheservomotor isconnectedandthecustomangleasinputparameters.Thisfunctioncanbeusedasapart ofvariouslargeprojectsthatinvolveservos: #CustomangletosetServomotorangle defsetServoAngle(pin,angle): board.digital[pin].write(angle) sleep(0.015) Inthemainlogicofthistemplate,wewanttoincrementallymovethemotorshaftinone directionuntilitachievesthemaximumachievableangle(180degrees)andthenmoveit backtotheoriginalpositionwiththesameincrementalspeed.Inthewhileloop,wewill asktheusertoprovideinputtocontinuethisroutine,whichwillbecapturedusingthe raw_input()function.Theusercanenterthecharacterytocontinuethisroutineorenter anyothercharactertoaborttheloop: #Testingthefunctionbyrotatingmotorinbothdirection whileTrue: foriinrange(0,180): setServoAngle(pin,i) foriinrange(180,1,-1): setServoAngle(pin,i) #Continueorbreakthetestingprocess i=raw_input("Enter'y'tocontinueorEntertoquit):") ifi=='y': pass else: board.exit() break Whileworkingwithalltheseprototypingexamples,weusedthedirectcommunication methodbyusingdigitalandanalogpinstoconnectthesensorswithArduino.Now,let’s getfamiliarwithanotherwidelyusedcommunicationmethodbetweenArduinoandthe sensors,whichiscalledI2Ccommunication. PrototypingwiththeI2Cprotocol Intheprevioussection,sensorsoractuatorsweredirectlycommunicatingwithArduino viadigital,analog,orPWMpins.Thesemethodsareutilizedbyalargenumberofbasic, low-levelsensorsandyouwillbewidelyusingtheminyourfutureArduinoprojects. Besidethesemethods,thereisawidevarietyofpopularsensorsthatarebasedon integratedcircuit(IC),whichrequiredifferentwaysofcommunication.TheseIC-based advancedsensorsutilizeI2C-orSPIbus-basedmethodstocommunicatewiththe microcontroller.AswearegoingtouseI2C-basedsensorsintheupcomingprojects,the sectionwillonlycovertheI2Cprotocolandpracticalexampletounderstandtheprotocol inabetterway.OnceyouunderstandthefundamentalsoftheI2Cprotocol,youcanlearn theSPIprotocolveryquickly. Note YoucanlearnmoreaboutSPIprotocolandthesupportedArduinoSPIlibraryfromthe followinglinks: http://arduino.cc/en/Reference/SPI http://www.instructables.com/id/Using-an-Arduino-to-Control-or-Test-an-SPIelectro/ In1982,thePhilipscompanyneededtofindoutasimpleandefficientwaytoestablish communicationbetweenamicrocontrollerandtheperipheralchipsonTVsets,whichled tothedevelopmentoftheI2Ccommunicationprotocol.TheI2Cprotocolconnectsthe microcontrollerortheCPUtoalargenumberoflow-speedperipheraldevicesusingjust twowires.ExamplesofsuchperipheraldevicesorsensorsincludeI/Odevices,A/D converters,D/Aconverters,EEPROM,andmanysimilardevices.I2Cusestheconceptof master-slavedevices,wherethemicrocontrolleristhemasterandtheperipheralsarethe slavedevices.ThefollowingdiagramshowsanexampleoftheI2Ccommunicationbus: Asdisplayedintheprecedingdiagram,themasterdevicecontainstwobidirectionallines: SerialDataLine(SDA)andSerialClockLine(SCL).InthecaseofArduinoUno,the analogpins4and5provideinterfacesforSDAandSCL.Itisimportanttonotethatthese pinconfigurationswillchangewithdifferentvariantsoftheArduinoboard.Theperipheral sensorsthatareworkingasslavesconnecttotheselines,whicharealsosupportedbythe pullresistors.ThemasterdeviceisresponsibleforgeneratingtheclocksignalontheSCL andinitializingcommunicationwiththeslaves.Theslavedevicesreceivetheclockand respondtothecommandssentbythemasterdevice. Theorderoftheslavedevicesisnotimportantasthemasterdevicecommunicateswith theslavesusingtheirpartaddress.Toinitializethecommunication,themastersendsone ofthefollowingtypesofmessageonthebuswiththespecificpartaddress: Asinglemessageinwhichdataiswrittenontheslave Asinglemessageinwhichdataisreadfromtheslave Multiplemessagesinwhichfirstdataisrequestedfromtheslaveandthenthe receiveddataisread TosupportI2CprotocolinArduinoprogramming,theArduinoIDEcomesequippedwith adefaultlibrarycalledWire.ThislibrarycanbeimportedtoyourArduinosketchby addingthefollowinglineofcodeatthebeginningofyourprogram: #include<Wire.h> ToinitializeI2Ccommunication,theWirelibraryusesacombinationofthefollowing functionstowritedataontheslavedevice: Wire.beginTransmission(0x48); Wire.write(0); Wire.endTransmission(); Theseslavedevicesaredifferentiatedusinguniquepartaddresses.Asyoucanseeinthe precedingexample,0x48isthepartaddressofaconnectedslavedevice. TheWirelibraryalsoprovidestheWire.read()andWire.requestFrom()functionsto readandrequestdatafromtheslavedevices.Thesefunctionsareexplainedindetailinthe nextsection. Note YoucanlearnmoreabouttheI2CprotocolandtheWirelibraryfromthefollowinglinks: http://www.instructables.com/id/I2C-between-Arduinos/ http://arduino.cc/en/reference/wire ArduinoexamplesforI2Cinterfacing InordertopracticeprototypingexercisesfortheI2Cprotocol,let’sutilizetwopopular I2Csensorsthatdetecttemperatureandambientlightintheenvironment.Asthefirststep towardsunderstandingI2Cmessaging,wewillworkwithArduinosketchesforI2C interfacing,andlater,wewilldevelopsimilarfunctionalitiesusingPython. ArduinocodingfortheTMP102temperaturesensor TMP102isoneofthewidelyuseddigitalsensorstomeasureambienttemperature. TMP102providesbetterresolutionandaccuracycomparedtotraditionalanalog temperaturesensorssuchasLM35orTMP36.ThefollowingisanimageofTMP102: ThepreviousimageshowsabreakoutboardwiththeavailablepinsfortheTMP102 sensor.PleasekeepinmindthattheTMP102sensorthatyouobtainmighthaveadifferent pinlayoutcomparedtotheonedisplayedintheimage.Itisalwaysadvisabletocheckthe datasheetofyoursensorbreakoutboardbeforemakinganyconnections.Asyoucanseein theimage,theTMP102sensorsupportstheI2CprotocolandisequippedwithSDAand SCLpins.Connectanalogpins4and5ofyourArduinoUnoboardtotheSDAandSCL pinsoftheTMP102sensor.Also,connect+5Vandthegroundasdisplayedinthe followingdiagram.Inthisexample,weareusingtheArduinoUnoboardasthemasterand TMP102astheslaveperipheral,wherethepartaddressofTMP102is0x48inhex: Note YoucanobtaintheTMP102sensorbreakoutboardfromSparkFunElectronicsat https://www.sparkfun.com/products/11931. Thedatasheetofthisboardcanbeobtainedat https://www.sparkfun.com/datasheets/Sensors/Temperature/tmp102.pdf. Now,connectyourArduinoboardtoyourcomputerusingaUSBcableandcreateanew sketchintheArduinoIDEusingthefollowingcodesnippet.Onceyouhaveselectedthe appropriateserialportandtypeofboardintheArduinoIDE,uploadandrunthecode.If allthestepsareperformedasdescribed,onexecution,youwillbeabletoseethe temperaturereadinginCelsiusandFahrenheitintheSerialMonitorwindow: #include<Wire.h> intpartAddress=0x48; voidsetup(){ Serial.begin(9600); Wire.begin(); } voidloop(){ Wire.requestFrom(partAddress,2); byteMSB=Wire.read(); byteLSB=Wire.read(); intTemperatureData=((MSB<<8)|LSB)>>4; floatcelsius=TemperatureData*0.0625; Serial.print("Celsius:"); Serial.println(celsius); floatfahrenheit=(1.8*celsius)+32; Serial.print("Fahrenheit:"); Serial.println(fahrenheit); delay(500); } Intheprecedingcodesnippet,theWire.requestFrom(partAddress,2)functionrequests twobytesfromtheslaveTMP102.Theslavesendsdatabytestothemaster,whichget capturedbytheWire.read()functionandarestoredastwodifferentbits:most significantbit(MSB)andleastsignificantbit(LSB).Thesebytesareconvertedintoan integervalue,whichisthenconvertedintotheactualCelsiusreadingbymultiplyingthe incrementalfractionoftheTMP102sensorthatisobtainedfromthedatasheet.TMP102is oneoftheeasiestI2CsensorstointerfacewithArduinoasthesensorvaluescanbe obtainedviaasimpleI2Crequestmethod. ArduinocodingfortheBH1750lightsensor BH1750isadigitallightsensorthatmeasurestheamountofvisiblelightinagivenarea. AlthoughvariousDIYprojectsutilizesimplephotocellsasacheapalternative,the BH1750sensorisknownforhigherresolutionandaccuracyinawiderangeof applications.Theambientlight,alsocalledluminousfluxorlux,ismeasuredinunit lumen.TheBH1750sensorsupportsI2Ccommunicationwithpartaddress0x23,with 0x5CasthesecondaryaddressifyouareusingmultipleBH1750sensors.Thefollowingis animageofatypicalbreakoutboardconsistingofBH1750: ConnecttheSDAandSCLpinsoftheBH1750breakoutboardtoanalogpins4and5of theArduinoUnoboard,asdisplayedinthefollowingcircuitdiagram.Also,completethe +5Vandgroundconnectionsasdisplayedinthefollowingdiagram: Inthepreviousexample,weusedfunctionsfromtheWirelibrarytocompletetheI2C communication.AlthoughBH1750isasimpleandconvenientI2Csensor,inthecaseofa sensorwithmultiplemeasurementcapabilities,itisnotconvenienttocodedirectlyusing theWirelibrary.Inthissituation,youcanusesensor-specificArduinolibrariesthatare developedbythemanufacturerortheopensourcecommunity.ForBH1750,wewill demonstratetheuseofsuchalibrarytoassisttheI2Ccoding.Beforewecanusethis library,wewillhavetoimportittotheArduinoIDE.Itisreallyimportanttoknowthe processofimportinglibrariestoyourArduinoIDEasyouwillberepeatingthisprocessto installotherlibrariesinfuture.ExecutethefollowingstepstoimporttheBH1750libraryto yourArduinoIDE: 1. DownloadandextractChapter7,TheMidtermProject–aPortableDIYThermostat, codeexamplesinafolder. 2. OpentheArduinoIDEandnavigatetoSketch|ImportLibrary…|Add Library…. 3. Whenyouareaskedforadirectory,gototheBH1750folderinthedownloadedfile andclickonSelect. 4. Tocheckifyourlibraryisinstalled,navigatetoSketch|ImportLibrary…andlook forBH1750inthedrop-downlist. 5. Finally,restarttheArduinoIDE. Tip IfyouareusinganArduinoIDEwithversion1.0.4oranolderversion,youmightnot beabletofindtheImportLibrary…optionfromthemenu.Inthiscase,youneedto followthetutorialathttp://arduino.cc/en/Guide/Libraries. TheBH1750libraryhasamethodtodirectlyobtainambientlightvalues.Let’stestthis libraryusingabuilt-incodeexample. AfterrestartingyourArduinoIDE,navigatetoFile|Examples|BH1750andopenthe BH1750testArduinosketch.ThisshouldopenthefollowingcodesnippetintheArduino IDE.SetupanappropriateserialportanduploadthecodetoyourArduinoboard.Once thecodeisexecuted,youwillbeabletochecktheluminousflux(lux)valuesusingthe serialmonitoroftheArduinoIDE.Makesurethattheserialmonitorisconfiguredto9600 baud: #include<Wire.h> #include<BH1750.h> BH1750lightMeter; voidsetup(){ Serial.begin(9600); lightMeter.begin(); Serial.println("Running…"); } voidloop(){ uint16_tlux=lightMeter.readLightLevel(); Serial.print("Light:"); Serial.print(lux); Serial.println("lx"); delay(1000); } Asyoucanseefromtheprecedingcodesnippet,wehaveimportedtheBH1750libraryby includingBH1750.hfilewithWire.h.ThislibraryprovidesthereadLightLevel() function,whichwillfetchtheambientlightvaluefromthesensorandprovideitasan integer.AstheArduinocoderunsinaloopwithadelayof1000milliseconds,thelux valueswillbefetchedfromthesensorandsenttotheserialporteverysecond.Youcan observethesevaluesintheSerialMonitorwindow. PyMataforquickI2Cprototyping WehavebeenusingpyFirmataasourdefaultPythonlibrarytointerfacetheFirmata protocol.ThepyFirmatalibraryisaveryusefulPythonlibrarytogetstartedwiththe Firmataprotocol,asitprovidesmanysimpleandeffectivemethodstodefinetheFirmata portsandtheirroles.Duetothesereasons,weextensivelyusedpyFirmataforrapid prototypingintheprevioussection.AlthoughpyFirmatasupportsanalog,digital,PWM, andSERVOmodeswitheasy-to-usemethods,itprovideslimitedsupporttotheI2C protocol. Inthissection,wearegoingtouseadifferentPythonFirmatalibrarycalledPyMatatoget familiarwithPython-basedprototypingofI2Csensors.ThePyMatalibrarysupports regularFirmatamethodsandalsoprovidesfullsupportfortheI2Cmessagingprotocol. PyMatacanbeeasilyinstalledusingSetuptools,whichweusedinthepreviouschaptersto installotherPythonlibraries.WeareassumingthatyoualreadyhaveSetuptoolsandpip onyourcomputer.Let’sstartperformingthefollowingsteps: 1. ToinstallPyMataonaWindowscomputer,executethefollowingcommandinthe commandprompt: C:\>easy_install.exepymata 2. IfyouareusingLinuxorMacOSX,usethefollowingcommandintheterminalto installthePyMatalibrary: $sudopipinstallpymata 3. Ifeverythingissetupproperly,thisprocesswillcompletewithoutanyerror.Youcan confirmPyMatabyopeningPython’sinteractivepromptandimportingPyMata: >>>importPyMata 4. Iftheexecutionoftheprecedingcommandfails,youneedtochecktheinstallation processforanyerror.Resolvetheerrorandrepeattheinstallationprocess. InterfacingTMP102usingPyMata InordertoutilizePyMatafunctionalities,youwillneedyourArduinoboardtobeequipped withthestandardfirmatafirmwarejustlikethepyFirmatalibrary.Beforeweproceedto explainthePyMatafunctions,let’sfirstrunthefollowingcodesnippet.Connectyour TMP102temperaturesensorasexplainedintheprevioussection.UsingtheArduinoIDE, navigatetoFile|Examples|FirmataanduploadthestandardFirmatasketchfromthere toyourArduinoboard.Now,createaPythonexecutablefileusingthefollowingcode snippet.Changethevalueofport(COM5),ifneeded,toanappropriateportnameas requiredbyyouroperatingsystem.Finally,runtheprogram: importtime fromPyMata.pymataimportPyMata #InitializeArduinousingportname port=PyMata("COM5") #ConfigureI2Cpin port.i2c_config(0,port.ANALOG,4,5) #Oneshotreadaskingperipheraltosend2bytes port.i2c_read(0x48,0,2,port.I2C_READ) #Waitforperipheraltosendthedata time.sleep(3) #Readfromtheperipheral data=port.i2c_get_read_data(0x48) #Obtaintemperaturefromreceiveddata TemperatureSum=(data[1]<<8|data[2])>>4 celsius=TemperatureSum*0.0625 printcelsius fahrenheit=(1.8*celsius)+32 printfahrenheit firmata.close() Ontheexecutionoftheprecedingcodesnippet,youwillbeabletoseethetemperature readinginFahrenheitandCelsius.Asyoucanseefromtheinlinecommentsinthecode, thefirststeptoutilizeArduinousingPyMataistoinitializetheportusingthePyMata constructor.PyMatasupportstheconfigurationofI2Cpinsviathei2c_config()function. PyMataalsosupportssimultaneousreadingandwritingoperationsviathei2c_read()and i2c_write()functions. InterfacingBH1750usingPyMata InthecaseofBH1750,thepreviousPyMatacodesnippetcanbeutilizedwithminor modificationstoobtainambientlightsensordata.Asthefirstchange,youwanttoreplace thepartaddressofTMP102(0x48)withtheoneofBH1750(0x23)inthefollowingcode snippet.Youwillalsohavetoconverttherawvaluesreceivedfromthesensorintothelux valueusingthegivenformula.Afterthesemodifications,runthefollowingprogramfrom theterminal: importtime fromPyMata.pymataimportPyMata port=PyMata("COM5") port.i2c_config(0,port.ANALOG,4,5) #RequestBH1750tosend2bytes port.i2c_read(0x23,0,2,port.I2C_READ) #WaitforBH1750tosendthedata time.sleep(3) #ReaddatafromBH1750 data=port.i2c_get_read_data(0x23) #Obtainluxvaluesfromreceiveddata LuxSum=(data[1]<<8|data[2])>>4 lux=LuxSum/1.2 printstr(lux)+'lux' firmata.close() Onrunningtheprecedingcodesnippet,youwillbeabletoseetheambientlightsensor readinginluxattheterminal.ThisprocesscanbeusedinalargenumberofI2Cdevices toreadtheregisteredinformation.IncomplexI2Cdevices,youwillhavetofollowtheir datasheetorexamplestoorganizethereadandwritecommandsoftheI2C. UsefulpySerialcommands ThestandardFirmataprotocolandPython’sFirmatalibrariesareveryusefulfortestingor quickprototypingoftheI2Csensors.Althoughtheyhavemanyadvantages,Firmatabasedprojectsfacethefollowingdisadvantages: Delayinreal-timeexecution:Firmata-basedapproachesrequireaseriesofserial communicationmessagestoreceiveandsenddata,whichaddsadditionaldelayand reducesthespeedofexecution. Unwantedspace:TheFirmataprotocolcontainsalargeamountofadditionalcodeto supportvariousotherArduinofunctions.Inawell-definedproject,youdon’treally needthecompletesetoffunctions. Limitedsupport:AlthoughaversionofFirmataincludesI2Csupport,itisquite difficulttoimplementcomplexI2Cfunctionswithoutaddingdelay. Insummary,youcanalwaysuseFirmata-basedapproachestoquicklyprototypeyour projects,butwhenyouareworkingonproduction-leveloradvancedprojects,youcanuse alternativemethods.Inthesescenarios,youcanusecustomArduinocodethatis supportedbyPython’sseriallibrary,pySerial,toenablecommunicationforveryspecific functionalities.Inthissection,wearegoingtocoverafewhelpfulpySerialmethodsthat youcanuseifyouhavetoutilizethelibrarydirectly. Connectingwiththeserialport OnceyouhaveconnectedyourArduinotoaUSBportofyourcomputer,youcanopenthe portinyourPythoncodeusingtheSerialclassasdisplayedinthefollowingcode example: importserial port=serial.Serial('COM5',9600,timeout=1) Inadditiontoportnameandbaudrate,youcanalsospecifyanumberofserialport parameterssuchastimeout,bytesize,parity,stopbits,andsoonusingSerial().Itis necessarytoinitializetheserialportbeforeexecutinganyothercommandfromthe pySeriallibrary. Readingalinefromtheport Oncetheserialportisopened,youcanstartreadingtheportusingreadline().The readline()functionrequiresthetimeouttobespecifiedwhileinitializingtheport, otherwisethecodecanterminatewithanexception: line=port.readline() Thereadline()functionwillprocesseachlinefromtheportthatisterminatedwiththe endlinecharacter\n. Flushingtheporttoavoidbufferoverflow WhileworkingwithpySerial,itisnecessarytoflushtheinputbuffertoavoidbuffer overflowandmaintainreal-timeoperations: port.flushInput() Iftheport’sbaudrateishighandtheprocessingoftheinputdataisslow,bufferoverflow mayoccur,reducingthespeedofexecutionandmakingtheexperiencesluggish. Closingtheport Itisagoodcodingpracticetoclosetheserialportoncetheprocessiscomplete.This practicecaneliminatetheport-blockingproblemoncethePythoncodeisterminated: port.close() Summary Inthischapter,youlearnedimportantmethodsthatarerequiredtosuccessfullyinterface theArduinoboardwithPython.Youwerealsointroducedtovariousprototypingcode templateswithpracticalapplications.Theseprototypingtemplateshelpedustolearnnew PythonprogramingparadigmsandFirmatamethods.Laterinthechapter,wedivedfurther intoprototypingbylearningmoreaboutthedifferentwaysofestablishingcommunication betweensensorsandtheArduinoboard.Althoughwecoveredavastamountof programmingconceptswiththeseprototypingexamples,thegoalofthechapterwasto makeyoufamiliarwiththeinterfacingproblemsandprovidequickrecipesforyour projects. Weareassumingthatbynowyouarecomfortabletestingyoursensorsorproject prototypesusingPythonandArduino.It’stimetostartworkingtowardscreatingyour applicationsthathavecomplexPythonfeaturessuchasusercontrols,charts,andplots.In thenextchapter,wearegoingtodevelopcustomgraphicaluserinterfaces(GUIs)foryour Python-Arduinoprojects. Chapter5.WorkingwiththePythonGUI Inthefirstfourchapters,weusedthePythoninteractivepromptorArduinoserialmonitor toobservetheresults.Themethodofusingtext-basedoutputonpromptmaybeusefulfor basicandquickprototyping,butwhenitcomestoanadvancedlevelofprototypingand demonstratingyourprototypeorfinalproduct,youneedtohaveanicelookinganduserfriendlyinterface.GUIhelpsuserstounderstandvariouscomponentsofyourhardware projectandeasilyinteractwithit.Itcanalsohelpyoutovalidatetheresultsfromyour project. PythonhasanumberofwidelyusedGUIframeworkssuchasTkinter,wxPython,PyQt, PySide,andPyGTK.Eachoftheseframeworkspossessesanalmostcompletesetoffeatures thatarerequiredtocreateprofessionalapplications.Duetothecomplexityinvolved,these frameworkshavedifferentlevelsoflearningcurvesforfirst-timePythonprogrammers. Now,asthisbookisdedicatedtoPythonprogrammingforArduino-basedprojects,we can’tspendalargeamountoftimelearningthenitty-grittyofaspecificframework. Instead,wewillchooseourinterfacelibrarybasedonthefollowingcriteria: Easetoinstallandgetstarted Easetoimplementwithnegligiblelearningefforts Useofminimumcomputationalresources TheframeworkthatsatisfiesalltheserequirementsisTkinter (https://wiki.python.org/moin/TkInter).TkinterisalsothedefaultstandardGUIlibrary deployedwithallPythoninstallations. Note AlthoughTkinteristhede-factoGUIpackageforPython,youcanlearnmoreaboutother GUIframeworksthatwerementionedearlierfromtheirofficialwebsites,whichareas follows: wxPython:http://www.wxpython.org/ PyGTK:http://www.pygtk.org/ PySide:http://qt-project.org/wiki/PySide PyQt:http://sourceforge.net/projects/pyqt/ LearningTkinterforGUIdesign Tkinter,shortforTkinterface,isacross-platformPythoninterfacefortheTkGUItoolkit. TkinterprovidesathinlayeronPythonwhileTkprovidesthegraphicalwidgets.Tkinter isacross-platformlibraryandgetsdeployedaspartofPythoninstallationpackagesfor majoroperatingsystems.ForMacOSX10.9,TkinterisinstalledwiththedefaultPython framework.ForWindows,whenyouinstallPythonfromtheinstallationfile,Tkintergets installedwithit. Tkinterisdesignedtotakeminimalprogrammingeffortsfordevelopinggraphical applications,whilealsobeingpowerfulenoughtoprovidesupportforthemajorityofGUI applicationfeatures.Ifrequired,Tkintercanalsobeextendedwithplugins.Tkintervia Tkoffersanoperatingsystem’snaturallookandfeelafterthereleaseofTkVersion8.0. TotestyourcurrentversionoftheTktoolkit,usethefollowingcommandsonthePython prompt: >>>importTkinter >>>Tkinter._test() Youwillbepromptedwithanimagesimilartothatdisplayedinthefollowingscreenshot thatcontainsinformationaboutyourTkversion: Ifyoufaceanyproblemingettingthiswindow,checkyourPythoninstallationand reinstallit,asyouwon’tbeabletomovefurtheraheadinthischapterwithouttheTkinter libraryandtheTktoolkit. TheTkinterinterfacesupportsvariouswidgetstodevelopGUIs.Thefollowingtable describesafewoftheimportantwidgetsthatwewillbeusinginthischapter: Widget Description Tk() Thisistherootwidgetthatisrequiredbyeachprogram Label() Thisshowsatextoranimage Button() Thisisasimplebuttonthatcanbeusedtoexecuteactions Entry() Thisisatextfieldtoprovideinputstotheprogram Scale() Thisprovidesanumericvaluebydraggingtheslider Checkbox() Thisenablesyoutotogglebetweentwovaluesbycheckingthebox Note AdetaileddescriptionoftheTkinterfunctionsandmethodstoimplementthemajorityof functionalitiesprovidedbytheTktoolkitcanbeobtainedfrom https://docs.python.org/2/library/tk.html. YourfirstPythonGUIprogram Aswediscussedinanearlierchapter,thefirstprogramwhilelearninganyprogramming languageincludesprintingHelloWorld!.Now,aswearestartingPythonprogramming forGUI,let’sstartbyprintingthesamestringinaGUIwindowinsteadofaprompt. JusttostartwithGUIprogramming,wearegoingtoexecuteaPythonprogramandthen jumpintoexplainingthestructureandthedetailsofthecode.Let’screateaPython executablefileusingthefollowinglinesofcode,nameithelloGUI.py,andthenrunit. Theexecutionprocessshouldcompletewithoutanydependencyerrors: importTkinter #Initializemainwindowswithtitleandsize top=Tkinter.Tk() top.title("HelloGUI") top.minsize(200,30) #Labelwidget helloLabel=Tkinter.Label(top,text="HelloWorld!") helloLabel.pack() #Startandopenthewindow top.mainloop() Youshouldbepromptedwiththefollowingwindowonthesuccessfulexecutionofthe precedingcodesnippet.Asyoucansee,theHelloWorld!stringhasbeenprintedinside thewindowandhasHelloGUIasthetitleofthewindow: So,whatexactlyhappened?Asyoucanseefromthecodesnippet,weinstantiatedvarious Tkinterwidgetsonebyonetoobtainthisresult.Thesewidgetsarethebuildingblocksfor anyPythonGUIapplicationthatisdevelopedusingTkinter.Let’sstartwiththefirstand themostimportantwidget,Tk(). TherootwidgetTk()andthetop-levelmethods TheTk()widgetinitializesamainemptywindowwithatitlebar.Thisisarootwidget anditisrequiredbyeachprogramonlyonce.Themainwindowgetsitsdecorationand stylesfromtheoperatingsystem’senvironment.Therefore,whenyourunthesame Tkintercodeondifferentoperatingsystems,youwillgetthesamewindowandtitlebar butinadifferentstyle. Onceyoucreatearootwidget,youcanperformsometop-levelmethodstodecorate, describe,orresizethiswindow.Incode,weareusingthetitle()methodtosetthetitle ofthemainwindow.Thistitle()methodtakesastringasaninputargument: Top=Tkinter.Tk() top.title("HelloGUI") Next,wecalltheminsize()methodonthemainwindowtosettheminimumsizeofthe windowwiththeargument(width,height): top.minsize(200,30) Similarly,youcanalsousethemaxsize()methodtospecifythemaximumsizethatthe mainwindowshouldhave.Intheminsize()andmaxsize()methods,thevaluesofwidth andheightareprovidedinthenumberofpixels. Oncetheentireprogramhasbeeninstantiated,themainloop()functionisrequiredtostart theeventloop: top.mainloop() Youwon’tbeabletoseeanyotherwidgets,includingthemainwindow,ifthecodedoes notenterinthemaineventloop.Theeventloopwillbealiveuntilthewindowismanually closedorthequitmethodiscalled. Youmighthavevariousquestionsaboutupdatingthewindow,programmaticallyclosing it,arrangingwidgetsinthegrid,andsoon.Therearedefinitelyalotmoretop-level methodsthantheonesspecifiedearlier. TheLabel()widget TheotherwidgetusedinthecodebesideTk()isLabel().TheTkinterwidgetsarepart ofthewidgethierarchy,whereLabel()isthechildoftherootwidget,Tk().Thiswidget cannotbecalledwithoutspecifyingtherootwidgetorthemainwindowonwhichthe labelneedstobedisplayed.Themajoruseofthiswidgetistodisplaytextorimageinthe mainwindow.Inthefollowinglineofcode,weuseittodisplaytheHelloWorld!string: helloLabel=Tkinter.Label(top,text="HelloWorld!") Here,wecreatedandinitializedalabelobjectcalledhelloLabel,whichhastwoinput parameters:thetopvariablethatspecifiestherootwidgetandatextstring.TheLabel() widgetishighlycustomizableandacceptsvariousconfigurationparametersforadjusting thewidth,border,background,andjustificationasoptions.Examplesinvolvingthese customizationsarecoveredintheupcomingsections.Youcanlearnmoreaboutthe supportedinputargumentsathttp://effbot.org/tkinterbook/label.htm. ThePackgeometrymanager ThePackgeometrymanagerorganizeswidgetsinrowsandcolumns.Tousethis,Tkinter requiresthepack()methodtobecalledforeachwidgettomakethewidgetvisibleonthe mainwindow: helloLabel.pack() ThePackgeometrymanagercanbeusedbyallTkinterwidgets,exceptroot,toorganize thewidgetintherootwindow.Inthecaseofmultiplewidgets,ifthepositionsforthe widgetsarenotspecified,thePackmanagerarrangestheminthesamerootwindow.The Packmanagerissimpletoimplement,butithasalimitationintermsofitsdegreeof customization.Analternativegeometrymanagerthatishelpfultocreateacomplexlayout iscalledGrid,whichisexplainedintheupcomingsections. Wewillcoveradditionalwidgetsandtheirassociatedmethodsintheupcomingcoding exercises.Intheseexercises,wewillexplaineachindividualwidgetwithpractical applicationstogiveyouabetterunderstandingoftheusecases. TheButton()widget–interfacingGUI withArduinoandLEDs Nowthatyouhavehadyourfirsthands-onexperienceincreatingaPythongraphical interface,let’sintegrateArduinowithit.Pythonmakesiteasytointerfacevarious heterogeneouspackageswithineachotherandthatiswhatyouaregoingtodo.Inthenext codingexercise,wewilluseTkinterandpyFirmatatomaketheGUIworkwithArduino. Inthisexercise,wearegoingtousetheButton()widgettocontroltheLEDsinterfaced withtheArduinoboard. Beforewejumptotheexercises,let’sbuildthecircuitthatwewillneedforallupcoming programs.ThefollowingisaFritzingdiagramofthecircuitwhereweusetwodifferent coloredLEDswithpullupresistors.ConnecttheseLEDstodigitalpins10and11onyour ArduinoUnoboard,asdisplayedinthefollowingdiagram: Note Whileworkingwiththeprogramsprovidedinthisandupcomingsections,youwillhave toreplacetheArduinoportthatisusedtodefinetheboardvariableaccordingtoyour operatingsystem.TofindoutwhichportyourArduinoboardisconnectedto,followthe detailedinstructionsprovidedinChapter2,WorkingwiththeFirmataProtocolandthe pySerialLibrary.Also,makesurethatyouprovidethecorrectpinnumberinthecodeif youareplanningtouseanypinsotherthan10and11.Forsomeexercises,youwillhave tousethePWMpins,somakesurethatyouhavecorrectpins. Inthepreviousexercise,weaskedyoutousetheentirecodesnippetasaPythonfileand runit.Thismightnotbepossibleintheupcomingexercisesduetothelengthofthe programandthecomplexityinvolved.Therefore,wehaveassembledtheseexercisesin theprogramfilesthatcanbeaccessedfromthecodefolderofChapter4,Divinginto Python-ArduinoPrototyping,whichcanbedownloadedfrom https://www.packtpub.com/books/content/support/1961.FortheButton()widget exercise,opentheexampleButton.pyfilefromthecodefolderofChapter4,Divinginto Python-ArduinoPrototyping.Thecodecontainsthreemaincomponents: ThepyFirmatalibraryandArduinoconfigurations TheTkinterwidgetdefinitionsforabutton TheLEDblinkfunctionthatgetsexecutedwhenyoupressthebutton Asyoucanseeinthefollowingcodesnippet,wehavefirstimportedlibrariesand initializedtheArduinoboardusingpyFirmatamethods.Forthisexercise,weareonly goingtoworkwithoneLEDandwehaveinitializedonlytheledPinvariableforit: importTkinter importpyfirmata fromtimeimportsleep port='/dev/cu.usbmodemfa1331' board=pyfirmata.Arduino(port) sleep(5) ledPin=board.get_pin('d:11:o') Note AsweareusingthepyFirmatalibraryforalltheexercisesinthischapter,makesurethat youhaveuploadedthelatestversionofthestandardFirmatasketchonyourArduino board. Inthesecondpartofthecode,wehaveinitializedtherootTkinterwidgetastopand providedatitlestring.Wehavealsofixedthesizeofthiswindowusingtheminsize() method.Inordertogetmorefamiliarwiththerootwidget,youcanplayaroundwiththe minimumandmaximumsizeofthewindow: top=Tkinter.Tk() top.title("BlinkLEDusingbutton") top.minsize(300,30) TheButton()widgetisastandardTkinterwidgetthatismostlyusedtoobtainthe manual,externalinputstimulusfromtheuser.LiketheLabel()widget,theButton() widgetcanbeusedtodisplaytextorimages.UnliketheLabel()widget,itcanbe associatedwithactionsormethodswhenitispressed.Whenthebuttonispressed, Tkinterexecutesthemethodsorcommandsspecifiedbythecommandoption: startButton=Tkinter.Button(top, text="Start", command=onStartButtonPress) startButton.pack() Inthisinitialization,thefunctionassociatedwiththebuttonisonStartButtonPressand the"Start"stringisdisplayedasthetitleofthebutton.Similarly,thetopobjectspecifies theparentortherootwidget.Oncethebuttonisinstantiated,youwillneedtousethe pack()methodtomakeitavailableinthemainwindow. Intheprecedinglinesofcode,theonStartButonPress()functionincludesthescriptsthat arerequiredtoblinktheLEDsandchangethestateofthebutton.Abuttonstatecanhave thestateasNORMAL,ACTIVE,orDISABLED.Ifitisnotspecified,thedefaultstateofany buttonisNORMAL.TheACTIVEandDISABLEDstatesareusefulinapplicationswhen repeatedpressingofthebuttonneedstobeavoided.AfterturningtheLEDonusingthe write(1)method,wewilladdatimedelayof5secondsusingthesleep(5)function beforeturningitoffwiththewrite(0)method: defonStartButtonPress(): startButton.config(state=Tkinter.DISABLED) ledPin.write(1) #LEDisonforfixamountoftimespecifiedbelow sleep(5) ledPin.write(0) startButton.config(state=Tkinter.ACTIVE) Attheendoftheprogram,wewillexecutethemainloop()methodtoinitiatetheTkinter loop.Untilthisfunctionisexecuted,themainwindowwon’tappear. Torunthecode,makeappropriatechangestotheArduinoboardvariableandexecutethe program.Thefollowingscreenshotwithabuttonandtitlebarwillappearastheoutputof theprogram.ClickingontheStartbuttonwillturnontheLEDontheArduinoboardfor thespecifiedtimedelay.Meanwhile,whentheLEDison,youwillnotbeabletoclickon theStartbuttonagain.Now,inthisparticularprogram,wehaven’tprovidedsufficient codetosafelydisengagetheArduinoboardanditwillbecoveredinupcomingexercises. TheEntry()widget–providingmanual userinputs Inthepreviousexercise,youusedabuttontoblinktheLEDontheArduinoboardfora fixedamountoftime.Let’ssaythatyouwanttochangethisfixedtimedelayandspecifya valueaccordingtoyourapplication’srequirement.Toperformthisoperation,youwill needawidgetthatacceptscustomvaluesthatcanthenbeconvertedintothedelay.Just likeanyotherGUIframework,Tkinterprovidestheinterfaceforasimilarwidgetcalled Entry()andwewillutilizethisinthenextexercise. KeepthesameArduinoandLEDconfigurationsthatyouusedforthepreviousexercise andopentheexampleEntry.pyfile.Inthebeginningofthecode,youwillfindthesame configurationfortheArduinoboardandtheLEDpinthatweusedintheprevious exercise.Movingontothenextstage,youwillbeabletoseethefollowingcodesnippet thatdefinestherootwidget.Inthiscodesnippet,wehavechangedthetitleofthemain windowtoreflectthepremiseoftheexercise.Theuseofuniquestringsforthetitleofthe windowwillhelpyoutodifferentiatethesewindowsaccordingtotheirproperties,when youaredealingwithmultiplewindowsinoneapplication: top=Tkinter.Tk() top.title("SpecifytimeusingEntry") AlthoughtheEntry()widgetcanbeeasilyinitializedbyspecifyingtheparentwidgetas theonlyparameter,italsosupportsalargenumberofparameterstocustomizethewidget. Forexample,inourexercise,weareusingthebdparametertospecifythewidthofthe widgetborderandwidthtoprovidetheexpectedwidthofthewidget.Youcanlearnmore abouttheavailableoptionsathttp://effbot.org/tkinterbook/entry.htm: timePeriodEntry=Tkinter.Entry(top, bd=5, width=25) timePeriodEntry.pack() timePeriodEntry.focus_set() startButton=Tkinter.Button(top, text="Start", command=onStartButtonPress) startButton.pack() Intheprecedinglinesofcode,wehaveinitializedtwowidgetobjectsinourmainwindow: timePeriodEntryfortheEntry()widgetandstartButtonthatweusedintheprevious exercisefortheButton()widget.ThePackgeometrymanageralwayssetsthegraphical pointertothelastwidgetthathasbeenaddedtothemainwindow.Wecanmanuallyshift thefocusofthegraphicalpointertothetimePeriodEntrywidgetusingthefocus_set() method. ContrarytotheonStartButtonPress()functioninthepreviousexercise,thisfunction doesn’tusethetimedelayfix.It,instead,obtainsthevaluefromthetimePeriodEntry object.Youcanusetheget()methodtoobtaintheenteredvaluefromthe timePeriodEntryobjectandconvertitintoafloatingvalueusingthefloat()function. Asyoucanseeinthefollowingcodesnippet,weusethisfloatvalueasthetimedelay betweenswitchingtheLEDofffromtheonstate: defonStartButtonPress(): #ValuefordelayisobtainedfromtheEntrywidgetinput timePeriod=timePeriodEntry.get() timePeriod=float(timePeriod) startButton.config(state=Tkinter.DISABLED) ledPin.write(1) sleep(timePeriod) ledPin.write(0) startButton.config(state=Tkinter.ACTIVE) OnceyouhaveunderstoodtheprocessofinitializingtheEntry()widgetandthemethod toobtainacustomvaluefromit,let’sexecutethecode. Whenyourunthisexercise,youshouldbeabletoseeawindowsimilartotheone displayedinthefollowingscreenshot.Enteratimedelayvalueinsecondsandclickon StarttoseetheresultsontheLED.Basically,whenthebuttonispressed,theprogram willcalltheonStartButtonPress()functionanditwillutilizethisvaluetoproducethe timedelay. TheScale()widget–adjustingthe brightnessofanLED Inthissection,wewilldevelopsomecodetochangeanLED’sbrightnessusingthe PythonGUI.Previously,welearnedthatyoucanuseadigitalpinofArduinotoproduce ananalogoutputusingPWM.AlthoughyoucanusetheEntry()widgettoprovideone timevalueforthePWMsignal,itwillbeusefultohaveawidgetthatcandynamically providethisvalue.Asbrightnesscanbefluctuatedbetween0and100percent,itmakes sensetouseasliderthatvariesbetween0and100.TheTkinterlibraryprovidesthiskind ofslidinginterfaceusingtheScale()widget. AsweareworkingtochangethebrightnessoftheLEDandsupplyanaloginput,wewill beusingadigitalpinwiththePWMsupport.Inthepreviousexercise,weuseddigitalpin 11,whichalreadysupportsPWM.Ifyouareusingacustomversionofthecircuitdifferent totheoneprovidedearlier,werecommendthatyouchangeittoapinthatsupportsPWM. Nowitistimetoopentheprogramfile,exampleScale.py,forthisexercise. Thefirststageoftheprogramthatinvolvesimportingthenecessarylibrariesand initializingtheArduinoboardusingpyFirmataisalmostthesameasintheprevious exercise.Changethestringthatisusedtospecifytheappropriatevaluefortheport variableaccordingtotheoperatingsystemandtheportthatyouareusing.Wewillalso instantiatetherootwindowwiththeuniquetitleforthisexercise,aswedidintheprevious exercises.Thispartoftheprogramwilloftenreoccurforalargenumberofexercisesand youcanrefertothepreviousexerciseformoreinformation. Inthenextstage,wewillcontinuebuildingthecodethatwedevelopedearliertoprovidea manualtimedelayfortheLED.WewillalsousethesameEntry()widgettoobtainthe timeintervalasaninput: timePeriodEntry=Tkinter.Entry(top, bd=5, width=25) timePeriodEntry.pack() timePeriodEntry.focus_set() TheScale()widgetoffersasliderknobthatcanbemovedoverafixedscaletoprovidea numericvalueasanoutput.Thestartingandtheendingvaluesforthisscaleareprovided usingthefrom_andtooptions.Theorientationofthisslidercanalsobeconfiguredusing theorientoption,wheretheacceptablevaluesfortheorientationareHORIZONTALand VERTICAL.However,youwillhavetoimportHORIZONTALandVERTICALconstantsfromthe Tkinterlibrarybeforeutilizingthemhere. Ifnooptionsareprovided,thedefaultwidgetusesthescalefrom0to100andthevertical orientation.Inourprogram,wehaveusedthehorizontalorientationasademonstrationof theorientoption.Onceyouhavedefinedthewidgetobject,brightnessScale,youwill havetoaddittothePackgeometrymanagerusingpack(): brightnessScale=Tkinter.Scale(top, from_=0,to=100, orient=Tkinter.HORIZONTAL) brightnessScale.pack() Inordertostarttheprocessandreusethepreviouscode,wehavekepttheinstantiationof thestartButtonwidgetandtheonStartButtonPressfunctionasitis.However,the propertyofthefunctionischangedtoaccommodatetheScale()widget: startButton=Tkinter.Button(top, text="Start", command=onStartButtonPress) startButton.pack() InthisversionoftheonStartButtonPress()function,wewillobtaintheledBrightness valuebyusingtheget()methodonthebrightnessScalewidgetobject,wheretheget() methodwillreturnthevalueofthecurrentlocationoftheslider.AsthePWMinput requiresvaluesbetween0and1,andtheobtainedslidervalueisbetween0and100,we willconverttheslidervalueintotheappropriatePWMinputbydividingitwith100.This newvaluewillthenbeusedwiththewrite()methodandthiswillultimatelyturnonthe LEDwiththeappliedbrightnessforthetimeperiodthatisprovidedbythe timePeriodEntryvalue: defonStartButtonPress(): timePeriod=timePeriodEntry.get() timePeriod=float(timePeriod) ledBrightness=brightnessScale.get() ledBrightness=float(ledBrightness) startButton.config(state=Tkinter.DISABLED) ledPin.write(ledBrightness/100.0) sleep(timePeriod) ledPin.write(0) startButton.config(state=Tkinter.ACTIVE) ForinformationabouttheScale()widget,youcanreferto http://effbot.org/tkinterbook/scale.htm.Now,runtheexampleScale.pyfile.Youwillbe abletoseethefollowingscreenshotwiththeEntry()andScale()widgets.Enterthetime delay,dragtheslidertothebrightnessthatyouwant,andthenclickontheStartbutton: YouwillbeabletoseetheLEDlightupwiththebrightnesssetbytheScale()widget. OncetheLEDisturnedoffafterthegiventimedelay,youcanresettheslidertoanother positiontodynamicallyvarythevalueforthebrightness. TheGridgeometrymanager Inthepreviousexercise,weaddedthreedifferentwidgetstotherootwindowusingthe Packgeometrymanagerandthepack()method.Wedidn’tactivelyorganizethese widgetsbutthePackmanagerautomaticallyarrangedthemintheverticalposition.While designingameaningfulinterface,youneedtoarrangethesewidgetsintheappropriate order.Ifyoulookatthepreviousoutputwindow,itisreallydifficulttoidentifythe functionofeachwidgetortheirassociationwithothers.Inordertodesignanintuitive GUI,youalsoneedtodescribethesewidgetsusingtheappropriatelabels.Asasolution, TkinterprovidesanalternativewaytoorganizeyourwidgetsthatiscalledGrid geometrymanager. TheGridgeometrymanagerprovidesatwo-dimensional(2D)tableinterfacetoarrange widgets.Everycellthatresultsfromtherowandcolumnofthe2Dtablecanbeusedasa placeforthewidgets.Youwilllearnthevariousoptionsthatareprovidedbythegrid() classtoorganizewidgetsinthenextprogrammingexercise.Openthe exampleGridManager.pyfilefromthecodefolderofthischapter.Intermsof functionalities,thisfilecontainsthesameprogramthatwebuiltinthepreviousexercise. However,wehaveaddedmoreLabel()widgetsandorganizedthemusingtheGrid geometrymanagertosimplifytheGUIandmakeitmoreuseful. Asyoucanobserveinthecode,thetimePeriodEntryobject(anEntry()widget)now usesthegrid()methodinsteadofthepack()method.Thegrid()methodisinitialized withthecolumnandrowoptions.Thevaluessuppliedfortheseoptionsdeterminethe positionofthecellwherethetimePeriodEntryobjectwillbeplaced. Ontheotherhand,wehavealsocreatedalabelobjectusingtheLabel()widgetand placeditbesidetheEntry()widgetinthesamerow.Thelabelcontainsadescription stringthatisspecifiedusingthetextoption.Afterplacingitinacellusingthegrid() method,widgetsarearrangedinthecenterinthatcell.Tochangethisalignment,youcan usethestickyoptionwithoneormorevaluesfromN,E,S,andW,thatis,north,east, south,andwest: timePeriodEntry=Tkinter.Entry(top,bd=5) timePeriodEntry.grid(column=1,row=1) timePeriodEntry.focus_set() Tkinter.Label(top,text="Time(seconds)").grid(column=2,row=1) Wehaverepeatedthispracticeofplacingthewidgetinacellanddescribingitusinga Label()widgetfortheobjectsoftheScale()andButton()widgetsaswell: brightnessScale=Tkinter.Scale(top,from_=0,to=100, orient=Tkinter.HORIZONTAL) brightnessScale.grid(column=1,row=2) Tkinter.Label(top,text="Brightness(%)").grid(column=2,row=2) startButton=Tkinter.Button(top,text="Start",command=onStartButtonPress) startButton.grid(column=1,row=3) Asyoucanseeintheprecedingcodesnippet,weareusingdifferentrowvaluesforthe widgetswhilehavingsimilarcolumnvalues.Asaresult,ourwidgetswillbeorganizedin thesamecolumnandtheywillhavetheirdescriptionlabelsinthenextcolumnofthesame row.Youcanskiptotheoutputwindowifyouwanttocheckthisorganizationpattern. Sofar,wewererelyingontheusertomanuallyclosethemainwindow.However,youcan createanotherButton()widgetandthroughthat,callthemethodtoclosethiswindow.In thiscodingexercise,wehaveanadditionalbuttoncomparedtothepreviousexercisethat iscalledexitButton.Thecommandparameterassociatedwiththisbuttonisquit,which endstheloopstartedbytheTkintermethodtop.mainloop()andclosestheGUI: exitButton=Tkinter.Button(top, text="Exit", command=top.quit) exitButton.grid(column=2,row=3) Inthiscodesample,thequitmethodisinitializedasacommandoptionanditcanbealso becalledasamethod: top.quit() Beforewegoaheadtothenextstep,performtheappropriatechangesinthecodeandrun theprogram.Youwillbepromptedwithawindowsimilartotheonedisplayedinthe followingscreenshot: Thereddottedlinesareinsertedlatertohelpyouidentifythegridandtheywon’tappear inthewindowthatisopenedbyrunningtheprogram.Youcannowclearlyidentifythe roleofeachwidgetduetothepresenceofthedescriptionlabelbesidethem.Intheopened window,playaroundwiththetimeandbrightnessvalueswhileusingtheStartandExit buttonstoperformtheassociatedactions.Fromthenextexercise,wewillstartusingthe grid()methodregularlytoarrangethewidgets. TheCheckbutton()widget–selecting LEDs Whiledevelopingcomplexprojects,youwillencounterscenarioswhereyouhaveto dependontheusertoselectsingleormultipleoptionsfromagivensetofvalues.For example,whenyouhavemultiplenumbersofLEDsinterfacedwiththeArduinoboard andyouwanttheusertoselectanLEDorLEDsthatneedtobeturnedon.Thislevelof customizationmakesyourinterfacemoreinteractiveanduseful.TheTkinterlibrary providesaninterfaceforastandardwidgetcalledCheckbutton()thatenablesthemanual selectionprocessfromthegivenoptions. Inthisexercise,wearegoingtoworkwithboththeLEDs,greenandred,thatyou connectedtotheArduinoboardatthebeginning.TheentirePythonprogramforthis exerciseislocatedinthecodefolderwiththenameexampleCheckbutton.py.Openthe filewiththesameeditorthatyouhavebeenusingallalong.Thisprogramimplementsthe Checkbutton()widgetforuserstoselecttheredand/orgreenLEDwhentheStartbutton isclicked. Tounderstandtheentireprogramlogic,let’sstartfromtheinitializationandimportingof thelibraries.Asyoucansee,nowwehavetwopinassignmentsfordigitalpins10and11 asredPinandgreenPinrespectively.ThecodefortheinitializationoftheArduinoboard isunchanged: port='/dev/cu.usbmodemfa1331' board=pyfirmata.Arduino(port) sleep(5) redPin=board.get_pin('d:10:o') greenPin=board.get_pin('d:11:o') InourutilizationoftheCheckbutton()widget,weareusingaveryusefulTkinter variableclassthatiscalledIntVar().TheTkintervariablecantellthesystemwhenthe valueofthevariableischanged.TobetterunderstandtheTkintervariableclassandits specificutilizationinourexercise,takealookatthefollowingcodesnippetfromthe program: redVar=Tkinter.IntVar() redCheckBox=Tkinter.Checkbutton(top, text="RedLED", variable=redVar) redCheckBox.grid(column=1,row=1) TheCheckbutton()widgetletsauserselectbetweentwodifferentvalues.Thesevalues areusually1(on)or0(off),makingtheCheckbutton()widgetaswitch.Tocapturethis selection,thevariableoptionisrequiredinthewidgetdefinition.Avariablecanbe initializedusingoneoftheTkintervariableclass,IntVar(). Asyoucansee,theredVarvariableobjectthatisinstantiatedusingtheIntVar()classis usedforthevariableoptionwhiledefiningtheCheckbutton()widget,redCheckButton. Therefore,anyoperationontheredCheckButtonobjectwillbetranslatedtotheredVar variableobject.AsIntVar()isaTkinterclass,itautomaticallytakescareofanychanges inthevariablevaluesthroughtheCheckbutton()widget.Therefore,itisadvisabletouse theTkintervariableclassfortheCheckbutton()widgetinsteadofthedefaultPython variables.AfterdefiningtheCheckbutton()widgetfortheredLED,wehaverepeated thisprocessforthegreenLED,asshowninthefollowingcodesnippet: greenVar=Tkinter.IntVar() greenCheckBox=Tkinter.Checkbutton(top, text="GreenLED", variable=greenVar) greenCheckBox.grid(column=2,row=1) ThisprogramalsocontainstheStartandExitbuttonsandtheirrespectiveassociation withtheonStartButtonPressandtop.quit()functions,similartohowweusedthemin thepreviousexercise.Whencalled,theonStartButtonPressfunctionwillobtainthe valuesoftheIntVar()variables,redVarandgreenVar,usingtheget()method.Inthis case,thevariablevalueoftheCheckbutton()widgetwillbe1whenitischeckedand0 otherwise.Thiswillenabletheprogramtosendthevalue1or0totheArduinopinusing thewrite()methodbycheckingoruncheckingthewidgetandultimately,turntheLED onoroff: defonStartButtonPress(): redPin.write(redVar.get()) greenPin.write(greenVar.get()) Asyoucansee,thecodealsoimplementsanadditionalStopbuttontoturnofftheLEDs thatwereturnedonusingtheStartbutton: stopButton=Tkinter.Button(top, text="Stop", command=onStopButtonPress) stopButton.grid(column=2,row=2) TheonStopButtonPrerss()functionassociatedwiththisbuttonturnsoffboththeLEDs byusingwrite(0)onboththepins: defonStopButtonPress(): redPin.write(0) greenPin.write(0) SinceyouhavenowlearnedabouttheTkintervariablesandtheCheckbutton()widget, let’srunthePythonprogram,exampleCheckbutton.py.Asyoucanseeinthenext screenshot,theGUIhastwoCheckbutton()widgetseachfortheredandgreenLEDs.As thereisaseparateinitializationoftheCheckbutton()widgets,ausercancheckboththe redandgreenLEDs.TkinteralsoprovidessimilarwidgetssuchasRadiobutton()and Listbox()forcaseswhereyouwanttoselectonlyasinglevaluefromthegivenoptions. Note YoucanlearnmoreabouttheRadiobutton()andListbox()widgetsfromthefollowing webpages: http://effbot.org/tkinterbook/radiobutton.htm http://effbot.org/tkinterbook/listbox.htm TheLabel()widget–monitoringI/Opins Arduinoprojectsoftendealwithreal-timesystemsandarerequiredtocontinuously monitorinputvaluesfromdigitalandanalogpins.Therefore,ifthesevaluesarebeing displayedonagraphicalinterface,theyneedtobeupdatedperiodicallyorwhenthestate ofapinchanges. IfyouobservethepreviousGUIexercises,youwillnoticethatweinitializedtheroot windowusingmainloop()attheendofthecode,whichstartedtheTkinterloopand initializedallthewidgetswiththeupdatedvalues.Oncethemainloop()wasinitialized, wedidnotuseanyotherTkinterclassormethodtoperiodicallyupdatethewidgetswith thelatestvalues. Inthisexercise,wewilluseapotentiometertoprovidevariableinputtotheanalogpin0, whichwillbereflectedbyTkinter’sLabel()widget.Toupdatethelabelanddisplaythe valuesoftheanaloginput,wearegoingtoimplementafewPythonandTkintertricks. Asweareusingapotentiometertoprovideinput,youwillneedtochangethecircuitas displayedinthefollowingdiagram,beforejumpingtothePythonprogram: ThePythonfileforthisexerciseislocatedinthecodefolderasthe workingWithLabels.pyfile.Forthisexercise,let’srunthecodefirsttounderstandthe premiseoftheexercise.MakesurethatyouhavetheappropriatestringfortheArduino boardwhenyoudefinetheportvariable.Onsuccessfulexecution,theprogramwill displaythefollowingscreenshotandyoucanclickontheStartbuttontoinitiatethe continuousupdateofthepotentiometer’sinputvalue: So,howdidwedothis?Thiscodecontainscomplexlogicandadifferentprogramflow comparedtowhatwehavedonesofar.Asyoucanseefromthecode,weareusinga variablecalledflagtotrackthestateoftheExitbuttonwhilecontinuouslyrunningthe whileloopthatmonitorsandupdatesthevalue.Tounderstandtheprogramproperly,let’s firstgetfamiliarwiththefollowingnewTkinterclassesandmethods: BooleanVar():JustliketheIntVar()variableclassthatweusedtotracktheinteger values,BooleanVar()isaTkintervariableclassthattrackschangesinBoolean: flag=Tkinter.BooleanVar(top) flag.set(True) Intheprecedingcodesnippet,wehavecreatedavariableobject,flag,usingthe BooleanVar()classandsetthevalueoftheobjectasTrue.BeingaBooleanobject, flagcanonlyhavetwovalues,TrueorFalse.Tkinteralsoprovidesclassesfor stringanddoubletypewiththeStringVar()andDoubleVar()classesrespectively. Duetothis,whentheStartbuttonisclicked,thesystemstartsupdatingtheanalog readvalue.TheExitbuttonsetstheflagvariabletofalse,breaksthewhileloop, andstopsthemonitoringprocess. update_idletasks:WhileusingtheTkinterlibraryinPython,youcanlinka PythoncodetoanychangesthathappeninaTk()widget.ThislinkedPythoncodeis calledacallback.Theupdate_idletasksmethodcallsallidletaskswithout processinganycallbacks.Thismethodalsoredrawsthegeometrywidgets,if required: AnalogReadLabel.update_idletasks() Inourexercise,thismethodcanbeusedtocontinuouslyupdatethelabelwiththe latestpotentiometervalue. update:Thistop-levelmethodprocessesallthependingeventsandcallbacksand alsoredrawsanywidget,ifitisnecessary: top.update() Weareusingthismethodwiththerootwindowsothatitcanperformthecallbackfor theStartbutton. Nowlet’sgobacktotheopenedPythonprogram.Asyoucansee,besidesassigningan analogpinthroughtheget_pin()methodandinitializingtheIterator()classoverthe Arduinoboard,thecodecontainssimilarprogrammingpatternsthatweusedinthe exercisesfortheotherTkinterwidgets.Inthiscode,weareperformingthereadoperation fortheanalogpininsidetheonStartButtonPress()functionThisfunctionchecksthe statusoftheflagvariablewhileperformingtheread()operationonthepinand subsequentlyupdatesthevalueoftheanalogReadLabel()widgetifthevalueoftheflag variableisTrue.IfthevalueoftheflagvariableisfoundtobeFalse,thefunctionwill exitafterdisengagingtheArduinoboardandclosingtherootwindow.Duetotheuseof thewhilestatement,thisprocesswillcontinuouslychecktheflagvalueuntilitisbroken bytheonExitButtonPress()functionbychangingtheflagvaluetoFalse: defonStartButtonPress(): whileTrue: ifflag.get(): analogReadLabel.config(text=str(a0.read())) analogReadLabel.update_idletasks() top.update() else: break board.exit() top.destroy() TheonExitButtonPress()functioniscalledfromtheExitbuttonanditsimplyresetsthe flagvariabletoFalseusingtheset()method: defonExitButtonPress(): flag.set(False) RemakingyourfirstPython-Arduino projectwithaGUI Justtorefreshyourmemory,Iwouldliketoremindyouthatwecreatedamotion detectionsystemthatgeneratedalertsbyblinkingtheredLEDwhenamotionwas detected.Whileworkingwiththeproject,wewereprintingthestateoftheproximity sensorontothePythonprompt.Inthisexercise,wearegoingtousetheconceptsthatyou learnedinthepreviousexercisesandwewillcreateaninterfaceforourproject. Aspartofthisexercise,youhavetoconnectthesamecircuitthatweusedinChapter3, TheFirstProject–Motion-triggeredLEDs.Makesureyouhavetheexactsamecircuit withthePIRsensorandtheLEDsbeforeyoumoveahead.Onceyouarereadywithyour hardware,openthefirstProjectWithGUI.pyfilefromthecodefolderofthischapter.In thecode,changetheappropriateportvaluesandruntheGUIfortheproject. Asyoucanseeinthepinassignments,wenowhavethreedigitalpins—twoofthemas outputsandoneasaninput.TheoutputpinsareassignedtotheredandgreenLEDswhile theinputpinisassignedtothePIRmotionsensor.IfthePIRsensorisinidlemode,we willperformaonetimeread()operationtowakeupthesensor: pirPin=board.get_pin('d:8:i') redPin=board.get_pin('d:10:o') greenPin=board.get_pin('d:11:o') pirPin.read() OneoftheimportantfunctionsthatisimplementedbythecodeisblinkLED().This functionupdatestheLabel()widgetthatisassignedtodescribethestatusofthemotion sensor.ItalsoblinksthephysicalLEDsusingthewrite()methodandtheinsertedtime delay.Asinputparameters,theblinkLED()functionacceptsthepinobjectandamessage stringfromthefunctioncall,wherethepinobjects,thatis,redPinorgreenPin,shouldbe oneofthepinassignmentfortheLEDs: defblinkLED(pin,message): MotionLabel.config(text=message) MotionLabel.update_idletasks() top.update() pin.write(1) sleep(1) pin.write(0) sleep(1) TheothertwoTkinterrelatedfunctions,onStartButtonPress()and onExitButtonPress(),arebasicallyderivedfromthepreviousexercise.Inthisversionof onStartButtonPress(),wecalltheblinkLED()functioniftheflagvariableisTrueand themotionisdetectedusingpinPir.read(): defonStartButtonPress(): whileTrue: ifflag.get(): ifpirPin.read()isTrue: blinkLED(redPin,"MotionDetected") else: blinkLED(greenPin,"NomotionDetected") else: break board.exit() top.destroy() Theprogramalsoinstantiatestwobuttons,StartandExit,andonelabelusingthe methodssimilartothoseweusedinthepreviousexercises. Asyoucanobservefromthecode,thelogicbehindthemotiondetectionsystemisstillthe same.Weareonlyaddingalayerofgraphicalinterfacetodisplaythestateofthedetected motioncontinuouslyusingaLabel()widget.WehavealsoaddedtheStartandExit buttonstocontroltheprojectexecutioncycle.Onceyourunthecode,youwillbeableto seeawindowsimilartotheonedisplayedinthefollowingscreenshot.ClickontheStart buttonandwaveinfrontofthemotionsensor.Ifthesensordetectsthemotion,thelabel willchangefromNomotiondetectedtoMotiondetected. Summary Nowyouhavehands-onexperienceofbuildingabasicGUItohandleArduinoprojects. Withminormodificationstotheincludedexercises,youcanusethemtocreateaGUIfor alargevarietyofArduinoprototypingprojects.Intheprevioustwoexercises,we displayedthesensoroutputsasstringsinlabelwidgets.Itwillbemoremeaningfulifthese numericalvaluesareplottedasagraphandstoredforfurtheranalysis.Thisiswhatyou aregoingtoperforminthenextchapter. Chapter6.StoringandPlottingArduino Data SensorsthatareconnectedtoArduinoproducelotsofanaloganddigitaldata.Analog sensorsproducedatapointsasnumericalinformationwhiledigitalsensorsproduce Booleanvalues,thatis,1(on)or0(off).Untilnow,weprintedthisdataasastringonthe commandpromptordisplayeditinaGUI.Thedatawasbeingprintedinrealtimeandit wasnotbeingsavedforanyfurtheranalysis.Insteadofusingthestringformat,ifthedata isprintedasaplotorgraph,itwillprovideusefulinformationforustorapidlyunderstand itandderiveconclusions.Plotsareevenmoreusefulforreal-timeapplicationsastheycan provideinformationregardingthesystem’sbehaviorforbetterunderstandingofthedata. Thischapterisorganizedaroundtwomajorsections:storingtheArduinosensordataand plottingthisdata.WewillstartbycreatingandmanipulatingfilesusingPython.Afterthat, wewillworkwithmethodsforstoringArduinodataintheCSVfileformat.Inthesecond section,youwillbeintroducedtothePythonplottinglibrary,matplotlib.Then,wewill workwithexamplesthatdealwithplottingdatafromasavedfileandalsofromreal-time sensorreadings.Intheend,wewilltrytointegratethematplotlibplotswiththeTkinter windowthatwecreatedinthepreviouschapter. Intermsofhardwarecomponents,wewillbeworkingwithfamiliarsensorssuchasa potentiometerandthePIRmotionsensor,whichweusedinthepreviouschapters,so,you willnothavetolearnorbuyanyadditionalsensorsforthischapter. WorkingwithfilesinPython Pythonprovidesbuilt-inmethodstocreateandmodifyfiles.File-relatedPython operationsareusefulinalargenumberofprogrammingexercises.Thesemethodsare providedbystandardPythonmodulesanddonotrequireinstallationofadditional packages. Theopen()method Theopen()methodisadefaultmethodthatisavailableinPythonanditisoneofthemost widelyusedfunctionstomanipulatefiles.Now,thefirststepofdealingwithafileisto openit: >>>f=open('test.txt','w') Thiscommandwillcreateatest.txtfileinthesamefolderinwhichyoustartedthe Pythoninterpreterorthelocationfromwherethecodeisbeingexecuted.Thepreceding commandusesthewmodethatopensafileforwritingorcreatesanewoneifitdoesn’t exist.Theothermodesthatcanbeusedwiththeopen()functionaredisplayedinthe followingtable: Mode Description w Thisopensorcreatesafileforwritingonly.Itoverwritesanexistingfile. w+ Thisopensorcreatesafileforwritingandreading.Itoverwritesanexistingfile. r Thisopensafileforreadingonly. r+ Thisopensafileforreadingandwriting. a Thisopensafileforappending.Itstartsappendingfromtheendofthedocument. a+ Thisopensafileforappendingandreading.Itstartsappendingfromtheendofthedocument. Note Makesurethatyouhavetheproperreadandwritepermissionsforthefilesifyouare utilizingthesemodesinaUnixorLinuxenvironment. Thewrite()method Oncethefileisopeninoneofthewritingorappendingmodes,youcanstartwritingtothe fileobjectusingthismethod.Thewrite()methodonlytakesastringasaninput argument.Anyotherdataformatneedstobeconvertedintoastringbeforeitiswritten: >>>f.write("HelloWorld!\n") Inthisexample,wearewritingtheHelloWorld!stringthatendswithanewline character,\n.Thisnewlinecharacterhasbeenexplainedinthepreviouschapterandyou canobtainmoreinformationaboutitathttp://en.wikipedia.org/wiki/Newline. Youcanalsousethewritelines()methodifyouwanttowriteasequenceofstringsto thefile: >>>sq=["PythonprogrammingforArduino\n","Bye\n"] >>>f.writelines(sq) Theclose()method Theclose()methodclosesthefileandfreesystemresourcesthatareoccupiedbythefile. Oncetheyareclosed,youcan’tusethefileobjectasithasbeenflushedalready.Itisa goodpracticetoclosethefileonceyouaredoneworkingwithafile: >>>f.close() Theread()method Thisread()methodreadsthecontentofanopenedfilefromthebeginningtotheend.To usethismethod,youneedtoopenthefilewithoneofthereadingcompatiblemodessuch asw+,r,r+,ora+: >>>f=open('test.txt','r') >>>f.read() 'HelloWorld!\nPythonprogrammingforArduino\nBye\n' >>>f.close() Astheread()methodgrabstheentirecontentsofthefileintomemory,youcanuseit withtheoptionalsizeparametertoavoidanymemorycongestionwhileworkingwith largefiles.Asanalternativemethod,youcanusethereadlines()methodtoreadthe contentofanopenedfilelinebyline: >>>f=open('test.txt','r') >>>l=f.readlines() >>>printl ['HelloWorld!\n','PythonprogrammingforArduino\n','Bye\n'] >>>f.close() Asyoucanseeintheprecedingexample,eachstringisprintedasanelementofalistthat youcanaccessindividually.Youcanplayaroundwiththesemethodstogetfamiliarwith creatingandmodifyingfiles.Theseexerciseswillbehandyfortheupcomingcoding exercises. Thewithstatement–Pythoncontextmanager Althoughthewithstatementcanbeusedtocovertheexecutionofacodeblockthatis definedbyacontextmanager,itiswidelyusedinPythontodealwithfiles.Executethe followingcommandonthePythoninteractiveprompt,assumingthatyouhavealready executedthepreviouscommandsandhavethetest.txtfilewithsomedata: >>>withopen('test.txt','r')asf: lines=f.readlines() forlinlines: printl Onexecution,youwillbeabletoseeeachlineofthefileprintedonthecommandprompt. Thewithstatementwhileusedwiththeopen()methodcreatesacontextmanager,which executesthewrappedcodewhileautomaticallytakingcareofclosingthefile.Thisisthe recommendedmethodtoworkwithfilesinPythonandwewillbeutilizingitinallofour exercises.YoucanlearnmoreaboutthePythoncontextmanageronthefollowing websites: https://docs.python.org/2/reference/compound_stmts.html#with http://preshing.com/20110920/the-python-with-statement-by-example/ UsingCSVfilestostoredata Nowyouknowmethodstoopen,manipulate,andclosefilesusingPython.Intheprevious examples,weusedthePythoninterpreterandstringdatatogetfamiliarwiththese methods.Butwhenitcomestosavingalargenumberofnumericalvaluesfromsensor data,thecommaseparatedvalues(CSV)fileformatisoneofthemostwidelyusedfile formatsotherthantext.Asthenamestates,valuesareseparatedandstoredusingcommas orotherdelimiterssuchasaspaceortab.Pythonhasabuilt-inmoduletodealwithCSV files. Tobeginwith,usethefollowingcodesnippettocreateaPythonfileandrunyourfirst CSVprogram: importcsv data=[[1,2,3],['a','b','c'],['Python','Arduino','Programming']] withopen('example.csv','w')asf: w=csv.writer(f) forrowindata: w.writerow(row) YoucanalsoopenthecsvWriter.pyfilefromthischapter’scodefolder,whichcontains thesamecode.Afterexecutingthecode,youwillbeabletofindafilenamed example.csvinthesamelocationasthisfile,whichwillcontainthedataseparatedwith commas. Asyoucanseeinthecode,theCSVmoduleoffersthewriter()functionontheopened filethatinitializesawriterobject.Thewriterobjecttakesasequenceorarrayofdata (integer,float,string,andsoon)asinputandjoinsthevaluesofthisarrayusingthe delimitercharacter: w=csv.writer(f) Intheprecedingexample,sincewearenotusingadelimiteroption,theprogramwilltake thedefaultcharactercommaasthedelimiter.Ifyouwanttousespaceasthedelimiter character,youcanusethefollowingwriter()option: w=csv.writer(f,delimiter='') Towriteeachelementofalisttoanewlineofthiswriterobject,weusethewriterow() method. Similarly,PythonCSVmodulealsoprovidesthereader()functiontoreadaCSVfile. Checkoutthefollowingexampletolearnmoreaboutthisfunction,oryoucanopenthe csvReader.pyfilefromthenextchapter’scodefolder: importcsv withopen('example.csv','r')asfile: r=csv.reader(file) forrowinr: printrow Thereader()functioncreatesareaderobjecttoiterateoverlinesintheopenedCSVfile. Thereaderobjectretrieveseachelementofarowbysplittingitusingthedelimiter.You canaccesseachlineofthefilebyiteratingovertheobjectusingtheforloopasdisplayed intheprecedingcodesnippet,orusethenext()methodeverytimeyouwanttoaccessthe nextline.Onexecutionofthepreviouscode,youwillbeabletoseethreeseparatearray liststhatareprintedwiththreeindividualelements. Tip ToopentheCSVfilesexternally,youcanuseaspreadsheetprogramsuchasMicrosoft Excel,OpenOfficeCalc,orAppleNumbers. StoringArduinodatainaCSVfile Intheprevioustwosections,youlearnedmethodstostorevaluesinaCSVfile.Although thedatarequiredforthefilewasalreadyinitializedinthecode,thesamecodecouldbe modifiedtostoreArduinoinputdata. TobeginwithstoringArduinodata,let’screateacircuitthatproducesthesevaluesforus. WeusedamotionsensorintheprojectofChapter3,TheFirstProject–Motion-triggered LEDs,andapotentiometerintheexerciseofChapter4,DivingintoPython-Arduino Prototyping.Wewillbeusingthesetwosensorstoprovideuswithdigitalandanalog inputvaluesrespectively.Todevelopthecircuitrequiredforthisexercise,connectthe potentiometertotheanalogpin0andthePIRmotionsensortodigitalpin11,asdisplayed inthefollowingdiagram: ConnectotherArduinopinssuchas5Vandtheground,asshownintheprecedingFritzing diagram.AswearegoingtousepyFirmatatointerfacePythonwiththeArduinoboard, youwillhavetouploadtheStandardFirmatasketchtotheArduinoboardusingthe methoddescribedinChapter3,TheFirstProject–Motion-triggeredLEDs. Note Whenyouareworkingwithprototyping,youreallydon’tneedlarge,powerful,and computation-intensivedatabasestodealwithinformation.Theeasiestandquickestwayto workwithsensordatainthisphaseisbyusingCSVfiles. OnceyouhaveyourArduinoboardreadywiththeappropriateconnections,usethe followingcodesnippettocreateaPythonfileandrunit.Youcanalsoopenthe csvArduinoStore.pyfilefromthischapter’scodefolder: importcsv importpyfirmata fromtimeimportsleep port='/dev/cu.usbmodemfa1331' board=pyfirmata.Arduino(port) it=pyfirmata.util.Iterator(board) it.start() pirPin=board.get_pin('d:11:i') a0=board.get_pin('a:0:i') withopen('SensorDataStore.csv','w')asf: w=csv.writer(f) w.writerow(["Number","Potentiometer","Motionsensor"]) i=0 pirData=pirPin.read() potData=a0.read() whilei<25: sleep(1) ifpirDataisnotNone: i+=1 row=[i,potData,pirData] w.writerow(row) print"Done.CSVfileisready!" board.exit() Whilethecodeisrunning,rotatetheknobofthepotentiometerandwaveyourhandin frontofthemotionsensors.Thisactionwillhelpyoutogenerateandmeasuredistinct valuesfromthesesensors.Meanwhile,theprogramwilllogthisdatainthe SensorDataStore.csvfile.Whencomplete,opentheSensorDataStore.csvfileusing anytextviewerorspreadsheetprogramandyouwillbeabletoseethesesensorvalues storedinthefile.Now,let’strytounderstandtheprogram. Asyoucanobservefromthecode,wearenotutilizinganewmoduletointerfacethe Arduinoboardorstoresensorvaluestothefile.Instead,wehaveutilizedthesame methodsthatweusedinthepreviousexercises.Thecodehastwodistinctcomponents: Python-ArduinointerfacingandstoringdatatoaCSVfile.Byskippingtheexplanationof pyFirmatamethodstointerfacetheArduinoboard,let’sfocusonthecodethatis associatedwithstoringthesensordata.ThefirstlinethatwewillwritetotheCSVfile usingwriterow()istheheaderlinethatexplainsthecontentofthecolumns: w.writerow(["Number","Potentiometer","Motionsensor"]) Later,wewillobtainthereadingsfromthesensorsandwritethemtotheCSVfile,as showninthefollowingcodesnippet.Wewillrepeatthisprocess25timesasdefinedby thevariable,i.Youcanchangethevalueofiaccordingtoyourrequirements. whilei<25: sleep(1) ifpirDataisnotNone: i+=1 row=[i,potData,pirData] w.writerow(row) Thenextquestionishowcanyouutilizethiscodingexerciseinyourcustomprojects?The programhasthreemainsectionsthatcanbecustomizedtoaccomplishyourproject requirements,whichareasfollows: Arduinopins:YoucanchangetheArduinopinnumbersandthenumberofpinsto beutilized.Youcandothisbyaddingadditionalsensorvaluestotherowobject. TheCSVfile:Thenameofthefileanditslocationcanbechangedfrom SensorDataStore.csvtotheonethatisspecifictoyourapplication. Thenumberofdatapoints:Wehavecollected25differentpairsofdatapoints whilerunningthewhileloopfor25iterations.Youcanchangethisvalue.Youcan alsochangethetimedelaybetweeneachsuccessivepointfromonesecond,asused intheprogram,tothevaluethatyouneed. Gettingstartedwithmatplotlib ThematplotliblibraryisoneofthemostpopularandwidelysupportedPythonplotting libraries.AlthoughmatplotlibisinspiredbyMATLAB,itisindependentofMATLAB. SimilartootherPythonlibrariesthatwehavebeenusing,itisanopensourcePython library.Thematplotliblibraryassistsincreating2Dplotsfromsimplelinesofcodefrom easytousebuilt-infunctionsandmethods.Thematplotliblibraryisextensivelyusedin Python-basedapplicationsfordatavisualizationandanalysis.ItutilizesNumPy(theshort formofnumericalPython)andSciPy(shortformofscientificPython)packagesfor mathematicalcalculationsfortheanalysis.Thesepackagesaremajordependenciesfor matplotlibincludingfreetypeandpyparsing.Makesurethatyouhavethesepackages preinstalledonyoursystemifyouareusinganyotherinstallationmethodsbesidesthe onesmentionedinthenextsection.Youcanobtainmoreinformationaboutthe matplotliblibraryfromitsofficialwebsite(http://matplotlib.org/). ConfiguringmatplotlibonWindows BeforeweinstallmatplotlibonWindows,makesurethatyouhaveyourWindows operatingsystemwiththelatestversionofPython2.xdistribution.InChapter1,Getting StartedwithPythonandArduino,weinstalledSetuptoolstodownloadandinstall additionalPythonpackages.MakesurethatyouhaveSetuptoolsinstalledandconfigured properly.Beforeweadvancefurther,wewillhavetoinstalldependenciesformatplotlib. Openthecommandpromptandusethefollowingcommandtoinstallthedateutiland pyparsingpackages: >easy_install.exepython_dateutil >easy_install.exepyparsing Onceyouhavesuccessfullyinstalledthesepackages,downloadandinstallthe precompiledNumPypackagefromhttp://sourceforge.net/projects/numpy/.Makesurethat youchoosetheappropriateinstallationfilesforPython2.7andthetypeofyourWindows operatingsystem. Now,yourcomputershouldhavesatisfiedalltheprerequisitesformatplotlib.Download andinstalltheprecompiledmatplotlibpackagefrom http://matplotlib.org/downloads.html. Inthisinstallationprocess,wehaveavoidedtheusageofSetuptoolsforNumPyand matplotlibbecauseofsomeknownissuesrelatedtomatplotlibintheWindows operatingsystem.IfyoucanfigureoutwaystoinstallthesepackagesusingSetuptools, thenyoucanskiptheprecedingmanualsteps. ConfiguringmatplotlibonMacOSX InstallationofmatplotlibonMacOSXcanbedifficultdependingupontheversionof MacOSXandtheavailabilityofdependencies.MakesurethatyouhaveSetuptools installedasdescribedinChapter1,GettingStartedwithPythonandArduino.Assuming thatyoualreadyhaveSetuptoolsandpip,runthefollowingcommandontheterminal: $sudopipinstallmatplotlib Executingthiscommandwillleadtooneofthefollowingthreepossibilities: Successfulinstallationofthelatestmatplotlibversion Notificationthattherequirementsarealreadysatisfiedbuttheinstalledversionis olderthanthecurrentversion,whichis1.3atthemoment Errorwhileinstallingthematplotlibpackage Ifyouencounterthefirstpossibility,thenyoucanadvancetothenextsection;otherwise followthetroubleshootinginstructions.Youcancheckyourmatplotlibversionusingthe followingcommandsonthePythoninteractiveprompt: >>>importmatplotlib >>>matplotlib.__version__ Upgradingmatplotlib Ifyouencounterthesecondpossibility,whichstatesthattheexistingversionofthe matplotlibisolderthanthecurrentversion,usethefollowingcommandtoupgradethe matplotlibpackage: $sudopipinstall–-upgradematplotlib Gothroughthenextsectionincaseyouendupwitherrorsduringthisupgrade. Troubleshootinginstallationerrors Ifyouencounteranyerrorsduringthematplotlibinstallationviapip,itismostlikely thatyouaremissingsomedependencypackages.Followthesestepsonebyoneto troubleshoottheerrors. Tip Aftereverystep,useoneofthefollowingcommandstocheckwhethertheerroris resolved: $sudopipinstallmatplotlib $sudopipinstall–-upgradematplotlib 1. InstallXcodefromApple’sAppStore.OpenXcodeandnavigatetotheDownload tabinPreferences….DownloadandinstallCommandLineToolsfrom Preferences….Thisstepshouldsolveanycompilation-relatederrors. 2. Installhomebrewusingthefollowingcommandintheterminal: $ruby-e"$("$(curl-fsSL https://raw.github.com/Homebrew/homebrew/go/install)")" 3. Installthefollowingpackagesusinghomebrew: $brewinstallfreetype $brewinstallpkg-config Ifyoustillreceiveanerrorwiththefreetypepackage,trytocreatealinkfor freetypeusingthefollowingcommand: $brewlinkfreetype $ln-s/usr/local/opt/freetype/include/freetype2 /usr/local/include/freetype Ifyoureceiveanyfurthererrorsafterperformingtheprecedingsteps,gotothe matplotlibforumsathttp://matplotlib.1069221.n5.nabble.com/forthosespecific errors. Note IfyouusematplotlibinMacOSX,youneedtosetuptheappropriatedrawing backendasshowninthefollowingcodesnippet: importmatplotlib matplotlib.use('TkAgg''') Youcanlearnmoreaboutdrawingbackendsformatplotlibat http://matplotlib.org/faq/usage_faq.html#what-is-a-backend. SettingupmatplotlibonUbuntu Theinstallationofmatplotlibandtherequireddependenciesisaverystraightforward processonUbuntu.WecanperformthisoperationwithoutusingSetuptoolsandwiththe helpoftheUbuntupackagemanager.Thefollowingsimplecommandshoulddothetrick foryou: $sudoapt-getinstallpython-matplotlib Whenpromptedtoselectdependencies,clickonYestoinstallthemall.Youshouldbe abletofindthematplotlibpackageinotherpopularLinuxdistributionstoo. Plottingrandomnumbersusing matplotlib Thematplotliblibraryprovidesacollectionofbasicplotting-relatedfunctionsand methodsviathepyplotframework.Thepyplotframeworkcontainsfunctionsforcreating figures,drawingplots,settinguptitles,settingupaxes,andmanyadditionalplotting methods.Oneoftheimportfunctionsprovidedbypyplotisfigure().Thisinitializesan emptyfigurecanvasthatcanbeselectedforyourplotorasetofplots: fig1=pyplot.figure(1) Youcansimilarlycreatemultiplefiguresbyspecifyinganumberastheparameter,thatis, figure(2).Ifafigurewiththisnumberalreadyexists,themethodactivatestheexisting figurethatcanthenbefurtherusedforplotting. Thematplotliblibraryprovidestheplot()methodtocreatelinecharts.Theplot() methodtakesalistoranarraydatastructurethatismadeupofintegerorfloatingpoint numbersasinput.Iftwoarraysareusedasinputs,plot()utilizesthemasvaluesforthex axisandtheyaxis.Ifonlyonelistorarrayisprovided,plot()assumesittobethe sequencevaluesfortheyaxisandusesauto-generatedincrementalvaluesforthexaxis: pyplot.plot(x,y) Thethirdoptionalparameterthatissupportedbytheplot()methodisfortheformat string.Theseparametershelpuserstochangethestyleoflineandmarkerswithdifferent colors.Inourexample,weareusingthesolidlinestyle.So,theplot()functionforour plotlookslikethis: pyplot.plot(x,y,'-') Theplot()functionprovidesaselectionfromalargecollectionofstylesandcolors.To findmoreinformationabouttheseparameters,usePython’shelp()functiononthe plot()functionofmatplotlib: >>>importmatplotlib >>>help(matplotlib.pyplot.plot) Thishelp()functionwillprovidethenecessaryinformationtocreateplottingstyleswith differentmarkers,linestyles,andcolors.Youcanexitthishelpmenubytypingqatthe prompt. Now,aswehaveexploredplottingsufficiently,let’screateyourfirstPythonplotusingthe followingcodesnippet.Theprogramcontainingthiscodeisalsolocatedinthischapter’s codefolderwiththenameplotBasic.py: frommatplotlibimportpyplot importrandom x=range(0,25) y=[random.randint(0,100)forrinrange(0,25)] fig1=pyplot.figure() pyplot.plot(x,y,'-') pyplot.title('FirstPlot-Randomintegers') pyplot.xlabel('XAxis') pyplot.ylabel('YAxis') pyplot.show() Inthepreviousexercise,werandomlygeneratedadatasetfortheyaxisusingthe randint()method.Youcanseeaplotdepictingthisdatawiththesolidlinestyleinan openedwindowafterrunningtheprogram.Asyoucanseeinthecodesnippet,weused theadditionalpyplotmethodssuchastitle(),xlabel(),ylabel(),andplot().These methodsareself-explanatoryandtheyarelargelyusedtomakeyourplotsmore informativeandmeaningful. Atendoftheexample,weusedoneofthemostimportantpyplotmethodscalledshow(). Theshow()methoddisplaysthegeneratedplotsinafigure.Thismethodisnotmandatory todisplayfigureswhenrunningfromPython’sinteractiveprompt.Thefollowing screenshotillustratestheplotofrandomlygeneratedvaluesusingmatplotlib: PlottingdatafromaCSVfile Atthebeginningofthechapter,wecreatedaCSVfilefromArduinodata.Wewillbe usingthatSensorDataStore.csvfileforthissection.Ifyourecall,weusedtwodifferent sensorstologthedata.Hence,wehavetwoarraysofvalues,onefromadigitalsensorand anotherfromtheanalogone.Now,inthepreviousexample,wejustplottedonesetof valuesfortheyaxis.So,howarewegoingtoplottwoarraysseparatelyandina meaningfulway? Let’sstartbycreatinganewPythonprogramusingthefollowinglinesofcodeorby openingtheplotCSV.pyfilefromthischapter’scodefolder: importcsv frommatplotlibimportpyplot i=[] mValues=[] pValues=[] withopen('SensorDataStore.csv','r')asf: reader=csv.reader(f) header=next(reader,None) forrowinreader: i.append(int(row[0])) pValues.append(float(row[1])) ifrow[2]=='True': mValues.append(1) else: mValues.append(0) pyplot.subplot(2,1,1) pyplot.plot(i,pValues,'-') pyplot.title('Lineplot-'+header[1]) pyplot.xlim([1,25]) pyplot.xlabel('XAxis') pyplot.ylabel('YAxis') pyplot.subplot(2,1,2) pyplot.bar(i,mValues) pyplot.title('Barchart-'+header[2]) pyplot.xlim([1,25]) pyplot.xlabel('XAxis') pyplot.ylabel('YAxis') pyplot.tight_layout() pyplot.show() Inthisprogram,wehavecreatedtwoarraysofsensorvalues—pValuesandmValues—by readingtheSensorDataStore.csvfilerowbyrow.Here,pValuesandmValuesrepresent thesensordataforthepotentiometerandthemotionsensorrespectively.Oncewehad thesetwolists,weplottedthemusingthematplotlibmethods. Thematplotliblibraryprovidesvariouswaystoplotdifferentarraysofvalues.Youcan individuallyplotthemintwodifferentfiguresusingfigure(),thatis,figure(1)and figure(2),orplotbothinasingleplotinwhichtheyoverlayeachother.Thepyplot methodalsooffersathirdmeaningfulalternativebyallowingmultipleplotsinasingle figureviathesubplot()method: pyplot.subplot(2,1,1) Thismethodisstructuredassubplot(nrows,ncols,plot_number),whichcreatesgrids onthefigurecanvasusingrowandcolumnnumbers,thatis,nrowsandncols respectively.Thismethodplacestheplotonthespecificcellthatisprovidedbythe plot_numberparameter.Forexample,throughsubplot(2,1,1),wecreatedatableof tworowsandonecolumnandplacedthefirstsubplotinthefirstcellofthetable. Similarly,thenextsetofvalueswasusedforthesecondsubplotandwasplacedinthe secondcell,thatis,row2andcolumn1: pyplot.subplot(2,1,2) Inthefirstsubplot,wehaveusedtheplot()methodtocreateaplotusingtheanalog valuefromthepotentiometer,thatis,pValues.Whileinthesecondsubplot,wecreateda barchartinsteadofalinecharttodisplaythedigitalvaluesfromthemotionsensor.The barchartfunctionalitywasprovidedbythebar()method. Asyoucanseeinthecodesnippet,wehaveutilizedanadditionalpyplot()methodcalled xlim().Thexlim([x_minimum,x_maximum])orylim([y_minimum,y_maximum]) methodsareusedtoconfinetheplotbetweenthegivenmaximumandminimumvaluesof theparticularaxes. Beforewedisplayedthesesubplotsinthefigureusingtheshow()method,weusedthe tight_layout()functiontoorganizethetitleandlabeltextsinthefigure.The tight_layout()functionisaveryimportantmatplotlibmodulethatnicelyfitthe subplotparametersinonefigure.Youcanchecktheeffectsofthismodulebycommenting thatlineandrunningthecodeagain.Thefollowingscreenshotshowsthesesubplotswith labelsandatitleinonefigureobject: Plottingreal-timeArduinodata Inthepreviouschapter,whiledealingwithGUIandArduinodata,youmusthavenoticed thatthecodewasupdatingtheinterfacewitheverynewvaluethatwasobtainedfromthe Arduinosensors.Similarly,inthisexercise,wewillberedrawingtheploteverytimewe receivenewvaluesfromArduino.Basically,wewillbeplottingandupdatingareal-time chartinsteadofplottingtheentiresetofsensorvaluesaswedidinthepreviousexercise. WewillbeusingthesameArduinocircuitthatyoubuiltinthepreviousexercises.Here, wewillutilizeonlythepotentiometersectionofthecircuittoobtaintheanalogsensor values.Now,beforeweexplainthenewmethodsusedinthisexercise,let’sfirstopenthe programfileforthisexercise.Youcanfindtheprogramfilefromthischapter’sfolder;itis namedplotLive.py.Inthecode,changetheappropriateparametersfortheArduino boardandexecutethecode.Whilethecodeisrunning,rotatetheknobofthe potentiometertoobservethereal-timechangesintheplot. Onrunningtheprogram,youwillgetascreensimilartothefollowingscreenshotthat showsaplotfromreal-timeArduinodata. Onecanmakevariousconclusionsaboutthepotentiometer’sknobrotationorsomeother sensorbehaviorbyjustlookingattheplot.Thesetypesofplotsarewidelyusedinthe graphicaldashboardforreal-timemonitoringapplications.Now,let’strytounderstandthe methodsthatareusedinthefollowingcodesnippettomakethispossible. importsys,csv frommatplotlibimportpyplot importpyfirmata fromtimeimportsleep importnumpyasnp #AssociateportandboardwithpyFirmata port='/dev/cu.usbmodemfa1321'' board=pyfirmata.Arduino(port) #Usingiteratorthreadtoavoidbufferoverflow it=pyfirmata.util.Iterator(board) it.start() #Assignaroleandvariabletoanalogpin0 a0=board.get_pin(''a:0:i'') #Initializeinteractivemode pyplot.ion() pData=[0]*25 fig=pyplot.figure() pyplot.title(''Real-timePotentiometerreading'') ax1=pyplot.axes() l1,=pyplot.plot(pData) pyplot.ylim([0,1]) #real-timeplottingloop whileTrue: try: sleep(1) pData.append(float(a0.read())) pyplot.ylim([0,1]) delpData[0] l1.set_xdata([iforiinxrange(25)]) l1.set_ydata(pData)#updatethedata pyplot.draw()#updatetheplot exceptKeyboardInterrupt: board.exit() break Thereal-timeplottinginthisexerciseisachievedbyusingacombinationofthepyplot functionsion(),draw(),set_xdata(),andset_data().Theion()methodinitializesthe interactivemodeofpyplot.Theinteractivemodehelpstodynamicallychangethexandy valuesoftheplotsinthefigure: pyplot.ion() OncetheinteractivemodeissettoTrue,theplotwillonlybedrawnwhenthedraw() methodiscalled. JustlikethepreviousArduinointerfacingexercises,atthebeginningofthecode,we initializedtheArduinoboardusingpyFirmataandthesetuppinstoobtainthesensor values.Asyoucanseeinthefollowinglineofcode,aftersettinguptheArduinoboard andpyplotinteractivemode,weinitializedtheplotwithasetofblankdata,0inourcase: pData=[0]*25 Thisarrayforyvalues,pData,isthenusedtoappendvaluesfromthesensorinthewhile loop.Thewhileloopkeepsappendingthenewestvaluestothisdataarrayandredrawsthe plotwiththeseupdatedarraysforthexandyvalues.Inthisexample,weareappending newsensorvaluesattheendofthearraywhilesimultaneouslyremovingthefirstelement ofthearraytolimitthesizeofthearray: pData.append(float(a0.read())) delpData[0] Theset_xdata()andset_ydata()methodsareusedtoupdatethexandyaxesdatafrom thesearrays.Theseupdatedvaluesareplottedusingthedraw()methodoneachiteration ofthewhileloop: l1.set_xdata([iforiinxrange(25)]) l1.set_ydata(pData)#updatethedata pyplot.draw()#updatetheplot Youwillalsonoticethatweareutilizinganxrange()functiontogeneratearangeof valuesaccordingtotheprovidedlength,whichis25inourcase.Thecodesnippet,[ifor iinxrange(25)],willgeneratealistof25integernumbersthatstartincrementallyat0 andendat24. IntegratingplotsintheTkinterwindow DuetothepowerfulintegrationcapabilitiesofPython,itisveryconvenienttointerface theplotsgeneratedbythematplotliblibrarywiththeTkintergraphicalinterface.Inthe lastexerciseofthepreviouschapter,weintegratedTkinterwithpyFirmatatoimplement theprojectofChapter3,TheFirstProject–Motion-triggeredLEDs,withtheGUI.Inthis exercise,wewillextendthisintegrationfurtherbyutilizingmatplotlib.Wewillperform thisactionbyutilizingthesameArduinocircuitthatwehavebeenusinginthischapter andexpandthecodethatweusedinthepreviousexercise.Meanwhile,wearenot introducinganynewmethodsinthisexercise;insteadwewillbeutilizingwhatyou learneduntilnow.OpentheplotTkinter.pyfilefromthischapter’scodefolder. Asmentionedearlier,theprogramutilizesthreemajorPythonlibrariesandinterfacesthem witheachothertodevelopanexcellentPython-Arduinoapplication.Thefirstinterfacing pointisbetweenTkinterandmatplotlib.Asyoucanseeinthefollowinglinesofcode, wehaveinitializedthreebuttonobjects,startButton,pauseButton,andexitButton,for theStart,Pause,andExitbuttonsrespectively: startButton=Tkinter.Button(top, text="Start", command=onStartButtonPress) startButton.grid(column=1,row=2) pauseButton=Tkinter.Button(top, text="Pause", command=onPauseButtonPress) pauseButton.grid(column=2,row=2) exitButton=Tkinter.Button(top, text="Exit", command=onExitButtonPress) exitButton.grid(column=3,row=2) TheStartandExitbuttonsprovidecontrolpointsformatplotliboperationssuchas updatingtheplotandclosingtheplotthroughtheirrespectiveonStartButtonPress()and onExitButtonPress()functions.TheonStartButtonPress()functionalsoconsistsof theinterfacingpointbetweenthematplotlibandpyFirmatalibraries.Asyoucanobserve fromthefollowingcodesnippet,wewillstartupdatingtheplotusingthedraw()method andtheTkinterwindowusingtheupdate()methodforeachobservationfromtheanalog pina0,whichisobtainedusingtheread()method: defonStartButtonPress(): whileTrue: ifflag.get(): sleep(1) pData.append(float(a0.read())) pyplot.ylim([0,1]) delpData[0] l1.set_xdata([iforiinxrange(25)]) l1.set_ydata(pData)#updatethedata pyplot.draw()#updatetheplot top.update() else: flag.set(True) break TheonExitButtonPress()functionimplementstheexitfunctionasdescribedbythe nameitself.ItclosesthepyplotfigureandtheTkinterwindowbeforedisengagingthe Arduinoboardfromtheserialport. Now,executetheprogramaftermakingtheappropriatechangestotheArduinoport parameter.Youshouldbeabletoseeawindowonyourscreenthatissimilartotheone displayedinthefollowingscreenshot.Withthiscode,youcannowcontrolyourreal-time plotsusingtheStartandPausebuttons.ClickontheStartbuttonandstartrotatingthe potentiometerknob.WhenyouclickonthePausebutton,youcanobservethatthe programhasstoppedplottingnewvalues.WhilePauseispressed,evenrotatingtheknob willnotresultinanyupdatestotheplot. AssoonasyouclickontheStartbuttonagain,youwillagainseetheplotgetupdated withreal-timevalues,discardingthevaluesgeneratedwhilepaused.ClickontheExit buttontosafelyclosetheprogram: Summary Inthischapter,weintroducedtwomajorPythonprogrammingparadigms:creating, reading,andwritingfilesusingPythonwhilealsostoringdataintothesefilesandplotting sensorvaluesandupdatingplotsinrealtime.Wealsoexploredmethodstostoreandplot real-timeArduinosensordata.BesideshelpingyouinyourArduinoprojects,these methodscanalsobeusedinyoureverydayPythonprojects.Throughoutthechapter,using simpleexercises,weinterfacedthenewlylearnedCSVandmatplotlibmoduleswiththe TkinterandpyFirmatamodulesthatwelearnedinthepreviouschapters.Inthenext chapter,youwillbeintroducedtoyoursecondproject—aportableunitthatmeasuresand displaysenvironmentaldatasuchastemperature,humidity,andambientlight.Wewillbe utilizingtheconceptsthatwehavelearnedsofartobuildthisproject. Chapter7.TheMidtermProject–a PortableDIYThermostat AfterthefirstPython-Arduinoproject,youlearnedtheprocessofprototypingvarious sensors,developinguserinterfaces,andplottingsensordata.Theconceptsthatyou learnedinthepreviouschapterscanbeutilizedtocreateawidevarietyofArduino-based hardwareprojects.Theinceptionofagoodapplicationconceptalwaysbeginswitharealworldnecessityandendsupasapracticalprojectifitisexecutedproperly.Inthischapter, wewilldemonstratethisproject-buildingprocesswithanexampleofaportablesensor unit.Asyoucanestimatefromthechaptertitle,wewillbebuildingasimpleandportable DIYthermostatthatcanbedeployedwithoutadesktopcomputeroralaptop. Tobeginwith,wewilldescribetheproposedthermostatwithspecificgoalsandprocesses toachievethem.Oncethestrategytoachievethesegoalshasbeenlaiddown,youwillbe introducedtothetwosuccessiveprogrammingstagestodevelopthedeployableand portableunit.Inthefirststage,wewillutilizeatraditionalcomputertosuccessfully developtheprogramtointerfaceArduinowithPython.Inthesecondstage,wewill replacethiscomputerwithaRaspberryPitomakeitportableanddeployable. Thermostat–theprojectdescription Fromthemultipleprojectsthatwecanbuildusingthethingsthatyoulearned,aproject thathelpsyoutomonitoryoursurroundingenvironmentreallystandsoutasanimportant real-worldapplication.Fromthevariousenvironment-monitoringprojectssuchasweather station,thermostat,andplantmonitoringsystem,wewillbedevelopingthethermostatas itfocusesonindoorenvironmentandcanbepartofyourdailyroutine. Thethermostatisoneofthemostimportantcomponentsofanyremotehomemonitoring systemandhomeautomationsystem.Apopularcommercialexampleofaconnected thermostatistheNestThermostat(https://www.nest.com),whichprovidesintelligent remotemonitoringandschedulingfeaturesforyourexistinghome’sheatingandcooling system.Beforewethinkaboutafull-stackproductsuchasNest,weneedfirstneedto buildaDIYthermostatwiththebasicsetoffeatures.Later,wecanbuilduponthisproject byaddingfeaturestoimprovetheDIYthermostatexperience.Let’sfirstoutlinethe featuresthatweareplanningtoimplementinthisversionofthethermostatproject. Projectbackground Temperature,humidity,andambientlightarethethreemainphysicalcharacteristicsthat wewanttomonitorusingthethermostat.Intermsofuserexperience,wewanttohavean elegantuserinterfacetodisplaythemeasuredsensordata.Theuserexperiencecanbe moreresourcefulifanyofthissensordataisplottedasalinegraph.Inthecaseofa thermostat,thevisualrepresentationofthesensordataprovidesamoremeaningful comprehensionoftheenvironmentthanjustdisplayingplainnumericalvalues. Oneofthemajorobjectivesoftheprojectistomakethethermostatportableand deployablesothatitcanbeusedinyourday-to-daylife.Tosatisfythisrequirement,the thermostatdisplayneedstobechangedfromaregularmonitortosomethingsmalland moreportable.Toensureitsreal-worldandmeaningfulapplication,thethermostatshould demonstratereal-timeoperation. Itisimportanttonotethatthethermostatwillnotbeinterfacingwithanyactuatorssuchas homecoolingandheatingsystems.Astheinterfacingofthesesystemswiththethermostat projectrequireshigh-levelunderstandingandexperienceofworkingwithheatingand coolingsystems,itwilldeviatetheflowofthechapterfromitsoriginalgoalofteaching youArduinoandPythonprogramming. Projectgoalsandstages Inordertodescribethefeaturesthatwewanttohaveinthethermostat,let’sfirstidentify thegoalsandmilestonestoachievetheseobjectives.Themajorgoalsfortheprojectcan bedeterminedasfollows: Identifythenecessarysensorsandhardwarecomponentsfortheproject Designandassemblethecircuitforthethermostatusingthesesensorsandthe Arduinoboard Designaneffectiveuserexperienceanddevelopsoftwaretoaccommodatetheuser experience Developandimplementcodetointerfacethedesignedhardwarewiththesoftware components Thecodedevelopmentprocessofthethermostatprojectisdividedintotwomajorstages. Theobjectivesofthefirststageincludesensorinterfacing,thedevelopmentofthe Arduinosketch,andthedevelopmentofthePythoncodeonyourregularcomputerthat youhavebeenusingallalong.Thecodingmilestoneforthefirststagecanbefurther distributedasfollows: DeveloptheArduinosketchtointerfacesensorsandbuttonswhileprovidingoutput ofthesensordatatothePythonprogramviatheserialport DevelopthePythoncodetoobtainsensordatafromtheserialportusingthe pySeriallibraryanddisplaythedatausingGUIthatisdesignedinTkinter Createaplottodemonstratethereal-timehumidityreadingsusingthematplotlib library Inthesecondstage,wewillattachtheArduinohardwaretoasingle-boardcomputeranda miniaturedisplaytomakeitmobileanddeployable.Themilestonetoachieveobjectiveof thesecondstageareasfollows: Installandconfigureasingle-boardcomputer,RaspberryPi,torunthePythoncode fromthefirststage InterfaceandconfiguretheminiaturescreenwiththeRaspberryPi OptimizetheGUIandplotwindowtoadjusttothissmallscreen’sresolution Inthefollowingsubsectionofthissection,youwillbenotifiedaboutthelistofrequired componentsforboththestages,followedbythehardwarecircuitdesignandthesoftware flowdesign.Theprogrammingexercisesforthesestagesareexplainedinthenexttwo sectionsofthechapter. Thelistofrequiredcomponents Insteadofgoingthroughtheprocessofidentifyingtherequiredcomponents,wehave alreadyselectedthecomponentsforthisprojectbasedontheirutilizationintheprevious exercises,easeofuse,andavailability.Youcanreplacethesecomponentsaccordingto theiravailabilityatthetimeyouarebuildingthisprojectoryourfamiliaritywithother sensors.Justmakesurethatyoutakecareofmodificationsinthecircuitconnectionsand code,ifthesenewcomponentsarenotcompatiblewiththeonesthatweareusing. Inthefirststageofprototyping,wewillneedcomponentstodeveloptheelectroniccircuit forthethermostatunit.Aswementionedearlier,wearegoingtomeasuretemperature, humidity,andambientlightthroughourunit.Wealreadylearnedaboutthetemperature sensorTMP102andtheambientlightsensorBH1750inChapter4,DivingintoPythonArduinoPrototyping.Wewillbeusingthesesensorsforthisprojectwiththehumidity sensorHIH-4030.TheprojectwillutilizethesameArduinoUnoboardthatyouhavebeen usingthroughoutthepreviouschapterswiththenecessarycables.Wewillalsoneedtwo pushbuttonstoprovidemanualinputstotheunit.Thesummaryoftherequired componentsforthefirststageisprovidedinthefollowingtable: Component(firststage) Quantity Website ArduinoUno 1 https://www.sparkfun.com/products/11021 USBcableforArduino 1 https://www.sparkfun.com/products/512 Breadboard 1 https://www.sparkfun.com/products/9567 TMP102temperaturesensor 1 https://www.sparkfun.com/products/11931 HIH-4030humiditysensor https://www.sparkfun.com/products/9569 1 BH1750ambientlightsensor 1 http://www.robotshop.com/en/dfrobot-light-sensor-bh1750.html Pushbuttonswitch 2 https://www.sparkfun.com/products/97 1kilo-ohmresistor 2 10kilo-ohmresistor 2 Connectionwires Asrequired Althoughthetableprovideslinksforfewspecificwebsite,youcanobtainthese componentsfromyourpreferredproviders.ThetwomajorcomponentsHIH-4030 humiditysensorandpushbuttonswitchthatwehaven’tusedpreviouslyaredescribedas follows: HIH-4030humiditysensor:Thismeasuresandprovidesrelativehumidityresultsas ananalogoutput.Theoutputofthesensorcanbedirectlyconnectedtoanyanalog pinofArduino.ThefollowingimageshowsthebreakoutboardwiththeHIH-4030 sensorthatissoldbySparkFunElectronics.YoucanlearnmoreabouttheHIH-4030 sensorfromitsdatasheet,whichcanbeobtainedfrom https://www.sparkfun.com/datasheets/Sensors/Weather/SEN-09569-HIH-4030datasheet.pdf: Pushbuttonswitch:Pushbuttonswitchesaresmallswitchesthatcanbeusedona breadboard.Whenpressed,theswitchoutputchangesitsstatustoHIGH,whichis LOWotherwise. Inthesecondstage,wearegoingtomakethesensorunitmobilebyreplacingyour computerwithaRaspberryPi.Forthat,youwillneedthefollowingcomponentstoget started: Component(secondstage) Quantity Image RaspberryPi 1 https://www.sparkfun.com/products/11546 MicroUSBcablewithapower adapter 1 http://www.amazon.com/CanaKit-Raspberry-Supply-AdapterCharger/dp/B00GF9T3I0/ 8GBSDcard 1 https://www.sparkfun.com/products/12998 TFTLCDscreen 1 http://www.amazon.com/gp/product/B00GASHVDU/ AUSBhub Optional Furtherexplanationsofthesecomponentsareprovidedlaterinthechapter. Hardwaredesign Theentirehardwarearchitectureofthethermostatcanbedividedintotwounits,a physicalworldinterfacingunitandacomputationunit.Thephysicalworldinterfacing unit,asitsnameindicates,monitorsphenomenonofthephysicalworldsuchas temperature,humidity,andambientlightusingsensorsconnectedtotheArduinoboard. Thephysicalworldinterfacingunitisinterchangeablymentionedasthethermostatsensor unitthroughoutthechapter.Thecomputationalunitisresponsiblefordisplayingthe sensorinformationviatheGUIandplots. Thefollowingdiagramshowsthehardwarecomponentsforthefirststagewherethe thermostatsensorunitisconnectedtoacomputerusingtheUSBport.Inthethermostat sensorunit,varioussensorcomponentsareconnectedtotheArduinoboardusingI2C, analog,anddigitalpins: Inthesecondprogrammingstagewherewearegoingmakeourthermostatintoamobile anddeployableunit,youwillbeusingasingle-boardcomputer,RaspberryPi,asthe computationaldevice.Inthisstage,wewilluseaminiaturethin-filmtransistorliquidcrystaldisplay(TFTLCD)screenthatisconnectedtoaRaspberryPiviageneralpurposeinput/output(GPIO)pinsandisusedasadisplayunittoreplacethetraditional monitororlaptopscreen.Thefollowingdiagramshowsthisnewthermostatcomputational unit,whichtrulyreducestheoverallsizeofthethermostatandmakesitportableand mobile.CircuitconnectionsfortheArduinoboardareunchangedforthisstageandwe willusethesamehardwarewithoutanymajormodifications. Asthecommonunitforbothstagesoftheproject,theArduino-centricthermostatsensor unitrequiresslightlymorecomplexcircuitconnectionscomparedtootherexercisesthat youhavebeenthrough.Inthissection,wearegoingtointerfacethenecessarysensorsand pushbuttonstotheirrespectivepinsontheArduinoboardandyouwillneedabreadboard tomaketheseconnections.IfyouarefamiliarwithPCBprototyping,youcancreateyour ownPCBboardbysolderingthesecomponentsandavoidthebreadboard.PCBboardsare morerobustcomparedtobreadboardsandlesspronetolooseconnections.Usethe followinginstructionsandtheFritzingdiagramtocompletethecircuitconnections: 1. Asyoucanseeinthefollowingdiagram,connecttheSDAandSCLpinsofTMP102 andBH1750toanalogpins4and5oftheArduinoboardandcreateanI2Cbus.To maketheseconnections,youcanusemultiplecolor-codedwirestosimplifythe debuggingprocess. 2. Usetwo10kilo-ohmpull-upresistorswiththeSDAandSCLlines. 3. ContrarytotheseI2Csensors,theHIH-4030humiditysensorisasimpleanalog sensorandcanbedirectlyconnectedtotheanalogpin.ConnecttheHIH-4030tothe analogpinA0. 4. ConnectVCCandthegroundofTMP102,BH1750,andHIH-4030to+5Vandthe groundoftheArduinoboardusingpowerstripsofthebreadboard,asdisplayedinthe diagram.Werecommendthatyouuseredandblackwirestorepresentthe+5Vand groundlinesrespectively. 5. ThepushbuttonprovidestheoutputasHIGHorLOWstateandinterfacedusing digitalpins.Asdisplayedinthecircuit,connectthesepushbuttonstodigitalpins2 and3usingtwo1kilo-ohmresistors. 6. Completetheremainingconnectionsasdisplayedinthefollowingdiagram.Make surethatyouhavefirmlyconnectedallthewiresbeforepoweringuptheArduino board: Note MakesurethatyoualwaysdisconnectyourArduinoboardfromthepowersourceora USBportbeforemakinganyconnections.Thiswillpreventanydamagetotheboarddue toshortcircuiting. Completealltheconnectionsforthethermostatsensorunitbeforeheadingtothenext section.Asthisunitisbeingusedinboththeprogrammingstages,youwon’tbe performinganyfurtherchangestothethermostatsensorunit. Softwareflowforuserexperiencedesign Oneofthecriticalcomponentsofanyprojectisitsusabilityoraccessibility.Whenyouare workingonmakingyourprojectprototypeintoaproduct,itisnecessarytohavean intuitiveandresourcefuluserinterfacesothattheusercaneasilyinteractwithyour product.Hence,itisnecessarytodefinetheuserexperienceandsoftwareflowofaproject beforeyoustartcoding.Thesoftwareflowincludestheflowchartandthelogical componentsoftheprogramthatarederivedfromtheprojectrequirements.Accordingto thegoalsthatwehavedefinedforthethermostatproject,thesoftwareflowcanbe demonstratedinthefollowingdiagram: Intheimplementation,thesoftwareflowoftheprojectbeginsbymeasuringthe temperature,humidity,andambientlightfromArduinoandprintingthemonaserialport linebyline.ThePythonprogramobtainsthesensordatafromArduinoviatheserialport beforepresentingthedataonthescreen.Meanwhile,thePythonprogramkeepslooking foranewlineofdata. Ausercaninteractwiththethermostatusingapushbutton,whichwilllettheuserchange theunitforthetemperaturedata.Oncethebuttonispressed,theflaggetschangedto HIGHandthetemperatureunitischangedtoCelsiusfromitsdefaultunit,Fahrenheit.If thebuttonispressedagain,theoppositeprocesswillhappenandtheunitwillbechanged backtoitsdefaultvalue.Similarly,anotheruserinteractionpointisthesecondpushbutton thatallowsausertoopenaplotforreal-timehumidityvalues.Thesecondpushbutton alsoutilizesasimilarmethodofusingflagstocapturetheinputandopensanewplot window.Ifthesamebuttonispushedsequentially,theprogramwillclosetheplotwindow. Stage1–prototypingthethermostat Inthisprototypingstage,wewilldeveloptheArduinoandPythoncodeforourthermostat, whichwillbelaterusedinthesecondstagewithminorchanges.Beforeyoustartthe codingexercise,makesurethatyouhavethethermostatsensorunitreadywiththe Arduinoboardandtheconnectedsensors,asdescribedintheprevioussection.Forthis stage,youwillbeusingyourregularcomputerwhichisequippedwiththeArduinoIDE andthePythonprogrammingenvironment.Theprototypingstagerequirestwolevelsof programming,theArduinosketchforthethermostatsensorunitandthePythoncodefor thecomputationalunit.Let’sgetstartedwithcodingforourthermostat. TheArduinosketchforthethermostat ThegoalofthisArduinoprogramistointerfacesensors,getmeasurementsfromthe sensors,andprintthemontheserialport.Aswediscussedearlier,ratherthanusingthe standardFirmatasketchthatweusedinthepreviousproject,wearegoingtodevelopa customArduinosketchinthisproject.Togetstarted,opentheThermostat_Arduino.ino sketchfromthischapter’scodefolder,whichispartofthesourcecodethatyoureceived forthebook. ConnecttheUSBportoftheArduinoboard,whichisnowpartofthethermostatsensor unit,toyourcomputer.SelecttheappropriateboardandportnamesintheArduinoIDE andverifythecode.UploadthecodetoyourArduinoboardandopentheSerialMonitor windowoncethecodeissuccessfullyuploaded.Youshouldbeabletoseetextsimilarto thatdisplayedinthefollowingscreenshot: TheArduinocodestructureandbasicdeclarationsarealreadyexplainedinvarious sectionsthroughoutthebook.Insteadofexplainingtheentirecodelinebyline,wewill focushereonthemaincomponentsofthesoftwareflowthatwedescribedearlier. Interfacingthetemperaturesensor IntheArduinosketch,thetemperaturedataisobtainedfromtheTMP102sensorusingthe getTemperature()function.ThefunctionimplementstheWirelibraryontheI2Caddress ofTMP102toreadthesensordata.Thisisthenconvertedintopropertemperaturevalues: floatgetTemperature(){ Wire.requestFrom(tmp102Address,2); byteMSB=Wire.read(); byteLSB=Wire.read(); //it'sa12bitint,usingtwo'scomplimentfornegative intTemperatureSum=((MSB<<8)|LSB)>>4; floatcelsius=TemperatureSum*0.0625; returncelsius; } ThegetTemperature()functionreturnsthetemperaturevaluesinCelsius,whichisthen senttotheserialport. Interfacingthehumiditysensor Althoughthehumiditysensorprovidestheanalogoutput,itisnotstraightforwardto obtainrelativehumiditysinceitalsodependsuponthetemperature.ThegetHumidity() functioncalculatestherelativehumidityfromtheanalogoutputprovidedbytheHIH4030sensor.Theformulastocalculatetherelativehumidityareobtainedfromthe datasheetandreferenceexamplesofthesensor.Ifyouareusingadifferenthumidity sensor,pleasemakesurethatyouchangetheformulasaccordingly,astheymaychange theresultssignificantly: floatgetHumidity(floatdegreesCelsius){ //caculaterelativehumidity floatsupplyVolt=5.0; //Getthesensorvalue: intHIH4030_Value=analogRead(HIH4030_Pin); //converttovoltagevalue floatvoltage=HIH4030_Value/1023.*supplyVolt; //convertthevoltagetoarelativehumidity floatsensorRH=161.0*voltage/supplyVolt-25.8; floattrueRH=sensorRH/(1.0546-0.0026*degreesCelsius); returntrueRH; } Aswearecalculatingrelativehumidity,thereturnedhumidityvaluesaresenttotheserial portwithpercentageastheunit. Interfacingthelightsensor TointerfacetheBH1750lightsensor,wewillusetheBH1750Arduinolibrary,whichwe usedearlier.Usingthislibrary,theambientlightvaluecanbedirectlyobtainedusingthe followinglineofcode: uint16_tlux=lightMeter.readLightLevel(); Thislineprovidestheluminancevaluesintheunitoflux.Thesevaluesarealsosentto theserialportsothePythonprogramcanutilizeitfurther. UsingArduinointerrupts UntilnowyouusedtheArduinoprogramtoreadthephysicalstateofanI/Opinusingthe DigitalRead()orAnalogRead()functions.Howwouldyouautomaticallyobtainthestate changeinsteadofperiodicallyreadingthepinsandwaitingforthestatetochange? ArduinointerruptsprovideaveryconvenientwayofcapturingsignalsfortheArduino board.Interruptsareaverypowerfulwayofautomaticallycontrollingvariousthingsin Arduino.ArduinosupportsinterruptsusingtheattachInterrupt()method.Intermsof thephysicalpins,ArduinoUnoprovidestwointerrupts:interrupt0(ondigitalpin2)and interrupt1(ondigitalpin3).VariousArduinoboardshavedifferentspecificationsfor interruptpins.IfyouareusinganyboardotherthanUno,pleaserefertoArduino’swebsite tofindoutabouttheinterruptpinforyourboard. TheattachInterrupt()functiontakesthreeinputarguments(pin,ISR,andmode).In theseinputarguments,pinreferstothenumberoftheinterruptpin,ISR(whichstandsfor InterruptServiceRoutine)referstothefunctionthatgetscalledwhentheinterruptoccurs, andmodedefinestheconditionwhentheinterruptshouldbetriggered.Wehaveutilized thisfunctioninourArduinoprogram,asdescribedinthefollowingcodesnippet: attachInterrupt(0,button1Press,RISING); attachInterrupt(1,button2Press,RISING); ThesupportedmodeforattachInterrupt()areLOW,CHANGE,RISING,andFALLING.Inour case,theinterruptsaretriggeredwhenthemodeisRISING,thatis,thepingoesfromlow tohigh.Forinterruptsdeclaredat0and1,wecallthebutton1Pressandbutton2Press functionsthatwillchangeflagTemperatureandflagPlotrespectively.When flagTemperatureissettoHIGH,ArduinosendsthetemperatureinCelsius,otherwiseit sendsthetemperatureinFahrenheit.WhenflagPlotisHIGH,Arduinowillprinttheflag ontheserialport,whichwillbeusedbythePythonprogramlatertoopentheplot window.YoucanlearnmoreaboutArduinointerruptsfromthetutorialat http://arduino.cc/en/Reference/attachInterrupt. DesigningtheGUIandplotinPython Onceyourthermostatsensorunitstartssendingsensordatatotheserialport,itistimeto executethesecondpartofthisstage,thePythoncodefortheGUIandtheplot.Fromthis chapter’scodefolder,openthePythonfilecalledThermostat_Stage1.py.Inthefile,go tothelinethatcontainstheSerial()functionwheretheserialportisdeclared.Change theserialportnamefromCOM5totheappropriateone.Youcanfindthisinformationfrom theArduinoIDE.Savethechangeandexittheeditor.Fromthesamefolder,runthe followingcommandontheterminal: $pythonThermostat_Stage1.py ThiswillexecutethePythoncodeandyouwillbeabletoseetheGUIwindowonthe screen. UsingpySerialtostreamsensordatainyourPythonprogram Asdescribedinthesoftwareflow,theprogramreceivesthesensordatafromtheArduino usingthepySeriallibrary.ThecodethatdeclarestheserialportinthePythoncodeisas follows: Importserial port=serial.Serial('COM5',9600,timeout=1) ItisveryimportanttospecifythetimeoutparameterwhileusingthepySeriallibrary,as thecodemayhaveanerroriftimeoutisnotspecified. DesigningtheGUIusingTkinter TheGUIforthisprojectisdesignedusingtheTkinterlibrarythatweusedearlier.Asa GUI-buildingexercise,threecolumnsoflabels(labelstodisplaythesensortype,the observationvalues,andobservationunits)areprogrammedasshowninthefollowing codesnippet: #Labelsforsensorname Tkinter.Label(top,text="Temperature").grid(column=1,row=1) Tkinter.Label(top,text="Humidity").grid(column=1,row=2) Tkinter.Label(top,text="Light").grid(column=1,row=3) #Labelsforobservationvalues TempLabel=Tkinter.Label(top,text="") TempLabel.grid(column=2,row=1) HumdLabel=Tkinter.Label(top,text="") HumdLabel.grid(column=2,row=2) LighLabel=Tkinter.Label(top,text="") LighLabel.grid(column=2,row=3) #Labelsforobservationunit TempUnitLabel=Tkinter.Label(top,text="") TempUnitLabel.grid(column=3,row=1) HumdUnitLabel=Tkinter.Label(top,text="%") HumdUnitLabel.grid(column=3,row=2) LighUnitLabel=Tkinter.Label(top,text="lx") LighUnitLabel.grid(column=3,row=3) OnceyouinitializethecodeandbeforeyouclickontheStartbutton,youwillbeableto seethefollowingwindow.Theobservationlabelsarepopulatedwithoutanyvaluesatthis stage: OncetheStartbuttonisclicked,theprogramwillengagethethermostatsensorunitand startreadingthesensorvaluesfromtheserialport.Usingthelinesthatareobtainedfrom theserialport,theprogramwillpopulatetheobservationlabelswiththeobtainedvalues. Thefollowingcodesnippetupdatesthetemperaturevaluesintheobservationlabeland alsoupdatesthetemperatureunit: TempLabel.config(text=cleanText(reading[1])) TempUnitLabel.config(text="C") TempUnitLabel.update_idletasks() Intheprogram,weareusingsimilarmethodsforhumidityandambientlighttoupdate theirlabelsrespectively.Asyoucanseeinthefollowingscreenshot,theGUInowhasthe valuesforthetemperature,humidity,andambientlightreadings: TheStartandExitbuttonsareprogrammedtocalltheonStartButtonPress()and onExitButtonPress()functionswhentheyareclickedbytheuser.The onStartButtonPress()functionexecutesthecodenecessarytocreatetheuserinterface, whiletheonExitButtonPress()functionclosesalltheopenedwindows,disconnectsthe thermostatsensorunit,andexitsthecode: StartButton=Tkinter.Button(top, text="Start", command=onStartButtonPress) StartButton.grid(column=1,row=4) ExitButton=Tkinter.Button(top, text="Exit", command=onExitButtonPress) ExitButton.grid(column=2,row=4) YoucanplaywiththeStartandExitbuttonstoexplorethePythoncode.Toobservethe changesinthesensorreadings,trytoblowairorplaceanobstacleoverthethermostat sensorunit.Iftheprogramdoesn’tbehaveappropriately,checktheterminalforerror messages. Plottingpercentagehumidityusingmatplotlib Wewillusethematplotliblibrarytoplottherelativehumidityvaluesinrealtime.We willplottherelativehumidityvaluesinthisproject,astherangeofthedataisfixed between0and100percent.Usingasimilarmethod,youcanalsoplottemperatureand ambientlightsensorvalues.Whiledevelopingthecodetoplottemperatureandambient lightsensordata,makesurethatyouareusingappropriaterangestocoverthesensordata inthesameplot.Now,aswehavespecifiedintheonStartButtonPress()function,a windowsimilartothefollowingscreenshotwillpopuponceyoupressthepushbuttonfor theplot: Thefollowingcodesnippetisresponsibleforplottingthelinechartusingthehumidity sensorvalues.Thevaluesarelimitedbetween0and100ontheyaxis,wheretheyaxis representstherelativehumidityrange.Theplotisupdatedeverytimetheprogram receivesanewhumidityvalue: pyplot.figure() pyplot.title('Humidity') ax1=pyplot.axes() l1,=pyplot.plot(pData) pyplot.ylim([0,100]) Usingbuttoninterruptstocontroltheparameters Thepushbuttoninterruptsareacriticalpartoftheuserexperience,astheusercancontrol thetemperatureunitandtheplotusingtheseinterrupts.ThePythonfeaturesimplemented usingthepushbuttoninterruptsareasfollows. Changingthetemperatureunitbypressingabutton TheArduinosketchcontainsthelogictohandleinterruptsfrompushbuttonsandusethem tochangethetemperatureunit.Whenaninterruptoccurs,insteadofprintingthe temperatureinFahrenheit,itsendsthetemperatureinCelsiustotheserialport.Asyoucan seeinthefollowingscreenshot,thePythoncodejustprintstheobtainednumericvalueof thetemperatureobservationandtheassociatedunitofmeasurementwithit: Asyoucanseeinthefollowingcodesnippet,ifthePythoncodereceivesthe Temperature(C)string,itprintsthetemperatureinCelsius,andifitreceivesthe Temperature(F)string,itprintsthetemperatureinFahrenheit: if(reading[0]=="Temperature(C)"): TempLabel.config(text=cleanText(reading[1])) TempUnitLabel.config(text="C") TempUnitLabel.update_idletasks() if(reading[0]=="Temperature(F)"): TempLabel.config(text=cleanText(reading[1])) TempUnitLabel.config(text="F") TempUnitLabel.update_idletasks() SwappingbetweentheGUIandtheplotbypressingabutton IfthePythoncodereceivesthevalueoftheflagfromtheserialportas1(HIGH),it createsanewplotanddrawsthehumidityvaluesasalinechart.However,itclosesany openplotsifitreceives0(LOW)asthevalueoftheflag.Asyoucanseeinthefollowing codesnippet,theprogramwillalwaystrytoupdatetheplotwiththelatestvaluesfor humidityreadings.Iftheprogramcan’tfindanopenedplottodrawthisvaluefrom,itwill createanewplot: if(reading[0]=="Flag"): printreading[1] if(int(reading[1])==1): try: l1.set_xdata(np.arange(len(pData))) l1.set_ydata(pData)#updatethedata pyplot.ylim([0,100]) pyplot.draw()#updatetheplot except: pyplot.figure() pyplot.title('Humidity') ax1=pyplot.axes() l1,=pyplot.plot(pData) pyplot.ylim([0,100]) if(int(reading[1])==0): try: pyplot.close('all') l1=None except: Bynow,youshouldhaveacompleteideaabouttheprogramsthatarerequiredbythe thermostatsensorunitandthecomputationunit.Duetothecomplexityinvolved,youmay faceafewknownproblemsduringtheexecutionoftheseprograms.Youcanrefertothe Troubleshootingsectionincaseyourunintoanytrouble. Troubleshooting Herearesomeoftheerrorsthatyoumayfind,andtheirfixes: I2Csensorreturnstheerrorstring: ChecktheconnectionstotheSDAandSCLpins. Confirmthatyouareprovidingenoughdelaybetweenthereadingcyclesofthe sensor.Checkthedatasheetforthedelayandmessagesequence. Theplotwindowflickersinsteadofstayingonwhenthebuttonispressed: Don’ttrytopressitmultipletimes.Holdandletgoquickly.Makesurethatyour buttonisconnectedproperly. AdjustthedelayintheArduinosketch. Stage2–usingaRaspberryPiforthe deployablethermostat WehavenowcreatedathermostatthatexistsasanArduinoprototypewhilethePython programrunsfromyourcomputer.Thisprototypeisstillnowherenearadeployableor mobilestateduetotheconnectedcomputer,andthedisplaymonitorifyouareusinga desktopcomputer.Areal-worldthermostatdeviceshouldhaveasmallfootprint,portable size,andminiaturedisplaytoshowlimitedinformation.Thepopularandpracticalwayto achievethisgoalistouseasmallsingle-boardcomputerthatiscapableofhostingan operatingsystemandhenceprovidingtheessentialPythonprogramminginterface.For thisstageoftheproject,wewillbeutilizingasingle-boardcomputer—aRaspberryPi— withasmallLCDdisplay. Note Notethatthisstageoftheprojectisoptionalunlessyouwanttoextendthepreviousstage oftheprojecttoadevicethatcanbeusedonaregularbasis.Ifyouarereferringtothe projecttojustlearnPythonprogramming,youcanskipthisentiresection. ThefollowingisanimageoftheRaspberryPiModelB: Ifyouhaven’tworkedwithasingle-boardcomputerbefore,youmayhavealotof unansweredquestions,suchas“WhatexactlydoesaRaspberryPiconsistsof?”,“What arethebenefitsofusingaRaspberryPiinourproject?”,and“Can’twejustuseArduino forthat?”.Thesearelegitimatequestionsandwewilltrytoanswertheminthefollowing section. WhatisaRaspberryPi? TheRaspberryPiisasmall(almostthesizeofacreditcard)single-boardcomputerthat wasdevelopedwiththeinitialaimofhelpingstudentslearnthebasicsofcomputer science.Today,theRaspberryPimovement,guidedbytheRaspberryPiFoundation,has turnedintoaDIYphenomenonandcapturedtheattentionofenthusiastsanddevelopers aroundtheworld.ThecapabilitiesandfeaturesshippedwithaRaspberryPiatanominal cost($35)haveboostedthepopularityofthedevice. Thetermsingle-boardcomputerisusedfordevicesthathaveallthenecessary componentstorunanoperatingsystemononeboard,suchasaprocessor,RAM,graphics processor,storagedevice,andbasicadaptorsforexpansion.Thismakesasingle-board computeranappropriatecandidateforportableapplications,astheycanbepartofthe portablehardwaredevicethatwearetryingtocreate.Althoughtherewereanumberof single-boardcomputersinthemarketbeforetheintroductionoftheRaspberryPi,theopen sourcenatureofthehardwareandtheeconomicalpricearethemainreasonsbehindthe popularityandrapidadoptionoftheRaspberryPi.Thefollowingfigureshowsthe RaspberryPiModelBwithitsmajorcomponents: ThecomputationalcapabilitiesoftheRaspberryPiareadequateforrunningatrimmed downversionofLinuxOS.Althoughpeoplehadtriedtousemanytypesofoperating systemsonaRaspberryPi,wewillbeusingthedefaultandrecommendedoperating systemcalledRaspbian.RaspbianisaDebiandistribution-basedopensourceLinuxOS, whichisoptimizedfortheRaspberryPi.TheRaspberryPiusesanSDcardasthestorage device,whichwillbeusedtostoreyourOSandprogramfiles.InRaspbian,youcanavoid runningtheunnecessaryOScomponentsthatareshippedwithtraditionalOSes.These includetheInternetbrowser,communicationapplication,andinsomecaseseventhe graphicalinterface. Afteritsintroduction,theRaspberryPihasgonethroughafewmajorupgrades.The earlierversion,calledModelA,didnotincludetheEthernetportandonlyhadamemory of256MB.Inourproject,weareusingtheRaspberryPi’sModelBthathasadedicated Ethernetport,512MBmemory,anddualUSBports.ThelatestversionsofRaspberryPi, ModelB+,canbealsousedasitisalsoequippedwithanEthernetport. Installingtheoperatingsystemandconfiguringthe RaspberryPi AlthoughtheRaspberryPiisacomputer,itisdifferentthantraditionaldesktopcomputers whenitcomestointerfacingperipheraldevices.InsteadofsupportingtraditionalVGAor DVIdisplayports,theRaspberryPiprovidesaRCAvideoportforTVsandanHDMIport forthelatestgenerationofmonitorsandTVs.Inaddition,theRaspberryPihasonlytwo USBportsthatneedtobeutilizedforconnectingvariousperipheraldevicessuchasthe mouse,thekeyboard,theUSBwirelessadapter,andtheUSBmemorystick.Let’sget startedbycollectingcomponentsandcablestostartworkingwithaRaspberryPi. WhatdoyouneedtobeginusingtheRaspberryPi? ThehardwarecomponentsrequiredtogetstartedwithaRaspberryPiareasfollows: ARaspberryPi:Forthisstageoftheproject,youwillneedaRaspberryPiversion ModelBorlatest.YoucanbuytheRaspberryPifrom http://www.raspberrypi.org/buy. Apowercable:TheRaspberryPirunson5VDCandrequiresatleast750mA current.ThepowerisappliedthroughthemicroUSBportthatislocatedonthe board.Inthisproject,youwillneedamicroUSBpowersupply.Optionally,youcan useamicroUSB-basedphonechargertosupplypowertotheRaspberryPi. Adisplaycable:IfyouhaveanHDMImonitororaTV,youcanuseanHDMIcable toconnectittoyourRaspberryPi.IfyouwanttouseyourVGAorDVI-based monitor,youwillneedaVGAtoHDMIorDVItoHDMIadapterconverter.Youcan buytheseadapterconvertersfromAmazonorBestBuy. AnSDcard:Youarerequiredtohaveatleastan8GBSDcardtogetstarted.Itis preferabletouseanSDcardthathasaqualityofclass4orbetter.Youcanalsobuy anSDcardwiththepreinstalledOSat http://swag.raspberrypi.org/collections/frontpage/products/noobs-8gb-sd-card. Note TheRaspberryPiModelB+requiresamicroSDcardinsteadofaregularSDcard. Amouseandkeyboard:YouwillneedastandardUSBkeyboardandaUSBmouse toworkwiththeRaspberryPi. AUSBhub(optional):SincetheModelBhasjusttwoUSBports,youwillhaveto removeexistingdevicesfromtheUSBportstomakespaceforanotherdeviceifyou wanttoconnectaWi-Fiadapterormemorysticktoit.AUSBhubcanbehandyto attachmultipleperipheralcomponentstoyourRaspberryPi.Werecommendthatyou useaUSBhubwithexternalpowersupply,astheRaspberryPicandrivealimited numberofperipheraldevicesthroughtheUSBportsduetopowerlimitations. PreparinganSDcard ToinstallandconfiguresoftwarecomponentssuchasPythonandtherequiredlibraries, firstweneedanoperatingsystemfortheRaspberryPi.ARaspberryPiofficiallysupports Linux-basedopensourceoperatingsystemsthatarepreconfiguredforcustomRaspberry Pihardwarecomponents.Variousversionsoftheseoperatingsystemsareavailableon RaspberryPi’swebsite(http://www.raspberrypi.org/downloads). RaspberryPi’swebsiteprovidesavarietyofOSesforuserswhorangefromnewbiesto experts.Itisdifficultforafirst-timeusertoidentifytheappropriateOSanditsinstallation process.IfthisisyourfirstattemptwithaRaspberryPi,werecommendthatyouusethe NewOutOfBoxSoftware(NOOBS)package.DownloadthelatestversionofNOOBS fromthepreviouslink.TheNOOBSpackageincludesfewdifferentoperatingsystemssuch asRaspbian,Pidora,Archlinux,andRaspBMC.NOOBSstreamlinestheentireinstallation processandhelpsyoutoinstallandconfigureyourpreferredversionoftheOSeasily.Itis importanttonotethatNOOBSisjustaninstallationpackageandyouwillbeleftwithonly theRaspbianOSonceyoucompletethegiveninstallationsteps. RaspberryPiusestheSDcardtohosttheoperatingsystemandyouneedtopreparethe SDcardfromyourcomputerbeforeplacingitintotheSDcardslotoftheRaspberryPi. InsertyourSDcardintoyourcomputerandmakesurethatyouhaveabackupofany importantinformationthatisontheSDcard.Duringtheinstallationprocess,youwilllose allthedatastoredontheSDcard.Let’sstartbypreparingyourSDcard. FollowthesestepstoprepareanSDcardfromWindows: 1. YouwillrequireasoftwaretooltoformatandpreparetheSDcardforWindows.You candownloadthefreelyavailableformattingtoolfrom https://www.sdcard.org/downloads/formatter_4/eula_windows/. 2. DownloadandinstalltheformattingtoolonyourWindowscomputer. 3. InsertyourSDcardandstarttheformattingtool. 4. Intheformattingtool,opentheOptionsmenuandsetFORMATSIZE ADJUSTMENTtoON. 5. SelecttheappropriateSDcardandclickonFormat. 6. Then,waitfortheformattingtooltofinishformattingtheSDcard.Oncethisisdone, extractthedownloadedNOOBSZIPfiletotheSDcard.Makesurethatyouextractthe contentoftheZIPfoldertotherootlocationoftheSDcard. FollowthesedirectionstoprepareSDcardfromMacOSX: 1. YouwillrequireasoftwaretooltoformatandpreparetheSDcardforMacOSX. Youcandownloadthefreelyavailableformattingtoolfrom https://www.sdcard.org/downloads/formatter_4/eula_mac/. 2. Downloadandinstalltheformattingtoolonyourmachine. 3. InsertyourSDcardandruntheformattingtool. 4. Intheformattingtool,selectOverwriteFormat. 5. SelecttheappropriateSDcardandclickonFormat. 6. Then,waitfortheformattingtooltofinishformattingtheSDcard.Oncethisisdone, extractthedownloadedNOOBSZIPfiletotheSDcard.Makesurethatyouextractthe contentoftheZIPfoldertotherootlocationoftheSDcard. FollowthesestepstopreparetheSDcardfromUbuntuLinux: 1. ToformattheSDcardonUbuntu,youcanuseaformattingtoolcalledgparted. Installgpartedusingthefollowingcommandontheterminal: $sudoapt-getinstallgparted 2. InsertyourSDcardandrungparted. 3. Inthegpartedwindow,selecttheentireSDcardandformatitusingFAT32. 4. Oncetheformatprocessiscomplete,extractthedownloadedNOOBSZIPfiletothe SDcard.MakesurethatyouextractthecontentoftheZIPfoldertotherootlocation oftheSDcard. Tip Ifyouhaveanytroublefollowingthesesteps,youcanrefertotheofficial documentationforpreparingtheSDcardforaRaspberryPiat http://www.raspberrypi.org/documentation/installation/installing-images/. TheRaspberryPisetupprocess OnceyouhavepreparedyourSDcardwithNOOBS,insertitintotheSDcardslotofthe RaspberryPi.Connectyourmonitor,mouse,andkeyboardbeforeconnectingthemicro USBcableforthepoweradapter.Onceyouconnectthepoweradapter,theRaspberryPi willturnonautomaticallyandyouwillbeabletoseetheinstallationprocessonthe monitor.Ifyouarenotabletoseeanyprogressonthemonitorafterconnectingthepower adapter,refertothetroubleshootingsectionthatisavailablelaterinthischapter. OncetheRaspberryPibootsup,itwillrepartitiontheSDcardandshowyouthefollowing installationscreensothatyoucangetstarted: Note Theprecedingscreenshotistakenfromraspberry_pi_F01_02_5a.jpgbySimonMonk andislicensedunderAttributionCreativeCommonslicense (https://learn.adafruit.com/assets/11384). 1. Asafirst-timeuser,selectRaspbian[RECOMMENDED]astherecommended operatingsystemandclickontheInstallOSbutton.RaspbianisaDebian-basedOS thatisoptimizedfortheRaspberryPianditsupportsusefulLinuxcommandsthatwe havealreadylearnedinthepreviouschapters.Theprocesswilltakeabout10to20 minutestocomplete. 2. Onsuccessfulcompletion,youwillbeabletoseeascreensimilartotheone displayedinthefollowingscreenshot.Thescreenshotdisplaystheraspi-configtool thatwillletyousetuptheinitialparameters.Wewillskipthisprocesstocomplete theinstallation.Select<Finish>andpressEnter: 3. Youcangobacktothisscreenagain,incaseyouwanttochangeanyparameter,by typingthefollowingcommandintheterminal: $sudoraspi-config 4. RaspberryPiwillnowrebootandyouwillbepromptedtothedefaultloginscreen. Loginusingthedefaultusernamepiandpasswordraspberry. 5. YoucanstartthegraphicaldesktopoftheRaspberryPibytypingthefollowing commandintheterminal: $startx 6. TorunthePythoncodethatwedevelopedinthefirststage,youwillneedtosetup requiredPythonlibrariesontheRaspberryPi.Youwillhavetoconnectyour RaspberryPitotheInternetusingtheEthernetcabletoinstallthepackages.Install therequiredPythonpackagesontheRaspberryPiterminalusingthefollowing command: $sudoapt-getinstallpython-setuptools,python-matplotlib,python- numpy 7. InstallpySerialusingSetuptools: $sudoeasy_installpyserial Now,yourRaspberryPiisreadywithanoperatingsystemandthenecessarycomponents tosupportPython-Arduinoprogramming. UsingaportableTFTLCDdisplaywiththe RaspberryPi TFTLCDisagreatwaytoexpandtheRaspberryPi’sfunctionalitiesandavoidtheuseof largedisplaydevices.TheseTFTLCDdisplayscanbeinterfaceddirectlywithGPIOpins. TFTLCDscreensareavailableinvariousshapesandsize,butfortheRaspberryPiwe recommendthatyouuseascreenwithasizesmallerthanorequalto3.2inchesdueto interfacingconvenience.Mostofthesesmallscreensdonotrequireadditionalpower supplyandcanbedirectlypoweredusingtheGPIOpins.Inafewcases,touchscreen versionsarealsoavailabletoextendthefunctionalityoftheRaspberryPi. Inthisproject,weareusingaTontec2.4inchTFTLCDscreenthatcanbedirectly interfacedwiththeRaspberryPiviaGPIO.AlthoughyoucanuseanyavailableTFTLCD screen,thisbookonlycoverthesetupandconfigurationprocessforthisparticularscreen. Inmostcases,manufacturersofthesescreensprovidedetailedconfigurationtutorialson theirwebsites.RaspberryPiforumsandblogsareanothergoodplacestolookforhelpif youareusingadifferenttypeoftheTFTLCDscreen.Thefollowingimageshowsthe backoftheTontec2.4inchTFTLCDscreenwiththelocationoftheGPIOpins.Let’sget startedandusethisscreenwithyourRaspberryPi: ConnectingtheTFTLCDusingGPIO Beforewecanusethescreen,wewillhavetoconnectittotheRaspberryPi.Let’s disconnectthemicroUSBpoweradapterfromtheRaspberryPiandlocatetheGPIOmale pinsneartheRCAvideoportontheRaspberryPi.GetyourTFTscreenandconnectthe GPIOpinsassuchyoucanseeRaspberryPiandthescreenasdisplayedinthefollowing image.Inhandfulcases,thenotationsonthescreenwillbemisleading,andthereforewe suggestthatyoufollowtheguidelinesfromthemanufacturertomaketheconnections: OnceyourscreenisconnectedtotheRaspberryPi,poweritupusingthemicroUSB cable.DonotdisconnectyourHDMIcableyet,asyourscreenisstillnotready.Beforewe goaheadwithanyoftheconfigurationsteps,let’sfirstconnecttheRaspberryPitothe Internet.ConnecttheEthernetportoftheRaspberryPitoyourhomeorofficenetwork usinganEthernetcable.Now,let’sconfiguretheTFTLCDscreenintheRaspbianOSto makeitworkproperly. ConfiguringtheTFTLCDwiththeRaspberryPiOS OnceyourRaspberryPiispoweredup,loginusingyourusernameandpassword. CompletethefollowingstepstoconfigurethescreenwithyourRaspberryPi: 1. Downloadthesupportingfilesandmanualusingthefollowingcommandonthe terminal: $wgethttps://s3.amazonaws.com/tontec/24usingmanual.zip 2. Unzipthefile.Thefollowingcommandwillextractthefilesintothesamedirectory: $unzip24usingmanual.zip 3. Navigatetothesrcdirectory: $cdcdmztx-ext-2.4/src/ 4. Enterfollowingcommandtocompilethesourcefiles: $make 5. Openthebootconfigurationfiles: $sudopico/boot/config.txt 6. Intheconfig.txtfile,locateanduncommentthefollowinglinesofcode: framebuffer_width=320 framebuffer_height=240 7. Saveandexitthefile. 8. Now,everytimetheRaspberryPirestartsweneedtoexecuteacommandtostartthe TFTLCDscreen.Todothis,opentherc.localfileusingthefollowingcommand: $sudopico/etc/rc.local 9. Addthefollowinglineofcodetothefilethatstartsthescreen: sudo/home/pi/mztx-ext-2.4/src/mztx06a& 10. Saveandexitthefile.Then,reboottheRaspberryPiusingthefollowingcommand: $sudoreboot YoucanremoveyourHDMImonitornowandstartworkingwithyourTFTLCDscreen. Onethingthatyouwillhavetokeepinmindisthatthescreenresolutionisverysmalland itisnotoptimizedforcoding.WeprefertousetheHDMImonitortoperformthemajor codemodificationsthatarerequiredinthenextsection.TheutilizationoftheTFTLCD screeninthisprojectistoaccommodatethemobilityandportabilityrequirementsofthe thermostat. OptimizingtheGUIfortheTFTLCDscreen TheresolutionoftheTFTLCDscreenthatweconfiguredintheprevioussectionisonly 320x240pixels,butthewindowsthatwecreatedinfirstprogrammingstagearequite large.Therefore,beforewecopyandrunourPythoncodeontheRaspberryPi,weneedto adjustafewparametersinthecode. Inyourregularcomputerwhereyouhavethischapter’sfolderfromthebook’ssource code,opentheThermostat_Stage2.pyfile.Thisfilecontainsthedetailsofthe modificationrequiredtoobtaintheoptimumsizewithminorcosmeticchanges.Youwill beusingthisfile,insteadoftheonethatweusedinthepreviousstage,onyourRaspberry Pi.Theseadjustmentsinthecodeareexplainedinthefollowinglinesofcode. Thefirstmajoralterationisintheportname.FortheRaspberryPi,youneedtochangethe nameoftheArduinoportfromthatyouwereusinginthefirststageto/dev/ttyACM0, whichistheaddressassignedtoArduinointhemajorityofthecases: port=serial.Serial('/dev/ttyACM0',9600,timeout=1) Inthisprogramfile,thesizeoftheTkintermainwindowandthematplotlibfigureare alsoadjustedtofitthescreensize.Ifyouareusingadifferent-sizedscreen,changethe followinglinesofcodeappropriately: top.minsize(320,160) pyplot.figure(figsize=(4,3)) Now,withtheprecedingchanges,theGUIwindowshouldbeabletofitwithinRaspberry Pi’sscreen.AstheRaspberryPi’sscreenwillbeusedasthededicatedscreenforthe thermostatapplication,weneedtoadjustthetextsizeonthescreentofitthewindow properly.Addthefont=("Helvetica",20)textinthedeclarationofthelabelsto increasethefontsize.Thefollowinglineofcodeshowschangesthatareperformedonthe labelstocontainthesensornames: Tkinter.Label(top, text="Humidity", font=("Helvetica",20)).grid(column=1,row=2) Similarly,thefontoptionisaddedtotheobservationlabels: HumdUnitLabel=Tkinter.Label(top, text="%", font=("Helvetica",20)) Thelabelsfortheobservationunitalsocarrysimilarmodifications: HumdLabel.config(text=cleanText(reading[1]), font=("Helvetica",20)) TheThermostat_Stage2.pyfilealreadyincludestheprecedingmodificationsandis readytorunonyourRaspberryPi.Beforeyourunthefile,firstweneedtocopythefileto theRaspberryPi.Atthisstage,theUSBhubwillbeveryhandytocopythefiles.Ifyou don’thaveaUSBhub,youcanutilizetwoavailableUSBportssimultaneouslytoattach theUSBpendrive,mouse,andkeyboard.WiththeuseoftheUSBhub,connecttheUSB pendrivecontainingthePythonfilesandcopythemtothehomefolder.AttachtheUSB portoftheArduinoboardtooneoftheendsoftheUSBhub.Fromthestartmenuofthe RaspberryPi,opentheLXTerminalprogrambynavigatingtoAccessories|LXterminal. RunthePythoncodefromthehomefolderandyouwillbeabletoseetheoptimizeduser interfacewindowthatopensontheRaspberryPi’sscreen.Ifeverystepmentionedinthe chapterisperformedcorrectly,youwillbeabletoseethesensorobservationbeingprinted whenyouclickontheStartbutton: Attheendofthechapter,youmustbewonderingwhatamobileunitwithsensors, Arduino,RaspberryPi,andTFTscreenmightlooklike.Thefollowingimageshowsa samplethermostatthatwasdevelopedusingtheinstructionsgiveninthischapter.Weused anacrylicsheettoholdtheRaspberryPiandtheArduinoboardtogetherandcreateda compactformfactor: Troubleshooting Thereareafewknownproblemsthatyoumayfaceinthisstageoftheproject.The followingsectiondescribestheseproblemsandtheirquickfixes: TheRaspberryPiisnotbootingup: MakesurethattheSDcardisformattedproperlywiththespecifiedtools.The RaspberryPiwon’tbootiftheSDcardisnotpreparedproperly. ChecktheHDMIcableandthemonitortoseewhethertheyareworkingfine. MakesurethatthepoweradapteriscompatiblewiththeRaspberryPi. TheTFTLCDscreendoesn’tturnon: MakesurethatthescreenisproperlyconnectedtotheGPIOpinsofthe RaspberryPi. IfyouareusinganyotherTFTLCDscreen,makesurefromitsdatasheetthat yourscreendoesn’trequireadditionalpower. Checkwhetherthescreenisproperlyconfiguredusingthestepsdescribedinthe OptimizingtheGUIfortheTFTLCDscreensection. ThereisaslowrefreshrateofthesensordataontheRaspberryPi: TrydecreasingthedelaybetweeneachserialmessagethatissentbyArduino. Terminateanyotherapplicationthatisrunninginthebackground. Summary Withthisproject,wesuccessfullycreatedaportableanddeployablethermostatusing Arduino,whichmonitorstemperature,humidity,andambientlight.Duringthisprocess, weassembledthethermostatsensorunitusingthenecessarycomponentsanddeveloped customArduinoprogramtosupportthem.WealsoutilizedPythonprogrammingmethods includingGUIdevelopmentandplotsusingTkinterandmatplotliblibraries respectively.Laterinthechapter,weutilizedtheRaspberryPitoconvertamereproject prototypeintoapracticalapplication.Henceforth,youshouldbeabletodevelopsimilar projectsthatrequireyoutoobserveandvisualizereal-timesensorinformation. Goingforward,wewillbeexpandingthisprojecttoaccommodateupcomingtopicssuch asArduinonetworking,cloudcommunication,andremotemonitoring.Inthenextlevelof thethermostatproject,wewillintegratetheseadvancedfeaturesandmakeitareally resourcefulDIYprojectthatcanbeusedineverydaylife.Inthenextchapter,wearegoing tostartthenextstageofourjourneyfrommakingsimplePython-Arduinoprojectsto Internet-connectedandremotelyaccessibleIoTprojects. Chapter8.IntroductiontoArduino Networking Sofar,weusedahardwiredserialconnectiontointeractwithArduino,aserialmonitorto observetheArduinoserialdata,andaPythonseriallibrary(pySerial)totransferdata betweentheArduinoandPythonapplications.Duringthisentireexchange,therangeof communicationwaslimitedduetothehardwiredserialconnection.Asasolution,youcan useawirelessprotocolsuchasZigBee,Bluetooth,orotherRFchannelstoestablisha communicationchannelforaremoteserialinterface.Thesewirelessprotocolsare extensivelyusedinremotehardwareapplications,andtheyusetheserialinterfaceto transferdata.Duetotheiruseofserialcommunication,theseprotocolsrequireverylittle tonoadditionalprogrammingchangesontheArduinoorPythonside.Youmayrequire additionalhardwaretoenabletheseprotocols,however.Themajorbenefitofthese protocolsisthattheyarereallyeasytoimplement.However,theyarerestrictedwithonly asmallgeographicalcoverageareaandlimiteddatabandwidth. Besidesserialcommunicationmethods,theotherwaytoremotelyaccessyourArduino deviceistouseacomputernetwork.Today,computernetworksarethemostprolificway ofcommunicatingbetweencomputingunits.Inthenexttwochapters,wewillexplore variousnetworkingtechniquesusingArduinoandPython,whichrangefromestablishing verybasicEthernetconnectivitytodevelopingcomplex,cloud-basedwebapplications. Inthischapter,wewillcoverthefollowingtopics: Thefundamentalsofnetworkingandhardwareextensionsthatenablenetworkingfor Arduino PythonframeworksusedtodevelopHypertextTransferProtocol(HTTP)web serversonyourcomputer InterfacingArduino-basedHTTPclientswiththePythonwebserver IoTmessagingprotocolMQTT(wewillinstallamiddlewaretoolcalledMosquitto toenableMQTTonourcomputer) Utilizingthepublisher/subscriberparadigm,usedbyMQTT,todevelopArduinoPythonwebapplications Arduinoandthecomputernetworking Computernetworkingisahugedomain,andcoveringeveryaspectofnetworkingisnot themainobjectiveofthisbook.Wewill,however,trytoexplainafewfundamentalsof computernetworkingwhereverthisknowledgewillneedtobeapplied.Unliketheserial interfaceapproach,whereapoint-to-pointconnectionisrequiredbetweendevices,the network-basedapproachprovidesdistributedaccesstoresources.Specificallyinhardware applicationswhereasinglehardwareunitisrequiredtobeaccessedbymultipleendpoints (forexample,inapersonalcomputer,mobilephone,orremoteserver),thecomputer networkstandssuperior. Inthissection,wewillcoverthebasicsofnetworkingandhardwarecomponentsthat enablenetworkinginArduino.Laterinthischapter,wewillusetheArduinolibraryanda built-inexampletodemonstratehowremoteaccesstoArduinousingyourlocalnetwork works. Networkingfundamentals Wheneveryouseeacomputerormobiledevice,youarealsolookingatsometypeof computernetworkbeingusedtoconnectthosedeviceswithotherdevices.Insimple terms,acomputernetworkisagroupofinterconnectedcomputationaldevices(alsocalled networknodes)thatallowtheexchangeofdatabetweenthesedevices.Thesenetwork nodesincludevariousdevicessuchasyourpersonalcomputers,mobilephones,servers, tablets,routers,andotherpiecesofnetworkinghardware. Acomputernetworkcanbeclassifiedintonumeroustypesaccordingtoparameterssuch asgeographicallocation,networktopology,andorganizationalscope.Intermsof geographicalscale,anetworkcanbecategorizedintolocalareanetwork(LAN),home areanetwork(HAN),wideareanetwork(WAN),andsoon.Whenyouareutilizing yourhomeroutertoconnecttotheInternet,youareusingtheLANcreatedbyyourrouter. Withregardstotheorganizationthathandlesthenetwork,LANcanbeconfiguredas Intranet,Extranet,andInternet.TheInternetisthelargestexampleofanycomputer network,asitinterconnectsalltypesofnetworksdeployedglobally.Inyour implementationofvariousprojectsthroughoutthisbook,youwillmostlybeusingyour LANandtheInternetfortheexchangeofdatabetweenanArduino,yourcomputer,the RaspberryPi,andthecloudservices. Tostandardizecommunicationbetweennetworknodes,variousgoverningbodiesand organizationshavecreatedasetofrulescalledprotocols.Inthelargelistofstandard protocols,thereareafewprotocolsthatyourcomputerusesonadailybasis.The examplesofthoseprotocolsassociatedwiththelocalareanetworkincludeEthernetand Wi-Fi.IntheIEEE802familyofstandards,theIEEE802.3standarddescribesdifferent typesofwiredconnectivitybetweennodesinalocalareanetwork,alsocalledEthernet. Similarly,WirelessLAN(alsoreferredtoasWi-Fi),ispartoftheIEEE802.11standard, whereacommunicationchanneluseswirelessfrequencybandstoexchangedata. MostnetworknodesdeployedwithIEEE802standards(thatis,Ethernet,Wi-Fi,andso on)haveauniqueidentifierassignedtothenetworkinterfacehardware,calledamedia accesscontrol(MAC)address.Thisaddressisassignedbythemanufacturerandis mostlyfixedforeachnetworkinterface.WhileusingArduinofornetworkconnectivity, wewillneedtheMACaddresstoenablenetworking.AMACaddressisa48-bitaddress, andinhuman-friendlyformitcontainssixgroupsoftwohexadecimaldigits.Forexample, 01:23:45:67:89:abisthehuman-readableformofa48-bitMACaddress. WhiletheMACaddressisassociatedwiththehardware-level(thatis,“physical”) protocols,theInternetProtocol(IP)isacommunicationprotocolthatiswidelyusedat theInternetleveltoenableinternetworkingbetweennetworkednodes.Inthe implementationofversion4oftheIPprotocolsuite(IPv4),eachnetworknodeisassigned a32-bitnumbercalledtheIPaddress(forexample,192.168.0.1).Whenyouconnecta computer,phone,oranyotherdevicetoyourlocalhomenetwork,anIPaddressis assignedtothatdevicebyyourrouter.OneofthemostpopularIPaddressesis127.0.0.1, whichisalsocalledthelocalhostIPaddress.ApartfromtheIPaddressassignedtoa computerbythenetwork,eachcomputeralsohasthelocalhostIPaddressassociatedwith it.ThelocalhostIPaddressisveryusefulwhenyouwanttointernallyaccessorcallyour computerfromthesamedevice.Inthecaseofaremote-accessapplication,youneedto knowtheIPaddressassignedbythenetwork. ObtainingtheIPaddressofyourcomputer Arduinoisaresource-constraineddevice,andthereforeitcanonlydemonstratealimited amountofnetworkcapability.WhileworkingwithArduino-basedprojectsthatincludethe utilizationofacomputernetwork,youwillrequireaserverorGatewayinterface.These interfacesinclude,butarenotlimitedto,adesktopcomputer,alaptop,theRaspberryPi, andotherremotecomputinginstances.Ifyouareusingtheseinterfacesaspartofyour hardwareproject,youwillneedtheirIPaddresses.Ensurethattheyareunderthesame networkasyourArduino.ThefollowingarethetechniquestoobtainIPaddressesinmajor operatingsystems. Windows InmostversionsoftheWindowsOS,youcanobtaintheIPaddressfromtheNetwork ConnectionutilityinControlPanel.NavigatetoControlPanel|NetworkandInternet |NetworkConnectionsandopentheLocalAreaConnectionStatuswindow.Clickon theDetailsbuttontoseethedetailsoftheNetworkConnectionDetailswindow.Asyou canseeinthisscreenshot,theIPaddressofthenetworkinterfaceislistedasIPv4 Addressintheopenedwindow: YoucanalsoobtaintheIPaddressofyourcomputerusingthebuilt-inipconfigutility. OpentheCommandPromptandenterthefollowingcommand: >ipconfig Asyoucanseeinthefollowingscreenshot,theIPaddressofyourcomputerislistedunder theEthernetadapter.Ifyouareusingawirelessconnectiontoconnecttoyournetwork, theEthernetadapterwillbereplacedbythewirelessEthernetadapter. MacOSX IfyouareusingMacOSX,youcanobtaintheIPaddressfromthenetworksettings.Open SystemPreferencesandclickontheNetworkicon.Youwillseeawindowsimilarto whatisshowninthenextscreenshot.Intheleftsidebar,clickontheinterfaceyouare lookingtoobtaintheIPaddressof. IfyouwanttogettheIPaddressusingtheterminal,youcanusethefollowingcommand. Thiscommandwillrequireyoutoenterthesystemnameoftheinterface,en0: $ipconfiggetifaddren0 Ifyouareconnectedtomultiplenetworksandarenotawareofthenetworkname,youcan findthelistofIPaddressesassociatedwithyourcomputer,usingthecommandshown here: $ifconfig|grepinet Asyoucanseeinthisscreenshot,youwillgetallthenetworkaddressesassociatedwith yourMaccomputerandothernetworkparameters: Linux OntheUbuntuOS,youcanobtaintheIPaddressofyourcomputerfromtheNetwork Settingsutility.Toopenit,navigatetoSystemSettings|Networkandclickonthe adapterthroughwhichthecomputerisconnectedtoyourhomenetwork.Youcanselectan appropriateadaptertoobtaintheIPaddress,asdisplayedinthefollowingscreenshot: InaLinux-basedsystem,therearemultiplewaysofobtainingtheIPaddressfromthe commandline.Youcanusethesamecommand(ifconfig)thatweusedinMacOSXin theLinuxenvironmenttoobtaintheIPaddressofyourcomputer: $ifconfig YoucanobtaintheIPaddressfromtheinetaddrfieldoftheappropriateadapter,as displayedinthisscreenshot: Ifsupportedbyyouroperatingsystem,anothercommandthatcanbeutilizedtoobtainthe IPaddressishostname: $hostname–I BecarefulwhenusingthisutilitytoobtaintheIPaddress,asyoumayendupgettingthe IPaddressofadifferentadapterifyouarenotfamiliarwiththesupportedcommand optionsoftheutility. Note IfyouaregoingtoconnectyourArduinotothesamelocalareanetworkasyourcomputer, makesureyouarechoosingtheproperIPaddressthatiscoveredbythesamedomainas thatofyourcomputer.AlsoensurethatnoothernetworkdeviceisusingthesameIP addressthatyouhaveselectedforyourArduino.ThispracticewillhelpyouavoidIP addressconflictswithinthenetwork. NetworkingextensionsforArduino TherearevarioushardwaredevicesavailableintheArduinocommunitythatenable networkingfortheArduinoplatform.Amongthesedevices,afewcanbeusedas extensionsforyourexistingArduinoboard,whileothersexistasstandaloneArduino moduleswithnetworkingcapabilities.Themostpopularextensionsusedtoenable networkingaretheArduinoEthernetShieldandArduinoWiFiShield.Similarly,Arduino YúnisanexampleofastandaloneArduinoplatformthatincludesbuilt-innetworking capabilities.Inthisbook,wearegoingtodevelopvariousnetworkingapplicationsaround theArduinoEthernetShield.Therearealsoafewotherextensions(ArduinoGSMShield) andstandaloneArduinoplatforms(ArduinoEthernet,ArduinoTre,andsoon),butweare notgoingtocoverthemindetail.Let’sgetfamiliarwiththefollowingArduinoextensions andboard. ArduinoEthernetShield TheArduinoEthernetShieldisanofficiallysupportedandopensourcenetworkextension designedtoworkwithArduinoUno.TheEthernetShieldisequippedwithanRJ45 connectortoenableEthernetnetworking.TheEthernetShieldisdesignedtomountontop ofArduinoUnoanditextendsthelayoutofthepinsfromyourArduinoUnotothetopof theboard.TheEthernetShieldisalsoequippedwithamicroSDcardslottostore importantfilesoverthenetwork.Justlikemostoftheseshieldextensions,theEthernet ShieldispoweredbytheArduinoboarditisattachedto. Source:http://arduino.cc/en/uploads/Main/ArduinoEthernetShield_R3_Front.jpg EveryEthernetShieldboardisequippedwithauniquehardware(MAC)address.Youcan seeitonthebackoftheboard.Youmaywanttonotedownthishardwareaddress,asit willberequiredfrequentlyintheupcomingexercises.Alsomakesurethatyouget familiarwithmountingtheArduinoEthernetShieldforthoseexercises.BuyanArduino EthernetShieldmodulefromSparkFunorAmazonbeforeyourstartworkingonany exercises.YoucanobtainadditionalinformationaboutthisShieldat http://arduino.cc/en/Main/ArduinoEthernetShield. ArduinoWiFiShield TheArduinoWiFiShieldhasalayoutsimilartothatoftheArduinoEthernetShieldasfar asmountingontopoftheArduinoboardisconcerned.InsteadoftheEthernetRJ45 connector,theWiFiShieldcontainscomponentstoenablewirelessnetworking.Usingthe WiFiShield,youcanconnecttotheIEEE802.11(Wi-Fi)wirelessnetworks,whichisone ofthemostpopularwaysofconnectingcomputerstothehomenetworknowadays. Source:http://arduino.cc/en/uploads/Main/A000058_front.jpg TheArduinoWiFiShieldrequiresadditionalpowerthroughaUSBconnector.Italso containsamicroSDslottosavefiles.JustliketheEthernetShield,youcanviewtheMAC addressonthebackoftheboard.MoreinformationabouttheArduinoWiFiShieldcanbe foundathttp://arduino.cc/en/Main/ArduinoWi-FiShield. ArduinoYún UnliketheEthernetShieldandtheWiFiShield,theArduinoYúnisastandalonevariant oftheArduinoboard.ItincludesbothEthernet-andWi-Fi-basednetworkconnectivity,in additiontothebasicArduinocomponent—themicrocontroller.Yúnisequippedwiththe latestandmorepowerfulprocessingunitscomparedtoUno.Insteadofthetraditionalway ofusingArduinocode,YúnsupportsalightweightversionoftheLinuxoperatingsystem, providingfunctionalitysimilartoasingle-boardcomputersuchastheRaspberryPi.You canuseyourArduinoIDEtoprogramYúnevenwhilerunningUnixshellscripts. Source:http://arduino.cc/en/uploads/Main/ArduinoYunFront_2.jpg YoucanfindmoreinformationaboutYúnattheArduinoofficialwebsite,at http://arduino.cc/en/Main/ArduinoBoardYun. ArduinoEthernetlibrary TheArduinoEthernetlibraryprovidessupportfortheEthernetprotocol,andhence providessupportforEthernetextensionsofArduino,suchastheEthernetShield.Thisisa standardArduinolibraryanditgetsdeployedwiththeArduinoIDE. Thelibraryisdesignedtoacceptincomingconnectionrequestswhendeployedasaserver andwhilemakingoutgoingconnectionstootherserverswhenbeingutilizedasaclient. Thelibraryconcurrentlysupportsuptofourconnectionsduetothelimitedcomputation capabilityoftheArduinoboard.TousetheEthernetlibraryinyourArduinoprogram,the firststepyouhavetotakeistoimportitintoyourArduinosketch: #include<Ethernet.h> TheEthernetlibraryimplementsvariousfunctionalitiesthroughspecificclasses,whichare describedasfollows. Tip Wearegoingtodescribeonlytheimportantmethodsprovidedbytheseclasses.Youcan obtainmoreinformationregardingthislibraryanditsclassesfrom http://arduino.cc/en/Reference/Ethernet. TheEthernetclass TheEthernetclassisacoreclassoftheEthernetlibrary,anditprovidesmethodsto initializethislibraryandthenetworksettings.Thisisanessentialclassforanyprogram thatwantstousetheEthernetlibrarytoestablishconnectionsthroughtheEthernetShield. TheprimaryinformationrequiredtoestablishthisconnectionistheMACaddressofthe device.You’llneedtocreateavariablethathastheMACaddressasanarrayof6bytes,as describedhere: bytemac[]={0xDE,0xAD,0xBE,0xEF,0xFE,0xED}; TheEthernetlibrarysupportstheDynamicHostControlProtocol(DHCP),whichis responsiblefordynamicallyassigningIPaddressestonewnetworknodes.Ifyourhome networkisconfiguredtosupportDHCP,youcanestablishtheEthernetconnectionusing thebegin(mac)methodfromtheEthernetclass: Ethernet.begin(mac); KeepinmindthatwhenyouareinitializinganEthernetconnectionusingthisclass,you areonlyinitializingtheEthernetconnectionandsettinguptheIPaddress.Thismeansthat youstillneedtoconfigureArduinoasaserveroraclientinordertoenablefurther communication. TheIPAddressclass InapplicationswhereyouhavetomanuallyassigntheIPaddresstoyourArduinodevice, youwillhavetousetheIPAddressclassoftheEthernetlibrary.Thisclassprovides methodstospecifytheIPaddress,whichcanbeeitherlocalorremotedependinguponthe application: IPAddressip(192,168,1,177); TheIPaddresscreatedusingthismethodcanbeusedintheinitializationofthenetwork connectionthatweperformedintheprevioussection.IfyouwanttoassignamanualIP addresstoyourArduino,youcanusethebegin(mac,ip)methodwiththeMACandIP addresses: Ethernet.begin(mac,ip); TheServerclass TheServerclassisdesignedtocreateaserverusingtheEthernetlibraryonArduino, whichlistenstoincomingconnectionrequestsforaspecificport.TheEthernetServer() method,whenspecifiedwithinintegervalueoftheportnumber,initializestheserveron Arduino: EthernetServerserver=EthernetServer(80); Byspecifyingport80inthepreviouslineofcode(whichrepresentstheHTTPprotocolon theTCP/IPsuite),wehavespecificallycreatedawebserverusingtheEthernetlibrary.To startlisteningtotheincomingconnectionrequests,youhavetousethebegin()method ontheserverobject: server.begin(); Oncetheconnectionisestablished,youcanrespondtoarequestusingvariousmethods supportedbytheserverclass,suchaswrite(),print(),andprintln(). TheClientclass TheClientclassprovidesmethodstocreateanEthernetclienttoconnectand communicatewithservers.TheEthernetClient()methodinitializesaclientthatcanbe connectedtoaspecificserverusingitsIPaddressandportnumber.Theconnect(ip, port)methodontheclientobjectwillestablishaconnectionwiththeserveronthe mentionedIPaddress: EthernetClientclient; client.connect(server,80); TheClientclassalsohastheconnected()method,whichprovidesthestatusofthe currentconnectioninbinary.Thisstatuscanbetrue(connected)orfalse(disconnected). Thismethodisusefulfortheperiodicmonitoringoftheconnectionstatus: client.connected() Otherimportantclientmethodsincluderead()andwrite().Thesemethodshelpthe Ethernetclienttoreadtherequestfromtheserverandtosendmessagestotheserver respectively. Exercise1–awebserver,yourfirstArduino networkprogram ThebestwaytotesttheArduinoEthernetlibraryandtheEthernetShieldisbyusingthe built-inexamplesthataredeployedwiththeArduinoIDE.Ifyouareusingversion1.xof theArduinoIDE,youcanfindabunchofEthernetexamplesbynavigatingtoFile| Examples|Ethernet.Byutilizingoneoftheseexamples,wearegoingtobuildaweb serverthatdeliversthesensorvalueswhenrequestedbyawebbrowser.AsArduinowill beconnectedtoyourhomenetworkthroughtheEthernet,youwillbeabletoaccessit fromanyothercomputerconnectedtoyournetwork.Themajorgoalsforthisexerciseare listedhere: UsetheArduinoEthernetlibrarywiththeArduinoEthernetShieldextensionto createawebserver RemotelyaccessArduinousingyourhomecomputernetwork UtilizeadefaultArduinoexampletoprovidehumidityandmotionsensorvalues usingawebserver Toachievethesegoals,theexerciseisdividedintothefollowingstages: DesignandbuildhardwarefortheexerciseusingyourArduinoandtheEthernet Shield RunadefaultexamplefromtheArduinoIDEasthestartingpointoftheexercise Modifytheexampletoaccommodateyourhardwaredesignandredeploythecode ThefollowingisaFritzingdiagramofthecircuitrequiredforthisexercise.Thefirstthing youshoulddoismounttheEthernetShieldontopofyourArduinoUno.Ensurethatall thepinsoftheEthernetShieldarealignedwiththecorrespondingpinsoftheArduino Uno.Thenyouneedtoconnectthepreviouslyusedhumiditysensor,HIH-4030,andthe PIRmotionsensor. Note WhiledeployingtheArduinohardwareforremoteconnectivitywithoutUSB,youwill havetoprovideexternalpowerfortheboard,asyounolongerhaveaUSBconnectionto powertheboard. NowconnectyourArduinoUnotoacomputerusingaUSBcable.Youwillalsoneedto connectArduinotoyourlocalhomenetworkusinganEthernetcable.Todothat,usea straightCAT5orCAT6cableandconnectoneendofthecabletoyourhomerouter.This routershouldbethesamedevicethatprovidesnetworkaccesstothecomputeryouare using.ConnecttheotherendoftheEthernetcabletotheEthernetportoftheArduino EthernetShieldboard.Ifthephysical-levelconnectionhasbeenestablishedcorrectly,you shouldseeagreenlightontheport. Nowit’stimetostartcodingyourfirstEthernetexample.OpentheWebServerexample bynavigatingtoFile|Examples|Ethernet|WebServerinyourArduinoIDE.Asyou cansee,theEthernetlibraryisincludedwiththeotherrequiredlibrariesandthesupported code.Inthecode,youwillneedtochangetheMACandIPaddressestomakeitworkfor yourconfiguration.WhileyoucanobtaintheMACaddressoftheEthernetShieldfrom thebackoftheboard,youwillhavetoselectanIPaddressaccordingtoyourhome networkconfiguration.AsyouhavealreadyobtainedtheIPaddressofthecomputeryou areworkingwith,selectanotheraddressintherange.Ensurethatnoothernetworknodeis usingthisIPaddress.UsetheseMACandIPaddressestoupdatethefollowingvaluesin yourcode.Youwillneedtorepeatthesestepsforeveryexercisewhenyouaredealing withArduinoEthernet: bytemac[]={0x90,0xA2,0xDA,0x0D,0x3F,0x62}; IPAddressip(10,0,0,75); Tip IntheIPnetwork,thevisiblerangeofIPaddressesforyournetworkisafunctionof anotheraddresscalledsubnetworkorsubnet.ThesubnetofyourLANIPnetworkcan helpyouselecttheappropriateIPaddressfortheEthernetShieldintherangeoftheIP addressofyourcomputer.Youcanlearnaboutthebasicsofthesubnetat http://en.wikipedia.org/wiki/Subnetwork. Beforeventuringfurtherintothecode,compilethecodewiththesemodificationsand uploadittoyourArduino.Oncetheuploadingprocessiscompletedsuccessfully,opena webbrowserandentertheIPaddressthatyouhadspecifiedintheArduinosketch.If everythinggoesfine,youshouldseetextdisplayingthevaluesoftheanalogpins. Tobetterunderstandwhathappenedhere,let’sgobacktothecode.Asyoucansee,atthe beginningofthecodeweinitializetheEthernetserverlibraryonport80usingthe EthernetServermethodfromtheEthernetlibrary: EthernetServerserver(80); Duringtheexecutionofsetup(),theprograminitializestheEthernetconnectionthrough theEthernetShieldusingtheEthernet.being()methodwiththemacandipvariables thatyoudefinedearlier.Theserver.begin()methodwillstarttheserverfromhere.Both ofthesestepsaremandatorytostartaserverifyouareusingtheEthernetlibraryfor servercode: Ethernet.begin(mac,ip); server.begin(); Intheloop()function,weinitializeaclientobjecttolistentoincomingclientrequests usingtheEthernetClientmethod.Thisobjectwillrespondtoanyrequestcomingfrom connectedclientsthattrytoaccesstheEthernetserverthroughport80: EthernetClientclient=server.available(); Onreceivingtherequest,theprogramwillwaitfortherequestpayloadtoend.Thenitwill replytotheclientwithformattedHTMLdatausingtheclient.print()method: while(client.connected()){ if(client.available()){ charc=client.read(); Serial.write(c); #Responsecode } IfyoutrytoaccesstheArduinoserverfromthebrowser,youwillseethatthewebserver repliestotheclientswiththeanalogpinreadings.Now,toobtainthepropervaluesofthe humidityandPIRsensorsthatweconnectedinthehardwaredesign,youwillhaveto performthefollowingmodificationtothecode.Youwillnoticeherethatwearereplying totheclientswiththecalculatedvaluesofrelativehumidity,insteadofrawreadingsfrom alltheanalogpins.Wehavealsomodifiedthetextthatwillbeprintedinthewebbrowser tomatchthepropersensortitle: if(c=='\n'&¤tLineIsBlank){ //sendastandardhttpresponseheader client.println("HTTP/1.1200OK"); client.println("Content-Type:text/html"); client.println("Connection:close"); client.println("Refresh:5"); client.println(); client.println("<!DOCTYPEHTML>"); client.println("<html>"); floatsensorReading=getHumidity(analogChannel,temperature); client.print("RelativeHumidityfromHIH4030is"); client.print(sensorReading); client.println("%<br/>"); client.println("</html>"); break; } Inthisprocess,wealsoaddedanArduinofunction,getHumidity(),thatwillcalculatethe relativehumidityfromthevaluesobservedfromtheanalogpins.Wehavealreadyuseda similarfunctiontocalculaterelativehumidityinoneofthepreviousprojects: floatgetHumidity(intanalogChannel,floattemperature){ floatsupplyVolt=5.0; intHIH4030_Value=analogRead(analogChannel); floatanalogReading=HIH4030_Value/1023.0*supplyVolt; floatsensorReading=161.0*analogReading/supplyVolt-25.8; floathumidityReading=sensorReading/(1.0546-0.0026*temperature); returnhumidityReading; } YoucanimplementthesechangestotheWebServerArduinoexampleforthetesting phase,orjustopentheWebServer_Custom.inosketchfromtheExercise1-Web Serverfolderofyourcodedirectory.Asyoucanseeintheopenedsketchfile,wehave alreadymodifiedthecodetoreflectthechanges,butyouwillstillhavetochangethe MACandIPaddressestotheappropriateaddresses.Onceyouaredonewiththeseminor changes,compileanduploadthesketchtoArduino. Ifeverythinggoesasplanned,youshouldbeabletoaccessthewebserverusingyourweb browser.OpentheIPaddressofyourrecentlypreparedArduinointhewebbrowser.You shouldbeabletoreceiveasimilarresponseasdisplayedinthefollowingscreenshot. Althoughweareonlydisplayinghumidityvaluesthroughthissketch,youcaneasily attachmotionsensorvaluesusingadditionalclient.print()methods. Justlikethemechanismweimplementedinthisexercise,awebserverrespondstothe requestmadebyawebbrowseranddeliversthewebpagesyouarelookingfor.Although thismethodisverypopularanduniversallyusedtodeliverwebpages,thepayload containsalotofadditionalmetadatacomparedtotheactualsizeofthesensorinformation. Also,theserverimplementationusingtheEthernetserverlibraryoccupiesalotofthe Arduino’sresources.Arduino,beingaresource-constraineddevice,isnotsuitablefor runningaserverapplication,astheArduino’sresourcesshouldbeprioritizedtohandlethe sensorsratherthancommunication.Moreover,thewebservercreatedusingtheEthernet librarysupportsaverylimitedamountofconnectionsatatime,makingitunusablefor large-scaleapplicationsandmultiusersystems. ThebestapproachtoovercomethisproblemisbyusingArduinoasaclientdevice,orby usinglightweightcommunicationprotocolsthataredesignedtoworkwithresourceconstrainedhardwaredevices.Inthenextfewsections,youaregoingtolearnand implementtheseapproachesforArduinocommunicationontheEthernet. DevelopingwebapplicationsusingPython Byimplementingthepreviousprogram,youhaveenablednetworkingonArduino.Inthe precedingexample,wecreatedanHTTPwebserverusingmethodsavailablefromthe Ethernetlibrary.BycreatinganArduinowebserver,wemadetheArduinoresources availableonthenetwork.Similarly,Pythonalsoprovidesextensibilitybywayofvarious librariestocreatewebserverinterfaces.ByrunningthePython-basedwebserveronyour computerorotherdevicessuchastheRaspberryPi,youcanavoidusingArduinotohost thewebserver.Webapplicationscreatedusinghigh-levellanguagessuchasPythoncan alsoprovideadditionalcapabilitiesandextensibilitycomparedtoArduino. Inthissection,wewillusethePythonlibrary,web.py,tocreateaPythonwebserver.We willalsousethislibrarytocreateinteractivewebapplicationsthatwillenablethetransfer ofdatabetweenanArduinoclientandawebbrowser.Afteryouhavelearnedthebasicsof web.py,wewillinterfaceArduinowithweb.pyusingserialportstomakeArduino accessiblethroughthePythonwebserver.ThenwewillupgradetheArduino communicationmethodfromtheserialinterfacetoHTTP-basedmessaging. Pythonwebframework–web.py AwebservercanbedevelopedinPythonusingvariouswebframeworkssuchasDjango, bottle,Pylon,andweb.py.Wehaveselectedweb.pyasthepreferredwebframeworkdue toitssimpleyetpowerfulfunctionalities. Theweb.pylibrarywasinitiallydevelopedbythelateAaronSwartzwiththegoalof developinganeasyandstraightforwardapproachtocreatewebapplicationsusingPython. Thislibraryprovidestwomainmethods,GETandPOST,tosupporttheHTTP RepresentationStateTransfer(REST)architecture.Thisarchitectureisdesignedto supporttheHTTPprotocolbysendingandreceivingdatabetweenclientsandtheserver. Today,theRESTarchitectureisimplementedbyahugenumberofwebsitestotransfer dataoverHTTP. Installingweb.py Togetstartedwithweb.py,youneedtoinstalltheweb.pylibraryusingSetuptools.We installedSetuptoolsforvariousoperatingsystemsinChapter1,GettingStartedwith PythonandArduino.OnLinuxandMacOSX,executeeitherofthesecommandsonthe terminaltoinstallweb.py: $sudoeasy_installweb.py $sudopipinstallweb.py OnWindows,opentheCommandPromptandexecutethefollowingcommand: >easy_install.exeweb.py IfSetuptoolsissetupcorrectly,youshouldbeabletoinstallthelibrarywithoutany difficulty.Toverifytheinstallationofthelibrary,openthePythoninteractivepromptand runthiscommandtoseewhetheryouhaveimportedthelibrarywithoutanyerrors: >>>importweb YourfirstPythonwebapplication Implementingawebserverusingweb.pyisaverysimpleandstraightforwardprocess. Theweb.pylibraryrequiresthedeclarationofamandatorymethod,GET,tosuccessfully startthewebserver.Whenaclienttriestoaccesstheserverusingawebbrowseror anotherclient,web.pyreceivesaGETrequestandreturnsdataasspecifiedbythemethod. Tocreateasimplewebapplicationusingtheweb.pylibrary,createaPythonfileusingthe followinglinesofcodeandexecutethefileusingPython.Youcanalsorunthe webPyBasicExample.pyfilefromthecodefolderofthischapter: importweb urls=( '/','index' ) classindex: defGET(self): return"Hello,world!" if__name__=="__main__": app=web.application(urls,globals()) app.run() Onexecution,youwillseethattheserverisnowrunningandaccessiblethroughthe http://0.0.0.0:8080address.Astheserverprogramisrunningonthe0.0.0.0IP address,youcanaccessitusingthesamecomputer,localhost,oranyothercomputerfrom thesamenetwork. Tocheckouttheserver,openawebbrowserandgotohttp://0.0.0.0:8080.Whenyou aretryingtoaccesstheserverfromthesamecomputer,youcanalsouse http://127.0.0.1:8080orhttp://localhost:8080.The127.0.0.1IPaddressactually standsforlocalhost,thatis,thenetworkaddressofthesamecomputeronwhichthe programisrunning.Youwillbeabletoseetheresponseoftheserverdisplayedinthe browser,asshowninthefollowingscreenshot: Tounderstandhowthissimplecodeworks,checkouttheGETmethodinthepreviouscode snippet.Asyoucansee,whenthewebbrowserrequeststheURL,theGETmethodreturns theHello,world!stringtothebrowser.Meanwhile,youcanalsoobservetwoother mandatoryweb.pycomponentsinyourcode:theurlsandweb.application()methods. Theweb.pylibraryrequiresinitializationoftheresponselocationinthedeclarationofthe urlsvariable.Everyweb.py-basedwebapplicationrequirestheapplication(urls, global())methodtobecalledtoinitializethewebserver.Bydefault,theweb.py applicationsrunonportnumber8080,whichcanbechangedtoanotherportnumberby specifyingitduringexecution.Forexample,ifyouwanttorunyourweb.pyapplicationon port8888,executethefollowingcommand: $pythonwebPyBasicExample.py8888 Althoughthisonlyreturnssimpletext,youhavenowsuccessfullycreatedyourfirstweb applicationusingPython.Wewilltakeitforwardfromhereandcreatemorecomplexweb applicationsintheupcomingchaptersusingtheweb.pylibrary.Todevelopthesecomplex applications,wewillrequiremorethanjusttheGETmethod.Let’sstartexploringadvance conceptstofurtherenhanceyourfamiliaritywiththeweb.pylibrary. Essentialweb.pyconceptsfordevelopingcomplex webapplications Theweb.pylibraryhasbeendesignedtoprovideconvenientandsimplemethodsto developdynamicwebsitesandwebapplicationsusingPython.Usingweb.py,itisreally easytobuildcomplexwebsitesbyutilizingjustafewadditionalPythonconceptsalong withwhatyoualreadyknow.Duetothislimitedlearningcurveandeasy-to-implement methods,web.pyisoneofthequickestwaystocreatewebapplicationsinany programminglanguage.Let’sbeginwithunderstandingtheseweb.pyconceptsindetail. HandlingURLs Youmighthavenoticedthatinourfirstweb.pyprogram,wedefinedavariablecalled urlsthatpointstotherootlocation(/)oftheIndexclass: urls=( '/','index' ) Intheprecedingdeclaration,thefirstpart,'/',isaregularexpressionusedtomatchthe actualURLrequests.Youcanuseregularexpressionstohandlecomplexqueriescoming toyourweb.pyserverandpointthemtotheappropriateclass.Inweb.py,youcan associatedifferentlandingpagelocationswithappropriateclasses.Forexample,ifyou wanttoredirectthe/datalocationtothedataclassinadditiontotheIndexclass,youcan changetheurlsvariableasfollows: urls=( '/','index', '/data','data', ) Withthisprovision,whenaclientsendsarequesttoaccessthehttp://<ipaddress>:8080/dataaddress,therequestwillbedirectedtowardsthedataclassandthen theGETorPOSTmethodofthatclass. TheGETandPOSTmethods Inexercise1,wherewecreatedanArduino-basedwebserverrunningonport80,weused awebbrowsertoaccessthewebserver.Webbrowsersareoneofthemostpopulartypes ofwebclientsusedtoaccessawebserver;cURL,Wget,andwebcrawlersaretheother types.AwebbrowserusesHTTPtocommunicatewithanywebservers,includingthe Arduinowebserverthatweused.GETandPOSTaretwofundamentalmethodssupported bytheHTTPprotocoltoaddressserverrequestscomingfromawebbrowser. WheneveryouaretryingtoopenawebsiteinyourbrowseroranyotherHTTPclient,you areactuallyrequestingtheGETfunctionfromthewebserver;forexample,whenyouopen awebsiteURL,http://www.example.com/,youarerequestingthatthewebserverthat hoststhiswebsiteservesyoutheGETrequestforthe'/'location.IntheHandlingURLs section,youlearnedhowtoassociatetheweb.pyclasseswithURLlandinglocations. UsingtheGETmethodprovidedbytheweb.pylibrary,youcanassociatetheGETrequest withindividualclasses.OnceyouhavecapturedtheGETrequest,youneedtoreturn appropriatevaluesastheresponsetotheclient.Thefollowingcodesnippetshowshowthe GET()functionwillbecalledwhenanyonemakesaGETrequesttothe'/'location: defGET(self): f=self.submit_form() f.validates() t=75 returnrender.test(f,t); ThePOSTfunctionoftheHTTPprotocolismainlyusedtosubmitaformoranyotherdata tothewebserver.Inmostcases,POSTisembeddedinawebpage,andarequesttothe serverisgeneratedwhenausersubmitsthecomponentcarryingthePOSTfunction.The web.pylibraryalsoprovidesthePOST()function,whichiscalledwhenawebclienttries tocontacttheweb.pyserverusingthePOSTmethod.Inmostimplementationsofthe POST()function,therequestincludessomekindofdatasubmittedthroughforms.Youcan retrieveindividualformelementsusingf['Celsius'].valuewhichwillgiveyouavalue associatedwiththeformelementcalledCelsius.OncethePOST()functionhasperformed theprovidedactions,youcanreturnappropriateinformationtotheclientinresponseto thePOSTrequest: defPOST(self): f=self.submit_form() f.validates() c=f['Celsius'].value t=c*(9.0/5.0)+32 returnrender.test(f,t) Templates NowyouknowhowtoredirectanHTTPrequesttoanappropriateURL,andalsohowto implementmethodstorespondtotheseHTTPrequests(thatis,GETandPOST).Butwhat aboutthewebpagethatneedstoberenderedoncetherequestisreceived?Tounderstand therenderingprocess,let’sstartwithcreatingafoldercalledtemplatesinthesame directorywhereourweb.pyprogramisgoingtobeplaced.Thisfolderwillstorethe templatesthatwillbeusedtorenderthewebpageswhenrequested.Youhavetospecify thelocationofthistemplatefolderintheprogramusingthetemplate.render()function, asdisplayedinthefollowinglineofcode: render=web.template.render('templates') Onceyouhaveinstantiatedtherenderingfolder,itistimetocreatetemplatefilesforyour program.Accordingtotherequirementsofyourprogram,youcancreateasmany templatefilesasyouwant.AlanguagecalledTempletorisusedtocreatethesetemplate filesinweb.py.Youcanlearnmoreaboutitathttp://webpy.org/templetor.Eachtemplate filecreatedusingTempletorneedstobestoredintheHTMLformatwiththe.html extension. Let’screateafilecalledtest.htmlinthetemplatesfolderusingatexteditorandpaste thefollowingcodesnippetintothefile: $defwith(form,i) <formmethod="POST"> $:form.render() </form> <p>Valueis:$:i</p> Asyoucanseeintheprecedingcodesnippet,thetemplatefilebeginswiththe$def with()expression,whereyouneedtospecifytheinputargumentsasvariableswithinthe brackets.Oncethetemplateisrendered,thesewillbetheonlyvariablesyoucanutilizefor thewebpage;forexample,inthepreviouscodesnippet,wepassedtwovariables(form andi)asinputvariables.Weutilizedtheformobjectusing$:form.render()torenderit insidethewebpage.Whenyouneedtorendertheformobject,youcandirectlypassthe othervariablebysimplydeclaringit(thatis,$:i).TempletorwillrendertheHTMLcode ofthetemplatefileasitis,whileutilizingthevariablesintheinstanceswheretheyare beingused. Nowyouhaveatemplatefile,test.html,readytobeusedinyourweb.pyprogram. WheneveraGET()orPOST()functionisexecuted,youarerequiredtoreturnavaluetothe requestingclient.Althoughyoucanreturnanyvariablefortheserequests,includingNone, youwillhavetorenderatemplatefilewheretheresponseisassociatedwithloadingaweb page.Youcanreturnthetemplatefileusingtherender()function,followedbythe filenameofthetemplatefileandinputarguments: returnrender.test(f,i); Asyoucanseeintheprecedinglineofcode,wearereturningtherenderedtest.html pagebyspecifyingtherender.test()function,wheretest()isjustthefilenamewithout the.htmlextension.Thefunctionalsoincludesaformobject,f,andvariable,i,thatwill bepassedasinputarguments. Forms Theweb.pylibraryprovidessimplewaysofcreatingformelementsusingtheForm module.ThismoduleincludesthecapabilitytocreateHTMLformelements,obtaininputs fromusers,andvalidatetheseinputsbeforeutilizingtheminthePythonprogram.Inthe followingcodesnippet,wearecreatingtwoformelements,TextboxandButton,usingthe Formlibrary: submit_form=form.Form( form.Textbox('Celsius',description='Celsius'), form.Button('submit',type="submit",description='submit') ) BesidesTextbox(whichobtainstextinputfromusers)andButton(whichsubmitsthe form),theFormmodulealsoprovidesafewotherformelements,suchasPasswordto obtainhiddentextinput,Dropboxtoobtainamutuallyexclusiveinputfromadrop-down list,Radiotoobtainmutuallyexclusiveinputsfrommultipleoptions,andCheckboxto selectabinaryinputfromthegivenoptions.Whilealloftheseelementsareveryeasyto implement,youshouldselectformelementsonlyaccordingtoyourprogram requirements. Intheweb.pyimplementationofForm,thewebpageneedstoexecutethePOSTmethod everytimetheformissubmitted.Asyoucaninseeinthefollowingimplementationofthe forminthetemplatefile,weareexplicitlydeclaringtheformsubmissionmethodasPOST: $defwith(form,i) <formmethod="POST"> $:form.render() </form> Exercise2–playingwithweb.pyconceptsusingthe Arduinoserialinterface Nowyouhaveageneralideaofthebasicweb.pyconceptsusedtobuildawebapplication. Inthisexercise,wewillutilizetheconceptsyoulearnedtocreateanapplicationtoprovide theArduinowithsensorinformation.Asthegoalofthisexerciseistodemonstratethe web.pyserverforArduinodata,wearenotgoingtoutilizetheEthernetShieldfor communication.Instead,wewillcapturetheArduinodatausingtheserialinterface,while usingtheweb.pyservertorespondtotherequestscomingfromdifferentclients. Asyoucanseeinthefollowingdiagram,weareusingthesamehardwarethatyou designedforexercise1,butwithoututilizingtheEthernetconnectiontoourhomerouter. Yourcomputerrunningtheweb.pyserver,whichisalsoapartofyourhomenetwork,will servetheclientrequests. Inthefirststep,wearegoingtocodeArduinotoperiodicallysendthehumiditysensor valuetotheserialinterface.FortheArduinocode,openthe WebPySerialExample_Arduino.inosketchfromtheExercise2folderofyourcode directory.AsyoucanseeinthefollowingcodesnippetoftheArduinosketch,weare sendingrawvaluesfromtheanalogporttotheserialinterface.Nowcompileandupload thesketchtoyourArduinoboard.OpentheSerialMonitorwindowfromtheArduino IDEtoconfirmthatyouarereceivingtherawhumidityobservations.Onceyouhave confirmedit,closetheSerialMonitorwindow.Youwon’tbeabletorunthePythoncode iftheSerialMonitorwindowisusingtheport: voidloop(){ intanalogChannel=0; intHIH4030_Value=analogRead(analogChannel); Serial.println(HIH4030_Value); delay(200); } OncetheArduinocodeisrunningproperly,itistimetoexecutethePythonprogram, whichcontainstheweb.pyserver.ThePythonprogramforthisexerciseislocatedinthe WebPySerialExample_Pythondirectory.OpenthewebPySerialExample.pyfileinyour codeeditor.ThePythonprogramisorganizedintwosections:capturingsensordatafrom theserialinterfaceusingthepySeriallibrary,andusingtheweb.pyserver-basedserverto respondtotherequestsfromtheclients. Inthefirststageofthecode,weareinterfacingtheserialportusingtheSerial()method fromthepySeriallibrary.Don’tforgettochangetheserialportnameasitmaybe differentforyourcomputer,dependingontheoperatingsystemandphysicalportthatyou areusing: importserial port=serial.Serial('/dev/tty.usbmodemfa1331',9600,timeout=1) Oncetheportobjectfortheserialportiscreated,theprogramstartsreadingthetext comingfromthephysicalport,usingthereadline()method.Usingthe relativeHumidity()function,weconverttherawhumiditydatatoappropriaterelative humidityobservations: line=port.readline() ifline: data=float(line) humidity=relativeHumidity(line,25) Onthewebserverside,wewillbeusingallthemajorweb.pycomponentsyoulearnedin theprevioussectiontocompletethisgoal.Aspartofit,weareimplementinganinput formforthetemperaturevalue.Wewillcapturethisuserinputandutilizeitwiththeraw sensordatatocalculaterelativehumidity.Therefore,weneedtodefinetherenderobject tousethetemplatedirectory.Inthisexercise,weareonlyusingthedefaultlandingpage location('/')forthewebserver,whichisdirectedtowardstheIndexclass: render=web.template.render('templates') AsyoucanseeintheWebPySerialExample_Pythonfolder,wehaveadirectorycalled templates.Thisdirectorycontainsatemplatewiththebase.htmlfilename.Asthisisan HTMLfile,itislikelythatifyoujustclickonthefile,itopensinawebbrowser.Make surethatyouopenthefileinatexteditor.Intheopenedfile,you’llseethatweare initializingthetemplatefilewith$defwith(form,humidity).Inthisinitialization,form andhumidityareinputvariablesthatarerequiredbythetemplateduringtherendering process.Thetemplatedeclarestheactual<form>elementwiththe$:form.render() method,whiledisplayingthehumidityvalueusingthe$humidityvariable: <formmethod="POST"> $:form.render() </form> <h3>RelativeHumidityis:</h3> <pname="temp">$humidity</p> Althoughthetemplatefilerenderstheformvariable,wehavetodefinethisvariableinthe Pythonprogramfirst.Asyoucanseeinthefollowingcodesnippet,wehavedeclareda variablecalledsubmit_formusingtheform.Form()methodoftheweb.pylibrary.The submit_formvariableincludesaTextboxelementtocapturethetemperaturevalueanda Buttonelementtoenablethesubmitaction: submit_form=form.Form( form.Textbox('Temperature',description='Temperature'), form.Button('submit',type="submit",description='submit') ) Whenyouwanttoaccessthecurrentsubmittedvaluesofthesubmit_formvariable,you willhavetovalidatetheformusingthevalidates()method: f=self.submit_form() f.validates() Nowwehavetheuser-facingwebpageandinputcomponentsdesignedfortheexercise.It istimetodefinethetwomainmethods,GETandPOST,torespondtotherequestcoming fromthewebpage.Whenyoulaunchorrefreshthewebpage,theweb.pyservergenerates theGETrequest,whichisthenhandledbytheGETfunctionoftheIndexclass.Soduring theexecutionoftheGETmethod,theprogramobtainsthelatestrawhumidityvaluefrom theserialportandcalculatestherelativehumidityusingtherelativeHumidity()method. Note IntheprocessofdealingwiththeGETrequest,wearenotsubmittinganyformwiththe userinput.Forthisreason,intheGETmethod,wewillusethedefaultvalueoftemperature (25)fortherelativeHumidity()method. Oncethehumidityvalueisderived,theprogramwillrenderthebasetemplateusingthe render.base()function,asdisplayedinthefollowingcodesnippet,wherebase()refers tothebasetemplate: defGET(self): f=self.submit_form() f.validates() line=port.readline() ifline: data=float(line) humidity=relativeHumidity(line,25) returnrender.base(f,humidity); else: returnrender.base(f,"Notvaliddata"); ContrarytotheGETmethod,thePOSTmethodisinvokedwhentheformissubmittedtothe webpage.Thesubmittedformincludesthetemperaturevalueprovidedbytheuser,which willbeusedtoobtainthevalueoftherelativehumidity.LiketheGET()function,the POST()functionalsorendersthebasetemplatewiththerecenthumidityvalueoncethe humidityiscalculated: defPOST(self): f=self.submit_form() f.validates() temperature=f['Temperature'].value line=port.readline() ifline: data=float(line) humidity=relativeHumidity(line,float(temperature)) returnrender.base(f,humidity); else: returnrender.base(f,"Notvaliddata"); Nowitistimetoruntheweb.py-basedwebserver.InthePythonprogram,makethe necessarychangestoaccommodatetheserialportnameandanyotherappropriatevalues. Ifeverythingisconfiguredcorrectly,youwillbeabletoexecutetheprogramfromthe terminalwithoutanyerrors.Youcanaccessthewebserver,whichisrunningonport8080, fromawebbrowseronthesamecomputer,thatis,http://localhost:8080.Nowthe goaloftheexerciseistodemonstratetheremoteaccessibilityofthewebserverfromyour homenetwork,andyoucandothisbyopeningthewebsitefromanothercomputerinyour network,thatis,http://<ip-address>:8080,where<ip-address>referstotheIP addressofthecomputerthatisrunningtheweb.pyservice. Theprecedingscreenshotshowshowthewebapplicationwilllookwhenopenedinaweb browser.Whenyouloadthewebsite,youwillbeabletoseearelativehumidityvalue obtainedusingtheGETmethod.Nowyoucanenteranappropriatetemperaturevalueand pressthesubmitbuttontoinvokethePOSTmethod.Onsuccessfulexecution,youwillbe abletoseethelatestrelativehumidityvalue,whichiscalculatedbasedonthetemperature valuethatyousubmitted. RESTfulwebapplicationswithArduino andPython Inthepreviousexercise,weimplementedtheGETandPOSTrequestsusingtheweb.py library.Theserequestsareactuallypartofthemostpopularcommunicationarchitectureof theWorldWideWeb(WWW)calledREST.TheRESTarchitectureimplementsaclientserverparadigmusingtheHTTPprotocolforoperationssuchasPOST,READ,andDELETE. TheGET()andPOST()functions,implementedusingweb.py,arefunctionalsubsetsof thesestandardHTTPRESToperations,thatis,GET,POST,UPDATE,andDELETE.TheREST architectureisdesignedfornetworkapplications,websites,andwebservicestoestablish communicationthroughHTTP-basedcalls.Ratherthanbeingjustasetofstandardrules, theRESTarchitectureutilizesexistingwebtechnologiesandprotocols,makingitacore componentofthemajorityofthewebsitesweusetoday.Duetothisreason,theWWW canbeconsideredtobethelargestimplementationofREST-basedarchitecture. DesigningREST-basedArduinoapplications TheRESTarchitectureusesaclient-servermodel,wheretheserveractsasacentralized nodeinthenetwork.Itrespondstotherequestsmadebythedistributednetworknodes (calledclients)thatqueryit.Inthisparadigm,theclientinitiatesarequestforthestate directedtowardstheserver,whiletheserverrespondstothestaterequestwithoutstoring theclientcontext.Thiscommunicationisalwaysone-directionalandalwaysinitiatedfrom theclientside. TofurtherexplainthestatetransferfortheGETandPOSTrequests,checkouttheprevious diagram.WhenaclientsendsaGETrequesttoaserverusingaURL,theserverresponds withrawdataastheHTTPresponse.Similarly,inthePOSTrequest,theclientsendsdataas payloadtotheserver,whiletheserverrespondswithsimplya“receivedconfirmation” message. RESTmethodsarerelativelysimpletoimplementanddevelopusingsimpleHTTPcalls. WearegoingtostartdevelopingArduinonetworkingapplicationsusingREST-based requests,astheyareeasytoimplementandunderstandandaredirectlyavailablethrough examples.WewillbeginbyindividuallyimplementingREST-basedArduinoclientsfor HTTP-basedGETandPOSTmethods.Laterinthischapter,wewillgothroughanexercise tocombinetheGETandPOSTmethodsthroughthesameArduinoRESTclient,while developingtheHTTPserverusingweb.py. WorkingwiththeGETrequestfromArduino Inthisexercise,wewillimplementtheHTTPGETclientonArduino,whileusinganHTTP serverthatwasdevelopedusingweb.py.Thepremiseofthisprogrammingexerciseisto usetheEthernetShieldextensionandtheEthernetlibrarytodevelopaphysicalArduino HTTPclientthatsupportstheGETrequest. TheArduinocodetogeneratetheGETrequest TheArduinoIDEshipswithafewbasicexamplesthatutilizetheEthernetlibrary.Oneof theseexamplesisWebClient,whichcanbefoundbynavigatingtoFile|Examples| Ethernet|WebClient.ItisdesignedtodemonstratetheGETrequestbyimplementingthe HTTPclientonArduino.OpenthissketchintheArduinoIDE,aswearegoingtousethis sketchandmodifyittoaccommodatetheArduinohardwarewecreated. ThefirstthingyouneedtochangeintheopenedsketchistheIPaddressandtheMAC addressofyourArduinoEthernetShield.Replacethefollowingvariableswiththe variablesappropriateforyoursystem.ThefollowingcodesnippetshowstheIPaddress andtheMACaddressforourhardware,andyouneedtochangeittoaccommodateyours: bytemac[]={0x90,0xA2,0xDA,0x00,0x47,0x28}; IPAddressip(10,0,0,75); Asyoucansee,theexampleusesGoogleasaservertogetaresponse.Youneedtochange thisaddresstoreflecttheIPaddressofyourcomputer,whichwillhosttheweb.pyserver: charserver[]="10.0.0.20"; Inthesetup()function,youwillhavetochangetheserverIPaddressagain.Alsochange thedefaultHTTPport(80)totheportusedbyweb.py(8080): if(client.connect(server,8080)){ Serial.println("connected"); //MakeaHTTPrequest: client.println("GET/dataHTTP/1.1"); client.println("Host:10.0.0.20"); client.println("Connection:close"); client.println(); } Onceyouhavemadeallofthesechanges,gototheArduino_GET_Webpy\ArduinoGET folderandopentheArduinoGET.inosketch.Compareyourmodifiedsketchwiththis sketchandperformtheappropriatechanges.Nowyoucansaveyoursketchandcompile yourcodeforanyerrors. Atthisstage,weareassumingthatyouhavetheArduinoEthernetShieldmountedon yourArduinoUno.ConnecttheEthernetShieldtoyourlocalnetworkusinganEthernet cable,andconnectUnowithyourcomputerusingaUSBcable.Uploadthesketchtothe ArduinoboardandopentheSerialMonitorwindowtochecktheactivity.Atthisstage, Arduinowouldnotbeabletoconnecttotheserverbecauseyourweb.pyserverisstillnot running.Youcanclosetheserialmonitorfornow. TheHTTPserverusingweb.pytohandletheGETrequest Inyourfirstweb.pyapplication,youdevelopedaserverthatreturnedHello,world! whenrequestedfromawebbrowser.Despitealltheadditionaltasksitcanperform,your webbrowserisanHTTPclientatitscore.Thismeansthatifyourfirstweb.pyservercode wasabletorespondtotheGETrequestmadebythewebbrowser,itshouldalsobeableto respondtotheArduinowebclient.Tocheckthisout,openyourfirstweb.pyprogram, webPyBasicExample.py,andchangethereturnstringfromHelloWorld!totest.Weare performingthisstringchangetodifferentiateitfromtheotherinstancesofthisprogram. ExecutethePythonprogramfromtheterminalandopentheSerialMonitorwindowin theArduinoIDEagain.Thistime,youwillbeabletoseethatyourArduinoclientis receivingaresponsefortheGETrequestitsenttotheweb.pyserver.Asyoucanseeinthe followingscreenshot,youwillbeabletoseetheteststringprintedintheSerialMonitor window,whichisreturnedbytheweb.pyserverfortheGETrequest: AlthoughinthisexamplewearereturningasimplestringfortheGETrequest,youcan extendthismethodtoobtaindifferentuser-specifiedparametersfromthewebserver.This GETimplementationcanbeusedinalargenumberofapplicationswhereArduinorequires repeatedinputfromtheuserorotherprograms.Butwhatifthewebserverrequiresinput fromtheArduino?Inthatcase,wewillhavetousethePOSTrequest.Let’sdevelopan ArduinoprogramtoaccommodatetheHTTPPOSTrequest. WorkingwiththePOSTrequestfromArduino SincewehavenowimplementedtheGETrequest,wecanuseasimilarapproachto exercisethePOSTrequest.Insteadofaskingtheservertoprovidearesponseforastate request,wewillsendsensordataaspayloadfromArduinointheimplementationofthe POSTrequest.Similarly,ontheserverside,wewillutilizeweb.pytoacceptthePOST requestanddisplayitthroughawebbrowser. TheArduinocodetogeneratethePOSTrequest OpentheArduinosketchArduinoPOST.inofromtheArduino_POST_Webpy\ArduinoPOST folderofthecoderepository.Asinthepreviousexercise,youwillfirsthavetoprovidethe IPaddressandtheMACaddressofyourArduino. Onceyouhavecompletedthesebasicchanges,observethefollowingcodesnippetforthe implementationofthePOSTrequest.Youmightnoticethatwearecreatingpayloadforthe POSTrequestasthevariabledatafromthevaluesobtainedfromanalogpin0: Stringdata; data+=""; data+="Humidity"; data+=analogRead(analogChannel); InthefollowingArduinocode,we’llfirstcreateaclientobjectusingtheEthernetlibrary. Intherecurringloop()function,we’llusethisclientobjecttoconnecttotheweb.py serverrunningonourcomputer.YouwillhavetoreplacetheIPaddressintheconnect() methodwiththeIPaddressofyourweb.pyserver.Onceconnected,we’llcreateacustom POSTmessagewiththepayloaddatawecalculatedpreviously.TheArduinoloop() functionwillperiodicallysendtheupdatedsensorvaluegeneratedbythiscodesampleto theweb.pyserver: if(client.connect("10.0.0.20",8080)){ Serial.println("connected"); client.println("POST/dataHTTP/1.1"); client.println("Host:10.0.0.20"); client.println("Content-Type:application/x-www-form-urlencoded"); client.println("Connection:close"); client.print("Content-Length:"); client.println(data.length()); client.println(); client.print(data); client.println(); Serial.println("Datasent."); } Onceyouhaveperformedthechanges,compileanduploadthissketchtotheArduino board.Astheweb.pyserverisyetnotimplemented,thePOSTrequestthatoriginatedfrom Arduinowillnotbeabletoreachitsdestinationsuccessfully,solet’screatetheweb.py servertoacceptPOSTrequests. TheHTTPserverusingweb.pytohandlethePOSTrequest InthisimplementationofthePOSTmethod,werequiretwoweb.pyclasses,indexand data,toindividuallyserverequestsfromthewebbrowserandArduinorespectively.As wearegoingtousetwoseparateclassestoupdatecommonsensorvalues(thatis, humidityandtemperature),wearegoingtodeclarethemasglobalvariables: globaltemperature,humidity temperature=25 AsyoumayhavenoticedintheArduinocode(client.println("POST/data HTTP/1.1")),weweresendingthePOSTrequesttotheURLlocatedat/data.Similarly, wewillusethedefaultrootlocation,'/',tolandanyrequestcomingfromtheweb browser.Theserequestsfortherootlocationwillbehandledbytheindexclass,justaswe coveredinexercise2: urls=( '/','index', '/data','data', ) ThedataclasstakescareofanyPOSTrequestoriginatingfromthe/datalocation.Inthis case,thesePOSTrequestscontainpayloadthathassensorinformationattachedbythe ArduinoPOSTclient.Onreceivingthemessage,themethodsplitsthepayloadstringinto sensor-typeandvalue,updatingtheglobalvalueofthehumidityvariableinthisprocess: classdata: defPOST(self): globalhumidity i=web.input() data=web.data() data=data.split()[1] humidity=relativeHumidity(data,temperature) returnhumidity EachPOSTrequestreceivedfromArduinoupdatestherawhumidityvalue,whichis representedbythedatavariable.Weareusingthesamecodefromexercise2toobtain manualtemperaturevaluesfromtheuser.Therelativehumidityvalue,humidity,is updatedaccordingtothetemperaturevalueyouupdatedusingthewebbrowserandthe rawhumidityvalueisobtainedfromyourArduino. TocheckoutthePythoncode,opentheWebPyEthernetPOST.pyfilefromthecode repository.Aftermakingtheappropriatechanges,executethecodefromtheterminal.If youdon’tstartgettinganyupdatesfromtheArduinoontheterminal,youshouldrestart Arduinotoreestablishtheconnectionwiththeweb.pyserver.Onceyoustartseeing periodicupdatesfromtheArduinoPOSTrequestsattheterminal,openthelocationofthe webapplicationinyourbrowser.Youwillbeabletoseesomethingsimilartothe precedingscreenshot.Here,youcansubmitthemanualtemperaturevalueusingtheform, whilethebrowserwillreloadwiththeupdatedrelativehumidityaccordingtothe temperaturevalueentered. Exercise3–aRESTfulArduinowebapplication ThegoalofthisexerciseistosimplycombinetheGETandPOSTmethodsyoulearnedin theprevioustwosectionsinordertocreateacompleteRESTexperienceusingArduino andPython.Thearchitectureforthisexercisecanbedescribedasfollows: TheArduinoclientperiodicallyusestheGETrequesttoobtainthesensortypefrom theserver.Itusesthissensortypetoselectasensorforobservation.Inourcase,itis eitherahumidityormotionsensor. ThewebserverrespondstotheGETrequestbyreturningthecurrentsensortypeofthe sensorselectedbytheuser.Theuserprovidesthisselectionthroughaweb application. Afterreceivingthesensortype,theArduinoclientutilizesPOSTtosendsensor observationtotheserver. ThewebserverreceivesthePOSTdataandupdatesthesensorobservationforthat particularsensortype. Ontheuserside,thewebserverobtainsthecurrentsensortypethroughtheweb browser. Whenthesubmitbuttoninthebrowserispressed,theserverupdatesthesensor valueinthebrowserwiththelatestvalue. TheArduinosketchfortheexercise UsingthesameArduinohardwarewebuilt,opentheArduinosketchnamed WebPyEthernetArduinoGETPOST.inofromtheExercise3-RESTfulapplication Arduinoandwebpycodefolder.Aswedescribedintheexercise’sarchitectureearlier,the ArduinoclientshouldperiodicallysendGETrequeststotheserverandgetthe correspondingvalueofthesensortypeintheresponse.Aftercomparingthesensortype, theArduinoclientfetchesthecurrentsensorobservationfromtheArduinopinsandsends thatobservationbacktotheserverusingPOST: if(client.connected()){ if(client.find("Humidity")){ #Fetchhumiditysensorvalue if(client.connect("10.0.0.20",8080)){ #Posthumidityvalues } } else{ #Fetchmotionsensorvalue if(client.connect("10.0.0.20",8080)){ #Postmotionvalues } } #Adddelay } Afterchangingtheappropriateserver’sIPaddressinthecode,compileanduploaditto theArduino.OpentheSerialMonitorwindow,whereyouwillfindunsuccessful connectionattempts,asyourweb.pyserverisnotyetrunning.Closeanyotherinstanceor programoftheweb.pyserverrunningonyourcomputer. Theweb.pyapplicationtosupportRESTrequests OpentheWebPyEthernetGETPOST.pyfilefromtheExercise3-RESTfulapplication Arduinoandwebpycodefolder.Asyoucansee,theweb.pybasedwebserverimplements twoseparateclasses,indexanddata,tosupporttheRESTarchitecturefortheweb browserandtheArduinoclient,respectively.Weareintroducinganewconceptforthe Formelement,calledDropdown().UsingthisFormmethod,youcanimplementthedropdownselectionmenuandasktheusertoselectoneoptionfromthelistofoptions: form.Dropdown('dropdown', [('Humidity','Humidity'),('Motion','Motion')]), form.Button('submit', type="submit",description='submit')) Inthepreviousweb.pyprogram,weimplementedtheGETandPOSTmethodsfortheindex classandonlythePOSTmethodforthedataclass.Movingforwardinthisexercise,we’ll alsoaddtheGETmethodtothedataclass.Thismethodreturnsthevalueofthe sensorTypevariablewhentheGETrequestismadeforthe/datalocation.Fromtheuser side,thevalueofthesensorTypevariableisupdatedwhentheformgetssubmittedwith anoption.ThisactionsendsaselectedvaluetothePOSTmethodoftheindexclass, ultimatelyupdatingthesensorTypevalue: classdata: defGET(self): returnsensorType defPOST(self): globalhumidity,motion i=web.input() data=web.data() data=data.split()[1] ifsensorType=="Humidity": humidity=relativeHumidity(data,temperature) returnhumidity else: motion=data returnmotion BeforeyourunthisPythonprogram,makesureyouhavecheckedeverycomponentofthe codeandupdatedthevalueswhereneeded.Thenexecutethecodefromtheterminal.Your webserverwillnowrunonyourlocalcomputerontheportnumber8080.Power-cycle yourArduinodeviceincasetheconnectionattemptfromArduinofails.Totestyour system,openthewebapplicationfromyourwebbrowser.Youwillseeawebpageopenin yourbrowser,asdisplayedinthefollowingscreenshot: Youcanchoosethesensortypefromthedropdownmenu(HumidityorMotion)before pressingtheSubmitbutton.Onsubmission,youwillbeabletoseethepageupdatedwith theappropriatesensortypeanditscurrentvalue. Whydoweneedaresource-constrainedmessaging protocol? Intheprevioussection,youlearnedhowtousetheHTTPRESTarchitecturetosendand receivedatabetweenyourArduinoandthehostserver.TheHTTPprotocolwasoriginally designedtoservetextualdatathroughwebpagesontheInternet.Thedatadelivery mechanismusedbyHTTPrequiresacomparativelylargeamountofcomputationand networkresources,whichmaybesufficientforacomputersystembutnotforresourceconstrainedhardwareplatformssuchasArduino.Aswediscussedearlier,theclient-server paradigmimplementedbytheHTTPRESTarchitecturecreatesatightlycoupledsystem. Inthisparadigm,bothsides(theclientandtheserver)needtobeconstantlyactive,orlive, torespond.Also,theRESTarchitectureonlyallowsunidirectionalcommunicationfrom clienttoserver,whererequestsarealwaysinitializedbytheclientandtheserverresponds totheclient.Thisrequest-response-basedarchitectureisnotsuitableforconstrained hardwaredevicesbecauseof(butnotlimitedto)thefollowingreasons: Thesedevicesshouldavoidactivecommunicationmodetosavepower Thecommunicationshouldhavelessdataoverhaultosavenetworkresources Theyusuallydonothaveenoughcomputationalresourcestoenablebidirectional RESTcommunication,thatis,implementingbothclientandservermechanismson eachside Thecodeshouldhaveasmallerfootprintduetostorageconstraints Tip TheREST-basedarchitecturecanstillbeusefulwhentheapplicationspecifically requiresarequest-responsearchitecture,butmostsensor-basedhardwareapplications arelimitedduetotheprecedingpoints. Amongotherdatadeliveryparadigmsthatsolvetheprecedingproblems,thearchitecture basedonpublisher/subscriber(pub/sub)standstall.Thepub/subarchitectureenables bidirectionalcommunicationcapabilitiesbetweenthenodethatgeneratesthedata (Publisher)andthenodethatconsumesthedata(Subscriber).Wearegoingtouse MQTTastheprotocolthatusesthepub/submodelofmessagetransportation.Let’sbegin bycoveringthepub/subarchitectureandMQTTindetail. MQTT–Alightweightmessagingprotocol JustlikeREST,pub/subisoneofthemostpopularmessagingpatterns,mostlydeployedto transfershortmessagesbetweennodes.Insteadofdeployingclient-server-based architecture,thepub/subparadigmimplementsmessagingmiddlewarecalledabrokerto receive,queue,andrelaymessagesbetweenthesubscriberandpublisherclients: Thepub/subarchitectureutilizesatopic-basedsystemtoselectandprocessmessages, whereeachmessageislabeledwithaspecifictopicname.Insteadofsendingamessage directlytothesubscriber,thepublishersendsitfirsttothebrokerwithatopicname.Ina totallyindependentprocess,thesubscriberregistersitssubscriptionforparticulartopics withthebroker.Intheeventofreceivingamessagefromthepublisher,thebroker performstopic-basedfilteringonthatmessagebeforeforwardingittothesubscribers registeredforthattopic.Aspublishersarelooselycoupledtosubscribersinthis architecture,thepublishersdonotneedtoknowthewhereaboutsofthesubscribersand canworkuninterruptedwithoutworryingabouttheirstatus. WhilediscussingthelimitationsoftheRESTarchitecture,wenoticedthatitrequiresthe implementationofboththeHTTPclientandserverontheArduinoendtoenable bidirectionalcommunicationwithArduino.Withthebroker-basedarchitecture demonstratedbypub/sub,youonlyneedtoimplementlightweightcodeforthepublisher orsubscriberclientonArduino,whilethebrokercanbeimplementedonadevicewith morecomputationresources.Henceforth,youwillhavebidirectionalcommunication enabledonArduinowithoutusingsignificantresources. IntroductiontoMQTT MessageQueueTelemetryTransport(MQTT)isaverysimple,easy,andopen implementationofthepub/subparadigm.IBMhasbeenworkingonstandardizingand supportingtheMQTTprotocol.Thedocumentationforthelatestspecificationofthe MQTTprotocol,v3.1,canbeobtainedfromtheofficialMQTTwebsiteat http://www.mqtt.org. Asastandardformachinemessaging,MQTTisdesignedtobeextremelylightweightand withasmallerfootprintforcode,whilealsousingalowernetworkbandwidthfor communication.MQTTisveryspecificallydesignedtoworkonembeddedsystems—like hardwareplatformssuchasArduinoandotherappliances—thatcarrylimitedprocessor andmemoryresources.WhileMQTTisatransportlayermessagingprotocol,ituses TCP/IPfornetwork-levelconnectivity.AsMQTTisdesignedtosupportthepub/sub messagingparadigm,theimplementationofMQTTonyourhardwareapplicationprovides supportforone-to-manydistributedmessaging,eliminatingthelimitationofunidirectional communicationdemonstratedbyHTTPREST.AsMQTTisagnosticofthecontentofthe payload,thereisnorestrictiononthetypeofmessageyoucanpassusingthisprotocol. Duetoallthebenefitsassociatedwiththepub/subparadigmanditsimplementationinthe MQTTprotocol,wewillbeusingtheMQTTprotocolfortherestoftheexercisestohave messagescommunicatedbetweenArduinoanditsnetworkedcomputer.Toachievethis, wewillbeusingtheMQTTbrokertoprovidethegroundworkformessage communicationandhosttopics,whiledeployingtheMQTTpublisherandsubscriber clientsattheArduinoandPythonends. Mosquitto–anopensourceMQTTbroker Aswedescribed,MQTTisjustaprotocolstandard,anditstillrequiressoftwaretoolsso thatitcanbeimplementedinactualapplications.Mosquittoisanopensource implementationofthemessagebroker,whichsupportsthelatestversionoftheMQTT protocolstandard.TheMosquittobrokerenablesthepub/subparadigmimplementedby theMQTTprotocol,whileprovidingalightweightmechanismtoenablemessaging betweenmachines.DevelopmentofMosquittoissupportedthroughcommunityefforts. MosquittoisoneofthemostpopularMQTTimplementations,freelyavailableandwidely supportedontheInternet.Youcanobtainfurtherinformationregardingtheactualtooland communityfromitswebsite,athttp://www.mosquitto.org. SettingupMosquitto TheinstallationandconfigurationofMosquittoareverystraightforwardprocesses.Atthe timeofwritingthisbook,thelatestversionofMosquittois1.3.4.Youcanalsoobtainthe latestupdatesandinstallationinformationregardingMosquittoat http://www.mosquitto.org/download/. OnWindows,youcansimplydownloadthelatestversionoftheinstallationfilesfor Windows,whichismadeforWin32orWin64systems.Downloadandruntheexecutable filetoinstalltheMosquittobroker.TorunMosquittofromthecommandprompt,youwill havetoaddtheMosquittodirectorytothePATHvariablesintheenvironmentvariablesof thesystemproperties.InChapter1,GettingStartedwithPythonandArduino,we comprehensivelydescribedtheprocessofaddingaPATHvariabletoinstallPython.Using thesamemethod,addthepathoftheMosquittoinstallationdirectoryattheendofthe PATHvalue.Ifyouareusinga64-bitoperatingsystem,youshoulduseC:\ProgramFiles (x86)\mosquitto.Fora32-bitoperatingsystem,youshoulduseC:\Program Files\mosquittoasthepath.Onceyouaredonewithaddingthisvalueattheendofthe PATHvalue,closeanyexistingcommandpromptwindowsandopenanewCommand Promptwindow.Youcanvalidatetheinstallationbytypingthefollowingcommandinthe newlyopenedwindow.Ifeverythingisinstalledandconfiguredcorrectly,thefollowing commandshouldexecutewithoutanyerrors: C:\>mosquitto ForMacOSX,thebestwaytoinstallMosquittoistousetheHomebrewtool.Wealready wentthroughtheprocessofinstallingandconfiguringHomebrewinChapter1,Getting StartedwithPythonandArduino.InstalltheMosquittobrokerbysimplyexecutingthe followingscriptontheterminal.ThisscriptwillinstallMosquittowiththeMosquitto utilitiesandalsoconfigurethemtorunfromtheterminalascommands: $brewinstallmosquitto OnUbuntu,thedefaultrepositoryalreadyhastheinstallationpackageforMosquitto. DependingontheversionofUbuntuyouareusing,thisMosquittoversioncouldbeolder thanthecurrentversion.Inthatcase,youmustaddthisrepositoryfirst: $sudoapt-add-repositoryppa:mosquitto-dev/mosquitto-ppa $sudoapt-getupdate NowyoucaninstalltheMosquittopackagesbysimplyrunningthefollowingcommand: $sudoapt-getinstallmosquittomosquitto-clients GettingfamiliarwithMosquitto Duetothemultipleinstallationmethodsinvolvedfordifferentoperatingsystems,the initializationofMosquittomaybedifferentforyourinstance.Insomecases,Mosquitto mightalreadyberunningonyourcomputer.ForaUnix-basedoperatingsystem,youcan checkwhetherMosquittoisrunningornotwiththiscommand: $psaux|grepmosquitto Unlessyoufindarunninginstanceofthebroker,youcanstartMosquittobyexecutingthe followingcommandintheterminal.Afterexecutingit,youshouldbeabletoseethe brokerrunningwhileprintingtheinitializationparametersandotherrequestscomingtoit: $mosquitto WhenyouinstalledtheMosquittobroker,theinstallationprocesswouldalsohave installedafewMosquittoutilities,whichincludetheMQTTclientsforthepublisherand thesubscriber.TheseclientutilitiescanbeusedtocommunicatewithanyMosquitto broker. Tousethesubscriberclientutility,mosquitto_sub,usethefollowingcommandatthe terminalwiththeIPaddressoftheMosquittobroker.Aswearecommunicatingtothe Mosquittobrokerrunningonthesamecomputer,youcanavoidthe–h<Broker-IP> option.Thesubscriberutilityusesthe–toptiontospecifythenameofthetopicthatyou areplanningtosubscribe.Asyoucansee,wearesubscribingtothetesttopic: $mosquitto_sub-h<Broker-IP>-ttest Similartothesubscriberclient,thepublisherclient(mosquitto_pub)canbeusedto publishamessagetothebrokerforaspecifictopic.Asdescribedinthefollowing command,youarerequiredtousethe–moptionfollowedbyamessagetosuccessfully publishit.Inthiscommand,wearepublishingaHellomessageforthetesttopic: $mosquitto_pub-h<Broker-IP>-ttest-mHello OtherimportantMosquittoutilitiesincludemosquitto_passwordandmosquitto.conf, whichcanbeusedtomanagetheMosquittopasswordfilesandthesetupbroker configuration,respectively. GettingstartedwithMQTTonArduino andPython NowthatyouhavetheMosquittobrokerinstalledonyourcomputer,itmeansthatyou haveaworkingbrokerthatimplementstheMQTTprotocol.Ournextgoalistodevelop theMQTTclientsinArduinoandalsoinPythonsothattheywillworkaspublishersand subscribers.AfterimplementingtheMQTTclients,wewillhaveafully-functionalMQTT system,wheretheseclientscommunicatethroughtheMosquittobroker.Let’sbeginwith deployingMQTTontheArduinoplatform. MQTTonArduinousingthePubSubClientlibrary AsMQTTisanetwork-basedmessagingprotocol,youwillalwaysneedanEthernet Shieldtocommunicatewithyournetwork.Forthefollowingexercise,wewillcontinue usingthesamehardwarethatwehavebeenusingthroughoutthischapter. InstallingthePubSubClientlibrary TouseArduinoforpub/subandenablesimpleMQTTmessaging,youneedtheArduino clientlibraryforMQTT,alsoknownasthePubSubClientlibrary.ThePubSubClient libraryhelpsyoudevelopArduinoasanMQTTclient,whichcanthencommunicatewith theMQTTserver(Mosquittobrokerinourcase)runningonyourcomputer.Asthelibrary providesmethodstocreateonlyanMQTTclientandnotabroker,thefootprintofthe Arduinocodeisquitesmallcomparedtoothermessagingparadigms.ThePubSubClient libraryextensivelyutilizesthedefaultArduinoEthernetlibraryandimplementsthe MQTTclientasasubclassoftheEthernetclient. TogetstartedwiththePubSubClientlibrary,you’llfirstneedtoimportthelibrarytoyour ArduinoIDE.DownloadthelatestversionofthePubSubClientArduinolibraryfrom https://github.com/knolleary/pubsubclient/.Onceyouhavethefiledownloaded,importit toyourArduinoIDE. WewillbeusingoneoftheexamplesinstalledwiththePubSubClientlibrarytoget started.ThegoaloftheexerciseistoutilizeabasicexampletocreateanArduinoMQTT client,whileperformingminormodificationstoaccommodatethelocalnetwork parameters.WewillthenusetheMosquittocommandsyoulearnedintheprevioussection totesttheArduinoMQTTclient.Meanwhile,ensurethatyourMosquittobrokeris runninginthebackground. DevelopingtheArduinoMQTTclient Let’sstartwithopeningthemqtt_basicexamplebynavigatingtoFile|Examples| PubSubClientinourArduinoIDEmenu.Intheopenedprogram,changetheMACandIP addressvaluesforArduinobyupdatingthemac[]andip[]variables,respectively.Inthe previoussection,yousuccessfullyinstalledandtestedtheMosquittobroker.UsetheIP addressofthecomputerrunningMosquittotoupdatetheserver[]variable: bytemac[]={0x90,0xA2,0xDA,0x0D,0x3F,0x62}; byteserver[]={10,0,0,20}; byteip[]={10,0,0,75}; Asyoucanseeinthecode,weareinitializingtheclientusingtheIPaddressoftheserver, Mosquittoportnumber,andEthernetclient.Beforeusinganyothermethodforthe PubSubClientlibrary,youwillalwayshavetoinitializetheMQTTclientusingasimilar method: EthernetClientethClient; PubSubClientclient(server,1883,callback,ethClient); Furtheroninthecode,weareusingthepublish()andsubscribe()methodsonthe clientclasstopublishamessagefortheoutTopictopicandsubscribetotheinTopic topic.Youcanspecifythenameoftheclientusingtheclient.connect()method.Asyou canseeinthefollowingcodesnippet,wearedeclaringarduinoClientasthenamefor thisclient: Ethernet.begin(mac,ip); if(client.connect("arduinoClient")){ client.publish("outTopic","helloworld"); client.subscribe("inTopic"); } Asweareusingthiscodeinthesetup()function,theclientwillonlypublishthehello worldmessageonce—duringtheinitializationofthecode—whilethesubscribemethod willkeeplookingfornewmessagesforinTopicduetotheuseoftheclient.loop() methodintheArduinoloop()function: client.loop(); Now,whilerunningMosquittointhebackground,openanotherterminalwindow.Inthis terminalwindow,runthefollowingcommand.Thiscommandwilluseacomputer-based MosquittoclienttosubscribetotheoutTopictopic: $mosquitto_sub-t"outTopic" CompileyourArduinosketchanduploadit.Assoonastheuploadprocessiscomplete, youwillbeabletoseethehelloworldstringprinted.Basically,assoonastheArduino codestartsrunning,theArduinoMQTTclientwillpublishthehelloworldstringtothe MosquittobrokerfortheoutTopictopic.Ontheotherside,thatis,onthesideofthe Mosquittoclient,you’vestartedusingthemosquitto_subutilityandwillreceivethis message,asitissubscribedtooutTopic. AlthoughyouranthemodifiedArduinoexample,mqtt_basic,youcanalsofindthecode forthisexercisefromthischapter’scodefolder.Inthisexercise,theArduinoclientisalso subscribedtoinTopictoreceiveanymessagethatoriginatesforthistopic.Unfortunately, theprogramdoesn’tdisplayordealwithmessagesitobtainsasasubscriber.Totestthe subscriberfunctionalitiesoftheArduinoMQTTclient,let’sopenthemqtt_advance Arduinosketchfromthischapter’scodefolder. Asyoucanseeinthefollowingcodesnippet,wehaveaddedcodetodisplaythereceived messageinthecallback()method.Thecallback()methodwillbecalledwhenthe clientreceivesanymessagefromthesubscribedtopics.Therefore,youcanimplementall typesoffunctionalityonthereceivedmessagefromthecallback()method: voidcallback(char*topic,byte*payload,unsignedintlength){ //handlemessagearrived Serial.print(topic); Serial.print(':'); Serial.write(payload,length); Serial.println(); } Inthismqtt_advanceArduinosketch,wehavealsomovedthepublishingstatementof outTopicfromsetup()totheloop()function.Thisactionwillhelpustoperiodically publishthevalueforoutTopic.Infuture,wewillexpandthismethodtousesensor informationasmessagessothattheotherdevicescanobtainthosesensorvaluesby subscribingtothesesensortopics: voidloop() { client.publish("outTopic","FromArduino"); delay(1000); client.loop(); } Afterupdatingthemqtt_advancesketchwiththeappropriatenetworkaddresses,compile anduploadthesketchtoyourArduinohardware.TotesttheArduinoclient,usethesame mosquitto_subcommandtosubscribetooutTopic.Thistime,youwillperiodicallyget updatesforoutTopicontheterminal.Tocheckoutthesubscriberfunctionalityofyour Arduinoclient,openyourSerialMonitorwindowinyourArduinoIDE.OncetheSerial Monitorwindowbeginsrunning,executethefollowingcommandintheterminal: $mosquitto_pub–t"inTopic"–m"Test" YoucanseeintheSerialMonitorwindowthattheTesttextisprintedwiththetopic nameasinTopic.Henceforth,yourArduinowillserveasbothanMQTTpublisherandan MQTTsubscriber.Nowlet’sdevelopaPythonprogramtoimplementtheMQTTclients. MQTTonPythonusingpaho-mqtt Inthepreviousexercise,wetestedtheArduinoMQTTclientusingcommand-lineutilities. UnlessthepublishedandsubscribedmessagesarecapturedinPython,wecannotutilize themtodevelopalltheotherapplicationswe’vebuiltsofar.Totransfermessagesbetween theMosquittobrokerandthePythoninterpreter,weuseaPythonlibrarycalledpahomqtt.Thislibraryusedtobecalledmosquitto-pythonbeforeitwasdonatedtothePaho project.IdenticaltotheArduinoMQTTclientlibrary,thepaho-mqttlibraryprovides similarmethodstodeveloptheMQTTpub/subclientusingPython. Installingpaho-mqtt LikeallotherPythonlibrariesweused,paho-mqttcanalsobeinstalledusingSetuptools. Toinstallthelibrary,runthiscommandintheterminal: $sudopipinstallpaho-mqtt FortheWindowsoperatingsystem,useeasy_install.exetoinstallthelibrary.Onceitis installed,youcancheckthesuccessfulinstallationofthelibraryusingthefollowing commandinthePythoninteractiveterminal: >>>importpaho.mqtt.client Usingthepaho-mqttPythonlibrary Thepaho-mqttPythonlibraryprovidesverysimplemethodstoconnecttoyourMosquitto broker.Let’sopenthemqttPython.pyfilefromthischapter’scodefolder.Asyoucansee, wehaveinitializedthecodebyimportingthepaho.mqtt.clientlibrarymethod: importpaho.mqtt.clientasmq JustliketheArduinoMQTTlibrary,thepaho-mqttlibraryalsoprovidesmethodsto connecttotheMosquittobroker.Asyoucansee,wehavenamedourclient mosquittoPythonbysimplyusingtheClient()method.Thelibraryalsoprovides methodsforactivities,forexample,whentheclientreceivesamessage,on_message,and publishesamessage,on_publish.Onceyouhaveinitializedthesemethods,youcan connectyourclienttotheMosquittoserverbyspecifyingtheserverIPaddressandthe portnumber. Tosubscribetoorpublishforatopic,yousimplyneedtoimplementthesubscribe()and publish()methodsontheclient,respectively,asdisplayedinthefollowingcodesnippet. Inthisexercise,weareusingtheloop_forever()methodfortheclienttoperiodically checkthebrokerforanynewmessages.Asyoucanseeinthecode,weareexecutingthe publishTest()functionbeforethecontrolenterstheloop: cli=mq.Client('mosquittoPython') cli.on_message=onMessage cli.on_publish=onPublish cli.connect("10.0.0.20",1883,15) cli.subscribe("outTopic",0) publishTest() cli.loop_forever() Itisveryimportanttorunalltherequiredfunctionsorpiecesofcodebeforeyouenterthe loop,astheprogramwillentertheloopwiththeMosquittoserveronceloop_forever()is executed.Duringthisperiod,theclientwillonlyexecutetheon_publishandon_message methodsforanyupdateonthesubscribedorpublishedtopics. Toovercomethissituation,weareimplementingthemultithreadingparadigmofthe Pythonprogramminglanguage.Althoughwearenotgoingtodivedeepinto multithreading,thefollowingexamplewillteachyouenoughtoimplementbasic programminglogic.TounderstandmoreaboutthePythonthreadinglibraryandsupported methods,visithttps://docs.python.org/2/library/threading.html. Tobetterunderstandourimplementationofthethreadingmethod,checkoutthefollowing codesnippet.Asyoucanseeinthecode,weareimplementingrecursionforthe publishTest()functionevery5seconds,usingtheTimer()threadingmethod.Usingthis method,theprogramwillstartanewthreadthatisseparatefromthemainprogramthread thatcontainstheloopforMosquitto.Every5seconds,thepublishTest()functionwillbe executed,recursivelyrunningthepublish()method,andultimatelypublishingamessage forinTopic: importthreading defpublishTest(): cli.publish("inTopic","FromPython") threading.Timer(5,publishTest).start() Now,inthemainthread,whentheclientgetsanewmessagefromthesubscribedtopics, thethreadinvokestheonMessage()function.Inthecurrentimplementationofthis function,wearejustprintingthetopicandmessagefordemonstrationpurposes.Inreal applications,thisfunctioncanbeusedtoimplementanykindofoperationonthereceived message,forexample,writingamessagetoadatabase,runninganArduinocommand, selectinganinput,callingotherfunctions,andsoon.Inshort,thisfunctionistheentry pointofanyinputyoureceivethroughtheMosquittobrokerfromyoursubscribedtopics: defonMessage(mosq,obj,msg): printmsg.topic+":"+msg.payload Similarly,everytimeyoupublishamessagefromthesecondthread,theonPublish() functionisexecutedbytheprogram.Justlikethepreviousfunction,youcanimplement variousoperationswithinthisfunction,whilethefunctionbehavesastheexitpointofany messagepublishedusingthisPythonMQTTclient.Inthecurrentimplementationof onPublish(),wearenotperforminganyoperations: defonPublish(mosq,obj,mid): pass IntheopenedPythonfile,mqttPython.py,youwillonlyneedtochangetheIPaddressof theserverrunningtheMosquittobroker.IfyouarerunningtheMosquittobrokeronthe samecomputer,youcanuse127.0.0.1astheIPaddressofthelocalhost.Beforeyou executethisPythonfile,ensurethatyourArduinoisrunningwiththeMQTTclientwe createdinthepreviousexercise.Onceyourunthiscode,youcanstartseeingthemessages beingsentfromyourArduinointhePythonterminal,asdisplayedinthefollowing screenshot.Wheneveranewmessageisreceived,thePythonprogramprintstheoutTopic topicnamefollowedbytheFromArduinomessage.ThisconfirmsthatthePythonclient isreceivingmessagesforoutTopic,towhichitissubscribed.Ifyoulookbackatthe Arduinocode,youwillnoticethatitisthesamemessagethatwewerepublishingfromthe Arduinoclient. Now,toconfirmthepublishingoperationofthePythonMQTTclient,let’sopentheSerial MonitorwindowfromyourArduinoIDE.AsyoucanseeintheSerialMonitorwindow, textthatcontainstheinTopictopicnameandtheFromPythonmessageisbeingprinted every5seconds.ThisvalidatesthePythonpublisher,aswearepublishingthesame messageforthesametopicevery5secondsthroughthepublishTest()function. Exercise4–MQTTGatewayforArduino Inexercise3,weusedtheRESTarchitecturetotransfermotionandhumiditysensordata betweenourArduinoandthewebbrowser.Inthisexercise,wewilldevelopanMQTT GatewayusingtheMosquittobrokerandtheMQTTclientstotransfersensorinformation fromourArduinotothewebbrowser.Thegoaloftheexerciseistoreplicatethesame componentsthatweimplementedintheRESTexercise,butwiththeMQTTprotocol. Asyoucanseeinthearchitecturalsketchofthesystem,wehaveArduinowiththe EthernetShieldconnectedtoourhomenetwork,whilethecomputerisrunningthe MosquittobrokerandthePythonapplicationsonthesamenetwork.Weareusingthesame sensors(thatis,amotionsensorandahumiditysensor)andthesamehardwaredesignthat weusedinthepreviousexercisesinthischapter. Inthesoftwarearchitecture,wehavetheArduinocodethatinterfaceswiththehumidity andmotionsensorsusinganalogpin0anddigitalpin3,respectively.Usingthe PubSubClientlibrary,theArduinopublishessensorinformationtotheMosquittobroker. OntheMQTTGateway,wehavetwodifferentPythonprogramsrunningonthecomputer. Thefirstprogramusesthepaho-mqttlibrarytosubscribeandretrievesensorinformation fromtheMosquittobrokerandthenpostittothewebapplication.ThesecondPython program,whichisbasedonweb.py,implementsthewebapplicationswhileobtaining sensorvaluesfromthefirstPythonprogram.Thisprogramprovidesauserinterfacefront fortheMQTTGateway. AlthoughbothoftheprecedingPythonprogramscanbepartofasingleapplication,we aredelegatingthetasksofcommunicatingwithMosquittoandservinginformationusing thewebapplicationtoseparateapplicationsforthefollowingreasons: Wewanttodemonstratethefunctionsofbothlibraries,paho-mqttandweb.py,in separateapplications Ifyouwanttorunroutinesbasedonpaho-mqttandweb.pyinthesameapplication, youwillhavetoimplementmultithreading,asbothoftheseroutinesneedtoberun independently WealsowanttodemonstratethetransferofinformationbetweenthetwoPython programsusingPython-basedRESTmethodswiththehelpofthehttpliblibrary Inthisexercise,wearelabelinghumidityandmotionsensorinformationwiththetopic labelsArduino/humidityandArduino/motion,respectively.TheArduino-basedMQTT publisherandthePython-basedMQTTsubscriberwillbeutilizingthesetopicnamesif theywanttotransferinformationthroughtheMosquittobroker.Beforewebeginwith implementingtheMQTTclientonourArduino,let’sstarttheMosquittobrokeronour computer. DevelopingArduinoastheMQTTclient ThegoaloftheArduinoMQTTclientistoperiodicallypublishthehumidityandmotion datatotheMosquittobrokerrunningonyourcomputer.OpentheStep1_Arduino.ino sketchfromtheExercise4-MQTTgatewayfolderinyourcoderepository.Likeallthe otherexercises,youfirstneedtochangetheMACaddressandtheserveraddressvalue, andassignanIPaddressforyourArduinoclient.Onceyouaredonewiththese modifications,youcanseethesetup()functionthatwearepublishingasaone-time connectionmessagetotheMosquittobrokertochecktheconnection.Youcanimplement asimilarfunctiononaperiodicbasisifyouhaveaproblemwithkeepingyourMosquitto connectionalive: if(client.connect("Arduino")){ client.publish("Arduino/connection","Connected."); } Intheloop()method,weareexecutingthepublishData()functionevery5seconds.It containsthecodetopublishsensorinformation.Theclient.loop()methodalsohelpsus keeptheMosquittoconnectionaliveandavoidstheconnectiontimeoutfromthe Mosquittobroker. voidloop() { publishData(); delay(5000); client.loop(); } Asyoucanseeinthefollowingcodesnippet,thepublishData()functionobtainsthe sensorvaluesandpublishesthemusingtheappropriatetopiclabels.Youmighthave noticedthatweareusingthedtostrf()functioninthisfunctiontochangethedataformat beforepublishing.Thedtostrf()functionisafunctionprovidedbythedefaultArduino librarythatconvertsadoublevalueintoanASCIIstringrepresentation.Wearealso addingadelayofanother5secondsbetweenthesuccessivepublishingofsensordatato avoidanydatabufferingissues: voidpublishData() { floathumidity=getHumidity(22.0); humidityC=dtostrf(humidity,5,2,message_buff2); client.publish("Arduino/humidity",humidityC); delay(5000); intmotion=digitalRead(MotionPin); motionC=dtostrf(motion,5,2,message_buff2); client.publish("Arduino/motion",motionC); } Completeanyothermodificationyouwanttoimplement,andthencompileyourcode.If yourcodeiscompiledsuccessfully,youcanuploadittoyourArduinoboard.Ifyour Mosquittoisrunning,youwillbeableseethatanewclientisconnectedasArduino, whichistheclientnameyouspecifiedintheprecedingArduinocode. DevelopingtheMQTTGatewayusingMosquitto YoucanhavetheMosquittobrokerrunningonthesamecomputerastheMosquitto Gateway,oronanyothernodeinyourlocalnetwork.Forthisexercise,let’srunitonthe samecomputer.OpentheprogramfilenamedmosquittoGateway.pyforthisstagefrom theStep2_Gateway_mosquittofolder,whichisinsidetheExercise4-MQTTgateway folder.ThefirststageoftheGatewayapplicationincludesthepaho-mqttbasedPython program,whichsubscribestotheMosquittobrokerfortheArduino/humidityand Arduino/motiontopics: cli.subscribe("Arduino/humidity",0) cli.subscribe("Arduino/motion",0) WhenthisMQTTsubscriberprogramreceivesamessagefromthebroker,itcallsthe onMessage()function,aswe’vealreadydescribedinthepreviouscodingexercise.This methodthenidentifiestheappropriatesensortypeandsendsthedatatotheweb.py programusingthePOSTmethod.WeareusingthedefaultPythonlibrary,httplib,to implementthePOSTmethodinthisprogram.Whileusingthehttpliblibrary,youhaveto usetheHTTPConnection()methodtoconnecttothewebapplicationrunningonport number8080. Note Althoughthisprogramrequiresthatyourwebapplication(secondstage)mustrunin parallel,wearegoingtoimplementthiswebapplicationintheupcomingsection.Make surethatyoufirstrunthewebapplicationfromthenextsectionbeforeexecutingthis program;otherwiseyouwillendupwitherrors. Theimplementationofthislibraryrequiresthatyoufirstimportthelibraryintoyour program.Beingabuilt-inlibrary,httplibdoesnotrequireanadditionalsetupprocess: importhttplib Oncetheconnectionisestablishedwiththewebapplication,youhavetopreparethedata thatneedstobesentinthePOSTmethod.Thehttplibmethodusestherequest()method ontheopenedconnectiontopostthedata.Youcanalsousethesamemethodinother applicationstoimplementtheGETfunction.Onceyouaredonewithsendingthedata,you canclosetheconnectionusingtheclose()method.Inthecurrentimplementationofthe httpliblibrary,wearecreatingandclosingtheconnectiononeachmessage.Youcanalso declaretheconnectionoutsidetheonMessage()functionandcloseitwhenyouterminate theprogram: defonMessage(mosq,obj,msg): printmsg.topic connection=httplib.HTTPConnection('10.0.0.20:8080') ifmsg.topic=="Arduino/motion": data="motion:"+msg.payload connection.request('POST','/data',data) postResult=connection.getresponse() printpostResult elifmsg.topic=="Arduino/humidity": data="humidity:"+msg.payload connection.request('POST','/data',data) postResult=connection.getresponse() printpostResult else: pass connection.close() Onceyouhaveperformedtheappropriatemodifications,suchaschangingtheIPaddress oftheMosquittobrokerandtheweb.pyapplication,gotothenextexercisebeforerunning thecode. ExtendingtheMQTTGatewayusingweb.py TheMQTTGatewaycodeprovidestheuserinterfacewiththesensorinformationusing theweb.pybasedwebapplication.Thecodeisquitesimilartowhatyouimplementedin exercise3.TheprogramfileisnamedGatewayWebApplication.pyandlocatedinyour Exercise4-MQTTgatewaycodefolder.Inthisapplication,wehaveremovedthesensor selectionprocessbysimplyimplementingabutton,displayedasRefresh.Thisapplication waitsforthePOSTmessagefromthepreviousprogram,whichwillbereceivedonthe http://<ip-address>:8080/dataURL,ultimatelytriggeringthedataclass.ThePOST methodinthisclasswillsplitthereceivedstringtoidentifyandupdatethevalueofthe humidityandmotionglobalsensorvariables: classdata: defPOST(self): globalmotion,humidity i=web.input() data=web.data() data=data.split(":") ifdata[0]=="humidity": humidity=data[1] elifdata[0]=="motion": motion=data[1] else: pass return"Ok" ThedefaultURL,http://<ip-address>:8080/,displaysthebasetemplatewiththe Refreshbutton,populatedusingtheForm()method.Asdisplayedinthefollowingcode snippet,thedefaultindexclassrendersthetemplatewiththeupdated(current)humidity andmotionvalueswhenitreceivestheGETorPOSTrequest: classindex: submit_form=form.Form( form.Button('Refresh', type="submit", description='refresh') ) #GETfunction defGET(self): f=self.submit_form() returnrender.base(f,humidity,motion) #POSTfunction defPOST(self): f=self.submit_form() returnrender.base(f,humidity,motion) Runtheprogramfromthecommandline.Makesurethatyouarerunningbothprograms fromseparateterminalwindows. TestingyourMosquittoGateway Youhavetofollowthesestepsinthespecifiedordertosuccessfullyexecuteandtestall thecomponentsofthisexercise: 1. RuntheMosquittobroker. 2. RuntheArduinoclient.Ifitisrunningalready,restarttheprogrambypoweringoff theArduinoclientandpoweringitonagain. 3. ExecutethewebapplicationinyourterminalorfromtheCommandPrompt. 4. Runthepaho-mqttGatewayprogram. Ifyoufollowthissequence,allofyourprogramswillstartwithoutanyerrors.Ifyouget anyerrorswhileexecuting,makesurethatyoufollowalltheinstructionscorrectly,while alsoconfirmingtheIPaddressesinyourprograms.TocheckoutyourArduinoMQTT client,opentheSerialMonitorwindowinyourArduinoIDE.Youwillbeabletoseethe periodicpublicationofthesensorinformation,asdisplayedinthisscreenshot: NowopenawebbrowseronyourcomputerandgototheURLofyourwebapplication. Youshouldbeabletoseeawindowthatlookslikewhatisshowninthefollowing screenshot.YoucanclickontheRefreshbuttontocheckouttheupdatedsensorvalues. Note Wehavesetadelayof5secondsbetweensuccessivesensorupdates.Henceforth,you won’tbeabletoseetheupdatedvaluesifyourapidlypresstheRefreshbutton. OntheGatewayprogramterminal,youwillbeabletoseethelabelofthetopiceverytime theprogramreceivesanewmessagefromMosquitto.Ifthedelaybetweensuccessive sensorupdatesisnotsufficientandhttplibdoesn’thaveenoughtimetogettheresponse backfromtheweb.pyapplication,theprogramwillgenerateanerrormessagewiththe httplibfunction.Althoughwerequireanadditionaldelayforhttplibtosuccessively sendthedataandreceivetheresponse,wewillbeabletoavoidthisdelaywhenwe implementthecorePythoncodewiththreading,avoidingtheentirenotionofPOSTin betweentheprograms: Withthisexercise,youhaveimplementedtwodifferenttypesofmessagingarchitectureto transferdatabetweenyourArduinoandyourcomputerorwebapplicationsusingyour homenetwork.Althoughwerecommendtheuseofhardware-centricandlightweight MQTTmessagingparadigmsoverRESTarchitecture,youcanuseeitherofthese communicationmethodsaccordingtotheapplication’srequirements. Summary Connectivitytocomputernetworkscanreallyopenuplimitlesspossibilitiesforfuture applicationdevelopmentusingArduino.Westartedthechapterbyexplainingimportant computernetworkfundamentals,whilealsocoveringhardwareextensionsthatenable computernetworkingforArduino.Regardingthevariousmethodsofenabling networking,webeganthechapterbyestablishingawebserverforArduino.Weconcluded thatthewebserveronArduinoisnotthebestwayfornetworkcommunicationduetothe limitednumberofconnectionsofferedbythewebserver.Thenwedemonstratedtheuse ofArduinoasawebclienttoenableHTTP-basedGETandPOSTrequests.Althoughthis methodisusefulforrequest-basedcommunicationandrequiresfewerresourcescompared toawebserver,itisstillnotthebestwayforsensorcommunicationduetotheadditional dataoverhead.Inthelaterpartofthechapter,wedescribedalightweightmessaging protocol,MQTT,designedspecificallyforsensorcommunication.Wedemonstratedits superioritytoHTTP-basedprotocolsusingafewexercises. WiththehelpofeachmethodofArduinoEthernetcommunication,youlearnedabout compatiblePythonlibrariesusedtosupportthesecommunicationmethods.Weusedthe web.pylibrarytodevelopawebserverusingPython,anddemonstratedtheuseofthe librarywithmultipleexamples.TosupporttheMQTTprotocol,weexploredanMQTT broker,Mosquitto,andemployedthePythonlibrary,paho_mqtt,toservetheMQTT requests. Overall,wecoveredeverymajoraspectofArduinoandPythoncommunicationmethods throughoutthischapter,anddemonstratedthemwithsimpleexercises.Intheupcoming chapters,wewillbuilduponthebasicsyoulearnedinthischapter,inordertodevelop advancedArduino-PythonprojectsthatwillenableremoteaccesstoourArduinohardware throughtheInternet. Chapter9.ArduinoandtheInternetof Things Inthepreviouschapter,welearnedhowtoaccessArduinousingEthernetfromaremote location.ThemainobjectivewastogetyoustartedwithdevelopingArduino-based networkapplicationsusingPython.Wewereabletoaccomplishthisusingvarioustools suchastheweb.pyPythonlibrary,MosquittoMQTTbroker,andtheArduinoEthernet library.RemoteaccesstosensordataviaaPython-likeextensiblelanguagecanopenup limitlesspossibilitiesforsensor-basedwebapplications.Inrecentyears,therapidgrowth oftheseapplicationshasenabledthedevelopmentofadomaincalledtheInternetof Things(IoT). Inthelastchapter,weworkedonArduinonetworking.However,itwaslimitedtoLAN andthepremiseoftheexerciseswaslimitedtoyourhomeoroffice.Wedidn’teven involvetheInternettoenableglobalaccessinourexercises.TraditionalIoTapplications requireArduinotobeaccessedremotelyfromanypartoftheworldviatheInternet.Inthis chapter,wewillextendtheArduinonetworkingconceptsbyinterfacingArduinowith cloud-basedplatforms.Wewillalsodevelopwebapplicationstoaccessthesensordata fromthesecloudplatforms.Laterinthechapter,wewillgothroughtheprocessofsetting upyourcloud-basedmessagingplatformtoservesensordata.Attheendofthischapter, youshouldbeabletodesignanddevelopfull-stackIoTapplications,usingArduino, Python,andthecloud. GettingstartedwiththeIoT LongbeforetheInternet,sensor-andactuator-basedelectroniccontrolsystemsexistedin high-techautomationsystems.Inthosesystems,sensorswereinterfacedtothe microcontrollerviahard-wiredconnections.Duetoextensibilitylimitations,thecoverage areaofthesesystemswasgeographicallyrestricted.Examplesofthesehigh-techsystems includedfactoryautomation,satellitesystems,weaponsystems,andsoon.Inmostcases, thesensorsusedinthesesystemswerehugeandthemicrocontrollerswerealsolimitedby theirlowcomputationalcapabilities. Withrecentadvancementsintechnology,especiallyinthesemiconductorindustry,the physicalsizeofsensorsandmicrocontrollershassignificantlyreduced.Ithasalsobeen madepossibletomanufacturelow-costandhighlyefficientelectroniccomponents,hence todayitisrelativelyinexpensivetodevelopsmallandefficientsensor-basedhardware products.ArduinoandRaspberryPiaregreatexamplesoftheseachievements.These sensor-andactuator-basedhardwaresystemsinterfacewiththephysicalworldthatwelive in.Thesensorsmeasurevariouselementsfromthephysicalenvironment,whilethe actuatorsmanipulatethephysicalenvironment.Thesetypesofhardware-basedelectronic systemsarealsoknownasphysicalsystems. Ontheotherfront,advancementsinthesemiconductorindustryalsoenabledthe developmentofhighlyefficientcomputationunits,empoweringpersonalcomputerand networkingindustries.Thismovementledtotheworldwidenetworkofconnected computerscalledCyberWorldortheInternet.Everyday,petabytesofdatagetgenerated andtransferredacrosstheInternet. ThedomainofIoTstandsatthecrossroadsoftheseprogressesinphysicalandcyber systems,whereancienthardwiredsensor-basedsystemsarereadytogetupgradedtomore powerfulandefficientsystemsthatarealsohighlyconnectedthroughtheInternet.Dueto thelargenumberofsensorsinvolved,thesesystemsgenerateandsendanavalancheof data.Thedatageneratedbythesesensorshasalreadyeclipsedthedatageneratedby humans. TheIoThasstartedtobecomeasignificantdomaininrecentyearsafteralargenumberof consumerIoTproductshavestartedenteringthemarket.Theseproductsinclude applicationsinhomeautomation,healthcare,activitytracking,smartenergy,andsoon. OneofthemajorreasonsbehindtherapidgrowthoftheIoTdomainistheintroductionof thesevisiblesolutions.Inalargenumberofcases,thiswasmadepossibleduetofastand inexpensiveprototypingthatwasenabledbyArduinoandotheropensourcehardware platforms. Uptothispointinthebook,wehavelearnedvariousmethodsofinterfacingsensorsand thendevelopingapplicationsusingtheseconnectedsensors.Inthischapter,wewilllearn thelaststepinthedevelopmentofafull-stackIoTapplication—enablingaccessforyour Python-ArduinoapplicationthroughtheInternet.Now,let’strytofirstunderstandthe architectureoftheIoT. ArchitectureofIoTwebapplications Inthisbook,wehavecoveredthreemajorconceptsinthefirsteightchapters: Physicallayer:WeusedvarioussensorsandactuatorswiththeArduinoboardto dealwiththephysicalenvironment.Thesensorssuchasthetemperaturesensor, humiditysensor,andmotionsensorwereusedmeasuredthephysicalphenomenon, whiletheactuatorssuchasLEDswereutilizedtoalterorproducephysicalelements. Computationlayer:WeusedArduinosketchesandPythonprogramstoconvert thesephysicalelementsintonumericaldata.Wealsoutilizedthesehigh-level languagestoperformvariouscomputationssuchascalculatingrelativehumidity, developinguserinterfaces,plottingdata,andprovidingwebinterfaces. Interfacinglayer:Throughoutthematerialthatwecovered,wealsoutilizedvarious interfacingmethodstoestablishcommunicationbetweenArduinoandPython.For interfacingpartoftheinterfacinglayerbetweenthephysicalandcomputationlayers, weusedserialportlibraries,establishednetwork-basedcommunicationusingthe RESTandMQTTprotocol,anddevelopedwebapplications. Asyoucansee,wehavedevelopedapplicationswithtightly-coupledphysical, computation,andinterfacinglayers.Intheresearchdomain,thesetypesofapplicationsare alsoknownascyber-physicalsystems.Oneofthewidelyusedandpopulartermsforthe domainofcyber-physicalsystemistheIoT.Althoughthecyber-physicaldomainis thoroughlydefinedcomparedtotheIoT,theIoThasrecentlygainedmorepopularitydue tothelargenumberofsubdomains—industrialInternet,wearabledevices,connected devices,smartgrid,andsoon—thatarecoveredunderthisumbrellaterm.Insimple terms,anapplicationcanqualifyasanIoTapplicationifitconsistsofhardwaredevices thatdealwiththephysicalworldandhavesufficientcomputationalcapabilitieswith Internetconnectivity.Let’strytounderstandthearchitectureoftheIoTfromthematerial thatwehavealreadycovered. Onthephysicalside,thefollowingfigureshowsthehardwarecomponentsthatweutilized todealwiththephysicalenvironment.Thesensorsandactuatorsthatinterfacewiththe actualphysicalworldcanbeconnectedtoArduinousingmultiplelow-levelprotocols. ThesecomponentscanbeconnectedusingGPIOpinsandusingtheI2CorSPIprotocols. ThedataacquiredfromthesecomponentsgetsprocessedontheArduinoboardusingthe codethatisuploadedbytheuser.AlthoughtheArduinocodecanbemadeself-reliantto executetaskswithoutanyexternalinputs,theseinputsfromusersorotherapplicationsare requiredinadvancedapplications. Aspartofthecommunicationlayer,Arduinocanbeconnectedlocallytoothercomputers usingUSB.OnecanextendthecoveragerangebyutilizingEthernet,Wi-Fi,oranyother radiocommunicationmethod. Asillustratedinthefollowingfigure,thesensordataiscollectedusingcomputationunits foradvanceprocessing.Thesecomputationunitsarepowerfulenoughtohostoperating systemsandprogrammingplatforms.Inthisbook,weutilizedPythontodevelopvarious featuresatthecomputationlayer.Atthislevel,weperformedhigh-levelcomputationtasks suchasdevelopinggraphicaluserinterfacesusingtheTkinterlibrary,plottingcharts usingthematplotliblibrary,anddevelopingwebapplicationsusingtheweb.pylibrary. Inallthecodingexercisesthatweperformedpreviously,thephysicalcoverageareasof theprojectswerelimitedbecauseofhardwiredserialinterfacesorlocalEthernetnetwork, asdisplayedinthefollowingfigure: Todevelopfull-stackIoTapplications,weneedtoremotelyaccessArduinoorhostthe computationlayerontheInternet.Inthischapter,wearegoingtoworkonthismissing linkanddevelopvariousapplicationstoprovideInternetconnectivitytotheexercises.To performthisoperation,wearegoingtoutilizeacommercialcloudplatforminthefirst sectionanddevelopourcustomizedplatforminthelatersection. Asthefocusofthischapterisgoingtobeoncloudconnectivity,wearenotgoingto developahardwarecircuitforeachexercise.Wewillgothroughthehardwaredesign exerciseonlyonceandkeepusingthesamehardwareforalltheprogrammingexercises. Similarly,wewillalsoreusetheweb.pyprogramsthatwedevelopedintheprevious chaptertofocusoncodesnippetsthatareassociatedwithPythonlibrariestodevelop cloudapplications. Hardwaredesign Let’sbeginbydevelopingstandardhardwareforalltheupcomingexercises.Wewillneed theArduinoboardthatisattachedtotheEthernetShieldtousetheEthernetprotocolfor networkconnectivity.Intermsofcomponents,youwillbeusingsimplesensorsand actuatorsthatyoualreadyusedinthepreviouscodingexercises.WewillusethePIR motionsensorandtheHIH-4030humiditysensortoprovidedigitalandanalogoutputs, respectively.WewillalsohaveanLEDaspartofthehardwaredesignandthiswillbe usedincodingexercisesasanactuator.Formoreinformationregardingthepropertiesand detailedexplanationsofthesesensors,youcanrefertopreviouschapters. Tobeginassemblyofthehardwarecomponents,firstattachtheEthernetShieldontopof theArduinoboard.Connectthesensorsandactuatorstotheappropriatepins,asdisplayed inthefollowingfigure.Onceyouhavethehardwareassembled,youcanconnectthe EthernetShieldtoyourhomerouterusingtheEthernetcable.Youwillneedtopowerthe boardusingtheUSBcabletouploadtheArduinocodefromyourcomputer.Incaseyou wanttodeploytheArduinoboardtoaremotelocation,youwillneedanexternal5V supplytopowerArduino. TheIoTcloudplatforms ThetermIoTcloudplatformisusedforthecloudplatformsthatprovideveryspecific services,protocolsupport,andweb-basedtoolsforIoTapplications.Inmoreinformal terms,thesecloudIoTplatformscanbeusedtouploadyoursensordataandaccessthem fromanywhereusingtheInternet.Withthesebasicfeatures,theyalsoprovidetoolsto access,visualize,andprocessyoursensordataonvariousplatformssuchascomputers andsmartphones.ExamplesofsimilarIoTcloudplatformsincludeXively (http://www.xively.com),2lemetry(http://www.2lemetry.com),Carriots (http://www.carriots.com),ThingSpeak(http://thingspeak.com),andsoon. ThefollowingfigureshowsthearchitectureofanIoTsystemwithanArduino-based sensorsystemthatissendingdatatoacloudplatform,whileacomputationunitis accessingthedataremotelyfromthecloud: Xively,beingtheoldestandmostpopularIoTplatform,hasalargeamountofcommunitybasedonlinehelpthatisavailableforbeginners.Thisisoneofthemajorreasonswhywe havechosenXivelyasourplatformofchoicefortheupcomingexercises.Recently, Xivelyhaschangedtheirpolicyofcreatingfreedeveloperaccountsandauserhasto requestaccesstothisfreeaccountinsteadofobtainingonefreely.Incaseyouwanttouse anotherplatformotherthanXively,wehavebrieflycoveredafewsimilarplatformsatthe endofthissection. Xively–acloudplatformfortheIoT XivelyisoneoftheveryfirstIoT-specificcloudplatformsthatwasfoundedin2007as Pachube.Itwentthroughmultiplenamechanges,asitwascalledCosm,butitiscurrently knownasXively.XivelyprovidesanIoTcloudplatformwithtoolsandservicesto developconnecteddevices,products,andsolutions.Asmentionedonitswebsite,Xively isthepubliccloudthatisspecificallybuiltfortheIoT. SettingupanaccountonXively Now,wecangoaheadandsetupanewuseraccountfortheXivelyplatform.Tosetupan account,youneedtoexecutefollowingstepsinthegivenorder: 1. TobeginthesignupprocessonXively.com,openhttps://xively.com/signupinaweb browser. 2. Onthesignuppage,youwillbepromptedtoselecttheusernameandthepassword, asdisplayedinthefollowingscreenshot: 3. Onthenextpage,youwillbeaskedtoentersomeadditionalinformationthat includesyourfullname,organization’sname,country,zipcode,timezone,andso on.FillouttheformappropriatelyandclickontheSignUpbutton: 4. Xivelywillsendanactivatione-mailtothee-mailaccountthatyouspecifiedinthe form.Openthee-mailandclickontheactivationlink.Checkyourspamfolderifyou don’tseethee-mailinyourinbox. 5. Onceyouclickontheactivationlink,youwillberedirectedtothewelcomepageon Xively’swebsite.Weadviseyoutogothroughthetutorialsprovidedonthewelcome page,asitwillhelpyoutogetfamiliarwiththeXivelyplatform. 6. Aftercompletingthetutorials,youcancomebacktothemainuserscreenfromthe pageusingthehttps://xively.com/loginlink. Ifyouarenotalreadyloggedin,youwillrequireyoure-mailaddressastheusername andanappropriatepasswordtologintotheXivelyplatform. WorkingwithXively TheXivelyplatformletsyoucreateclouddeviceinstancesthatcanbeconnectedtothe actualhardwaredevice,app,orservice.Performthefollowingstepsinordertoworkwith Xively: 1. TobeginworkingwiththeXivelyplatform,addadevicefromthemainpage,as displayedinthefollowingscreenshot: 2. OnceyouclickontheAddDevicebutton,itwillpromptyoutothefollowing windowwhereyouwillbeaskedtoprovidethedevicename,description,and privacystatusofthedevicethatyouaregoingtoassign.Intheform,selectadevice namethatyouwantyourdevelopmentdevicetobecalled,provideabrief description,andselectPrivateDeviceastheprivacystatus: 3. OnceyouclicktheAddDevicebutton,Xivelywillcreateadeviceinstancewith automatically-generatedparametersandpromptyoutothedevelopmentworkbench environment.Onthepageofthedevicethatyoujustadded,youcanseevarious identificationandsecurityparameterssuchasProductID,SerialNumber,FeedID, FeedURL,andAPIEndpoint.Fromamongtheseparameters,youwillfrequently needtheFeedIDinformationfortheupcomingexercises: 4. AuniqueandsecureAPIkeyofthenewlycreateddeviceisalsolocatedintherighthandsidebarofthepage.ThisAPIkeyisveryimportantandneedstobesecured justlikeyourpassword,asanyonewiththeAPIkeycanaccessthedevice. 5. Now,toremotelyaccessthisdevice,opentheterminalandusethecURLcommand tosenddatatoit.Inthefollowingcommand,changethe<Your_Feed_ID>and <Your_API_key>valueswiththeonesavailableforyourdevice: $curl--requestPUT--data"0,10"--header"X-ApiKey:<Your_API_key" https://api.xively.com/v2/feeds/<Your_Feed_ID>.csv 6. Asyoucansee,thepreviouscommandsentthevalueof10onchannel0ofyour deviceonXively.Afterexecutingthepreviouscommand,youwillnoticethatthe XivelyworkbenchisupdatedwiththeinformationthatyoujustsentusingcURL: 7. Trysendingmultiplevaluesonchannel0usingthepreviouscommand.Onthe Xivelyworkbench,youwillbeabletoseeaplotbeinggeneratedbythesevaluesin realtime.Accesstheplotbyclickingonchannel0intheworkbench: Usingthemethodthatweusedinthisexample,wecanalsoconfigureArduinotosend sensorvaluesautomaticallytotheXivelyplatform.Thiswillenablethestorageand visualizationofArduinodataonXively. AlternativeIoTplatforms Inthissection,wehaveprovidedimportantlinksfortheThingSpeakandCarriots platforms.Aswearenotcoveringtheseplatformsindetail,theselinkswillhelpyouto findsimilarexamplestointerfaceArduinoandPythonwithThingSpeakandCarriots. ThingSpeak ThetutorialsinthefollowinglinkswillhelpyoutogetfamiliarwiththeThingSpeak platformifyouchosetouseitinsteadofXively: Theofficialwebsite:https://thingspeak.com/ UsingArduinoandEthernettoupdateaThingSpeakchannel: http://community.thingspeak.com/tutorials/arduino/using-an-arduino-ethernet-shieldto-update-a-thingspeak-channel/ ArduinoexamplesforThingSpeak:https://github.com/iobridge/ThingSpeakArduino-Examples CommunicatingwithThingSpeakusingPython: http://www.australianrobotics.com.au/news/how-to-talk-to-thingspeak-with-pythona-memory-cpu-monitor UsingArduinoandPythontotalktoaThingSpeakchannel: http://vimeo.com/19064691 SeriesofThingSpeaktutorials:http://community.thingspeak.com/tutorials/ ThingSpeakisanopensourceplatformandyoucancreateyourowncustomizedversion ofThingSpeakusingthefilesprovided.Youcanobtainthesefilesandtheassociated guidelinefromhttps://github.com/iobridge/ThingSpeak. Carriots Carriotsalsoprovidesafree,basicaccountfordevelopers.IfyouwanttouseCarriotsas analternativetoXively,usethetutorialsinthefollowinglinkstogetstarted: Theofficialwebsite:https://www.carriots.com/ SettingupanaccountonCarriots:https://learn.adafruit.com/wireless-gardeningarduino-cc3000-wifi-modules/setting-up-your-carriots-account TheCarriotslibraryforArduino:https://github.com/carriots/arduino_library ACarriotsexampleforArduino:https://github.com/carriots/arduino_examples ConnectCarriotstothePythonwebapplication: http://www.instructables.com/id/Connect-your-Carriots-Device-to-Panics-Status-Boa/ Developingcloudapplicationsusing PythonandXively Now,youhaveabasicideaabouttheavailablecommercialIoTplatformsandyoucan selectoneaccordingtoyourcomfortlevelandrequirements.Itwillbeverydifficultto comprehensivelyexplaineverycloudplatformwithpracticalexamples,astheobjectiveof thischapteristomakeyoufamiliarwithintegratingthecloudplatformwithPythonand Arduino.Forthisreason,wearegoingtouseXivelyasthedefactoIoTcloudplatformfor therestoftheintegrationexercises. NowthatyouknowhowtocreateanaccountonXivelyandworkwiththeXively platform,itistimetostartinterfacingrealhardwarewiththeXivelyplatform.Inthis section,wewillgothroughmethodstouploadanddownloaddatafromXively.Wewill combinetheArduinohardwarethatwebuiltwiththePythonprogramstoshowyoubasic methodsofcommunicatingwithXively. InterfacingArduinowithXively ThefirststagetoestablishcommunicationwithXivelyincludesinterfacingtheArduino boardwiththeXivelyplatformviastandaloneArduinocode.Wehavealreadybuiltthe necessaryhardwareusingtheArduinoUno,EthernetShield,andafewsensors.Let’s connectittoyourcomputerusingtheUSBport.YoualsoneedtoconnecttheEthernet ShieldtoyourhomerouterusingtheEthernetcable. UploadingArduinodatatoXively TheArduinoIDEhasabuilt-inexamplethatcanbeusedtocommunicatewiththeXively service.ThisisknownasPachubeClient(PachubewasXively’spreviousname). Note Itisimportanttonotethatthereasonbehindusingthisdefaultexampleistogiveyoua jump-startintheinterfacingexercises.Thisparticularsketchisratheroldandmayget droppedasadefaultexerciseintheupcomingreleasesoftheArduinoIDE.Inthatcase, youcandirectlyjumptothenextexerciseordevelopyourcustomsketchtoperformthe sameexercise. PerformthefollowingstepstouploadArduinodatatoXively: 1. OpentheArduinoIDEandthenopenthePachubeClientexamplebynavigatingto File|Examples|Ethernet|PachubeClient. 2. ToestablishcommunicationwithXively,youwillneedthefeedIDandtheAPIkey ofyourXivelydevice,whichyouobtainedinthelastsection. 3. IntheopenedArduinosketch,performthefollowingchangesusingtheobtainedfeed IDandAPIkey.YoucanspecifyanyprojectnamefortheUSERAGENTparameter: #defineAPIKEY"<Your-API-key>" #defineFEEDID<Your-feed-ID> #defineUSERAGENT"<Your-project-name>" 4. IntheArduinosketch,youwillalsohavetochangetheMACaddressandtheIP addressofyourEthernetShield.Youshouldbefamiliarwithobtainingthese addressesfromtheexercisethatyouperformedinthepreviouschapter.Usethese valuesandmodifythefollowinglinesofcodeappropriately: bytemac[]={0x90,0xA2,0xDA,0x0D,0x3F,0x62}; IPAddressip(10,0,0,75); 5. AstheopenedArduinoexamplewascreatedforthePachube,youneedtoupdatethe serveraddresstoapi.xively.comasspecifiedinthefollowingcodesnippet. CommenttheIPaddresslineaswewillnotneeditanymoreandaddtheserver[] parameter: //IPAddressserver(216,52,233,122); charserver[]="api.xively.com"; 6. InthesendData()function,changethechannelnametoHumidityRawaswehaveour HIH-4030humiditysensorconnectedtotheanalogport.Wearenotperformingany relativehumiditycalculationsatthisstageandaregoingtouploadjusttherawdata fromthesensor: //here'stheactualcontentofthePUTrequest: client.print("HumidityRaw,"); client.println(thisData); 7. Onceyouhaveperformedthesechanges,opentheXivelyClientBasic.inofilefrom thefoldercontainingcodesforthischapter.Comparethemwithyourcurrentsketch andcompile/uploadthesketchtotheArduinoboardifeverythingseemssatisfactory. Onceyouhaveuploadedthecode,opentheSerialMonitorwindowintheArduino IDEtoobservethefollowingoutput: 8. IfyouseeanoutputintheSerialMonitorwindowthatissimilartotheone displayedinthepreviousscreenshot,yourArduinoissuccessfullyconnectedto XivelyandisuploadingdataontheHumidityRawchannel. 9. OpenyourdeviceinXively’swebsiteandyouwillbeabletoseeanoutputthatis similartothefollowingscreenshotonthewebpage.Thisconfirmsthatyouhave successfullyuploadeddatatoanIoTcloudplatformusingyourremotely-located Arduino: DownloadingdatatoArduinofromXively Inthepreviouscodingexercise,weusedadefaultArduinoexampletocommunicatewith Xively.However,XivelyalsoprovidesaveryefficientArduinolibrarywithbuilt-in functionsforrapidprogramming.Inthenextexercise,wewilluseanalternativemethod tocommunicatewiththeXivelyplatformusingtheXively-Arduinolibrary.Althoughyou canuseeitherofthesemethods,werecommendthatyouusetheXively-Arduinolibrary asitisofficiallymaintainedbyXively. Inthisexercise,wewilldownloaddigitalvaluesfromachannelcalledLED.Later,we willusethesedigitalvalues,0and1,toswitchanLEDthatisconnectedtoourArduino board.Asaninputtothischannel,wewillalterthecurrentvalueofthechannelonthe Xivelyplatform’swebsitewhilelettingtheArduinodownloadthatvalueandperformthe appropriatetask. Let’sbeginbyimportingtheXively-Arduinolibraryanditsdependencies.Asyoualready knowhowtoimportlibrariesintheArduinoIDE,visit https://github.com/amcewen/HttpClienttodownloadandimporttheHttpClientlibrary. ThisisadependencythatisrequiredbytheXively-Arduinolibrarytofunction. OnceyouhaveimportedtheHttpClientlibrary,downloadtheXively-Arduinolibrary fromhttps://github.com/xively/xively_arduinoandrepeattheimportprocess. TheXively-Arduinolibraryshipswithfewexamplessothatyoucangetstarted.Wewill usetheirexampleasbasecodefordownloadingdataforourexercise. 1. IntheArduinoIDE,navigatetoFile|Examples|Xively_arduino| DatastreamDownloadandopentheDatastreamDownloadexample.Changethe defaultAPIkeytoyourownAPIkeythatwasobtainedfromthedevicethatyou created.Asdisplayedinthefollowingcodesnippet,youneedtoalsoidentifyyour channelname,whichisLEDinthiscase: charxivelyKey[]="<Your-API-key>"; charledId[]="LED"; 2. TheXively-ArduinolibraryrequiresyoutodefinetheXivelyDatastreamvariable asanarray.Youcanalsospecifymultipledatastreamsaccordingtoyourapplication: XivelyDatastreamdatastreams[]={ XivelyDatastream(ledId,strlen(ledId),DATASTREAM_FLOAT), }; 3. YoualsoneedtodeclareavariablecalledfeedusingtheXivelyFeedfunction.As displayedinthefollowinglineofcode,replacethedefaultfeedIDwiththe appropriateone.Intheinitializationofthefeedvariable,thevalue1representsthe numberofdatastreamsintheXivelyDatastreamarray: XivelyFeedfeed(<Your-feed-ID>,datastreams,1); 4. Inourexercise,wewanttoperiodicallyretrievethevalueoftheLEDchanneland turntheactualLEDonoroffaccordingly.Inthefollowingcodesnippet,weobtain thefloatvaluefromfeed[0],where0specifiesthedatastreamlocatedatthe0 positioninthedatastreamsarray: Serial.print("LEDvalueis:"); Serial.println(feed[0].getFloat()); if(feed[0].getFloat()>=1){ digitalWrite(ledPin,HIGH); } else{ digitalWrite(ledPin,LOW); } 5. Asyounowknowthattheparametersneedtobechangedforthisexercise,openthe XivelyLibBasicRetrieveData.inoArduinosketchfromthecodefolder.Thissketch containstheexactcodethatyouneedtousefortheexercise.Althoughthissketch includesthenecessarymodifications,youwillstillhavetochangethevaluesfor account-specificparameters,thatis,theAPIkey,feedID,andsoon.Beforeyougo aheadanduploadthissketch,gototheXivelyplatformandcreateachannelcalled LEDwithCurrentValueas1,asdisplayedinthefollowingscreenshot: 6. Now,compileanduploadthecodetoyourArduino. 7. OnceyouhaveuploadedthecompiledcodetoyourArduino,opentheSerial Monitorwindowandwaitforanoutputthatissimilartotheonedisplayedin followingscreenshot.YouwillnoticethattheLEDontheArduinohardwareis turnedon: 8. YoucangobacktotheXivelyLEDchannelandchangetheCurrentValuefieldto 0.Withinafewseconds,youwillnoticethattheLEDontheArduinohardwareis turnedoff.Withthisexercise,youhavesuccessfullyestablishedtwo-way communicationbetweenArduinoandtheXivelyplatform. AdvancedcodetouploadanddownloaddatausingArduino IntheprevioustwoArduinoexercises,weindividuallyperformedtheuploadingand downloadingtasks.Inthisexercise,wewanttocreateanArduinoprogramwherewecan uploaddatafromtheconnectedsensors(thePIRmotionsensorandtheHIH-4030 humiditysensor)whileretrievingthevaluetocontroltheLED.OpentheArduinosketch, XivelyLibAdvance.ino,whichcontainsthecodethatdemonstratesboththe functionalities.Asyoucanseeinthefollowingcodesnippet,wehavedefinedthree separatechannelsforeachcomponentwhilehavingindependentXivelyDatastream objectsforupload(datastreaU[])anddownload(datastreamD[]).Similarly,wehave alsocreatedtwodifferentfeeds,feedUandfeedD.Themainreasonbehinddelegatingthe uploadanddownloadtaskstodifferentobjectsistoindependentlyupdatethevalueofthe LEDchannelwhileuploadingthedatastreamforchannels,HumidityRawandMotionRaw: charledId[]="LED"; charhumidityId[]="HumidityRaw"; charpirId[]="MotionRaw"; intledPin=2; intpirPin=3; XivelyDatastreamdatastreamU[]={ XivelyDatastream(humidityId,strlen(humidityId),DATASTREAM_FLOAT), XivelyDatastream(pirId,strlen(pirId),DATASTREAM_FLOAT), }; XivelyDatastreamdatastreamD[]={ XivelyDatastream(ledId,strlen(ledId),DATASTREAM_FLOAT), }; XivelyFeedfeedU(<Your-feed-ID>,datastreamU,2); XivelyFeedfeedD(<Your-feed-ID>,datastreamD,1); Intheloop()functionoftheArduinocode,weperiodicallyfetchthecurrentvalueofthe LEDchannelfromfeedDandthenperformtheLEDaction: intretD=xivelyclient.get(feedD,xivelyKey); Serial.print("xivelyclient.getreturned"); Inthesecondstageoftheperiodicfunction,weobtaintherawsensorvaluesfromthe analoganddigitalpinsoftheArduinoboardandthenuploadthosevaluesusingfeedU: inthumidityValue=analogRead(A0); datastreamU[0].setFloat(humidityValue); intpirValue=digitalRead(pirPin); datastreamU[1].setFloat(pirValue); intretU=xivelyclient.put(feedU,xivelyKey); Serial.print("xivelyclient.putreturned"); MaketheappropriatechangesinthecodetoaccommodatefeedIDandAPIkeyandthen uploadthesketchtotheArduinoboard.OnceyouuploadthisArduinosketchtoyour platform,youshouldbeabletoseethefollowingoutputontheSerialMonitorwindow. YoucannowdisconnectyourArduinofromtheUSBportandconnecttheexternalpower supply.NowthatyouhaveconnectedyourArduinoassemblytoyourlocalnetworkusing anEthernetcable,youcanplacetheArduinoassemblyatanylocationinyourworkplace. Python–uploadingdatatoXively SimilartohowweinterfacedArduinotoXively,wewillnowexploremethodstoconnect theXivelyplatformviaPythonandthuscompletetheloop.Inthissection,wewillfocus ondifferentwaysofuploadingdatatoXivelyusingPython.Wewillstartwithabasic methodofcommunicatingwithXivelyandextenditfurtherwithweb.pytoimplementthe interfaceusingawebapplication. Tobeginwith,let’sfirstinstallXively’sPythonlibrary,xively-python,onyourcomputer usingthefollowingcommand: $sudopipinstallxively-python Thebasicmethodforsendingdata Onceagain,youwillneedtheAPIkeyandfeedIDofyourvirtualdevicethatyoucreated ontheXivelyplatform.Python,assistedbythexively-pythonlibrary,providesvery simplemethodstoestablishacommunicationchannelwiththeXivelyplatform.From yourcodefolder,opentheuploadBasicXively.pyfile.Asspecifiedinthecode,replace theFEED_IDandAPI_KEYvariableswiththeappropriatefeedIDandAPIkey: FEED_ID="<Your-feed-ID>" API_KEY="<Your-API-key>" UsingtheXivelyAPIClientmethod,createanapiinstanceandcreatethefeedvariable byusingtheapi.feeds.get()method: api=xively.XivelyAPIClient(API_KEY) feed=api.feeds.get(FEED_ID) JustaswedidintheArduinoexercises,youwillneedtocreatedatastreamsforeach channelfromthefeeds.Asspecifiedinthefollowingcodesnippet,trytogetthespecified channelfromthefeedorcreateoneifitisnotpresentontheXivelyvirtualdevice.You canalsospecifytagsandothervariableswhilecreatinganewchannel: try: datastream=feed.datastreams.get("Random") exceptHTTPErrorase: print"HTTPError({0}):{1}".format(e.errno,e.strerror) datastream=feed.datastreams.create("Random",tags="python") print"Creating'Random'datastream" Onceyouhaveopenedthedatastreamforachannel,youcanspecifythecurrentvalue usingthedatastream.cuurent_valuemethodandupdatethevalue,whichwillupload thisvaluetothespecifiedchannel: datastream.current_value=randomValue datastream.at=datetime.datetime.utcnow() datastream.update() OnceyouhaveperformedthespecifiedmodificationstotheuploadBasicXively.pyfile, executeitusingthefollowingcommand: $pythonuploadBasicXively.py OpenyourvirtualdeviceontheXivelywebsitetofindtheRandomchannelpopulatedwith thedatathatyouuploaded.Itwilllooksimilartothefollowingscreenshot: Uploadingdatausingawebinterfacebasedonweb.py Inthepreviouschapter,weworkedwiththeweb.pylibrarywhiledevelopingtemplates andwebapplications.Inthisexercise,wewillutilizeoneoftheprogramsinwhichwe createdtheweb.pyformswiththeXivelycodethatwedevelopedinthepreviousexercise. ThegoalofthisexerciseistosenddatatotheLEDchannelusingawebapplicationwhile observingtheLED’sbehaviorontheArduinohardware. YoucanfindthePythonprogramforthisexerciseinthischapter’sfolderwiththename uploadWebpyXively.py.Asyoucanseeinthecode,weareusingtheweb.pyformsto obtaintwoinputs,ChannelandValue.Wewillusetheseinputstomodifythecurrent valueoftheLEDchannel: submit_form=form.Form( form.Textbox('Channel',description='Channel'), form.Textbox('Value',description='Value'), form.Button('submit',type="submit",description='submit') ) Thetemplatefile,base.html,isalsomodifiedtoaccommodateminorchangesthatare requiredbythisexercise.AsyoucanseeintheopenedPythonfile,weareusingthesame codethatweusedtointerfacewithXivelyinthepreviousexercise.Theonlymajor modificationisdonetothedatastream.update()method,whichisnowplacedinthe POST()function.Thismethodwillbeexecutedwhenyousubmittheform.Onceyou changetheAPIkeyandfeedIDinthisfile,executethePythoncodeandopen http://localhost:8080inyourwebbrowser.Youcanseethewebapplicationrunning, asdisplayedinthefollowingscreenshot.Enterthevalueasdisplayedinthefiguretoturn ontheLEDontheArduinoboard.YoucanchangetheValueparameterto0toturnoffthe LED. Python–downloadingdatafromXively TheprocessofdownloadingdatafromXivelyincludesrequestingtheCurrentValue parameterforthespecifiedchannel.Inthenextexercise,wewilldevelopareferencecode thatwillbeusedinthenextdownloadingexercise.Inthatexercise,wewilldevelopan advancedwebapplicationtoretrievedatafromaspecificXivelychannel. AsweareusingfunctionsbasedontheRESTprotocoltocommunicatewithXively, Xivelywillnotsimplynotifyyouaboutanynew,availableupdate,insteadyouwillhave torequestit.Atthispoint,itisimportanttonotethatwewillhavetoperiodicallyrequest datafromXively.However,Xivelyprovidesanalternativemethodcalledtriggersto overcomethisproblem,whichisexplainedlaterinthissection. ThebasicmethodforretrievingdatafromXively Justliketheuploadingexercises,thedownloadingexercisesalsorequireasimilarcodeto instantiatetheXivelyAPIClient()andapi.feeds.get()methods.Asweareretrieving thedatainsteadofsendingit,wewillonlyusethefeed.datastreams.get()methodand avoidthefeed.datastreams.create()method.Thedownloadprocessrequiresthe channeltobealreadypresentandthisisthemainreasonwhyweonlyhavetousethe get()method: try: datastream=feed.datastreams.get("Random") exceptHTTPErrorase: print"HTTPError({0}):{1}".format(e.errno,e.strerror) print"Requestedchanneldoesn'texist" Oncethedatastreamobjectisinitialized,thelatestavailablevaluefromthechannelcan beobtainedusingthedatastream.current_valuemethod: latestValue=datastream.current_value Toenablethecompletecodetoperformthisexercise,openthedownloadXivelyBasic.py codeandchangethevaluesforthefeedIDandAPIkeytotheappropriateones.Inthis exercise,weareworkingwiththeRandomchannelthatwecreatedintheuploading exercise.BeforeyouexecutethisPythoncode,youneedtoexecutethe uploadXivelyBasic.pyfilethatwillcontinuouslyproviderandomdatatotheRandom channel.Now,youcanexecutethedownloadXivelyBasic.pyfilethatwillfetchthe currentvalueoftheRandomchannelperiodically(withadelayspecifiedbythesleep() function).Asyoucanseeinthefollowingscreenshot,wearegettinganewvalueforthe Randomchannelevery10seconds: Retrievingdatafromtheweb.pywebinterface ThisisanadvancedexercisewherewewilluploaddatatooneXivelychannelafter fetchingdatafromanotherXivelychannel,andprocessitbyusingthedataenteredviathe webform.Asyouknow,theanalogpinonwhichtheHIH-4030sensorisconnected providesyouwithrawsensorvalue,whereastherelativehumiditydependsuponthevalue ofthecurrenttemperature.Inthisexercise,wewilldevelopawebapplicationsothatthe usercanmanuallyenterthetemperaturevalueandwewillusethistocalculaterelative humidityfromtherawsensordata. Beforewebeginwiththedetailsofthecode,let’sfirstopentheuploadWebpyXively.py file,changetheappropriateparameters,andexecutethefile.Now,inawebbrowser,open thehttp://localhost:8080location.Youwillbeabletoseefollowingwebapplication, askingyoutoprovideitwiththecurrenttemperaturevalue.Meanwhile,uploadthe XivelyLibAdvance.inosketchtotheArduinoboardaftermakingtheappropriatechanges. Withthisprogram,Arduinowillstartsendingrawmotionandhumidityvaluestothe MotionRawandHumidityRawchannels.Inthewebapplicationthatisrunning,submitthe formwiththecustomtemperaturevalueandyouwillbeabletoseethewebapplication loadthecurrentrelativehumidityinpercentageunits.Internally,whenyousubmittedthe form,thewebapplicationretrievedthecurrentrawhumidityvaluefromtheHumidityRaw channel,executedtherelativeHumidity(data,temperature)function,uploadedthe calculatedhumidityvaluetoanewchannelcalledHumidity,andthendisplayedthatvalue inthewebapplication. IfyouopenyourXivelyplatformpageonawebbrowser,youwillbeabletoseeanewly createdHumiditychannelwiththecurrentvalueforrelativehumidity.Youcansubmit multiplevaluesfortemperatureinthewebapplicationtoseetheresultsreflectedonthe graphoftheHumiditychannel,asdisplayedinthefollowingscreenshot.Althoughthis exercisedemonstratesasingleusecase,thiswebapplicationcanbeextendedinmultiple waystocreatecomplexapplications. Triggers–customnotificationsfromXively TheXivelyplatformprimarilydeploysservicesbasedontheRESTprotocol,which doesn’thaveaprovisiontoautomaticallypublishdatawhenitisupdatedwithanew value.Inordertoovercomethislimitation,Xivelyimplementstheconceptoftriggers, whichprovideadditionalfunctionalitybeyondjustpublishingdatawhenitischanged. Throughthis,youcanbasicallycreateatriggerforanychanneltoperformthePOST operationonthespecifiedlocationwhenconditionsthataresetforthattriggerget satisfiedbytheincomingdata.Forexample,youcansetatriggerontheHumiditychannel tosendyouanotificationwhenthevalueofhumiditychanges,thatis,increasesaboveor decreasebelowagiventhreshold.YoucancreateatriggerinyourXivelyplatform accountbyjustclickingontheAddTriggerbutton,asdisplayedinthefollowing screenshot: Whilecreatingatrigger,youcanspecifythechannelyouwanttomonitorandthe conditiontotriggeranotificationonthespecifiedHTTPPOSTURL.Asshowninthe followingscreenshot,completetheinformationforChannel,Condition,andHTTP POSTURLbeforesavingthetrigger.Themajordrawbackwiththisapproachisthat XivelyrequiresanactualURLtosendthePOSTnotification.Ifyourcurrentcomputer doesn’thaveastaticIPaddressoraDNSaddress,thetriggerwon’tbeabletosendyou thenotification: YourowncloudplatformfortheIoT Intheprevioussection,weworkedwithacommercialIoTplatformthatalsoprovides restricted,freeaccesstobasicfunctionalities.Wealsolearnedvariouswaysto communicatewithXivelythatisbasedontheRESTprotocol.Foranysmallprojectsor prototypes,XivelyandothersimilarIoTplatformsprovideasufficientsolutionandare thereforerecommendedbyus.However,thelimitedfreeserviceprovidedbyXivelymay notsatisfyallofyourrequirementstodevelopafull-stackIoTproduct.Thefollowingare afewcaseswhereyoumaywanttoconfigureordevelopyourownIoTplatform: DevelopyourowncommercialIoTplatform Developcustomfeaturesthatareexclusivetoyourproduct Addmorecontrolfeaturesandcommunicationprotocolswhilealsosecuringyour data Requireaninexpensivesolutionforlarge-scaleprojects Thissectionwillguideyouthroughthestep-by-stepprocessofcreatinganelementary small-levelIoTcloudplatform.Thegoalofthesectionistomakeyoufamiliarwiththe requirementsandtheprocessofcreatinganIoTplatform.Todevelopalarge-scale, diverse,andfeature-richplatformsuchasXively,youwillneedasignificantamountof knowledgeandexperienceinthedomainsofcloudanddistributedcomputing. Unfortunately,cloudanddistributedcomputingareoutofscopeofthisbookandwewill stickwiththeimplementationofthebasicfeatures. TodevelopacloudplatformthatisaccessiblethroughtheInternet,youwillatleast requireacomputationalunitwithInternetconnectionandastaticIPorDNSaddress. Today,themajorityofconsumer-orientedInternetServiceProviders(ISPs)donot providestaticIPswiththeirInternetservice,makingitdifficulttohostaserverathome. However,variouscompaniessuchasAmazon,Google,andMicrosoft,providefreeor cost-effectivecloudcomputingservices,whichmakeiteasiertohostyourcloudontheir platforms.Theseservicesarehighlyscalableandtheyareequippedwithalargeamountof featurestosatisfythemajorityofconsumerrequirements.Inthefollowingsection,you willbecreatingyourfirstcloudcomputinginstanceonAmazonWebServices(AWS). Laterinthischapter,wewillinstallandconfiguretheappropriatesoftwaretoolssuchas Python,Mosquittobroker,andsoon,toutilizethisAmazoninstanceasanIoTcloud platform. Note Themajorreasonbehinddevelopingorconfiguringapersonalcloudplatformistohave accesstoyourIoThardwarethroughtheInternet.DuetothelackofastaticIPaddressfor yourhomenetwork,youmaynotbeabletoaccessyouprototypesorprojectsfroma remotelocation.Acloudplatformcanbeusedasthedefactocomputationunitforyour network-basedprojects. GettingfamiliarwiththeAmazonAWSplatform AWSisacollectionofvariouscloudservicesofferedbyAmazon,whichtogethermakeup acloudcomputingplatform.Oneoftheoriginalandmostpopularservicesofferedby AWSisitsElasticComputerCloud(EC2)service.TheEC2serviceletsausercreate instancesofavirtualmachinewithdifferentcombinationsofcomputationpowerand operatingsystemsfromtheirlargecloudinfrastructure.Itisalsoreallyeasytochangethe computationalpropertiesofthesevirtualinstancesatanytime,makingthemhighly scalable.WhenyouaretryingtocreateyourownIoTplatformusingEC2,thisscalability featuregreatlyhelpsyouasyoucanexpandorcompressthesizeofyourinstances accordingtodemand.IfyouarenotfamiliarwiththeconceptofcloudcomputingorAWS asaparticularproduct,youcanlearnmoreaboutthemfromhttp://aws.amazon.com. TheEC2cloudplatformisdifferentfromXivelyasitprovidesgeneral-purposecloud instances,virtualmachines,withcomputationpowerandstoragethatcanbeconvertedto anyfeature-specificplatformbyinstallingandconfiguringplatform-specificsoftware.Itis importanttonotethatyoureallydonothavetobeanexpertincloudcomputingtofurther advanceinthischapter.Theupcomingsectionsprovideanintuitiveguidetoperformbasic tasks,suchassettingupanaccount,creatingandconfiguringyourvirtualmachines,and installingsoftwaretoolstocreateIoTplatforms. SettingupanaccountonAWS Amazonprovidesoneyearoffreeaccesstothebasicinstanceofthecloud-basedvirtual machine.Thisinstanceincludes750hoursoffreeusagetimepermonthandthisisgreater thanthenumberofhoursinanymonth,therebymakingitfreefortheentiremonth.The datastoragecapacityandbandwidthoftheAWSaccountaresufficientforbasicIoTor Arudinoprojects.TocreateafreeaccountforayearonAmazon’sAWScloudplatform, performthefollowingsteps: 1. Openhttp://aws.amazon.comandclickonthebuttonthatasksyoutotryAWSfor freeorsomeothersimilartext. 2. ThisactionwillleadyoutoaSignInorCreateanAWSAccountpageasdisplayed inthefollowingscreenshot.Enterthee-mailaddressthatyouwanttouseforthis accountwhenyouselecttheIamanewuser.optionandclickontheSigninusing oursecureserverbutton.IfyoualreadyhaveanAWSaccountandyouknowhowto createanaccountonAmazonAWS,youcanusethosecredentialsandskiptothe nextsection: Note Amazononlyallowsonefreeinstanceforeachaccount.IfyouareanexistingAWS userandyourfreeinstanceisalreadyoccupiedwithanotherapplication,youcanuse thesameinstancetoaccommodatetheMQTTbrokerorbuyanotherinstance. 3. Onthenextpage,youwillbepromptedtoenteryourname,e-mailaddress,anda password,asdisplayedinthefollowingscreenshot.Fillintheinformationto continuewiththesignupprocess: 4. Youwillbeaskedtoenteryourcreditcardinformationduringthesignupprocess. However,youwon’tbechargedforusingtheservicesincludedinthefreeaccount. Yourcreditcardwillbeonlyusedifyouexceedanylimitationsorbuyanyadditional services. 5. Thenextstageincludestheverificationofyouraccountusingyourphonenumber. Followtheinstructionsthataredisplayedinthefollowingscreenshottocompletethe identityverificationprocess: 6. Onceyouhaveverifiedyouridentity,youwillberedirectedtothepagethatliststhe availableAmazonAWSplans.Selecttheappropriateplanthatyouwanttosubscribe toandcontinue.Ifyouarenotsure,youcanselecttheBasic(Free)planoption, whichwerecommendforourpurpose.TheAmazonManagementConsolepage willletyouselectotherplansifyouwanttoupgradethecurrentone. 7. LaunchtheAmazonmanagementconsole. AsyouhaveanAmazonAWSaccountnow,let’screateyourvirtualinstanceonit. CreatingavirtualinstanceontheAWSEC2service InordertocreateavirtualinstanceonAmazon’sEC2platform,firstlogintoAWSusing yourcredentialsandopenthemanagementconsole.Next,clickontheEC2taband executethefollowinginstructionsstepbystep: 1. OntheEC2Consolepage,gotoCreateInstanceandclickontheLaunchInstance button.Thiswillopenawizardtocreateaninstancethatwillguideyouthroughthe setupprocess: 2. Onthefirstpageofthewizard,youwillbepromptedtoselectanoperatingsystem foryourvirtualinstance.SelectUbuntuServer14.04LTSasdisplayedinthenext screenshot,whichiseligibleforthefreetier.Toavoidanychargesforusingan advancedinstance,makesurethattheoptionyouselectiseligibleforthefreetier: 3. Innextwindow,youwillbepromptedwithalistofoptionsthathavedifferent configurationsofcomputationalcapacity.FromtheGeneralpurposefamily,select thet2.microtype,whichiseligibleforthefreetier.Thecomputationalcapabilities providedbythet2.microtieraresufficientfortheexercisesthatwearegoingto performinthebookandformostoftheDIYprojects.Makesurethatyoudonot selectanyothertierunlessyouareconfidentofyourselection. 4. Onceyouhaveselectedthespecifiedtier,clickontheReviewandLaunchbuttonto reviewthefinalconfigurationoftheinstance. 5. Reviewtheconfigurationandmakesurethatyouhaveselectedtheappropriate options,asmentionedearlier.YoucannowclickontheLaunchbuttontoproceed further. 6. Thiswillopenapop-upwindowthatwillpromptyoutocreateanewkeypairthat willbeusedforauthenticationintheupcomingsteps: 7. Asshowninthepreviousscreenshot,selectCreateanewkeypairfromthefirst drop-downmenuwhileprovidinganameforthekeypair.ClickontheDownload KeyPairbuttontodownloadthekey.Thedownloadedkeywillhavethenamethat youprovidedinthepreviousoptionwiththe.pemextension.Ifyoualreadyhavean existingkey,youcanselecttheappropriateoptionsfromthefirstdrop-downmenu. Youwillneedthiskeyeverytimeyouwanttologintothisinstance.Savethiskeyin asafeplace. 8. Onceagain,clickontheLaunchInstancesbuttontofinallystarttheinstance.Your virtualinstanceislaunchedonAWSnowanditisrunningintheEC2. 9. Now,clickontheViewInstancebuttonthatwilltakeyoubacktotheEC2console window.Youwillbeabletoseeyourrecentlycreatedt2.microinstanceinthelist. 10. Tofindoutmoredetailsaboutyourvirtualinstance,selectitfromthelist.Assoonas youselectyourinstance,youwillbeabletoseeadditionalinformationinthebottom tab.ThisinformationincludesthepublicDNS,privateDNS,publicIPaddress,and soon. 11. Savethisinformation,asyouwillneedittologintoyourinstance. Now,youhavesuccessfullycreatedandturnedonavirtualcloudinstanceusingAmazon AWS.However,thisinstanceisrunningintheAmazonEC2andyouwillhaveto remotelyauthenticateintothisinstancetoaccessitsresources. Loggingintoyourvirtualinstance Inreality,yourvirtualinstanceisavirtualcomputeronacloudwithcomputation resourcesthataresimilartoyourregularcomputer.Younowneedtologintotherunning virtualinstancetoaccessfiles,runscripts,andinstalladditionalpackages.Toestablisha secureauthenticationandaccessprocedure,youneedtousetheSecureShell(SSH) protocolandtherearemultiplewaystouseSSHfromyourcomputer.Ifyouareusing MacOSXorUbuntu,anSSHclientprogramalreadyexistswithinyouroperatingsystem. ForWindows,youcandownloadthePuTTYSSHclientfromhttp://www.putty.org/. FromtheEC2managementwindow,retrievethepublicIPaddressofyourinstance.To usethedefaultSSHclientintheLinuxorMacenvironment,opentheterminaland navigatetothefolderwhereyouhavesavedyourkeyfilewiththe.pemextension.Inthe terminalwindow,executethefollowingcommandtomakeyourkeyaccessible: $chmod400test.pem Onceyouhavechangedpermissionforyourkeyfile,runthefollowingcommandtologin tothevirtualinstance.Inthecommand,youwillhavetoreplace<key-name>withthefile nameofyourkeyand<public-IP>withthepublicIPthatyouretrievedfromthe managementconsole: $ssh–i<key-name>.pemubuntu@<public-IP> Onceyouexecutethiscommand,youwillbeaskedtocontinuewiththeconnection processifyouareauthenticatingtheinstancefortheveryfirsttime.Attheprompt,write yesandpressEntertocontinue.Onsuccessfulauthentication,youwillbeabletoseethe commandpromptofyourvirtualinstanceinthesameterminalwindow. IncaseyouareusingtheWindowsoperatingsystemandarenotsureaboutthestatusof yourSSHclient,selectyourinstanceintheEC2windowandclickontheConnectbutton inthetopnavigationbar,whichisdisplayedinthefollowingscreenshot: Thisactionwillopenapop-upwindowwithashorttutorialthatexplainstheconnection process.Thistutorialisalsolinkedtothestep-by-stepauthenticationguideforPuTTY. CreatinganIoTplatformontheEC2instance AsyouhavesuccessfullysetupanAmazonEC2instance,youhaveavirtualcomputer thatisrunninginthecloudandhasastaticIPaddresstoenableremoteaccess.However, thisinstancecannotbecategorizedasanIoTplatform,asitonlycontainsaplainoperating system(UbuntuLinuxinourcase)andlacksthenecessarysoftwarepackagesand configurations. TherearetwodistinctwaysofsettingupacustomIoTcloudplatformonyourvirtual instance: SettingupanopensourceIoTplatformsuchasThingSpeak Separatelyinstallingandconfiguringtherequiredsoftwaretools KeepthefollowingpointsinmindwhensettingupanopensourceIoTplatform: ThingSpeakisoneoftheopensourceIoTplatformsthatprovidessupportingfilesto createandhostyourownreplicaoftheThingSpeakplatform. SettingupthisplatformonyourAWSinstanceisquitesimpleandyoucanobtainthe necessaryfilesandguidelinestoinstallitvia https://github.com/iobridge/ThingSpeak. AlthoughthispersonalizedversionoftheThingSpeakplatformwillprovide sufficienttoolstostartdevelopingIoTapplications,thefunctionalitiesoftheplatform willbeconfinedtothesuppliedfeatureset.Tohavecompletecontrolover customization,youmayhavetousethenextoption. Ifyouwanttoseparatelyinstallandconfigurethenecessarysoftwaretools,here’swhat youneedtoremember: Thisoptionincludesfurnishingproject-specificsoftwaretoolssuchasPythonandthe MosquittobrokerwiththerequiredPythonlibrariessuchasweb.pyandpaho_mqtt. Wehavealreadyworkedwithexercisesthatimplementedapplicationswhichwere basedontheMosquittobrokerandweb.py.ThisversionofthecustomIoTcloud platformcanreducethecomplexityofinstallingadditionalopensourceplatform toolsandstillprovidethenecessarysupporttohostapplications. TheArduinoprogramcandirectlycommunicatewiththiscustomplatformusing RESTorMQTTprotocols.Itcanalsobehaveastheremotecomputationunitto communicatewithXivelyorotherthird-partyIoTcloudplatforms. Inthenextsection,wewillbegintheplatformdeploymentprocessbyinstallingthe Mosquittobrokerandthenecessarypackagesonyourvirtualinstance.Thiswillbe followedbytheconfigurationofthevirtualinstancetosupporttheMQTTprotocol.Once yourIoTcloudplatformisupandrunning,youcanjustrunthePython-basedMosquitto codefromthelastchapterfromtheinstancewithminorornomodifications.Infuture,this IoTplatformthatcontainstheMosquittobrokerandthePythonprojectcanbeextendedto accommodateadditionalfeatures,protocols,andextrasecurity. InstallingthenecessarypackagesonAWS UsingtheSSHprotocolandthekeypair,logintoyourvirtualinstance.Onceyouareat theCommandPrompt,thefirsttaskthatyouneedtoperformistoupdatealltheoutdated packagesinUbuntu,theoperatingsystemofyourvirtualinstance.Successivelyexecute thefollowingcommands: $sudoapt-getupdate $sudoapt-getupgrade UbuntualreadycomeswiththelatestversionofPython.However,youwillstillneedto installSetuptoolstoinstalltheadditionalPythonpackages: $sudoapt-getinstallpython-setuptools Ubuntu’spackagerepositoryalsohostsMosquittoanditcanbedirectlyinstalledusingthe followingcommand.Withthiscommand,wewillinstalltheMosquittobroker,Mosquitto client,andallotherdependenciestogether.Duringtheinstallation,youwillbeaskedto confirmtheinstallationofadditionalpackages.EnterYesattheterminalandproceedwith theinstallation: $sudoapt-getinstallmosquitto* NowyouhaveinstalledtheMosquittobrokeronyourvirtualinstanceandyoucanrunit byexecutingtheMosquittocommand.TodevelopPython-basedMosquittoapplications, weneedthePythonMosquittolibraryonourinstance.Let’sinstallthelibraryusing Setuptools,throughthefollowingcommands: $sudoeasy_installpip $sudopipinstallpaho_mqtt Inthepreviouschapter,wedevelopedawebapplicationbasedonweb.pythatutilizesthe paho_mqttlibrarytosupporttheMQTTprotocol.Aswiththefirstproject,wearegoingto deploythesamewebapplicationontheEC2-basedvirtualinstancetodemonstrateyour customIoTcloudplatform.Asadependencyofthisproject,youfirstneedtheweb.py Pythonlibrary,whichyoucaninstallusingthefollowingcommand: $sudopipinstallweb.py NowyouhaveallthenecessarysoftwarepackagestoruntheIoTapplication.Tomake yourwebapplicationaccessibleviatheInternet,youneedtoconfigurethesecurityofyou virtualinstance. Configuringthesecurityofthevirtualinstance First,wewillconfigurethevirtualinstancetosecurelyhosttheMosquittobroker.Later, wewillgothroughthemethodstosetupbasicsecuritytopreventtheabuseofyour Mosquittoserverbyautomatedbotsorspammingattempts. Tochangeanyparametersonyourvirtualinstance,youwillhavetousetheSecurity GroupstoolsfromtheNetwork&SecuritysectionofyourAWSManagementConsole page.OpentheSecurityGroupssection,asdisplayedinthefollowingscreenshot: Eachvirtualinstancehasadefaultsecuritygroupthatisgeneratedautomaticallytoallow accesstoyourinstancethroughtheSSHport22.Thissecurityconfigurationisresponsible forlettingyouaccessyourvirtualinstancethroughtheSSHclientfromyourcomputer. TheMosquittobrokerusestheTCPportnumber1883toestablishcommunicationwith publishersandsubscriberclients.ToallowincomingaccessfromthisMosquittoport,you willhavetoeditthecurrentinboundrulesandaddanentryforport1883: OnceyouclickontheEditbutton,thewebsitewillopenapop-upwindowtoaddnew rulesandedittheexistingrules.ClickontheAddRulebuttontocreateanadditionalrule toaccommodatetheMosquittobroker: Asdisplayedinthefollowingscreenshot,entertheTCPport’snumberas1883and completetheotherinformationintheform.Onceyouhavecompletedtheformwiththe givenvalues,savetherulesandexitthewindow: Now,withthisconfiguration,port1883isaccessiblebyotherdevicesandenablesremote communicationwiththeMosquittobroker.Youcanusethesamemethodtoaddarulefor port8080toallowaccesstoPython’swebapplicationsthatweredevelopedusingweb.py. Infuture,youcanaddanyadditionalportstoallowaccesstovariousservices.Althoughit isveryeasytochangethesecurityrulesonyourvirtualinstance,makesurethatyou refrainfromopeningexcessiveportstoavoidanysecurityrisk. Testingyourcloudplatform Inthistestingsection,wewillfirstperformchecksfortheMosquittobrokerfromyour computerandthensetupauthenticationparametersfortheMosquittobroker.Later,we willuploadfilesandfolderscontainingthePythoncodetoourvirtualinstanceusingthe SSHfiletransferprotocol. TestingtheMosquittoservice ThefirstthingthatwearegoingtocheckonourIoTplatformistheaccessibilityofthe Mosquittobroker.Opentheterminalonyourcomputerandexecutethefollowing command,afterreplacing<Public-IP>withthepublicIPorpublicDNSaddressofyour virtualinstance: $mosquitto_pub-h<Public-IP>-ttest-m3 Thiscommandwillpublishthemessagevalue3forthetesttopicfortheMosquitto brokerthatisspecifiedatthegivenIPaddress;inourcase,thisisthevirtualinstance. Now,openaseparateterminalwindowandexecutethefollowingcommandtosubscribe tothetesttopiconourbroker: $mosquitto_sub-h<Public-IP>-ttest Ontheexecutionofthiscommand,youwillbeabletoseethelatestvaluethatispublished forthistopic.Usethemosquitto_pubcommandtopostmultiplemessagesandyoucan seetheoutputofthesemessagesintheotherterminalwindowthatisrunningthe mosquitto_subcommand. Configuringandtestingbasicsecurity Asyousawinthepreviousexample,thepublishingandsubscribingcommandsjustused theIPaddresstosendandreceivedatawithoutusinganyauthenticationparameters.This isamajorsecurityloophole,asanyoneontheInternetcansenddatatoyourMosquitto broker.Toavoidunauthorizedaccesstoyourbroker,youhavetoestablishauthentication credentials.Youcanspecifytheseparametersbyfollowingthesestepsinthegivenorder: 1. IfyouhavenotalreadyloggedintoyourinstancethroughSSH,openaterminal windowandloginusingSSH.Onceyouareloggedin,navigatetotheMosquitto directoryandcreateanewfilecalledpasswdusingthefollowingsetofcommands. Wewillusethisfiletostoretheusernamesandpasswords: $cd/etc/mosquitto $sudonanopasswd 2. Inthefile,entertheusernameandpasswordinformationseparatedbyusingthecolon operator(:).Fortestingpurposes,wewillusethefollowingcredentials,whichcanbe changedanytimeonceyouaremorefamiliarwiththeMosquittoconfiguration: user:password 3. PressCtrl+Xtosaveandexitthefilefromthenanoeditor.Whenyouareprompted toconfirmthesaveoperation,selectYandpressEnter. 4. Inthesamefolder,opentheMosquittoconfigurationfileusingthenanoeditor: $sudonanomosquitto.conf 5. Intheopenedfile,scrolldownthetextcontentuntilyoureachthesecuritysection.In thissection,findthe#allow_anonymoustruelineofthecodeandreplaceitwith allow_anonymousfalse.Makesurethatyouhaveremovedthe#symbol.Withthis operation,wehavedisabledtheanonymousaccesstotheMosquittobrokerandonly thoseclientswithpropercredentialscanaccessit. 6. Afterperformingthepreviouschanges,scrollfurtherdowninthefile,uncomment theline#password_file,andreplaceitwiththis: password_file/etc/mosquitto/passwd 7. Nowthatyouhaveconfiguredthebasicsecurityparametersforyourbroker,you mustrestarttheMosquittoserviceforthechangestotakeeffect.InUbuntu, Mosquittoisinstalledaspartofthebackgroundserviceandyoucanrestartitusing thefollowingcommand: $sudoservicemosquittorestart 8. Totesttheseauthenticationconfigurations,openanotherterminalwindowinyour computerandexecutethefollowingcommandwiththepublicIPaddressofyour instance.Ifyouareabletosuccessfullypublishyourmessagewithoutanyerrors, yourMosquittobrokernowhasasecurityconfiguration: $mosquitto_pub-uuser-Ppassword-h<Public-Ip>-ttest-m3 9. Also,checkyourMosquittosubscriberusingthefollowingcommand: $mosquitto_sub-uuser-Ppassword-h<Public-Ip>-ttest Uploadingandtestingaprojectontheinstance Aswediscussedinthepreviouschapters,youcanalwaysuseyourcomputerfor developmentpurposes.Onceyouarereadyfordeployment,youcanutilizethisnewly configuredvirtualinstanceasthedeploymentunit.Youcancopyyourfilesfromyour localcomputertothevirtualinstanceusingautilitycalledPuTTY (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html)orusingtheSCP (SSHcopy)command. Nowitistimetouploadtheprojectfilesfromthefinalcodingexerciseoftheprevious chapter,whichimplementedtheMQTTprotocolusingPythonandtheMosquittolibrary. Asareminder,thefinalexerciseislocatedinthefoldernamedExercise4-MQTT gatewayofthepreviouschapter’scoderepository.WewillbeusingtheSCPutilityto uploadthesefilestoyourvirtualinstance.Beforeweusethisutility,let’sfirstcreatea directoryonyourvirtualinstance.Logintoyourvirtualinstanceandgototheuser directoryofthevirtualinstancebyusingthefollowingcommand: $ssh–i<key-name>.pemubuntu@<public-ip> $cd~ Usingthecharactertilde(~)withthecdcommandwillchangethecurrentdirectorytothe homedirectory,unlessyouareplanningtouseanyotherlocationonyourvirtualinstance. Atthislocation,createanewemptydirectorynamedprojectbyusingfollowing command: $mkdirproject Now,onthecomputeryouareworkingon(MacOSXorLinux),openanotherterminal windowandusethefollowingcommandtocopytheentiredirectorytotheremote instance: $scp-v-itest.pem-r<project-folder-path>ubuntu@<your-ec2-static- ip>:~/project Onceyouhavesuccessfullycopiedthefilestothislocation,youcangobacktothe terminalthatisloggedintoyourvirtualinstanceandchangethedirectorytoproject: $cdproject Beforerunninganycommands,makesurethatyouhavechangedtheappropriateIP addressesintheArduinosketchandthePythonprograms.Youwillhavetoreplacethe previousIPaddresswiththeoneofyourvirtualinstance.Nowthatyouhavemadethese changes,youcanexecutethePythoncodecontainingtheMosquittoGatewayandweb applicationtostarttheprogram.Openyourwebbrowserfromthehttp://<PublicIp>:8080locationtoseeyouwebapplicationrunningonthecustomIoTplatform.From nowon,youshouldbeabletoaccessthisapplicationfromanyremotelocationthrough theInternet. Tip DonotforgettochangetheIPaddressoftheMosquittobrokerintheArduinosketchand uploadthesketchtotheArduinoboardagain.Youmaynotbeabletoobtainthesensor dataiftheappropriateIPaddresschangesarenotapplied. Summary Attheendofthischapter,andhencetheendofthecontextualpartofthebook,youshould beabletodevelopyourownInternetofThingsprojects.Inthischapter,weuseda commercialIoTcloudplatformtohandleyoursensordata.Wealsodeployedacloud instancetohostopensourceIoTtoolsandcreatedourownversionofthecustomizedIoT cloudplatform.Certainly,thecontentthatyoulearnedisnotsufficienttodevelopscalable andfully-stackedcommercialproducts,butitisreallyhelpfultogetyoustartedwith them.Inalargenumberofcases,thismaterialissufficienttodevelopDIYprojectsand productprototypesthatwillultimatelyleadyoutothefinalproduct.Inthenexttwo chapters,wewillputthematerialthatwelearnedtothetestanddeveloptwocompleteIoT hardwareprojects.Wearealsogoingtolearnaprojectdevelopmentmethodologythatis specifictohardware-basedIoTproducts,whichcanbeappliedtoconvertyourprototypes intorealproducts. Chapter10.TheFinalProject–aRemote HomeMonitoringSystem Itisnowtimetocombineeverytopicthatwelearnedinthepreviouschaptersintoa projectthatcombinesArduinoprogramming,PythonGUIdevelopment,MQTT messagingprotocol,andaPython-basedcloudapplication.Asyoumighthavealready figuredoutfromthechaptertitle,wearegoingtodeveloparemotehomemonitoring systemusingthesecomponents. Thefirstsectionofthechaptercoverstheprojectdesignprocess,includinggoals, requirements,architecture,andUX.Oncewearedonewiththedesignprocess,wewill jumpintotheactualdevelopmentoftheproject,whichisdividedintothreeseparate stages.Next,wewillcovercommontroubleshootingtopicsthatareusuallyfacedwhile workingwithlargeprojects.InoureffortstodeveloputilizableDIYprojects,thelater sectioncoverstipsandfeaturestoextendtheproject.Asthisisquitealargeproject comparedtootherprojectsinthebook,wearenotgoingtojumpstraightintotheactual developmentprocesswithouthavinganystrategy.Let’sstartbygettingourselvesfamiliar withthestandarddesignmethodologyforhardwareprojects. ThedesignmethodologyforIoTprojects Theprocessofdevelopingacomplexproductthattightlycoupleshardwaredeviceswith high-levelsoftwareservicesrequiresanadditionallevelofplanning.Forthisproject,we willexerciseaproperproductdevelopmentapproachtohelpyougetfamiliarwiththe processofcreatingreal-worldhardwareprojects.Thismethodcanthenbeusedtoplan yourownprojectsandtakethemtothenextlevel.Thefollowingdiagramdescribesa typicalprototypedevelopmentprocess,whichalwaysbeginsbydefiningthemajorgoals thatyouwanttoachievewithyourproduct: Onceyouhavedefinedthesetofmajorgoals,youneedtobreakthemdownintoproject requirementsthatincludeeverydetailofthetasksthatyourprototypeshouldexecuteto achievethesegoals.Usingtheprojectrequirements,youneedtosketchouttheoverall architectureofthesystem.ThenextstepincludestheprocessofdefiningtheUXflowthat willhelpyoutolayouttheuserinteractionpointsforyoursystem.Atthisstage,youwill beabletoidentifyanychangesthatarerequiredinthesystemarchitectureandthe hardwareandsoftwarecomponentstostartthedevelopment. Asyouhavedefinedtheinteractionpoints,nowyouneedtodistributetheentireproject developmentprocessintomultiplestagesanddelegatethetasksbetweenthesestages. Onceyouhavecompletedthedevelopmentofthesestages,youwillhavetointerface thesestageswitheachotheraccordingtoyourarchitectureanddebugthecomponentsifit isneeded.Attheend,youwillhavetotestyourprojectasawholesystemand troubleshootminorproblems.Inhardwareprojects,itisverydifficulttoworkonyour electriccircuitsagainafterthecompletionofcomplexdevelopmentprocesses,asthe changescanhaverecurringeffectsonallothercomponents.Thisprocesswillhelpyouto minimizeanyhardwarereworkandsubsequentsoftwaremodifications. Nowthatyouhavelearnedaboutthemethodology,let’sbeginwiththeactual developmentprocessforourremotehomemonitoringsystem. Projectoverview Thesmarthomeisoneofthemostwell-definedandpopularsubdomainsoftheIoT.The mostimportantfeatureofanysmarthomeisitscapabilitytomonitorthephysical environment.Fortunately,theexercisesandprojectsthatwecoveredintheprevious chaptersincludecomponentsandfeaturesthatcanbeusedforthesamepurpose.Inthis chapter,wearegoingtodefineaprojectthatwillutilizetheseexistingcomponentsand programmingexercises.InthemidtermprojectofChapter7,TheMidtermProject–a PortableDIYThermostat,wecreatedadeployablethermostatwiththeabilitytomeasure temperature,humidity,andambientlight.Ifwewanttoutilizethismidtermproject,the nearestIoTprojectthatwecanbuildontopofitistheremotehomemonitoringsystem. TheprojectwillhaveArduinoasthemainpointofinteractionbetweenthephysical environmentandthesoftware-basedservices.WewillhaveaPythonprogramasthe middlelayer,whichwillbridgethesensorinformationcomingfromArduinowiththe user-facinggraphicalinterface.Let’sstartbydefiningthegoalsthatwewanttoachieve andtheprojectrequirementstosatisfythesegoals. Theprojectgoals TheNestthermostatprovidesanideaofthetypeoffeaturesthataproperlydesigned remotemonitoringsystemwithprofessionalfeaturesshouldhave.Achievingthislevelof systemcapabilitiesrequiresalotofdevelopmenteffortfromalargeteam.Althoughitwill bedifficulttoincludeeachofthefeaturesthataresupportedbyacommercialsystemin ourproject,wewillstilltrytoimplementthecommonfeaturesthatcanbeincorporatedby aprototypeproject. Thetop-levelfeaturesthatweareplanningtoincorporateinthisprojectcanbedescribed bythefollowinggoals. Observethephysicalenvironmentandmakeitaccessibleremotely Providebasiclevelcontrolstotheusertointeractwiththesystem Demonstrateaprimitivelevelofbuilt-insituationalawareness Theprojectrequirements Nowthatwehavedefinedthemajorgoals,let’sconvertthemintodetailedsystem requirements.Onthecompletionoftheproject,thesystemshouldbeabletosatisfythe followingrequirements: Itmustbeabletoobservephysicalphenomenonsuchastemperature,humidity, motion,andambientlight. Itshouldprovidelocalaccesstosensorinformationandcontroloveractuatorssuch asabuzzer,abuttonswitch,andanLED. Themonitoringshouldbedonebyaunitthatisdevelopedusingtheopensource hardwareplatform,Arduino. Themonitoringunitshouldbelimitedtocollectsensorinformationandcommunicate ittothecontrolunit. Thecontrolunitshouldnotcompriseofadesktopcomputerorlaptop.Instead,it shouldbemadedeployableusingaplatformsuchasaRaspberryPi. Thecontrolunitshoulddemonstrateaprimitivelevelofsituationawareness capabilitybyutilizingthecollectedsensorinformation. Thecontrolunitshouldhaveagraphicalinterfacetoprovidethesensor’sobservation andthecurrentstateofthesystem. ThesystemmustbeaccessibleviatheInternetusingcloud-basedservices. Thewebapplicationthatprovidesremoteaccessshouldhavethecapabilitytodisplay thesensor’sobservationsthroughawebbrowser. Thesystemshouldalsoprovidebasiccontroloftheactuatorstocompletetheremote accessexperiencebyusingthewebapplication. Asthemonitoringunitcanbeconstrainedbycomputationresources,thesystem shouldusehardware-orientedmessagingprotocolstotransferinformation. Althoughtherearemanyotherminorrequirementsthatcanbepartofourproject,they havebeenskippedinthisbook.Ifyouhaveanyadditionalplansforyourremotehome monitoringsystem,thisisthetimethatyoumustdefinetheserequirementsbeforeyou jumpintodesigningthearchitecture.Anyfuturechangestotherequirementscan significantlyaffectthedevelopmentstageandmakehardwareandsoftwaremodification difficult.Inthelastsectionofthechapter,wehavelaiddownanumberofadditional featuresthatyoumaywanttoconsiderimplementingforyourfutureprojects. Designingsystemarchitecture Continuingfromprojectgoals,first,youneedtosketchoutahigh-levelarchitectureofthe system.Thisarchitecturalsketchshouldincludemajorcomponentsthatenablethesystem topassoninformationbetweenthesensorsandtheremoteusers.Thefollowingfigure showsanarchitecturalsketchforourproject: Accordingtothegoals,theusershouldbeabletoaccessthesystemusingtheInternet;this meansthatweneedcloudcomponentsinthearchitecture.Thesystemalsoneedsto monitorthephysicalenvironmentusingaresource-constraineddevice,andthiscanbe executedusingArduino.Themiddlelayer,whichconnectsthecloudserviceandthe sensorsystem,canbebuiltusingaRaspberryPi.Inthelastproject,weconnectedArduino andtheRaspberryPiusingaserialconnection,butwewanttomoveawayfromserial connectionsandstartusingourhome’sEthernetnetworktomakethesystemdeployable. Hence,theArduino-basedunitisconnectedtothenetworkusingEthernetwhilethe RaspberryPiusesWi-Fitoconnecttothesamenetwork. Inordertolayouttheoverallsystemarchitecture,let’sutilizethesketchthatwedesigned, whichcanbeseenintheprecedingfigure.Asyoucanseeinthenextfigure,wehave convertedtheoverallsystemintothreemainarchitecturalunits: Monitoringstation Controlcenter Cloudservice Inthisfigure,wehaveaddressedeachandeverymajorcomponentthatwearegoingto utilizeintheprojectalongwiththeirassociationtoeachother.Inthefollowingsections, wearegoingtodefinethesethreemainunitsbriefly.Thecomprehensivedescriptionand implementationstepsfortheseunitsareprovidedlaterinthechapterunderseparate sections. Themonitoringstation Weneedaresource-constrainedandrobustunitthatwillcommunicatewiththephysical environmentperiodically.ThismonitoringunitcanbebuiltusingArduinosincelow-level microcontrollerprogrammingcanprovideuninterruptedstreamofsensordata.Theusage ofArduinoatthisstagewillalsohelpustoavoidthedirectinterfacingofbasiclow-level sensorswithcomputersthatarerunningoncomplexoperatingsystems.Thesensorsand theactuatorsareconnectedtoArduinousingdigital,analog,PWM,andI2Cinterfaces. Thecontrolcenter Thecontrolcenterbehavesasthemainuserinteractionpointbetweenthesensor informationandtheuser.Itisalsoresponsibleforconveyingthesensorinformationfrom themonitoringstationtothecloudservices.Thecontrolcentercanbedevelopedusing yourregularcomputerorasingle-boardcomputersuchasaRaspberryPi.Wearegoingto utilizeaRaspberryPisinceitcanbeeasilydeployedasahardwareunitanditisalso capableenoughathostingPythonprograms.Wewillreplaceacomputerscreenwitha smallTFTLCDscreenfortheRaspberryPitodisplaytheGUI. Thecloudservices ThemainpurposeofthecloudservicesistoprovideanInternet-basedinterfaceforthe controlcentersothattheusercanaccessitremotely.Beforewehostawebapplicationto performthisoperation,wewillneedanintermediatedatarelay.Thissensordatarelay worksasahostbetweenthecloud-basedwebapplicationandthecontrolcenter.Inthis project,wewillbeusingXivelyastheplatformtocollectthissensordata.Theweb applicationcanbehostedonanInternetserver;inourcase,wearegoingtouseAmazon AWSduetoourfamiliaritywithit. DefiningUXflow Now,althoughweknowwhatthearchitectureoftheoverallsystemlookslike,wehaven’t definedhowtheuserisgoingtointeractwithit.Thisprocessofdesigninguserinteraction foroursystemwillalsohelpustofigureoutdataflowbetweenmajorcomponents. Let’sbeginwiththecomponentsthatareoperatinglocallyatyourhouse,thatis,the monitoringstationandthecontrolcenter.Asyoucanseefromthefollowingfigure,we haveourfirstuserinteractionpointatthecontrolcenter.Theusercanobservethe informationoractuponitifthesystem’sstatusisanalert.Theuseractiontodismissthe alertpromptsmultipleoperationstotakeplaceatthecontrolcenterandthemonitoring station.Werecommendyouthoroughlyexaminethefiguretobetterunderstandtheflow ofthesystem. Similarly,theseconduserinteractionpointislocatedatthewebapplication.Theweb applicationdisplaystheobservationsandsystem’sstatusthatwecalculatedatthecontrol centerandprovidesaninterfacetodismissthealert.Inthisscenario,thedismissaction willtravelthroughXivelytothecontrolcenterwheretheappropriateactionsforthe controlcenterwillremainthesameasinthepreviousscenario.However,intheweb application,theuserhastoloadthewebbrowsereverytimetorequestthedata,whichwas happeningautomaticallyatthecontrolcenter.Takealookatthefollowingfigureto understandtheUXflowforthewebapplication: Thelistofrequiredcomponents Thenecessarycomponentsfortheprojectarederivedusingthreemaincriteria: Easeofavailability CompatibilitywiththeArduinoboard Familiaritywiththecomponentsduetopreviousutilizationinthisbook Thisisthelistofthecomponentsthatyouwillneedtostartworkingontheproject.Ifyou havecompletedthepreviousexercisesandprojects,youshouldalreadyhavemostofthe components.Ifyoudon’twanttodisassembletheprojects,youcanobtainthemfromthe websitesofSparkFun,Adafruit,orAmazon,whoselinksareprovideinthenexttable. Thehardwarecomponentsforthemonitoringstationareasfollows: Component(firststage) Quantity Link ArduinoUno 1 https://www.sparkfun.com/products/11021 ArduinoEthernetShield 1 https://www.sparkfun.com/products/9026 Breadboard 1 https://www.sparkfun.com/products/9567 TMP102temperaturesensor 1 https://www.sparkfun.com/products/11931 HIH-4030humiditysensor 1 https://www.sparkfun.com/products/9569 Miniphotocell 1 https://www.sparkfun.com/products/9088 PIRmotionsensor 1 https://www.sparkfun.com/products/8630 Super-fluxRGBLED,common anode 1 http://www.adafruit.com/product/314 Buzzer 1 http://www.adafruit.com/products/160 Pushbuttonswitch 1 https://www.sparkfun.com/products/97 1 https://www.sparkfun.com/products/512 1 http://www.amazon.com/Arduino-9V-1A-PowerAdapter/dp/B00CP1QLSC/ Resistors As required 220ohm,1kilo-ohm,and10kilo-ohm Connectionwires As required USBcableforArduino (fordevelopmentstage) Arduinopowersupply (fordeploymentstage) Thehardwarecomponentsforthecontrolcenterareasfollows: Component(firststage) Quantity Link RaspberryPi 1 https://www.sparkfun.com/products/11546 TFTLCDscreen 1 http://www.amazon.com/gp/product/B00GASHVDU/ SDcard(8GB) 1 https://www.sparkfun.com/products/12998 Wi-Fidongle 1 http://www.amazon.com/Edimax-EW-7811Un-150Mbps-RaspberrySupports/dp/B003MTTJOY RaspberryPipowersupply 1 http://www.amazon.com/CanaKit-Raspberry-Supply-AdapterCharger/dp/B00GF9T3I0 Keyboard,mouse,USBhub, andmonitor As Requriedfordevelopmentanddebuggingstages required Definingtheprojectdevelopmentstages Asperthesystemarchitecture,wehavethreemainunitsthatcollaborativelycreatethe remotehomemonitoringproject.Theoverallhardwareandsoftwaredevelopmentprocess isalsoalignedwiththesethreeunitsandcanbedistributedasfollows: Monitoringstationdevelopmentstage Controlcenterdevelopmentstage Webapplicationdevelopmentstage Thesoftwaredevelopmentforthemonitoringstationstageincludesdevelopingthe Arduinocodetomonitorsensorsandperformactuatoractionsononeside,while publishingthisinformationtothecontrolcenterontheotherside.Themiddlelayerofthe developmentstage,thatis,theRaspberryPi-basedcontrolcenter,hoststheMosquitto broker.ThisstagealsocontainsthePythonprogramthatcontainstheGUI,situation awarenesslogic,andsubroutinestocommunicatewiththeXivelycloudservice.Thelast stage,thecloudservices,includestwodistinctcomponents,sensordatarelayandaweb application.WewillbeusingtheXivelyplatformasoursensordatarelayandtheweb applicationwillbedevelopedinPythonontheAmazonAWScloudinstance.Now,let’s jumpintotheactualdevelopmentprocessandourfirststopwillbetheArduino-based monitoringstation. Stage1–amonitoringstationusing Arduino Aswediscussed,themaintasksofthemonitoringsystemsaretointerfacesensor componentsandcommunicatetheinformationgeneratedbythesesensorstotheobservers. YouwillbeusingArduinoUnoasthecentralmicrocontrollercomponenttointegratethese sensorsandactuators.WealsoneedameansofcommunicationbetweentheArduinoUno andthecontrolcenterandwewillbeutilizingtheArduinoEthernetShieldforthis purpose.Let’sdiscussthehardwarearchitectureofthemonitoringstationandits components. Designingthemonitoringstation WealreadydesignedunitsbasedonArduinoandtheEthernetShieldinvariousexercises inChapter8,IntroductiontoArduinoNetworking,andChapter9,ArduinoandtheInternet ofThings.Therefore,wehaveassumedthatyouarefamiliarwithinterfacingtheEthernet ShieldwiththeArduinoboard.Wewillconnectvarioussensorsandactuatorswiththe Arduinoboard,asdisplayedinthefollowingdiagram.Asyoucanseeinthisdiagram,the sensorswillprovidethedatatotheArduinoboardwhiletheactuatorswillseekthedata fromtheArduinoboard.Althoughweareautomaticallycollectingenvironmentdatafor thesesensors,thedatafromthebuttonwillbecollectedfrommanualuserinputs. CheckoutthefollowingFritzingdiagramforthedetailedconnectionsinthemonitoring station.Asyoucanseeinourhardwaredesign,thetemperaturesensorTMP102is connectedthroughtheI2Cinterface,whichmeansthatwewillneedtheSDAandSCL lines.Wewillbeusinganalogpins5and6oftheArduinoboardtointerfaceSDAand SCLrespectively.Thehumidity(HIH-4030)andambientlightsensorsalsoprovideanalog outputandareconnectedtotheanalogpinsoftheArduinoboard.Meanwhile,thebuzzer, thebuttonswitch,andthePIRmotionsensorareconnectedthroughthedigitalI/Opins. Thesuper-fluxRGBLEDisacommonanodeLED;thismeansthatitisalwayspowered usingthecommonanodepinsandtheR,G,andBpinsarecontrolledbyusingthePWM pins. Makesurethatyouproperlyconnectallthecomponentstothepinsthatarespecifiedin thefollowingdiagram: Note YoucanlearnmoreabouttheinterfacingofRGBLEDwithArduinofromthetutorialat https://learn.adafruit.com/all-about-leds. IfyouareusinganArduinoboardotherthanArduinoUno,youwillhavetoadjustthe appropriatepinnumbersintheArduinocode.Inaddition,makesurethatthisArduino boardiscompatiblewiththeEthernetShield. Intermsofcircuitconnections,youcanuseabreadboardasshownintheprevious diagram,orifyouarecomfortable,youcanuseaPCBprototypeboardandsolderthe components.Inoursetup,wefirsttestedthecomponentsonthebreadboardandoncethey weretested,wesolderedthecomponents,asshowninthefollowingfigure.Ifyouventure tosolderthePCBboard,makesurethatyouhavethenecessarycomponentsforthejob. ThePCBprototypewillyieldarobustperformancecomparedtothebreadboard,butit willalsomakeitdifficultforyoutodebugandchangethecomponentsafterwards. Ifyouarereadywithyourcircuitconnection,connectyourArduinotoyourcomputer usingtheUSBcable.Also,connecttheEthernetShieldtoyourhomerouterusingan Ethernetcable. TheArduinosketchforthemonitoringstation Beforejumpingintothecodingstage,makesurethatyouhavecollectedtheprebuilt Arduinocodefortheproject.Youcanfinditinthecodefolderofthischapterwiththe filenameArduino_monitoring_station.ino.Thecodeimplementsthenecessarylogicto supporttheoverallUXflowatthemonitoringstation,whichwediscussedintheprevious section.Inthefollowingsections,wewillgothroughthemajorareasoftheprogramso thatyoucanbetterunderstandthesecodesnippets.Now,openthissketchintheArduino IDE.YouarealreadyfamiliarwithsettinguptheIPaddressforArduino.Youalsolearned howtousetheArduinoMQTTlibraryPubSubClientinthepreviouschapter,which meansthatyourArduinoIDEshouldalreadyhavethePubSubClientlibraryinstalledon it.Atthebeginningofthecode,wehavealsodeclaredfewconstants,suchastheIP addressesoftheMQTTserverandArduinoandthepinnumbersofvarioussensorand actuators. Note YouwillhavetochangetheIPaddressofthemonitoringstationandthecontrolcenter accordingtoyournetworksetup.Makesurethatyouperformthesemodificationsbefore uploadingtheArduinocode. Inthecodestructure,wehavetwomandatoryArduinofunctions,setup()andloop().In thesetup()function,wewillsetuptheArduinopintypesandtheMQTTsubscriber channels.Inthesamefunction,wewillalsoattachaninterruptforthepressofthebutton whilesettingupthetimerforthepublishData()function. Publishingsensorinformation ThepublishData()functionreadsthesensorinputsandpublishesthisdatatothe Mosquittobrokerthatislocatedonthecontrolcenter.Asyoucanseeinthefollowing codesnippet,wearemeasuringsensorsvaluesonebyoneandpublishingthemtothe brokerusingtheclient.publish()method: voidpublishData(){ Wire.requestFrom(partAddress,2); byteMSB=Wire.read(); byteLSB=Wire.read(); intTemperatureData=((MSB<<8)|LSB)>>4; floatcelsius=TemperatureData*0.0625; temperatureC=dtostrf(celsius,5,2,message_buff2); client.publish("MonitoringStation/temperature",temperatureC); floathumidity=getHumidity(celsius); humidityC=dtostrf(humidity,5,2,message_buff2); client.publish("MonitoringStation/humidity",humidityC); intmotion=digitalRead(MotionPin); motionC=dtostrf(motion,5,2,message_buff2); client.publish("MonitoringStation/motion",motionC); intlight=analogRead(LightPin); lightC=dtostrf(light,5,2,message_buff2); client.publish("MonitoringStation/light",lightC); } Ifyoucheckoutthesetup()function,youwillnoticethatwehaveusedalibrarycalled SimpleTimertosetupatimermethodforthisfunction.Thismethodexecutesthe publishData()functionperiodicallywithoutinterruptingandblockingtheactualflowof theArduinoexecutioncycle.Inthefollowingcodesnippet,thenumber300000represents thetimedelayinmilliseconds,thatis,5minutes: timer.setInterval(300000,publishData); Note YouwillneedtodownloadandimporttheSimpleTimerlibrarytocompileandrunthe codesuccessfully.Youcandownloadthelibraryfrom https://github.com/infomaniac50/SimpleTimer. Subscribingtoactuatoractions Youcanseeinthesetup()functionthatweareinitializingthecodebysubscribingtothe MonitoringStation/ledandMonitoringStation/buzzerchannels.The client.subscribe()methodwillmakesurethatwhenevertheMosquittobrokergetsany updatesforthesechannels,theArduino-basedmonitoringsystemgetsnotified: if(client.connect("MonitoringStation")){ client.subscribe("MonitoringStation/led"); client.subscribe("MonitoringStation/buzzer"); } Programminganinterrupttohandlethepressofabutton Wehavetakencareofthepublishingandsubscribingfunctionsofthemonitoringstation. Now,wewillneedtointegratethebuttonswitchthatiscontrolledbyinputsfromtheuser. IntheArduinoprogrammingroutines,werunaperiodiclooptocheckthestatusofthe pins.However,thismaynotbeusefulifthebuttonispressedsinceitrequiresimmediate action.ThisactionofpressingthebuttonishandledusingtheArduinointerrupts,as showninthefollowinglineofcode: attachInterrupt(0,buttonPress,RISING); Theprecedinglineofcodeassociatesaninterruptatpin0(digitalpin2)withthe buttonPress()function.Thisfunctionsetsoffthebuzzerswheneverthestateofthe interruptischanged.Inotherwords,whenthebuttonispressedbytheuser,thebuzzer willbeinstantaneouslyturnedoffirrespectiveofthecurrentstatusofthebuzzer: voidbuttonPress(){ digitalWrite(BUZZER,LOW); Serial.println("Setbuzzeroff"); } Testing ThecurrentArduinocodecommunicateswiththecontrolcenterforpublishingand subscribingthedata,butwehaven’tyetsetuptheMosquittobrokertohandlethese requests.YoucanstillgoaheadanduploadtheArduinosketchtoyourmonitoringstation usingtheUSBcable.Thiswillnotresultinanyfruitfulactionsfromthemonitoring stationandyouwillonlybeabletousetheSerial.prinln()commandtoprintvarious sensormeasurements.Therefore,wewilldevelopthecontrolcenternextsothatwecan startaddressingcommunicationrequestsfromthemonitoringstation. Stage2–acontrolcenterusingPython andtheRaspberryPi Inordertodeliverthestatusofthesystemandothersensorobservationstotheuser,the controlcenterneedstoperformvariousoperationsthatincludeobtainingrawsensordata fromthemonitoringstation,calculatingthestatusofthesystem,reportingthisdatatothe cloudservices,anddisplayingobservationusingGUI.Whilethecontrolcenterincludes twomajorhardwarecomponents(theRaspberryPiandTFTLCDscreen),itisalso comprisedoftwomajorsoftwarecomponents(theMosquittobrokerandPythoncode)to handlethecontrolcenterlogic. Tip WeareusingaRaspberryPiinsteadofaregularcomputeraswewantthecontrolcenterto beadeployableandportableunitthatcanbemountedonawall. YoucanstilluseyourowncomputertoeditandtestthePythoncodefordevelopment purposesinsteadofusingaRaspberryPidirectly.However,werecommendthatyou switchbacktotheRaspberryPionceyouarereadyfordeployment. Thecontrolcenterarchitecture TheRaspberryPiisthemaincomputationunitofthecontrolcenterandworksasthebrain oftheentiresystem.SincetheRaspberryPiisusedasareplacementforaregular computer,thearchitectureofthecontrolcentercaninterchangeablyuseacomputerin placeoftheRaspberryPi.Asyoucanseeinthefollowingdiagram,thecontrolcenteris connectedtothehomenetworkusingWi-Fiandthiswillmakeitaccessibletothe monitoringstation.ThecontrolcenterincludestheMosquittobroker;thisisusedasthe communicationpointbetweenthemonitoringstationandthePythonprogramforthe controlcenter.ThePythonprogramutilizestheTkinterlibraryforGUIandthe paho_mqttlibrarytocommunicatewiththeMosquittobroker.Byutilizingthesetwo libraries,wecanconveysensorinformationfromthemonitoringstationtotheuser. However,wewillneedaseparatearrangementtoestablishcommunicationbetweenthe controlcenterandcloudservices.Inouroverallsystemarchitecture,thecontrolcenteris designedtocommunicatewiththeintermediatedatarelay,Xively.ThePythoncodeuses thexively-pythonlibrarytoenablethiscommunication. InChapter8,IntroductiontoArduinoNetworking,wealreadyprovidedyouwithmethods toinstalltheMosquittobroker,thePython-mosquittolibrary,andthexively-python library.WealsolearnedtheprocessofsettinguptheTFTLCDscreenwiththeRaspberry PiinChapter7,TheMidtermProject–aPortableDIYThermostat.Pleaserefertothose tutorialsincaseyouhaven’tcompletedthoseexercisesyet.Assumingthatyouhave configuredtheMosquittobrokerandtherequiredPythonlibraries,youcanmoveontothe nextsection,whichincludestheactualPythonprogramming. ThePythoncodeforthecontrolcenter BeforeyoustartinterfacingtheselibrariesinthePythoncode,startyourMosquittobroker firstfromthecommandlineusingthissimplecommand: $mosquitto Makesurethatyourestartyourmonitoringstationeverytimeyoustartorrestartthe Mosquittobroker.Thisactionwillmakesurethatyourmonitoringstationisconnectedto theMosquittobroker,sincetheprocessofestablishingtheconnectiononlygetsexecuted onceinourArduinocode,thatis,atthebeginningofthesetupprocess. ThePythoncodeforthecurrentprojectislocatedinthecodefolderofthischapterwith thenamecontrolCenter.py.OpenthisfileusingyourPythonIDEandmodifythevalues oftheappropriateparametersbeforeexecutingit.TheseparametersincludetheIPaddress oftheMosquittobrokeralongwiththefeedIDandtheAPIkeyoftheXivelyvirtual device.YoushouldalreadyhavethefeedIDandtheAPIkeyofyourXivelyvirtualdevice fromthepreviouschapter: cli.connect("10.0.0.18",1883,15) FEED_ID="<feed-id>" API_KEY="<api-key" IfyouareusingalocalinstanceoftheMosquittobroker,youcanreplacetheIPaddress with127.0.0.1.Otherwise,replacethe10.0.0.18addresswiththeappropriateIPaddress ofthecomputerthatishostingtheMosquittobroker.Let’strytounderstandthecodenow. Note SometimesonMacOSX,youwon’tbeabletorunTkinterwindowandPythonthreads inparallelduetoanunknownbug.Youshouldbeabletoexecutetheprogram successfullyinWindowsandLinuxenvironments.Thisprogramhasbeentestedwiththe RaspberryPi,whichmeansyouwon’tencounterthesamebugwhiledeployingthecontrol center. CreatingtheGUIusingTkinter Inthepreviousexercises,wealwaysusedasinglePythonthreadtoruntheprogram.This practicewillnothelpustoperformmultipletasksinparallelsuchasobtainingsensor observationfromthemonitoringstationandsimultaneouslyupdatingtheGUIwiththat information.Asasolution,wehaveintroducedmultithreadinginthisexercise.Aswe needtwoseparateloops,oneeachforTkinterandpaho-mqtt,wewillberunningthem independentlyinseparatethreads.Themainthreadwillrunmethodsthatarerelatedto Mosquittoandthecloudservices,whilethesecondthreadwillhandletheTkinterGUI.In thefollowingcodesnippet,youcanseethatwehaveinitializedthe controlCenterWindow()classwiththethreading.threadparameter.Therefore,when weexecutewindow=controlCenterWindow()inthemainprogram,itwillcreateanother threadforthisclass.Basically,thisclasscreatestheGUIwindowwhilepopulatinglabels andotherGUIcomponents.Thelabelsneedtobeupdatedwhennewsensorobservations arrive,aredeclaredasclassvariables,andareaccessiblefromtheclassinstant.Asyoucan seeinthefollowingcodesnippet,wehavedeclaredthelabelsfortemperature,humidity, light,andmotionasclassvariables: classcontrolCenterWindow(threading.Thread): def__init__(self): #Tkintercanvas threading.Thread.__init__(self) self.start() defcallback(self): self.top.quit() defrun(self): self.top=Tkinter.Tk() self.top.protocol("WM_DELETE_WINDOW",self.callback) self.top.title("ControlCenter") self.statusValue=Tkinter.StringVar() self.statusValue.set("Normal") self.tempValue=Tkinter.StringVar() self.tempValue.set('-') self.humdValue=Tkinter.StringVar() self.humdValue.set('-') self.lightValue=Tkinter.StringVar() self.lightValue.set('-') self.motionValue=Tkinter.StringVar() self.motionValue.set('No') #Begincodesubsection #DeclaresTkintercomponents #Includedinthecodesampleofthechapter #Endcodesubsection self.top.mainloop() Thepreviouscodesnippetdoesn’tcontaintheportionwherewedeclaredtheTkinter components,asitissimilartowhatwecodedinthemidtermproject.Ifyouhave questionsregardingTkinter-relatedissues,pleaserefertoChapter6,StoringandPlotting ArduinoData,andChapter7,TheMidtermProject–aPortableDIYThermostat. CommunicatingwiththeMosquittobroker Atthecontrolcenterlevel,wesubscribetotopicsthatarepublishedfromthemonitoring station,thatis,MonitoringStation/temperature,MonitoringStation/humidity,andso on.IfyouhaveperformedanymodificationtotheArduinocodetochangetheMQTT topics,youneedtoreflectthosechangesinthissection.Ifthetopicspublishedbythe monitoringstationdonotmatchthetopicsinthecontrolcenter’scode,youwillnotget anyupdates.AsyoucanseeinthePythoncode,weareassociatingtheon_messageand on_publishmethodswithveryimportantfunction.Wheneveramessagearrivesfromthe subscriber,theclientwillcallthefunctionsassociatedwiththeon_messagemethod. However,everytimeamessagegetspublishedfromthePythoncode,theonPublish() functionwillgetcalled: cli=mq.Client('ControlCenter') cli.on_message=onMessage cli.on_publish=onPublish cli.connect("10.0.0.18",1883,15) cli.subscribe("MonitoringStation/temperature",0) cli.subscribe("MonitoringStation/humidity",0) cli.subscribe("MonitoringStation/motion",0) cli.subscribe("MonitoringStation/light",0) cli.subscribe("MonitoringStation/buzzer",0) cli.subscribe("MonitoringStation/led",0) Calculatingthesystem’sstatusandsituationawareness Thecontrolcenterisassignedwiththetaskofcalculatingthestatusoftheoverallsystem. ThecontrolcentercalculatesthestatusofthesystemasAlert,Caution,orNormalusing thecurrentvaluesoftemperatureandhumidity.Tocalculatethestatus,thecontrolcenter executesthecalculateStatus()functioneverytimeitgetsanupdateforthetemperature orhumidityfromthemonitoringstation.Accordingtothecurrentsituationawareness logic,ifthetemperatureismeasuredabove45degreeCelsiusorbelow5degreeCelsius, wecallthesystem’sstatusasAlert.Similarly,youcanidentifytherangeoftemperature andhumidityvaluesforCautionandNormalstatusesfromthefollowingcodesnippet: defcalculateStatus(): if(tempG>45): if(humdG>80): status="HighTemperature,HighHumidity" elif(humdG<20): status="HighTemperature,LowHumidity" else: status="HighTemperature" setAlert(status) elif(tempG<5): if(humdG>80): status="LowTemperature,HighHumidity" elif(humdG<20): status="LowTemperature,LowHumidity" else: status="LowTemperature" setAlert(status) else: if(humdG>80): status="HighHumidity" setCaution(status) elif(humdG<20): status="LowHumidity" setCaution(status) else: status="Normal" setNormal(status) CommunicatingwithXively ThecontrolcenterisalsorequiredtocommunicatewithXivelywhenitreceivesa messagefromthesubscribedtopics.Wearealreadyfamiliarwiththeprocessofsettingup virtualdevicesanddatastreamsonXively.OpenyourXivelyaccountandcreateavirtual devicecalledControlCenter.NotedownthefeedIDandAPIkeyforthisdeviceand replacetheminthecurrentcode.Onceyouhavethesevalues,createtheTemperature, Humidity,Light,Motion,Buzzer,andStatuschannelsinthisvirtualdevice. LookingatthePythoncode,youcanseethatwehavedeclaredtheindividualdatastream foreachtopicandassociatedthemwiththeappropriateXivelychannel.Thefollowing codesnippetshowsthedatastreamforjustthetemperatureobservation,butthecodealso containsasimilarconfigurationforalltheothersensorobservations: try: datastreamTemp=feed.datastreams.get("Temperature") exceptHTTPErrorase: print"HTTPError({0}):{1}".format(e.errno,e.strerror) datastreamTemp=feed.datastreams.create("Temperature",tags="C") print"Creatingnewchannel'Temperature'" Oncethecontrolcenterreceivesamessagefromthemonitoringstation,itupdatesthedata streamwiththelatestvaluesandpushesthesechangestoXively.Atthesametime,we willalsoupdatetheappropriatelabelintheTkinterGUIusingtheonMessage()function. Wewillusethesamecodesnippetforallthesubscribedchannels: ifmsg.topic=="MonitoringStation/temperature": tempG=float(msg.payload) window.tempValue.set(tempG) datastreamTemp.current_value=tempG try: datastreamTemp.update() exceptHTTPErrorase: print"HTTPError({0}):{1}".format(e.errno,e.strerror) Thecontrolcenteralsoimplementsthefunctiontosetthesystem’sstatusacrossthe system,onceitiscalculatedusingthecalculateStatus()function.Therearethree differentfunctionstoperformthistaskusingamethodthatissimilartowhatwedescribed inthepreviouscodesnippet.ThesefunctionsincludesetAlert(),setCaution(),and setNormal()andtheseareassociatedwithAlert,Caution,andNormalrespectively. Whileupdatingthesystem’sstatus,thesefunctionsalsoperformbuzzerandLEDactions bypublishingtheLEDandbuzzervaluestotheMosquittobroker: defsetAlert(status): window.statusValue.set(status) datastreamStatus.current_value="Alert" try: datastreamStatus.update() exceptHTTPErrorase: print"HTTPError({0}):{1}".format(e.errno,e.strerror) cli.publish("MonitoringStation/led",'red') cli.publish("MonitoringStation/buzzer",'ON') Checkingandupdatingthebuzzer’sstatus Inthecontrolcenter,wesetthebuzzer’sstatustoONifthesystem’sstatusisdeterminedas Alert.IfyoulookbackattheUXflow,youwillnoticethatwealsowanttoincludea featurefortheusertomanuallyturnoffthebuzzer.ThecheckBuzzerFromXively() functionkeepstrackofthebuzzer’sstatusfromXivelyandiftheusermanuallyturnsoff thebuzzerusingthewebapplication,thisfunctionsetsoffthebuzzer. TocontinuethisprocessindependentlyfromtheGUIandsituationawarenessthreads,we willneedtocreateanotherthreadforthisfunction.Thetimeronthisthreadwill automaticallyexecutethefunctionevery30seconds: defcheckBuzzerFromXively(): try: datastreamBuzzer=feed.datastreams.get("Buzzer") buzzerValue=datastreamBuzzer.current_value buzzerValue=str(buzzerValue) cli.publish("MonitoringStation/buzzer",buzzerValue) exceptHTTPErrorase: print"HTTPError({0}):{1}".format(e.errno,e.strerror) print"Requestedchanneldoesn'texist" threading.Timer(30,checkBuzzerFromXively).start() Withthisfunctionrunninginaseparatethreadevery30seconds,thecontrolcenterwill checkthestatusoftheXivelychannelandstopthebuzzerifthestatusissettoOFF.We willexplainhowtheusercanupdatetheXivelychannelforthebuzzerinthenextsection. Testingthecontrolcenterwiththemonitoring station AssumingyourMosquittobrokerisrunning,executethecontrolCenter.pycodewiththe changedparameters.Then,startthemonitoringstation.Afterafewmoments,youwillsee ontheterminalthatthecontrolcenterhasalreadystartedgettingmessagesfromthe publishersthatareinitializedonthemonitoringstation.Theupdateintervalforthe messagesfromthepublisheratthecontrolcenterdependsupontheconfiguredpublishing intervalatthemonitoringstation. Note TheArduinocodeexecutestheprocessofconnectingtotheMosquittobrokeronlyonce afterpoweringon.IfyoustartyourMosquittobrokerafterthat,itwon’tbeableto communicatewiththebroker.So,youneedtomakesurethatyoustarttheMosquitto brokerbeforepoweringonthemonitoringstation. IfyouneedtorestarttheMosquittobrokerforanyreason,removeandrestartthe monitoringstationfirst. Onexecutionoftheprogram,youwillbeabletoseeasmallGUIwindow,asshowninthe followingscreenshot.Thiswindowdisplaysthesensor’svaluesfortemperature,humidity, ambientlight,andmotion.Alongwiththesevalues,theGUIalsodisplaysthestatusofthe system,whichisNormalinthisscreenshot.Youcanalsoobservethateverytimethe controlcentergetsupdatesfromthemonitoringstation,thesystem’sstatusandsensor observationschangeinrealtime: Ifthissetupisworkingcorrectlyonyourcomputer,let’smoveontodeploythecontrol centerontheRaspberryPi. SettingupthecontrolcenterontheRaspberryPi TheprocessofinstallingtheRaspbianoperatingsystemisexplainedinChapter7,The MidtermProject–aPortableDIYThermostat.Youcanusethesamemodulethatyou usedintheMidtermprojectorsetupanewone.OnceyouhaveinstalledRaspbianand configuredtheTFTscreen,connecttheWi-FidonglethroughaUSBport.Atthisstage, weassumethatyourRaspberryPiisconnectedwithamonitor,akeyboard,andamouse toperformthebasicchanges.Althoughwewon’trecommendit,youcanalsousetheTFT screenforthefollowingoperations,ifyouarecomfortablewithit: 1. StartyourRaspberryPiandlogin.Atthecommandprompt,executethefollowing commandtoenterthevisualdesktopmode: $startx 2. Onceyourgraphicaldesktopstarts,youwillbeabletoseetheiconoftheWiFi configutility.Double-clickonthisiconandopentheWiFiconfigutility.Scanfor wirelessnetworksandconnecttotheWi-Finetworkthathasthemonitoringstation. Whenasked,enterthepasswordofyournetworkintheformwindowcalledPSK, andconnecttoyournetwork. 3. Now,yourRaspberryPiisconnectedtothelocalhomenetworkandtotheInternet throughit.It’stimetoupdatetheexistingpackagesandinstalltherequiredones.To updatetheRaspberryPi’sexistingsystem,executethefollowingcommandsinthe terminal: $sudoapt-getupdate $sudoapt-getupgrade 4. Onceyoursystemisupdatedwiththelatestversion,it’stimetoinstalltheMosquitto brokeronyourRaspberryPi.TheRaspbianOShasMosquittointhedefault repository,butitdoesn’thavethecurrentversionthatweneed.Toinstallthelatest versionofMosquitto,executefollowingcommandsintheterminal: $curl-Ohttp://repo.mosquitto.org/debian/mosquitto-repo.gpg.key $sudoapt-keyaddmosquitto-repo.gpg.key $rmmosquitto-repo.gpg.key $cd/etc/apt/sources.list.d/ $sudocurl-Ohttp://repo.mosquitto.org/debian/mosquitto-repo.list $sudoapt-getupdate $sudoapt-getinstallmosquitto,mosquitto-clients 5. ToinstallotherPythondependencies,let’sfirstinstalltheSetuptoolspackageusing apt-get: $sudoapt-getinstallpython-setuptools 6. UsingSetuptools,wecannowinstallalltherequiredPythonlibrariessuchas paho_mqtt,xively-python,andweb.py: $sudoeasy_installpip $sudopipinstallxively-pythonweb.pypaho_mqtt Nowthatwehaveinstalledallthenecessarysoftwaretoolsthatarerequiredtorunour controlcenterontheRaspberryPi,itistimetoconfiguretheRaspberryPisothatitcan provideuninterruptedoperationforacriticalsystemsuchasaremotehomemonitoring system: 1. InthecurrentconfigurationoftheRaspberryPi,thescreenoftheRaspberryPiwill gotosleepaftersometimeandtheWi-Ficonnectionwillbeterminatedwhenthis happens.Toavoidthisproblemandforcethescreentoremainactive,youwillneed toperformthefollowingchanges.Openthelightdm.conffileusingthefollowing command: $sudonano/etc/lightdm/lightdm.conf 2. Inthefile,navigatetotheSetDefaultssectionandeditthefollowingline: xserver-command-X–s0dpms 3. NowthatyourRaspberryPiissetup,itistimetocopytheprogramfilefromyour computertotheRaspberryPi.YoucanuseSCP,PuTTY,orjustaUSBdriveto transferthenecessaryfiletotheRaspberryPi. Ifyouinstallandconfigureeverythingasspecified,yourprogramshouldrunwithoutany errors.YoucanrunthePythonprogramconstantlyinthebackgroundusingthefollowing command: $nohuppythoncontrolCenter.py& ThelastthingthatwewanttosetupontheRaspberryPiistheTFTLCDscreen.The installationandconfigurationprocessesoftheTFTLCDscreenaredescribedinChapter 7,TheMidtermProject–aPortableDIYThermostat.Pleasefollowthestepsinthegiven ordertosetupthescreen.ThecontrolcentermodulealongwiththeRaspberryPiandthe TFTscreencannowbedeployedinanypartofyourhouse. Stage3–awebapplicationusingXively, Python,andAmazoncloudservice Thecloudservicesmoduleoftheoverallsystemenablesremoteaccesstoyourmonitoring stationthroughtheInternet.Theunitinteractswiththeuserviaawebapplicationasan extendedversionofthecontrolcenter.Withtheuseofthiswebapplication,theusercan observethesensorinformationfromthemonitoringstationandthesystem’sstatus calculatedbythecontrolcenterwhilehavingremotecontroltoturnoffthebuzzer.So, whatdoesthearchitectureofthecloudserviceslooklike? Architectureofthecloudservices Thearchitectureofthecloudservicesmodulewithitsassociatedcomponentsisdisplayed inthefollowingdiagram.Inthecloudservicesarchitecture,weareusingXivelyasthe intermediatedatarelaybetweenthewebapplicationandthecontrolcenter.Thecontrol centerpushestheobservationsobtainedfromthemonitoringstationtotheXively channels.Xivelystoresandrelaysthedatatothewebapplicationthatishostedonthe AmazonAWS.TheserverinstanceontheAmazonAWSisusedtomaketheweb applicationaccessiblethroughtheInternet.TheserverinstancerunstheUbuntuoperating systemandthewebapplicationthatisdevelopedusingtheweb.pylibraryinPython. Inthepreviousstage,wealreadycoveredtheprocessofsettingupXivelyandthe channelstoaccommodatesensordata.Inthecontrolcentercode,wealsoexplainedhow wecanpushtheupdatedobservationstotheappropriateXivelychannels.Therefore,we reallydonothaveanygroundtocoverfortheXivelyplatformatthisstageandwecan moveontothewebapplication. PythonwebapplicationhostedonAmazonAWS Inthepreviouschapter,wesetupanAmazonAWScloudinstancetohostaweb application.Youcanusethesameinstancetohostthewebapplicationfortheremote homemonitoringsystemtoo.However,makesurethatyouhaveinstalledtheweb.py libraryonyourserver. 1. Inyourcomputer,opentheWeb_Applicationfolderandthenthe RemoteMonitoringApplication.pyfileinyoureditor. 2. Inthecode,youwillbeabletoseethatwejustexpandthewebapplicationprogram thatwecreatedinChapter9,ArduinoandtheInternetofThings.Weusethe templatesbasedonweb.pyandtheGET()andPOST()functionstoenabletheweb application. 3. Intheapplication,wefetchinformationfromeachXivelychannelandprocessitvia aseparatefunction.Forexample,thefetchTempXively()functionobtainsthe temperatureinformationfromXively.EverytimethePOST()functionisexecuted, thefetchTempXively()functionfetchesthelatestvalueoftemperaturereadingfrom Xively.Thisalsomeansthatthewebapplicationdoesnotpopulateandrefreshthe latestinformationautomaticallyandwaitsforPOST()toexecutetheappropriate functions: deffetchTempXively(): try: datastreamTemp=feed.datastreams.get("Temperature") exceptHTTPErrorase: print"HTTPError({0}):{1}".format(e.errno,e.strerror) print"Requestedchanneldoesn'texist" returndatastreamTemp.current_value 4. Thewebapplicationalsoprovidesaccesstocontrolthebuzzerfromtheuser interface.ThefollowingcodesnippetaddstheBuzzerOffbuttonwithotherForm components.Whentheformissubmittedafterthisbuttonispressed,theweb applicationexecutesthesetBuzzer()function: inputData=web.input() ifinputData.btn=="buzzerOff": setBuzzer("OFF") 5. ThesetBuzzer()functionaccesstheXivelychannel,Buzzer,andsendstheoffvalue iftheBuzzerOffbuttonispressed.Thecurrentwebapplicationdoesn’tincludethe BuzzerOnbutton,butyoucaneasilyimplementthisfunctionalitybyreusingthe codethatwedevelopedfortheBuzzerOffbutton.Thisfunctionprovidesthe referencecodeforothercontrolpoints,whichyoucanreusewithminor modifications: defsetBuzzer(statusTemp): try: datastream=feed.datastreams.get("Buzzer") exceptHTTPErrorase: print"HTTPError({0}):{1}".format(e.errno,e.strerror) datastream=feed.datastreams.create("Buzzer", tags="buzzer") print"CreatingnewChannel'Buzzer" datastream.current_value=statusTemp try: datastream.update() exceptHTTPErrorase: print"HTTPError({0}):{1}".format(e.errno,e.strerror) 6. Inthecode,youwillalsohavetomodifytheXivelyfeedIDandtheAPIkeyand replacethemwiththevaluesthatyourobtainedfromyourvirtualdevice.Onceyou haveperformedthismodification,runthefollowingcommand.Ifeverythinggoesas planned,youwillbeabletoopenthewebapplicationinyourwebbrowser. $pythonRemoteMonitoringApplication.py IfyouarerunningthePythoncodeonyourcomputer,youcanopen http://127.0.0.1:8080toaccesstheapplication.Ifyouarerunningtheapplicationon thecloudserver,youneedtoentertheIPaddressordomainnameofyourservertoaccess thewebapplication,http://<AWS-IP-address>:8080.Ifthewebapplicationisrunning fromthecloud,itcanbeaccessedfromanywhereusingtheInternet,whichwasoneofthe originalprojectrequirements.Withthislaststep,youhavesuccessfullycompletedthe developmentoftheremotehomemonitoringsystemthatisbasedonArduinoandPython. Testingthewebapplication Whenyouopenthewebapplicationinabrowser,youwillbeabletoseeasimilaroutput asshowninthefollowingscreenshot.Asyoucansee,thewebapplicationdisplaysthe temperature,humidity,light,andmotionvalues.TheRefreshbuttonfetchesthesensor datafromXivelyagainandloadstheapplicationoncemore.TheBuzzerOffbuttonsets thevalueoftheXively’sBuzzerchanneltoOFF,whichthengetpickedupbythecontrol center,anditturnsoffthebuzzeratthemonitoringstationsubsequently: Testingandtroubleshooting Duetothenumberofcomponentsinvolvedandcomplexprogrammingassociatedwith them,theoverallprojectisacomplexsystemtotestanddebug.Beforeyoujumpinto troubleshooting,makesurethatyouhaveproperlyfollowedthestepsthatweredescribed intheprevioussectionsinorder.Thefollowingareafewsolutionstopossibleproblems thatcanoccurduringtheexecutionoftheproject: Troubleshootindividualsensorperformance: Ifyoursensormeasurementsarewayofftheexpectedvalues,thefirstthingthat youwanttoevaluateistheconnectionofthesensorpinstotheArduinoboard. Makesurethatyouhaveconnectedthedigital,analog,andPWMpinscorrectly. CheckwhetheryourEthernetShieldboardisproperlyconnectedtoArduino Uno. Evaluatetheconnectionsofthe5Vpowersupplyandgroundforeach component. AvoidXively’supdatelimit Xivelyimposesalimitonthemaximumnumberoftransactionsthatyoucan performinalimitedamountoftime.Whilerunningyourcontrolcentercode,if youencounteranerrorforexceedingthelimit,waitfor5minutesbeforeyour accesslimitgetslifted. IncreasethedelaybetweenconsecutiveXivelyupdatesatthecontrolcenter level: threading.Timer(120,checkBuzzerFromXively).start() Reducethefrequencyofpublishedmessagesatthemonitoringstation: timer.setInterval(600000,publishData); YoucanalsocombinevariousXivelychannelsbyformattingdataintoJSONor XML. WorkingwiththemaximumcurrentdrawlimitationofArudino: The+5VpowerpinanddigitalpinofArduinocanprovideamaximumcurrent of200mAand40mArespectively.Whenrunningsensorsdirectlyfromthe Arduinoboard,makesurethatyoudonotexceedtheselimits. Makesurethecombinedcurrentrequirementofallthesensorsislessthan200 mA.Otherwise,thecomponentswon’tbeabletogetenoughpowertorunand thiswilltranslateintofaultysensorinformation. Youcanprovideexternalpowertothecomponentsthatrequirelargeamountsof currentandcontrolthispowermechanismviaArduinoitself.Youwillneeda transistorthatisactingasaswitchthatcanthenbecontrolledusingthedigital pinsofArduino.Thetutorialathttps://learn.adafruit.com/adafruit-arduinolesson-13-dc-motors/transistorsshowsasimilarexampleforaDCmotor. Solvenetworkproblems: Insomescenarios,yourmonitoringstationwon’tbeabletocommunicatewith thecontrolcenterduetonetworkproblems. ThisproblemcanbesolvedbyusingmanualIPaddressesforboth,Arduinoand theRaspberryPi.Inourproject,weuseamanualIPaddressfortheArduino,but theRaspberryPiisconnectedusingtheWi-Finetwork.Inmostcases,whenyou areusingyourhomeWi-Finetwork,Wi-Firoutersaresetuptoprovidedynamic IPaddressestothedeviceeverytimetheyreconnecttotherouter. YoucansolvethisbyconfiguringyourWi-FiroutertoafixedIPaddressforthe RaspberryPi.AsthetypeandmodeloftheWi-Firouterisdifferentforevery scenario,youwillhavetouseitsusermanualoronlinehelpforumsforsettingit up. Workingwithbuzzer-relatedissues: Sometimesthebuzzersoundcanbetooloudortooquiet,dependinguponthe sensorthatyouareusing.YoucanusePWMtoconfiguretheintensityofthe buzzer.Inourproject,weusedtheArduinodigitalpin9toconnectthebuzzer. ThispinalsosupportsPWM.InyourArduinocode,modifythelinetoreflect changesforthePWMpin.ReplacethedigitalWrite(BUZZER,HIGH);line withanalogWrite(BUZZER,127);. Thisroutinewillreducetheintensityofthebuzzerbyhalffromtheoriginal level.YoucanalsochangethePWMvaluefrom0to255andsettheintensityof thebuzzersoundfromlowesttohighest. ControlcenterGUIcalibration: DependinguponthesizeoftheTFTLCDscreenthatyouareusing,youwill havetoadjustthesizeofthemainwindowofTkinter. First,runthecurrentcodeonyourRaspberryPiandifyouseethattheGUI windowdoesnotmatchthescreen,addthefollowinglineofcodeafter initializingthemainwindow: top.minsize(320,200) Thiscodewillfixtheproblemwiththesizefora2.8inchTFTLCDscreen.In thepreviouscodesnippet,320and200representthepixelsizesforwidthand lengthrespectively.Forotherscreensizes,changethepixelsizeaccordingly. TesttheLED: Incurrentcodeconfiguration,theLEDisturnedononlywhenthesystem changestoAlertorCaution.Thatmeansyouwon’tbeabletotesttheLEDs unlessthesesituationsoccur.Tocheckwhethertheyareworkingcorrectly, executethefollowingcommandatthecontrolcenter: $mosquitto_pub–t"MonitoringStation/led"–m"red" ThiscommandwilllightuptheLEDinred.ToturnofftheLED,justuseoff insteadofredinthepreviouscode. Ifnothinglightsup,youshouldchecktheconnectionwiresoftheLEDs.In addition,checkfornetwork-relatedissuesastheMosquittoitselfmightnotbe working. Ifyouseeanycolorotherthanred,thismeansthatyouhaven’tconnectedthe LEDcorrectlyandyouneedtointerchangethepinconfigurationofyourLED. IfyouareusinganLEDdifferentthansuper-fluxRGB,youshouldcheckout thepinlayoutinthedatasheetandreorganizetheconnections. Extendingyourremotehomemonitoring system TosuccessfullycreatecommercialproductsfromDIYprojectprototypes,youwillneedan additionallayeroffeaturesontopofbasicfunctionalities.Thesefeaturesactuallymake thingsconvenientforauserwhentheyinteractwiththesystem.Theotherdistinguishable featureisthetangibilityofthesystem,whichmakeslarge-scaleproductionandsupport possible.Althoughthereareplentyoffeaturesthatyoucanimplement,werecommendthe followingmajorimprovementstoelevatethelevelofthecurrentproject. Utilizingmultiplemonitoringstations Inthisproject,wedevelopedamonitoringstationasaprototypewitharangeof functionalitythatisdemonstratedbyaremotehomemonitoringsystem.Aremote monitoringsystemcanhavemultiplenumbersofmonitoringstationstocovervarious geographicallocations,suchasdifferentroomsinsideahouse,ordifferentofficecubicles. Basically,alargenumberofmonitoringstationscancoveranextendedareaandprovide efficientsurveillanceofthedomainthatyouaretryingtomonitor.Ifyouwanttoextend thecurrentprojectwithanarrayofmonitoringstations,youwillrequiresomeofthe followingmodifications: Eachmonitoringstationcanhaveitsowncontrolcenteroracentralizedcontrol centerforallofthem,dependingupontheapplicationrequirements. YouwillhavetoupdatethePythoncodeforthecontrolcentertoaccommodatethe changes.ExamplesofthesechangesincludemodifyingtopictitlesforMQTT, coordinatingbetweenthesemonitoringstations,updatingdatamodelsforXively updates,andsoon. ThefreeXivelyaccountmaynotbeabletohandlethelargeamountsofdatacoming fromthemonitoringstations.Inthiscase,youcaneitheroptimizetheupdaterate and/orpayloadsizeorupgradeyourXivelyaccounttocomplywiththerequirements. YoucanalsoresorttootherfreeservicessuchasThingSpeak,Dweet.io,andCarriots, butyouwillhavetomakesubstantialmodificationstotheexistingcodestructure. Youcanalsoupdatethewebapplicationtoprovideyouwithaselectionmenuforthe monitoringstationsordisplayallofthematonce.Youwillalsohavetochangethe codetoyieldthemodifieddatamodels. Extendingsensorycapabilities Intermofsensors,weareonlyinterfacingtemperature,humidity,ambientlight,and motionsensors.However,theactuationislimitedtothebuzzerandLED.Youcan implementthefollowingchangestoimprovethesensorycapabilitiesoftheproject. Inarealscenario,aremotehomemonitoringsystemshouldbeabletointerfacewith otherexistingsensorssuchasthesecuritysystem,monitoringcameras,refrigerator sensors,doorsensors,andgaragesensorsthroughoutahome. Youcanalsointerfacethisprojectwithotherappliancessuchastheairconditioner, heater,andsecurityalarm,whichcanhelpyoutocontroltheenvironmentthatyou arealreadymonitoring.Asatrial,thesecomponentscanbeinterfacedusingasetof relaysandswitches. Youcanupgradethecurrentsensorsatthemonitoringstationwithmorepowerful, efficient,andaccuratesensors.However,themonitoringstationwiththeupgraded sensorsmayrequireamorepowerfulversionofArduinowithmoreI/Opinsand computationcapabilities. Youcanalsouseadditionalsensorsotherthanthoseusedinthisprojectatthe monitoringstation.Therearelargeamountofheterogeneous,Arduino-supportedDIY sensorsthatyoucanbuyofftheshelf.ExamplesofthesesensorsincludetheAlcohol GasSensor(MQ-3),LPGGasSensor(MQ-6),CarbonMonoxideSensor(MQ-7), MethaneGasSensor(MQ-4),andsoon.Thesesensorscanbesimplyinterfacedwith theArduinojustliketheothersensorsthatweconnectedearlier. Toaccommodatethesechanges,youwillberequiredtochangethecontrolcenter logicandalgorithms.Ifyouareinterfacingathird-partycomponent,youmayalso havetorevisitthesystemarchitectureandadjustit. Similarly,youwillalsohavetorunfrequentupdatestoXivelyfortheadditional numberofsensors,makingthefreeversioninadequate.Toresolvethis,youcanpay forthecommercialversionofaXivelyaccountorusealimitednumberofrequests usingaJSONfileformatsimilartotheonedisplayedinthefollowingcodesnippet: { "version":"1.0.0", "datastreams":[ { "id":"example", "current_value":"333" }, { "id":"key", "current_value":"value" }, { "id":"datastream", "current_value":"1337" } ] } ImprovingUX Whenwedesignedtheuserexperienceforthisproject,ourgoalwastodemonstratethe usefulnessofaUXdesignindevelopingthesoftwareflow.InthecurrentUXdesign,the controlcenterandthewebapplicationhavelimitedcontrolandfeaturesforauser.The followingareafewchangesthatyouneedtoimplementtoimprovetheUXoftheproject: Addtooltipsandpropernamingconventionsforthevariousdescriptions.Implement aproperlayouttodifferentiatebetweenthevariousinformationcategories. AddbuttonsforthebuzzerandtheLEDcontrolonthecontrolcenterGUI. Inthewebapplication,useaJavaScriptandAjax-basedinterfacetoautomatically refreshthechangesinsensorvalues. ProvideaUImechanismsothattheusercanchangetheupdateintervalatthecontrol centerandthewebapplication.Oncethesechangesaremade,propagatethem througheachprogramsothatthemonitoringstationcanstartpublishingmessagesat thenewinterval. Expandingcloud-basedfeatures Inthecurrentsetup,weareusingtwostagestoprovidecloud-basedcapabilitiesand enableremotemonitoring.WehaveXivelyasadatarelayandAmazonAWStohostthe webapplication.Ifyouareworkingonacommercial-gradeproductandwanttoreduce thecomplexityofthearchitecture,youcanimplementthefollowingchanges: Youcandevelopyourowndatarelayonyourcloudinstanceusingopensourcetools suchasThingSpeak.Yourcontrolcenterwillthencommunicatedirectlytoyour serverandeliminatedependencyonthird-partyIoTservices. IfXivelyisyourplatform,youcanalsouseadditionalfeatures,suchasgraphson yoursmartphone,whichareprovidedbyXively.Onceyourphoneispairedwith Xively,youcanaccessthisfeaturedirectly. Alternatively,youcanuseothercloudservicessuchasMicrosoftAzureandGoogle AppengineinsteadofAmazonAWS.Youcanalsosetupyourowncloudserver, dependinguponyourfamiliaritywithcloudcomputing.Althoughhavingyourown cloudwillgiveyoucompletecontroloftheserver,third-partyservicessuchas Amazoncanbemorecosteffectiveandrequirelessmaintenancecomparedtoselfhostedservers. Ifyouareplanningtodevelopalarge-scalesystemthatisbasedonthecurrent architecture,youcanincreasethecomputingcapabilityofyourexistingcloud instance.Youcanalsoimplementadistributedserversystemtoaccommodatethe largenumberofremotemonitoringsystemsthatcanbeaccessedbyanevengreater numberofusers. Improvingintelligenceforsituationawareness Inthisproject,wehaveusedfourdifferentsensorstomonitorthephysicalenvironment— eachsensorobtainsuserinputswithtwotypesofactuatorsfornotification.Althoughwe areusingagoodamountofinformationsources,oursituationawarenessalgorithmis limitedtoidentifyingout-of-rangetemperatureandhumidityvalues.Youcanimplementa fewextendedfeaturestomakeyoursystemmoreversatileanduseful: Implementdifferentlogicfordayandnightscenarios,whichcanhelpyoutoavoid unwarrantedfalsealarmsatnight. Implementanintruderdetectionalgorithmusingthemotionsensorforwhenyouare notathome. Utilizeacombinationofambientlightsensorvalueswithmotionsensorstoidentify energywastage.Forexample,ascenarioinwhichmorelightisrecordedduringthe nightwhenthemotionsaresignificantlylowexplainsthatyoumayhaveforgottento turnoffthelightsduringthenight. Creatinganenclosureforhardwarecomponents Justlikesoftware-basedfeatures,thehardwarecomponentsalsorequireamajorrevampif youdevelopacommercial-gradeproduct.Nowadays,3Dprintershavebecomeviableand itisreallyeasytodesignandprintplastic3Dcomponents.Youcanalsouseprofessional 3DprintingservicessuchasShapeways(http://www.shapeways.com),Sculpteo (http://www.sculpteo.com),ormakexyz(http://www.makexyz.com)foryourenclosures. Youcanevenusealasercutterorothermeansofmodelmakingtocreatethehardware enclosures.Theseareafewhardwareimprovementsthatyoucanimplement: Thesensorandactuatorsthatareassembledonaprototypeboardcanbeorganizedon aPCBandpermanentlyfixedforstableandrobustoperation. Ahardwareenclosureforthemonitoringstationcanmakeitportableandeasily deployableinanyenvironment.Whendesigningthisenclosure,youshouldalso considertheproperplacementofthemotionsensorandtheambientlightsensor, alongwithabuttontomakethemaccessibletotheuser. TheRaspberryPiandTFTLCDscreen,whichmakeupthecontrolcenterhardware, canalsobeenclosedinamountablepackage. AddingtouchscreencapabilitiestotheTFTLCDscreencanenableadditional controloverthesystem,expandingtheUXusecases. Summary Inthischapter,wedevelopedaworkingprototypeofaremotehomemonitoringsystem andalsolearnedtheprocessofhardwareproductdevelopmentsimultaneously.Inthe project,weutilizedmostofthehardwarecomponentsandsoftwaretoolsthatweused throughoutthebook.Webeganbydesigningthesystemarchitecturesothatwecould coordinatetheutilizationofthesetools.Later,weventuredintotheactualdevelopment stages,whichincludeddesigningthehardwareunitsanddevelopingprogramstorunthese units.Intheend,weprovidedalistofimprovementstomakethisprototypeintoareal commercialproduct.Youarewelcometousethismethodologytodevelopyourfuture projectsandproducts,asyounowhaveexperienceworkingwiththisone. Inthelastchapter,wearegoingtoutilizethesameprojectdevelopmentmethodologyto createaninterestingprojectthatutilizesyourmessagesfromasocialnetworkwebsiteto giveyoucontroloveryourhardware. Chapter11.Tweet-a-PowerStrip SmartpowermanagementunitsorstripsarepartofsomeofthemostpopularIoT subdomains,smarthomesandsmartgrids.Nowadays,smartpowerstripsare commerciallyavailableandprovidealargenumberoffeatures,suchasremoteaccess, smartpowerusage,andpowermanagement.Inthisproject,wearegoingtocreateasmart DIYpowerstripthatcanbecontrolledremotelyusingstatusmessagespostedonTwitter, thepopularsocialmediawebsite(http://www.twitter.com).Thesemessagesarealso knownastweets.Basically,justlikeyoucancontrolsensorsremotelyusingaweb browser,youcancontrolthembysendingatweet.We’vealreadyworkedwithlow-power sensorsinthepreviousproject,solet’sworkwithACappliancesinthisproject.Wewill beimplementingthesameprojectdevelopmentmethodsthatweutilizedintheprevious project.Thischapteravoidsadditionalexplanationsabouttheprocessandsticksonlyto thedetailsassociatedwiththeproject. Projectoverview ThisprojectrequiresthedevelopmentofasmartpowerstripusingArduinoandPython, whilethecontrolinputstothestripsaretweets.Althoughweareonlyenablingremote accesstothepowerstrip,therearealargenumberofadditionalfeaturesthatcanbe implementedinfuturetoelevatethisDIYprojecttoacommercialproduct. Themajorgoalswewanttoachieveinthisprojectareasfollows: Theusershouldbeabletoturntheindividualpowerportsonandoffusing customizedtweets TheusershouldbeabletocheckthestatusofthepowerportsusingTwitter Projectrequirements Herearetheinitialprojectrequirements,derivedfromthegoals: Thesystemshouldhave110V(or220V)ACpowerportsinterfacedwithrelays. AnArduino-basedunitshouldbeabletocontroltheserelays,ultimatelycontrolling theapplianceconnectedthroughthepowerports. Thesystemshouldbeabletodecodethetweetssentbytheuserandconvertthem intoappropriatecontrolmessagesforArduino. ThePython-basedprogramthatprocessesthetweetsshouldthenpublishthese messagessothatArduinocancompletethoseactionsusingtherelays. Tosumup,therelaysshouldbecontrolledinanearreal-timemannerusingthe tweetssentbytheuser. Thesystemshouldalsounderstandkeywordstocheckthestatusoftherelaysand automaticallytweetthestatus.Thesystemshouldprocessatweetonlyonceand shouldbeabletorememberthelasttweetprocessed. Note 110Vversus220VACpower Dependingonthecountry,yourACpowersupplymayhavevoltageratingsof 110/120Vor220/240V.Althoughthecircuitdiagramusedbythisprojectmentionsa 110VACpowersupply,thesamecircuitshouldalsoworkfora220Vpowersupply. Ifyouareusinga220Vsupply,checkoutthefollowingnotesbeforemoving forward: Ensurethattheappliancesyouaretryingtooperate,suchasfans,lights,andso on,areratedforsimilarACpower Youhavetoensurethattherelaysusedbytheprojectarecompatiblewithyour ACpowersupply ArduinoworksonaDCpowersupply,anditisnotaffectedbyanyvariationin ACpower Systemarchitecture Fromtheprecedingrequirements,let’ssketchthearchitectureoftheTweet-a-PowerStrip system.Thesystemarchitecturetriestoutilizethehardwarecomponentsandsoftware toolsyoulearnedinthepreviouschapters,whilehavingarelaycomponentastheonly exceptionalcomponent.Asyoucanseeinthearchitectureinthefollowingdiagram,we areemployingtherelaytocontrolvarioushomeappliances.Theseappliancesareusually poweredbyacommon110VACpowersupplyavailableineachhome.Insteadof controllingasingleappliance,weareimplementingafour-channelrelaytocontrolatleast fourappliances,suchasalamp,afan,atoaster,andacoffeemachine. TherelayiscontrolledusingthedigitalpinsoftheArduinoUnoboard,whichutilizesthe EthernetShieldtoconnecttoyourhomenetwork.Acomputationunitthatmayconsistof acomputer,aRaspberryPi,oraserver,usesPythonanditssupportinglibrariestoaccess tweets.ThecomputationunitalsodeploysaMosquittobroker.Thisbrokerhandlesthe topicsfromthePythonprogramandArduinotocontroltherelays.Theusercanpost tweetscontainingkeywordsfromanyplatform,suchasaphoneorabrowser,andthe tweetsareultimatelycapturedbythecomputationunit. Requiredhardwarecomponents Thisprojectwillrequirethefollowinghardwarecomponentsthroughoutthedevelopment andthedeploymentstages: Component Amount Website/note ArduinoUno 1 https://www.sparkfun.com/products/11021 ArduinoEthernetShield 1 https://www.sparkfun.com/products/9026 Relay(four-channel,Arduinocompatible) 1 http://www.amazon.com/JBtek-Channel-Module-ArduinoRaspberry/dp/B00KTEN3TM/ PowerSwitchTail 4 Powerstrip Optional Breadboard 1 Fordevelopmentstage USBcableforArduino 1 Fordevelopmentstage Arduinopowersupply 1 Fordeploymentstage Electrictape Asper requirements Connectionwires Asper requirements http://www.powerswitchtail.com/ Alternativetorelay Relays Asyoucanseeinthefollowingimage,weareintroducinganewhardwarecomponent thatwasnotutilizedinanyofthepreviouschapters—arelay: Thisisanelectromagneticdevicethatuseselectricitytobeoperatedasaswitch.Atypical relaycontainsthreecontactsonthehigh-powerside,normallyconnected(NC),common (C),andnormallyopen(NO).Theotherside(thecontrolside)oftherelayrequiresan activationvoltagetotoggletheconnectionfromcommon-NCtocommon-NO.Thisaction demonstratestheswitchfunctionalitiesfortheconnectiononthehigh-powerside.We’ll useArduino-compatiblerelaysfrommanufacturerssuchasKeyesorSainSmart.These relaysareavailableinsingle-,two-orfour-channelconfigurations.Onthehigh-power side,therelayssupportupto250V,10AACpoweror30V,10ADCpower.Therelaysare controlledusing5VDConthelow-powerside,whichisprovidedusingthedigitalI/O pinsoftheArduinoboard. PowerSwitchTail WorkingwithACpowercanbehazardousifyouhaven’tdealtwithitpreviouslyorifyou arenotfamiliarwiththenecessaryprecautionsandmeasurements.Ifyouarenot comfortablewithworkingwithopenrelaysorconnectingACpowertothem,thereis anotherdevicethatyoucanusetoreplacetherelay—thePowerSwitchTail,asafely enclosedboxthatcontainsopticallyisolatedsolid-staterelaysandprovidesaconvenient waytointerfaceyourACappliancewiththeArduinoboard.Thefollowingisanimageof thePowerSwitchTail,whichcanbeobtainedfromitsofficialwebsite (http://www.powerswitchtail.com/): Note Ifyouaredealingwitha220V/240Vpowersupply,thePowerSwitchTailwebsitealso providesanassemblykitfor200Vto240Vpowersupply,at http://www.powerswitchtail.com/Pages/PowerSwitchTail240vackit.aspx. Itisreallyeasytoassemblethekitfromtheguidelinesprovidedat http://www.powerswitchtail.com/Documents/PSSRTK%20Instructions.pdf. Forthisproject,youwillneedfourofthesedevicestoreplacethefour-channelrelaythat wearegoingtouse.Asyoucanseeinthefollowingdiagram,oneendoftheTailgoesinto theregularpowerport,whileyouneedtoconnectyourappliancetotheotherport. Meanwhile,youcanusethethreecontrolinputstocontroltherelay.Weareusingoneof thedigitalI/OpinsoftheArduinoboardtosendthecontrolsignaltotheTail.Whengoing aheadwiththeTailsinsteadoftherelays,makesurethatyoumakenecessaryamendments totheupcominghardwaredesign. Userexperienceflow Fromthesystemarchitecturewehavecreated,whatshouldtheuserexperience(UX) flowwhileworkingwiththeTweet-a-PowerStripbe?WehavedividedtheUXintotwo separatesections:controllingthepowertotheappliances,andcheckingthestatusofthe powerstrip. InthefirstUXflowdesign,asdisplayedinthefollowingdiagram,theuserbeginsby sendingatweetcontainingthenameoftheappliance(#fan,#lamp,#toaster,or#coffee) andthecontrolcommand(#onor#off).Thesystemshouldbeabletohandlethetweet fromthepointofparsinguntiltheappliancehasbehavedasaskedfor.Thesystemshould alsoprovideahassle-freeexperiencefortheuser,wheretheuserdoesn’thavetoperform anyfurtheractionsthansimplysendingtweets. Similarly,theusershouldbeabletopost#status#checktweetsandsimplyobtainthe statusreportpostedbackbythesystem.Thesystemshouldhandlecheckingthestatusof thepowerports,publishingittothecomputationunit,andpostingatweetwiththe messagewithoutanyadditionalinputfromtheuser. ThefollowingdiagramshowstheUXflowforcheckingthesystemstatus: Developmentanddeploymentstages Accordingtothearchitecture,werequiretwomaindevelopmentstagestocompletethe project.Thefirststage,whichinteractswiththeappliancethroughtherelays,isdeveloped usingArduino.Thisunitsubscribestothetopicsassociatedwiththeappliances,andonce itreceivesanappropriatemessage,itexecutestheactionontherelaylevel.Inthesecond stage,wedealwiththeindividualtweets,whereweparsethetweetsfromtheTwitter account,checkforduplicates,decodeactionsfromthemessages,andalsoposttweetswith statusreports.Duringthesedevelopmentstages,wearegoingtouseabreadboardand jumperwirestotesttheArduinoandPythonprograms.Atthisstage,theprojectisstillnot readytodeployasaportableunitfordailyusage. ThedeploymentstagecontainstasksofcreatingaPCBforthebreadboardconnections andinsulatingwirestoavoidanyelectrichazard.Youcanalsobuyorcreateanenclosure boxtoisolatetheopenhardwarefromphysicalcontact.Asthedevelopmentstagecontains everythingthatisrequiredtoconverttheprojectintoitsworkingstate,wearenotgoingto divedeepintothedeploymentstage.Youcanperformadditiondeploymenttasks accordingtoyourpersonalrequirements. Let’sstartfromthehardwaredesignstageanddevelopthephysicalsectionofthesmart powerstripusingArduino. Stage1–asmartpowerstripwith Arduinoandrelays ThehardwareofTweet-a-PowerStripcontainsArduinoasthemaincontrollerunitthat interfaceswiththerelaysandtheEthernetShieldtocommunicatewiththecomputation unit.TheArduinocodeimplementstheMQTTclient,usingthePubSubClientlibraryto publishandsubscribetothetopics.Althoughweareusingsomeexampleappliancesto controltheuseoftherelay,youcanselectanyotherapplianceyouown.Youcanalsouse acommercialpowerstripinsteadofanindividualpowerplug. Hardwaredesign Whileassemblingthehardwarecomponents,asdisplayedinthefollowingdiagram,make sureyouarepreciseinconnectingtheapplianceswiththeACpowerplugs.Onewireof theACplugisdirectlyconnectedtotheappliance,whiletheotherisconnectedbetween theCandNOportsoftherelay.Wehaveconnectedthecontrolsideoftherelaytothe digitalpinofourArduino.Asweareusingafour-channelrelay,wewillhavetoutilize fourdigitalIOpinsfromtheArduinoboard.Completetheremainingconnectionsas shownhere: Connectingthehardwareunitisfairlysimple,butrequiresalotofprecisionbecauseit involveshigh-powerACconnections. Tip Youshouldcovertheopen110VACpowercordsgoingtotherelayandtheappliance withelectrictapetoavoidanytypeofelectricalhazard.Keepingtheselivewiresopencan bereallydangerousduetothelargeamountofcurrentbeingcarriedbythem.Inthe deploymentstage,aplasticcoveroraboxaroundtherelayunitcanalsobehelpfulin coveringthelivepowerwires. Onceyouarereadywiththeconnections,connecttheArduinoboardtoyourcomputer usingaUSBport,asshowninthefollowingimage: TheArduinocode TheArduinosketchforthissectionislocatedinthefoldercontainingthechaptercode withtheArduino_powerstrip.inofilename.YoucanopenthefileintheArduinoIDEto explorethecode.Asusual,youwillhavetochangetheIPaddressesofthedeviceandthe MosquittoservertotheappropriateIPaddresses,whilealsochangingtheMACaddressof theEthernetShield.ThefollowingcodesnippetshowsthedeclarationoftheArduinopins andtheirrolesinthemainfunction,setup().Makesurethatyouareusingthesamepin numbersthatyouhaveusedtoconnecttherelay.Alternatively,youcanchangethe appliancenametothatoftheapplianceyouareusing.Also,makesurewhateverchanges youmakeinthevariablenamesshouldbereflectedintheentirecodetoavoidany compilationerrors: pinMode(FAN,OUTPUT); pinMode(LAMP,OUTPUT); pinMode(TOASTER,OUTPUT); pinMode(COFFEEMAKER,OUTPUT); fanStatus=false; lampStatus=false; toasterStatus=false; coffeemakerStatus=false; digitalWrite(FAN,LOW); digitalWrite(LAMP,LOW); digitalWrite(TOASTER,LOW); digitalWrite(COFFEEMAKER,LOW); Inthesetup()function,thecodealsosubscribestotheappropriateMQTTchannelsso thatitcanreceivemessagesfromtheMosquittobrokerassoonastheyareavailable.As youcansee,wearealsosubscribingtothePowerStrip/statuscheckchanneltodealwith thestatusreport: if(client.connect("PowerStrip")){ client.subscribe("PowerStrip/fan"); client.subscribe("PowerStrip/lamp"); client.subscribe("PowerStrip/toaster"); client.subscribe("PowerStrip/coffeemaker"); client.subscribe("PowerStrip/statuscheck"); } Inthecallback()function,weusetheifstatementtomatchthetopicwiththe appropriatedigitalWrite()action.Asyoucansee,wearesettingupHIGHandLOW statusesforthedigitalpinwhentheprogramreceivesonandoffmessages,respectively (forthatappliance).Withthisaction,wearealsochangingthestateoftheBoolean variableassociatedwiththeappliance,whichwillbehelpfulinretrievingthestatusofthe port.Thesameprocessisthenrepeatedforallappliances: if(topicS=="PowerStrip/fan"){ if(payloadS.equalsIgnoreCase("on")){ digitalWrite(FAN,HIGH); fanStatus=true; } if(payloadS.equalsIgnoreCase("off")){ digitalWrite(FAN,LOW); fanStatus=false; } } Whenthesystemreceivesagetmessagethatisassociatedwiththestatuscheck,the programcreatesamessageusingtheBooleanvariablesthatwetoggledearlier.The programthenpublishesthestatustothePowerStrip/statusreportchannel: if(topicS.equals("PowerStrip/statuscheck")){ if(payloadS.equalsIgnoreCase("get")){ Stringreport=""; if(fanStatus)report+="Fan:on,"; elsereport+="Fan:off,"; if(lampStatus)report+="Lamp:on,"; elsereport+="Lamp:off,"; if(toasterStatus)report+="Toaster:on,"; elsereport+="Toaster:off,"; if(coffeemakerStatus)report+="Coffeemaker:on"; elsereport+="Coffeemaker:off"; report.toCharArray(reportChar,100); client.publish("PowerStrip/statusreport",reportChar); } } Justaswedidinthepreviousproject,youcansetupthecodetoperiodicallysendkeep alivemessagestoavoidtheterminationoftheconnectionwiththeMosquittobroker. Onceyouarereadywiththecode,connecttheEthernetcable,compilethecode,andthen uploadittoyourArduino.YourArduinoshouldbeinreceivingmodenow,anditwillwait forthemessagefromthesubscribedchannels.Aswediscussedintheprevioustheproject, youneedtoensurethatyourMosquittobrokerisrunningontheserverIPaddressyou specifiedintheArduinocode. Stage2–thePythoncodetoprocess tweets AstheuserisinteractingwiththesystemattheleveloftheTwitterapplication,wedonot requireadeployablecomputationorcontrolunitforthisproject.Duetothis,wecanjust useanycomputercapableofhostingPythonandMosquittoasthecomputationunit.You stillneedtoensurethattheunitisalwaysonandconnectedtotheInternet,otherwisethe systemwillnotworkasexpected.Forsimplicity,youcandeploythesystemonthe Raspberry-Pi-basedcontrolcenterthatyoudevelopedinthepreviousproject,orevenon theAmazonAWSserver.Forthedevelopmentstage,let’sstartwiththeregularcomputer thatyouhavebeenusingallalong.WeareassumingthatthiscomputerhastheMosquitto brokerinstalledandrunning.NotedowntheIPaddressofthisunit,asyouwillneeditin theArduinocodethatyoudevelopedintheprevioussection. Pythonsoftwareflow ThePythoncodedealswithtwoservicesduringexecution,theTwitterAPItogetorpost tweetsandtheMosquittobrokertorelaymessagestothehardwareunit.Theprogram beginsbyparsingthelatesttweetfromtheuseraccountandcheckingwhetherithasbeen utilizedinthepreviousactionornot.Thisavoidsanycommandduplication,asthe frequencyofnewtweetsissignificantlylowerthanthefrequencyoftheprogramloop. Oncethecodefindsanewtweetwiththeappropriatekeywordstoperformoperationson theappliance(orappliances),itpublishesthemessagetotheMosquittobroker.Ifthe tweetcontainsamessagetocheckthestatus,thecoderequeststhestatusfromyour Arduinoandpostsanewtweetwiththestatusafterreceivingit. Thefollowingdiagramshowsthedetailedprogramflowofthecomputationunit: Youcanchangetheprogramflowtoaccommodateanyotherfeatureyouwanttoaddat thePythonlevel.Thelogicbehindidentifyingandtogglingtheappliancecanbe improvisedtoaccommodatemorecomplextweettext. SettinguptheTwitterapplication WeareassumingthatyouhaveaTwitteraccountbynow.Ifyoudon’t,youcancreatea newaccountjustforthisprojecttoavoidchangestoyourownprofile.Withthe introductionofthelatestAPIs,TwitterrequiresyoutoauthenticateusingOAuthbefore accessinganyinformationfromyouraccount.Todothat,youwillhavetocreateaTwitter appusingyouraccount.ExecutethefollowingstepsinordertocreateanewTwitterapp forthisproject: 1. LogintoyourTwitteraccountandopenthehttps://apps.twitter.comaddressinyour webbrowser. 2. ClickontheCreateNewAppicononthepage,andyouwillbedirectedtoapage askingforyourapplicationdetails,asdisplayedinthefollowingscreenshot: 3. Fillinalltherequireddetails(markedwithredasterisks)andcontinuetothenext page.Ensurethatyourapplicationnameisunique,asTwitterasksforaunique applicationname. 4. Onceyourapplicationiscreated,youcanclickontheAPIKeystabandfindthe consumerkey(APIkey)andconsumersecret(APIsecret)foryourapp.Savethis informationinasafeplace,asyouwillneedthemtoauthenticatewiththeTwitter API. 5. AstheUXoftheTweet-a-PowerStripprojectrequiresthesystemtoautomatically sendthesystemstatus,weneedread-and-writeaccesstoourapplication.Gotothe Permissionstab,selecttheReadandWriteoption,andsaveitforthechangesto takeeffect. 6. Onceyouaredonewithsettingupthepermissionsfortheapplication,gobacktothe APIkeystabandclickontheCreateAccessTokenicontogenerateanewaccess tokenforthisapplication.Afterawhile,youshouldbeabletoseetheaccesstoken onthesamepage,asdisplayedinthisscreenshot: 7. SavetheAccesstokenandAccesstokensecretinformation.Yourapplicationisnow readyforuseandcanhelpyoutoauthenticatewiththeTwitterAPI. Nowlet’smoveontothePythoncode. ThePythoncode Beforeyoujumpintothecode,youarerequiredtoinstalltheTwitterlibraryforPython. UsetheSetuptoolsorpiptoinstallthelibraryusingthefollowingcommand.Weare assumingthatyoualreadyhavethelatestpaho_mqttlibraryinstalledonyourcomputer: $sudopipinstallpython-twitter ThePythoncodeforthissectionislocatedinthecodefolderwiththe PythonTweetAPowerStrip.pyfilename.OpenthecodeinyourIDEandstartexploringit. ThecodecontainstwoparallelthreadstohandlethetweetsandtheMosquittolibrary separately. Asyoucanseeinthefollowingcodesnippet,weareusingtheApiclassfromthepythontwitterlibrarytoestablishaconnectionwiththeTwitterAPI.Weareusingtheconsumer key,consumersecret,accesstokenkey,andaccesstokensecretvaluesforthis authentication.Oncetheauthenticationisestablished,theApiclasscanbeusedtogetthe lateststatusfromthetimelineusingtheGetHomeTimeline()functioncall,andtopostthe newstatususingthePostUpdate()functioncall.TheGetHomeTimeline()functiongives anarrayofstatusesfromtheuser;weneedthelateststatus,whichcanbefetchedusing statuses[0](thefirstelementofthearray): api=twitter.Api(consumer_key='<consumer-key>', consumer_secret='<consumer-secret>', access_token_key='<access-token-key>', access_token_secret='access-token-secret>') Oncewehaveretrievedthelatesttweet,weneedtomakesurethatwehaven’tusedthat tweetalready.SowesavethelatesttweetIDinaglobalvariable,aswellasinafilein caseweneedtorunthecodeagain: withopen('lastTweetID.txt','w+')asfh: lastTweetId=fh.readline() print"InitializingwithID:"+lastTweetId WeretrievetheIDoftheprevioustweetfromthelastTweetID.txtfiletomatchwiththe latestID.Ifitdoesn’tmatch,weupdatethelastTweetID.txtfilewiththelatestIDfor thenextloop: iflastTweetId!=str(currentStatus.id): lastTweetId=str(currentStatus.id) print"UpdatedfilewithID:"+lastTweetId withopen('lastTweetID.txt','w+')asfh: fh.write(lastTweetId) currentStatusText=currentStatus.text printcurrentStatusText Oncewehaveidentifiedthelatestuniquetweet,weusethePythonstringoperationto decodethekeywordsfortheapplianceandpowercommands.Asyoucanseeinthe followingcodesnippet,thekeywordwearelookingforinthetweetedtexttoaccessthe fanis#fan.Oncewehaveidentifiedthatthemessageisdirectedtothefan,wecheckfor actionkeywordssuchas#onand#off,andthentaketheassociatedactionofpublishing themessagetotheMosquittobroker.Werepeatthisactionforalltheappliancesconnected tothesystem.YourArduinotakesanactionusingthepublishedmessage,andcompletes theUXflowforthecontrolledappliances: if"#fan"incurrentStatusText.lower(): if"#on"incurrentStatusText.lower(): cli.publish("PowerStrip/fan","on") if"#off"incurrentStatusText.lower(): cli.publish("PowerStrip/fan","off") Similarly,whenthecodereceivesanupdatefromthePowerStrip/statusreporttopic,it obtainsthestatusfromthemessagepayloadandpostsitasanewtweettotheuser timelineofthatTwitteraccount.ThiscompletestheUXflowforthestatuscheckusing Twitter: defonMessage(mosq,obj,msg): ifmsg.topic=="PowerStrip/statusreport": printmsg.payload api.PostUpdate(msg.payload) Testingandtroubleshooting Testingcansimplybeperformedbypostingthe#fan#onstatustotheTwitteraccount usedinthisproject.Youshouldbeabletoseethefanturningonbyusingthecommand shownhere: Similarly,sendthe#fan#offstatustoturnoffthefan.Youmayfindsomelagging,asthe loopusedtoretrievethetweetsissetwithadelayofaminute. Toaccessthestatusofthesystem,postthe#status#getstatustotheaccount,andyou willbeabletoseethesystemstatusautomaticallypostedbythecomputationunit. ThetweetshowninthefollowingscreenshotisgeneratedusingtheTweet-a-PowerStrip unit.Itdisplaysthestatusofalltheconnectedappliances. Whileworkingwiththesystem,youwillwanttoeitheravoidthefollowingscenariosor troubleshootthem: 'Twitterratelimitexceed'error:Twitterimposesalimitonthenumberof requestsyoucanmaketotheirpublicAPI.IfyouarerequestingtheAPItoooften (thisoftenoccurswhenyoureducethesleeptimebetweenconsecutivequeries),your applicationwillexitwithanexception.Toavoidthis,setalongersleeptimeinthe PythonprogramloopbeforerequestingtheAPIagain.Thereisatrade-offbetween thefrequencyofrequestsandtheresponsetimeofyourappliances.Youcanlearn aboutthislimitationathttp://dev.twitter.com/rest/public/rate-limitingandadjustyour requestintervalaccordingly.Onceyouhavereceivedthiserror,youwillhavetowait forsometime(approximately10to15minutes)beforemakingrequeststothe TwitterAPIagain. 'Read-onlyapplicationcannotpost'error:Thiserrorwillonlyoccurifyou forgottochangethepermissionsonyourapplicationtoReadandWritefromRead only.Makesurethatyouhaveperformedthischange.Also,Twittertakessometime forthechangestotakeeffect. Extendingtheprojectwithadditional features Thecurrentsystemcanbeexpandedtoincludemultiplefeatures: Youcanstartsavingthetimedurationinwhichaparticularappliancewasonoroff, andthenprovideadetailedanalysistotheuser.Youcanalsousethisinformationto calculatetheenergybeingexpendedbytheseappliances. Youcanutilizethecurrentmeasurementsensorstocalculatethepowerloadateach port.Combiningitwiththetimethedevicewason,youcancalculatevery comprehensivepowerusagetofurtherimprovepowermanagement. Youcanusethesystemclockwiththemotionsensortointelligentlyturnoffthe applianceduringnightsandperiodsofnoactivity. TheTweet-a-PowerStripprojectcanbeinterfacedwiththeremotehomemonitoring systemthatwedevelopedinthepreviousproject,inordertoobtainuseful informationfromothersensorsbeingusedinthesamehouse. OneofthemodificationsyoucaneasilyimplementistoutilizeTwitter’sprivate messagesinsteadofitstweetstocontroltheappliances.Thiswillextendtheaccess permissionsofyoursystemtoothertrustedTwitteraccounts.Forsecurityreasons, youshouldtightentheaccesslevelandonlyletapprovedpeoplepostsuchmessages toyouraccount. Summary YouhavenowsuccessfullycompletedtwodifferentIoTprojectsusingjusttwobase technologies,ArduinoandPython.Withthecurrentproject,itisobviousthatitisvery easytointerfaceanyothertechnology,tool,orAPIwithArduinoandPython.Theproject developmentmethodologyweusedinthesetwoprojectswillalsohelpyouwithyourDIY projectsandotherfutureproducts.Happyprototyping!Andhappycoding! Index A AmazonAWSplatform about/GettingfamiliarwiththeAmazonAWSplatform URL/GettingfamiliarwiththeAmazonAWSplatform account,settingup/SettingupanaccountonAWS analogdigitalbuzzer URL/Buzzer–generatingsoundalarmpattern architecture,IoTwebapplications about/ArchitectureofIoTwebapplications physicallayer/ArchitectureofIoTwebapplications computationlayer/ArchitectureofIoTwebapplications interfacinglayer/ArchitectureofIoTwebapplications Arduino about/IntroductiontoArduino history/History objectives/WhyArduino? variants/Arduinovariants Unoboard/TheArduinoUnoboard URL,forinstallationonLinux/Linux interfacing,withPython/Prototyping computernetworking/Arduinoandthecomputernetworking Arduino,interfacingwithXively about/InterfacingArduinowithXively Arduinodata,uploading/UploadingArduinodatatoXively data,downloadingtoArduino/DownloadingdatatoArduinofromXively advancedcode,fordatauploadanddownload/Advancedcodetouploadand downloaddatausingArduino Arduinoboard StandardFirmatasketch,uploading/UploadingaFirmatasketchtotheArduino board settingup,pyFirmatamethodsused/SettinguptheArduinoboard Arduinoboardconnection establishing/ConnectingtheArduinoboard establishing,onLinux/Linux establishing,onMacOSX/MacOSX establishing,onWindows/Windows troubleshooting/Troubleshooting Arduinocode,Tweet-a-PowerStrip/TheArduinocode Arduinodata storing,inCSVfile/StoringArduinodatainaCSVfile plotting,fromCSVfile/PlottingdatafromaCSVfile ArduinoEthernetlibrary about/ArduinoEthernetlibrary URL/ArduinoEthernetlibrary Ethernetclass/TheEthernetclass IPAddressclass/TheIPAddressclass Serverclass/TheServerclass Clientclass/TheClientclass ArduinoEthernetShield about/ArduinoEthernetShield URL/ArduinoEthernetShield ArduinoIDE about/Arduinovariants,GettingstartedwiththeArduinoIDE installing/InstallingtheArduinoIDE installing,onLinux/Linux URL,forinstallationonUbuntu/Linux URL,forinstallationonFedora/Linux installing,onMacOSX/MacOSX installing,onWindows/Windows URL,forsetupfile/Windows sketch/WhatisanArduinosketch? libraries/Workingwithlibraries examples,using/UsingArduinoexamples URL,forbuilt-inexamples/UsingArduinoexamples sketch,compiling/Compilinganduploadingsketches sketch,uploading/Compilinganduploadingsketches serialmonitor,using/UsingtheSerialMonitorwindow Arduinointerrupts about/UsingArduinointerrupts using/UsingArduinointerrupts referencelink/UsingArduinointerrupts Arduinopins configuring/ConfiguringArduinopins configuring,withdirectmethod/Thedirectmethod pinmodes,assigning/Assigningpinmodes workingwith/Workingwithpins data,reporting/Reportingdata monitoring/Manualoperations write()method,using/Thewrite()method read()method,using/Theread()method Arduinoprogramming about/IntroductiontoArduinoprogramming comments/Comments variables/Variables constants/Constants datatypes/Datatypes conversionfunctions/Conversions statements/Functionsandstatements functions/Functionsandstatements Arduinosketch,monitoringstation about/TheArduinosketchforthemonitoringstation sensorinformation,publishing/Publishingsensorinformation actuatoractions,subscribingto/Subscribingtoactuatoractions interrupt,programming/Programminganinterrupttohandlethepressofa button ArduinoWiFiShield about/ArduinoWiFiShield URL/ArduinoWiFiShield ArduinoYún about/ArduinoYún URL/ArduinoYún arraydatatype about/Datatypes B BH1750lightsensor interfacing,Arduinoused/ArduinocodingfortheBH1750lightsensor interfacing,PyMatalibraryused/InterfacingBH1750usingPyMata booleandatatype about/Datatypes breadboard using/Workingwiththebreadboard URL/Workingwiththebreadboard history/Workingwiththebreadboard referencelink/Workingwiththebreadboard broker about/MQTT–Alightweightmessagingprotocol built-infunctions about/Built-infunctions conversionmethods/Conversions mathoperations/Mathoperations stringoperations/Stringoperations URL/Stringoperations built-intypes about/Pythonoperatorsandbuilt-intypes,Built-intypes datastructures/Datastructures Button()widget about/LearningTkinterforGUIdesign,TheButton()widget–interfacingGUI withArduinoandLEDs using/TheButton()widget–interfacingGUIwithArduinoandLEDs buzzer using/Buzzer–generatingsoundalarmpattern connections/Connections Pythoncode/ThePythoncode bytedatatype about/Datatypes C callback about/TheLabel()widget–monitoringI/Opins Carriots about/Carriots chardatatype about/Datatypes Checkbox()widget about/LearningTkinterforGUIdesign Checkbutton()widget about/TheCheckbutton()widget–selectingLEDs used,forselectingLEDs/TheCheckbutton()widget–selectingLEDs Clientclass about/TheClientclass close()method used,forclosingfile/Theclose()method comments about/Comments blockcomment/Comments single-lineorinlinecomment/Comments computernetworking about/Arduinoandthecomputernetworking IPaddress,obtaining/ObtainingtheIPaddressofyourcomputer networkingextensions,forArduino/NetworkingextensionsforArduino ArduinoEthernetlibrary/ArduinoEthernetlibrary webserver,buildingwithArduino/Exercise1–awebserver,yourfirst Arduinonetworkprogram constants about/Constants controlcenter,remotehomemonitoringsystem about/Stage2–acontrolcenterusingPythonandtheRaspberryPi architecture/Thecontrolcenterarchitecture Pythoncode/ThePythoncodeforthecontrolcenter GUI,creatingwithTkinter/CreatingtheGUIusingTkinter Mosquittobroker,communicatingwith/CommunicatingwiththeMosquitto broker systemstatus,calculating/Calculatingthesystem’sstatusandsituation awareness Xively,communicatingwith/CommunicatingwithXively buzzerstatus,checking/Checkingandupdatingthebuzzer’sstatus buzzerstatus,updating/Checkingandupdatingthebuzzer’sstatus testing,withmonitoringstation/Testingthecontrolcenterwiththemonitoring station settingup,onRaspberryPi/SettingupthecontrolcenterontheRaspberryPi conversionfunctions char()/Conversions byte()/Conversions int()/Conversions float()/Conversions about/Conversions CSVfile about/UsingCSVfilestostoredata used,forstoringdata/UsingCSVfilestostoredata Arduinodata,storing/StoringArduinodatainaCSVfile data,plotting/PlottingdatafromaCSVfile customcloudplatform,IoT configuring/YourowncloudplatformfortheIoT AmazonAWSplatform/GettingfamiliarwiththeAmazonAWSplatform cyber-physicalsystems/ArchitectureofIoTwebapplications D datastructures about/Datastructures list/Lists tuples/Tuples sets/Sets dictionaries/Dictionaries URL/Dictionaries datatypes about/Datatypes void/Datatypes boolean/Datatypes byte/Datatypes int/Datatypes float/Datatypes char/Datatypes array/Datatypes DCmotors using/DCmotor–controllingmotorspeedusingPWM connections/Connections Pythoncode/ThePythoncode deploymentstage,Tweet-a-PowerStrip about/Developmentanddeploymentstages designmethology,IoTprojects about/ThedesignmethodologyforIoTprojects developmentstage,Tweet-a-PowerStrip about/Developmentanddeploymentstages developmentstages,remotehomemonitoringsystem defining/Definingtheprojectdevelopmentstages do-it-yourself(DIY)projects about/IntroductiontoArduino Dualin-linePackage(DIP) about/Workingwiththebreadboard DynamicHostControlProtocol(DHCP) about/TheEthernetclass E EC2service about/GettingfamiliarwiththeAmazonAWSplatform electroniccomponents interfacing,withArduino/Prototyping EndofLine(EOL) about/PlayingwithapySerialexample Entry()widget about/LearningTkinterforGUIdesign,TheEntry()widget–providingmanual userinputs used,forprovidingmanualuserinputs/TheEntry()widget–providingmanual userinputs Ethernetclass about/TheEthernetclass ez_setup.pyfile URL,fordownloading/Windows,MacOSX F Fedora/RedHatLinux Python,installing/FedoraandRedHat files workingwith/WorkingwithfilesinPython manipulating,withopen()method/Theopen()method write()method,using/Thewrite()method closing,close()methodused/Theclose()method read()method,using/Theread()method withstatement,using/Thewithstatement–Pythoncontextmanager Firmata about/IntroducingtheFirmataprotocol URL/WhatisFirmata?,TestingtheFirmataprotocol StandardFirmatasketch,uploadingtoArduinoboard/UploadingaFirmata sketchtotheArduinoboard testing/TestingtheFirmataprotocol andpySeriallibrary,bridging/BridgingpySerialandFirmata Firmatalibraries disadvantages/UsefulpySerialcommands floatdatatype about/Datatypes formattingtool,SDcard URL,fordownloading/PreparinganSDcard forstatement about/Theforstatement Fritzing about/TestingtheFirmataprotocol using/IntroducingFritzing–ahardwareprototypingsoftware URL/IntroducingFritzing–ahardwareprototypingsoftware functions about/Functionsandstatements setup()function/Thesetup()function loop()function/Theloop()function pinMode()function/ThepinMode()function functions,pins digitalWrite()function/Workingwithpins digitalRead()function/Workingwithpins analogRead()function/Workingwithpins analogWrite()function/Workingwithpins G general-purposeinput/output(GPIO)pins about/Hardwaredesign graphicaluserinterfaces(GUIs) about/WhyweusePython Grid about/ThePackgeometrymanager Gridgeometrymanager about/TheGridgeometrymanager GUI,thermostat designing/DesigningtheGUIandplotinPython pySerial,usedforstreamingsensordata/UsingpySerialtostreamsensordata inyourPythonprogram designing,Tkinterused/DesigningtheGUIusingTkinter percentagehumidity,plottingwithmatplotlib/Plottingpercentagehumidity usingmatplotlib buttoninterrupts,using/Usingbuttoninterruptstocontroltheparameters buttoninterrupts,usedforchangingtemperatureunit/Changingthetemperature unitbypressingabutton buttoninterrupts,usedforswappingbetweenGUIandplot/Swappingbetween theGUIandtheplotbypressingabutton H hardwarecomponents,RaspberryPi RaspberryPi/WhatdoyouneedtobeginusingtheRaspberryPi? powercable/WhatdoyouneedtobeginusingtheRaspberryPi? displaycable/WhatdoyouneedtobeginusingtheRaspberryPi? SDcard/WhatdoyouneedtobeginusingtheRaspberryPi? mouse/WhatdoyouneedtobeginusingtheRaspberryPi? keyboard/WhatdoyouneedtobeginusingtheRaspberryPi? USBhub(optional)/WhatdoyouneedtobeginusingtheRaspberryPi? hardwarecomponents,remotehomemonitoringsystem about/Thelistofrequiredcomponents hardwarecomponents,Tweet-a-PowerStrip about/Requiredhardwarecomponents relays/Relays PowerSwitchTail/PowerSwitchTail hardwaredesign,IoT about/Hardwaredesign,TheIoTcloudplatforms hardwaredesign,Tweet-a-PowerStrip about/Hardwaredesign hardwaresystemdesign,motion-triggeredLEDs Fritzing,using/IntroducingFritzing–ahardwareprototypingsoftware breadboard,using/Workingwiththebreadboard hardwareprototype,designing/Designingthehardwareprototype help()function about/Plottingrandomnumbersusingmatplotlib HIH-4030humiditysensor using/Thelistofrequiredcomponents homeareanetwork(HAN) about/Networkingfundamentals Homebrew URL,/MacOSX installing/MacOSX I I2Cprotocol referencelink/PrototypingwiththeI2Cprotocol ifstatement about/Theifstatement input/output(I/O)pins about/Arduinovariants installation,ArduinoIDE onLinux/Linux onMacOSX/MacOSX onWindows/Windows installation,paho-mqttlibrary/Installingpaho-mqtt installation,pip about/Installingpip installation,PubSubClientlibrary/InstallingthePubSubClientlibrary installation,pySeriallibrary about/InstallingpySerial installation,Python about/InstallingPythonandSetuptools onLinux/Linux onUbuntu/Ubuntu onFedora/RedHatLinux/FedoraandRedHat onWindows/Windows onMacOSX/MacOSX installation,Pythonpackages about/InstallingPythonpackages installation,Setuptools about/InstallingSetuptools onLinux/Linux onWindows/Windows onMacOSX/MacOSX installation,web.py about/Installingweb.py intdatatype about/Datatypes integratedcircuit(IC) about/PrototypingwiththeI2Cprotocol integrateddevelopmentenvironment(IDE) about/InstallingtheArduinoIDE integrateddevelopmentenvironment(IDLE) about/ThefundamentalsofPythonprogramming InternetofThings(IoT)applications about/WhyweusePython InternetProtocol(IP) about/Networkingfundamentals IoT gettingstartedprocess/GettingstartedwiththeIoT hardwaredesign/Hardwaredesign,TheIoTcloudplatforms cloudapplications,developingwithPythonandXively/Developingcloud applicationsusingPythonandXively customcloudplatform/YourowncloudplatformfortheIoT IoTcloudplatform,onEC2instance creating/CreatinganIoTplatformontheEC2instance necessarypackages,installingonAWS/Installingthenecessarypackageson AWS virtualinstancesecurity,configuring/Configuringthesecurityofthevirtual instance testing/Testingyourcloudplatform Mosquittoservice,testing/TestingtheMosquittoservice basicsecurity,configuring/Configuringandtestingbasicsecurity basicsecurity,testing/Configuringandtestingbasicsecurity project,uploadingoninstance/Uploadingandtestingaprojectontheinstance project,testingoninstance/Uploadingandtestingaprojectontheinstance IoTcloudplatforms Xively/TheIoTcloudplatforms,Xively–acloudplatformfortheIoT 2lemetry/TheIoTcloudplatforms Carriots/TheIoTcloudplatforms,Carriots ThingSpeak/TheIoTcloudplatforms,ThingSpeak IoTprojects designmethodology/ThedesignmethodologyforIoTprojects IoTwebapplications architecture/ArchitectureofIoTwebapplications IPaddress about/Networkingfundamentals obtaining/ObtainingtheIPaddressofyourcomputer obtaining,forWindows/Windows obtaining,forMacOSX/MacOSX obtaining,forLinux/Linux IPAddressclass about/TheIPAddressclass L Label()widget about/LearningTkinterforGUIdesign,TheLabel()widget,TheLabel() widget–monitoringI/Opins used,formonitoringI/Opins/TheLabel()widget–monitoringI/Opins leastsignificantbit(LSB) about/ArduinocodingfortheTMP102temperaturesensor LED brightness,controllingwithPWM/LED–controllingLEDbrightnessusing PWM connections/Connections Pythoncode/ThePythoncode libraries,ArduinoIDE about/Workingwithlibraries URL/Workingwithlibraries Linefeed+CarriageReturn(LF+CR) about/PlayingwithapySerialexample Linux Python,installing/Linux Setuptools,installing/Linux ArduinoIDE,installing/Linux Arduinoboardconnection,establishing/Linux IPaddress,obtaining/Linux Listbox()widget about/TheCheckbutton()widget–selectingLEDs URL/TheCheckbutton()widget–selectingLEDs localareanetwork(LAN) about/Networkingfundamentals localhostIPaddress about/Networkingfundamentals loop()function about/Theloop()function using/Theloop()function M MacOSX Python,installing/MacOSX Setuptools,installing/MacOSX ArduinoIDE,installing/MacOSX Arduinoboardconnection,establishing/MacOSX matplotlib,configuring/ConfiguringmatplotlibonMacOSX SDcard,preparing/PreparinganSDcard IPaddress,obtaining/MacOSX matplotlib about/Gettingstartedwithmatplotlib URL/Gettingstartedwithmatplotlib,ConfiguringmatplotlibonWindows configuring,onWindows/ConfiguringmatplotlibonWindows configuring,onMacOSX/ConfiguringmatplotlibonMacOSX upgrading/Upgradingmatplotlib installationerrors,troubleshooting/Troubleshootinginstallationerrors referencelink/Troubleshootinginstallationerrors settingup,onUbuntu/SettingupmatplotlibonUbuntu used,forplottingrandomnumbers/Plottingrandomnumbersusingmatplotlib mediaaccesscontrol(MAC)address about/Networkingfundamentals monitoringstation,remotehomemonitoringsystem defining/Stage1–amonitoringstationusingArduino,Designingthe monitoringstation Arduinosketch/TheArduinosketchforthemonitoringstation Mosquitto about/Mosquitto–anopensourceMQTTbroker URL/Mosquitto–anopensourceMQTTbroker settingup/SettingupMosquitto initialization/GettingfamiliarwithMosquitto mostsignificantbit(MSB) about/ArduinocodingfortheTMP102temperaturesensor motion-triggeredLEDs developing/Motion-triggeredLEDs–theprojectdescription projectgoals/Theprojectgoal examples/Theprojectgoal onlineresources/Theprojectgoal softwareflowdesign/Thesoftwareflowdesign hardwaresystemdesign/Thehardwaresystemdesign hardwareconnections,testing/Testinghardwareconnections motion-triggeredLEDs,components PIRsensors/Thelistofcomponents LEDs/Thelistofcomponents wires/Thelistofcomponents resistors/Thelistofcomponents breadboard/Thelistofcomponents Arduinoboard/Thelistofcomponents USBcable/Thelistofcomponents computer/Thelistofcomponents motion-triggeredLEDs,usingArduinosketch developing/Method1–usingastandaloneArduinosketch projectsetup/Theprojectsetup coding/TheArduinosketch setup()function,using/Thesetup()function loop()function,using/Theloop()function customArduinofunctions,using/WorkingwithcustomArduinofunctions testing/Testing troubleshooting/Troubleshooting motion-triggeredLEDs,usingPythonandFirmata developing/Method2–usingPythonandFirmata projectsetup/Theprojectsetup Pythonexecutablefiles,using/WorkingwithPythonexecutablefiles coding/ThePythoncode pyFirmatamethods,using/WorkingwithpyFirmatamethods Pythonfunctions,using/WorkingwithPythonfunctions testing/Testing troubleshooting/Troubleshooting MQTT about/MQTT–Alightweightmessagingprotocol URL/IntroductiontoMQTT Mosquitto/Mosquitto–anopensourceMQTTbroker MQTT,onArduino PubSubClientlibrary,using/MQTTonArduinousingthePubSubClientlibrary ArduinoMQTTclient,developing/DevelopingtheArduinoMQTTclient MQTT,onPython paho-mqttlibrary,using/MQTTonPythonusingpaho-mqtt,UsingthepahomqttPythonlibrary MQTTGateway developing,forArduino/Exercise4–MQTTGatewayforArduino Arduinodeveloping,asMQTTclient/DevelopingArduinoastheMQTTclient developing,Mosquittoused/DevelopingtheMQTTGatewayusingMosquitto extending,web.pyused/ExtendingtheMQTTGatewayusingweb.py testing/TestingyourMosquittoGateway N NestThermostat URL/Thermostat–theprojectdescription networking fundamentals/Networkingfundamentals localareanetwork(LAN)/Networkingfundamentals homeareanetwork(HAN)/Networkingfundamentals wideareanetwork(WAN)/Networkingfundamentals protocols/Networkingfundamentals mediaaccesscontrol(MAC)address/Networkingfundamentals InternetProtocol(IP)/Networkingfundamentals IPaddress/Networkingfundamentals localhostIPaddress/Networkingfundamentals networkingextensions,forArduino about/NetworkingextensionsforArduino ArduinoEthernetShield/ArduinoEthernetShield ArduinoWiFiShield/ArduinoWiFiShield ArduinoYún/ArduinoYún newlinecharacter about/PlayingwithapySerialexample URL/PlayingwithapySerialexample NewOutOfBoxSoftware(NOOBS) about/PreparinganSDcard NumPypackage URL/ConfiguringmatplotlibonWindows O open()method used,formanipulatingfiles/Theopen()method modes/Theopen()method operators about/Pythonoperatorsandbuilt-intypes,Operators P Packgeometrymanager about/ThePackgeometrymanager paho-mqttlibrary about/MQTTonPythonusingpaho-mqtt installing/Installingpaho-mqtt using/Usingthepaho-mqttPythonlibrary passiveinfrared(PIR)sensor about/Theprojectgoal using/Thelistofcomponents URL/Thelistofcomponents PEP-8 URL/Operators physicalsystems/GettingstartedwiththeIoT pinMode()function about/ThepinMode()function pip installing/Installingpip plot()function about/Plottingrandomnumbersusingmatplotlib portableTFTLCDdisplay using/UsingaportableTFTLCDdisplaywiththeRaspberryPi connecting,GPIOused/ConnectingtheTFTLCDusingGPIO configuring,withRaspberryPiOS/ConfiguringtheTFTLCDwiththe RaspberryPiOS GUI,optimizing/OptimizingtheGUIfortheTFTLCDscreen potentiometer connections/Connections Pythoncode/ThePythoncode PowerSwitchTail URL/PowerSwitchTail Processing about/IntroductiontoArduinoprogramming protocols about/Networkingfundamentals prototyping about/Prototyping prototyping,thermostat about/Stage1–prototypingthethermostat Arduinosketch/TheArduinosketchforthethermostat temperaturesensor,interfacing/Interfacingthetemperaturesensor humiditysensor,interfacing/Interfacingthehumiditysensor lightsensor,interfacing/Interfacingthelightsensor troubleshooting/Troubleshooting prototyping,withI2Cprotocol about/PrototypingwiththeI2Cprotocol Arduinoexamples/ArduinoexamplesforI2Cinterfacing TMP102temperaturesensor,usingArduino/ArduinocodingfortheTMP102 temperaturesensor BH1750lightsensor,usingArduino/ArduinocodingfortheBH1750light sensor PyMatalibrary,using/PyMataforquickI2Cprototyping TMP102temperaturesensor,usingPyMatalibrary/InterfacingTMP102using PyMata BH1750lightsensor,usingPyMatalibrary/InterfacingBH1750usingPyMata pySerialcommands,using/UsefulpySerialcommands prototypingtemplates,usingFirmata about/PrototypingtemplatesusingFirmata potentiometer/Potentiometer–continuousobservationfromananaloginput buzzer,using/Buzzer–generatingsoundalarmpattern DCmotor,using/DCmotor–controllingmotorspeedusingPWM LED/LED–controllingLEDbrightnessusingPWM servomotors,using/Servomotor–movingthemotortoacertainangle PubSubClientlibrary using/MQTTonArduinousingthePubSubClientlibrary installing/InstallingthePubSubClientlibrary URL/InstallingthePubSubClientlibrary pulse-widthmodulation(PWM) about/TheArduinoUnoboard pushbuttonswitch using/Thelistofrequiredcomponents pyFirmatamethods workingwith/WorkingwithpyFirmatamethods used,forsettingupArduinoboard/SettinguptheArduinoboard used,forconfiguringArduinopins/ConfiguringArduinopins used,forworkingwithArduinopins/Workingwithpins servo_config(pin,min_pulse=544,max_pulse=2400,angle=0)/Additional functions pass_time(seconds)/Additionalfunctions get_firmata_version()/Additionalfunctions exit()/Additionalfunctions pulseIn/pulseOut/Upcomingfunctions shiftIn/shiftOut/Upcomingfunctions PyPI URL/WhyweusePython,InstallingPythonpackages about/WhyweusePython pyplotframework about/Plottingrandomnumbersusingmatplotlib figure()function/Plottingrandomnumbersusingmatplotlib show()method/Plottingrandomnumbersusingmatplotlib pySerialcommands using/UsefulpySerialcommands used,forconnectingwithserialport/Connectingwiththeserialport used,forreadingalinefromport/Readingalinefromtheport used,forflushingporttoavoidbufferoverflow/Flushingtheporttoavoid bufferoverflow used,forclosingport/Closingtheport pySeriallibrary about/GettingstartedwithpySerial installing/InstallingpySerial URL/InstallingpySerial example/PlayingwithapySerialexample andFirmata,bridging/BridgingpySerialandFirmata Python about/IntroductiontoPython benefits/WhyweusePython usageconsiderations/Whendoweuseotherlanguages URL/Whendoweuseotherlanguages installing/InstallingPythonandSetuptools installing,onLinux/Linux installing,onUbuntu/Ubuntu installing,onFedora/RedHatLinux/FedoraandRedHat installing,onWindows/Windows URL,fordownloading/Windows,MacOSX installing,onMacOSX/MacOSX pip,installing/Installingpip URL,fordocumentation/Controllingtheflowofyourprogram Pythoncode,Tweet-a-PowerStrip about/ThePythoncode Pythoncontextmanager referencelink/Thewithstatement–Pythoncontextmanager Pythondata,downloadingtoXively about/Python–downloadingdatafromXively basicmethod,forretrievingdata/Thebasicmethodforretrievingdatafrom Xively dataretrieving,fromweb.pywebinterface/Retrievingdatafromtheweb.py webinterface customnotifications,fromXively/Triggers–customnotificationsfromXively triggers/Triggers–customnotificationsfromXively Pythondata,uploadingtoXively about/Python–uploadingdatatoXively basicmethod,forsendingdata/Thebasicmethodforsendingdata webinterfaceused/Uploadingdatausingawebinterfacebasedonweb.py Pythonexecutablefiles using/WorkingwithPythonexecutablefiles Pythonfunctions using/WorkingwithPythonfunctions defkeyword/WorkingwithPythonfunctions PythonGUI Tkinter/LearningTkinterforGUIdesign firstprogram/YourfirstPythonGUIprogram Python-Arduinoproject,remaking/RemakingyourfirstPython-Arduino projectwithaGUI Pythonpackages installing/InstallingPythonpackages installing,$pipinstall*PackageName>=version*commandused/Installing Pythonpackages Pythonprogramming fundamentals/ThefundamentalsofPythonprogramming operators/Pythonoperatorsandbuilt-intypes,Operators built-intypes/Pythonoperatorsandbuilt-intypes,Built-intypes comments/Pythonoperatorsandbuilt-intypes programflow,controlling/Controllingtheflowofyourprogram ifstatement/Theifstatement forstatement/Theforstatement whilestatement/Thewhilestatement Pythonsoftwareflow,Tweet-a-PowerStrip about/Pythonsoftwareflow Pythonthreadinglibrary URL/Usingthepaho-mqttPythonlibrary Pythontutorials URL/ThefundamentalsofPythonprogramming,Thewhilestatement R Radiobutton()widget about/TheCheckbutton()widget–selectingLEDs URL/TheCheckbutton()widget–selectingLEDs RaspberryPi about/WhatisaRaspberryPi? Raspbian/WhatisaRaspberryPi? versions/WhatisaRaspberryPi? configuring/InstallingtheoperatingsystemandconfiguringtheRaspberryPi operatingsystem,installing/Installingtheoperatingsystemandconfiguringthe RaspberryPi hardwarecomponents/WhatdoyouneedtobeginusingtheRaspberryPi? URL/WhatdoyouneedtobeginusingtheRaspberryPi?,PreparinganSD card SDcard,preparing/PreparinganSDcard setupprocess/TheRaspberryPisetupprocess read()method using/Theread()method real-timeArduinodata plotting/Plottingreal-timeArduinodata remotehomemonitoringsystem projectoverview/Projectoverview projectgoals/Theprojectgoals projectrequirements/Theprojectrequirements systemarchitecture,designing/Designingsystemarchitecture UXflow,defining/DefiningUXflow hardwarecomponents/Thelistofrequiredcomponents developmentstages,defining/Definingtheprojectdevelopmentstages monitoringstation,Arduinoused/Stage1–amonitoringstationusingArduino testing/Testing,Testingandtroubleshooting controlcenter,using/Stage2–acontrolcenterusingPythonandtheRaspberry Pi webapplication/Stage3–awebapplicationusingXively,Python,and Amazoncloudservice troubleshooting/Testingandtroubleshooting extending/Extendingyourremotehomemonitoringsystem multiplemonitoringstations,utilizing/Utilizingmultiplemonitoringstations sensorycapabilities,extending/Extendingsensorycapabilities UX,improving/ImprovingUX cloud-basedfeatures,expanding/Expandingcloud-basedfeatures improvedintelligence,forsituationawareness/Improvingintelligencefor situationawareness hardwareenclosures,creating/Creatinganenclosureforhardwarecomponents RepresentationStateTransfer(REST) about/Pythonwebframework–web.py RESTfulwebapplications developing,withArduinoandPython/RESTfulwebapplicationswithArduino andPython designing/DesigningREST-basedArduinoapplications GETrequest,implementing/WorkingwiththeGETrequestfromArduino GETrequest,generating/TheArduinocodetogeneratetheGETrequest GETrequest,handlingwithweb.py/TheHTTPserverusingweb.pytohandle theGETrequest POSTrequest,implementing/WorkingwiththePOSTrequestfromArduino POSTrequest,generating/TheArduinocodetogeneratethePOSTrequest POSTrequest,handlingwithweb.py/TheHTTPserverusingweb.pytohandle thePOSTrequest architecture/Exercise3–aRESTfulArduinowebapplication Arduinosketch/TheArduinosketchfortheexercise web.pywebapplication/Theweb.pyapplicationtosupportRESTrequests resource-constrainedmessagingprotocol,using/Whydoweneedaresourceconstrainedmessagingprotocol? S Scale()widget about/LearningTkinterforGUIdesign,TheScale()widget–adjustingthe brightnessofanLED used,foradjustingbrightnessofLED/TheScale()widget–adjustingthe brightnessofanLED SDcard referencelink/WhatdoyouneedtobeginusingtheRaspberryPi?,Preparing anSDcard preparing/PreparinganSDcard preparing,fromWindows/PreparinganSDcard preparing,fromMacOSX/PreparinganSDcard preparing,fromUbuntuLinux/PreparinganSDcard SecureShell(SSH)protocol/Loggingintoyourvirtualinstance SerialClockLine(SCL) about/PrototypingwiththeI2Cprotocol SerialDataLine(SDA) about/PrototypingwiththeI2Cprotocol serialmonitor using/UsingtheSerialMonitorwindow serialperipheralinterface(SPI) about/Prototyping Serverclass about/TheServerclass servomotors using/Servomotor–movingthemotortoacertainangle connections/Connections Pythoncode/ThePythoncode setup()function using/Thesetup()function Setuptools installing/InstallingSetuptools about/InstallingSetuptools installing,onLinux/Linux installing,onWindows/Windows installing,onMacOSX/MacOSX sketch about/WhatisanArduinosketch? compiling/Compilinganduploadingsketches uploading/Compilinganduploadingsketches sketchbook about/WhatisanArduinosketch? slicing about/Lists StandardFirmatafirmware using/Prototyping statements about/Functionsandstatements,Statements subnetwork/subnet about/Exercise1–awebserver,yourfirstArduinonetworkprogram referencelink/Exercise1–awebserver,yourfirstArduinonetworkprogram systemarchitecture,remotehomemonitoringsystem designing/Designingsystemarchitecture monitoringstation/Themonitoringstation controlcenter/Thecontrolcenter cloudservices/Thecloudservices systemarchitecture,Tweet-a-PowerStrip about/Systemarchitecture T Templetor about/Templates URL/Templates thermostat building/Thermostat–theprojectdescription projectdescription/Thermostat–theprojectdescription projectbackground/Projectbackground projectstages/Projectgoalsandstages projectgoals/Projectgoalsandstages requiredcomponents,identifying/Thelistofrequiredcomponents hardwaredesign/Hardwaredesign softwareflow,foruserexperiencedesign/Softwareflowforuserexperience design prototyping/Stage1–prototypingthethermostat GUI,designing/DesigningtheGUIandplotinPython plot,designing/DesigningtheGUIandplotinPython deploying,RaspberryPiused/Stage2–usingaRaspberryPiforthedeployable thermostat thermostat,prototyping Arduinointerrupts,using/UsingArduinointerrupts thermostat,usingRaspberryPi deploying/Stage2–usingaRaspberryPiforthedeployablethermostat portableTFTLCDdisplay,using/UsingaportableTFTLCDdisplaywiththe RaspberryPi TFTLCDconnection,usingGPIO/ConnectingtheTFTLCDusingGPIO TFTLCD,configuring/ConfiguringtheTFTLCDwiththeRaspberryPiOS GUI,optimizingforTFTLCDscreen/OptimizingtheGUIfortheTFTLCD screen troubleshooting/Troubleshooting thin-filmtransistorliquid-crystaldisplay(TFTLCD) about/Hardwaredesign ThingSpeak about/ThingSpeak Tk()widget about/LearningTkinterforGUIdesign,TherootwidgetTk()andthetop-level methods Tkinter about/LearningTkinterforGUIdesign Packgeometrymanager/ThePackgeometrymanager Gridgeometrymanager/TheGridgeometrymanager plots,integrating/IntegratingplotsintheTkinterwindow Tkinter,widgets Tk()/LearningTkinterforGUIdesign Label()/LearningTkinterforGUIdesign Button()/LearningTkinterforGUIdesign Entry()/LearningTkinterforGUIdesign Scale()/LearningTkinterforGUIdesign Checkbox()/LearningTkinterforGUIdesign Tkinterclass about/TheLabel()widget–monitoringI/Opins BooleanVar()method/TheLabel()widget–monitoringI/Opins update_idletasksmethod/TheLabel()widget–monitoringI/Opins updatemethod/TheLabel()widget–monitoringI/Opins TMP102temperaturesensor interfacing,Arduinoused/ArduinocodingfortheTMP102temperaturesensor interfacing,PyMatalibraryused/InterfacingTMP102usingPyMata transistorterminals referencelink/Connections troubleshooting Tweet-a-PowerStrip/Testingandtroubleshooting troubleshooting,Arduinoboardconnection about/Troubleshooting Tweet-a-PowerStrip projectoverview/Projectoverview projectrequirements/Projectrequirements systemarchitecture/Systemarchitecture hardwarecomponents/Requiredhardwarecomponents userexperienceflow/Userexperienceflow developmentstage/Developmentanddeploymentstages deploymentstage/Developmentanddeploymentstages smartpowerstripwithArduino/Stage1–asmartpowerstripwithArduinoand relays hardwaredesign/Hardwaredesign Arduinocode/TheArduinocode Pythoncode/Stage2–thePythoncodetoprocesstweets,ThePythoncode Pythonsoftwareflow/Pythonsoftwareflow Twitterapplication,settingup/SettinguptheTwitterapplication testing/Testingandtroubleshooting troubleshooting/Testingandtroubleshooting multiplefeatures,adding/Extendingtheprojectwithadditionalfeatures Twitterapplication,Tweet-a-PowerStrip settingup/SettinguptheTwitterapplication U Ubuntu Python,installing/Ubuntu matplotlib,settingup/SettingupmatplotlibonUbuntu UbuntuLinux SDcard,preparing/PreparinganSDcard UniversalSerialBus(USB) about/UsingtheSerialMonitorwindow Unoboard about/TheArduinoUnoboard userexperience(UX)flow,Tweet-a-PowerStrip about/Userexperienceflow V variables about/Variables virtualinstance,onAWSEC2service creating/CreatingavirtualinstanceontheAWSEC2service logginginto/Loggingintoyourvirtualinstance voiddatatype about/Datatypes W web.py used,fordevelopingwebapplications/Pythonwebframework–web.py installing/Installingweb.py basicconcepts/Essentialweb.pyconceptsfordevelopingcomplexweb applications URL,handling/HandlingURLs GETmethods/TheGETandPOSTmethods POSTmethods/TheGETandPOSTmethods templates/Templates forms/Forms withArduinoserialinterface/Exercise2–playingwithweb.pyconceptsusing theArduinoserialinterface webapplication,remotehomemonitoringsystem about/Stage3–awebapplicationusingXively,Python,andAmazoncloud service architecture/Architectureofthecloudservices Pythonwebapplication,hostedonAmazonAWS/Pythonwebapplication hostedonAmazonAWS testing/Testingthewebapplication,Testingandtroubleshooting webapplications developing,withPython/DevelopingwebapplicationsusingPython developing,web.pyused/Pythonwebframework–web.py implementing,web.pyused/YourfirstPythonwebapplication whilestatement about/Thewhilestatement wideareanetwork(WAN) about/Networkingfundamentals Windows Python,installing/Windows Setuptools,installing/Windows ArduinoIDE,installing/Windows Arduinoboardconnection,establishing/Windows matplotlib,configuring/ConfiguringmatplotlibonWindows SDcard,preparing/PreparinganSDcard IPaddress,obtaining/Windows Wirelibrary about/PrototypingwiththeI2Cprotocol URL/PrototypingwiththeI2Cprotocol Wiring about/IntroductiontoArduinoprogramming withstatement using/Thewithstatement–Pythoncontextmanager WorldWideWeb(WWW) about/RESTfulwebapplicationswithArduinoandPython write()method used,forworkingwithfiles/Thewrite()method X Xively/Architectureofthecloudservices Xively,IoTcloudplatforms about/Xively–acloudplatformfortheIoT account,settingup/SettingupanaccountonXively workingwith/WorkingwithXively Adruino,interfacingwith/InterfacingArduinowithXively