PDA

View Full Version : Port indexing & PWM for LED fade



MOUNTAIN747
- 29th November 2013, 17:30
Greatings! I have stated a new project working with PWM and fading LEDs. All is going well until I tried to combine two simple test routines. The first two routines work fine. When I tried to use port indexing with PWM it failed. Can anyone point out my error or does the PWM command have limitations on pin discriptions? Manual says it can be a variable or pin discription, e.g. PortB.0 Is there another way to do this?

PIC16f886, PBP 2.6, using LAB X2 board.
;Cycle through PortB to fade ON then fade OFF eight LEDs in sequence.



Symbol Port_Pin=PortB
Avar var byte
Duty var byte
Cycle var byte

;more stuff in here

;--[ LED fade ON and fade OFF ]--------- works fine!
FadeTest:
cycle=4 ;cycle is number of cycles of pulse
for Duty=0 to 100 step 1
pwm led1,Duty,cycle
next Duty
cycle=1 ;cycle is number of cycles of pulse
for Duty=100 to 0 step -2
pwm led1,Duty,cycle
next Duty
low led1 ;end of routine
pause 1000
goto FadeTest

;--[ PortB indexing LEDs ]-------------- works fine!
IndexTest:
for Avar=0 to 7
Port_Pin.0[Avar]=1
pause 250
Port_Pin.0[Avar]=0
pause 250
next
goto IndexTest

;--[ FireFlies routine ]------------------- FAILED
FireFlies:
for Avar=0 to 7
cycle=4
for Duty=0 to 220 step 1
pwm Port_Pin.0[Avar],Duty,cycle
next Duty
cycle=1
for Duty=220 to 0 step -2
pwm Port_Pin.0[Avar],Duty,cycle
next Duty
low Port_Pin.0[Avar] ;end of routine
Next Avar
goto FireFlies


Comments please, Thanks.
Wayne

Art
- 1st December 2013, 12:19
Looks good to me if the addressing works with PWM.
What happens if you only try to PWM a single LED when you address it that way.. same thing?


I've read about the trick to address pins, what if you knock them into a declared array first,
and then aliased each one, I wonder what that would do.



pins[8] var byte
portb.0 var pins[0]
portb.1 var pins[1]
portb.2 var pins[2]…


Then cycle "pins" in the PWN command
for selected = 0 to 7
pins[selected] = value
next selected

Art
- 1st December 2013, 13:10
but my comment is, software PWM command (not HPWM) is a dead end.

How about starting with a constant loop that counts from zero to something,
or a hardware counter, then look at that counter each cycle of your program,
and determining which LEDs to turn on or off based on their own preset on/off counters.

Then you can vary the counters, and you're not limited to a single simultaneous PWM channel.

MOUNTAIN747
- 1st December 2013, 23:35
Art, Thanks for your reply. PWM with a single LED or port (LED1 var PortB.1) or single port (PortB.1) will work with PWM however I have been unable to get indexing to work with the PWM in any shape, form, or fashion. Some LED will light up but will not be the one you addressed. I think the problem must be within the PWM command structure. It will not recognize the indexing as a port location. I tried several versions of your suggestion of array declaration, no luck. I think indexing in some form should work but I have not figured it out yet. I have the routine working with Select Case approach but an indexing method would reduce the code considerably. Work continues…

richard
- 2nd December 2013, 03:11
from the book :- pwm pin,duty,cycle [ it says pin can be a constant or var from 0 to 15] whwre portb.0 = 0
therefore this may work , I have not tested it

for Avar=0 to 7
cycle=4
for Duty=0 to 220 step 1
pwm Avar,Duty,cycle
next Duty
cycle=1
for Duty=220 to 0 step -2
pwm Avar,Duty,cycle
next Duty
low Avar ;end of routine

MOUNTAIN747
- 2nd December 2013, 15:44
Richard, it worked, Thanks, although it raises as many questions as it answers.

This works



for Avar= 0 to 7
cycle=4 ;cycle is number of cycles of pulse
for Duty=0 to 220 step 1
pwm Avar,Duty,cycle
next Duty
cycle=2 ;cycle is number of cycles of pulse
for Duty=220 to 0 step -2
pwm Avar,Duty,cycle
next Duty
low Avar
next Avar


