PDA

View Full Version : DT's multi SPWM issue



Scampy
- 29th December 2012, 00:37
Following on from my previous thread (http://www.picbasic.co.uk/forum/showthread.php?t=17497&p=117802#post117802) I've opted to use Darrels multi SPWM option, and after some fuffing around I've managed to get the delay working for the pause value - it's not exact, but it will fade up a LED from 0 to whatever value is set for B_MAX in whatever time frame (been using 5min and 10 min in testing). Having got one channel working I replicated everything using new variables for the white channel and this is where I'm having issues.

If I set the blues to fade up from 0 to 255 over 5 minutes between 8:00 and 8:05, and then set the whites to fade up from 0 to 255 but between 8:00 and 8:10, both fade up at the same rate - that being the longest, the whites, so by 5 minutes the blues have reached around 127, rather than around 255, so as they have reached the Day on time the leds jump in brightness from 50% to 100%. I assume this is because in the main loop it's having to wait for the VW_7 value in the pause loop, as would happen with a normal pause statement. However I was under the impression the multi spwm routine would run independently ??

Anyway, here's the bulk of the code (config settings etc removed), and would welcome comments




DEFINE OSC 40 ; config settings 18F4580, 20mhz crystal
ADCON1 = $0F
clear

SCLpin var PORTC.3 ' RTC pin - clk
SDApin var PORTC.4 ' RTC pin - data

TimeH var byte ' Variable to store current hour
TimeM var Byte ' Variable to store current minutes

B_lights var byte
W_lights var byte

CounterA var byte ' General purpose Variable
CounterB var byte ' General purpose Variable

RTC_Secs var byte
RTC_Mins var byte
RTC_Hours var byte
RTC_Day var byte
RTC_WDay var byte
RTC_Month var byte
RTC_Year var byte
RTC_Ctrl var byte

SetupPreset:
RTC_Secs=$00 ' Seconds preset to 00
RTC_Mins=$00 ' Minutes preset
RTC_Hours=$08 ' Hours preset
RTC_WDay=$01 ' Weekday preset to 01
RTC_Day=$12 ' Day preset 12
RTC_Month=$06 ' Months preset to June
RTC_Year=$02 ' Year preset to 2002
RTC_Ctrl=$10 ' Control preset to output 1 second 'Tick' on SQWpin

I2CWrite SDApin,SCLpin,$D0,$00,[RTC_Secs,rtc_mins,RTC_Hours,RTC_Ctrl]

B_Min var word 'Min Light value
B_Max var word 'Max Light value
B_Dawn_On_H var word 'What time to turn the lights on
B_Dawn_On_M var word 'What time to turn the lights on
B_Day_On_H var word 'Start of Day Hours
B_Day_On_M var word 'Start of Day Min
B_Dusk_On_H var word 'Start of Dusk period Hours
B_Dusk_On_M var word 'Start of Dusk period min
B_Off_H var word 'Time to turn lights off
B_Off_M var word 'Time to turn lights off

W_Min var word 'Min Light value
W_Max var word 'Max Light value
W_Dawn_On_H var word 'What time to turn the lights on
W_Dawn_On_M var word 'What time to turn the lights on
W_Day_On_H var word 'Start of Day Hours
W_Day_On_M var word 'Start of Day Min
W_Dusk_On_H var word 'Start of Dusk period Hours
W_Dusk_On_M var word 'Start of Dusk period min
W_Off_H var word 'Time to turn lights off
W_Off_M var word 'Time to turn lights off

Blue_Day_Cycle var word 'Store for which part of the day cycle we are in
White_Day_Cycle var word

B_FadeIn_Time var word
W_FadeIn_Time var word

' Constants for the current running mode cycle for the lights
DAWN con 0
DAY con 1
DUSK con 2
NIGHT con 3

Vw_1 var word
Vw_2 var word
Vw_3 var word
Vw_4 var word
Vw_5 var word
Vw_6 Var word
Vw_7 var Word
Vw_8 var word


Vb_1 var word
Vb_2 Var word
Vb_3 var word
Vb_4 var word
Vb_5 var word
Vb_6 Var word
Vb_7 var word
Vb_8 var word

fn var byte

define SPWMFREQ 500 ' PWM frequency in Hz

DutyCycle1 VAR byte ' BLUE - 0-255 0=Idle Low 255=Idle High
DutyCycle2 VAR byte ' WHITE - 0-255 0=Idle Low 255=Idle High
include "Multi_SPWM.pbp"

SPWM1PIN VAR PORTD.7 ' SPWM channel 1
define SPWM1VAR _DutyCycle1

SPWM2PIN VAR PORTD.6 ' SPWM channel 2
define SPWM2VAR _DutyCycle2


'************************************************* ******************************
' LED variables
' Whites:
'************************************************* ******************************
W_Min = 0 'Min Light value
W_Max =255 'Max Light value
W_Dawn_On_H =8 'What time to turn the lights on
W_Dawn_On_M =0 'What time to turn the lights on
W_Day_On_H =8 'What time to turn the lights on
W_Day_On_M =10 'What time to turn the lights on
W_Dusk_On_H =08 'What time to turn the lights on
W_Dusk_On_M =15 'What time to turn the lights on
W_Off_H =08 'Time to turn lights off
W_Off_M =20 'Time to turn lights off



'************************************************* ******************************
' LED variables
' Blues:
'************************************************* ******************************
B_Min =0 'Min Light value
B_Max =127 'Max Light value
B_Dawn_On_H =8 'What time to turn the lights on
B_Dawn_On_M =0 'What time to turn the lights on
B_Day_On_H =8 'What time to turn the lights on
B_Day_On_M =3 'What time to turn the lights on
B_Dusk_On_H =8 'What time to turn the lights on
B_Dusk_On_M =15 'What time to turn the lights on
B_Off_H =8 'Time to turn lights off
B_Off_M =19 'Time to turn lights off

DutyCycle1 = 0 'turn off the lights
DutyCycle2 = 0

gosub fade:
fn=0


'************************************************* **************************
'**** MAIN PROGRAM ****************
'************************************************* **************************
main:

gosub Read_Clock

if B_Dawn_On_H = TimeH and B_Dawn_On_M = TimeM Then B_lights =1
if B_lights =1 then
Blue_Day_Cycle = Dawn
endif

if B_Day_On_H = TimeH and B_Day_On_M = TimeM then B_Lights =2
if B_lights =2 then
Blue_Day_Cycle = DAY
endif

if B_Dusk_On_H = TimeH and B_Dusk_On_M = TimeM then B_lights =3
if B_lights =3 then
Blue_Day_Cycle = Dusk
endif

if B_Off_H = TimeH and B_Off_M = TimeM then B_lights =4
if B_lights =4 then
Blue_Day_Cycle = Night
endif




if W_Dawn_On_H = TimeH and W_Dawn_On_M = TimeM Then W_Lights=1
if W_lights =1 then
White_Day_Cycle = Dawn
endif

if W_Day_On_H = TimeH and W_Day_On_M = TimeM then W_Lights=2
if W_lights =2 then
White_Day_Cycle = Day
endif

if W_Dusk_On_H = TimeH and W_Dusk_On_M = TimeM then W_lights=3
If W_Lights=3 then
White_Day_Cycle = Dusk
endif

if W_Off_H = TimeH and W_Off_M = TimeM then W_lights=4
if W_lights =4 then
White_Day_Cycle = Night
endif

;***************************
'*** Do BLUE daily cycle ***
;***************************

select case Blue_Day_Cycle
case DAWN
lcdout $FE,$94,"BLUE: DAWN "
DutyCycle1 = DutyCycle1 +1
pause Vb_7
if DutyCycle1=B_Max then
B_lights = 2
endif

case DAY
lcdout $FE,$94,"BLUE: DAY "
DutyCycle1 = B_max

CASE DUSK
lcdout $FE,$94,"BLUE: DUSK "
DutyCycle1 = DutyCycle1 -1
pause Vb_7
if DutyCycle1=B_Min then
B_Lights =4
endif


case NIGHT
lcdout $FE,$94,"BLUE: NIGHT"
DutyCycle1 = B_min

end select

;****************************
'*** Do WHITE daily cycle ***
;****************************

select case White_Day_Cycle
case DAWN
lcdout $FE,$D4+8,"White: DAWN "
DutyCycle2 = DutyCycle2 +1
pause Vw_7
if DutyCycle2=W_Max then
W_lights = 2
endif

case DAY
lcdout $FE,$D4+8,"White: DAY "
DutyCycle2 = W_max

CASE DUSK
lcdout $FE,$D4+8,"White: DUSK "
DutyCycle2 = DutyCycle2 -1
pause Vw_7
if DutyCycle2=W_Min then
W_Lights =4
endif

case NIGHT
lcdout $FE,$D4+8,"White: NIGHT"
DutyCycle2 = W_min
end select


lcdout $FE,$80,#vb_7," ",#vw_7
lcdout $FE,$C0,#DutyCycle1," ",#DutyCycle2
Goto main

'************************************************* *******************************

Read_Clock:

I2CRead SDApin,SCLpin,$D0,$00,[RTC_Secs,rtc_mins,rtc_hours,RTC_Ctrl] ; read DS1307 chip
If RTC_Hours.6=1 then
CounterA=(RTC_Hours>>4)&$01 ' Work-Out 12 or 24 hour Display for Hours
else
CounterA=(RTC_Hours>>4)&$03
endif
CounterA=CounterA*10+(RTC_Hours&$0F) ' Display Hours appropriately for 12 or 24 hour Mode
If RTC_Hours.6=1 then

LCDOut $FE,$D4,#CounterA
else
LCDOut $FE,$D4,#CounterA Dig 1,#CounterA Dig 0
endif

LCDOut ":",#(RTC_Mins>>4)&$0F,#RTC_Mins&$0F

TimeH=(RTC_Hours>>4) 'convert the BCD format of the hours register and store in variable timeH
TimeH=(TimeH &$03)*10
TimeH=TimeH+(RTC_Hours&$0F)

TimeM=(RTC_Mins>>4)
TimeM=(TimeM &$07)*10
TimeM=TimeM+(RTC_Mins&$0F) 'convert the BCD format of the mins register and store in variable timeM
Return


'************************************************* ******************************

Fade:

Vb_1 = ((B_Day_On_H - B_Dawn_On_H)*60) ' difference between day start and dawn start hour, converted to min
Vb_2 = (B_Day_On_M - B_Dawn_On_M) ' difference between day start and dawn start mins
Vb_3 = (Vb_1+Vb_2)*60 ' Get total duration time in seconds
Vb_4 = B_Max - B_Min ' Work out the 'distance' the lights go from min to max
Vb_3 = Vb_3 * 100 ' Convert into whole number
B_fadein_time = vb_3/vb_4 ' Get number of seconds between each PWM pulse
Vb_6 = Vb_3 // Vb_4 ' Get fractions of a second
if Vb_6 >=5 then B_Fadein_Time = B_Fadein_Time + 16
Vb_7 = B_Fadein_Time *5

Vw_1 = ((W_Day_On_H - W_Dawn_On_H)*60) ' difference between day start and dawn start hour, converted to min
Vw_2 = (W_Day_On_M - W_Dawn_On_M) ' difference between day start and dawn start mins
Vw_3 = (Vw_1+Vw_2)*60 ' Get total duration time in seconds
Vw_4 = W_Max - W_Min ' Work out the 'distance' the lights go from min to max
Vw_3 = Vw_3 * 100 ' Convert into whole number
W_fadein_time = Vw_3/Vw_4 ' Get number of seconds between each PWM pulse
Vw_6 = Vw_3 // Vw_4 ' Get fractions of a second
if Vw_6 >=5 then W_Fadein_Time = W_Fadein_Time + 16
Vw_7 = W_Fadein_Time *5


Return