Created
November 11, 2014 15:45
-
-
Save electricimp/93e20924417f50361e5f to your computer and use it in GitHub Desktop.
Squirrel class for 8x8 LED matrix displays driven by the MAX7219 controller
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MAX7219 | |
{ | |
// Squirrel class for 8x8 LED matrix displays driven by the MAX7219 controller | |
// For example: https://www.sparkfun.com/products/11861 | |
// Communicates with any imp GPIO (three pins) | |
// Written by Tony Smith (@smittytone) Jume 2014 | |
// Version 1.0 | |
MAX7219_REGISTER_BCD = 0x09 | |
MAX7219_REGISTER_BRIGHT = 0x0A | |
MAX7219_REGISTER_SCAN = 0x0B | |
MAX7219_REGISTER_PWR_MODE = 0x0C | |
MAX7219_REGISTER_TEST_MODE = 0x0F | |
// Define the Ascii character set | |
charset = [ | |
[0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0], // Space - Ascii 32 | |
[0x0,0x10,0x10,0x10,0x10,0x0,0x10,0x0], // ! | |
[0x0,0x24,0x24,0x0,0x0,0x0,0x0,0x0], // ” | |
[0x0,0x24,0x7E,0x24,0x24,0x7E,0x24,0x0], // # | |
[0x0,0x8,0x3E,0x28,0x3E,0xA,0x3E,0x8], // $ | |
[0x0,0x62,0x64,0x8,0x10,0x26,0x46,0x0], // % | |
[0x0,0x10,0x28,0x10,0x2A,0x44,0x3A,0x0], // & | |
[0x0,0x8,0x10,0x0,0x0,0x0,0x0,0x0], // ‘ | |
[0x0,0x4,0x8,0x8,0x8,0x8,0x4,0x0], // ( | |
[0x0,0x20,0x10,0x10,0x10,0x10,0x20,0x0], // ) | |
[0x0,0x0,0x14,0x8,0x3E,0x8,0x14,0x0], // * | |
[0x0,0x0,0x8,0x8,0x3E,0x8,0x8,0x0], // + | |
[0x0,0x0,0x0,0x0,0x0,0x8,0x8,0x10], // , | |
[0x0,0x0,0x0,0x0,0x3E,0x0,0x0,0x0], // - | |
[0x0,0x0,0x0,0x0,0x0,0x18,0x18,0x0], // . | |
[0x0,0x2,0x4,0x8,0x10,0x20,0x40,0x0], // / | |
[0x0,0x3C,0x46,0x4A,0x52,0x62,0x3C,0x0], // 0 - Ascii 48 | |
[0x0,0x30,0x50,0x10,0x10,0x10,0x7C,0x0], // 1 | |
[0x0,0x3C,0x42,0x2,0x3C,0x40,0x7E,0x0], // 2 | |
[0x0,0x3C,0x42,0xC,0x2,0x42,0x3C,0x0], // 3 | |
[0x0,0x8,0x18,0x28,0x48,0x7E,0x8,0x0], // 4 | |
[0x0,0x7E,0x40,0x7C,0x2,0x42,0x3C,0x0], // 5 | |
[0x0,0x3C,0x40,0x7C,0x42,0x42,0x3C,0x0], // 6 | |
[0x0,0x7E,0x2,0x4,0x8,0x10,0x10,0x0], // 7 | |
[0x0,0x3C,0x42,0x3C,0x42,0x42,0x3C,0x0], // 8 | |
[0x0,0x3C,0x42,0x42,0x3E,0x2,0x3C,0x0], // 9 | |
[0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x0], // : - Ascii 58 | |
[0x0,0x0,0x10,0x0,0x0,0x10,0x10,0x20], // | |
[0x0,0x0,0x4,0x8,0x10,0x8,0x4,0x0], // < | |
[0x0,0x0,0x0,0x3E,0x0,0x3E,0x0,0x0], // = | |
[0x0,0x0,0x10,0x8,0x4,0x8,0x10,0x0], // > | |
[0x0,0x3C,0x42,0x4,0x8,0x0,0x8,0x0], // ? | |
[0x0,0x3C,0x4A,0x56,0x5E,0x40,0x3C,0x0], // @ | |
[0x0,0x3C,0x42,0x42,0x7E,0x42,0x42,0x0], // A - Ascii 65 | |
[0x0,0x7C,0x42,0x7C,0x42,0x42,0x7C,0x0], // B | |
[0x0,0x3C,0x42,0x40,0x40,0x42,0x3C,0x0], // C | |
[0x0,0x78,0x44,0x42,0x42,0x44,0x78,0x0], // D | |
[0x0,0x7E,0x40,0x7C,0x40,0x40,0x7E,0x0], // E | |
[0x0,0x7E,0x40,0x7C,0x40,0x40,0x40,0x0], // F | |
[0x0,0x3C,0x42,0x40,0x4E,0x42,0x3C,0x0], // G | |
[0x0,0x42,0x42,0x7E,0x42,0x42,0x42,0x0], // H | |
[0x0,0x7C,0x10,0x10,0x10,0x10,0x7C,0x0], // I | |
[0x0,0x2,0x2,0x2,0x2,0x42,0x3C,0x0], // J | |
[0x0,0x44,0x48,0x70,0x48,0x44,0x42,0x0], // K | |
[0x0,0x40,0x40,0x40,0x40,0x40,0x7E,0x0], // L | |
[0x0,0x42,0x66,0x5A,0x42,0x42,0x42,0x0], // M | |
[0x0,0x42,0x62,0x52,0x4A,0x46,0x42,0x0], // N | |
[0x0,0x3C,0x42,0x42,0x42,0x42,0x3C,0x0], // O | |
[0x0,0x7C,0x42,0x42,0x7C,0x40,0x40,0x0], // P | |
[0x0,0x3C,0x42,0x42,0x52,0x4A,0x3C,0x0], // Q | |
[0x0,0x7C,0x42,0x42,0x7C,0x44,0x42,0x0], // R | |
[0x0,0x3C,0x40,0x3C,0x2,0x42,0x3C,0x0], // S | |
[0x0,0x7C,0x10,0x10,0x10,0x10,0x10,0x0], // T | |
[0x0,0x42,0x42,0x42,0x42,0x42,0x3C,0x0], // U | |
[0x0,0x42,0x42,0x42,0x42,0x24,0x18,0x0], // V | |
[0x0,0x42,0x42,0x42,0x42,0x5A,0x24,0x0], // W | |
[0x0,0x42,0x24,0x18,0x18,0x24,0x42,0x0], // X | |
[0x0,0x44,0x28,0x10,0x10,0x10,0x10,0x0], // Y | |
[0x0,0x7E,0x4,0x8,0x10,0x20,0x7E,0x0], // Z - Ascii 90 | |
[0x0,0xE,0x8,0x8,0x8,0x8,0xE,0x0], // [ | |
[0x0,0x0,0x40,0x20,0x10,0x8,0x4,0x0], // \ | |
[0x0,0x70,0x10,0x10,0x10,0x10,0x70,0x0], // ] | |
[0x0,0x10,0x38,0x54,0x10,0x10,0x10,0x0], // ^ | |
[0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFF], // _ | |
[0x0,0x1C,0x22,0x78,0x20,0x20,0x7E,0x0], // £ | |
[0x0,0x0,0x38,0x4,0x3C,0x44,0x3C,0x0], // a - Ascii 97 | |
[0x0,0x40,0x40,0x78,0x44,0x44,0x78,0x0], // b | |
[0x0,0x0,0x38,0x40,0x40,0x40,0x38,0x0], // c | |
[0x0,0x4,0x4,0x3C,0x44,0x44,0x3C,0x0], // d | |
[0x0,0x0,0x38,0x44,0x78,0x40,0x3C,0x0], // e | |
[0x0,0x30,0x40,0x60,0x40,0x40,0x40,0x0], // f | |
[0x0,0x3C,0x44,0x44,0x3C,0x4,0x38,0x0], // g | |
[0x0,0x40,0x40,0x40,0x78,0x44,0x44,0x0], // h | |
[0x0,0x20,0x0,0x60,0x20,0x20,0x70,0x0], // i | |
[0x0,0x8,0x0,0x8,0x8,0x48,0x30,0x0], // j | |
[0x0,0x40,0x50,0x60,0x60,0x50,0x48,0x0], // k | |
[0x0,0x40,0x40,0x40,0x40,0x40,0x30,0x0], // l | |
[0x0,0x0,0x68,0x54,0x54,0x54,0x54,0x0], // m | |
[0x0,0x0,0x78,0x44,0x44,0x44,0x44,0x0], // n | |
[0x0,0x0,0x38,0x44,0x44,0x44,0x38,0x0], // o | |
[0x0,0x78,0x44,0x44,0x78,0x40,0x40,0x0], // p | |
[0x0,0x3C,0x44,0x44,0x3C,0x4,0x6,0x0], // q | |
[0x0,0x0,0x1C,0x20,0x20,0x20,0x20,0x0], // r | |
[0x0,0x0,0x38,0x40,0x38,0x4,0x78,0x0], // s | |
[0x0,0x20,0x70,0x20,0x20,0x20,0x18,0x0], // t | |
[0x0,0x0,0x44,0x44,0x44,0x44,0x38,0x0], // u | |
[0x0,0x0,0x44,0x44,0x28,0x28,0x10,0x0], // v | |
[0x0,0x0,0x44,0x54,0x54,0x54,0x28,0x0], // w | |
[0x0,0x0,0x44,0x28,0x10,0x28,0x44,0x0], // x | |
[0x0,0x0,0x44,0x44,0x3C,0x4,0x38,0x0], // y | |
[0x0,0x0,0x7C,0x8,0x10,0x20,0x7C,0x0], // z - Ascii 122 | |
[0x0,0xE,0x8,0x30,0x8,0x8,0xE,0x0], // { | |
[0x0,0x8,0x8,0x8,0x8,0x8,0x8,0x0], // | | |
[0x0,0x70,0x10,0xC,0x10,0x10,0x70,0x0], // } | |
[0x0,0x14,0x28,0x0,0x0,0x0,0x0,0x0], // ~ | |
[0x3C,0x42,0x99,0xA1,0xA1,0x99,0x42,0x3C], // © - Ascii 127 | |
[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF], // Block Graphic 1 | |
[0xF,0xF,0xF,0xF,0xFF,0xFF,0xFF,0xFF], | |
[0xF0,0xF0,0xF0,0xF0,0xFF,0xFF,0xFF,0xFF], | |
[0x0,0x0,0x0,0x0,0xFF,0xFF,0xFF,0xFF], | |
[0xFF,0xFF,0xFF,0xFF,0xF,0xF,0xF,0xF], | |
[0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF], | |
[0xF0,0xF0,0xF0,0xF0,0xF,0xF,0xF,0xF], | |
[0x0,0x0,0x0,0x0,0xF,0xF,0xF,0xF], | |
[0xFF,0xFF,0xFF,0xFF,0x55,0xAA,0x55,0xAA], | |
[0xAA,0x55,0xAA,0x55,0xFF,0xFF,0xFF,0xFF], | |
[0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55], // Block Graphic 11 | |
] | |
// Display Properties | |
clk = null | |
din = null | |
cs = null | |
inverseVideoFlag = false | |
rotateMatrixFlag = false | |
// Set the number of characters in your character set | |
_alphaCount = 107 | |
constructor(clockPin, dataPin, selectPin, shouldRotate = false) | |
{ | |
clk = clockPin | |
din = dataPin | |
cs = selectPin | |
// Set these pins as digital outputs | |
clk.configure(DIGITAL_OUT) | |
cs.configure(DIGITAL_OUT) | |
din.configure(DIGITAL_OUT) | |
// Set screen rotation flag | |
rotateMatrixFlag = shouldRotate | |
} | |
function init() | |
{ | |
// Initialise the MAX7219’s parameter registers by writing | |
// the register’s address followed by its 8-bit value | |
// Address and data values from the Maxim Integrated MAX7219 Datasheet: | |
// http://www.maximintegrated.com/datasheet/index.mvp/id/1339 | |
write(MAX7219_REGISTER_BCD, 0x00) // Set MAX7219’s BCD decode mode to ‘none’ | |
write(MAX7219_REGISTER_BRIGHT, 0x02) // Set MAX7219’s LED intensity to a 5/32 duty cycle | |
write(MAX7219_REGISTER_SCAN, 0x07) // Set MAX7219’s scan limit to all eight LED columns | |
write(MAX7219_REGISTER_PWR_MODE, 0x01) // Set MAX7219’s power mode. 0 = power down, 1 = normal | |
write(MAX7219_REGISTER_TEST_MODE, 0x00) // Set MAX7219’s display test mode off | |
} | |
function writeByte(byteVal) | |
{ | |
// Writes a single byte of data to the MAX7219 display controller one bit at a time. | |
// Writes data to the LED in the MAX7219’s 16-bit serial format, which puts the | |
// register address in the first eight bits then the data in the second set of eight bits. | |
for (local i = 8 ; i > 0 ; i--) | |
{ | |
clk.write(0) | |
din.write(byteVal & 0x80) // Extract bit 8 and write it to the LED | |
byteValue = byteVal << 1 // Shift the data bits left by one bit | |
clk.write(1) | |
} | |
} | |
function write(RegAddress, value) | |
{ | |
// Writes a single value to the MAX7219, preceded by the register | |
// it is being written to | |
cs.write(0) | |
writeByte(RegAddress) | |
writeByte(value) | |
cs.write(1) | |
} | |
function clearDisplay() | |
{ | |
displayLine(" ") | |
} | |
function displayIcon(inputMatrix = [0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF]) | |
{ | |
inputMatrix = rotateMatrix(inputMatrix) | |
for (local k = 0 ; k < 8 ; k++) | |
{ | |
if (inverseVideoFlag) | |
{ | |
write(k + 1, ~inputMatrix[k]) | |
} | |
else | |
{ | |
write(k + 1, inputMatrix[k]) | |
} | |
} | |
} | |
function displayChar(asciiVal = 32) | |
{ | |
asciiVal = asciiVal - 32 | |
if (asciiVal < 0 || asciiVal > _alphaCount) asciiVal = 0 | |
local inputMatrix = clone(charset[asciiVal]) | |
inputMatrix = rotateMatrix(inputMatrix) | |
for (local k = 0 ; k < 8 ; k++) | |
{ | |
if (inverseVideoFlag == 1) | |
{ | |
write(k + 1, ~inputMatrix[k]) | |
} | |
else | |
{ | |
write(k + 1, inputMatrix[k]) | |
} | |
} | |
} | |
function displayLine(line = "No text entered") | |
{ | |
// Bit-scroll through the characters in the variable ‘line’ | |
local a = 0 | |
local b = 0 | |
local count = 0 | |
local outputMatrix = [0,0,0,0,0,0,0,0] | |
local matrixOne = [0,0,0,0,0,0,0,0] | |
local matrixTwo = [0,0,0,0,0,0,0,0] | |
count = line.len() | |
if (count == 1) | |
{ | |
count = 2 | |
line = " " + line | |
} | |
for (local k = 0 ; k < (count - 1) ; k++) | |
{ | |
// Run through the line character by character up to the penultimate character | |
// Get the current character to be displayed and the next character along by | |
// copying them from the character set array | |
a = line[k] | |
b = line[k + 1] | |
matrixOne = clone(charset[a - 32]) | |
matrixTwo = clone(charset[b - 32]) | |
for (local j = 0 ; j < 8 ; j++) | |
{ | |
// We use two character matrices, one on the left and one on the right. | |
// Line by line, we shift the left matrix's bit pattern one bit at a time. | |
// If the seventh bit of a line in the right-hand matrix is set, | |
// we then set bit 0 of the left-hand matrix. | |
// We then shift the right-hand matrix leftward one bit. | |
outputMatrix = matrixOne | |
outputMatrix = rotateMatrix(outputMatrix) | |
for (local i = 0 ; i < 8 ; i++) | |
{ | |
// Write the current character’s matrix | |
if (inverseVideoFlag) | |
{ | |
write(i + 1, ~outputMatrix[i]) | |
} | |
else | |
{ | |
write(i + 1, outputMatrix[i]) | |
} | |
// Use the Logical Shift Left operator to move the line one pixel | |
matrixOne[i] = matrixOne[i] << 1 | |
// Move over second matrix by one pixel | |
if ((matrixTwo[i] & 128) > 0) | |
{ | |
// If bit 7 of the right-hand character’s line is set, | |
// carry it over to bit 0 of the left-hand character | |
matrixOne[i] = matrixOne[i] | (1 << 0) | |
} | |
// Shift right-hand character line left one pixel | |
matrixTwo[i] = (matrixTwo[i] << 1) | |
} | |
imp.sleep(0.04) | |
} | |
} | |
// For the final character, we need to perform a last pixel shift to leave | |
// the character completely on the display | |
outputMatrix = matrixOne | |
outputMatrix = rotateMatrix(outputMatrix) | |
for (local i = 0 ; i < 8 ; i++) | |
{ | |
if (inverseVideoFlag) | |
{ | |
write(i + 1, ~outputMatrix[i]) | |
} | |
else | |
{ | |
write(i + 1, outputMatrix[i]) | |
} | |
matrixOne[i] = matrixOne[i] << 1 | |
if ((matrixTwo[i] & 128) > 0) matrixOne[i] = matrixOne[i] | (1 << 0) | |
matrixTwo[i] = (matrixTwo[i] << 1) | |
} | |
imp.sleep(0.04) | |
} | |
function rotateMatrix(inputMatrix) | |
{ | |
// Only rotate the matrix if rotate_matrix_flag has not been set | |
if (rotateMatrixFlag == false) return inputMatrix | |
// Rotate the character matrix through 90 degrees anti-clockwise | |
// Used if the LED matrix pins are connected directly to a breadboard | |
local a = 0 | |
local lineValue = 0 | |
local outputMatrix = [0,0,0,0,0,0,0,0] | |
for (local i = 0 ; i < 8 ; i++) | |
{ | |
lineValue = inputMatrix[i] | |
for (local j = 7 ; j > -1 ; j--) | |
{ | |
a = (lineValue & math.pow(2, j).tointeger()) | |
if (a > 0) outputMatrix[7 - j] = outputMatrix[7 - j] + math.pow(2, i).tointeger() | |
} | |
} | |
return outputMatrix | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment