The QB64 Edition

Full Version: Waltersmind's - Single Color LED sign with scrolling letters
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Here is the code to my really cool LED scrolling sign.

Code Snippet: [Select]
' *************************************************************************************************
' *                                                                                               *
' *  Walter's LED sign  - By member Waltersmind.                                                  *
' *                                                                                               *
' *  Created: May 04, 2014                                                                        *
' *                                                                                               *
' *************************************************************************************************

TYPE LEDCharacter
   Image AS _UNSIGNED LONG
   ImageWidth AS _UNSIGNED INTEGER
   ImageHeight AS _UNSIGNED INTEGER
END TYPE

DIM SHARED ScreenWidth AS _UNSIGNED LONG
DIM SHARED ScreenHeight AS _UNSIGNED LONG
DIM SHARED MainScreen AS _UNSIGNED LONG
DIM SHARED BackBuffer AS _UNSIGNED LONG
DIM SHARED SaveBuffer AS _UNSIGNED LONG

DIM SHARED ScrollSpeed AS INTEGER
DIM SHARED Character(126) AS LEDCharacter
DIM SHARED LEDPixelSize AS _UNSIGNED INTEGER
DIM SHARED LEDBulbSize AS _UNSIGNED INTEGER
DIM SHARED LEDScreenWidth AS _UNSIGNED INTEGER
DIM SHARED LEDScreenHeight AS _UNSIGNED INTEGER
DIM SHARED LEDPanelWidth AS _UNSIGNED INTEGER
DIM SHARED LEDPanelHeight AS _UNSIGNED INTEGER
DIM SHARED LEDImageOn AS _UNSIGNED LONG
DIM SHARED LEDImageOff AS _UNSIGNED INTEGER

DIM SHARED CurrentLine AS _UNSIGNED INTEGER
DIM SHARED CurrentCharacter AS _UNSIGNED INTEGER
DIM SHARED CurrentPixelDelay AS _UNSIGNED INTEGER
DIM SHARED CurrentPixelCounter AS _UNSIGNED INTEGER
DIM SHARED CurrentCharacterPixel AS _UNSIGNED INTEGER
DIM SHARED PixelSpeed AS _FLOAT
DIM SHARED CurrentPixelState AS _UNSIGNED LONG

REDIM SHARED Message(-1) AS STRING

LEDPixelSize = 6 '12 'The LED pixel unit that contains the LED bulb
LEDBulbSize = 4 '8  ' The size of the LED bulb
LEDPanelWidth = 200 ' The width is in LED pixels (a space that contains one LED bulb), not monitor pixels.
LEDPanelHeight = 16 ' This is the actual height the current font uses.
CurrentPixelDelay = LEDPanelWidth + 10 ' The delay in LED units before the next line is displayed.
PixelSpeed = 1 ' Change this to speed up the scrolling.

ScreenWidth = LEDPanelWidth * LEDPixelSize
ScreenHeight = LEDPanelHeight * LEDPixelSize

MainScreen = _NEWIMAGE(ScreenWidth, ScreenHeight, 32)
BackBuffer = _NEWIMAGE(ScreenWidth, ScreenHeight, 32)
SaveBuffer = _NEWIMAGE(ScreenWidth, ScreenHeight, 32)
LEDImageOn = _NEWIMAGE(LEDPixelSize, LEDPixelSize, 32)
LEDImageOff = _NEWIMAGE(LEDPixelSize, LEDPixelSize, 32)

SCREEN MainScreen

' *** Get read to draw the turned-off LED bulb
_DEST LEDImageOff

' *** Draw LED background
LINE (0, 0)-(LEDPixelSize, LEDPixelSize), _RGB(32, 0, 0), BF

' *** Draw grey-filled gradient circle that represents the turned-off LED bulb
FOR CircleSize% = LEDBulbSize TO 1 STEP -1
   Red% = 64 - CircleSize% * 6
   Green% = 0 ' Red%
   Blue% = 0 'Red%
   Colr& = _RGB(Red%, Green%, Blue%)
   CIRCLE (LEDPixelSize / 2 - 1, LEDPixelSize / 2 - 1), CircleSize% / 2 + 0.05, Colr&
   PAINT (LEDPixelSize / 2 - 1, LEDPixelSize / 2 - 1), Colr&, Colr&
NEXT


' *** Get ready to draw the turned-on LED bulb
_DEST LEDImageOn

' *** Draw LED Background
LINE (0, 0)-(LEDPixelSize, LEDPixelSize), _RGB(64, 0, 0), BF

