PDA

View Full Version : Making a flying star effect with LEDs



lilimike
- 22nd December 2011, 18:59
The theory in my head was quite simple, I connected 16 LEDs in a matrix like so:
6195
but physically they are positioned in a single row from LED1 to LED16
I am testing with 16 LEDs but ideally I would do this with 64.

I can turn them on one at a time using this:

portb = %00011110:pause 25
portb = %00101110:pause 25
portb = %01001110:pause 25
portb = %10001110:pause 25
portb = %00011101:pause 25
portb = %00101101:pause 25
portb = %01001101:pause 25
portb = %10001101:pause 25
portb = %00011011:pause 25
portb = %00101011:pause 25
portb = %01001011:pause 25
portb = %10001011:pause 25
portb = %00010111:pause 25
portb = %00100111:pause 25
portb = %01000111:pause 25
portb = %10000111:pause 25


But I actually want to turn them on much like a flying star where LED1 stays on until LED9 goes on.
I was able to get one row lit but I can't figure out how to turn on the LEDs on the second row while keeping the LEDs on in the first row.

Is there a simple trick for this?

Mike

HenrikOlsson
- 22nd December 2011, 19:34
Hi Mike,
You need to scan the matrix continously. Ie. do what you did in your example but over and over again at fast rate. The LEDs will blink but if the scan rate is high the human eye won't see it.

EDIT: Just remember not to sink too much current into the B0-B3 pins!

/Henrik.

lilimike
- 22nd December 2011, 19:52
Hi Henrik,

It does not show on my drawing but I have a resistor on each led's anode.

For the scanning part I think I see what you mean and I will play with my code. I presume I should make two subroutines for each led (ON / OFF) and have a the main program call the subroutines based on what's on and what's off.
Now the theory in my head is becoming a little more complex...

Mike

sayzer
- 23rd December 2011, 05:06
You may use this to create flying star effect.

http://www.picbasic.co.uk/forum/showthread.php?t=10564

lilimike
- 23rd December 2011, 05:21
This is going to be handy, I've been pulling my hair out all day trying to figure this out.

Thanks for the link.

Mike

Charles Linquis
- 23rd December 2011, 06:26
PLEASE put resistors in series with the LEDs. LEDS ARE NOT INCANDESCENT LAMPS!!

HenrikOlsson
- 23rd December 2011, 14:22
It does not show on my drawing but I have a resistor on each led's anode

Even so, depending on how much current you push thru the LEDs there might be (probably is) to much current going into B0-B3. If the LED current is 10mA and you set B4-B7 there will be a total current of 40mA going into B0-B3 when you pull them low. That's beyond the specification for the PIC I/O pin.

lilimike
- 23rd December 2011, 14:48
Yes I realized that's what you meant after responding. I am presently in a test environment and just using a LED bar graph type and pushing +/-5mA
My final product will probably have transistors for each row/col.
If I can just understand how to code using BAM, the rest will be simple. I have read many websites about BCM/BAM but for some reason I am not getting it. I have yet to find the one explanation that will have probably just a slight difference in the way it is explained that I will understand.

I don't want to just copy some code to make it work, I want to understand and manipulate this at ease.

Mike

sayzer
- 23rd December 2011, 16:23
If you are driving some LEDs directly without any resistor, you should be pulsing it.
This subject differs from designer to designer.
Some argue that it is wrong.
Some say that it is perfectly normal.
Some argue the people (not the subject) who say it is perfectly normal.
Some argue the people back, not the subject.
So why don't you try driving your LEDs without any resistor but using some PWM freq like MIBAM?
And then if your circuit collapses, then have some resistor and try again.
Post your result here.

A similar LED - Resistor - PWM relationship complexity had been gone on this forum.

lilimike
- 23rd December 2011, 16:33
I was looking at MIBAM but then moved away due to its limitations:

