PDA

View Full Version : How to swap a variable?



jessey
- 18th June 2010, 12:34
Hello Everyone,

I'm trying to swap Radiator_temp and Block_temp into a temp variable before reading the temperature of two DS1820 in the code below and can't seem to get it right. I've only included 2 subroutines below that are part of a bigger program to make it easier to read and I compiled the code below as it is and I get the same results.

I have 2 DS1820's and am reading one at a time in each pass through the mainloop to speed up using my push buttons. I try and use: Sensor_Select = Radiator_Sensor : Radiator_temp = temp : GOSUB Check_Temperature

Then on the next pass through the mainloop I use: Sensor_Select = Block_Sensor : Block_temp = temp : GOSUB Check_Temperature

With that code then I warm up the Block_Sensor it shows the temperature rise to the Radiator_Sensor on my Lcd but if I mix it up a bit and write the code like this: Sensor_Select = Block_Sensor : Radiator_temp = temp : GOSUB Check_Temperature and the same with the Radiator_Sensor then it displays properly?

Anyone have any idea of what's going on here, it's working ok but the logic is very confusing to say the least. Any help with this would be very much appreciated.

Thanks In Advance
jessey






'************************************************* ******************************
'* Name : Two Ds1820 18F452.bas *
'* Author : Jessey Montgomery *
'* Includes : STRINGS.PBP By Darrel Taylor *
'* Notice : Copyright (c) 2004 *
'* : All Rights Reserved *
'* Date : 22/10/2005 *
'* Version : Using PicBasic Pro Ver 2.50, MPASM Ver 5.20, Using MicroCode *
'* : Studio 3.0.0.5, PICkit 2 programmer - Application Version *
'* : 2.50.02 - Device File Version 1.5100 - OS Firmware Version *
'* : 2.30.01. Using a PIC18f452-20/P *
'************************************************* ******************************

' --------------
' | 18F452 |
' MCLR/Vpp ------> |1 40| <-----> RB7/PGD
' RA0/AN0 <-----> |2 39| <-----> RB6/PGC
' RA1/AN1 <-----> |3 38| <-----> RB5/PGM
' RA2/AN2/Vref- <-----> |4 37| <-----> RB4
' RA3/AN3/Vref+ <-----> |5 36| <-----> RB3/CCP2*
' RA4/TOCK1 <-----> |6 35| <-----> RB2/INT2
' RA5/AN5/SS/LVDIN <-----> |7 34| <-----> RB1/INT1
' RE0/RD/AN5 <-----> |8 33| <-----> RB0/INT0
' RE1/WR/AN6 <-----> |9 32| <----- Vdd
' RE2/CS/AN7 <-----> |10 31| <----- Vss
' Vdd -----> |11 30| <-----> RD7/PSP7
' VSS -----> |12 29| <-----> RD6/PSP6
' OSC1/CLK1 -----> |13 28| <-----> RD5/PSP5
' OSC2/CLKO/RA6 <------ |14 27| <-----> RD4/PSP4
' RC0/T1OSO/TICK1 <-----> |15 26| <-----> RC7/RX/DT
' RC1/T1OSI/CCP2* <-----> |16 25| <-----> RC6/TX/CK
' RC2/CPP1 <-----> |17 24| <-----> RC5/SDO
' RC3/SCK/SCL <-----> |18 23| <-----> RC4/SD1/SDA
' RD0/PSP0 <-----> |19 22| <-----> RD3/PSP3
' RD1/PSP1 <-----> |20 21| <-----> RD2/PSP2
' --------------


'------------------------------------------------------------------------------'
'-- Clear All The Variables And Each Port Before Setting The TRIS Registers ---'
'------------------------------------------------------------------------------'

Clear 'Set all ram registers to zero
PORTA = 0
PORTB = 0
PORTC = 0
PORTD = 0
PORTE = 0

'--------------------------- VSS VDD MCLR Ect. Pins ---------------------------'

'MCLR (Pin 1)
'VDD (Pin 11)
'VSS (Pin 12)
'OSC/CLKIN (Pin 13)
'OSC2/CLKOUT (Pin 14)
'VSS (Pin 31)
'Vdd (Pin 32)

'((OPTION_REG=127 ' ENABLE WEAK PULL UP RESISTORS ON PORTB))

'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
'XXXXXXXXXXXXXXXXXXXXXXXXXX Set The TRIS In/Out Pins XXXXXXXXXXXXXXXXXXXXXXXXXX'
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX BELOW XXX'

