Results 1 to 8 of 8

Thread: Chasing/Scrolling LEDs

  1. #1
    New Member
    Join Date
    Aug 2011
    Location
    Florida, USA
    Posts
    6

    Default Chasing/Scrolling LEDs

    I used a PICAXE 40X2 to drive 208 chasing LEDs for a sign.
    The LEDs are mounted on a clear acrylic sheet in the pattern of an EKG heatbeat.
    The sheet is mounted on a plywood frame behind a sheet of red acrylic.
    A co-worker cut the patterns in the plywood and acrylic with a CNC router.

    Notes on the code:
    There is extra code to increase the speed in parts of the sign. This may not be needed for other applications.
    Sign runs on 3 D-cells, and checks the battery voltage before each sweep. If lower than 3 warning thresholds, it blinks the first LED 1-3 times. Circuit has been running for 2 months now. They usually turn it off at night but sometimes forget.

    Only one LED is lit at a time - more will overload current on pins.
    Speed is adjustable with the pot.
    The push button toggles a slow speed mode used to check the wiring.
    If the push button is held down on power-up, it leaves the 1st LED on - used for max current measurement for battery life.

    I have a video of the working sign. I'll try to upload separately (too big).
    Attached Files Attached Files

  2. #2
    Moderator
    Join Date
    Mar 2008
    Location
    Western Australia
    Posts
    11,203

    Default

    Well done on your project and thank you for posting the code, schematic diagrams, images, etc.

    There are places where the code can be optimised.
    1. A few cases where an alternative command may slightly improve the speed of a calculation
    2. removing calculations from within the main loops which are only in reality changed if there is an action such as pressing a button.

    Untested, but try the following code and see if you gain any significant speed improvement. But then you might need to increase the time delays if the overall speed is crucial.
    If you gain enough speed through code changes in the program you may be able to reduce the PAUSE delay intervals and adjust the PICAXE speed back to 8 MHz which will save some power (current drain) for the PICAXE chip.

    Code:
    ' Test Chasing LEDs 
    '  208 LEDs in 16 column x 13 row matrix
    ' 21 Jan 12  
    ' 25 Jan 12  add Batt_Check
    ' 04 Feb 12  add pushbutton for slow speed
    ' 05 Feb 12  16MHz, all pauses 2x
    ' 16 Feb 12  v5 add row_12 on A.5
    ' 22 Feb 12  v6 update pulsetimes
    ' 27 Feb 12  v7 addl debug msg
    ' 19 Apr 12  v8 adjust battery warn levels
    
    #picaxe 40X2
    #no_data
    #no_table
    #terminal 19200
    '#define verbose	; for debug messages
    setfreq m16			; 8MHz default, 16MHz max w/o res
    
    '-----------------------------------------
    ' I/O definitions
    symbol PushB     	= pinA.6		; Push Button to +V on pin 9
    symbol Knob			= 7			; 20k pot on ADC7 - A.7,pin 10
    
    symbol Col_MSB		= outpinsC	; Column bits [15:8]
    symbol Col_LSB		= outpinsD	; Column bits [ 7:0]
    symbol Row_MSB		= outpinsA	; Row    bits [12:8]
    symbol Row_LSB		= outpinsB	; Column bits [ 7:0]
    
    Col_MSB				= %00000000	; Init
    Col_LSB				= %00000000
    dirsC					= %11111111
    dirsD					= %11111111
    
    Row_MSB				= %00101111	; skip A.4 (SerOut)
    Row_LSB				= %11111111
    dirsA					= %00101111
    dirsB					= %11111111
    
    adcsetup 			= 0x0080		; enable ADC7 (pin 10)
    
    ' Program definitions
    symbol row					= b10
    symbol col					= b11
    symbol LED_Num				= b12
    
    symbol time_multiplier	= b13
    symbol on_time			= w10 ; b20,b21
    symbol pulse_time 		= w11 ; b22,b23
    symbol pulse_time2 		= w12 ; b24,b25
    symbol on_time_M			= w13 ; b26,b27
    symbol pulse_time_M 		= w14 ; b28,b29
    symbol pulse_time_M2		= w15 ; b30,b31
    
    '=========================================
    
    main:
    pause 100
    sertxd("208 Chasing LEDs (40X2) v8", cr,lf)
    time_multiplier = 1
    
    if PushB is ON then
    	Col_MSB = $00		; light (0,0) LED for current meas. 
    	Col_LSB = $01
    	Row_MSB = $2F
    	Row_LSB = $FE
    	do loop until PushB is OFF
    	pause 100
    	endif
    
    
    again:
    readadc Knob,b0						; read speed adj (0-255)
    sertxd("Knob:  ",#b0, cr,lf)
    on_time     = b0 / 2	 			; 0-127 ( 0-63 msec)
    pulse_time  = on_time * 3 / 4		; 75% delay
    pulse_time2 = on_time     / 2		; 50% delay
    GOSUB Setdelays
    #ifdef verbose
    sertxd("OnTime:  ",#on_time,    "  Mult: ",  #time_multiplier,cr,lf)
    sertxd("Pulse:   ",#pulse_time, "  Pulse2: ",#pulse_time2,cr,lf)
    #endif
    
    Row_MSB = $2F
    Row_LSB = $FF
    
    
    for row = 0 to 12
    	Col_MSB = $00
    	Col_LSB = $00
    	
    	w0   = 1 << row
    	if row=12 then : w0 = w0 <<1 : endif  ; skip A.4, use A.5
    	Row_LSB = NOT b0
    	Row_MSB = b1 XOR $2F
    	 
    	#ifdef verbose
    	sertxd("Row info: ",#row, "  ",#Row_MSB,"  ",#Row_LSB, cr,lf)
    	#endif
    	
    	for col = 0 to 15
    		w0   = 1 << col
    		Col_LSB = b0
    		Col_MSB = b1
    		#ifdef verbose
    		sertxd("Col info: ",#col, "  ",#Col_MSB,"  ",#Col_LSB, cr,lf)
    		#endif
    
    
    		LED_Num = row * 16 + col		; 0 to 207
    
    		select LED_Num
    		case  28 to  67
    			pause pulse_time_M
    		case  68 to  119
    			pause pulse_time_M2
    		case 120 to 131
    			pause pulse_time_M
    		else
    			pause on_time_M
    			endselect
    				
    		if PushB is ON then gosub PushButton
    		next col
    	next row
    
    
    Col_MSB = $00
    Col_LSB = $00
    
    gosub Batt_Check
    
    for b0 = 1 to 1
    	pause 100
    	if PushB is ON then gosub PushButton
    	next b0
    
    goto again
    
    end			
    
    '=======================================
    
    PushButton:
    ' If pushbutton was pressed, then toggle multiplier
    	sertxd("Button pressed.",cr,lf)
    	time_multiplier = time_multiplier XOR $04
    
    	do loop until PushB is OFF
    	pause 100 ; debounce
    Setdelays:
    		on_time_M     = on_time     * time_multiplier + 1
    		pulse_time_M  = pulse_time  * time_multiplier
    		pulse_time_M2 = pulse_time2 * time_multiplier
    	return
    
    '-----------------------------------------
    
    Batt_Check:
    ' Measure internal reference to check +V power
    	symbol ADCval   = w26
    	symbol V_plus   = w27			; *100 volts
    
    	calibadc10 ADCval
    	; V_plus / 1023 = 1.024 / ADCval
    	; 100 x V_plus = 100 x 1047.552 / ADCval
    	; 100 x V_plus = 52377.6 / ADCval * 2
    	V_plus = 52378 / ADCval 	
    	V_plus = V_plus * 2
    	sertxd ("+V * 100 = ", #V_plus,cr,lf)
    	
    
    	'bintoascii V_plus, b4,b3,b2,b1,b0
    	'sertxd (#ADCval," counts,   ",b2,".",b1,b0,  " volts",cr,lf)
    
    	' new is ~ 4.6V
    	if V_plus<380 then gosub Blink_LED00	; < 3.8 V
    	if V_plus<360 then gosub Blink_LED00	; < 3.6 V
    	if V_plus<330 then gosub Blink_LED00	; < 3.3 V
    	return
    
    '---------------------------------------
    	
    Blink_LED00:
    	; alert, blink the first LED
    	Col_MSB = $00
    	Col_LSB = $01
    	Row_MSB = $2F
    	Row_LSB = $FE
    	pause 500
    	Col_MSB = 0		; all off
    	Col_LSB = 0
    	Row_MSB = $2F
    	Row_LSB = $FF
    	pause 500
    	return
    
    '---------------------------------------
    #rem
    
    Battery Life:
    3x D cells = 3 x 12,000 mAh
    circuit current = 24.5 mA
    life = 61 days
    Last edited by westaust55; 28-04-2012 at 01:30. Reason: Posted the correct/intended potentially faster code
    westaust55

    Hey Hamlet, 2B OR NOT 2B = $FF

  3. #3
    New Member
    Join Date
    Aug 2011
    Location
    Florida, USA
    Posts
    6

    Default Chasing/Scrolling LEDs

    Movie attached. Had to make a new one at lower resolution.


    Westaus55 - thanks for your thoughts.
    Your attached code snippet looks like what I have already. Not sure what you are suggesting.
    This only gets run when the button is pushed, so speed here is not a big deal.

    Calculations were kept inside the loop so that the speed changes instantly when the button is toggled.
    Otherwise it would not change until the beginning of the next sweep.
    Could be a long time if the speed is slow.
    I did keep the ADC knob reading outside the loop due to time. I thought about also reading it on the button press, but it was not really helpful.
    Most of the current draw is in the LED (18-20 mA), and not in the PICAXE (~4mA), so CPU speed is not a big driver.


    A few more notes on the code.
    LEDs are in a matrix, and the outputs pins are initialized with all the column pins low, and all row pins high.
    To light one LED, a column pin is set high, and a row pin low.
    If more that one LED is attempted, others in a square may light, and will exceed the max current on an output pin.
    Be careful if modifying or debugging the code.
    Attached Files Attached Files

  4. #4
    Senior Member
    Join Date
    Jan 1970
    Location
    Rangiora, New Zealand
    Posts
    1,501

    Default

    Looks good. Good job.

    Had a look at the schematic. On Page1, you have a diode and a resistor on the power connector. What are they for?
    If it is for reverse polarity protection, then you don't need the 10R, but do require a fuse to blow.
    If it is an LED, then 1: the wrong symbol has been used; and 2: the wrong polarity is shown.
    In theory, there is no difference between theory and practice. In practice, there is...


  5. #5
    Moderator
    Join Date
    Mar 2008
    Location
    Western Australia
    Posts
    11,203

    Default

    @Peter,
    Westaus55 - thanks for your thoughts.
    Your attached code snippet looks like what I have already. Not sure what you are suggesting.
    sorry there some weird things happening at times when I try to post of recent.
    Even now when I click on "Reply with Quote" all I get is an empty "Quick Reply" window.
    Same is somtimes occring when I hit "Submit" and see an error. When I try to edit, on an iPhone using Safari all I get is an empty window (no tect to edit/fix/add to).


    I had not saved the revised code that was to be included at post 2 so have tried to reconstruct what I was thinking and have replaced the few lines that were visible with what I believe I had in mind. Give the new code posted at Post 2 a try - it should make more sense now.
    westaust55

    Hey Hamlet, 2B OR NOT 2B = $FF

  6. #6
    New Member
    Join Date
    Aug 2011
    Location
    Florida, USA
    Posts
    6

    Default

    Westaust55,
    Thanks again for looking at the code.
    Good improvement there. Needed re-calculations are only done when the button is pressed.
    I'll include that if I do an upgrade to the sign.

    MPep,
    The diode is a simple try at reverse-polarity protection.
    I did not want to use a series diode, because of the voltage drop across it.
    The diode clamps the voltage some, and the resistor limits the current thru it, so it does not burn up.
    It will only keep the reverse voltage down to a volt or 2, but was simple to include, and better than nothing.
    If I had a small fuse at hand, I would have used that.

  7. #7
    Senior Member
    Join Date
    Feb 2010
    Location
    Don't Mess With My Texas!
    Posts
    911

    Default

    Normally, you should upload videos to YouTube or similar and just provide the link to it here. Would like to see it!

    Quote Originally Posted by Peter Fender View Post
    ... I have a video of the working sign. I'll try to upload separately (too big).
    Truth lies dormant in our future history.

  8. #8

    Default

    Too bad you can't light more than 1 LED at a time. It would look really cool if you could emulate a CRT display where there's a sort of fading persistence effect on the pixels behind the bright trace.

    Actually, if you re-think how you do the loop timing, and hit every LED several times a second, then you could do a sort of PWM and accomplish the persistence/fade effect.

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •