KEMBAR78
PixelPusher Programming Guide | PDF | Communications Protocols | Library (Computing)
0% found this document useful (0 votes)
463 views10 pages

PixelPusher Programming Guide

The document provides an overview of programming the PixelPusher system. It discusses: 1) The PixelPusher firmware, library, and examples that allow users to control LED arrays. 2) How the PixelPusher discovers and configures itself on the network using discovery and strip update messages. 3) How groups and controllers are used to organize different sections of a PixelPusher array.

Uploaded by

Flo Belouet
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
463 views10 pages

PixelPusher Programming Guide

The document provides an overview of programming the PixelPusher system. It discusses: 1) The PixelPusher firmware, library, and examples that allow users to control LED arrays. 2) How the PixelPusher discovers and configures itself on the network using discovery and strip update messages. 3) How groups and controllers are used to organize different sections of a PixelPusher array.

Uploaded by

Flo Belouet
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

Programming the PixelPusher

version0.5

JasStrong<jasmine@heroicrobotics.com>

0. Introduction

ThePixelPusherisasimplebeast.Ittakespixelsfromthenetwork,anditpushesthemoutto
intelligentLEDsasfastasitcan.IthassomesoftwareinsideitthatrunsasimpleTCP/IP
networkstack,andanumberofmodulesthattellithowtotalktodifferentLEDcontrolchips.

Thesophisticationinthissystemcomesfromthedesignofthenetwork.PixelPusheris
designedtobeplugandplaytoabstractthecomplexityofthetaskawayfromtheuserto
allowartistsandarchitectstoconcentrateontheinterestingpartofthedesignequation.

Weprovideasoftwarestackthatiscomprisedofthreecomponents:

1.Firmware

Thefirmwareisapieceofsoftwarethatisloadedintotheflashmemoryofthe
PixelPushercontrollercards.Itcontainsabout100kilobytesofmachinecode.Itcontainsa
realtimeoperatingsystem,anetworkstack,aFATfilesystem,aUSBstack,andasignalling
stacktotalktothestripsorpixelsyouhaveattached.

2.Thelibrary

ThelibraryisapieceofJavacodewhichrunsonthecontrollingcomputer.Itconsistsof
asetofclasseswhichcollectivelyfind,makeorderly,andtalktooneormorePixelPusher
controllers.

3.Examples

Theexamplesareprovidedinthelibrarypackage.Theyaregenerallyquitesimple
implementationsoftherequiredsoftwaretomakeaPixelPusherarraywork.Ifyouhaveinstalled
thelibrary,youcanfindtheminProcessingsExamples...dialogue,underContributed
Libraries.


1. To begin...

1. Thefirstthingyoullneedisacomputer.ThesoftwareisbasedonProcessing,sohead
tohttp://processing.org/andpickuptherightversionforyourmachine.Itisavailablefor
PC,MacandLinux,soyoushouldbeprettywellcovered.

2. Nextyouneedtoinstallthelibrary.Youcanfindinstructionsonhowtoinstalllibraries
intoProcessingathttp://wiki.processing.org/w/How_to_Install_a_Contributed_Library
notethatatthetimeofwriting,PixelPusherisnotyetincludedintheAddlibrary...tool,
soyouwillhavetodoitmanually.YoucanfindthePixelPusherlibraryat
http://forum.heroicrobotics.com/notethatitisfrequentlyupdated,sobesuretokeepup
todate.

3. Thirdly,youshouldupdatethefirmwareonyourPixelPusher.Itisquitelikelythatnew
firmwareversionshavecomeoutsinceyourproductshipped,aswefollowacontinuous
developmentmethodology.Dontworryitsquiteeasytodo,andallyouneedisamini
USBcable.YoucanfindinstructionsonhowtodothisintheHowToPushPixels
document,alsoavailablefromtheHeroicRoboticsforum.

4. Andlastly,youwillneedtowriteaconfigurationfileforeachPixelPusherinyoursystem,
saveeachoneontoaUSBmemorystick,andinsertitintotheappropriatePixelPushers
USBhostport.Then,tomakethemreadtheirconfiguration,presstheresetbuttonor
powerthePixelPusheroffandthenon.Theconfigurationfileis,again,explainedinthe
HowToPushPixelsdocument.

YoullneedtoconnectallthePixelPusherstothesamenetworkyourcomputerison,ofcourse.

Onceyouvedonethat,youcanopenoneofthePixelPusherexamplesinProcessing,hitrun
andyoushouldseeitpickupallyourPixelPushersinafewseconds.

2. How does all this work?

