IF condition problem

in Propeller 1
Is there a problem with this IF condition as I have it? I can't seem to make it work.
IF (timbuf[hours]==6) AND (timbuf[minutes]==59) AND (timbuf[seconds]=>40)
Comments
if ((timbuf[hours] == 6) && (timbuf[minutes] == 59) && (timbuf[seconds] >= 40))
Mike
PUB init | mtpl ''start objects and define 1wire addresses waitcnt(clkfreq*2+cnt) '2 seconds for TV to come on tv.start(0) ow.start(10) cognew (counter,@stack) cognew (RTCcog,@RTCstack) dira[24]:=1 'make pin 24 output for freezer 110 volt alarm 'define device addresses of temp sensors 'use spin_onewire_test to determine addresses of devices addrs0[0]:=$3e676928 'least significant long of 64 bit address shop addrs0[1]:=$87000006 'most significant long of 64 bit address A_temp := @addrs0 ' the memory location of complete 64 bit address value 'other sensors addrs1[0] :=$3F560228 addrs1[1] :=$7A000006 'coop B_temp := @addrs1 addrs2[0] :=$70056F28 addrs2[1] :=$7F011431 'boiler C_temp := @addrs2 addrs3[0] :=$045B4E28 addrs3[1] :=$6F011431 'Outside D_temp := @addrs3 addrs4[0] :=$2BD92B28 addrs4[1] :=$E5011431 'Pen E_temp := @addrs4 addrs5[0] :=$5AE5AA28 addrs5[1] :=$B202131C 'TV_RM freezer F_temp := @addrs5 addrs6[0] :=$C59EAA28 addrs6[1] :=$D402131C 'Cave freezer G_temp := @addrs6 addrs7[0] :=$BB6DAA28 addrs7[1] :=$8102131C 'Pantry freezer H_temp := @addrs7 flag:=0 index:=1 { setconfig(12,0,0) 'leave commented out unless you want to change the ' resolution of all the devices } main PUB main ''loop waitcnt(clkfreq*2+cnt) 'wait for time keeping things to get started OSsensor :=readTemperature(D_temp) OSmin:=OSsensor frstBrnHrs:=timbuf[hours] 'preload 1st burn clock frstBrnMints:=timbuf[minutes] oldHours:=(timbuf[hours]) oldMints:=(timbuf[minutes]) oldDay:=(timbuf[day]) tv.move(1,28) tv.hex((oldHours & %0011_1111),2) 'the & %0011_1111 gets rid of extra character in hours display ? tv.str(string(":")) tv.hex(oldMints,2) tv.str(string(" ")) tv.str(lookup(oldDay:string("SUN"),string("MON"),string("TUE"),{ }string("WED"),string("THU"),string("FRI"),string("SAT"))) repeat 'Get readings from sensors ShopSens:=readTemperature(A_temp) 'shop waitcnt(clkfreq/10+cnt) CoopSens:=readTemperature(B_temp) 'coop waitcnt(clkfreq/10+cnt) BoilerSens:=readTemperature(C_temp) 'boiler waitcnt(clkfreq/10+cnt) OSsensor :=readTemperature(D_temp) 'OS IF (OSsensor < OSmin) AND (timbuf[seconds] =<3) ' OSmin:=OSsensor - 1 'update low temp (done pre conversion to °F) 'but restricted by time oldHours:=(timbuf[hours]) oldMints:=(timbuf[minutes]) oldDay:=(timbuf[day]) waitcnt(clkfreq/10+cnt) PenSens:= readTemperature(E_temp) 'pen waitcnt(clkfreq/10+cnt) TVsens:= readTemperature(F_temp) 'TV rm freezer TVout:=output waitcnt(clkfreq/10+cnt) caveSens:= readTemperature(G_temp) 'cave freezer CaveOut:=output waitcnt(clkfreq/10+cnt) PantrySens:= readTemperature(H_temp) 'pantry freezer PanOut:=output waitcnt(clkfreq/10+cnt) 'display temps TV.move(1,1) tv.out($08) 'backspace tv.str(string("Outside = ")) showf(OSsensor,0) tv.move(1,17) tv.str(string("LOW ")) tv.move(1,21) showf(OSmin,0) 'show time of LOW reading tv.move(1,28) tv.hex((oldHours & %0011_1111),2) 'the & %0011_1111 gets rid of extra character in hours display ? tv.str(string(":")) tv.hex(oldMints,2) tv.str(string(" ")) tv.str(lookup(oldDay:string("SUN"),string("MON"),string("TUE"),{ }string("WED"),string("THU"),string("FRI"),string("SAT"))) tv.move(2,1) tv.out($08) tv.str(string("Machine Shop = ")) showf(ShopSens,0) tv.str(string(13,"Chicken Coop = ")) showf(CoopSens,0) tv.str(string(13,"Chicken Pen = ")) showf(PenSens,0) tv.str(string(13,"Boiler Water = ")) 'now on row 5 ? showf(BoilerSens,0) IF INA[23]==1 AND flag==0 'when signal appears on pin 23 from boiler fan via optocoupler AND flag not set ms:= 0 'clear counter flag:=1 'set flag to prvent this again tv.move(7,1) tv.str(string(" ")) 'clear line tv.move(7,7) tv.str(string("Fan and Furnace are ON!")) beep1 IF index=>34 'if past 6th position index:=0 'reset index to 1st position IF rowcnt==1 'if already on line 10 rowcnt:=0 'go back to line 9 tv.move(9,1) 'clear lines 9 & 10 tv.str(string(" ",13)) tv.str(string(" ")) frstBrnHrs:=timbuf[hours] 'update 1st burn clock frstBrnMints:=timbuf[minutes] ELSE rowcnt:=1 'if not already on line 10 go there IF flag==1 BurnTime:=ms tv.move(8,1) tv.str(string("BurnTimes; Oldest First at ")) tv.hex((frstBrnHrs & %0011_1111),2) 'the & %0011_1111 gets rid of extra character in hours display ? tv.str(string(":")) tv.hex(frstBrnMints,2) 'IF index==1 AND rowcnt==0 AND burnTime =<4 tv.move(row+rowcnt,collunm+index) '1st position is row 9, collunm 1 tv.dec(burnTime) IF burnTime=>1200 AND burnTime=< 1210 'low wood warning beep3 IF INA[23]==0 AND flag==1 'when fan goes off AND flag set flag:=0 'clear flag, ready for next burn cycle tv.move(7,1) tv.str(string(" Draft Fan is off ")) burnTime:=0 beep2 index+=5 '1,6,11,16,21,26,31 'increment index for next cycle 'show freezer temperatures tv.move(11,1) tv.out($08) 'backspace tv.str(string("TV Freez ")) showf(TVsens,0) tv.str(string(" Cave ")) showf(CaveSens,0) tv.str(string(" Pantry ")) showf(pantrySens,0) tv.move(12,1) tv.out($08) 'backspace tv.str(string("Current time is ")) tv.hex(timbuf[hours] & %0011_1111,2) 'the & %0011_1111 gets rid of extra character in hours display ? tv.str(string(":")) tv.hex(timbuf[minutes],2) IF ||TVout < 62 'absolute value of ~~dsOut 62=25°F lower value = higher temp FreezWarn IF ||CaveOut < 62 'absolute value of ~~dsOut 62=25°F lower value = higher temp FreezWarn IF ||PanOut < 106 'absolute value of ~~dsOut 106=20°F lower value = higher temp FreezWarn ' outa[24]~~ 'sound loud 110v alarm through relay and manual switch 'Reset low for a new day IF (timbuf[hours]==9) AND (timbuf[minutes]==59) AND (timbuf[seconds]=>40) OSmin:=OSsensor 'output 426 = 80F 'reset low temp & time oldHours:=(timbuf[hours]) oldMints:=(timbuf[minutes]) oldDay:=(timbuf[day]) PUB RTCcog I2C.start(SCL,SDA,bitrate) repeat 'display time at lower center of screen waitcnt(clkfreq+cnt) I2C.readbytes(RTC,0,@timbuf,7) IF INA[16] ==1 'DST/CST switch for daylight savings time timbuf[hours] := timbuf[hours] + 1 'this will be summer (spring ahead)
I base this on these lines, where you're handling the display of the values in hex:
tv.hex((oldHours & %0011_1111),2) 'the & %0011_1111 gets rid of extra character in hours display ? tv.str(string(":")) tv.hex(oldMints,2)
This means that you need to convert the value from BCD to binary before any comparisons.
'This code should work but I haven't tested it... PRI GetBinFromBCD(bcdVal) result := ((bcdVal & $30) >> 4) * 10 + (bcdVal & $0F)
Walter
tv.hex(timbuf[hours] & %0011_1111,2) 'the & %0011_1111 gets rid of extra character in hours display ?
This implies that there are non-zero bits beyond the 6 least significant bits. Your IF statement doesn't account for this possibility. Maybe that is what's causing the problem. The other potential problem is that the seconds comparison uses "=>40", which means that the low temperature resets when the hours and minutes match your criteria, and the seconds are between 40 and 59. I don't know how fast timbuf is updated or how fast the main repeat loop runs, but maybe you are missing the 10-second window that your IF conditional uses. Or maybe timbuf isn't being updated fast enough.For this chip, the high bit has to be set for 12 hour mode (instead of 24 hour mode).
Which means that Aaron's code will need to also account for AM/PM when making the time comparison. Otherwise it will trigger twice a day.
wmosscrop
The RTC is a DS3231N and yes it is BCD output. I'll have to play with your conversion code. I also found this one in my old notes.
return (((BCD >> 4) * 10) + (BCD & $F))
. Don't know if they work similar.I'm displaying 24 hour mode.
Dave Hein
That brings up a second minor problem in that when the hour should read 10 it actually reads 0A. I've done RTC displays before and not had this problem. Must have used a different code then but can't find it.
The timbuf is a global byte VAR (IE) BYTE timbuf[7].
The RTC updates once per second (RTC COG) and the main loop takes about 4 - 6 seconds.
Thanks
Aaron
In addition, bit 6 is used to denote PM status in 12 hour mode.
In other words, 10 PM in 12 hour mode would have the binary value %0101_0000.
Your code won't work, it needs to strip off the high 2 bits of the value:
return ((((BCD & $30) >> 4) * 10) + (BCD & $F))
IF (timbuf[hours]==$6) AND (timbuf[minutes]==$59) AND (timbuf[seconds]=>$40)
If your using the 24-hour format you don't need to mask off the upper 2 bits. They will always be 0.IF INA[16] ==1 'DST/CST switch for daylight savings time timbuf[hours] := timbuf[hours] + 1 'this will be summer (spring ahead)
If timbuf[hours] has a value of $09 you will get $0A after the adjustment, which is not a valid BCD number. Also if the value was $23 you will get $24 instead of $00. You need to test for those special cases, so your code should look like this:IF INA[16] ==1 'DST/CST switch for daylight savings time timbuf[hours] := timbuf[hours] + 1 'this will be summer (spring ahead) IF timbuf[hours] == $0A timbuf[hours] := $10 ELSEIF timbuf[hours] == $24 timbuf[hours] := $00
Aaron
As usual, when I ask a question on this forum I learn more than I expected.
Aaron