'========================================================================== 'Programmer.: Sean Hillmeyer 'Description: Controls hydroponic garden via SX28 microcontroller and ' RTC. Water pump and lighting relays are actuated accouding ' to a stored schedule. 'Rev.History: V1 by Sean Hillmeyer (Feb. 2008) ' 'Licence: Copyright (c) <2008> ' 'Permission is hereby granted, free of charge, to any person 'obtaining a copy of this software and associated documentation 'files (the "Software"), to deal in the Software without 'restriction, including without limitation the rights to use, 'copy, modify, merge, publish, distribute, sublicense, and/or sell 'copies of the Software, and to permit persons to whom the 'Software is furnished to do so, subject to the following 'conditions: ' 'The above copyright notice and this permission notice shall be 'included in all copies or substantial portions of the Software. ' 'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 'EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 'OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 'NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 'HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 'WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 'FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 'OTHER DEALINGS IN THE SOFTWARE. '========================================================================== ' ------------------------------------------------------------------------- ' Device Settings ' ------------------------------------------------------------------------- DEVICE SX28, OSCXT2, TURBO, STACKX, OPTIONX, BOR42 FREQ 20_000_000 ' ------------------------------------------------------------------------- ' IO Pins ' ------------------------------------------------------------------------- SDI PIN RB.0 ' Serial from RTC SDO PIN RB.1 ' Serial to RTC SCL PIN RB.2 OUTPUT ' Clock to RTC CE PIN RB.3 OUTPUT ' RTC Enable Line Lights PIN RC.7 OUTPUT ' Relays connected to RA.0 and RA.1 Pump PIN RC.6 OUTPUT COMRX PIN RA.3 COMTX PIN RA.2 ' Debug serial port on RA.3 ' ------------------------------------------------------------------------- ' Constants ' ------------------------------------------------------------------------- ' Baud rate settings for ComPort, and SHIFTIN/OUT COMBAUD CON "T38400" SHFT_SCALE CON 10 ' Reg locations on RTC TIME_R CON $00 TIME_W CON $80 CRTL_W CON $8F STAT_R CON $10 TRIC_W CON $91 RAM_R CON $20 RAM_W CON $A0 ' ------------------------------------------------------------------------- ' Variables ' ------------------------------------------------------------------------- ' Working variables tmpB1 VAR Byte tmpB2 VAR Byte tmpB3 VAR Byte tmpW1 VAR Word pumpAlarm VAR Byte pumpStat VAR Bit ' Time variables (NOTE: these are expected to be binary values not BCD) Seconds VAR Byte Minutes VAR Byte Hours VAR Byte Light_ON VAR Word Light_OFF VAR Word Pump_M_ON VAR Byte Pump_M_OFF VAR Byte ' ========================================================================= PROGRAM Start ' ========================================================================= ' ------------------------------------------------------------------------- ' Subroutine Declarations ' ------------------------------------------------------------------------- DELAY SUB 1, 2 ' delay in milliseconds BCD_2_DEC SUB 1 ' translates a BCD number to binary DEC DEC_2_BCD SUB 1 ' translates a binary DEC to BCD UPDATE_TIME SUB 0 ' polls the RTC for the current time WRITE_RTC SUB 0 ' writes a new time to the RTC READ_RTC SUB 0 ' read settings from RTC CLOCK_INIT SUB 0 ' starts up the RTC COM_TX SUB 1, 2 'send byte over COM COM_RX_BYTE SUB 0 'recive byte over COM SFT_OUT_BYTE SUB 1 'shifts a byte out SDO SFT_IN_BYTE SUB 0 'shifts a byte in SDI ' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ' Reset Init ' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Start: DELAY 1000 ' wait for devices to powerup CLOCK_INIT ' start the RTC Lights = 0 Pump = 0 COM_TX $0D COM_TX "Send Data" SERIN COMRX, COMBAUD, tmpB1, 1000, SkipCodeDownload IF tmpB1 <> "!" THEN Start Light_ON_MSB = COM_RX_Byte Light_ON_LSB = COM_RX_Byte Light_OFF_MSB = COM_RX_Byte Light_OFF_LSB = COM_RX_Byte Pump_M_ON = COM_RX_Byte Pump_M_OFF = COM_RX_Byte Hours = COM_RX_Byte Minutes = COM_RX_Byte Seconds = COM_RX_Byte WRITE_RTC COM_TX $0D COM_TX "Writing Data" GOTO Main SkipCodeDownload: COM_TX $0D COM_TX "Skipping Download" COM_TX "Setting Up" READ_RTC UPDATE_TIME pumpStat = 0 PumpAlarm = Minutes ' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ' Main Program Code ' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Main: READ_RTC COM_TX $0D COM_TX "Running" DO UPDATE_TIME ' COM_TX $0D ' COM_TX Hours ' COM_TX Minutes ' COM_TX Seconds ' COM_TX Light_ON_MSB ' COM_TX Light_ON_LSB tmpW1 = Hours * 60 tmpW1 = tmpW1 + Minutes Light_Check: IF tmpW1 >= Light_ON THEN IF tmpW1 <= Light_OFF THEN Lights = 1 'Turn lights on GOTO Pump_Check ENDIF ENDIF Lights = 0 'Turn lights off Pump_Check: IF Minutes = PumpAlarm THEN 'If we match pumpAlarm time IF pumpStat = 0 THEN 'and the pump is off then. pumpStat = 1 'Turn the pump on and reset the alarm for off point pumpAlarm = Minutes + Pump_M_ON IF pumpAlarm >= 59 THEN pumpAlarm = pumpAlarm - 59 ENDIF Pump = 1 ELSE 'and the pump is on then. pumpStat = 0 'Turn the pump off and reset the alarm for on point pumpAlarm = Minutes + Pump_M_OFF IF pumpAlarm >= 59 THEN pumpAlarm = pumpAlarm - 59 ENDIF Pump = 0 ENDIF ENDIF LOOP ' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ' Subroutines ' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ' Use: DELAY ms ' -- 'ms' is delay in milliseconds, 1 - 65535 DELAY: tmpB1 = __PARAM1 ' save byte value PAUSE tmpB1 RETURN ' Use: BCD_2_DEC [ aByte ] ' -- "aByte" is single-byte constant or variable that will be converted to Binary ' and returned BCD_2_DEC: tmpB1 = __PARAM1 tmpB2 = tmpB1 / 16 tmpB2 = tmpB2 * 10 tmpB3 = tmpB1 // 16 tmpB1 = tmpB2 + tmpB3 RETURN tmpB1 ' Use: DEC_2_BCD [ aByte ] ' -- "aByte" is single-byte constant or variable that will be converted to ASCII ' and sent to the LCD DEC_2_BCD: tmpB1 = __PARAM1 tmpB2 = tmpB1 / 10 tmpB2 = tmpB2 * 16 tmpB3 = tmpB1 // 10 tmpB1 = tmpB2 + tmpB3 RETURN tmpB1 ' Use: UPATE_TIME ' This polls the DS1305 for the current time and stores it in the clock registers UPDATE_TIME: CE = 1 SFT_OUT_BYTE TIME_R tmpB1 = SFT_IN_BYTE 'Get Seconds Seconds = BCD_2_DEC tmpB1 'Convert Seconds and store tmpB1 = SFT_IN_BYTE 'Get Minutes Minutes = BCD_2_DEC tmpB1 'Convert Minutes and store tmpB1 = SFT_IN_BYTE 'Get Hours Hours = BCD_2_DEC tmpB1 'Convert Hours and store CE = 0 RETURN ' Use: WRITE_RTC ' This writes all of the used RTC registers using the stored values WRITE_RTC: CE = 1 SFT_OUT_BYTE TIME_W tmpB1 = DEC_2_BCD Seconds 'Convert Seconds and send SFT_OUT_BYTE tmpB1 tmpB1 = DEC_2_BCD Minutes 'Convert Minutes and send SFT_OUT_BYTE tmpB1 tmpB1 = DEC_2_BCD Hours 'Convert Hours and send SFT_OUT_BYTE tmpB1 CE = 0 DELAY 1 CE = 1 SFT_OUT_BYTE RAM_W SFT_OUT_BYTE Light_ON_MSB SFT_OUT_BYTE Light_ON_LSB SFT_OUT_BYTE Light_OFF_MSB SFT_OUT_BYTE Light_OFF_LSB SFT_OUT_BYTE Pump_M_ON SFT_OUT_BYTE Pump_M_OFF CE = 0 RETURN ' Use: READ_RTC ' This reads the stored values from the RTC ram READ_RTC: CE = 1 SFT_OUT_BYTE RAM_R Light_ON_MSB = SFT_IN_BYTE Light_ON_LSB = SFT_IN_BYTE Light_OFF_MSB = SFT_IN_BYTE Light_OFF_LSB = SFT_IN_BYTE Pump_M_ON = SFT_IN_BYTE Pump_M_OFF = SFT_IN_BYTE CE = 0 RETURN ' Use: CLOCK_INIT ' This starts up the RTC and sets the trickle charg reg CLOCK_INIT: CE = 1 'Write to CRTL_W Reg %0000_0000 SFT_OUT_BYTE CRTL_W SFT_OUT_BYTE $00 CE = 0 DELAY 1 CE = 1 'Write to TRIC_W Reg %1010_0101 SFT_OUT_BYTE TRIC_W SFT_OUT_BYTE %1010_0101 CE = 0 DELAY 1 RETURN ' ------------------------------------------------------------------------- ' Use: rxInput = COM_RX_BYTE ' -- reads byte from serial input and places it in 'rxInput' COM_RX_BYTE: SERIN COMRX, COMBAUD, tmpB1 ' receive a byte RETURN tmpB1 ' Use: COM_TX [ aByte | string | label ] ' -- "aByte" is single-byte constant or variable ' -- "string" is an embedded literal string ' -- "label" is DATA statement label for stored z-String COM_TX: tmpB1 = __PARAM1 ' byte or string offset IF __PARAMCNT = 2 THEN ' string specified? tmpB2 = __PARAM2 ' yes, save base DO READ tmpB2 + tmpB1, tmpB3 ' read a character IF tmpB3 = 0 THEN EXIT ' if 0, string complete SEROUT COMTX, COMBAUD, tmpB3 ' send the byte INC tmpB1 ' point to next character tmpB2 = tmpB2 + Z ' update base on overflow LOOP ELSE SEROUT COMTX, COMBAUD, tmpB1 ' send the byte ENDIF RETURN ' ------------------------------------------------------------------------- ' Use: char = SFT_IN_BYTE ' -- reads byte from RTC SFT_IN_BYTE: SHIFTIN SDI, SCL, 2, tmpB1, SHFT_SCALE RETURN tmpB1 ' return to caller ' ------------------------------------------------------------------------- ' Use: SFT_OUT_BYTE char ' -- transmits 'char' to RTC SFT_OUT_BYTE: tmpB1 = __PARAM1 ' save byte to send SHIFTOUT SDO, SCL, 1, tmpB1, SHFT_SCALE RETURN