' *** Draw filled gradient circles that represents the turned-on LED bulb
FOR CircleSize% = LEDBulbSize TO 1 STEP -1
   Red% = (LEDBulbSize - CircleSize%) * 35 + 140
   Green% = 0 'Red%
   Blue% = 0
   Colr& = _RGB(Red%, Green%, Blue%)
   CIRCLE (LEDPixelSize / 2 - 1, LEDPixelSize / 2 - 1), CircleSize% / 2 + 0.05, Colr&
   PAINT (LEDPixelSize / 2 - 1, LEDPixelSize / 2 - 1), Colr&, Colr&
NEXT

' Due to some strange thing with printing a text character to an exact text character size image,
' we can not print text straight to the characters image. So here we draw it to the backbuffer.
_DEST BackBuffer

' *** Create images for each character
FOR C = 32 TO 126

   CharLength% = _PRINTWIDTH(CHR$(C))
   Character(C).Image = _NEWIMAGE(CharLength%, 16, 32)
   Character(C).ImageWidth = CharLength%
   Character(C).ImageHeight = 16

   ' If you change this color value, you must change it below in the testing part. Please note, the
   ' color value cannot be &HFFFFFFFF. When we use POINT below, if there is an error reading the pixel
   ' color, it returns &HFFFFFFFF or -1. This is a single-color LED sample, so the color used is not
   ' at all important.
   COLOR &HFFFF0000
   LOCATE 1, 1
   PRINT CHR$(C)

   ' Now we copy the text image over to the character image.
   _PUTIMAGE (0, 0), BackBuffer, Character(C).Image

NEXT


' *** Draw blank LED panel to the backbuffer.
FOR PanelHeight~% = 0 TO LEDPanelHeight - 1
   FOR PanelWidth~% = 0 TO LEDPanelWidth - 1
       _PUTIMAGE (PanelWidth~% * LEDPixelSize, PanelHeight~% * LEDPixelSize), LEDImageOff, BackBuffer
   NEXT
NEXT

' Copy the back buffer over to the main screen image.
_PUTIMAGE (0, 0), BackBuffer, MainScreen



' *************************************************************************************************
' *                   MODIFIED VERSION OF FORUM MEMBER'S artmaker43 MODIFICATION                  *
' *************************************************************************************************


' *** Predefine the LED Message text file. No need to ask the user for it, and it speeds things up.
File$ = "LED_Messages.txt"

' *** See if the file exists before we try to open it.
IF _FILEEXISTS(File$) THEN

   ' *** The file exists, so get the next file handle to use.
   FileHandle% = FREEFILE

   ' *** Open the file for reading.
   OPEN "I", FileHandle%, File$

   ' *** Check to see if there are any messages in the file.
   IF LOF(FileHandle%) > 0 THEN

       ' *** If there is, then read all the message lines in the file, if there are any.
       DO UNTIL EOF(FileHandle%)

           ' *** Enlarge the Message ARRAY to accommodate the next line.
           REDIM _PRESERVE SHARED Message(UBOUND(Message) + 1) AS STRING

           ' *** Read the new line.
           LINE INPUT #FileHandle%, Message(UBOUND(Message))

           ' *** If the message line is of zero length, then make it have a space character
           ' *** to create a time delay until the next message is show.
           IF Message(UBOUND(Message)) = "" THEN Message(UBOUND(Message)) = " "

       LOOP

   END IF

   ' *** Close all open files.
   CLOSE

END IF

' *** Check to see if there are any messages in our array, and if not, create a message
' *** to let the user know there are no messages available at this time.
IF UBOUND(message) < 0 THEN

   ' *** Since there are no messages in the file, then let the user know on screen.
   REDIM _PRESERVE SHARED Message(0) AS STRING
   Message(0) = "---=== NO MESSAGES AVAILABLE AT THIS TIME ===---"

END IF


' *************************************************************************************************
' *                                   BACK TO WALTERSMIND CODE                                    *
' *************************************************************************************************



CurrentLine = 0 ' We will start off with the zero-index of the message$ array.
CurrentCharacter = 1 ' Set to the first character of the line. It cannot be zero.
CurrentPixelCounter = 30 ' This is the first LED-pixel delay value. It is lower than the default value.
CurrentCharacterPixel = 0 ' Always start with zero here.