This works, on PortB, why? This should work on PortA. PortB, I tought, would be 8-15.
Yes I had used ‘Symbol Port_Pin=PortB’ which would set PortB to 0-7 but now I’m not using Port_Pin in the routine. I remember there is a file somewhere that sets the port numbers but I can ‘t remember what or where it is. I may have changed the default numbering over the years. Oh well, it works and now and I’m happy. I’m surprised I had not seen an example for PWM that used this method to cycle through LEDs. Too easy! thank you both for your input!



; 16F886
@ DEVICE INTRC_OSC,MCLR_ON,BOD_OFF,WDT_OFF,LVP_OFF

define osc 8
;------[ Set Hardware ]------------------------------------------------------
OSCCON=$70 '$70=8MHz, $60=4MHz
ANSEL=$00
ANSELH=$0
ADCON0=$00
CM1CON0=0
CM2CON0=0
OPTION_REG=0 ; INTOC RB0 set to interrupt on falling edge

PORTA=%00000000
PORTB=%00000000
PORTC=%00000000 ' RAC6&7 set with Hserout command
TRISA=%00000011 ' PORTA RA0 & RA1 input all other output
TRISB=%00000000 ' PORTB all set to Onput
TRISC=%00000000 ' PortC RC7&RC6 for hserout
;--[ VARIBLES, CONSTATNS ]-------------------------------------------------
; Symbol Port_Pin=PortB ; To define PortB port numbers start at RB.0
Avar var byte
Duty var byte
Cycle var byte
;--[ Main Program ]-------------------------------------------------------------
Start:
gosub FadeTest

;--[ Routine for fade on and fade off LEDs]------------------------------------
FadeTest:
for avar = 0 to 7
cycle=4 ;cycle is number of cycles of pulse
for Duty= 0 to 220 step 1
pwm Avar,Duty,cycle
next Duty
cycle=2 ;cycle is number of cycles of pulse
for Duty= 220 to 0 step -2
pwm Avar,Duty,cycle
next Duty
low Avar
next Avar
Return
end

Archangel
- 2nd December 2013, 19:11
Hi All,
I tried this just the way it's published to no avail, but did manage to make it work after tinkering a bit. I used a PIC Demo board featuring a PIC16F690 and the 4 LEDs on Port C as follows:


#CONFIG
__CONFIG _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_ON & _WDT_ON

#ENDCONFIG
DEFINE OSC 4
TRISA = 0
TRISB = 0
TRISC = 0



;------[ Set Hardware ]------------------------------------------------------
OSCCON=$70 '$70=8MHz, $60=4MHz
ANSEL=$00
ANSELH=$0
ADCON0=$00
CM1CON0=0
CM2CON0=0


PORTA=%00000000
PORTB=%00000000
PORTC=%00000000 ' RAC6&7 set with Hserout command

TRISA=%00000011 ' PORTA RA0 & RA1 input all other output
TRISB=%00000000 ' PORTB all set to Onput
TRISC=%00000000 ' PortC RC7&RC6 for hserout

Avar var byte
Duty var byte
Cycle var byte
;--[ Main Program ]-------------------------------------------------------------
Start:
gosub FadeTest
goto start

;--[ Routine for fade on and fade off LEDs]------------------------------------
FadeTest:
for avar = 8 to 11
PortC = avar << 2 &%00000001 ;& OP damps a leading on signal
cycle=4 ;cycle is number of cycles of pulse
for Duty= 0 to 220 step 1
pwm Avar,Duty,cycle
next Duty
cycle=3 ;cycle is number of cycles of pulse
for Duty= 220 to 0 step -2
pwm Avar,Duty,cycle
next Duty

next Avar
Avar = 8
Return
end

richard
- 2nd December 2013, 21:04
a quick read through the old pb2.6c book (page 30 in my edition) indicates the pin number is a hangover from the old basic stamp
pin chips 0-7 8-15
8 gpio
14 porta portc
18 portb porta
28 portb portc

remember that if you can

MOUNTAIN747
- 2nd December 2013, 21:52
Yep! The manual says a constant of 0 -15. It just didn’t say that it starts on PortB.0 and continues into PortC.0 and then it confuses things by talking about PortA.0. the old basic stamp thing is just fine with me. No indexing needed, no fancy port descriptions, just a constants or variables of 0 – 15. Easy to cycle through or set up for Random enables. Why do I always complicate things! thanks guys for your comments.

Wayne

Demon
- 2nd December 2013, 22:56
Just a comment on logic:


Start:
gosub FadeTest
goto Start <---- missing


Robert