CPU = 16F876A MHZ = 10 CONFIG 16254 ;------------------------------------------------------ ;- RS485 Thermostat for use with the HCS system - ;- Uses a www.simm6etry.com Touch screen - ;- Free for use as long as my credit stays intact - ;- Copyright 2004 - By Ron Bihler - ;------------------------------------------------------ ;Init Outputs low a1 ;turn off heat Low a2 ;Turn off Cool Low a3 ;Turn off Fan ;-------Receive Packet from RS-485 Bus & Execute Response------- ;----------HCS II PIC-Link------------------ logo1 bytetable " Mini DIO " logo2 bytetable "HCS IO Module" 'RS485 using Hardware 232 - Pin C6 & C7 enable con C5 ;Data Send Enable Pin high=send for the RS485 'Used for the LCD lcd1 con b4 ;LCD control lcd2 con b6 ;Lines lcd3 con b5 'b0-b3 used for LCD 'Used for the max3100 Uart Chip din CON C0 ;DATA I/O LINE dout con C1 ;Data Out line sclk CON C2 ;CLOCK LINE max_cs CON C3 ;RST OR CHIP SELECT LINE 'DS1202 Clock 'din,dout,sclk used clk_cs CON C4 ;Clip Select Line for Clock '** A5= i2c 27C65 eeprom for storage '** A4= i2c an0 con 0 ;Analog Port 0 clk con 2 ;Analog cycles adsetup con %10001110 ;----Packet Receive Variables------- address var byte(4) ;Module Address packet var byte(38) rsin var byte data_line var byte(20) test_data var byte i var byte ;Gen Perp x var byte ;Gen Perp counter var x ;Used as a counter timeout var byte ;Used in Menu's to return back to main menu n var byte ;used as a pointer in the packet Array_pntr var byte ;Used as a pointer for the output array to the max3100 and lcd ct var word ;Analog Data line_length var byte temp var long ;Analog Temp calc_temp var byte ;Calulated Temp Prev_temp var byte ;Previous Temp that was displayed key var byte ;Used with the touch screen sl var byte ;SL thermostat command flag 0=no, 1=yes delay var byte ;used instead of pause - does network check ;------------------------------------------------------------------ ;System Varibles. Control_status var byte ;Byte that hold current statuts of the control network_Enable var control_status.bit0 ;Switch Setting heat var control_status.bit1 ;Heat cycle on/off cool var control_status.bit2 ;Cool cycle on/off heat_enable var control_status.bit3 ;Heat Enable cool_enable var control_status.bit4 ;Cool Enable , both = auto fan_mode var control_status.bit5 ;Fan Status 0=auto 1=ON fan var control_status.bit6 update var byte update_temp var update.bit0 update_heat var update.bit1 update_cool var update.bit2 update_mode var update.bit3 update_status var update.bit4 cool_default var byte ;Default Cool SP heat_default var byte ;default heat sp cool_max var byte heat_max var byte heat_sp var byte ;Heat Set Point cool_sp var byte ;Cool Set point set_point var byte ;Temp Var for Set point adjustment cool_delay var byte home_cool var byte home_heat var byte away_cool var byte away_heat var byte ;----Packet Send Variables ReturnValue var byte Checksum var byte ;---PIC to SN75176 RS-485 Transceiver connections:---- checksum_val var byte ;PIC B0 -->SN75176, Pins 2 & 3 /RX & TX enable DIOIn var byte ;PIC B1 -->SN75176, Pin 1, RX DataByte var byte ;PIC B2 -->SN75176, Pin 5, TX DataHighNibble var byte ;RS-485+-->SN75176, Pin 6 DataLowNibble var byte ;RS-485+-->SN75176, Pin 7 DIOInASCIIHigh var byte DIOInASCIILow var byte ChecksumASCIIHigh var byte ChecksumASCIILow var byte number var word ;Used in Max3100 ml routine ;Used Data_line Array Variable, when sending a line it must be CR terminated ;Uses General purpose Variable I for array pointer ;Uses Key as byte for touch screen keypress number uart_tx var word ;Send Buffer uart_rx var word ;Receive buffer ;--------------------------------------------------------------------- ;Max3100 configuration config_word1 var word uart_fen var config_word1.bit13 uart_shdni var config_word1.bit12 uart_tm var config_word1.bit11 uart_rm var config_word1.bit10 uart_pr var config_word1.bit9 uart_ram var config_word1.bit8 uart_ir var config_word1.bit7 uart_st var config_word1.bit6 uart_pe var config_word1.bit5 uart_l var config_word1.bit4 uart_b3 var config_word1.bit3 uart_b2 var config_word1.bit2 uart_b1 var config_word1.bit1 uart_b0 var config_word1.bit0 uart_rafe var config_word1.bit10 uart_cts var config_word1.bit9 xuart_pr var config_word1.bit8 uart_d7r var config_word1.bit7 uart_d6r var config_word1.bit6 uart_d5r var config_word1.bit5 uart_d4r var config_word1.bit4 uart_d3r var config_word1.bit3 uart_d2r var config_word1.bit2 uart_d1r var config_word1.bit1 uart_d0r var config_word1.bit0 ;--------------------------------------------------------------------- 'Used for the Dallas DS1202 Time Chip 'dta CON C0 ;DATA I/O LINE 'CLK CON C2 ;CLOCK LINE 'reset CON C4 ;RST OR CHIP SELECT LINE rtccmd var byte ctemp var x ctemp1 var i bitcnt var byte 'Used as counter timedata var byte(6) oldseconds var byte oldminutes var byte seconds var timedata(0) minutes var timedata(1) hours var timedata(2) date var timedata(3) month var timedata(4) year var timedata(5) secreg con %00000 minreg con %00001 hrsreg con %00010 datereg con %00011 monreg con %00100 yrreg con %00110 ctrlreg con %00111 brstreg con %11111 preset bytetable $00,$00,$12,$20,$03,$03, c_hour var byte 'converted current hour c_min var byte 'converted current min c_sec var byte 'converted current sec ;------------------------------------------------------------------------------------------- Begin: sethserial H9600 ;Configure hardware port for 9600 baud ;------------------------------------------------------------------------------------------- Let Address(0) = "M" ;Store Link address in PIC. Let Address(1) = "A" Let Address(2) = "N" Let Address(3) = "0" number =0 packet_header var byte prev_temp=75 temp=150 ;Good starting place cool_delay=0 ;******************************************* ;*** Reset *** ;******************************************* System_reset: pause 500 ;Init LCD panel and display opening message LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [INITLCD1, INITLCD2, TWOLINE, CLEAR, HOME,SCR] ;after the first initialization no more inits. will need to be sent. LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram+3,str logo1\10,scrram+$43,str logo2\13] low enable ;Lower Enable pin to allow data into the buffer from rs485 low clk_cs ;-------------------------Init DS1202 ----------------- ctemp=$10 rtccmd=ctrlreg gosub presetdata ;Init the DS1202 ;preset time registers using a byte table preset for ctemp1=0 to 5 ctemp=preset(ctemp1) rtccmd=ctemp1 gosub presetdata next ctemp=$80 rtccmd=ctrlreg gosub presetdata ;---------------------------Init Touch Screen for Thermostat control------------------------- gosub init_uart ;--------------------------Read default data stored in eeprom------------------------ readdm 0,[str address\4,cool_default,heat_default,cool_max,Heat_max,control_status] control_status=(control_status & %10111001) ;Mask out Heat/cool bits if address(0)<>"M" then address="MAN0" endif if cool_default<65 or cool_default>100 then cool_default=80 endif if heat_default>90 or heat_default<50 then heat_default=68 endif if heat_max>90 or cool_max<60 then heat_max=90 cool_max=60 endif cool_max=50 heat_max=110 heat_sp=heat_default ;Load the default Setpoint from memory cool_sp=cool_default if fan_mode=1 then fan=1 endif ;Test for I2c ; i2cout a4,a5,%10100001,0,[44,45] ; i2cin a4,a5,%10100001,0,[rsin] ; LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram+$40,dec rsin] ; pause 1000 ;-------------------------------------------------------------------- main_refresh: gosub display_main_screen Main: ;Main loop LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram+$40," "] low enable ;Lower Enable pin to allow data into the buffer from rs485 hserstat 4, main_cont Gosub Receivepacket ;Is there data to be processed part of get_touch now main_cont: gosub check_temp ;Read current temp and process gosub get_touch ;Access the touch screen ;----------------------Touch screen pressed-Process----------------------- if key=1 then set_point=cool_sp gosub change_sp if (heat_sp+1)set_point then ;Make sure there is still a 2deg span heat_sp=set_point endif gosub display_main_screen endif if key =3 then ;Cycle Mode option i=(control_status & 24) if i=8 then ;Heats on cool_enable=1 ;switch to cool heat_enable=0 elseif i =16 ;Cool is on add heat heat_enable=1 elseif i =24 cool_enable=0 ;Both are on, switch to off heat_enable=0 elseif i =0 ;Off, switch to Heat heat_enable=1 endif prev_temp=0 update_mode=1 gosub check_notouch endif if key=4 then ;Enter System menu goto System_settings endif if cool_delay>0 then ;Set after A/C is turned off. cool_delay=cool_delay+1 endif ; Check update bits to see if any of the display needs to be updated. update_display: if update<>0 then if update_mode=1 then ;Change the Mode display - Off,Heat,Cool,Auto gosub display_mode endif if update_temp=1 then ;Update current temp data_line="NL11,",dec3 calc_temp\3,13 gosub send_uart_line gosub wait_lcd endif if update_status=1 then ;Update system status, heat on/off, cool on/off, fan on/off gosub display_current endif if update_heat=1 then data_line="NS716,",dec3 heat_sp\3," ",13 ;Update the screen gosub send_uart_line gosub wait_lcd endif if update_cool=1 then data_line="NS316,",dec3 cool_sp\3," ",13 ;Update the screen gosub send_uart_line gosub wait_lcd endif update=0 endif pause 20 goto main ;-------------------------------Read Temp---------------------------- ;-----------Service control status, heat/cool on/off ---------------- ;-------------------------------------------------------------------- check_temp: adin an0,clk,adsetup,ct ;Read in Temp from A/D port 0 temp=(temp<<2)+ct temp=(temp/5) calc_temp=(temp>>1)*/64000 ;Temp compensation gosub readdata ;Read Timechip LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram+$40,dec3 calc_temp\3,dec2 (bcd2bin hours)\2,":",dec2 (bcd2bin minutes)\2] ;--------------------------------------------------------; ; Check current temp with max temp ; ; Turn off heat & cool if the temp has over run ; ; If all runs fine this should never be used ; ;--------------------------------------------------------; if (calc_tempheat_max) and heat=1 then heat=0 update_status=1 endif ;---------------Check for change in Temp-------------------- if calc_temp<>Prev_temp then ;Change in Temparature update_temp=1 if cool=1 then ;Cooling is on! if (calc_temp <= cool_sp) or (cool_enable=0) then ;Have we reached the set-point? cool=0 ;yes turn off cool if fan_mode=0 then ;If fan is Auto then turn off fan fan=0 endif update_status = 1 cool_delay=1 ;Start delay so that compressor pressure can equalize endif else 'debug LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram+$42,dec3 cool_sp\3," ",dec1 cool_enable," ",dec3 cool_delay\3] if (calc_temp > (cool_sp)) and (cool_enable=1) and (cool_delay=0) then cool=1 fan=1 update_status=1 endif endif if heat =1 then if (calc_temp >= heat_sp) or (heat_enable=0) then heat=0 if fan_mode=0 then ;If fan is Auto then turn off fan fan=0 endif update_status=1 endif else if (calc_temp < (heat_sp)) and heat_enable=1 then heat=1 fan=1 update_status=1 endif endif prev_temp=calc_temp endif return ;-----------------------------------Display Main Screen----------------------------------- display_main_screen: data_line="C",13 ;Clear gosub send_uart_line gosub wait_lcd data_line="W0",13 ;Set LCD 5ms delay gosub send_uart_line gosub wait_lcd data_line="BC",13 ;Enable Touch Screen Overlay gosub send_uart_line gosub wait_lcd data_line="BC",13 ;Enable Touch Screen Overlay gosub send_uart_line gosub wait_lcd data_line="TM112,Cool",13 gosub send_uart_line gosub wait_lcd data_line="TM512,Heat",13 gosub send_uart_line gosub wait_lcd data_line="TM73,Menu",13 gosub send_uart_line gosub wait_lcd data_line="L13,2,49,2",13 gosub send_uart_line gosub wait_lcd data_line="L13,15,49,15",13 gosub send_uart_line gosub wait_lcd data_line="L49,2,49,15",13 gosub send_uart_line gosub wait_lcd data_line="L13,15,13,2",13 gosub send_uart_line gosub wait_lcd data_line="L80,38,128,38",13 gosub send_uart_line gosub wait_lcd data_line="L128,38,128,63",13 gosub send_uart_line gosub wait_lcd data_line="L128,63,80,63",13 gosub send_uart_line gosub wait_lcd data_line="L80,63,80,38",13 gosub send_uart_line gosub wait_lcd data_line="L80,6,128,6",13 gosub send_uart_line gosub wait_lcd data_line="L128,6,128,31",13 gosub send_uart_line gosub wait_lcd data_line="L128,31,80,31",13 gosub send_uart_line gosub wait_lcd data_line="L80,31,80,6",13 gosub send_uart_line gosub wait_lcd data_line="NS316,",dec3 cool_sp\3," ",13 gosub send_uart_line gosub wait_lcd data_line="NS716,",dec3 heat_sp\3," ",13 gosub send_uart_line gosub wait_lcd ;Used to set auto touch ; data_line=";",13 ; gosub send_uart_line ; gosub wait_lcd gosub display_current gosub display_mode return display_current: ;Current system Status (Heat/Cool/Fan) if heat=1 then data_line="TS710,Heat",13 high A2 ;Turn on Heat elseif cool=1 data_line="TS710,Cool",13 High A3 ;Turn on Cool elseif (cool=0) and (heat=0) data_line="TS710, ",13 Low A2 ;Off Heat Low A3 ;Off Cool endif gosub send_uart_line gosub wait_lcd if (control_status & %00100110) =0 then fan=0 data_line="TS810, ",13 Low A4 ;Fan Off else fan=1 High A4 ;Fan On data_line="TS810,Fan ",13 endif gosub send_uart_line gosub wait_lcd return display_mode: ;Display control status if (control_status & 24) =8 then data_line="TM53,Heat",13 elseif (control_status & 24) =16 data_line="TM53,Cool",13 elseif (control_status & 24) =24 data_line="TM53,Auto",13 else data_line="TM53,Off ",13 endif gosub send_uart_line gosub wait_lcd data_line="L13,18,49,18",13 gosub send_uart_line gosub wait_lcd data_line="L13,31,49,31",13 gosub send_uart_line gosub wait_lcd data_line="L49,18,49,31",13 gosub send_uart_line gosub wait_lcd data_line="L13,31,13,18",13 gosub send_uart_line gosub wait_lcd return ;--------------------------------System Menu #1----------------------------- system_setting_menu: data_line="C",13 ;Clear gosub send_uart_line gosub wait_lcd data_line="TM31,Set Default SP",13 gosub send_uart_line gosub wait_lcd data_line="TM51,Set Max/Min Temp",13 gosub send_uart_line gosub wait_lcd data_line="TM71, More Options ",13 gosub send_uart_line gosub wait_lcd pause 200 data_line="BA",13 ;Enable Touch Screen Overlay gosub send_uart_line gosub wait_lcd pause 50 data_line="TM11,System Setup 1/3",13 gosub send_uart_line gosub wait_lcd return ;----------------------------System Menu #2------------------------------ system_setting_menu2: data_line="C",13 ;Clear gosub send_uart_line gosub wait_lcd data_line="TM31, Set Module # ",13 gosub send_uart_line gosub wait_lcd if fan_mode=0 then data_line="TM51, Fan Mode [Auto]",13 else data_line="TM51, Fan Mode [ON] ",13 endif gosub send_uart_line gosub wait_lcd data_line="TM71, More Options ",13 gosub send_uart_line gosub wait_lcd pause 200 data_line="BA",13 ;Enable Touch Screen Overlay gosub send_uart_line gosub wait_lcd pause 50 data_line="TM11,System Setup 2/3",13 gosub send_uart_line gosub wait_lcd return system_setting_menu3: data_line="C",13 ;Clear gosub send_uart_line gosub wait_lcd data_line=" ",13 gosub send_uart_line gosub wait_lcd if network_enable=0 then data_line="TM51,Network-Disabled",13 else data_line="TM51,Network--Enabled",13 endif gosub send_uart_line gosub wait_lcd data_line="TM71, More Options ",13 gosub send_uart_line gosub wait_lcd pause 200 data_line="BA",13 ;Enable Touch Screen Overlay gosub send_uart_line gosub wait_lcd pause 50 data_line="TM11,System Setup 3/3",13 gosub send_uart_line gosub wait_lcd return ;----------------------------Default Setpoint Menu------------------------ default_menu: ;Default setpoint menu data_line="C",13 ;Clear gosub send_uart_line gosub wait_lcd data_line="TM31,Cool Set Point",13 gosub send_uart_line gosub wait_lcd data_line="TM51,Heat Set Point",13 gosub send_uart_line gosub wait_lcd data_line="TM71, Done ",13 gosub send_uart_line gosub wait_lcd pause 200 data_line="BA",13 ;Enable Touch Screen Overlay gosub send_uart_line gosub wait_lcd pause 50 data_line="TM11,Default Setpoints ",13 gosub send_uart_line gosub wait_lcd return ;-----------------------Over/Under temp settings--------------------- maxtemp_menu: ;Max Temp menu data_line="C",13 ;Clear gosub send_uart_line gosub wait_lcd data_line="TM31,Max Cool Temp",13 gosub send_uart_line gosub wait_lcd data_line="TM51,Max Heat Temp",13 gosub send_uart_line gosub wait_lcd data_line="TM71, Done ",13 gosub send_uart_line gosub wait_lcd pause 200 data_line="BA",13 ;Enable Touch Screen Overlay gosub send_uart_line gosub wait_lcd pause 50 data_line="TM11,Maximum Tempurature",13 gosub send_uart_line gosub wait_lcd return ;------------------------------Select Module #------------------------- Select_module: ;Module setup menu data_line="C",13 ;Clear gosub send_uart_line gosub wait_lcd data_line="TM51,Cancel",13 gosub send_uart_line gosub wait_lcd data_line="TM72,Save",13 gosub send_uart_line gosub wait_lcd data_line="Tm213,UP",13 gosub send_uart_line gosub wait_lcd data_line="Tm612,Down",13 gosub send_uart_line gosub wait_lcd pause 200 data_line="BC",13 ;Enable Touch Screen Overlay gosub send_uart_line gosub wait_lcd pause 50 data_line="TM11,",str address\4,13 gosub send_uart_line gosub wait_lcd return display_set_point: ;Display setpoint routine data_line="NL11,",dec3 set_point\3,13 gosub send_uart_line gosub wait_lcd return ;--------------------------------------------------- ;------------ System Settings setup----------------- ;--------------------------------------------------- system_settings: ;main level gosub System_setting_menu ;Display menu #1 timeout=0 gosub check_notouch ;Clear x=address(3) update_temp=1 setting_loop: while timeout < 35 ;Counter loop to exit gosub get_touch if key = 2 then ;Set Default Set points for system startup goto set_default elseif key = 4 ;Select Menu 2 goto system_settings2 elseif key = 3 goto set_maxtemp ;Set Max Temp for Heat/Cool endif pause 200 timeout=timeout+1 Wend end_system_settings: ;House keeping gosub check_notouch goto save_data system_settings2: ;main level gosub System_setting_menu2 timeout=0 gosub check_notouch ;Clear x=address(3) prev_temp=0 setting_loop2: while timeout < 35 ;Counter loop to exit gosub get_touch if key = 2 then ;Select Module number goto module_setup timeout=0 endif if key=4 then ;Select menu #3 goto system_settings3 endif if key = 3 then ;Set Fan Mode (Auto or On) if fan_mode=0 then fan_mode=1 else fan_mode=0 endif goto system_settings2 endif pause 200 timeout=timeout+1 Wend end_system_settings2: ;House keeping gosub check_notouch goto save_data system_settings3: ;main level gosub System_setting_menu3 timeout=0 gosub check_notouch ;Clear x=address(3) prev_temp=0 setting_loop3: while timeout < 35 ;Counter loop to exit gosub get_touch ; if key = 2 then ; ; ; endif if key=4 then goto system_settings endif if key = 3 then ;Set network enable mode if network_enable=0 then network_enable=1 else network_enable=0 endif goto system_settings3 endif pause 200 timeout=timeout+1 Wend end_system_settings3: ;House keeping gosub check_notouch ;------------------------------------------ ;Save Data to eeprom ; ;------------------------------------------ save_data: writedm 0,[str address\4,cool_default,heat_default,cool_max,Heat_max,control_status] goto main_refresh ;--------------------------------------------------- ;------------ Module number setup ------------------ ;--------------------------------------------------- Module_setup: gosub select_module gosub check_notouch timeout=0 module_loop: while timeout < 100 ;Counter loop to exit gosub get_touch if key = 1 then address(3)=address(3)+1 if address(3)>57 then address(3)=57 endif data_line="TM11,",str address\4,13 gosub send_uart_line gosub wait_lcd pause 50 timeout=0 gosub get_touch endif if key = 2 then address(3)=address(3)-1 if address(3)<48 then address(3)=48 endif data_line="TM11,",str address\4,13 gosub send_uart_line gosub wait_lcd pause 50 timeout=0 gosub get_touch endif if key = 3 then address(3)=x goto system_settings endif if key = 4 then goto system_settings endif pause 200 timeout=timeout+1 Wend goto system_settings check_notouch: ;Check to be sure finger has lifted repeat pause 50 gosub get_touch until key=0 return ;------------------------------------------------------------- ;-----------------Change Default Set Points------------------- ;------------------------------------------------------------- set_default: gosub default_menu timeout=0 gosub check_notouch ;Clear default_loop: while timeout < 40 ;Counter loop to exit gosub get_touch if key = 4 then goto default_done endif if key = 2 then set_point=cool_default gosub change_sp timeout=0 cool_default=set_point endif if key = 3 then set_point=heat_default gosub change_sp timeout=0 heat_default=set_point endif pause 200 timeout=timeout+1 Wend default_done: 'Done changing Default Temps goto system_settings return ;-------------------------------Set Max temp defaults------------------------ set_maxtemp: gosub maxtemp_menu timeout=0 gosub check_notouch ;Clear max_loop: while timeout < 40 ;Counter loop to exit gosub get_touch if key = 4 then goto default_done endif if key = 2 then set_point=cool_max gosub change_sp timeout=0 cool_max=set_point endif if key = 3 then set_point=heat_max gosub change_sp timeout=0 heat_max=set_point endif pause 200 timeout=timeout+1 Wend max_done: 'Done changing Default Temps goto system_settings return ;-----------------------------Change Set Point Screen---------------------------------- Change_sp: prev_temp=0 data_line="C",13 ;Clear gosub send_uart_line gosub wait_lcd pause 200 data_line="TM72,Done",13 gosub send_uart_line gosub wait_lcd data_line="Tm213,UP",13 gosub send_uart_line gosub wait_lcd data_line="Tm612,Down",13 gosub send_uart_line gosub wait_lcd data_line="BC",13 ;Enable Touch Screen Overlay gosub send_uart_line gosub wait_lcd data_line="TM51,Change SP",13 gosub send_uart_line gosub wait_lcd gosub display_set_point timeout=0 gosub check_notouch change_sp_loop: while timeout < 40 ;Counter loop to exit gosub get_touch if key = 1 then set_point=set_point+1 if set_point > 110 then set_point = 110 endif gosub display_set_point pause 50 timeout=0 gosub get_touch endif if key = 2 then set_point=set_point-1 if set_point < 50 then set_point = 50 endif gosub display_set_point pause 50 timeout=0 gosub get_touch endif if key = 4 then goto exit_sp endif pause 200 timeout=timeout+1 Wend exit_sp: prev_temp=0 gosub check_notouch return pause_loop: ;Will pause and look for network data repeat i=i-1 hserstat 4,cont_pause_loop ;Is there network data to be processed gosub receivepacket i=0 cont_pause_loop: until i=0 return cont: ; LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram, dec3 rxbuf\3] exit_touch: return ;************************************************* ;** Receive a Packet ** ;************************************************* ReceivePacket: LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram+$40,"*"] ;Show we see a packet ;------------------------Check for a start Character------------------------ repeat hserin terror,20,[packet_header] until packet_header="#" or packet_header= "!" ;Header Character for packet with Checksum start_found: packet(0)=packet_header i=0 Packet_loop: repeat i=i+1 hserin receive_done,100,[packet(i)] until packet(i)=13 or packet(i)=$ff or i=34 ;---------------------------------------Display all Packets seen--------------------- LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram+3,str packet\i," "] ;------------------------------------------------------------------------------------- receive_done: line_length=i ;---------------------------Display Packet Checksum---------------------------- ;LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram,"#",hex checksum," "] ;Trouble shooting display Packet Info if packet(0)="#" then n=1 gosub convertHex2Byte ;Convert Checksum to one byte checksum=databyte packet(1)="0" packet(2)="0" n=4 ;Start of device address else n=2 ;Start of device address endif ;---------------------------------------------------------------------------- ;----------------------Check for module address match------------------------ ;---------------SL# is a thermostat command, MAN# is a answerman------------- ;---------------------------------------------------------------------------- if packet(n)="S" and packet(n+1)="L" then ;This is a Thermostat command if packet(n+2)<>address(3) then LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram+$40,"-"] ;Address doesn't match pause 20 hserstat 2 return ;Exit routine endif n=n+3 else for i= 0 to 3 ;receive the address if address(i)<>packet(i+n) then ;Verify address as we receive it LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram+$40,"-"] ;Address doesn't match pause 20 hserstat 2 return ;Exit routine endif next n=n+4 endif ;---------------------------------Display the Packet if unit match-------------------- ; LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram+$41,"#",hex checksum," ",str packet\line_length," "] ;------------------------------------------------------------------------------------ if packet(0)="#" then i=line_length gosub checkpacket ;verify checksum if checksum <> checksum_val then ;Is Checksum Valid ? ;****************Bad Checksum Skip******************** LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram+$40,"B ",hex checksum," ",hex checksum_val," ",dec line_length,"--"] LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram,"# ",str packet\line_length] hserstat 2 ;Clear buffer after a bad packet return endif endif ;----------------------------------------------------------------- ;-----------------Analyze Packet Information---------------------- ;----------------------------------------------------------------- Process_Packet: n=n+1 if n < line_length then if packet(n) = "S" Then ;Set value command if network_enable=1 then ;Is the network enabled? goto set_value endif endif if packet(n) = "Q" then ;Query Value goto query_value endif if packet(n) = "R" then ;Reset goto system_reset endif if packet(n) = "T" then ;Display Text goto display_text endif else return endif goto process_packet terror: ;Timeout error waiting to see the start of packet character LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram+$40,"T "] hserstat 2 ;Clear input buffer return set_value: n=n+1 if n+4<=line_length then ;Answer Man module set command if packet(n)="D" and packet(n+1)=" " then ;Set DAC AMan Only reads 8bits n=n+4 LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram+$40,"AS"] ;Convert first gosub converthex2byte gosub set_heat_sp ;update the sp n=n+5 ;Move to second byte gosub converthex2byte gosub set_cool_sp return ;-------------------------------------------------------------------------------------------- elseif packet(n)="P" ;Thermstat command format Setpoint change if packet(n+1) = "H" then ;Set Heat Setpoint n=n+2 if packet(n)="=" or packet(n)=" " then ;If it's a (space) or (=) skip n=n+1 endif gosub convert2num3 ;Convert ascii number to Decimal gosub set_heat_sp ;Set the SP elseif packet(n+1) = "C" ;Set Cool Setpoint n=n+2 if packet(n)="=" or packet(n)=" " then ;If it's a (space) or (=) skip n=n+1 endif gosub convert2num3 ;Convert ascii number to Decimal gosub set_cool_sp ;Set the sp endif return ;Exit Packet processing elseif packet(n)="M" ;Thermostat Mode change command n=n+1 if packet(n)="=" or packet(n)=" " then ;If it's a (space) or (=) skip n=n+1 endif if packet(n) = "A" then heat_enable=1 cool_enable=1 elseif packet(n)= "H" heat_enable=1 cool_enable=0 elseif packet(n) ="C" heat_enable=0 cool_enable=1 elseif packet(n) = "O" heat_enable=0 cool_enable=0 endif update_mode=1 return ;Exit packet processing elseif packet(n)="M" ;Thermostat Fan control command if packet(n+1)="0" then fan_mode=1 elseif packet(n+1)="1" fan_mode=0 endif update_mode=1 return ;Exit packet_processing endif else return ;Can't find the correct data endif goto set_value query_value: ;Read in Data and reply n=n+1 ;Inc to the next possition and check for DP if n+1<=line_length then ;We need at least two characters for this to work. ;----------------------------Answerman Module--------------------------------------- If Packet(n)="E" then ;Answer Man Query test_data=test_data+1 packet="$00 ",str address\4," I:",hex2 control_status\2," A1:0",hex2 calc_temp\2," A2:0",hex2 heat_sp\2," A3:0",hex2 cool_sp\2 i=35 gosub sendreply ;Send reply return endif if packet(n) = "C" then ; answerman Confige Query packet="$00 ",str address\4," C:0002" ;8bit data i=15 gosub sendreply ;Send reply return endif endif return ;Exit back ;--------------------------------Update setpoints and verify data------------------- set_heat_sp: ;update Set point from Network if heat_sp <> databyte then if databyte < heat_max then ;Make sure it's less than the max heat temp allowed heat_sp=databyte ;Yup save endif update_heat=1 prev_temp=0 endif return set_cool_sp: ;Update set point from network for Cool if cool_sp<>databyte then if databyte > cool_max then ;make sure we are not below then Min temp if (heat_sp+1) < (cool_sp) then ;Now check to make sure it's 2deg above the heat sp cool_sp=databyte else cool_sp=(heat_sp+2) ; nope we will fix it. endif endif update_cool=1 prev_temp=0 endif return Display_text: ;Routine to display a line of text to screen data_line="TS11," n=n+1 while (packet(n)<>13) and (n<30) data_line=data_line+packet(n) wend gosub send_uart_line gosub wait_lcd return ;-------------------------------Misc convert routines------------------------ convert2num3: if (packet(n+2)<58) and (packet(n+2)>47) then ;Three digit number databyte=(((packet(n))-48))*100 n=n+1 endif databyte=databyte + (((packet(n))-48)*10) databyte=databyte + ((packet(n+1))-48) return ConvertHex2Byte: ;Needs the Position in the Packet Returns in Databyte if packet(n) < 65 then databyte.highnib=((packet(N))-48) else databyte.highnib=((packet(n))-55) endif if packet(n+1) <65 then databyte.lownib=(packet(n+1)-48) else databyte.lownib=(packet(n+1)-55) endif return CheckPacket: ;Calculate Checksum value checksum_val=0 for x = 0 to (i-1) ;Add the additional packets Chars into checksum checksum_val=checksum_val+packet(x) next CHECKSUM_VAL =(CHECKSUM_VAL&/CHECKSUM_VAL)+1 ;2's compliment calc return ;---Convert DIO data to ASCII---- DIOInASCIIConvert: DataByte = DIOIn GoSub ASCIIConvert DIOInASCIIHigh = DataHighNibble DIOInASCIILow = DataLowNibble Return ;------------------------------------------------------------------------- ;---------------------Compose & Send Reply Packet------------------------- ;------------------------------------------------------------------------- SendReply: High ENABLE ;Enable Transmit Mode on RS-485 Transciever IC SN75176 gosub checkpacket ;Calculate the checksum Calculates the number, does always work databyte=(checksum_val) ;if using checkpacket, (Checksum_val-1) not 100% yet GoSub ASCIIConvert ;Convert checksum to ascii packet(1)=DataHighNibble ;Replace bytes with correct checksum packet(2)=DataLowNibble hserout [str packet\i,13] ;Send String. pause 50 'Wait for Data to be sent before lowering line again,. Return ;-----ASCII Convert Routine----- ASCIIConvert: DataHighNibble = DataByte.HighNib ;Separate data byte into two nibbles DataLowNibble = DataByte.LowNib If DataHighNibble < 10 Then DataHighNibble = DataHighNibble +48 Else DataHighNibble = DataHighNibble +55 Endif If DataLowNibble <10 Then DataLowNibble = DataLowNibble +48 Else DataLowNibble = DataLowNibble +55 Endif Return ;--------------------------------Max3100 Routines------------------------------ Init_uart: ;---------------------------Init Max3100------------------------- high max_cs ;Raise CS to dis-able chip low din ;Lower data line input dout ;Read line low sclk ;Lower Clock line config_word1.highbyte = %11000000 ;No Irq stuff config_word1.lowbyte = %00001011 ;9600 Baud setup uart_tx = config_word1 ;9600 Baud, 1 stop, No Parity low max_cs shiftout din,sclk,msbpre,[uart_tx] ;Send Configuration word high max_cs low din return ;----------------------------------Max 3100 Send/Rec routines----------------------------- ;-----------------Send a line of data via the uart----------------------------------- ;-----------------Uses data_line array that is CR terminated-------------------------- send_uart_line: Array_pntr=0 ;Array Pointer LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram+$40] hserstat 4,send_uart_cont gosub receivepacket send_uart_cont: repeat uart_tx.highbyte=128 ;Set send datauart uart_tx.lowbyte=data_line(Array_pntr) low max_cs ;Enable Chip shiftout din,sclk,msbpre,[uart_tx] high max_cs ;Disable low din ;Return Din to a low state, else it could mess what the config on the nextread pause 6 Array_pntr=Array_pntr+1 ;Increament array pointer until uart_tx.lowbyte=13 ;Loop until CR return send_uart_config: ;Send the config word to the uart. low max_cs shiftout din,sclk,msbpre,[uart_tx] high max_cs low din return Clear_uart: ;Read until buffer is empty low din repeat ;There is data low max_cs shiftin dout,sclk,msbpre,[uart_rx] high max_cs until uart_rx.highbyte < 128 return ;---------------------------------Touch Screen routine to waitfor >------------------ wait_lcd: pause 10 ;was 10 low din hserstat 4, wait_lcd_cont gosub receivepacket wait_lcd_cont: repeat ;There is lcd data low max_cs shiftin dout,sclk,msbpre,[uart_rx] high max_cs if uart_rx.lowbyte=">" then return endif until uart_rx.highbyte < 128 return ;-------------------------------Read Touch number------------------------------- ;----------------------Routine to look for a numeric input---------------------- get_touch: low din hserstat 4,get_touch_cont gosub receivepacket get_touch_cont: repeat ;Clear buffer low max_cs shiftin dout,sclk,msbpre,[uart_rx] high max_cs until uart_rx.highbyte < 128 ;Exit when no data left in buffer ;Adding a Auto Touc alert data_line="K",13 ;Send K command for data gosub send_uart_line ; n=5 n=255 key=0 repeat ;There is data low max_cs shiftin dout,sclk,msbpre,[uart_rx] high max_cs low din LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram,dec uart_rx.lowbyte] if uart_rx.lowbyte="#" then ;No key pressed return endif if (uart_rx.lowbyte>47) and (uart_rx.lowbyte<58) then key=(uart_rx.lowbyte-48) return endif n=n-1 until n=0 ;Timeout LCDWRITE LCD1\LCD2\LCD3, portb.nib0, [scrram,"timeout"] pause 20 ;was 20 return '********************************************* '***********DS1302 Routines ****************** '********************************************* presetdata: 'Sends commands to DS1202 'write to ds1302 high clk_cs shiftout din,sclk,lsbfirst,[%0\1,rtccmd\5,%10\2,ctemp\8] low clk_cs return readdata: 'Gets current Time from DS1202 high clk_cs shiftout din,sclk,lsbfirst,[%111111\6,%10\2] shiftin din,sclk,lsbpre,[seconds\8,minutes\8,hours\8,date\8,month\8,year\8] low clk_cs c_sec=(bcd2bin seconds) return