'-------------------- PORTA PINS --------------------'
TRISA.0 = 1 '(pin 2) ........................Adj_Dn_Button VAR PORTA.0 ' pin 2
TRISA.1 = 1 '(pin 3) ........................Adj_Up_Button VAR PORTA.1 ' pin 3
TRISA.2 = 1 '(pin 4) .......................Adj_Dn_Button2 VAR PORTA.2 ' pin 4
TRISA.3 = 1 '(pin 5) .......................Adj_Up_Button2 VAR PORTA.3 ' pin 5
TRISA.4 = 1 '(pin 6) NOT USED
TRISA.5 = 1 '(pin 7) NOT USED

'-------------------- PORTB PINS --------------------'
TRISB.0 = 1 '(pin 33) ........................................DS1820 Rad_Sensor
TRISB.1 = 1 '(pin 34) NOT USED VAR PORTB.1 'pin 34
TRISB.2 = 1 '(pin 35) NOT USED VAR PORTB.2 'pin 35
TRISB.3 = 0 '(pin 36) ..............................The_Led VAR PORTB.3 'pin 36
TRISB.4 = 1 '(pin 37) NOT USED VAR PORTB.4 'pin 37
TRISB.5 = 1 '(pin 38) NOT USED VAR PORTB.5 'pin 38
TRISB.6 = 1 '(pin 39) NOT USED VAR PORTB.6 'pin 39
TRISB.7 = 1 '(pin 40) NOT USED VAR PORTB.7 'pin 40

'-------------------- PORTC PINS --------------------'
TRISC.0 = 1 '(pin 15) ......................................DS1820 Block_Sensor
TRISC.1 = 1 '(pin 16) ...................Change_Mode_Button VAR PORTC.1 'pin 16
TRISC.2 = 1 '(pin 17) ....................Block_Code_Button VAR PORTC.2 'pin 17
TRISC.3 = 1 '(pin 18) NOT USED VAR PORTC.3 'pin 18
TRISC.4 = 1 '(pin 23) NOT USED VAR PORTC.4 'pin 23
TRISC.5 = 1 '(pin 24) NOT USED VAR PORTC.5 'pin 24
TRISC.6 = 1 '(pin 25) NOT USED VAR PORTC.6 'pin 25
TRISC.7 = 1 '(pin 26) NOT USED VAR PORTC.7 'pin 26

'-------------------- PORTD PINS --------------------'
TRISD.0 = 1 '(pin 19) NOT USED VAR PORTD.0 'pin 19
TRISD.1 = 0 '(pin 20) ................................Buzzer VAR PORTD.1 'pin 15
TRISD.2 = 0 '(pin 21) ...............................The_Fan VAR PORTD.2 'pin 21
TRISD.3 = 1 '(pin 22) NOT USED VAR PORTD.3 'pin 22
TRISD.4 = 0 '(pin 27) ...........................Lcd out for Data bit 4
TRISD.5 = 0 '(pin 28) ...........................Lcd out for Data bit 5
TRISD.6 = 0 '(pin 29) ...........................Lcd out for Data bit 6
TRISD.7 = 0 '(pin 30) ...........................Lcd out for Data bit 7

'-------------------- PORTE PINS --------------------'
TRISE.0 = 0 '(pin 8) ...........................LCD Register/Select
TRISE.1 = 0 '(pin 9) ...........................LCD Enable
TRISE.2 = 1 '(pin 10) NOT USED PORTE.2


;================================================= =========================
;@ __CONFIG _CONFIG1H, _OSCS_ON_1H & _XT_OSC_1H ' use this one for 4 mhz and
' also declare the osc as 4mhz
@ __CONFIG _CONFIG1H, _OSCS_OFF_1H & _HSPLL_OSC_1H ; use this one for 16 mhz
@ __CONFIG _CONFIG2L, _BOR_OFF_2L & _BORV_20_2L & _PWRT_ON_2L
@ __CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_128_2H
@ __CONFIG _CONFIG3H, _CCP2MX_OFF_3H
@ __CONFIG _CONFIG4L, _STVR_OFF_4L & _LVP_OFF_4L & _DEBUG_OFF_4L
@ __CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L
@ __CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
@ __CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L
@ __CONFIG _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
@ __CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L
@ __CONFIG _CONFIG7H, _EBTRB_OFF_7H


DEFINE OSC 16 ' using HSPLL X 4 gives us OSC 16
@ errorlevel -306 ; turn off the Crossing page boundary warnings