@ 4Mhz, you can only run 4 LEDs MAX. This can be useful for RGB LED's on small chips.
@ 20Mhz, you can run 20 LEDs since there are more instructions available per period.
@ 48Mhz, you can run 48 LEDs, and anywhere in-between you can have the equivelant number of LEDs to match the OSC frequency.
If you attempt to use too many LEDs for a specific OSC frequency, the program will give a warning to indicate the results will be "Blinky".
I am planing to use 64 LEDs (maybe more) and I am trying to keep the components to minimal.

I haven't figured out if the above limitations apply to MIBAM or BAM. I am still searching for a good BAM explanation.

Mike

lilimike
- 23rd December 2011, 17:02
I think I am starting to understand BAM and I am not sure this applies to what I need to do.
Fist I should specify, I indicated in the subject "flying star" as the french that I am but "Shooting star" is more appropriate.
I don't really need to dim any LEDs although it might give an extra quality effect, I only need to turn on and off each LED independently within 64+ LEDs and I was able to do this one by one but failed to have more than one row of LEDs on at the same time.

This is pretty much what I am trying to accomplish (http://www.youtube.com/watch?v=VgYDLHPwGBs)

Mike

sayzer
- 23rd December 2011, 17:02
If you are using 64 LEDs via a matrix, then you only need 8 I/O for MIBAM output.

For the video you posted, you need MIBAM.

lilimike
- 23rd December 2011, 19:49
I'm trying...

One MIBAM output (B0) going to a resistor then a LED which is then connected to VDD
Using a PIC16F628A with this code the LED remains on with no dimming.

@ __config _INTOSC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_ON & _LVP_OFF & _CP_OFF
clear
DEFINE OSC 8
INCLUDE "MIBAM.pbp" ' Mirror Image BAM module

;____[ For 12F/16F only - Interrupt Context save locations]_________________
wsave var byte $20 SYSTEM ' location for W if in bank0
;wsave var byte $70 SYSTEM ' Alternate save location for W
' if using $70, comment out wsave1-3
' --- IF any of these next three lines cause an error ?? -------------------
' Comment them out to fix the problem ----
' -- The chip being used determines which variables are needed -------------
wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
;wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
'---DO NOT change these-----------------------------------------------------
ssave VAR BYTE BANK0 SYSTEM ' location for STATUS register
psave VAR BYTE BANK0 SYSTEM ' location for PCLATH register

TRISB = 000000
PORTB = 0

LED1 VAR byte

BAM_COUNT CON 1; How many BAM Pins are used?
Speed CON 20; Smaller = Faster
Brightness CON 200; Max DutyCycle


ASM
BAM_LIST macro ; Define PIN's to use for BAM
BAM_PIN (PORTB,0, LED1) ; and the associated Duty variables
endm
BAM_INIT BAM_LIST ; Initialize the Pins
ENDASM



Main:
FOR LED1 = 0 to Brightness -1 ' Ramp up 1 by 1
PAUSE Speed
NEXT

FOR LED1 = Brightness to 1 STEP -1 ' Ramp down 1 by 1
PAUSE Speed
NEXT
GOTO Main

End

What am I doing wrong?

Mike

lilimike
- 23rd December 2011, 21:00
I played with the settings and the LED is now dimming.
I am now facing my first issue... how to produce the effect I want.

I will try to find more examples, there's lots of scrolling text but so far I found nothing that resemble what I'm trying to do.
If anyone have a link feel free to share.

Mike

sayzer
- 24th December 2011, 11:27
6197
Try this one.
Pot changes index value for test purposes.
You can have 64 LEDs with this example.
LED corresponding to Index value will turn on.
Playing with this code, you can drive PORTB pins via MIBAM and have lots of effects.




@ __config _HS_OSC & _WDT_OFF & _PWRTE_OFF & _BODEN_OFF & _LVP_OFF & _CP_ALL

CLEAR
DEFINE OSC 20
DEFINE LCD_DREG PORTD
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTD
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTD
DEFINE LCD_EBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50

DEFINE ADC_BITS 8 ' Set number of bits in result
DEFINE ADC_CLOCK 3 ' Set clock source (rc = 3)
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in microseconds
CMCON = 7 ' Disable Comparator & VRef. etc.
pauseus 10
CVRCON = 0
ADCON1 = 96 ' 100000 Set analog thingie.
ADCON0 = 0 ' All analog, we just need RA0.
TRISA = 255 ' PORTA all input. Others output.
TRISB = 0
TRISC = 0
TRISD = 0
X var PORTB
Y var PORTC
Index var byte
Index2 var byte
OldVal var byte
Pause 10

Begin:
pause 500
lcdout $fe,1,"Matrix Test"
pause 1000

X = 0
Y = 255

index = 0
oldval = 255

Start:
adcin 0, index ' Index = max 255.
index = index / 4 ' To get index values between 0 to 63.
if oldval <> index then ' Act only when the number changes.
index2 = index/8 ' X scans 8 bits.
x = 0 ' turn it Off.
x.0[index2] = 1 ' Set the bit in line.

y = 255 ' turn all pins on (output is off).
lookup index2,[7,15,23,31,39,47,55,63],index2 ' Get matrix line.
y.0[index2-index] = 0 ' Clear the bit in line (output is on)


lcdout $fe,$c0,dec3 index , " ",dec3 index2
pause 10
oldval = index
endif

goto start

end

lilimike
- 24th December 2011, 16:39
I will give this a try.
which PIC are you using? I can't read the text in the picture.

You are using one resistor per column, is it right to say that no matter what, there is only one LED ON at a time?

Thank you for the example, this will help a lot.

Mike

sayzer
- 24th December 2011, 16:50
The example is for 16F877A.
In the example, yes, there is only one LED at a time.

lilimike
- 27th December 2011, 20:15
(Post removed at user's request in next post)

lilimike
- 27th December 2011, 23:52
I would have liked to delete thread #18 because that issue was resolved, I was missing some piece of code for MIBAM.
Anyways, I started off using Sayzer's code, then I was able to bypass the POT and make the LEDs scan automaticly.
I then added the MIBAM code (with no apparent difference) and I am still back to square one; I am not able to have about 20 LEDs on at the same time (or appear to be) to produce an effect similar as the video in thread #11
I am obviously not getting it and I would appreciate some guidance.
Below is the code I have so far, it is turning on then off LED1 to LED64 at the right speed but I am trying to turn on LED1, LED2...LED20 and from there when LED21 turns on the LED1 will turn off, LED22 on - LED2 off and so on.

@ __config _CONFIG1, _HS_OSC & _WDT_OFF & _PWRTE_OFF & _BOREN_OFF & _LVP_OFF & _CP_OFF

CLEAR
DEFINE OSC 20
BAM_COUNT CON 8
INCLUDE "MIBAM.pbp"
;____[ For 12F/16F only - Interrupt Context save locations]_________________
wsave var byte $20 SYSTEM ' location for W if in bank0
;wsave var byte $70 SYSTEM ' Alternate save location for W
' if using $70, comment out wsave1-3
; Comment them out to fix the problem ----
; -- The chip being used determines which variables are needed -------------
wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
;---DO NOT change these-----------------------------------------------------
ssave VAR BYTE BANK0 SYSTEM ' location for STATUS register
psave VAR BYTE BANK0 SYSTEM ' location for PCLATH register

DEFINE LCD_DREG PORTD
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTD
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTD
DEFINE LCD_EBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50

DEFINE ADC_BITS 8 ' Set number of bits in result
DEFINE ADC_CLOCK 3 ' Set clock source (rc = 3)
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in microseconds

CM1CON0 = 0
CM2CON0 = 0
pauseus 10
ADCON1 = 0
ADCON0 = 0 ' All analog, we just need RA0.
TRISA = 255 ' PORTA all input. Others output.
TRISB = 0
TRISC = 0
TRISD = 0
test var byte
X var PORTB
Y var PORTC
x = 0 ; make sure all LEDs are off
y = 0 ; when powr is applied

I var byte
Index var byte
Index2 var byte
OldVal var byte
Pause 10

ASM
BAM_LIST macro ; Define PIN's to use for BAM
BAM_PIN (PORTB,0, X) ; and the associated Duty variables
BAM_PIN (PORTB,1, X)
BAM_PIN (PORTB,2, X)
BAM_PIN (PORTB,3, X)
BAM_PIN (PORTB,4, X)
BAM_PIN (PORTB,5, X)
BAM_PIN (PORTB,6, X)
BAM_PIN (PORTB,7, X)

endm
BAM_INIT BAM_LIST ; Initialize the Pins
ENDASM ' Mirror Image BAM module

Begin:
pause 500
;lcdout $fe,1,"Matrix Test"
;PAUSE 500

X = 0
Y = 255

index = 0
oldval = 255

Start:
; adcin 0, index ' Index = max 255.

for i = 0 to 255
index = i / 4 ' To get index values between 0 to 63.
;if oldval <> index then ' Act only when the number changes.
index2 = index/8 ' X scans 8 bits.
x = 0 ' turn it Off.
x.0[index2] = 1 ' Set the bit in line.

y = 255 ' turn all pins on (output is off).
lookup index2,[7,15,23,31,39,47,55,63],index2 ' Get matrix line.
y.0[index2-index] = 0 ' Clear the bit in line (output is on)

;lcdout $fe,$c0,dec3 index , " ",dec3 index2
;pause 10
oldval = index
;endif
pause 1
next i
pause 100
goto start

end

lilimike
- 30th December 2011, 15:40
I am still struggling with this, however I am a few steps further (I hope):ambivalence:

First off I played with Darrel's Cylon/Kitt code (http://www.picbasic.co.uk/forum/showthread.php?t=10564&p=70256#post70256)
and slightly modified it to scan one way but I have 2 issues;

Since I have 64 LEDs connected like Sayzer indicated I get 8 LEDs turned on and slowly drained at the same time.
After each scan I could not pause until the last LEDs fully extinguish and have an extra 2 seconds before the next scan starts.

This is the modified code:

CLEAR
;-- 16F887 Internal OSC @ 8Mhz ------
;@ __config _CONFIG1, _INTOSCIO & _WDT_OFF & _MCLRE_OFF & _LVP_OFF & _CP_OFF
@ __config _CONFIG1, _INTOSCIO & _WDT_OFF & _MCLRE_OFF & _LVP_OFF & _CP_OFF & _BOREN_OFF
ANSEL = 0
ANSELH = 0
OSCCON = %01110001
DEFINE OSC 8

TRISC = 0 ; I needed to clear PORTC
Y var PORTC
y = 0

;____[ For 12F/16F only - Interrupt Context save locations]_________________
wsave var byte $20 SYSTEM ' location for W if in bank0
;wsave var byte $70 SYSTEM ' Alternate save location for W
' if using $70, comment out wsave1-3
' --- IF any of these next three lines cause an error ?? -------------------
' Comment them out to fix the problem ----
' -- The chip being used determines which variables are needed -------------
wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
'---DO NOT change these-----------------------------------------------------
ssave VAR BYTE BANK0 SYSTEM ' location for STATUS register
psave VAR BYTE BANK0 SYSTEM ' location for PCLATH register


;----[ MIBAM Setup ]--------------------------------------------------------
;BAM_FREQ CON 100 ; Desired Refresh rate Limit
;ScopeSync VAR PORTB.0 ; if declared, generates sync for OScope
;DEFINE BAM_INFO 1 ; use to display MIBAM results

BAM_COUNT CON 8 ; How many BAM Pins are used?
INCLUDE "MIBAM.pbp" ; Bit Angle Modulation module

BAM_DUTY VAR BYTE[BAM_COUNT]
LED1 VAR BAM_DUTY[0] ; group them in an array for easy access
LED2 VAR BAM_DUTY[1] ; with FOR loops etc.
LED3 VAR BAM_DUTY[2]
LED4 VAR BAM_DUTY[3]
LED5 VAR BAM_DUTY[4]
LED6 VAR BAM_DUTY[5]
LED7 VAR BAM_DUTY[6]
LED8 VAR BAM_DUTY[7]

ASM
BAM_LIST macro ; Define PIN's to use for BAM
BAM_PIN (PORTB,0, LED1) ; and the associated Duty variables
BAM_PIN (PORTB,1, LED2)
BAM_PIN (PORTB,2, LED3)
BAM_PIN (PORTB,3, LED4)
BAM_PIN (PORTB,4, LED5)
BAM_PIN (PORTB,5, LED6)
BAM_PIN (PORTB,6, LED7)
BAM_PIN (PORTB,7, LED8)
endm
BAM_INIT BAM_LIST ; Initialize the Pins
ENDASM

;_________________________________________________
Speed CON 5 ; Smaller = Faster
TracerSpeed CON 20 ; Smaller = Faster Left/Right
Brightness CON 200 ; Tracers DutyCycle
DrainSpeed CON 40 ; Smaller = Shorter Trail

Idx VAR BYTE
LoopCount VAR BYTE
NextLED VAR BYTE
TraceDIR VAR BIT

TraceDIR = 0
LoopCount = 0
NextLED = 0

Main:
if LoopCount = TracerSpeed then ; __[ Cylon/Kitt Scanner ]__
LoopCount = 0
BAM_DUTY(NextLED) = Brightness
; if TraceDIR then ; if scanning left
; NextLED = NextLED - 1
; if NextLED = 0 then TraceDIR = 0
; else ; else scanning right
NextLED = NextLED + 1
; if NextLED = BAM_COUNT-1 then TraceDIR = 1
; endif
endif

FOR Idx = 0 to BAM_COUNT - 1 ; Drain all dutycycles
IF BAM_DUTY(Idx) > 0 then
BAM_DUTY(Idx) = BAM_DUTY(Idx)*DrainSpeed/(DrainSpeed+1)
ENDIF
NEXT Idx
pause Speed
if NextLED = BAM_COUNT then NextLED = 0 ; Added this line
LoopCount = LoopCount + 1
GOTO Main



Also looking at Sayzer's code example, I removed the ADC, the LCD and modified based on my understanding and came up with this result which is scanning at the proper rate and the pause between scans.

CLEAR
@ __config _CONFIG1, _INTOSCIO & _WDT_OFF & _MCLRE_OFF & _LVP_OFF & _CP_OFF & _BOREN_OFF
ANSEL = 0
ANSELH = 0
OSCCON = %01110001
DEFINE OSC 8

TRISB = 0
TRISC = 0
TRISD = 0
X var PORTB
Y var PORTC
xCOL var byte
yROW VAR BYTE
Speed var word

Pause 10

Begin:
X = 0
Y = 255
speed = 30
Start:
for xcol = 0 to 7
x = 0
x.0[xcol] = 1
for yrow =7 to 0 step -1
y = 255
y.0[yrow] = 0
pause speed
Next yrow
next xcol
y = 255 ; turn off (and drain all LEDs)
PAUSE 2000 ; wait before starting over
goto start
END

Last but not least I am trying to find a way to add a trail of 20 to 30 LEDs with the same effect as Darrel's code using MIBAM.
I can't figure it out :torn:

Mike

mackrackit
- 30th December 2011, 23:19
I can not help with MIBAM, but if you are willing to do a hardware change it can be done this way.
http://www.picbasic.co.uk/forum/showthread.php?t=10200&p=67151#post67151

lilimike
- 3rd January 2012, 03:20
Thanks Dave for the suggestion but that is a little too much hardware changes.
My project consists in a stream of LEDs lined up in a tube and I am trying to keep the hardware to the minimum.
I figured at the most I would add 8 transistors but I haven't added them yet and it's been running for about a week now and nothing is getting hot or warm.
It is running with the code listed in post #20 (top) using MIBAM with a trail of 32 LEDs. I still have the LEDs turn ON and DIM in sets of 8 but I am starting to understand and I believe I will resolve this shortly.

But thanks and by the way the code coming by a 7 years old that's impressive, if your son is still into programming he must be an expert by now!

Mike

mackrackit
- 3rd January 2012, 10:57
if your son is still into programming he must be an expert by now!
He went a different direction, he is into graphics now. But there is still hope that he will do some code. He is using Blender on a Linux box and is not afraid of using a terminal ;)