Shop OBEX P1 Docs P2 Docs Learn Events
A and B relay's using ds1307 — Parallax Forums

A and B relay's using ds1307

wayneBrainwayneBrain Posts: 4
edited 2007-01-04 23:21 in BASIC Stamp
i need to modify this code so i can have·it control two relays·, a and· b ,plus duration time of relays .and each relays have 5 diferent allarm times. also need a manual overide·button for each relay. all on lcd. Iam·working·off professonal development board parrallax..Bs2 .Email Me WB7076@yahoo.com



'
[noparse][[/noparse] Program Description ]
'
' Clock program
'· uses DS1307 clock chip
'· 2x16 LCD
'· pushbuttons
'· Uses quasi-hungarian notation for variable names. First letter (lowercase)
'· of each variable denotes type.
'· b = Bit
'· n = Nib
'· y = Byte
'· w = Word
'· p = DATA area
'· Constants and Pins are declared entirely in uppercase.
'· {$STAMP BS2}
'· {$PBASIC 2.5}
'
[noparse][[/noparse] I/O Definitions ]
SDA······· PIN···· 4········· ' I2C serial data line
SCL······· PIN···· 5········· ' I2C serial clock line
ButtonBus··· VAR··· INA········· ' 4 inputs 0 - 3
E······· PIN··· 8········· ' Enable pin
RW······· PIN··· 9········· ' Read/Write
RS······· CON··· 10········· ' Register Select
nLCDbus····· VAR··· OUTD······· ' 4-bit LCD data bus
'
[noparse][[/noparse] Constants ]
ACK······· CON··· 0········· ' acknowledge bit
NAK······· CON··· 1········· ' no ACK bit
DAYPOS····· CON··· 0
DATEPOS····· CON··· 4
MONTHPOS··· CON··· 7
YEARPOS····· CON··· 11
HOURPOS····· CON··· 0
MINPOS····· CON··· 3
SECPOS····· CON··· 6
COLON1POS··· CON··· 2
COLON2POS··· CON··· 5
DS1307····· CON··· %1101 << 4
'
[noparse][[/noparse] Constants ]
LCDCLS····· CON··· $01········· ' clear the LCD
LCDHOME····· CON··· $02········· ' move cursor home
LCDCRSRL··· CON··· $10········· ' move cursor left
LCDCRSRR··· CON··· $14········· ' move cursor right
LCDDISPL··· CON··· $18········· ' shift chars left
LCDDISPR··· CON··· $1C········· ' shift chars right
LCDCRONBLINK· CON··· $0F········· ' cursor on blinking
LCDCRON····· CON··· $0E········· ' cursor on
LCDCROFF··· CON··· $0C········· ' cursor off
LCDDDRAM··· CON··· $80········· ' Display Data RAM yControl
LCDCGRAM··· CON··· $40········· ' Character Generator RAM
LCDLINE1··· CON··· $80········· ' DDRAM address of line 1
LCDLINE2··· CON··· $C0········· ' DDRAM address of line 2
MINS····· CON··· 1
HRS······· CON··· 2
DAY······· CON··· 3
DATE····· CON··· 4
MONTH····· CON··· 5
YEAR····· CON··· 6
#DEFINE _LCDREADY = ($STAMP >= BS2P)
'
[noparse][[/noparse] Variables ]
ySlaveAddr··· VAR··· Byte······· ' I2C slave address
nDeviceNum··· VAR··· Nib········· ' device yNumber (0 - 7)
nAddrLen··· VAR··· Nib········· ' bytes in word addr (0 - 2)
wWordAddr··· VAR··· Word······· ' word address
yI2cData··· VAR··· Byte······· ' data to/from device
yI2cWork··· VAR··· Byte······· ' work byte for TX routine
bI2cAck····· VAR··· Bit········· ' ACK bit from device
ySecs····· VAR··· Byte······· ' DS1307 time registers
yMins····· VAR··· Byte
yHrs····· VAR··· Byte
yDay····· VAR··· Byte······· ' weekday
yDate····· VAR··· Byte······· ' yDay in yMonth, 1 - 31
yMonth····· VAR··· Byte
yYear····· VAR··· Byte
yControl··· VAR··· Byte········ ' SQW I/O yControl
nButtons··· VAR··· Nib
bBtnDown··· VAR··· nButtons.BIT2··· ' Decrement value
bBtnUp····· VAR··· nButtons.BIT1··· ' Incremenet value
bBtnMode··· VAR··· nButtons.BIT0··· ' nMode
bBlinkOff··· VAR··· Bit
nMode····· VAR··· Nib········· ' 0=none,1=min, 2=hour, 3=Day, 4=Date, 5=Month, 6=Year
yTimeout··· VAR··· Byte
yIdx····· VAR··· Byte······· ' loop yControl
yPtr····· VAR··· Byte······· ' ee pointer
yChr····· VAR··· Byte········ ' character for display
yNumber····· VAR··· Byte
yPos····· VAR··· Byte
'
[noparse][[/noparse] EEPROM Data ]
pDayNames··· DATA· "·· SunMonTueWedThuFriSat"
pMonthNames··· DATA· "·· JanFebMarAprMayJunJulAugSepOctNovDec"
'
[noparse][[/noparse] Initialization ]
Reset:
· #IF ($STAMP >= BS2P) #THEN
··· #ERROR "Please use BS2p version: SW20-EX33-DS1307.BSP"
· #ENDIF
Setup:
· ySlaveAddr = DS1307··········· ' 1 byte in word address
· nAddrLen = 1
Check_Stamp:
· #IF (_LCDREADY) #THEN
··· #ERROR "Please use BS2p version: SW20-EX11-LCD_Demo.BSP"
· #ENDIF
· DIRH = %11110111··········· ' setup pins for LCD
· PAUSE 100··············· ' let the LCD settle
Lcd_Setup:
· nLCDbus = %0011············· ' 8-bit nMode
· PULSOUT E, 3
· PAUSE 5
· PULSOUT E, 3
· PULSOUT E, 3
· nLCDbus = %0010············· ' 4-bit nMode
· PULSOUT E, 1
· yChr = %00101000
· GOSUB LCD_Cmd
· yChr = LCDCROFF
· GOSUB LCD_Cmd
· yChr = %00000110··········· ' inc crsr, no disp shift
· GOSUB LCD_Cmd
· yChr = LCDCLS············· ' clear the LCD
· GOSUB LCD_Cmd
· yChr = LCDLINE2 + COLON1POS······· ' Display colons for time
· GOSUB LCD_Cmd
· GOSUB LCD_Colon
· yChr = LCDLINE2 + COLON2POS
· GOSUB LCD_Cmd
· GOSUB LCD_Colon

