You are on page 1of 21

Explore (/tag/typeid/)

(/)
(/)

Create (/about/submit.jsp)

Contests
let's make (/contest/)

Community (/community/)
You (/you/)

share what you make >


(/editInstructable/)

(/id/intel/)

(/tag/typeid/categoryliving/channelreuse/?sort=FEATURED)
(/tag/typeid/categoryoutside/channelcamping/?sort=FEATU
(/tag/typeid/categorytechnology/chann

AboutThisInstructable
313,135views

Posted:
Jun14,2008

525favorites

License:

barney_1
(/member/barney_1/)
Follow

67

(/member/barney_1/)
Morebybarney_1

(/id/LEDHanukkah
Menorah)

(/id/BeerBottleDryingRack)
(http://cdn.instructables.com/FQP/VQXF/FHAVXW8U/FQPVQXFFHAVXW8U.LARGE.jpg)

(/id/HowtoMakeandCan
ConcordGrapeJam)
Tags:
(http://cdn.instructables.com/FF0/6U1X/FHEJ12BU/FF06U1XFHEJ12BU.LARGE.jpg)

avr(/tag/typeid/categorytechnology/keywordavr/)
8x8(/tag/typeid/categorytechnology/keyword8x8/)

Thisinstructableismeanttobeamorecompleteexplanationthanothers
availableonline.Notably,thiswillprovidemorehardwareexplanationthanis
availableintheLEDMarqueeinstructable(http://www.instructables.com/id/USB
(http://cdn.instructables.com/FXR/H9OQ/FHPVYGKP/FXRH9OQFHPVYGKP.LARGE.jpg)
LEDscrollingmarqueesign)byled555.

led(/tag/typeid/categorytechnology/keywordled/)
matrix(/tag/typeid/categorytechnology/keyword
matrix/)
marquee(/tag/typeid/categorytechnology/keyword
marquee/)

Goals
Thisinstructablepresentstheconceptsinvolvedwithshiftregistersandhigh
sidedrivers.Byillustratingtheseconceptswithan8x8LEDmatrixIhopeto
provideyouwiththetoolsneededtoadaptandexpandtothesizeandlayout
yourprojectcallsfor.

ExperienceandSkills
Iwouldratethisprojecttobeofmediumdifficulty:
Ifyoualreadyhaveexperienceprogrammingmicrocontrollersandworking
withLEDsthisprojectshouldbefairlyeasyforyoutocompleteandtoscale
tolargerarraysoflights.
IfyouarejuststartingoutwithmicrocontrollersandhaveflashedanLEDor
twoyoushouldbeabletocompletethisprojectwithsomehelpfromour
friendgoogle(http://www.google.com).
Ifyouhavelittleornoexperiencewithmicrocontrollersorprogrammingthis
isprobablybeyondwhatyoushouldbegettingyourselfinto.Tryoutafew
otherbeginnerprojectsandcomebackwhenyou'vegotsomemore
experiencewritingprogramsformicrocontrollers.

DisclaimerandCredit
First,Iamnotanelectricalengineer.Ifyouseesomethingthatiswrong,ornota
bestpractice,pleaseletmeknowandI'llmakethecorrection.
Dothisatyourownrisk!Youshouldknowwhatyou'redoingoryoucancause

shift(/tag/typeid/categorytechnology/keywordshift/)
register(/tag/typeid/categorytechnology/keyword
register/)
LEDs_guide(/tag/typeid/category
technology/keywordleds_guide/)

Addinstructableto:
Group

Related
UsingaDotMatrixLED
withanArduinoandShift
Register(/id/UsingaDot
MatrixLEDwithan
ArduinoandShiftR/)
Makea8x10L.E.DMatrix
(/id/810LEDMatrixwith
4017/)
bySyst3mX
(/member/Syst3mX/)

watchfuturamaonan8x8
pixelscreen(/id/watch
futuramaonan8x8pixel
screen/)
bysethj(/member/sethj/)

damagetoyourcomputer,yourmicrocontroller,andevenyourself.
Ihavelearnedalotfromtheinternet,particularlyfromtheforumsat:
http://www.avrfreaks.net(http://www.avrfreaks.net)
Iamusingafontsetthatcamewiththeks0108universalClibrary.Checkthat
outhere:
http://en.radzio.dxp.pl/ks0108/(http://en.radzio.dxp.pl/ks0108/)

Step1:Parts
PartsList
GeneralParts
Tomakean8x8gridofLEDsandcontrolthemyouwillneed:
64LEDsofyourchoice
8ResistorsfortheLEDs
1Shiftregisterforthecolumns
1Driverarrayfortherows
8Resistorsforswitchingthedriverarray
1microcontroller
1clocksourceformicrocontroller
1prototypingboard
1powersupply
Hookupwire

SpecificPartsUsedHere
ForthisinstructableIusedthefollowing:
64greenLEDs(Mouserpart#604WP7113GD)
8220ohm1/4wattresistorsfortheLEDs(Mouserpart#660
CFS1/4CT52R221J)
1HEF4794LEDdriverwithshiftregister(Mouserpart#771HEF4794BPN)
1mic2981HighVoltageHighCurrentSourceDriverArray(Digikeypart
#5761158ND)
83.3kohm1/4wattresistorsforswitchingthedriverarray(RadioShackpart
#2711328)
1AtmelATmega8microcontroller(Mouserpart#556ATMEGA816PU)
112MHzcrystalforthemicrocontrollerclocksource(Mouserpart#815AB
12B2)
12200holeprototypingboard(RadioShackpart#276147)
ConvertedATXpowersupply:SeeThisInstructable
(http://www.instructables.com/id/ConvertingacomputerATXpowersupply
toareally/)
Solidcore22awghookupwire(RadioShackpart#2781221)
Solderlessbreadboard(RadioShackpart#276169(nolongeravailable,try:
276002)
AVRDragon(Mouserpart#556ATAVRDRAGON)
DragonRider500byEcrosTechnologies:SeeThisInstructable
(http://www.instructables.com/id/AssemblingtheDragonRider500foruse
withtheA/)

NotesRegardingParts
RowandColumnDrivers:Probablythemostdifficultpartofthisprojectis
pickingtherowandcolumndrivers.Firstoff,Idonotthinkastandard74HC595
shiftregisterisagoodideaherebecausetheycannothandlethekindofcurrent
wewanttosendthroughtheLEDs.ThisiswhyIchosetheHEF4794driverasit
caneasilysinkthecurrentpresentwhenall8ledsareinonerowareswitched
on.
Theshiftregisterispresentonthelowside(thegroundpinoftheleds).Wewill
needarowdriverthatcansourceenoughcurrenttostringmultiplecolumns
together.Themic2981cansupplyupto500mA.TheonlyotherpartIhave
foundthatperformsthistaskistheUDN2981(digikeypart#6201120ND)
whichisthesamepartbyadifferentmanufacturer.Pleasesendmeamessage
ifyouknowofotherhighsidedriversthatwouldworkwellinthisapplication.

Beginnertutorial:
ControllingLEDmatrix
with2595shiftregisters
LEDDotMatrixDisplay
(/id/LEDDotMatrix
Display1/)
bykapilgupta
(/member/kapil+gupta/)

SeeMore(/tag/typeid/?q=)

LEDMatrix:Thismatrixis8x8becausetherowandcolumndriverseachhave
8pins.AlargerLEDarraymaybebuiltbystringingmultiplematricestogether
andwillbediscussedinthe"modularconcepts"step.Ifyouwantalargearray,
orderalloftheneededpartsatonetime.
Thereare8x8,5x7and5x8LEDmatricesavailableinoneconvenientpackage.
Theseshouldbeeasytosubstituteforadiymatrix.Ebayisagoodsourcefor
these.Mouserhassome5x7unitsavailablesuchaspart#604TA1211GWA.I
usedcheapgreenLEDsbecauseI'mjustplayingaroundandhavefun.
Spendingmoreonhighbrightness,highefficiencyLEDscanallowyouto
produceamuchmorespectacularlookingdisplay...thisisgoodenoughforme
though!
ControlHardware:ThematrixiscontrolledbyanAtmelAVRmicrocontroller.
Youwillneedaprogrammerforthis.BecauseIamprototypingIamusingthe
DragonRider500forwhichIhavewrittenbothassembly
(http://www.instructables.com/id/AssemblingtheDragonRider500forusewith
theA/)andusage(http://www.instructables.com/id/HowtousetheDragon
Rider500withyourAVRDrag/)instructables.Thisisaneasytoolfor
prototypingandIhighlyrecommendit.

Step2:Thematrix

(http://cdn.instructables.com/F4C/Y5HU/FHAVXW96/F4CY5HUFHAVXW96.LARGE.jpg)

(http://cdn.instructables.com/F0G/11OW/FHAVXW95/F0G11OWFHAVXW95.LARGE.jpg)

(http://cdn.instructables.com/FTE/NWEA/FHAVXW92/FTENWEAFHAVXW92.LARGE.jpg)

(http://cdn.instructables.com/FVK/ZL0H/FHAVXW93/FVKZL0HFHAVXW93.LARGE.jpg)

(http://cdn.instructables.com/F78/H5HL/FHAVXW8Z/F78H5HLFHAVXW8Z.LARGE.jpg)

(http://cdn.instructables.com/FWT/GG22/FHAVXW8Y/FWTGG22FHAVXW8Y.LARGE.jpg)

(http://cdn.instructables.com/FN7/QYU5/FHAVXW8X/FN7QYU5FHAVXW8X.LARGE.jpg)

(http://cdn.instructables.com/FLQ/PWTJ/FHAVXW8W/FLQPWTJFHAVXW8W.LARGE.jpg)

(http://cdn.instructables.com/FQP/VQXF/FHAVXW8U/FQPVQXFFHAVXW8U.LARGE.jpg)

IwillbebuildingmyownLEDmatrixforthisprojectusing5mmledsanda
(http://cdn.instructables.com/FGT/PID2/FHAVXW8V/FGTPID2FHAVXW8V.LARGE.jpg)
prototypingboardfromRadioShack.Itshouldbenotedthatyoucanpurchase
8x8dotmatrixledmodulesfromseveralsources,includingebay.Theyshould
workjustfinewiththisinstructable.
(http://cdn.instructables.com/FLP/N1OJ/FHAVXW94/FLPN1OJFHAVXW94.LARGE.jpg)

ConstructionConsiderations

Alignment
TheLEDSneedtobealignedsotheyfacethesamedirectionatthesame
angle.IfoundtheeasiestoptionformewastoputthebodyoftheLEDflushto
theboardandholdittherewithasmallpieceofplexiglassandaclamp.Iputa
fewLEDsinplaceacoupleofinchesawayfromtherowIwasworkingonto
makesuretheplexiglasswasparallelwiththeprototypingboard.
(http://cdn.instructables.com/FSW/VO3F/FHAVXXA0/FSWVO3FFHAVXXA0.LARGE.jpg)

RowsandColumns
Weneedtohaveacommonconnectionforeachrowaswellaseachcolumn.
Becauseofourrowandcolumndriverchoiceweneedtohavetheanode
(positiveleadoftheLED)connectedbyrowandthecathode(negativeleadof
theLED)connectedbycolumn.
ControlWires
ForthisprototypeIamusingsolidcore(singleconductor)hookupwire.Thiswill
beveryeasytointerfacewithasolderlessbreadboard.Feelfreetousea
differentconnectortypetosuityourproject.

BuildingtheMatrix
1.PlacethefirstcolumnofLEDSintheprototypingboard.
2.DoublecheckthatyourpolarityforeachLEDiscorrect,thiswillbevery
difficulttofixifyourealizeitlater.
3.SolderbothleadsoftheLEDtotheboard.Checktomakesuretheyare
alignedcorrectly(notatweirdangles)andclipoffthecathodeleads.Makesure
youdonotcliptheanodelead,wewillneedthatlatersojustleaveit
pointingup.

4.Removetheinsulationfromapieceofsolidcorewire.Solderthispieceof
wiretoeachcathoderightatboardlevel.
Itackedthisateachendthenwentbackandaddedabitofsolderateach
junction.
ThiswireshouldrunpastyourlastLEDtomakeforaneasyinterfacewhen
weaddcontrolwires.
5.Repeatparts14untilyouhaveallLEDsinplaceandallcolumnbuses
soldered.
6.Tocreatearowbus,bendseveraloftheanodeleadsata90degreeangleso
theytouchtheotheranodeleadsinthesamerow.
Therearedetailedpicturesofthisbelow.
Takecarenottoletthesecomeincontactwiththecolumnbuses,creatinga
shortcircuit.
7.Soldertheleadsateachjunctionandclipofftheexcessanodeleads.
LeavethelastanodestickingpastthefinalLED.Thiswillbeusedtoconnect
therowdrivercontrolwires.
8.Repeatparts6&7untilallrowsbuseshavebeensoldered.
9.Attachcontrolwires.
Iusedredsolidcorewirefortherowsandblackforthecolumns.
Connectonewireforeachcolumnandoneforeachrow.Thiscaneasilybe
doneattheendofeachbus.

Important
ThisLEDmatrixdoesnothaveanycurrentlimitingresistors.Ifyoutestthis
withoutresistorsyouwillprobablyburnoutyourLEDsandallthisworkwillbe
fornothing.

Step3:Thecontrolhardware

(http://cdn.instructables.com/FFK/5I0V/FHAVXX9Z/FFK5I0VFHAVXX9Z.LARGE.jpg)

(http://cdn.instructables.com/F11/QXQF/FHAVXWNH/F11QXQFFHAVXWNH.LARGE.jpg)

WeneedtocontrolthecolumnsandtherowsofourLEDmatrix.Thematrixhas
beenconstructedsothattheAnodes(voltagesideoftheLED)constitutethe
rows,andtheCathodes(groundsideoftheLED)makeupthecolumns.This
meansourrowdriverneedtosourcecurrentandourcolumndriverneedsto
sinkit.
InordertosaveonpinsIamusingashiftregistertocontrolthecolumns.This
wayIcancontrolanalmostunlimitednumberofcolumnswithjustfour
microcontrollerpins.ItispossibletouseonlythreeiftheEnableOutputpinis
tieddirectlytovoltage.IhaveselectedtheHEF4794LEDdriverwithshift
register.Thisisabetteroptionthanastandard74HC595asitcaneasilysink
thecurrentpresentwhenall8LEDsareonatonetime.
Onthehighside(currentsourcefortherows)Iamusinganmic2981.The
schematicshowsaUDN2981,Ibelievethesetwoareinterchangeable.This
drivercansourceupto500mAofcurrent.Becauseweareonlydriving1rowat
atimethisgivesalotofopportunityforexpansion,upto33columnsforthischip
(moreonthatinthe"modularconcepts"step).

BuildingtheControlHardware
ForthisinstructableIhavejustbreadboardedthiscircuit.Foramorepermanent
solutionyouwillwanttoeitheretchyourowncircuitboardoruseprototyping
board.
1.RowDriver
Placethemic2981(orUDN2981)inthebreadboard
ConnectPin9toVoltage(Thisisconfusingintheschematic)
ConnectPin10toGround(Thisisconfusingintheschematic)
insert3k3resistorsconnectingtopins18
ConnectfromPortDoftheATmega8(PD0PD8)tothe8resistors
Connectthe8rowcontrolwiresoftheLEDmatrixtopins1118(notethatI
haveconnectedthelowestrowofLEDstoPin18andtheHighestrowtoPin
11).
2.ColumnDriver
Placethehef4794inthebreadboard
ConnectPin16tovoltage
ConnectPin8toground
Connect220ohmresistorstoPins47and1114.
Connectthe8columncontrolwiresfromtheLEDmatrixtothe8resistors
youjustconnected.
ConnectPin1(Latch)toPC0oftheATmega8
ConnectPin2(Data)toPC1oftheATmega8
ConnectPin3(Clock)toPC2oftheATmega8
ConnectPin15(EnableOutput)toPC3oftheATmega8
3.ClockCrystal
Connecta12MHzcrystalandloadcapacitorsasshownintheschematic
4.ISP
Connecttheprogrammingheaderasshownintheschematic
5.FilteringCapacitorandPullupresistor
ItisbesttofilterthevoltagesuppliedtotheATmega8.Usea0.1ufcapacitor
betweenPin7&8oftheATmega8
Theresetpinshouldnotbeleftfloatingasitcancauserandomresets.Usea
resistortoconnectittovoltage,anythingabout1kshouldbegood.I'veused
a10kresistorintheschematic.
6.Makesureyouareusing+5vregulatedpower.It'suptoyoutodesignthe
regulator.

Step4:Software
TheTrick
Yes,likeeverything,there'satrick.Thetrickisthattherearenevermorethan8
LEDsilluminatedatonetime.
Forthistoworkwell,abitofcraftyprogrammingisneeded.TheconceptIhave
chosenistouseatimerinterrupt.Here'showthedisplayinterruptworksinplain
english:
Timercountsuptoacertainpoint,whenreachedtheinterruptservice

routineisrun.
Thisroutinedecideswhichrowisthenextonetobedisplayed.
Theinformationforthenextrowislookedupfromabufferandshiftedinto
thecolumndriver(thisinformationisnot"latched"soitisnotyetdisplayed).
Therowdriverisshutoff,noLEDsarecurrentlylit.
Thecolumndriveris"latched"makeintheinformationweshiftedintwo
stepsagothecurrentinformationtodisplay.
Therowdriverthenprovidescurrenttothenewrowwearedisplaying.
Theinterruptserviceroutineendsandprogramreturnstonormalflowuntil
thenextinterrupt.
Thishappensveryveryquickly.Theinterruptisthrownevery1mSec.This
meansthatwe'rerefreshingtheentiredisplayaboutonceevery8mSec.This
meansadisplayrateofaround125Hz.Thereissomeconcernregarding
brightnessbecauseweareessentiallyrunningtheLEDsata1/8dutycycle
(theyareoff7/8ofthetime).InmycaseIgetanadequatelybrightdisplaywith
novisibleflashing.
ThefullLEDdisplayismappedoutinanarray.Inbetweeninterruptsthearray
canbechanged(bemindfulofatomicity)andwillappearonthedisplayduring
thenextinterrupt.
ThespecificsofwritingcodefortheAVRmicrocontrollerandofhowtowrite
codetotalktotheshiftregistersisbeyondthescopeofthisinstructable.Ihave
includedthesourcecode(writteninCandcompiledwithAVRGCC)aswellas
thehexfiletoprogramdirectly.Ihavecommentedallofthecodesoyoushould
beabletousethistoclearupanyquestionsabouthowtogetdataintotheshift
registerandhowtherowrefreshisworking.
PleasenotethatIamusingafontfilethatcamewiththeks0108universalC
library.Thatlibrarycanbefoundhere:http://en.radzio.dxp.pl/ks0108/
(http://en.radzio.dxp.pl/ks0108/)
Update:

ShiftRegisters:HowTo
I'vedecidedtoaddabitabouthowtoprogramwithshiftregisters.Ihopethis
clearsthingsupforthosewhohaven'tworkedwiththembefore.
Whattheydo
ShiftRegisterstakeasignalfromonewireandoutputthatinformationtomany
differentpins.Inthiscase,thereisonedatawirethattakesinthedataand8
pinsthatarecontrolleddependingonwhatdatahasbeenreceived.Tomake
thingsbetter,thereisanoutpinforeachshiftregisterthatcanbeconnectedto
theinputpinofanothershiftregister.Thisiscalledcascadingandmakesthe
expansionpotentialanalmostunlimitedprospect.
TheControlPins
Shiftregistershave4controlpins:
LatchThispintellstheshiftregisterwhenitistimetoswitchtonewly
entereddata
DataThe1'sand0'stellingtheshiftregisterwhatpinstoactivateare
receivedonthispin.
ClockThisisapulsesentfromthemicrocontrollerthattellstheshift
registertotakeadatareadingandmovetothenextstepinthe
communicationprocess
EnableOutputThisisanon/offswitch,High=On,Low=Off
Makingitdoyourbidding:
Here'sacrashcourseintheoperationoftheabovecontrolpins:
Step1:SetLatch,Data,andClocklow
SettingtheLatchlowtellstheshiftregisterweareabouttowritetoit.
Step2:SetDatapintothelogicvalueyouwanttosendtotheShiftRegister
Step3:SetClockpinhigh,tellingtheShiftRegistertoreadinthecurrentData
pinvalue
AllothervaluescurrentlyintheShiftRegisterwillmoveoverby1place,
makingroomforthecurrentlogicvalueoftheDatapin.
Step4:SettheClockpinLowandrepeatsteps2and3untilalldatahasbeen
senttotheshiftregister.
TheclockpinmustbesetlowbeforechangingtothenextDatavalue.
Togglingthispinbetweenhighandlowiswhatcreatesthe"clockpulse"the
shiftregisterneedstoknowwhentomovetothenextstepintheprocess.

Step5:SetLatchhigh
Thistellstheshiftregistertotakeallofthedatathathasbeenshiftedinand
useittoactivatetheoutputpins.Thismeansthatyouwillnotseedataasit
isshiftinginnochangeintheoutputpinswilloccuruntiltheLatchisset
high.
Step6:SetEnableOutputhigh
TherewillbenopinoutputuntiltheEnableOutputissettohigh,nomatter
whatishappeningwiththeotherthreecontrolpins.
Thispincanalwaysbelefthighifyouwish
Cascading
Therearetwopinsyoucanuseforcascading,OsandOs1.Osisforfastrising
clocksandOs1isforslowrisingclocks.Hookthispintothedatapinofthenext
shiftregisterandtheoverflowfromthischipwillbeenteredintothenext.
Endofupdate

Addressingthedisplay
IntheexampleprogramIhavecreatedanarrayof8bytescalledrow_buffer[].
Eachbytecorrespondstoonerowofthe8x8display,row0beingthebottom
androw7beingthetop.Theleastsignificantbitofeachrowisontheright,the
mostsignificantbitontheleft.Changingthedisplayisaseasyaswritinganew
valuetothatdataarray,theinterruptserviceroutinetakescareofrefreshingthe
display.

Programming
Programmingwillnotbediscussedindetailhere.Iwouldwarnyounottousea
DAPAprogrammingcableasIbelieveyouwillbeunabletoprogramthechip
onceitisrunningat12MHz.Allotherstandardprogrammersshouldwork
(STK500,MKII,Dragon,Parallel/Serialprogrammers,etc.).
Fuses:
Makesuretoprogramthefusestousethe12MHzcrystal
hfuse:0xC9
lfuse:0xEF

InAction
Onceyouprogramthechipthedisplayshouldscrolla"HelloWorld!".Hereisa
videooftheLEDmatrixinactions.ThevideoqualityisprettylowasImadethis
withmydigitalcamera'svideofeatureandnotapropervideoorwebcam.

8x8_Matrix.zip

(/files/orig/FZ3/1Y26/FHEZC86Z/FZ31Y26FHEZC86Z.zip)9KB

Step5:Modularconcepts

(http://cdn.instructables.com/F8N/ED98/FHEZCBSF/F8NED98FHEZCBSF.LARGE.jpg)

(http://cdn.instructables.com/FWZ/5D6J/FHAVXWNI/FWZ5D6JFHAVXWNI.LARGE.jpg)

(http://cdn.instructables.com/FQM/22V9/FHEJ03DX/FQM22V9FHEJ03DX.LARGE.jpg)

Thisprojectisscalable.Theonlytruelimitingfactorwillbehowmuchcurrent
yourpowersupplycanprovide.(TheotherrealityishowmanyLEDsand
registershiftersyouhaveavailable).

Math

(http://cdn.instructables.com/FXB/F0OL/FHEJ03K8/FXBF0OLFHEJ03K8.LARGE.jpg)

IamdrivingtheLEDsatabout15mA(5V1.8vDrop/220ohms=14.5mA).This
meansIcandriveupto33columnswiththemic2981driver
(500mA/15mA=33.3).Dividedby8wecanseethatthisallowsustostring
together4shiftregisters.
Alsoconsiderthatyoudonotneedtohaveall32columnsstretchfromleftto
right.Youcouldinsteadcreatea16x16arraythatiswiredthesamewayyou
wouldan8x32array.Thiswouldbeaddressedbyshiftingin4bytes....thefirst
twowouldshiftallthewaytotheledsforthe9throw,thesecondtwobytes
wouldshiftintothefirstrow.Bothrowswouldbesourcedbyonepinontherow
driver.

CascadingShiftRegisters
Theshiftregistersusedarecascadingshiftregister.Thismeansthatwhenyou
shiftindata,theoverflowappearsontheOspin.Thebecomesveryusefulasa
setofshiftregisterscanbeconnectedtoeachother,OspintoDatapin,adding

8columnswitheachnewchip.
AlloftheshiftregisterswillconnecttothesameLatch,Clock,andEnable
Outputpinsonthemicrocontroller.The"cascading"effectiscreatedwhenthe
OsofthefirstshiftregisterisconnectedtotheDatapinofthesecond.The
programmingwillneedtobealteredtoreflecttheincreasednumberofcolumns.
Boththebufferthatstorestheinformationandthefunctionthatshiftsinformation
inforeachcolumnneedtobeupdatedtoreflecttheactualnumberofcolumns.
Aschematicofthisisgivenbelowasanexample.

MultipleRowDrivers
Therowdriver(mic2981)cansourceenoughcurrenttodrive32columns.What
ifyouwantmorethan32columns?Itshouldbepossibletousemultiplerow
driverswithoutusingmoremicrocontrollerpins.
WeneedtherowdriverstosourceenoughcurrenttolighttheLEDs.Ifyouare
usingmorecolumnsthanitispossibletolightatonetime,additionrowdrivers
cansupplytheneededcurrent.Thesameinputpinsfromthemicrocontrollerare
usedsothereisnoneedtoalterthescanningoftherows.Inotherwords,each
drivercontrolstherowsforan8x32block.Eventhough64columnsmayhave
thesamePHYSICALrowplacement,wedividetherowbusesintwo,usingone
driverforthe8rowsofthefirst32columns,andaseconddriverforthe8rows
ofthesecond32columnsandsoforth.
Aschematicofthisisgivenbelowasanexample.
PotentialMissteps:
1.Donotusemultiplerowdriverswiththesamenumberofcolumns.Doingso
wouldmeanthateachshiftregisterpinwouldbedrivingmorethanoneLEData
time.
2.Youmusthaveasetof8resistors(3k3)foreachrowdriver,onesetfor
multiplerowdriverswillnotworkasitwillnotprovidethenecessarycurrentto
switchthegates.

ForExample
IdecidedtoexpandonthematrixIbuiltearlier.Ihaveadded7morerowsfora
totalof15asthat'sallIcanfitonthisprotoboard.
IalsojustfoundoutaboutacontestthatInstructablesisdoingcalled"Letit
Glow".Hereisavideoofmytakeonthat.Onceagain,thedigitalcameraIused
totakethevideodoesn'tdoitjustice.Thislooksgreattothehumaneye,
especiallywherealltheLEDsflash,butdoesn'tlooknearlyasgoodinthevideo.
Enjoy:

Sourcecodeforthislargerdisplayisincludedbelow.

Let_It_Glo.zip

(/files/orig/FCQ/LVN5/FHEJ16M3/FCQLVN5FHEJ16M3.zip)11KB

Step6:Conclusion
PossibleAdditions

I2C
IhavelefttheTwoWireInterface(I2C)pinsunusedinthisdesign.Thereare
severalinterestingprospectsthatcanusethesetwopins.AdditionofanI2C
EEPROMwillallowforstorageofmuchlargermessages.Thereisalsothe
prospectofdesigningprogrammingtoturnthemega8intoanI2Ccompatible
displaydriver.ThiswouldopenupthepossibilityofhavingaUSBenabledevice
todisplaydataonyourLEDarraybypassingitovertheI2Cbus.
Input
TherearemanypinsleftoverthatcouldbeusedforbuttonsoranIRreceiver.
Thiswouldallowformessagestobeprogrammedinviaamenusystem.
Display
ForthisinstructableIonlyimplementedacoupleofdisplayfunctions.Onejust
writescharacterstothedisplay,theotherscrollscharactersontothedisplay.
Theimportantthingtorememberisthatwhatyouseeinthelightsisrepresented
inadataarray.Ifyoucomeupwithcleaverwaystochangethedataarray,the
lightswillchangeinthesameway.
Sometantalizingopportunitiesincludecreatingagraphingmeteroutofthe
columns.Thiscouldbeusedasasignalanalyzerwithastereo.Scrollingcanbe
implementedfromthetopdownorbottomup,evenlefttoright.Goodluck,have
fun!

Step7:FollowUp

(http://cdn.instructables.com/FW7/FSY5/FLROM0XY/FW7FSY5FLROM0XY.LARGE.jpg)

(http://cdn.instructables.com/FTE/0REG/FLROM0XX/FTE0REGFLROM0XX.LARGE.jpg)

(http://cdn.instructables.com/F25/WZ0J/FLROM0XU/F25WZ0JFLROM0XU.LARGE.jpg)

(http://cdn.instructables.com/FGP/U1U9/FLROM0XV/FGPU1U9FLROM0XV.LARGE.jpg)

(http://cdn.instructables.com/FI4/QJ4P/FLROM0XR/FI4QJ4PFLROM0XR.LARGE.jpg)

(http://cdn.instructables.com/FQ4/90RQ/FLROM0XS/FQ490RQFLROM0XS.LARGE.jpg)

(http://cdn.instructables.com/FLX/4CYK/FLROM0XT/FLX4CYKFLROM0XT.LARGE.jpg)

(http://cdn.instructables.com/FK7/AQVN/FLROM0XO/FK7AQVNFLROM0XO.LARGE.jpg)

(http://cdn.instructables.com/F4V/8TUF/FLROM0XP/F4V8TUFFLROM0XP.LARGE.jpg)

AfterlettingthecontrollercircuitsitinthebreadboardformonthsIfinally
designedandetchedafewcircuitboardstoputthisprototypetogether.
Everythingworkedoutgreat,Idon'tthinkthere'sanythingIwouldhavedone
differently.

CircuitBoardFeatures
Shiftregistersareonseparateboardsthatcanbedaisychainedtogetherto
increasethesizeofthedisplay.
Controllerboardhasit'sownpowerregulatorsothiscanberunbyany
powersourcethatprovides7v30v(9vbatteryor12vbenchsupplyboth
workjustfineforme).
(http://cdn.instructables.com/F7G/ZD2H/FLROM0XQ/F7GZD2HFLROM0XQ.LARGE.jpg)
6pinISPheaderincludedsothemicrocontrollercanbereprogrammed
withoutremovingitfromtheboard.

4pinheaderavailableforfutureuseoftheI2Cbus.Thiscouldbeusedfor
aneepromtostoremoremessagesoreventomakethisaslavedevice
controlledbyanothermicrocontroller(RSStickeranyone?)
3momentarypushbuttonsareincludedinthedesign.Imaytweakthe
firmwareinthefuturetoincludetheuseofthesebuttons.

Assembly
Givemeplexiglass,anglebrackets,6x32machinescrews,nuts,andwashers,
aswellasatapsettothreadholesandIcancreateanything.

LED_Matrix_PCB_Proto_Firmware.zip
(/files/orig/FJ8/9K1G/FLROM0XW/FJ89K1GFLROM0XW.zip)12KB

Wehaveabenicecommentpolicy.
Pleasebepositiveandconstructive.

IMadeit!

140of
130

AddImages

MakeComment

Next(http://www.instructables.com/id/LEDmatrixusingshiftregisters/?
&sort=ACTIVE&limit=40&offset=40#DISCUSS)

axeman911(/member/axeman911/)

4yearsago

Reply

insteadofmic2981wouldadecadecounterwork,orcouldwejustoutthepins
directlyonthearduino?
(/member/axeman911/)
flag

bweaver6(/member/bweaver6/) axeman911

3monthsago

Reply

YouwouldntwanttouseattlICtopowertheLED's.Thematrixwould
(/member/bweaver6/)
pulltomuchcurrentfortheICtohandle.
flag

zxlee(/member/zx+lee/)

1yearago

Reply

Thumbsup,greatexplanation,greatinstructables:D
(/member/zx+lee/)
flag

fredkylam(/member/fredkylam/)

1yearago

Reply

ThecolumndriverisdriveonlyONEcolumnatanyonetime,sothecurrent
(/member/fredkylam/)
loadshouldnotbemorethan8X15mAor120mA.Itseemsthatonedriver

shouldsufficetodriveanynumberofcolumns.Isthiscorrect?
flag

MCUman(/member/MCUman/)

2yearsago

LEDmatrixusingshiftregisters bybarney_1(/member/barney_1/)

Reply

IrecentlysawthiswrittenupinEDN.Itbegstwoquestions.Isthelatchreally
needed?WhatisthecostofthisHEF4794?GiventhePOVofthehumaneye
(/member/MCUman/)
versusthespeedofamicrocontroller,Ihaveneverseenthisasaproblem
Download(/id/LEDmatrixusingshiftregisters/?download=pdf)
(/id/LEDmatrixusingshiftregisters/)
usingaoldtrusty74HC164,which,BTW,drivesLEDSverynicely.Thecostof
theHC164isconsiderablycheaperoverthecostofthe4794by$2.00.How
Collection
IMadeit!
doIknowthis?I'veusedtheHC164inthismodefornumeroussuccessful
designsthathavegonetoproduction,fromtoystomedicaldevices.Thisa
greatarticletodemonstratetotheHEF4794butisittrulypractical?
flag

JHSTUBA(/member/JHSTUBA/)

2yearsago

Reply

Isthe10kresistornescessary?
(/member/JHSTUBA/)

flag

(/contest/letitglow/)

7Steps
Favorite

Share

Kamilon(/member/Kamilon/)

2yearsago

Reply

I'vebeenworkingonaverylargeLEDmatrixmyself.Ifanyonewantstoseea
matrixthatallowsfordirectdrive(eachLEDindividuallycontrolled),checkthis
(/member/Kamilon/)
out:
http://blog.kamilon.com/?page_id=114
Welldoneonthistutorial.Youcancreateasmallmatrixformuchcheaper
thanbuyingonebyfollowingyourinstructions.
flag

jigs859(/member/jigs859/)

3yearsago

Reply

imdoingthisproject....butadditioninthis,imuseagsmmodulewhich
receivesthemessagesendbyanycellphone,anditdisplaythemessageon
(/member/jigs859/)
theleddisplay...soineedCIRCUITDIAGRAMandCODEforthisproject....plz
helpmesoon...
flag

samwhiteUK(/member/samwhiteUK/) jigs859

2yearsago

Reply

Basicallyyouwantsomeoneelsetodoyourprojectforyouthendon't
you?You'lllearnalotmorebydoingtheresearchandthegraft
(/member/samwhiteUK/)
yourself.
flag

'earl(/member/%27earl/)

3yearsago

Reply

Shouldbe"clamp"Justsaying.
(/member/%27earl/)

flag

eriknyquist(/member/eriknyquist/)

3yearsago

Reply

IwanttobuildsomethinglikethisbutI'venoticedthatmostoftheexamplesof
codethatI'vefoundforLEDdrivingprogramsarewritteninanassembly
(/member/eriknyquist/)
language.Isthereareasonforthat?wouldliketoavoiditifpossible...
flag

axeman911(/member/axeman911/)

3yearsago

Reply

howdouuploadcodeinC++tothearduino???
(/member/axeman911/)

kimchhour(/member/kimchhour/)

flag

3yearsago

Reply

Hisirineedtomakeboardformatrix832.
(/member/kimchhour/)

Avadhut.Deshmukh(/member/Avadhut.Deshmukh/)

flag

4yearsago

Reply

Atmega16?codeHelpPLZ
(/member/Avadhut.Deshmukh/)

shanakaplus(/member/shanakaplus/)

flag

4yearsago

Reply

I'musingcadsofteaglesoftware.Icouldnotfindhef4794shiftregister.can
youhelpmetofindineagle?
(/member/shanakaplus/)
flag

avanner77(/member/avanner77/) shanakaplus

4yearsago

Reply

or,iftheydontmatchup,youcanmakeyourownpartwiththistutorial:
http://www.sparkfun.com/tutorials/110
(/member/avanner77/)
flag

avanner77(/member/avanner77/) shanakaplus

4yearsago

Reply

ifyoucheckthedatasheetsforthehef4794andthe74hc595,youcan
seeiftheyhavethesamepinoutandjustusetheeaglepartforthe595
(/member/avanner77/)
flag

EmilianoValencia(/member/Emiliano+Valencia/)

4yearsago

Reply

hi,imreallyinterestedinthisproject,speciallyinthe16x16array,butIwantto
useitwithanarduino,andalso,thateachLEDisindividuallyaddressable
(/member/Emiliano+Valencia/)
(meaningthatthecodeshuldhaveaplacewithlineswiththetext
"B00000000,x32"andthateachlinehasatotalof2560(Whichcanbe
changedto1tomaketleLEDlightup)soeachlinewouldbeanewframewith
everyLEDindividuallyaddressable.
TheproblemisthatImkindanewwithmicrocontrollersandcan'twritethe
code,WherecanIgetit??canyouhelpmewriteit??
plzhelp,
reallyinterestedinurproject.
Thanks.
flag

sun580(/member/sun580/)

4yearsago

Reply

thanksitsgood
(/member/sun580/)

kalasas18(/member/kalasas18/)

flag

4yearsago

IhaveasimpleASMprogramwithamatrixdisplaylightjustcolumns.An
(/member/kalasas18/)
example:

LISTP=16F876
#include<p16F876.inc>
__CONFIG_CP_OFF&_WDT_OFF&_PWRTE_ON&_XT_OSC
ORG0x2100
DE0x00
ORG0

cblock0x20
d1
d2
d3
endc
gotostart
Delay
999990cycles
movlw0x07
movwfd1
movlw0x2F
movwfd2
movlw0x03
movwfd3
Delay_0
decfszd1,f
goto$+2
decfszd2,f
goto$+2
decfszd3,f
gotoDelay_0
6cycles
goto$+1
goto$+1
goto$+1
4cycles(includingcall)
return
loop:
movlwb'00000111'
movwfPORTA
movlwb'11110010'
movwfPORTB
movlwb'11111111'
movwfPORTC
callDelay
callDelay
callDelay
gotoloop
start:

Reply

bsfSTATUS,RP0selectregisterpage1
movlw0put0intoW
movwfTRISCsetportCalloutput
clrfTRISA
clrfTRISB
bsfSTATUS,RP1selectPage2,
bcfSTATUS,RP0bysettingRP1inStatusregisterandclearingRP0
clrfPORTCselectDigitalI/OonportC

bcfSTATUS,RP1backtoRegisterPage0
gotoloop
end

ThisprogramcodeisOK.ButIwanttheprogramtowhichIcoulddisplaythe
wordsfleeingacrossthescreen.Started,Itriedtoigniteapairofcolumnson
differentsitesbutwiththeburningLEDs.Butreceivedsomestrangeflashing,
donotlightlonger...Anybodyknowwhat'swrong...
Programmecode:

LISTP=16F876
#include<p16F876.inc>
__CONFIG_CP_OFF&_WDT_OFF&_PWRTE_ON&_XT_OSC
ORG0x2100
DE0x00
ORG0

cblock0x20
Delay1delayloop1
Delay2delayloop2
Delay3delayloop3
TimeDelaytimedelayx0.001s
EndCountusedtotellPICtheendofthetableisreached
Counterusedastablecounter
Line1Line1
Line2Line2
Line3Line3
Line4Line4
Line5Line5
sad
Line6Line6
Line7Line7
Line8Line8
Layer4brightness,andtime
BrightnessLEDbrightness
Timetimeforeachpatterntostay
Temptempregister
d1
d2
d3
endc

gotostart
Delay
999990cycles
movlw0x17
movwfd1
movlw0x2F
movwfd2
movlw0x03
movwfd3
Delay_0
decfszd1,f
goto$+2
decfszd2,f
goto$+2
decfszd3,f
gotoDelay_0
6cycles
goto$+1
goto$+1

goto$+1
4cycles(includingcall)
return
loop:
movlwb'00000001'
movwfLine1
movlwb'11110010'
movwfLine2
calloutput

callDelay
movlwb'11100000'
movwfLine1
movlwb'10101010'
movwfLine2
calloutput
callDelay
gotoloop

start:
bsfSTATUS,RP0selectregisterpage1
movlw0put0intoW
movwfTRISCsetportCalloutput
clrfTRISA
clrfTRISB
bsfSTATUS,RP1selectPage2,
bcfSTATUS,RP0bysettingRP1inStatusregisterandclearingRP0
clrfPORTCselectDigitalI/OonportC
bcfSTATUS,RP1backtoRegisterPage0
gotoloop

output:
movfwLayer4
andlwb'00000001'
movwfTime
incfTime,1
bcfSTATUS,C
rlfTime,1
bcfSTATUS,C
rlfTime,1
bcfSTATUS,C
rlfTime,1
bcfSTATUS,C
rlfTime,1
bcfSTATUS,C
rlfTime,1

clrfPORTBclearportB
movfwLine1movelayer1toW
movwfPORTCputWontoPortC
bsfPORTB,4turnonlayer1buyoutputingbit5ofPortB
movfwBrightnessputbrightnessintoW
callDelayycallthedelay
bcfPORTB,4turnofflayer1
movfwBrightnessputBrightnessintoW
sublw4subWfrom4
btfssSTATUS,Zskipifthezeroflagisset
callDelayycallthedelay
decfszTime
clrfPORTBclearportB
movfwLine2moveLine2toW
movwfPORTCputWontoPortC
bsfPORTB,5turnonlayer2buyoutputingbit6ofPortB

movfwBrightnessputbrightnessintoW
callDelayycallthedelay
bcfPORTB,5turnofflayer2
movfwBrightnessputBrightnessintoW
sublw4subWfrom4
btfssSTATUS,Zskipifthezeroflagisset
callDelayycallthedelay
decfszTime
decfszTimedecrementtheTimeregiester
return

Delayy:
movwfDelay3putWintoDelay3
Loop1:
AfterDelay2decresesto0,itisresetto..
movlw0x1put1intoW
movwfDelay2putWintoDelay2
Loop2:
AfterDelay1decresesto0,itisresettoE9h
movlw0x1Dput80intoW
movwfDelay1putWintoDelay1
Loop3:
decfszDelay1decrementDelay1
gotoLoop3jumpbacktoLoop3
decfszDelay2decrementDelay2
gotoLoop2jumpbacktoLoop2
decfszDelay3decrementDelay3
gotoLoop1jumpbacktoLoop1
return
end

Thanksforhelp.:)
flag

ca.le(/member/ca.le/)

4yearsago

Reply

DoesanyoneknowifthematrixwouldworkwithanArduinoboard????
(/member/ca.le/)

ji394su3(/member/ji394su3/)

flag

4yearsago

Reply

goodarticle!!
(/member/ji394su3/)

pavanbhushan(/member/pavanbhushan/)

flag

4yearsago

Reply

whatistheadditionalconnectionthatshouldbemadetomaketheLEDsglow
individualletters???
(/member/pavanbhushan/)
flag

pavanbhushan(/member/pavanbhushan/)

4yearsago

Reply

howcanwemakethe8*8leddisplaytheletters????I'mstuckatthispoint...
(/member/pavanbhushan/)

Suresh.D.M(/member/Suresh.D.M/)

flag

4yearsago

Reply

canweaddshiftregisterstothecolumnandshiftthebit
(/member/Suresh.D.M/)

pontikakis3(/member/pontikakis3/)

flag

4yearsago

Reply

WhereistheFontSetathttp://en.radzio.dxp.pl/ks0108/??Anthony
(/member/pontikakis3/)

DanielIt(/member/DanielIt/)

flag

5yearsago

Reply

Heythere..niceproject,easytoacomplishandlotofstufftolearn.Nowthatiam
learningC,ienlargedtheprojecttobe8x32columns,buticantgetthecodeto
(/member/DanielIt/)
work.Anyhintswherearethepartsthatneedstobeworked?Therearesome
partsinthecodecommentedthatneedtobealtered,buticantfigureout
how.IfyoucanjelpplssendmeanPM,orustreplyhere.
Thank'sandkeepupthegoodwork!!
flag

dhimullai(/member/dhimullai/) DanielIt

5yearsago

Reply

Hi
Itootriedwithexpanding8x32,itdoesn'tworksasexpected.,Anyone
(/member/dhimullai/)
canhelpme,
flag

knektek(/member/knektek/)

5yearsago

Reply

Couldyouuseawholeloadoftransistors?Forswitchingsomethingelse?
Maybeanarrayofmotorsorswitchingrelays?
(/member/knektek/)
flag

greekwow(/member/greekwow/)

5yearsago

Reply

doestheledshavegoodbrighness?thereisnotproblemwithdutycycle?
becouseihavethatprobleminmyproject,(iuse4017decadecounter)
(/member/greekwow/)
flag

ndinitz(/member/ndinitz/)

5yearsago

Reply

canthisbedoneusingparallelloadshiftregistersordoesithavetobedone
withserialload.
(/member/ndinitz/)
ifitistobedoablewithparallelloadregistersthentheboarddoesnthaveto
displayonlyonecolumnatatime,right?thatwouldbesomuchcoolerand
youcouldbuildmodulesandconnectthemwithparallelinserialouttoserialin
parallelout.
lemeknowwhatyouthink...
flag

rammbo69(/member/rammbo69/)

5yearsago

Reply

Bothare20pF.
(/member/rammbo69/)

malth91(/member/malth91/)

flag

5yearsago

Reply

averyinformativeandinterestingsite
(/member/malth91/)

roketlights(/member/roketlights/)

flag

5yearsago

Reply

whatarevaluesforc2andc3?????imrelyingentirelyonthis!!please?igot
everythingbutthispartandtheprogramingpart.pleasehelp!!!
(/member/roketlights/)
flag

jeffo(/member/jeffo/)

5yearsago

Reply

Justtoclarify,couldIprograminabunchofphrases(like,3040)andcallup
anyoneofthembasedoncertaininputs?Whatisthelimitonphraselength
(/member/jeff
o/) withoutanyexternalmemory?
flag

roketlights(/member/roketlights/)

5yearsago

Reply

ijustboughtabuttloadofregisters.imtryingtomakea32x32anypointers?
onhowtoconnect8x8inrowsandcolumns?anyhelpwouldbeapprecieated.
(/member/roketlights/)
:)
flag

hype1(/member/hype1/)

5yearsago

Reply

IamlookingintoyoursetupandInoticedthis:Whydoyouusesuchadriver
onthehighsidewhenyouarelightingonecolumnatthetimeduring
(/member/hype1/)
multiplexing?Nowyoucouldsourcerowsof8LED'satonetime,butthatisn't
thecasewhilemultiplexing,right?
flag

monkeydluffy(/member/monkeydluffy/)

6yearsago

Reply

brobarney,canuhelpmetogetHEF4794?ineedtheHEF4794??9ofthem
tocontrollmySolarDisplay.Inmycountrythere'snostoresellthatshift
(/member/monkeydluffy/)
register:(:(CanIgetitfromu??I'llpayitlater.I'minJakarta,Indonesia.
Pleasehelpmemaster,thisisformygraduationproject.thankyouverymuch
:)
flag

ndegwa(/member/ndegwa/)

6yearsago

Reply

Ineedhelpprogrammingthemicrocontrollercouldyoupleasehelpiwould
likemydisplaytoscrollthefollowingNBI..............VOI.............MBSoverand
(/member/ndegwa/)
overandcanalsobemadetostopatoneofthelettersshown.
flag

CallumSnowden(/member/Callum+Snowden/)

6yearsago

Reply

CouldyouuseaMAX232toconnectittoacomputer?
(/member/Callum+Snowden/)

140of
130

flag

Next(http://www.instructables.com/id/LEDmatrixusingshiftregisters/?
&sort=ACTIVE&limit=40&offset=40#DISCUSS)

Wehaveabenicecommentpolicy.
Pleasebepositiveandconstructive.

IMadeit!

AboutUs

AddImages

MakeComment

FindUs

WhoWeAre(/about/)

Facebook(http://www.facebook.com/instructables)

Advertise(/advertise/)

Youtube(http://www.youtube.com/user/instructablestv)

Contact(/about/contact.jsp)

Twitter(http://www.twitter.com/instructables)

Jobs(/community/PositionsavailableatInstructables/)
Help(/id/howtowriteagreatinstructable/)

Pinterest(http://www.pinterest.com/instructables)
Google+(https://plus.google.com/+instructables)
Tumblr(http://instructables.tumblr.com)

Resources

Mobile

ForTeachers(/teachers/)

DownloadournewappsforiOS,

ArtistsinResidence(http://www.autodesk.com/artistinresidence/home)
Join!
Join our newsletter: enteremail
GiftProAccount(/account/give?sourcea=footer)

AndroidandWindows8!

Forums(/community/)
Answers(/tag/typequestion/?sort=RECENT)
TermsofService(http://usa.autodesk.com/adsk/servlet/item?siteID=123112&id=21959721)
|

Android
(https://play.google.com/store/apps/details?
id=com.adsk.instructables)

Sitemap(/sitemap/)
PrivacyStatement(http://usa.autodesk.com/adsk/servlet/item?siteID=123112&id=21292079) |
LegalNotices&Trademarks(http://usa.autodesk.com/legalnoticestrademarks/) | MobileSite(http://m.instructables.com)
(http://usa.autodesk.com/adsk/servlet/pc/index?id=20781545&siteID=123112)
2015Autodesk,Inc.

iOS
(https://itunes.apple.com/app/instructables/id586765571)
Windows
(http://apps.microsoft.com/windows/en
us/app/7afc8194c771441a9590
54250d6a8300)

GoProToday(/account/gopro?sourcea=footer)

We'reHiring!(/community/PositionsavailableatInstructables/)

You might also like