PixelPusherisdesignedtoautomaticallyconfigurethearray,anditdoesthisusingtwotypesof
message.OneissentfromacontrollingcomputertothePixelPushers,andtheotherissent
fromthePixelPusherstothecontrollingcomputer.Skipthenextpageifyourenotcuriousabout
howthisworks.

A technical aside:

The Universal Discovery Protocol

ThemessagesthataresentfromthePixelPushertothecontrollingcomputerfollowaformatwecallthe
UniversalDiscoveryProtocol.ThesepacketsaresentonceasecondbyallthePixelPushersonthe
network.TheycontainseveralpiecesofinformationaboutthePixelPusher,andarepickedupandstoredin
adatabasebythelibrary.Thepiecesofinformationinclude:

thePixelPushersIPaddressandMACaddress
twonumberscalledthegroupordinalandcontrollerordinal,assignedbytheuser
howmanystripsareattachedtothisPixelPusher
howmanypixelsareineachstrip
howlongittakesthisPixelPushertoprocesseachpacketofdata
howmanypacketsthePixelPushermissedinthelastsecond
howmanystripscanfitintoasingledatagram(packet).
aflagbyteforeachstrip,describingthepixellayout(RGBorRGBOW,24bitor48bit,
renormalizedorlinear).
thesoftwareversionthePixelPusherisrunning
aflagwordforthePixelPusher,denotingwhetheritrequirespackedstripdatagrams

Thelibraryusesthisinformationtobuildarepresentationofthearrayinmemory.This
representationispopulatedwithPixelPushersastheyareseen,andkeptuptodateasdiscovery
packetsarrive.Theapplicationsoftwarecanthenaskthelibraryforpiecesofthis
representation,andmodifythepixelsinthemodelthelibraryhandlessendingupdatesoutto
thePixelPushersautomaticallyandasynchronously.Todothis,itusesthesecondformof
traffic.

The Strip Update Message Protocol

Stripupdatesarepackedintodatagramsandsentbythisprotocol.Thepacketcontains
informationrelatingtospecificstrips,including:

apercardsequencenumberforthecurrentpacket
astripnumberfromzerotoseven
anumberofRGBtripletsappropriatetothenumberofpixelsinastrip

SincethememoryavailabletotheethernetcontrolleronPixelPusherislimited,onlyalimited
numberofpixelscanbesentinasingledatagram.Withourusualmaximumof240pixelsper
strip,twostripscanbesentineachdatagram.Eachdatagramhasasinglesequencenumber,
followedbyavariablenumberofrepetitionsofthestripnumberfollowedbythepixeldata.The
timinginformationandthemissedpacketdatafromthediscoverypacketareusedtothrottlethe
packetsbeingsenttotheavailablesystembandwidth.

3. Groups and Controllers

WeanticipatethatyoumightwanttohavemorethanonesectiontoyourPixelPusherarray.
Maybeyourelightingdifferentareas,oryouwanttohaveabigbillboardsizedvideodisplaythats
separatefromyour3dsculpture.Thatswhyweimplementedgroupsandcontrollers.

WhenthelibraryenumeratesaPixelPusheritreadsfromittwonumbers,whicharecalledgroup
andcontroller.Eachgroupisacollectionofcontrollers,andwithineachgrouptheyareordered
bythecontrollernumber.Youcanselectcontrollersbygroup,oryoucanjustselectallofthem
atonce,inwhichcasetheyareorderedfirstbygroupandthenbycontrollerso,forexample,
group2controller1comesbeforegroup2controller2,butgroup1controller37comesbefore
either.Iftwocontrollershavethesamenumber,theethernethardwareaddressisusedasa
tiebreaker.Sothereisathreelevelhierarchy:

4. Nuts and bolts

Asyoullseefromourexamples,thereareafewbitsandpiecesyoullneedinyourProcessing
sketchinordertomakethesystemwork.Heresaquickrundown.

Theimports

PixelPusherdefinesanumberofclassesthatprovideessentialfeatures.Atthetopofthesketch
youllseeablockthatlookslikethis:

importcom.heroicrobot.dropbit.registry.*
importcom.heroicrobot.dropbit.devices.pixelpusher.Pixel
importcom.heroicrobot.dropbit.devices.pixelpusher.Strip
importjava.util.*

Thisimportstheregistry,whichisthesoftwarecomponentthatlistensforthediscoverypackets,
thePixelPusherabstractionsforPixelsandStrips,andtheJavastandardutilityclasseswhich
areusedforcollections.

Theregistry

ThenextthingwedoistodeclaretheDeviceRegistry.

Theobserver

PixelPushersregistryusesanObservermodeltotellthesketchwhenPixelPushersappearand
disappear.Theresasimpleimplementationofthisbelow.

classTestObserverimplementsObserver{
publicbooleanhasStrips=false
publicvoidupdate(Observableregistry,ObjectupdatedDevice){
println("Registrychanged!")
if(updatedDevice!=null){
println("Devicechange:"+updatedDevice)
}
this.hasStrips=true
}
}

Thenwedeclareone,likethis:

TestObservertestObserver

Asyoucansee,itsnotabigclass,andjustimplementsamemberyoucanusetocheckwhen
therearestripsavailabletothesystem.Theobserverwillgetcalledandupdatedwheneverthe
arraysshapeorbehaviourchangessignificantly.

Setup

Thentherearesomebitsandpiecesweneedtodointhesketchssetup()method.Thisisa
methodthatrunsbeforethesketchstartsinearnest,anditsagoodplacetoinstantiatethebits
andpiecesweneedforPixelPusher.Thecodeweuselookslikethis:

registry=newDeviceRegistry()
testObserver=newTestObserver()
registry.addObserver(testObserver)

Thisinstantiatestheregistry,gettingitrunningandlisteningforPixelPusherstoappear.It
instantiatestheobserver,andthentellstheregistryaboutit.

Pushingthosepixels

Havingdoneallthissetup,weregoodtogo.Wedoouractualpushinginthesketchsdraw()
method.Firstwehavetowaituntilthereactuallyaresomestripsinexistence!Itmighttakea
secondortwoafterthesketchstartsuntilaPixelPusherannouncesitself.Wewaituntilsome
makeanappearance.

if(testObserver.hasStrips){
//...thePixelPushercodeiswrappedupinhere
}

Whentheymaketheirappearance,wemakeacalllikethistomaketheregistrystarttalkingto
thePixelPushers:

registry.startPushing()

Thenextthingweneedtodoistogetthestrips.TheStripclassisarepresentationofastringof
LEDpixelsoraflexibleLEDstrip.Aswesawearlier,therearegroupswhichcontaincontrollers
eachofwhichcontainsstrips.Sincewalkingthishierarchyistedious,weprovideawaythatyou
canbypassthisandhavetheregistrydoitforyou.

List<Strip>strips=registry.getStrips()

Thisreturnsalistofallthestripsknowntotheregistry.Alternatively,ifyouonlywanttotalkto
oneparticulargroup,youcandothis:

List<Strip>strips=registry.getStrips(some_group_number)

anditwillreturnalistofallthestripsbelongingtocontrollerswhosegroupnumberisgiven.

Thenallyouneedtodoistoloopthroughthestripsandsetthepixelswithinthemtothe
appropriatecolour.Bewarnedthatnotallthestripsmaybethesamelength!TheStripclass
givesyouamethodtodeterminethelength.strip.getLength()willreturnthenumberof
pixelsinthestrip.Tosetthecolourofapixel,youcancallstrip.setPixel(color,
number)wherecolourcaneitherbeaProcessingcolorobjectoraPixelPusherPixelobject.

5. Every day Im scrapin

Inmostofourexamples,wescrapepixelsfromtheProcessingsketchwindowandsendthem
tothearraydirectly.Thecodetodothislookslikethis:

intstripy=0
List<Strip>strips=registry.getStrips()
intyscale=height/(strips.size())

for(Stripstrip:strips){
intxscale=width/strip.getLength()
for(intstripx=0stripx<strip.getLength()stripx++){
colorc=get(stripx*xscale,stripy*yscale)
strip.setPixel(c,stripx)
}
stripy++
}

6. Tweaking the rate

Normally,theregistrykeepstrackofhowmanypacketsarebeinglost(theygetdroppedifthere
isntenoughbandwidthorifyoureusingawirelessnetworkandtheresnoise)andhowlong
eachPixelPusherissayingittakestopushoutacompletepackettothestrips,andadjuststhe
rateatwhichpacketsaresentautomatically.However,ifyoureonaveryslownetwork,likea
verylongwirelesslinkoracellularmodem,youmightwanttoaddanextraslowdown.Thats
whattheregistry.setExtraDelay()methodisfor.

registry.setExtraDelay(milliseconds)

Thisaddsanextradelaytoeverypacketthatissentbytheregistrysworkerthreads.Ifyousetit
tozero,onlythestandardratelimitingapplies.WithfulllengthHeroicRoboticsstripsandthe
defaultupdaterate,eachPixelPusherconsumesbetween5and10megabitspersecondof
bandwidth.Inthespecialturbomode,aPixelPusherwithtwostripsrunningatmaximumspeed
willconsumeabout52megabitspersecondofbandwidth.