'
[noparse][[/noparse] Program Code ]
Main:
· GOSUB Get_Clock············· ' read DS1307
· yHrs = yHrs & $3F
· GOSUB showDay············· ' yDay of week
· GOSUB showDate
· GOSUB showMonth············· ' Month
· GOSUB showYear
· GOSUB showHour
· GOSUB showMin
· GOSUB showSec
· GOSUB Get_nButtons
· IF (nButtons & %0111 > 0) THEN····· ' button pressed
··· yTimeout = 60··········· ' reset yTimeout value
··· IF (bBtnMode = 1) THEN······· ' Mode pressed ?
····· nMode = (nMode + 1)//7
····· IF (nMode = 0) THEN
······· yTimeout = 0
······· bBlinkOff = 0
····· ENDIF
··· ELSE
····· ON nMode-1 GOSUB modMin,modHour,modDay,modDate,modMonth,modYear
····· GOSUB Set_Clock················ ' update DS1307
··· ENDIF
· ELSE
··· IF ( yTimeout > 0 ) THEN
····· yTimeout = yTimeout - 1
····· bBlinkOff = ~bBlinkOff
····· IF (yTimeout = 0) THEN
······· bBlinkOff = 0
····· ENDIF
··· ENDIF
· ENDIF
· PAUSE 100
· GOTO Main

