LOL Shield Interface
LOL Shield Interface
Even now, after years of working within this industry, LEDs have a fascination to me. And an LED matrix is something that I can't wait to try out. A LOL Shield (Lots Of LEDs shield) for an Arduino board was purchased and I set to work creating a Charlieplexed interface for it from the Amicus18 board, which will physically accept any Arduino shield, and allows programs to be written in Positron8 BASIC, so they are easy to write and understand.
The LOL Shield is shown below:
All the LEDs on the board are white, and the matrix needs to be interfaced via a Charlieplex. A Charlieplex interface is very straightforward, and works because of the physics required for an LED to work. Its operation can be examined from here: https://en.wikipedia.org/wiki/Charlieplexing
The circuit for the LOL Shield is shown below:
As can be seen from the above circuit, the LEDs are arranged in, what looks like, a standard matrix. However, there are 126 LEDs connected to only 12 pins of the microcontroller. This is what intrigued me to want one for experimentation.
The LED matrix can be operated by routines in an include file. LOLShield.inc. There are several routines that allow the matrix to display graphics and text. These are outlined below:
Note.
The LCD is automatically initialised when the LOLShield.inc file is included into the program.
LOL_Cls
LOL_Cls()
Clear or Set the LED matrix.
Operator.
pColour: The colour of the LED (0 = Off, 1 = On)
Example:
Include "Amicus18.inc" ' Configure the compiler to use a PIC18F25K20 at 64MHz. i.e. An Amicus18 board.
Include "LOLShield.inc" ' Load the LOL shield routines into the program
LOL_Cls(0) ' Clear the LED matrix
LOL_Cursor(0, 0) ' Move to the start of the first line
Print "HW" ' Display some text
LOL_Plot
LOL_Plot(pXpos, pYpos, pColour)
Alter an LED on the LED matrix.
Operators.
pXpos: X position of the pixel (0 to 13)
pYpos: Y position of the pixel (0 to 8)
pColour: The colour of the pixel (0 = Off, 1 = On)
Example:
Include "Amicus18.inc" ' Configure the compiler to use a PIC18F25K20 at 64MHz. i.e. An Amicus18 board.
Include "LOLShield.inc" ' Load the LOL shield routines into the program
Dim bXpos as Byte ' Create a byte sized variable for the X position
Dim bYpos as Byte ' Create a byte sized variable for the Y position
LOL_Cls(0) ' Clear the LED matrix
For bYpos = 0 to 8 ' Form a loop for the Y position
For bXpos = 0 to 13 ' Form a loop for the X position
LOL_Plot(bXpos, bYpos, 1) ' Illuminate an LED at the current Xpos and Ypos
DelayMs 5 ' Slow things down so we can see the LEDs being drawn
Next ' Close the X position loop
Next ' Close the Y position loop
LOL_Pixel
Var = LOL_Pixel(pXpos, pYpos)
Read an LED's condition from the LED matrix.
Operators.
pXpos: X position of the pixel (0 to 13)
pYpos: Y position of the pixel (0 to 8)
Var: Can be a variable of type; Bit, Byte, Word, Dword, or an array.
Example:
Include "Amicus18.inc" ' Configure the compiler to use a PIC18F25K20 at 64MHz. i.e. An Amicus18 board.
Include "LOLShield.inc" ' Load the LOL shield routines into the program
Dim bXpos as Byte ' Create a byte sized variable for the X position
Dim bColour as Byte ' Create a byte sized variable to hold the pixel colour
LOL_Cls(0) ' Clear the LED matrix
For bXpos = 0 to 13 Step 2 ' Create a loop for the X pos with an increment of 8
LOL_Plot(bXpos, 0, 1) ' Illuminate an LED at the current Xpos
Next ' Close the X position loop
'
' Read the pixels and re-display
'
For bXpos = 0 to 13 ' Create a loop for the X position
bColour = LOL_Pixel(bXpos, 0) ' Read an LED's condition from the LED matrix
LOL_Plot(bXpos, 3, bColour) ' Copy the LED back to the matrix
DelayMs 50 ' Slow things down so we can see the LEDs being copied
Next ' Close the X position loop
LOL_Line
LOL_Line(pStartXpos, pStartYpos, pEndXpos, pEndYpos, pColour)
Draw a line on the LED matrix.
Operators.
pStartXpos: Starting X position of the line (0 to 13)
pStartYpos: Starting Y position of the line (0 to 8)
pEndXpos: Ending X position of the line (0 to 13)
pEndYpos: Ending Y position of the line (0 to 8)
pColour: The colour of the line (0 = Off, 1 = On)
Example:
Include "Amicus18.inc" ' Configure the compiler to use a PIC18F25K20 at 64MHz. i.e. An Amicus18 board.
Include "LOLShield.inc" ' Load the LOL shield routines into the program
Dim bEndYpos as Byte ' Create a byte sized variable for ending Y position
LOL_Cls(0) ' Clear the LCD’s screen
For bEndYpos = 0 to 8 ' Form a loop for the ending Y position
LOL_Line(0, 0, 13, bEndYpos, 1) ' Draw a line
Next ' Close the ending Y position loop
LOL_Circle
LOL_Circle(pXpos, pYpos, pRadius, pColour)
Draw a circle on the LED matrix.
Operators.
pXpos: Centre X position of the circle (0 to 13)
pYpos: Centre Y position of the circle (0 to 8)
pRadius: Radius of the circle in pixels (0 to 13)
pColour: The colour of the circle (0 = Off, 1 = On)
Example:
Include "Amicus18.inc" ' Configure the compiler to use a PIC18F25K20 at 64MHz. i.e. An Amicus18 board.
Include "LOLShield.inc" ' Load the LOL shield routines into the program
Dim bRadius as Byte ' Create a byte sized variable for radius of the circle
LOL_Cls(0) ' Clear the LCD’s screen
For bRadius = 0 to 13 ' Create a loop for the radius of the circle
LOL_Circle(7, 4, bRadius, 1) ' Draw a circle
DelayMs 100 ' Slow things down so we can see the circle being drawn
Next ' Close the radius loop
LOL_Cursor
LOL_Cursor(pXpos, pYpos)
Move the text position on the LED matrix, prior to displaying ASCII characters.
Operators.
pXpos: X position of the cursor (0 to 13)
pYpos: Y position (line) of the cursor (0 to 8)
Example:
Include "Amicus18.inc" ' Configure the compiler to use a PIC18F25K20 at 64MHz. i.e. An Amicus18 board.
Include "LOLShield.inc" ' Load the LOL shield routines into the program
LOL_Cls(0) ' Clear the LED matrix
LOL_Cursor(0, 0) ' Move to the start of the first line
Print "HW" ' Display some text
Print var {, var, var}
Replaces the compiler's Print command and places ASCII characters on the LED matrix at the current cursor position.
Example:
Include "Amicus18.inc" ' Configure the compiler to use a PIC18F25K20 at 64MHz. i.e. An Amicus18 board.
Include "LOLShield.inc" ' Load the LOL shield routines into the program
Dim bTemp as Byte ' Create a byte sized variable
LOL_Cls(0) ' Clear the LED matrix
LOL_Cursor(0, 0) ' Move to the start of the first line
Print "HW" ' Display some text
bTemp = 0 ' Reset variable bTemp
Do ' Create an infinite loop
LOL_Cursor(0, 0) ' Move to the start of the second line
Print Dec2 bTemp ' Convert an integer to ASCII and display it
Inc bTemp ' Increment variable bTemp
DelayMs 100 ' Slow things down so we can see the text change
Loop ' Do it forever
A Plasma effect Demo program is shown below:
' Code to operate the Arduino LOL shield from an Amicus18 board
' Produces a type of Plasma effect on the LED matrix
'
' Written by Les Johnson for the Positron8 BASIC compiler, operating the LOL Shield on the Amicus18 board
'
Include "Amicus18.inc" ' Configure the compiler for the PIC18F25K20 at 64MHz. i.e. An Amicus18 board
Include "LOLShield.inc" ' Load the LOL Shield routines into the program
'
' Create some variables for the demo
'
Dim bRow As Byte
Dim bCol As Byte
Dim fRow As Float
Dim fCol As Float
Dim fDistance As Float
Dim fColour As Float
Dim fPhase As Float
Dim Dist1_Xpos As Float
Dim Dist1_Ypos As Float
Dim Dist2_Xpos As Float
Dim Dist2_Ypos As Float
Dim Point1_Xpos As Float
Dim Point1_Ypos As Float
Dim Point2_Xpos As Float
Dim Point2_Ypos As Float
'-------------------------------------------------------------------------------------------------------
' The main program loop starts here
'
Main:
fPhase = 0
Do
fPhase = fPhase + 0.08 ' Controls the speed of the moving points. Higher = faster.
'
' The two points move along Lissajious curves, see: http://en.wikipedia.org/wiki/Lissajous_curve
' We want values that fit the LED grid: X values between 0..13 and Y values between 0..8
'
Point1_Xpos = Sin(fPhase * 1.0)
Point1_Xpos = (Point1_Xpos + 1.0) * 7.5
Point1_Ypos = Sin(fPhase * 1.31)
Point1_Ypos = (Point1_Ypos + 1.0) * 4.0
Point2_Xpos = Sin(fPhase * 1.77)
Point2_Xpos = (Point2_Xpos + 1.0) * 7.5
Point2_Ypos = Sin(fPhase * 2.865)
Point2_Ypos = (Point2_Ypos + 1.0) * 4.0
'
' For each row...
'
bRow = 9
Repeat
Dec bRow
fRow = bRow
'
' For each column...
'
bCol = 14
Repeat
Dec bCol
fCol = bCol
'
' Calculate the distance between this LED and Point1
'
Dist1_Xpos = fCol - Point1_Xpos ' \
Dist1_Ypos = fRow - Point1_Ypos ' / The vector from Point1 to this LED
fDistance = (Dist1_Xpos * Dist1_Xpos) + (Dist1_Ypos * Dist1_Ypos)
'
' Calculate the distance between this LED and Point2
'
Dist2_Xpos = fCol - Point2_Xpos ' \
Dist2_Ypos = fRow - Point2_Ypos ' / The vector from Point2 to this LED
'
' Multiply this with the other distance, this will create plasma values
'
fDistance = fDistance * ((Dist2_Xpos * Dist2_Xpos) + (Dist2_Ypos * Dist2_Ypos))
fDistance = Sqr(fDistance)
fColour = Sin(fDistance * 0.1)
fColour = fColour + 1.0
LOL_Plot(bCol, bRow, fColour) ' Illuminate or extinguish an LED
Until bCol = 0
Until bRow = 0
DelayMS 5 ' Slow down so we can see the LEDs moving because the code is too efficient
Loop
Below is a video of the plasma effect operating:
Another video is shown below that is of the Scrolling Text demo:
The Positron8 BASIC firmware source code for the LOL Shield sitting on an Amicus18 board is available from here: Amicus18_LOL_Shield_Source_Code