Ifyoureonanetworkwithahigherrorrate,likesomewirelessnetworks,orpoorlyinstalled
ethernet,youmightfindthatyougetpersistentlyhigherrorratesandtheupdatefrequencydrops
uncontrollably.Inthiscase,youmaywanttodisabletheautothrottlingentirely.Weprovidea
registrymethodtodothis.registry.setAutoThrottle(true)willturnautothrottlingon,
andregistry.setAutoThrottle(false)willturnitoff.

Asof20130325,thelibrarydefaultstoautothrottlingbeingturnedoff,soyouwillneedtomake
theabovemethodcalltoturniton.

7. Getting the colours right

Ifyoureusingvideosourcematerialandeverythinglookswashedout,youmaywanttoapplythe
antilogcurvecorrection.PixelPusherfaithfullysendseverythingyoutellittoouttothestrips,
otherwise.Asofthe20130608versionofthelibrary,thereisacalltotellittocorrectthe
luminancecurve:registry.setAntiLog(true)willsetthecurvecorrectionon.Thevalue
falsewillturnitoff.ThanksareduetoRusMaxhamforcontributingthiscode.

8. A note on architecture

ThewayPixelPusherslibraryactuallyworksisthatthereareseveralthreads,allrunning
asynchronously.Thedatastructuresusedinternallyarealllockless,sogoodrealtime
performanceispossible.Thethreadsarenamed,soifyouwanttouseVisualVMtoprofile
whatsusingCPUtime,youcaneasilyidentifythem.Thedifferentprocessesarethese:

TheUDPcallback(akaDiscoveryListener)

Theresasmallroutinethatgetscalledeverytimeadiscoverypacketarrives,whichupdatesthe
PixelPusherdatastructures.Itkeepsthestructuresuptodate,andalsonoteshowlongits
beensinceanygivenPixelPusherhasbeenseen.Iftheydisappearformorethanafew
seconds,theyareremovedfromthestructure.Iftheysaythattheyhavemissedpackets(as
indicatedbydiscontinuitiesinthesequencenumbers)thenthisroutineisresponsiblefor
changingtheappropriateratelimitingvariables.

Thepreeningthread

Thisrunseveryfewsecondstocleanthedatastructuresandremoveanysadlydeparted
PixelPushersfromthesystem.

Themarshallingthread(akaSceneThread)

Thisrunscontinuously,andtakescareoftheworkerthreads,makingsurethatthereisone
workerthreadforeveryPixelPusher.ItsresponsibleforkillingthreadswherethePixelPusher
hasdisappeared,andstartingnewoneswhennewPixelPushersappear.

Theworkerthreads(withnameslikeCardThreadfor00:04:13:a3:a6:5c)

EachPixelPushercardhasanassociatedworkerthread.Theworkerthreadissimpleit
checkstheRegistrytoseehowthecardisdoing,andthenitchecksthestripstructures
associatedwithitscard.Ifanyofthemaremarkedasupdated,itwalksthroughthem,sending
themtothecardattheratethathasbeencalculated,andmarksthemasnotupdated.

Thereareseveraldatastructuresinternaltothelibrarywhichareusedtokeeptrackofwhich
cardsarewhich,whichstripsbelongwhere,andwhichstripsarewhichlength.Itisstrongly
recommendedthatyousticktousingthesoftwareinterfaceslistedinthisdocument,ratherthan
modifyinganyofthestructuresyourself,sincethesehavechangedinthepastandwilllikely
changeinfuturewhichwouldrequireyoutowritenewcode!

9. Multi-head operations

Becausetheworkerthreadsonlysendpacketstoupdatepixelsthathavechanged,itispossible
tohavemultiplecontrollingPCs(orMacs,Androiddevices,etc.)onasinglePixelPusherarray,
aslongastheyareeachcontrollingseparatesubsetsofPixelPushers.Itisstrongly
recommendedthatyourestrictthissharingtoonecontrollingPCperPixelPusher,since
otherwisetherearelikelytobetimingconflictsandyoumayendupfloodingonepoor
PixelPusherwithtwiceasmuchnetworktrafficasitdeserves.Ifyoujustcantkeepthe
architecturethissimple,usetheExtraDelayfeaturedescribedafewpagesagotoreducethe
signallingrate.Youwillalsoneedtodisabletheautothrottlesystem,sincethesequence
numberswillnotbesynchronizedbetweendifferentcontrollingPCs.

You might also like