PDA

View Full Version : PWM/Temp setting help with math? or code.



wdmagic
- 3rd March 2013, 16:34
Ive got a problem with some code math, ive got some code that should work but i would like to get it a little more accurate and or just better.
Heres the issue,
A temprature is set into a variable called HighTemp
The PWM needs to have a minimum Pulse Width of 25%
The PWM needs to increase when Hightemp is greater than say 100 degrees and reaches 100% at 125 degrees
Temps read are from 60 to 140 degrees, so even at 60 the PWM should be at 25%

existing code:

HighTemp = ((HighTemp - 100)* 16) + 55
if HighTemp > 255 then HighTemp = 255
HPWM 1, HighTemp, 1000 'Freq = 1khz, HighTemp max is 255

so if HighTemp = 70 then
70 - 100 = 0, 0 * 16 = 0, 0 + 55 = 55, so PWM is set to 55 (roughly 20%)

if HighTemp = 101 then
101 - 100 = 1, 1 * 16 = 16, 16 + 55 = 81
and hereafter each degree increments the setting by 16. its kind of inacurate, I would like to replace this code with better code/math

HenrikOlsson
- 3rd March 2013, 17:01
Hi,
Is the minimum duty cycle 20 or 25%, you claim both....
If the minimum dutycycle is 25% you have 192 dutycycle values to be "spread across" 25 degrees, each degree represents a change in dutycycle of 192/25=7.68


IF HighTemp > 100 THEN
Duty = 64 + ((HighTemp - 100) */ 1958) ' If HighTemp is 125 duty will be 64+(25*1958/256)=255. If HighTemp is 110 Duty will be 64+(10*1958/256)=140
ELSE
Duty = 64 ' 25% Dutycycle
ENDIF
If Duty > 255 THEN DUTY = 255
To get more resolution you need to increase the resolution of the input variable.

/Henrik.

aratti
- 3rd March 2013, 17:02
I would do it this way:

If temp < 100 then
Duty = 25
Else
Duty = 25 + ((temp -100)*3)
Endif

Cheers

Al.

wdmagic
- 3rd March 2013, 18:16
that looks pretty good henrik, no I didn't say "20 or 25%, you claim both...." I said it needs to be 25% and existing is 20%, but thats ok, yes it needs to be 25%
I forgot what does "*/" do again?


and arrati, that code is basically what I had started with but didnt work because the end result max would have been 100 and I needed it to be 255, see henrik's code, he did 25% of 255 which is 64, I wasnt thinking when i made my code 55 and then I ended up getting a 20% minimum. numbers are important a decimal in the wrong place, 1 didgit off can ruin code. but thanks, everyones Ideas help somewhere even if its not today. :)

HenrikOlsson
- 3rd March 2013, 18:54
Hi,

The */ operator multiplies the two values you give it and the discards the least significant byte of the result. It's the same thing as first multiplying then dividing by 256. The good thing is that intermeditate result can be large within limits and you won't overflow like you would if you did the same thing "manually".

Put another way, the */ operator multiplies by units of 1/256. So:
100 */ 64 = 25
100 */ 128 = 50
100 */ 256 = 100
100 */ 384 = 150
100 */ 512 = 200
and so on.

Lets say you have a value of 123 and want to multiply it by say 3.477 (the correct answer is 427.67). To find the number to use with the */ operator all you need to do is 3.477*256=890. 123*/890 will return 427.

/Henrik.

wdmagic
- 3rd March 2013, 23:35
ohhhhh ok, thats actually kinda cool.
that would have helped alot in the past, I'm using LONG's now to get my accuracy in other projects up to 6 decimals deep. but I can see where this would come in handy.

Thanks.

LinkMTech
- 4th March 2013, 00:29
Sorry if I'm hijacking here but wanted thank you Henrik for the cool tip!
I've been experimenting with a 2000dps gyroscope that outputs a max of 32757 counts.
Then with the resolution at 0.07dps, I had to use LONG's to make (32757*0.07=2292.99dps) work.



INTxg VAR WORD
Xg VAR LONG

INTxg = (Xg*7)/100 ' Xg max value =32757


*** changed to ***


INTxg VAR WORD
Xg VAR WORD

INTxg = Xg*/18 ' 0.07*256=17.92 for (32757*18)/256=2303, rounding up only 0.43% error at max



I didn't know if it would work without LONGs but it did, and trimmed 1356 Words in my program!