' *** Now the setup part is done, let's now animate our happy little LED sign.
DO

   _LIMIT 25

   ' Get the current character in the line
   MIDCharacter% = ASC(MID$(Message(CurrentLine), CurrentCharacter, 1))

   ' Change the source to the current characters image
   _SOURCE Character(MIDCharacter%).Image

   ' Check to see if we are still in the display delay.
   IF CurrentPixelCounter > 0 THEN

       ' If we are here than scroll everything left by pixel amount until we are no longer in the delay.

       CurrentPixelCounter = CurrentPixelCounter - PixelSpeed

       ' Since the source and destination image cannot be the same, we have to copy part of the LED image
       ' we know will still be on screen when scrolled, to the save buffer.
       _PUTIMAGE (0, 0), BackBuffer, SaveBuffer, (LEDPixelSize * PixelSpeed, 0)-(ScreenWidth, ScreenHeight)

       ' Copy the save buffer image back into the back buffer at the far left of the image. This simulates scrolling.
       _PUTIMAGE (0, 0), SaveBuffer, BackBuffer

   ELSE

       ' Since the source and destination image cannot be the same, we have to copy part of the LED image
       ' we know will still be on screen when scrolled, to the save buffer.
       _PUTIMAGE (0, 0), BackBuffer, SaveBuffer, (LEDPixelSize * PixelSpeed, 0)-(ScreenWidth, ScreenHeight)

       ' Copy the save buffer image back into the back buffer at the far left of the image. This simulates scrolling.
       _PUTIMAGE (0, 0), SaveBuffer, BackBuffer

       ' X% is basically 0 to PixelSpeed-1.
       FOR PixelX% = (LEDPanelWidth - PixelSpeed) TO (LEDPanelWidth - 1)

           ' *** Let's draw the vertical slice of the character defined by "PixelSpeed" first.
           FOR PixelY% = 0 TO LEDPanelHeight - 1

               ' Get the current character pixel X position.
               CharX% = CurrentCharacterPixel + (PixelX% - (LEDPanelWidth - PixelSpeed))

               ' Get the color of the current pixel in the characters image.
               CurrentPixelState = POINT(CharX%, PixelY%)

               ' Check to see if it contains the previously defined color value.
               IF CurrentPixelState = &HFFFF0000 THEN

                   ' If it does, draw the LED ON image.
                   _PUTIMAGE (PixelX% * LEDPixelSize, PixelY% * LEDPixelSize), LEDImageOn, BackBuffer

               ELSE

                   ' If it doesn't, then draw the LED OFF image.
                   _PUTIMAGE (PixelX% * LEDPixelSize, PixelY% * LEDPixelSize), LEDImageOff, BackBuffer

               END IF
           NEXT
       NEXT

       ' Get the next character pixel X-offset.
       CurrentCharacterPixel = CurrentCharacterPixel + PixelSpeed

       ' See if it is outside the current characters width.
       IF CurrentCharacterPixel >= (Character(MIDCharacter%).ImageWidth) THEN

           ' If it is, reset the X-position back to 0.
           CurrentCharacterPixel = 0

           ' Go to the next character in the current line.
           CurrentCharacter = CurrentCharacter + 1

           ' See if exuasted the characters in this line.
           IF CurrentCharacter > LEN(Message(CurrentLine)) THEN

               ' We have, so go to the next line.
               CurrentLine = CurrentLine + 1

               ' Reset the character position to the first position.
               CurrentCharacter = 1

               ' Here we setup the delay to show the next line
               CurrentPixelCounter = CurrentPixelDelay

               ' Check to see if we ran out of lines.
               IF CurrentLine > UBOUND(Message) THEN

                   ' We have so reset the current line to the first one in our array.
                   CurrentLine = 0

               END IF
           END IF
       END IF
   END IF

   ' Copy the complete back buffer on to the main screen.
   _PUTIMAGE (0, 0), BackBuffer, MainScreen

   ' Show it.
   _DISPLAY

LOOP UNTIL _KEYHIT
SYSTEM

[attachment=152]


Here is the YouTube video of the demo.




Download the "LED_Messages.txt" file for the user defined message, and to see how to create your own messages.


Walter Whitman
The Joyful Programmer
Nice Sign display Walter!

I remember in the UK When a Company first Started selling these Signs...I mean real LED Ones [Image: smile.gif] to advertise in Windows like Hotels,Shops,Pubs, Etc. and they were Expensive!! Now a Hotel Etc. could link your Program from a PC to a Monitor in the Window and do the same thing! Cool!...


A.R.B
Anthony,

Thank you.


Walter Whitman
The Joyful Programmer
Walter, 

I remember being inside a deli in early 80's and they had a sign like that advertising their specials. That brings back a lot of memories.

Somewhere down the road in making my programs, I may have a use for the sign in one of my programs. Would it be ok to use your sign?


Donald
Donald,

Anyone may use any code published on this forum for their personal projects. I don't mind if anyone uses any graphics I add to my projects, but I would be careful about the graphics in some of the other projects posted on here that are hand made with other programs like Adobe Photoshop. They could be copyrighted by those members. The main projects I am speaking about is Vetea's games like Papi Commando. He worked hard on those images and he may not like someone using them without his permission.

I do plan on revamping this demo and adding hardware acceleration to it to make it faster, and allow for full color images to be used instead of just one color.


Walter Whitman
The Joyful Programmer
Reference URL's