andywpg
- 24th February 2015, 16:57
First off, I should mention that math and I don't get along very well..... :)
I doing a complete redesign of my charcoal smoker temperature controller. It worked very well, but I made some hardware mistakes when I designed the board, and I ran out of memory on the 16F886 I was using BEFORE I ran out of features I wanted to add.
To that end, I redesigned the board for an 18F2550, and decided on a fresh start with the program as I made some poor efficiency decisions on the first one. I am using Henrik's PID routines as before, and DT's Analog oversampling this time.
I want to have the temperature displays have one decimal place instead of just integer, so I am trying to comprehend the floating point example in 4FUNC.BAS (provided by MELabs). I am currently at work (testing a fire alarm system in a huge building), but I am basically sitting here while the Sprinkler Fitter moves around sending in his signals once in a while. That means I have time to play a bit.
C_TEMP and COOK_ADJUST are word variables.
Can someone 'vet' the following code and let me know if I'm on the right track here? Any suggestions or advice would be appreciated. I have tried to whittle down the example code so it only works for one decimal place. I have included the 18F 24-bit include file at the beginning of the program.
Thanks
C_TEMP = C_TEMP * 100 'MULTIPLY RAW ADC READING BY 100 THEN DIVIDE BY CALIBRATION VALUE TO GET
'CELCIUS TEMPERATURE
aint = C_TEMP
resulthold = aint
Gosub itofa ' Convert aint to float
bint = COOK_ADJUST 'DIVIDE BY ADJUST VALUE TO GET CELCIUS
Gosub itofb ' Convert int to float
Gosub fpdiv ' FP divide (/ COOK_ADJUST)
resulthold = aint 'STORE RESULT OF DIVISION IN RESULTHOLD
'NOW NEED TO CONVERT CELCIUS TO FARENHEIGHT
'F = ((C * 9) / 5) + 32
Gosub itofa ' Convert aint to float aint=result from divide
bint = 9
Gosub itofb ' Convert int to float
Gosub fpmul ' FP multiply (*9)
resulthold = aint 'STORE RESULT OF MULTIPLICATION IN RESULTHOLD
Gosub itofa ' Convert int back to float - aint=result from multiply
bint = 5
Gosub itofb ' Convert int to float
Gosub fpdiv ' FP divide (/5)
resulthold = aint 'STORE RESULT OF DIVISION IN RESULTHOLD
Gosub itofa ' Convert aint to float
bint = 32
Gosub itofb ' Convert bint to float
Gosub fpadd ' FP add (+32)
fpplaces = 1 'DISPLAY WITH ONE DECIMAL PLACE
Gosub fpdisplayr ' Call display routine
'OTHER STUFF
fpdisplayr:
'I DISPENSED WITH THE IF STATEMENTS, ONLY EVER WANT ONE DECIMAL PLACE
' Set floating point barg to 0.05
bexp = $7A
bargb0 = $4C
bargb1 = $CD
fpdisplay:
bexp = aexp ' Store the FP value of aarg to the barg variables
bargb0 = aargb0
bargb1 = aargb1
Gosub ftoia ' Convert aarg to integer
ahold = aint ' Save this value for the final display
Gosub itofa ' Convert integer back to float
Swap aexp,bexp ' Swap the FP values of aarg and barg before subtraction
Swap aargb0,bargb0
Swap aargb1,bargb1
Gosub fpsub ' Subtract the integer portion from the full number
bint = 10 ' Make bint = 10 E fpplaces
Gosub itofb ' Convert bint to integer prior to FP multiply
Gosub fpmul ' Multiply the decimal portion x 10 E fpplaces
Gosub ftoia ' Convert result to aint integer
'DISPLAY CT:xxx.x COOKER TEMP TO ONE DECIMAL PLACE
Lcdout $FE, 1, "CT:", dec abs ahold, ".", dec abs aint
RETURN
I doing a complete redesign of my charcoal smoker temperature controller. It worked very well, but I made some hardware mistakes when I designed the board, and I ran out of memory on the 16F886 I was using BEFORE I ran out of features I wanted to add.
To that end, I redesigned the board for an 18F2550, and decided on a fresh start with the program as I made some poor efficiency decisions on the first one. I am using Henrik's PID routines as before, and DT's Analog oversampling this time.
I want to have the temperature displays have one decimal place instead of just integer, so I am trying to comprehend the floating point example in 4FUNC.BAS (provided by MELabs). I am currently at work (testing a fire alarm system in a huge building), but I am basically sitting here while the Sprinkler Fitter moves around sending in his signals once in a while. That means I have time to play a bit.
C_TEMP and COOK_ADJUST are word variables.
Can someone 'vet' the following code and let me know if I'm on the right track here? Any suggestions or advice would be appreciated. I have tried to whittle down the example code so it only works for one decimal place. I have included the 18F 24-bit include file at the beginning of the program.
Thanks
C_TEMP = C_TEMP * 100 'MULTIPLY RAW ADC READING BY 100 THEN DIVIDE BY CALIBRATION VALUE TO GET
'CELCIUS TEMPERATURE
aint = C_TEMP
resulthold = aint
Gosub itofa ' Convert aint to float
bint = COOK_ADJUST 'DIVIDE BY ADJUST VALUE TO GET CELCIUS
Gosub itofb ' Convert int to float
Gosub fpdiv ' FP divide (/ COOK_ADJUST)
resulthold = aint 'STORE RESULT OF DIVISION IN RESULTHOLD
'NOW NEED TO CONVERT CELCIUS TO FARENHEIGHT
'F = ((C * 9) / 5) + 32
Gosub itofa ' Convert aint to float aint=result from divide
bint = 9
Gosub itofb ' Convert int to float
Gosub fpmul ' FP multiply (*9)
resulthold = aint 'STORE RESULT OF MULTIPLICATION IN RESULTHOLD
Gosub itofa ' Convert int back to float - aint=result from multiply
bint = 5
Gosub itofb ' Convert int to float
Gosub fpdiv ' FP divide (/5)
resulthold = aint 'STORE RESULT OF DIVISION IN RESULTHOLD
Gosub itofa ' Convert aint to float
bint = 32
Gosub itofb ' Convert bint to float
Gosub fpadd ' FP add (+32)
fpplaces = 1 'DISPLAY WITH ONE DECIMAL PLACE
Gosub fpdisplayr ' Call display routine
'OTHER STUFF
fpdisplayr:
'I DISPENSED WITH THE IF STATEMENTS, ONLY EVER WANT ONE DECIMAL PLACE
' Set floating point barg to 0.05
bexp = $7A
bargb0 = $4C
bargb1 = $CD
fpdisplay:
bexp = aexp ' Store the FP value of aarg to the barg variables
bargb0 = aargb0
bargb1 = aargb1
Gosub ftoia ' Convert aarg to integer
ahold = aint ' Save this value for the final display
Gosub itofa ' Convert integer back to float
Swap aexp,bexp ' Swap the FP values of aarg and barg before subtraction
Swap aargb0,bargb0
Swap aargb1,bargb1
Gosub fpsub ' Subtract the integer portion from the full number
bint = 10 ' Make bint = 10 E fpplaces
Gosub itofb ' Convert bint to integer prior to FP multiply
Gosub fpmul ' Multiply the decimal portion x 10 E fpplaces
Gosub ftoia ' Convert result to aint integer
'DISPLAY CT:xxx.x COOKER TEMP TO ONE DECIMAL PLACE
Lcdout $FE, 1, "CT:", dec abs ahold, ".", dec abs aint
RETURN