' ============================================================================== ' ' File...... RemoteStampDirectConn.BSp ' Purpose... Serial Comm with PC through modem. ' {$STAMP BS2p} ' {$PBASIC 2.5} ' ' ============================================================================== ' ------------------------------------------------------------------------------ ' Program Description ' ------------------------------------------------------------------------------ ' In this program the stamp will monitor temperature ' from the DS1620 Thermometer chip, and switch on/off a fan and heater according ' to the temperature limit. ' The stamp can be dialled up to by a PC using VB app ' When connected, a display of high and low temps will ' be displayed, along with the current temperature, hi/lows, fan/heater settings ' The use can input one of several commands, to either reset high/low readings, ' read temp again, disconnect, change fan/ heater values. ' ' An LCD display will be used to give information locally at the stamp. ' ------------------------------------------------------------------------------ ' Revision History ' ------------------------------------------------------------------------------ ' ------------------------------------------------------------------------------ ' I/O Definitions ' ------------------------------------------------------------------------------ ' DS1620 pins Rst CON 2 ' DS1620.3 Clk CON 5 ' DS1620.2 DQ CON 4 ' DS1620.1 ' MAX232 Pins RX CON 12 ' receive (from modem) TX CON 13 ' transmit (to modem) RTS CON 14 ' Request To Send (from modem) CTS CON 15 ' Clear To Send (to modem) FAN CON 10 ' Fan control Pin Heater CON 9 ' Heater contol pin ' ------------------------------------------------------------------------------ ' Constants ' ------------------------------------------------------------------------------ Baud CON 240 ' 9600-N-8-1 FF CON 12 ' Form Feed ModemTimeout CON 100 ' Comms timeout OptionTimeout CON 10000 ' User menu option timeout ' LCD constants WakeUp CON %00110000 'Wake-up FourBitMode CON %00100000 'Set to 4-bit mode FourLine5x8Font CON %00101000 'Set to 4 display lines, 5x8 font DisplayOff CON %00001000 'Turn off display, data is retained DisplayOn CON %00001100 'Turn on display, no cursor IncCrsr CON %00000110 'Auto-increment cursor, no display shift ClearDisplay CON %00000001 'Clear the display MoveCrsr CON %10000000 'Move cursor to position (must add address) LCDPin CON 0 ' ------------------------------------------------------------------------------ ' Variables ' ------------------------------------------------------------------------------ tmpIn VAR Word ' 9-bit temp input from DS1620 nFlag VAR tmpIn.BIT8 ' negative flag tempC VAR Byte ' converted whole celcius value tmpNow VAR Byte ' current temperature tmpLo VAR Byte ' lowest temp tmpHi VAR Byte ' highest temp tmpFanOn VAR Byte ' temp limit for fan tmpHeaterOn VAR Byte ' temp limit for heater sign VAR Byte ' - for negative temps signLo VAR Byte signHi VAR Byte inByte VAR Byte userOption VAR Byte DCDStatus VAR Bit ' Check bit for connection status ' ------------------------------------------------------------------------------ ' EEPROM Data ' ------------------------------------------------------------------------------ ' ------------------------------------------------------------------------------ ' Initialization ' ------------------------------------------------------------------------------ LOW FAN ' Fan off to start LOW Heater ' Heater off to start HIGH CTS ' not ready to receive data tmpLo = 50 tmpHi = 0 ' Initialise high/lows signLo = "+" signHi = "-" tmpFanOn = 21 ' Fan switch on at or above this temp tmpHeaterOn = 20 ' Heater switch on if tmpNow is less than this GOSUB InitLCD GOSUB InitDS1620 GOSUB InitModem ' Using modem connection ' ------------------------------------------------------------------------------ ' Program Code ' ------------------------------------------------------------------------------ Main: GOSUB ScanT ' get current temperature GOSUB FanTest GOSUB HeaterTest GOSUB UpdateLCD DCDStatus = IN11 ' Check for active connection IF (DCDStatus = 1) THEN GOSUB WhatNow ENDIF GOTO Main ' ------------------------------------------------------------------------------ ' Subroutines ' ------------------------------------------------------------------------------ ' Get Temperature ScanT: HIGH Rst ' alert the DS1620 SHIFTOUT DQ,Clk,LSBFIRST,[$AA] ' read temperature ($AA Read Command) SHIFTIN DQ,Clk,LSBPRE,[tmpIn\9] ' get the temperature LOW Rst GOSUB GetC ' convert to whole Degrees Celsius tmpNow = tempC GOSUB ChkHiLo RETURN ' convert reading from 1/2 degrees input (rounds up) GetC: IF nFlag = 0 THEN CPos ' check negative bit (8) sign = "-" ' set sign tempC = -tmpIn / 2 ' if neg, take 2's compliment GOTO CDone CPos: sign = "+" tempC = tmpIn / 2 CDone: RETURN ' Test to see if fan needs to be on or off FanTest: IF (tempC>=tmpFanOn AND sign = "+") THEN HIGH FAN ELSE LOW FAN ENDIF RETURN ' Test to see if heater needs to be on or off HeaterTest: IF (tempC<=tmpHeaterOn) THEN HIGH Heater ELSE LOW Heater ENDIF RETURN ChkHiLo: ' This subroutine checks the current temp against stored extremes, special case at zero IF (tmpNow = 0) THEN IF (tmpLo > 0 AND signLo = "+") THEN tmpLo = tmpNow signLo = sign ENDIF ELSEIF sign = "-" THEN IF (tmpNow > tmpLo AND signLo = "-") THEN tmpLo = tmpNow ELSEIF (tmpNow > tmpLo AND signLo = "+") THEN tmpLo = tmpNow signLo = sign ELSEIF (tmpNow > tmpHi) THEN tmpHi = tmpNow signHi = sign ENDIF ELSE ' sign = '+' IF (tmpNow < tmpLo AND signLo = "+") THEN tmpLo = tmpNow signLo = sign ELSEIF (tmpNow > tmpHi) THEN tmpHi = tmpNow signHi = sign ENDIF ENDIF RETURN '******************************** ' Send temperature data ' DisplayTemp: SEROUT TX\RTS, Baud, modemtimeout, main, [sign, tmpNow, signLo, tmpLo, signHi, tmpHi, tmpFanOn, tmpHeaterOn] RETURN ' Get user input WhatNow: SERIN RX\CTS, Baud, OptionTimeout, Main, [inByte] ' Gets user selection, compares it and does what user wants SELECT inByte CASE "T" ' User wants a temp update GOSUB ScanT GOSUB DisplayTemp CASE "R" ' User wants extremes reset GOSUB RstT CASE "F" ' User wants Fan on temperature set to new value GOSUB FanTemp CASE "H" ' User wants heater on temperature set to new value GOSUB HeaterTemp CASE "D" ' User wants to disconnect GOSUB Disconnect CASE ELSE ' Rubbish from comms setup can go here ENDSELECT RETURN '*************************************** ' Remote req for temperature data RemoteReq: GOSUB ScanT ' Get current temperature GOSUB DisplayTemp ' Send data to user RETURN ' reset high and low temperatures RstT: tmpLo = tmpNow signLo = sign tmpHi = tmpNow signHi = sign RETURN ' change fan threshold value FanTemp: SERIN RX\CTS, Baud, 500, Main, [inByte] tmpFanOn= inByte RETURN ' change heater on temperature HeaterTemp: SERIN RX\CTS, Baud, 500, Main, [inByte] tmpHeaterOn= inByte RETURN ModemError: LCDOUT LCDPin,MoveCrsr+80,[" "] ' Clear Line PAUSE 250 LCDOUT LCDPin,MoveCrsr+80,["Modem Error! "] PAUSE 2000 GOSUB InitModem GOTO MAIN InitDS1620: LCDOUT LCDPin,ClearDisplay,["Initalise DS1620"] PAUSE 250 ' Wait for DS1620 to power up HIGH Rst ' alert the DS1620 SHIFTOUT DQ,Clk,LSBFIRST,[$0C] ' write configuration (0C Write config command) ' use with CPU; free run mode SHIFTOUT DQ,Clk,LSBFIRST,[%00000010] LOW Rst PAUSE 50 ' pause for DS1620 EE write cycle HIGH Rst SHIFTOUT DQ,Clk,LSBFIRST,[$EE] ' start temp conversions (EE Start converting command) LOW Rst LCDOUT LCDPin,MoveCrsr+64,["DS1620 OK"] PAUSE 1500 ' Make sure it gets first read RETURN InitModem: LCDOUT LCDPin,MoveCrsr+16,["Initialise Modem"] ' DEBUG "Sending AT",CR,LF SEROUT TX\RTS, Baud, ModemTimeout, Modemerror, ["AT",CR,LF] ' Get modem to load default setup PAUSE 3000 ' Long delay to test flow control SERIN RX\CTS, Baud, ModemTimeout, ModemError, [WAIT ("OK")] ' DEBUG "Sending AT&D0",CR,LF ' SEROUT TX\RTS, Baud, ModemTimeout, ModemError, ["AT&D0",CR] ' Ignore DTR ' SERIN RX\CTS, Baud, ModemTimeout, ModemError, [WAIT ("OK")] ' DEBUG "Sending ATS12=50",CR,LF ' SEROUT TX\RTS, Baud, ModemTimeout, ModemError, ["ATS12=50",CR,LF] ' Set '+++' response time to 1sec ' SERIN RX\CTS, Baud, ModemTimeout, ModemError, [WAIT ("OK")] ' DEBUG "Sending ATS0=12",CR,LF ' SEROUT TX, Baud, ModemTimeout, ["ATS0=1",CR] ' auto answer after 1 ring ' SERIN RX\CTS, Baud, ModemTimeout, ModemError, [WAIT ("OK")] ' DEBUG "Sending AT&C1",CR,LF ' SEROUT TX, Baud, ModemTimeout, ["AT&C1",CR] ' DCD follows the state of the carrier C1 ' SERIN RX\CTS, Baud, ModemTimeout, ModemError, [WAIT ("OK")] ' DEBUG "Sending ATS7=50",CR,LF ' SEROUT TX, Baud, ModemTimeout, ["ATS7=50", CR] ' max carrier detect is 50 secs ' SERIN RX\CTS, Baud, ModemTimeout, ModemError, [WAIT ("OK")] SEROUT TX\RTS, Baud, ModemTimeout, ModemError, ["ATE0&K3S12=50S0=1&C1",CR] ' All commands in one go SERIN RX\CTS, Baud, ModemTimeout, ModemError, [WAIT ("OK")] RETURN Disconnect: PAUSE 2000 SEROUT TX, Baud,["+++"] ' Gets modem back into command mode PAUSE 2000 SEROUT TX,Baud,["ATH0",CR] ' AT command for 'Hang Up' RETURN InitLCD: LCDCMD LCDPin,WakeUp 'Send wakeup sequence to LCD PAUSE 50 'These pauses are necessary to meet the LCD specs LCDCMD LCDPin,WakeUp PAUSE 5 LCDCMD LCDPin,WakeUp PAUSE 5 LCDCMD LCDPin,FourBitMode 'Set bus to 4-bit mode LCDCMD LCDPin,FourLine5x8Font 'Set to 4-line mode with 5x8 font LCDCMD LCDPin,DisplayOff 'Turn display off LCDCMD LCDPin,DisplayOn 'Turn display on with blinking cursor LCDCMD LCDPin,IncCrsr 'Set to auto-increment cursor (no display shift) LCDCMD LCDPin,ClearDisplay 'Clear the display LCDOUT LCDPin,MoveCrsr+64,["RemoteStamp Modem"] ' Current Program PAUSE 3000 RETURN UpdateLCD: LCDOUT LCDPin,ClearDisplay,["Temp(Now)=", sign, DEC tmpNow, "C"] 'Clear the display, output temps LCDOUT LCDPin,MoveCrsr+64,["Temp(Low)=", signLo, DEC tmpLo, "C"] LCDOUT LCDPin,MoveCrsr+16,["Temp(High)=", signHi, DEC tmpHi, "C"] LCDOUT LCDPin,MoveCrsr+80,["Connect is:", DEC DCDStatus] '********* DCD status!! LCDOUT LCDPin,MoveCrsr+92,[DEC tmpFanOn,DEC tmpHeaterOn] ' Show me what the limits are on LCD RETURN