'·
[noparse][[/noparse] Subroutines ]
'· Increase Min
modMin:
· yMins = yMins.NIB1 * 10 + yMins.NIB0··· ' Convert from BCD
· IF (bBtnUp = 1) THEN
··· yMins = yMins + 1 // 60········· ' keep 0 - 59
· ELSE
··· yMins = yMins + 59 // 60
· ENDIF
· yMins = (yMins / 10 << 4) + (yMins // 10)· ' back to BCD
· ySecs = 0
· GOSUB showMin
· RETURN
'· Modify Hour
modHour:
· yHrs = yHrs.NIB1 * 10 + yHrs.NIB0····· ' Convert from BCD
· IF (bBtnUp = 1) THEN
··· yHrs = yHrs + 1 // 24········· ' keep 0 - 23
· ELSE
··· yHrs = yHrs + 23 // 24
· ENDIF
· yHrs = (yHrs / 10 << 4) + (yHrs // 10)··· ' back to BCD
· GOSUB showHour
· RETURN
'· Modify Day
modDay:
· IF (bBtnUp = 1) THEN
··· yDay = (yDay-1) + 1 // 7 + 1······· ' keep 1 - 7
· ELSE
··· yDay = (yDay-1) + 6 // 7 + 1
· ENDIF
· GOSUB showDay
· RETURN
'· Modify Date
modDate:
· yDate = yDate.NIB1 * 10 + yDate.NIB0····· ' Convert from BCD
· IF (bBtnUp = 1) THEN
··· yDate = (yDate-1) + 1 // 31 + 1······· ' keep 1 - 31
· ELSE
··· yDate = (yDate-1) + 30 // 31 + 1
· ENDIF
· yDate = (yDate / 10 << 4) + (yDate // 10)··· ' back to BCD
· GOSUB showDate
· RETURN
'· Modify Month
modMonth:
· yMonth = yMonth.NIB1 * 10 + yMonth.NIB0····· ' Convert from BCD
· IF (bBtnUp = 1) THEN
··· yMonth = (yMonth-1) + 1 // 12 + 1····· ' keep 1 - 11
· ELSE
··· yMonth = (yMonth-1) + 11 // 12 + 1
· ENDIF
· yMonth = (yMonth / 10 << 4) + (yMonth // 10)· ' back to BCD
· GOSUB showMonth
· RETURN
'· Modify Year
modYear:
· yYear = yYear.NIB1 * 10 + yYear.NIB0····· ' Convert from BCD
· IF (bBtnUp = 1) THEN
··· yYear = yYear + 1 // 100········· ' keep 1 - 99
· ELSE
··· yYear = yYear + 99 // 100
· ENDIF
· yYear = (yYear / 10 << 4) + (yYear // 10)··· ' back to BCD
· GOSUB showYear
· RETURN

showSec:
· yPos = LCDLINE2 + SECPOS··········· ' Second
· yNumber = ySecs
· GOSUB LCD_num
· RETURN
'· Show Min
showMin:
· yPos = LCDLINE2 + MINPOS··········· ' Minute
· IF (nMode = MINS AND bBlinkOff = 1) THEN
··· GOSUB LCD_blank
· ELSE
··· yNumber = yMins
··· GOSUB LCD_num
· ENDIF
· RETURN
'· Show hour
showHour:
· yPos = LCDLINE2 + HOURPOS··········· 'Hour
· IF (nMode = HRS AND bBlinkOff = 1) THEN
··· GOSUB LCD_blank
· ELSE
··· yNumber = yHrs
··· GOSUB LCD_num
· ENDIF
· RETURN
'· Show hour
showYear:
· yPos = LCDLINE1 + YEARPOS··········· 'Year
· IF (nMode = YEAR AND bBlinkOff = 1) THEN
··· GOSUB LCD_blank
· ELSE
··· yNumber = yYear
··· GOSUB LCD_num
· ENDIF
· RETURN
'· Display the yDay of the week from the pDayNames array at DAYPOS
'· -- pass in yDay in "yDay"
'· -- uses variable "yChr"
'· -- uses variable "yPtr"
'· -- uses variable "yIdx"
showDay:
· yChr = LCDLINE1 + DAYPOS
· GOSUB LCD_Cmd
· IF (nMode = DAY AND bBlinkOff = 1) THEN
··· yPtr = 0
· ELSE
··· yPtr = pDayNames + (yDay * 3)····· ' point to 1st yChr
· ENDIF
· FOR yIdx = 0 TO 2············· ' print 3 letters
··· READ (yPtr + yIdx), yChr······· ' read letter
··· GOSUB LCD_Out············· ' print it
· NEXT
· RETURN
'· Display the yMonth from the Monthnames array at MONTHPOS
'· -- pass in yMonth in "yMonth"
'· -- uses variable "yChr"
'· -- uses variable "yPtr"
'· -- uses variable "yIdx"
showMonth:
· yChr = LCDLINE1 + MONTHPOS
· GOSUB LCD_Cmd
· yMonth = yMonth.NIB1 * 10 + yMonth.NIB0
· IF (nMode = MONTH AND bBlinkOff = 1) THEN
··· yPtr = 0
· ELSE
··· yPtr = pMonthNames + (yMonth * 3)··· ' point to 1st yChr
· ENDIF
· FOR yIdx = 0 TO 2············· ' print 3 letters
··· READ (yPtr + yIdx), yChr······· ' read letter
··· GOSUB LCD_Out············· ' print it
· NEXT
· yMonth = ( yMonth / 10 << 4) + (yMonth//10)
· RETURN
'· show Date
showDate:
· yPos = LCDLINE1 + DATEPOS·········· ' yDate
· IF (nMode = DATE AND bBlinkOff = 1) THEN
··· GOSUB LCD_blank
· ELSE
··· yNumber = yDate
··· GOSUB LCD_num
· ENDIF
· RETURN
'· Display two blank chars
'· -- pass in yPos in "poisition"
'· -- uses variable "yChr"
LCD_blank:
· yChr = yPos
· GOSUB LCD_Cmd
· yChr = " "
· GOSUB LCD_Out
· GOSUB LCD_Out
· RETURN
'· Display BCD yNumber at current yPos as two ASCII characters
'· -- pass in BCD yNumber is "yNumber"
'· -- pass in yPos in "poisition"
'· -- uses variable "yChr"
LCD_num:
· yChr = yPos
· GOSUB LCD_Cmd
· yChr = yNumber >> 4 + $30
· GOSUB LCD_Out
· yChr = yNumber & %01111 + $30
· GOSUB LCD_Out
· RETURN
'· Get current state of pushbuttons
'· -- return nButtons in "yBtns"
'· -- uses variable "yIdx"
Get_nButtons:
'· yBtns = %11111111············· ' enable all eight inputs
· nButtons = %0111············· ' enable all 3 inputs
· FOR yIdx = 1 TO 5
'··· yBtns = yBtns & ~BtnBus········· ' test inputs
··· nButtons = nButtons & ~ButtonBus··· ' test inputs
··· PAUSE 5················ ' delay between tests
· NEXT
· RETURN

'· Do a block write to clock registers
Set_Clock:
· GOSUB I2C_Start··············· ' send Start
· yI2cWork = ySlaveAddr & %11111110····· ' send slave ID (write)
· GOSUB I2C_TX_Byte
· IF (bI2cAck = NAK) THEN Set_Clock····· ' wait until not busy
· yI2cWork = 0··············· ' point at ySecs register
· GOSUB I2C_TX_Byte
· FOR yIdx = 0 TO 7············· ' write ySecs to yControl
··· yI2cWork = ySecs(yIdx)
··· GOSUB I2C_TX_Byte
· NEXT
· GOSUB I2C_Stop
· RETURN

' Do a block read from clock registers
Get_Clock:
· GOSUB I2C_Start··············· ' send Start
· yI2cWork = ySlaveAddr & %11111110····· ' send slave ID (write)
· GOSUB I2C_TX_Byte
· IF (bI2cAck = NAK) THEN Get_Clock····· ' wait until not busy
· yI2cWork = 0··············· ' point at ySecs register
· GOSUB I2C_TX_Byte
· GOSUB I2C_Start
· yI2cWork = ySlaveAddr | %00000001····· ' send slave ID (read)
· GOSUB I2C_TX_Byte
· FOR yIdx = 0 TO 6············· ' read ySecs to yYear
··· GOSUB I2C_RX_Byte
··· ySecs(yIdx) = yI2cWork
· NEXT
· GOSUB I2C_RX_Byte_NAK··········· ' read yControl
· yControl = yI2cWork
· GOSUB I2C_Stop
· RETURN

'· =====[noparse][[/noparse] High Level I2C Subroutines]=======================================
'· Random location write
'· -- pass device slave address in "ySlaveAddr"
'· -- pass bytes in word address (0, 1 or 2) in "nAddrLen"
'· -- word address to write passed in "wWordAddr"
'· -- data byte to be written is passed in "yI2cData"
Write_Byte:
· GOSUB I2C_Start··············· ' send Start
· yI2cWork = ySlaveAddr & %11111110····· ' send slave ID (write)
· GOSUB I2C_TX_Byte
· IF (bI2cAck = NAK) THEN Write_Byte····· ' wait until not busy
· IF (nAddrLen > 0) THEN
··· IF (nAddrLen = 2) THEN
····· yI2cWork = wWordAddr.BYTE1····· ' send word address (1)
····· GOSUB I2C_TX_Byte
··· ENDIF
··· yI2cWork = wWordAddr.BYTE0······· ' send word address (0)
··· GOSUB I2C_TX_Byte
· ENDIF
· yI2cWork = yI2cData············· ' send data
· GOSUB I2C_TX_Byte
· GOSUB I2C_Stop
· RETURN

'· Random location read
'· -- pass device slave address in "ySlaveAddr"
'· -- pass bytes in word address (0, 1 or 2) in "nAddrLen"
'· -- word address to write passed in "wWordAddr"
'· -- data byte read is returned in "yI2cData"
Read_Byte:
· GOSUB I2C_Start··············· ' send Start
· IF (nAddrLen > 0) THEN
· yI2cWork = ySlaveAddr & %11111110····· ' send slave ID (write)
· GOSUB I2C_TX_Byte
· IF (bI2cAck = NAK) THEN Read_Byte····· ' wait until not busy
··· IF (nAddrLen = 2) THEN
····· yI2cWork = wWordAddr.BYTE1····· ' send word address (1)
····· GOSUB I2C_TX_Byte
··· ENDIF
··· yI2cWork = wWordAddr.BYTE0······· ' send word address (0)
··· GOSUB I2C_TX_Byte
··· GOSUB I2C_Start
· ENDIF
· yI2cWork = ySlaveAddr | %00000001····· ' send slave ID (read)
· GOSUB I2C_TX_Byte
· GOSUB I2C_RX_Byte_NAK
· GOSUB I2C_Stop
· yI2cData = yI2cWork
· RETURN

'·
[noparse][[/noparse] Low Level I2C Subroutines]
'· *** Start Sequence ***
I2C_Start:··················· ' I2C start bit sequence
· INPUT SDA
· INPUT SCL
· LOW SDA
Clock_Hold:
· DO : LOOP UNTIL (SCL = 1)········· ' wait for clock release
· RETURN

'· *** Transmit Byte ***
I2C_TX_Byte:
· SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]yI2cWork\8]· ' send byte to device
· SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]bI2cAck\1]··· ' get acknowledge bit
· RETURN

'· *** Receive Byte ***
I2C_RX_Byte_NAK:
· bI2cAck = NAK··············· ' no ACK = high
· GOTO I2C_RX
I2C_RX_Byte:
· bI2cAck = ACK··············· ' ACK = low
I2C_RX:
· SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]yI2cWork\8]··· ' get byte from device
· SHIFTOUT SDA, SCL, LSBFIRST, [noparse][[/noparse]bI2cAck\1]··· ' send ACK or NAK
· RETURN

