Help with pwmout command...Please :-)

raptorbasher

New Member
Hi All,

I am writing some code for a lighting timer project and have the core of the code working well, however I am having a little trouble with fading via pwm.

my code looks for the trigger time and sets off incrementing a word variable, which ultimately gets sent to the pwm command as the named variable.

when the lights come up all is well until it rolls over a value and the fade begins over again.

in my code there is a check for max value which also works, but I now realise this is all counting in hex, and the pwm command is expecting decimal values right? so when my value increments it goes over the decimal max 1023.

so I need a little help, I have got the input via buttons and LCD of a percentage, but using BCD, so the max value can have a four digit value xxx.x% and that is okay but how do I...

1, get the increment to happen in decimal? or at least convert it to decimal before incrementing and back again...

2, get the value in decimal to go to the pwm command?

any ideas??

thanks

Tim
 

raptorbasher

New Member
Hi Eclectic,


So here is the input routine from the LCD and buttons...

setpwm:
serout B.7,N2400,(254,192)
button A.0,1,5,10,modebutton,1,pwmexit:
button A.1,1,1,1,incbutton,1,pluspwm:
button A.2,1,1,1,decbutton,1,minuspwm:
goto setpwm:

pluspwm:
let temppwm2 = temppwm1 & %0001000000000000
if temppwm2 = $1000 then
goto setpwm:
endif
inc temppwm1
let temppwm2 = temppwm1 & %0000000000001010
if temppwm2 = $000a then
let temppwm1 = temppwm1 + 6
endif
let temppwm2 = temppwm1 & %0000000010100000
if temppwm2 = $00a0 then
let temppwm1 = temppwm1 + 96
endif
let temppwm2 = temppwm1 & %0000101000000000
if temppwm2 = $0a00 then
let temppwm1 = temppwm1 + 1536
endif
call displaypwm:
pause 20
goto setpwm:

minuspwm:

if temppwm1 = $0000 then
goto setpwm:
endif
dec temppwm1
let temppwm2 = temppwm1 & %0000111100000000
if temppwm2 = $0f00 then
let temppwm1 = temppwm1 - 1536
endif
let temppwm2 = temppwm1 & %0000000011110000
if temppwm2 = $00f0 then
let temppwm1 = temppwm1 - 96
endif
let temppwm2 = temppwm1 & %0000000000001111
if temppwm2 = $000f then
let temppwm1 = temppwm1 - 6
endif
call displaypwm:
pause 20
goto setpwm:

pwmexit:
pause 100
Return
which gets called in this section of code...

serout B.7,N2400,(254,1)
serout B.7,N2400,(254,128)
serout B.7,N2400,("Set CH2 Max level:")
let temppwm1 = ch2pwmmax
call displayPWM:
pause 500
call setPWM:
let ch2pwmmax = temppwm1
I have it set in a subroutine because there is two channels of lighting...the fade up and down of each channel is controlledby trigger bits, so each is independant of the other.

lights: `take care of the dimming section

if ch1trigon = 1 and ch1pwmcur = ch1pwmmax then
let ch1trigon = 0
let lcddisp1 = $2a
endif
if ch1trigon = 1 and ch1pwmcur <= ch1pwmmax then
inc ch1pwmcur
endif
if ch1trigoff = 1 and ch1pwmcur = 0 then
let ch1trigoff = 0
let lcddisp1 = $20
endif
if ch1trigoff = 1 and ch1pwmcur => 0 then
dec ch1pwmcur
endif

if ch2trigon = 1 and ch2pwmcur = ch2pwmmax then
let ch2trigon = 0
let lcddisp2 = $2a
endif
if ch2trigon = 1 and ch2pwmcur <= ch2pwmmax then
inc ch2pwmcur
` `
endif
if ch2trigoff = 1 and ch2pwmcur = 0 then
let ch2trigoff = 0
let lcddisp2 = $20
endif
if ch2trigoff = 1 and ch2pwmcur => 0 then
dec ch2pwmcur
endif

pwmduty C.1, ch1pwmcur
pwmduty C.2, ch2pwmcur
so where I'm getting stuck is the bit between getting the max value in a BCD word, and getting the loop to increment in the same way. all that is happening so far is the increment goes up and down in hex, but compares against the BCD max... I need to get the whole lot done in BCD or the whole lot done in hex but not both.

Thanks

Tim
 

hippy

Ex-Staff (retired)
I am not sure why you are using BCD numbers but the best way to use BCD in calculations is to convert them into decimal and then use those. That will make things far simpler.

To increase a number up to 1023 and to not exceed that ...

pwmValue = pwmValue + 1 Max 1023

And to decrease it to zero and not go below ...

pwmValue = pwmValue Min 1 - 1
 

raptorbasher

New Member
Hi Hippy,

I was using BCD because it was easier to send the values via the LCD display, so when I am inc/dec the PWM max value I get 0 - 100.0 % as I wanted.

I'll rethink how I do the whole process and make it easier...out of interest what is the best way of getting from BCD to decimal??

Thanks
Tim
 

raptorbasher

New Member
Thanks Nick12ab,

I am running this via a 28x2 sheild setup so it should support that command. need a little time to get my head around it.

Regards

Tim
 

hippy

Ex-Staff (retired)
I was using BCD because it was easier to send the values via the LCD display, so when I am inc/dec the PWM max value I get 0 - 100.0 % as I wanted.
Thanks, and I now understand what you are doing. It would probably be better to keep each digit as a separate variable, adjust those with simple +1/-1, then after each adjustment build up what the PWM duty would be from those.

' Set 013.8%
digitH = 0 ' hundreds
digitT = 1 ' tens
digitU = 3 ' units
digitF = 8 ' Fractional

' Determine as 0 to 1000 ( 000.0 to 100.0%)
pwmDuty = digitH * 10 + digitT * 10 + digitU * 10 + digitF

' Set PWM duty
PWMOUT pin, 250, pwmDuty
 

raptorbasher

New Member
Hi Hippy,

that was what I was trying to come up with...I need a fairly low step between pwm values so I was using the whole 1000( instead of 1023 ) as it matched up well with 100.0%, seemed to make sense at the time, but getting the inc/dec to work with the LCd input made me think of the BCD route.

looking at the conversion you give above to determine as 0 to 100.0 would it not need to be...

pwmDuty - digitH * 1000 + digitT * 100 + digitU * 10 + digitF

and limit digitH to 1 max... or am I looking at it the wrong way??

Tim
 

raptorbasher

New Member
Hi All,

I reworked the code and got it working , actually quite quick as well...so the code is done thanks to all for your input.

I also managed to get the alarms and max lighting values written to eeprom so they are saved and also got an option to update the rtc via the menu as well.

Next on the list is adding the temperature of two sensors, and cutting on a small fan in the hood when needed.

The intended goal is for this to run the lighting and fans on a marine aquarium, which has been converted to run on LED lighting. There is a channel for the main white reef lights and a second channel for the blue moonlights. the fade is supposed to be gentler on the inhabitants and simulate sunrise and sunset.

Regards

Tim
 
Top