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

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