'· *** Stop Sequence ***
I2C_Stop:··················· ' I2C stop bit sequence
· LOW SDA
· INPUT SCL
· INPUT SDA
· RETURN

LCD_Colon:
· yChr = ":"
· GOTO LCD_Out
LCD_Cmd:
· LOW RS··················· ' enter command nMode
LCD_Out:
· nLCDbus = yChr.HIGHNIB··········· ' output high nibble
· PULSOUT E, 3··············· ' strobe the Enable line
· nLCDbus = yChr.LOWNIB··········· ' output low nibble
· PULSOUT E, 3
· HIGH RS··················· ' return to character nMode
· RETURN

Comments

  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2007-01-04 15:14
    Wayne,
    ·
    ·· Rather than re-write your code, what I will do is provide an example code which allows you to use an RTC to set multiple on/off times.· This could easily be done for multiple relays, since this code controls both a Relay and a backlight on different schedules.· This is old code, but should help you out.· It’s from a Programmable Digital Thermostat I built when I lived in NY.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
  • wayneBrainwayneBrain Posts: 4
    edited 2007-01-04 18:34
    its a sprinkler system iam trying to control with an,·a and b zone. iam going to build the circuit and·see how i can make it work for me... As·iam realy not good at programing yet, can u recomend a couple of books so i can get the consept better. i understand but it isnt clickin yet. need·some type of flow charts on programing.
  • wayneBrainwayneBrain Posts: 4
    edited 2007-01-04 18:37
    Chris whats the differance between ds1302 and ds1307
  • FranklinFranklin Posts: 4,747
    edited 2007-01-04 19:01
    On the Parallax site there is a pdf file called "What is a microcontroller?" it's a good place to start.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - Stephen
  • allanlane5allanlane5 Posts: 3,815
    edited 2007-01-04 20:02
    I believe one is interfaced SPI (SHIFTIN/SHIFTOUT) and the other is interfaced I2C (special BS2p instructions).
  • Tom WalkerTom Walker Posts: 509
    edited 2007-01-04 20:02
    If I recall correctly, the 1302 has an SPI interface and the 1307 is I2C.

    Edit: allanlane5...looks like we hit at the same time...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Truly Understand the Fundamentals and the Path will be so much easier...

    Post Edited (Tom Walker) : 1/4/2007 8:08:02 PM GMT
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2007-01-04 20:43
    Gentlemen,
    ·
    ·· Those aren’t the only differences…Although they are important.· Either will still work with any BASIC Stamp 2 Model.· The DS1302 has a trickle-charging circuit on its battery back-up circuit, which means it can use a rechargeable battery.· The DS1307 does not have this, although it does have a battery backup circuit.· I believe it also has more SRAM than the DS1302, which has 31 bytes.· I believe the DS1307 is also 5V only whereas the DS1302 can operate from 5V down to 3V or even a little lower.· I hope this helps.· Take care.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
  • wayneBrainwayneBrain Posts: 4
    edited 2007-01-04 22:19
    i have the professional development board. how do i wire the lcd for this code.·iam trying to build it ·
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2007-01-04 23:21
    Wayne,
    ·
    ·· Please see the following document for wiring information for the PDB and a parallel LCD.· Take care.

    http://www.parallax.com/detail.asp?product_id=27220

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
Sign In or Register to comment.