Fork of code for LED panels
This is an Arduino sketch to drive 4 LED panels based on MBI5034 LED drivers.
Written by Oliver Dewdney and Jon Russell from LHS Updated by Courty (SLMS) to fully use the Adafruit GFX lib and Arduino Duemilanove nano
It works specifically on a Arduino Micro (ATMega32U4), as it accesses the registers directly. However, with a small amount of editing, it should work on most Arduinos.
Basic Operation:
The objective was to be able to drive four panels with a single Arduino. Each panel has two data lines, so four panels require 8 data lines, i.e. a single byte.
An Arduino Micro was selected, as it has a native USB port and slightly more RAM than an Uno. A Mega would probably work well too.
The code has a frame buffer in RAM with 4 sets of 384 bits (1 bank = 64 LEDs x 2 Rows x 3 bits (RGB) = 384) for each data line. Four panels, two data lines each, means all four panels can be driven by a byte wide frame buffer, assuming 3 bit colour. This means the update can be very efficient. The frame buffer is about 1.5KB so fits happily in to the ATMega32U4 with some room for local variables.
The UpdateFrame loop iterates over the line of 384 bits of serial data from the frame buffer and clocks them out quickly.
Ideally, we needed a contiguous port on the Microcontroller to be attached to 8 external data lines for the four panels. But most Arduinos don’t have this. On the Arduino Micro, PortB has the RX LED on bit 0 and PortD has the TX LED on bit 5. So, I have connected 4 data lines to the high nibble on PortB and 4 data lines to the low nibble on PortD.
If we had a contiguous port free (If we used a Mega) we could use only one port and the UpdateFrame loop would be 1 instruction faster ! :-) But currently I copy the data to both ports, ignoring the high and low nibbles I don’t need.
UpdateFrame is called by an interrupt 390 times a second (OCR1A = 160; // compare match register 16MHz/256/390Hz)). UpdateFrame needs to be called 4 times to update the entire panel, as the panel is split in to 4 rows of 128 LEDs (as 2 rows of 64).
For each half a panel (one data line) there are 8 rows of 64 LEDs, addresses in banks. Bank 0x00 is row 0&4, Bank 0x01 is row 1&5, Bank 0x02 is row 2&6, Bank 0x03 is row 3&7.
Each call updates one bank and leaves it lit until the next interrupt.
This method updates the entire frame (1024 RGB LEDs) about 100 times a second.
Port map for Arduino Micro (ATMega32U4) 7 6 5 4 3 2 1 0 PB D11 D10 D9 D8 MISO MOSI SCK RX/SS PC D13 D5 X X X X X X PD D6 D12 TX D4 D1 D0 D2 D3 PE X D7 X X X HWB X X PF A0 A1 A2 A3 X X A4 A5
Courty: ********************************************************************** This sketch now inherits from the Adafruit GFX library classes. This means we can use the graphics functions like drawCircle, drawRect, drawTriangle, plus the various text functions and fonts. ******************************************************************************/