Define LCD_DREG PORTD
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1

ADCON1 = 7 ' Set to Digital


'used for temperature'
'--------------------'
count_remain VAR BYTE ' Count remaining
count_per_c VAR BYTE ' Count per degree C
Sensor_Select VAR Byte ' this var allows 2 sensors to be read
Radiator_Sensor con 8 ' Sensor on PortC.0 One-wire data pin (pin 15)
Block_Sensor con 0 ' Sensor on PortB.0 One-wire data pin (pin 33)
temp Var Word ' temporary storage for Block_temp & Radiator_temp
Block_temp Var Word ' Temperature storage
Radiator_temp Var Word ' Temperature storage


INCLUDE "EE_Vars.PBP"

'Declare The EE Variable' 'Load A Default Setting For The EE Variable'
'=======================' '=========================================='
Temp_Mode VAR BYTE : @ EE_var _Temp_Mode, BYTE,1


' Allocate variables '
' ================== '
a var byte ' Enables if..then statements to execute without
a = 0 ' using GOTO's, a always equals 0
b Var Word ' counter to detect a sensor malfunction
I Var Byte ' This variable speeds up button presses by only
I = 0 ' reading one sensor at a time then displaying.

'Pushbuttons Variables '
'===================== '
Block_Code_Button VAR PORTC.2 ' pin 17

'Port pins Variables '
'=================== '
Buzzer VAR PORTD.1 ' pin 20
The_Fan VAR PORTD.2 ' pin 21

Fahrenheit con 1
Celsius CON 0
Is_On CON 1
Is_Off CON 0
Is_Pressed CON 0
Is_Not_Pressed CON 1

LCDOUT 254,64,28,20,28,0,0,0,0,0 ' Cust Char #0, Temp degree sign

Pause 1000' wait for Lcd to initialize

LCDOut $fe, 1, "Taurus Controler"
LCDOut $fe, $c0, "Jessy Montgomery"

PAUSE 2000

If a = 0 Then mainloop' Skip subroutines


Check_Temperature:

OWOut Sensor_Select, 1, [$CC, $44] ' Start the Temp conversion
waitloop:
If count_remain = 0 Then b = b + 1''''''''
If b >= 20000 then '
Loop_5: '
If Sensor_Select = Block_Sensor then '
LCDOut $fe, 1, "Block Sensor Has" '
Else ' If it's Radiator_Sensor ' This detects a sensor malfunction
LCDOut $fe, 1, " Rad Sensor Has " ' in 2.5 seconds.
Endif '
LCDOut $fe, $c0, "!Malfunctioned! " ' Rad sensor will sound the alarm if
PWM Buzzer,255,100 ' the positive or the 4.7K resistor
The_Fan = Is_On ' is dissconnected from the DS1820
Pause 100 '
IF Block_Code_Button = Is_Pressed THEN' Block sensor will only sound the
While Block_Code_Button = Is_Pressed' alarm if the 4.7K resistor is
Wend ' dissconnected?
Pause 150 '
If a = 0 then Return '
Endif '
If a = 0 then Loop_5 '
Endif'''''''''''''''''''''''''''''''''''''
OWIn Sensor_Select, 4, [count_remain]' Check for still busy converting
IF count_remain = 0 THEN waitloop
OWOut Sensor_Select, 1, [$CC, $BE] ' Read the Temp
OWIn Sensor_Select, 0, [temp.LOWBYTE, temp.HIGHBYTE, _
Skip 4, count_remain, count_per_c]
' Calculate temp in degrees Celsius to 2 decimal places
temp = ((ABS(temp) >> 1) * 100)
temp = temp - 25 + (((count_per_c - count_remain) * 100) / count_per_c)
IF Temp_Mode = Celsius then RETURN' If Mode is Fahrenheit then continue
' Convert Celsius to Fahrenheit before returning
temp = (ABS(temp) */ 461)
temp = temp + 3200
RETURN


Select_A_Sensor_To_Read:

