General area when it fits no where else

Moderator: Mmiscool

User avatar
By trackerj
#66725 This is how I'm doing it for a PCF8563, for DS1307 should work in a very similar way:

Code: Select alli2c.begin(address) 'start a transaction
i2c.write(2)     'point to the right REG
i2c.write(ss)    'Set sec
i2c.write(ms)    'Set mins
i2c.write(hs)    'Set hours
i2c.write(ds)    'Set day
i2c.write(0)     'Set day of week
i2c.write(mnts)  'Set month
i2c.write(ys)    'Set year
i2c.end()        'finish transaction
delay 10
wait


The set values need to be converted first in BCD format.

By the way, DS1307 is a 5Vcc device (not working properly at 3.3V!), how did you wire it with the ESP8266 module, with voltage level translator?
User avatar
By Electroguard
#66729 This is what I've discovered tonight...

If you want to write new time/date info to the RTC it requires at least 2 writes, the first is to set the required address offset for pointing to the appropriate byte register, which is then followed by the new data to be written to that register, optionally followed by more new data written to subsequent registers if required.

The RTC address is 104
The 'seconds' byte register is at that address, therefore the offset is 0.
The minutes byte register is offset 1 (address + 1)
hours = offset 2
day of week = offset 3
day of month = offset 4
month = offset 5
year = offset 6

If you want to write new hour info you first start transaction, write the appropriate hour offset (2), then write the required hour data.
You can keep writing additional data to subsequent offsets, then end transaction when done.

So if you only want to change the month, start transaction, write the month offset (5), write the month data, then end transaction.

If you want to update hours and minutes, start transaction, write minutes offset (1), write minutes data, write hours data, then end transaction.

If everything needs setting because the RTC came without a battery then
start transaction, write seconds offset (0), write seconds info, write minutes info, write hours info, write day of week info, write day of month info, write month info, write year, then end transaction.

The following just stuffs 1,2,3,4,5,6,7 into the consecutive registers to show what is going where.
Bear in mind that the register info should be BCD.
TrackerJ has recently created some useful Esp-Basic BCD routines if you need them...
http://www.esp8266-projects.com/search/label/ESPBasic

Edit: I suspect an end transaction is probably missing from the original RTC example (even though it seemed to work ok), so I've put a comment in the code where I've added it
Code: Select alladdress = 104
'goto [SHOWTIME]
i2c.begin(address) 'start a transaction
i2c.write(0) 'point to the seconds address offset
for count = 1 to 7
    i2c.write(count)
next count
i2c.end() 'finish transaction
goto [SHOWTIME]

[SHOWTIME]
delay 10
i2c.begin(address) 'start another transaction
i2c.write(0) 'point to the seconds address location
i2c.end() ' Finish the write transaction
i2c.requestfrom(address,numchars) 'start a transaction to read 7 bytes
nsecs = i2c.read() 'read the seconds
nmins = i2c.read() 'read the minutes
nhrs = i2c.read() 'read the hours
nday = i2c.read() 'read the day of the week
ndate = i2c.read() 'read the day of the month
nmonth = i2c.read() 'read the month
nyear = i2c.read() 'read the year

' I suspect an end transaction is missing from here in the original example, so I've added it below.
i2c.end() ' Finish the read transaction

d = nhrs
gosub [bcd]
tm = f & ":"
d = nmins
gosub [bcd]
tm = tm & f
tm = tm & ":"
d = nsecs
gosub [bcd]
tm = tm & f
d = ndate
gosub [bcd]
da = f
da = da & "/"
d = nmonth
gosub [bcd]
da = da & f
da = da & "/"
d = nyear
gosub [bcd]
da = da & f
tm = tm & chr(32)
tm = tm & da
print tm
end

[bcd]
a = d / 16
a = int(a)
a = a + 48
c = a * 16
b = d - c
b = b + 48
e = chr(a)
f = chr(b)
f = e & f
return
User avatar
By PhilTilson
#66815
By the way, DS1307 is a 5Vcc device (not working properly at 3.3V!), how did you wire it with the ESP8266 module, with voltage level translator?

No - fortunately, although the DS1307 does, indeed, need a 5 volt Vdd, its minimum logic high level is 2.2 volts. So by tying the clock and data lines to the 3.3V line (via resistors) you can still talk to the chip whilst not endangering the ESP!

This is what I've discovered tonight...

If you want to write new time/date info to the RTC it requires at least 2 writes, the first is to set the required address offset for pointing to the appropriate byte register, which is then followed by the new data to be written to that register, optionally followed by more new data written to subsequent registers if required.

Yes - and hopefully, that's what I have been trying to make work! This was the code from my original post:

Code: Select alli2c.setup(13,12)   'set I2C pins on ESP
i2c.begin(address)   'start I2C conversation
i2c.write(4)   'point to the date address location
'i2c.end()   'finish this conversation
'i2c.begin(address)   'start another conversation
i2c.write(3)   'the value to go in the date field
i2c.end   'finish this conversation - See more at: http://www.esp8266.com/viewtopic.php?f=45&t=15067#sthash.i1um4dqv.dpuf

which, leaving the two lines in the middle commented out, seems to be exactly as you describe. So why isn't it working?? :twisted:

Incidentally, I think your code example is correct - eg for minutes: i2c.write(1) - rather than the way you describe it - i2c.write(address+1) - which would make the parameter 105 rather than 1. Would you agree?

Phil
User avatar
By Electroguard
#66858
Incidentally, I think your code example is correct - eg for minutes: i2c.write(1) - rather than the way you describe it - i2c.write(address+1) - which would make the parameter 105 rather than 1. Would you agree?

No, I do not agree - you are confused, because I did not describe it as "i2c.write(address+1)" like you say. I said...
The RTC address is 104.
The 'seconds' byte register is at that address, therefore the offset is 0.
The minutes byte register is offset 1 (address + 1)

So the description was correct because:
the absolute 'seconds' address 104 + relative offset 0 = 104
the absolute 'minutes' address 104 + relative offset 1 = 105

The code was also correct, because the actual 2 line Esp-Basic I2C code to write to the device register uses a combination of 2 instructions, one to set the absolute base address and the other to access the relative offset from the base address
Code: Select alli2c.begin(address) 'address=104
i2c.write(offset)  'offset=1
which writes to the 'minutes' register at address 105

If it is still confusing you might want to just pick out the required bones from the RTC adjuster example:
http://www.esp8266.com/viewtopic.php?f=40&t=15112