123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- --------------------------------------------------------------------------------
- -- DS3231 I2C module for NODEMCU
- -- NODEMCU TEAM
- -- LICENCE: http://opensource.org/licenses/MIT
- -- Tobie Booth <tbooth@hindbra.in>
- --------------------------------------------------------------------------------
- require("bit")
- require("i2c")
- local moduleName = ...
- local M = {}
- _G[moduleName] = M
- -- Constants:
- M.EVERYSECOND = 6
- M.EVERYMINUTE = 7
- M.SECOND = 1
- M.MINUTE = 2
- M.HOUR = 3
- M.DAY = 4
- M.DATE = 5
- M.DISABLE = 0
- -- Default value for i2c communication
- local id = 0
- --device address
- local dev_addr = 0x68
- local function decToBcd(val)
- if val == nil then return 0 end
- return((((val/10) - ((val/10)%1)) *16) + (val%10))
- end
- local function bcdToDec(val)
- return((((val/16) - ((val/16)%1)) *10) + (val%16))
- end
- local function addAlarmBit(val,day)
- if day == 1 then return bit.bor(val,64) end
- return bit.bor(val,128)
- end
- --get time from DS3231
- function M.getTime()
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.TRANSMITTER)
- i2c.write(id, 0x00)
- i2c.stop(id)
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.RECEIVER)
- local c=i2c.read(id, 7)
- i2c.stop(id)
- return bcdToDec(tonumber(string.byte(c, 1))),
- bcdToDec(tonumber(string.byte(c, 2))),
- bcdToDec(tonumber(string.byte(c, 3))),
- bcdToDec(tonumber(string.byte(c, 4))),
- bcdToDec(tonumber(string.byte(c, 5))),
- bcdToDec(tonumber(string.byte(c, 6))),
- bcdToDec(tonumber(string.byte(c, 7)))
- end
- --set time for DS3231
- -- enosc setted to 1 disables oscilation on battery, stopping time
- function M.setTime(second, minute, hour, day, date, month, year, disOsc)
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.TRANSMITTER)
- i2c.write(id, 0x00)
- i2c.write(id, decToBcd(second))
- i2c.write(id, decToBcd(minute))
- i2c.write(id, decToBcd(hour))
- i2c.write(id, decToBcd(day))
- i2c.write(id, decToBcd(date))
- i2c.write(id, decToBcd(month))
- i2c.write(id, decToBcd(year))
- i2c.stop(id)
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.TRANSMITTER)
- i2c.write(id, 0x0E)
- i2c.stop(id)
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.RECEIVER)
- local c = string.byte(i2c.read(id, 1), 1)
- i2c.stop(id)
- if disOsc == 1 then c = bit.bor(c,128)
- else c = bit.band(c,127) end
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.TRANSMITTER)
- i2c.write(id, 0x0E)
- i2c.write(id, c)
- i2c.stop(id)
- end
- -- Reset alarmId flag to let alarm to be triggered again
- function M.reloadAlarms ()
- if bit == nil or bit.band == nil or bit.bor == nil then
- print("[ERROR] Module bit is required to use alarm function")
- return nil
- end
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.TRANSMITTER)
- i2c.write(id, 0x0F)
- i2c.stop(id)
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.RECEIVER)
- local d = string.byte(i2c.read(id, 1), 1)
- i2c.stop(id)
- -- Both flag needs to be 0 to let alarms trigger
- d = bit.band(d,252)
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.TRANSMITTER)
- i2c.write(id, 0x0F)
- i2c.write(id, d)
- i2c.stop(id)
- print('[LOG] Alarms reloaded')
- end
- -- Enable alarmId bit. Let it to be triggered
- function M.enableAlarm (almId)
- if bit == nil or bit.band == nil or bit.bor == nil then
- print("[ERROR] Module bit is required to use alarm function")
- return nil
- end
- if almId ~= 1 and almId ~= 2 then print('[ERROR] Wrong alarm id (1 or 2): '..almId) return end
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.TRANSMITTER)
- i2c.write(id, 0x0E)
- i2c.stop(id)
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.RECEIVER)
- local c = string.byte(i2c.read(id, 1), 1)
- i2c.stop(id)
- c = bit.bor(c,4)
- if almId == 1 then c = bit.bor(c,1)
- else c = bit.bor(c,2) end
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.TRANSMITTER)
- i2c.write(id, 0x0E)
- i2c.write(id, c)
- i2c.stop(id)
- M.reloadAlarms()
- print('[LOG] Alarm '..almId..' enabled')
- end
- -- If almID equals 1 or 2 disable that alarm, otherwise disables both.
- function M.disableAlarm (almId)
- if bit == nil or bit.band == nil or bit.bor == nil then
- print("[ERROR] Module bit is required to use alarm function")
- return nil
- end
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.TRANSMITTER)
- i2c.write(id, 0x0E)
- i2c.stop(id)
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.RECEIVER)
- local c = string.byte(i2c.read(id, 1), 1)
- i2c.stop(id)
- if almId == 1 then c = bit.band(c, 254)
- elseif almId == 2 then c = bit.band(c, 253)
- else
- almId = '1 and 2'
- c = bit.band(c, 252)
- end
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.TRANSMITTER)
- i2c.write(id, 0x0E)
- i2c.write(id, c)
- i2c.stop(id)
- print('[LOG] Alarm '..almId..' disabled')
- end
- -- almId can be 1 or 2;
- -- almType should be taken from constants
- function M.setAlarm (almId, almType, second, minute, hour, date)
- if bit == nil or bit.band == nil or bit.bor == nil then
- print("[ERROR] Module bit is required to use alarm function")
- return nil
- end
- if almId ~= 1 and almId ~= 2 then print('[ERROR] Wrong alarm id (1 or 2): '..almId) return end
- M.enableAlarm(almId)
- second = decToBcd(second)
- minute = decToBcd(minute)
- hour = decToBcd(hour)
- date = decToBcd(date)
- if almType == M.EVERYSECOND or almType == M.EVERYMINUTE then
- second = addAlarmBit(second)
- minute = addAlarmBit(minute)
- hour = addAlarmBit(hour)
- date = addAlarmBit(date)
- elseif almType == M.SECOND then
- minute = addAlarmBit(minute)
- hour = addAlarmBit(hour)
- date = addAlarmBit(date)
- elseif almType == M.MINUTE then
- hour = addAlarmBit(hour)
- date = addAlarmBit(date)
- elseif almType == M.HOUR then
- date = addAlarmBit(date)
- elseif almType == M.DAY then
- date = addAlarmBit(date,1)
- end
- local almStart = 0x07
- if almId == 2 then almStart = 0x0B end
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.TRANSMITTER)
- i2c.write(id, almStart)
- if almId == 1 then i2c.write(id, second) end
- i2c.write(id, minute)
- i2c.write(id, hour)
- i2c.write(id, date)
- i2c.stop(id)
- print('[LOG] Alarm '..almId..' setted')
- end
- -- Get Control and Status bytes
- function M.getBytes ()
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.TRANSMITTER)
- i2c.write(id, 0x0E)
- i2c.stop(id)
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.RECEIVER)
- local c = i2c.read(id, 2)
- i2c.stop(id)
- return tonumber(string.byte(c, 1)), tonumber(string.byte(c, 2))
- end
- -- Resetting RTC Stop Flag
- function M.resetStopFlag ()
- if bit == nil or bit.band == nil or bit.bor == nil then
- print("[ERROR] Module bit is required to reset stop flag")
- return nil
- end
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.TRANSMITTER)
- i2c.write(id, 0x0F)
- i2c.stop(id)
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.RECEIVER)
- local s = string.byte(i2c.read(id, 1))
- i2c.stop(id)
- s = bit.band(s,127)
- i2c.start(id)
- i2c.address(id, dev_addr, i2c.TRANSMITTER)
- i2c.write(id, 0x0F)
- i2c.write(id, s)
- i2c.stop(id)
- print('[LOG] RTC stop flag resetted')
- end
- return M
|