If I = 0 then'' This code here speeds up button presses
I = 1 ' by only reading one sensor then displaying
else ' the results instead of reading two sensors
I = 0 ' before displaying the results.
Endif''''''''''

If I = 0 Then''''''''''''''''''''
Sensor_Select = Radiator_Sensor' This is a little convoluted to say the
'SWAP temp, Radiator_temp ' least but it works, how and why I have no
'Radiator_temp = temp ' idea. If I uncomment the commented out code
Block_temp = temp ' lines and use them the way you would think
GOSUB Check_Temperature ' it should work then the program switches
Endif ' sensors around i.e. instead of reading the
' Radiator_Sensor on pin 15 it then reads
If I = 1 Then ' the sensor on 33 even though it's declared
Sensor_Select = Block_Sensor ' on pin 15 and vice versa for the
'SWAP temp, Block_temp ' DS1820 Block_Sensor. So it switches the
'Block_temp = temp ' two sensors, very confusing! It must be in
Radiator_temp = temp ' way I'm swaping Rad & Block_temp into the
GOSUB Check_Temperature ' temp variable but I also tried SWAP with
Endif ' the same results.
Return''''''''''''''''''''''''''''''

mainloop:

Gosub Select_A_Sensor_To_Read
b = 0

If Temp_Mode = Fahrenheit Then
LCDOut $FE, 1, "Radiator = ", DEC Radiator_temp / 100,0,"F"
LCDOut $fe, $c0, " Block = ", DEC Block_temp / 100,0,"F"
Else ' If Temp_Mode = Celsius
LCDOut $FE, 1, "Rad Temp = ", DEC Radiator_temp / 100,0,"C"
LCDOut $fe, $c0, " Block = ", DEC Block_temp / 100,0,"C"
Endif

Pause 100

If a = 0 then mainloop

End

mark_s
- 18th June 2010, 16:31
Hello,

Not sure if this will help you. The receiving variable is always on the left side

In this statement you are moving the contents of temp into Block_temp

Block_temp = temp

The way I read your question you wanted to store or move the contents of Block_temp into
temp?

temp = Block_temp

Regards
Mark

jessey
- 18th June 2010, 17:40
In this statement you are moving the contents of temp into Block_temp - Block_temp = temp


Hi Mark,

Yes that's correct, I want to move the contents of temp into Radiator_temp on the first pass in the mainloop so I can see the temperature on the first line of my Lcd then on the second pass I change the Sensor_Select to be the Block_Sensor and then want to load temp into Block_temp so I can see it on the second line of the Lcd. I've tried many different combinations and just can't seem to get that to work. It does work and display properly if I mix it up like my code shows above, but it's a puzzler for me and I can't figure why that works and if it'll be reliable.

Thanks
jessey

mark_s
- 18th June 2010, 19:07
Hi Jessey,

I noticed in your 1st subroutine "Select_A_Sensor_To_Read:" you are swapping your variables before the gosub to "Check_Temperature:" . What happens if you read the temperature first
right before the swap statement. The last sensor reading will now be in the temp variable. It can now be stored in Radiator_Temp or Block_temp. The way you have it now it reads the temperature to temp and exits the subroutine.

Try this
Add a new variable Old_temp

If I = 0 Then''''''''''''''''''''

Sensor_Select = Radiator_Sensor' This is a little convoluted to say the
GOSUB Check_Temperature ' it should work then the program switches
SWAP Old_temp, Radiator_temp ' least but it works, how and why I have no
Radiator_temp = temp ' idea. If I uncomment the commented out code


Endif ' sensors around i.e. instead of reading the
' Radiator_Sensor on pin 15 it then reads
If I = 1 Then ' the sensor on 33 even though it's declared
Sensor_Select = Block_Sensor ' on pin 15 and vice versa for the
GOSUB Check_Temperature ' it should work then the program switches
SWAP Old_temp, Block_temp ' DS1820 Block_Sensor. So it switches the
Block_temp = temp ' two sensors, very confusing! It must be in


Endif
Return''''''''''''''''''''''''''''''

jessey
- 19th June 2010, 03:35
What happens if you read the temperature first right before the swap statement. The last sensor reading will now be in the temp variable. It can now be stored in Radiator_Temp or Block_temp. The way you have it now it reads the temperature to temp and exits the subroutine.

Thanks Mark,

That's all it took, I changed it like you suggested and it works perfectly now. Thanks for your help I really appreciate it.

Thanks Again
jessey



If I = 0 Then
Sensor_Select = Radiator_Sensor
GOSUB Check_Temperature
Radiator_temp = temp
Endif

If I = 1 Then
Sensor_Select = Block_Sensor
GOSUB Check_Temperature
Block_temp = temp
Endif

mark_s
- 19th June 2010, 15:45
Jessey,
Glad to hear it's working!

How are you attaching or making contact with the DS1820's to your engine? I have a
generator that I would like to experiment with a temp read out and overheat cut off.

Thanks Mark