Arduino LED Matrix Control Controlling lots of LEDs
Intro LED basics Matrix-connected LED arrays Example: Lego 10196 Grand Carousel
LED V/I relation V I 3 2.5 diode current vs. voltage 2 Current flows, and the LED emits light, with positive voltage No current (light) with zero or negative voltage diode current (A) 1.5 1 0.5 0-0.5-1 -2-1.5-1 -0.5 0 0.5 1 1.5 2 diode voltage (V)
Using LEDs LEDs can only handle ~2V before damage But Arduino outputs are 5V logic Limit diode voltage and current with a series resistor V can now be 5V without damaging LED; the rest of the voltage drops across the ballast resistor V R I For Vdiode=2V Use: V=5V R=3kΩ I=1mA
Arduino UNO board Atmel AVR microcontroller Power with USB or AC adapter I/O, power pins on headers
Sequence blink Blink LEDs 1 through 6 in a sequential pattern...
Limitations of direct drive Number of LEDs limited to number of I/Os Arduino UNO: 13 digital outputs Ballast resistors are a big hassle Need one resistor per LED But we can get rid of them (more later...)
LED matrix Arrange diodes in a rectangular array: matrix Columns have common anode Rows have common cathode Reduced I/O: 12 lines (not 35)
Display a character =
Matrix LEDs: One diode Key idea #1: a diode only turns on when its anode is high (1) and its cathode is low (0) 0 1 Otherwise the diode is off 0 OFF 0 ON Driving cathode high disables the diode, independent of anode 0 1 1 OFF 1 OFF
Matrix LEDs: One row 0 1 1 1 0 OFF ON ON ON OFF 0 Enable the row by pulling the common cathode low Turn on individual diodes by pulling anodes high
Matrix LEDs: Two rows, first row on 0 1 1 1 0 0 1 Row 1 is enabled (cathode is low), anodes select LEDs Row 2 is off (cathode is high)
Matrix LEDs: Two rows, second row on 1 0 0 0 1 1 0 Row 1 is off (cathode is high) Row 2 is enabled (cathode is low), anodes select LEDs
Persistence of vision If we switch quickly between rows 1 and 2, it looks like they re both active Silicon is way faster than our eyes, so... Key idea #2: Use persistence of vision to scan the whole array Cycle through all the rows in sequence to create the illusion that all selected LEDs are on
Matrix LEDs: Array scan 0 1 1 1 0 1 0 0 0 1 1 0 0 0 1 1 1 1 1 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 Scan seven rows in sequence to make a character Scan fast enough and the eye thinks all the selected LEDs are turned on This is how all displays work: fast cycling through individual lines
Matrix LEDs: Challenges Coding all this is a lot of work Choose bit pattern Binary encode for each scan line Send the code sequences to anode, cathode pins Maintain timing for array scan refresh Change the pixel pattern? Do it all again... A ballast R for each column Better than one for each diode
Arduino example? Arduino 8x8 array example: File Examples 07.Display RowColumnScanning But this is too complicated, there is a simpler way to control LEDs
Adafruit 16x8 LED backpack board Holtek HT16K33 drives up to 16x8 LED matrix = 128 LEDs 3-bit I2C addressable for up to 8 matrices = 1024 LEDs No ballast resistors: current sources drive LEDs directly Four I/Os to Arduino: power, gnd, clock, data https://www.adafruit.com/product/1427 - $6
Breakout board demo Adafruit demo board with 16x8 LED array Sparkfun StemTera board integrates an Arduino board into a protoboard Only need power, ground, SCL (clock), SDA (data) from Arduino
Adafruit HT16K33 Arduino API The whole reason to use the backpack board API manages pixels, not hardware Draw dots, lines, rectangles Scroll text Dump bitmap pictures
Lego 10196 Carousel The stock model, with invisible(*) upgrades (*) Replaced center column mirrors with light columns
Carousel Electronics Block Diagram Slip ring allows electrical continuity through a rotating joint
Core column LEDs An Anode column
Carousel core LED matrix schematic Each An line goes to a 8-LED column in the core 12 of 16 possible columns used
Core HT16K33 board 12 of 16 possible columns used Not shown: set I2C address to 0x70
Crown section LEDs C4 C3 C4 C2 C2 C5 C0 C1 C5 C0 C1 Odd anode column Even anode column
Carousel crown LED matrix schematic Each An line goes to a 5 (or 6) LED section of the crown Missing C3 LED on odd columns is at the top (at beard deco)
Crown HT16K33 board 6 of 8 possible rows used Not shown: set I2C address to 0x71
Carousel Arduino code Setup: create two Matrix objects Variables: bitmaps for diagonal stripes, pseudorandom pattern Loop patterns All on All on / all off blink Core horizontal line crawl = crown loops Diagonal stripes (bitmap) Pseudorandom (bitmap) All off
References Adafruit LED driver breakout board, Arduino drivers https://www.adafruit.com/product/1427 Carousel blog post https://blog.adafruit.com/2017/04/11/lego-grand-carousel-with-ht16k33- breakout-leds-slip-ring-upgrade/ Sparkfun StemTera https://www.sparkfun.com/products/14083 Snappable protoboard https://www.sparkfun.com/products/13268 Matrix tutorial http://embedded-lab.com/blog/lab-12-basics-of-led-dot-matrix-display/
References Video demo https://youtu.be/bwpxw-rt0cw Brickshelf gallery, Arduino source http://www.brickshelf.com/cgi-bin/gallery.cgi?f=569208 Flickr https://www.flickr.com/photos/timrueger/ Demo slideshow PDF http://www.timrueger.net/docs/lego_10196_grand_carousel_with_arduino_leds.pdf