# DS3231 Module | Since | Origin / Contributor | Maintainer | Source | | :----- | :-------------------- | :---------- | :------ | | 2015-01-19 | [Tobie Booth](https://github.com/tobiebooth) | [Tobie Booth](https://github.com/tobiebooth) | [ds3231.lua](../../lua_modules/ds3231/ds3231.lua) | This Lua module provides access to [DS3231](https://datasheets.maximintegrated.com/en/ds/DS3231.pdf) I²C real-time clock. !!! note This module requires `i2c` C module built into firmware. ### Require ```lua ds3231 = require("ds3231") ``` ### Release ```lua ds3231 = nil package.loaded["ds3231"] = nil ``` ## ds3231.setTime() Sets the current date and time. If _disableOscillator_ is set to 1 the oscillator will **stop** on battery. #### Syntax `ds3231.setTime(second, minute, hour, day, date, month, year[, disableOscillator])` #### Parameters - `second`: 00-59 - `minute`: 00-59 - `hour`: 00-23 - `day`: 1-7 (Sunday = 1, Saturday = 7) - `date`: 01-31 - `month`: 01-12 - `year`: 00-99 - `disableOscillator`: (optional) 0-1, defaults to 0 if omitted #### Returns `nil` #### Example ```lua i2c.setup(3, 4, scl, i2c.SLOW) -- call i2c.setup() only once ds3231 = require("ds3231") -- Set date and time to Sunday, January 18th 2015 6:30PM ds3231.setTime(0, 30, 18, 1, 18, 1, 15); -- Don't forget to release it after use ds3231 = nil package.loaded["ds3231"] = nil ``` ## ds3231.getTime() Get the current date and time. #### Syntax `ds3231.getTime()` #### Parameters None #### Returns - `second`: integer. Second 00-59 - `minute`: integer. Minute 00-59 - `hour`: integer. Hour 00-23 - `day`: integer. Day 1-7 (Sunday = 1, Saturday = 7) - `date`: integer. Date 01-31 - `month`: integer. Month 01-12 - `year`: integer. Year 00-99 #### Example ```lua i2c.setup(3, 4, scl, i2c.SLOW) -- call i2c.setup() only once ds3231=require("ds3231") -- Get date and time second, minute, hour, day, date, month, year = ds3231.getTime(); -- Print date and time print(string.format("Time & Date: %s:%s:%s %s/%s/%s", hour, minute, second, date, month, year)) -- Don't forget to release it after use ds3231 = nil package.loaded["ds3231"] = nil ``` ## ds3231setAlarm() Set an alarm to be triggered on SQW pin. _alarm1_ has a precision of **seconds**; _alarm2_ has a precision of **minutes** (`second` parameter will be ignored). Alarms sets gpio.LOW over the SQW pin and let it unchanged until reloaded. When reloaded sets gpio.HIGH. Alarms trigger **only once**, after that, if you want them to trigger again, you need to call `reloadAlarms()` or `setAlarm(...)` again. Alarm type set the alarm match conditions: - `ds3231.EVERYSECOND` works only with _alarm1_ and triggers every second; - `ds3231.EVERYMINUTE` works only with _alarm2_ and triggers every minute (at 00 seconds); - `ds3231.SECOND` triggers when time match given `seconds` parameter; - `ds3231.MINUTE` triggers when time match given `seconds` and `minutes` parameters; - `ds3231.HOUR` triggers when time match given `seconds`, `minutes`, and `hours` parameters; - `ds3231.DAY` triggers when time match given `seconds`, `minutes`, and `hours` on week day `date/day` parameters; - `ds3231.DATE` triggers when time match given `seconds`, `minutes`, and `hours` on date (day of the month) `date/day` parameters; #### Syntax `ds3231.setAlarm(alarmId, alarmType, seconds, minutes, hours, date/day)` #### Parameters - `alarmId`: 1-2 - `alarmType`: 1-7 - `seconds`: 00-59 - `minutes`: 00-59 - `hours`: 00-23 - `date/day`: 01-31 or 1-7 (Sunday = 1, Saturday = 7) #### Returns `nil` #### Example ```lua i2c.setup(3, 4, scl, i2c.SLOW) -- call i2c.setup() only once ds3231=require("ds3231") -- Setting PIN1 to triggers on interrupt when alarm triggers gpio.mode(1,gpio.INT) gpio.trig(1,'down',function(level) print('Time is passing') -- If not reloaded it will be triggered only once ds3231.reloadAlarms() end) ds3231.setAlarm(2,ds3231.EVERYMINUTE) -- Don't forget to release it after use ds3231 = nil package.loaded["ds3231"] = nil ``` ## ds3231.reloadAlarms() Reload an already triggered alarm. Otherwise it will never be triggered again. There are two different alarms and they have to be reloaded both to let, even only one, to be triggered again. So there isn't a param to select which alarm to reload. #### Syntax `ds3231.reloadAlarms()` #### Parameters None #### Returns `nil` #### Example ```lua i2c.setup(3, 4, scl, i2c.SLOW) -- call i2c.setup() only once ds3231=require("ds3231") -- Setting PIN1 to triggers on interrupt when alarm triggers gpio.mode(1,gpio.INT) gpio.trig(1,'down',function(level) print('Time is passing') -- If not reloaded it will be triggered only once ds3231.reloadAlarms() end) ds3231.setAlarm(2,ds3231.EVERYMINUTE) -- Don't forget to release it after use ds3231 = nil package.loaded["ds3231"] = nil ``` ## ds3231.enableAlarm() Enable an already setted alarm with the previous matching conditions. It reloads alarms internally. #### Syntax `ds3231.enableAlarm(alarmId)` #### Parameters `alarmId`: 1-2 #### Returns `nil` #### Example ```lua i2c.setup(3, 4, scl, i2c.SLOW) -- call i2c.setup() only once ds3231=require("ds3231") -- Trigger on x:20:15 ds3231.setAlarm(1,ds3231.MINUTE,15,20) if badThing == 1 then ds3231.disableAlarm(1) end if goodThing == 1 then ds3231.enableAlarm(1) end -- Don't forget to release it after use ds3231 = nil package.loaded["ds3231"] = nil ``` ## ds3231.disableAlarm() Disable an already set alarm with the previous matching conditions. if _alarmId_ is not 1 or 2 it disables both alarms. **Warning**: `disableAlarm()` prevent alarms to trigger interrupt over SQW pin but alarm itself will triggers at the matching conditions as it could be seen on _status byte_. #### Syntax `ds3231.disableAlarm(alarmId)` #### Parameters `alarmId: 0-2` #### Returns `nil` #### Example ```lua i2c.setup(3, 4, scl, i2c.SLOW) -- call i2c.setup() only once ds3231=require("ds3231") -- Trigger on x:20:15 ds3231.setAlarm(1,ds3231.MINUTE,15,20) if badThing == 1 then ds3231.disableAlarm(1) end if goodThing == 1 then ds3231.enableAlarm(1) end -- Don't forget to release it after use ds3231 = nil package.loaded["ds3231"] = nil ``` ## ds3231.getBytes() Get bytes of control, for debug purpose, and status of DS3231. To see what they means check the [datasheet](http://datasheets.maximintegrated.com/en/ds/DS3231.pdf). #### Syntax `ds3231.getBytes()` #### Parameters None #### Returns - `control`: integer. Control 0-255 - `status`: integer. Status 0-143 (bit 6-5-4 unused) #### Example ```lua i2c.setup(3, 4, scl, i2c.SLOW) -- call i2c.setup() only once ds3231=require("ds3231") control,status = ds3231.getBytes() print('Control byte: '..control) print('Status byte: '..status) -- Don't forget to release it after use ds3231 = nil package.loaded["ds3231"] = nil ``` ## da3231.resetStopFlag() Stop flag on status byte means that the oscillator either is stopped or was stopped for some period and may be used to judge the validity of the timekeeping data. When set to 1 this flag keeps that values until changed to 0. Call `resetStopFlag()` if you need to check validity of time data after that. #### Syntax `ds3231.resetStopFlag()` #### Parameters None #### Returns `nil` #### Example ```lua i2c.setup(3, 4, scl, i2c.SLOW) -- call i2c.setup() only once ds3231=require("ds3231") control,status = ds3231.getBytes() if bit.band(bit.rshift(status, 7),1) == 1 then print('[WARNING] RTC has stopped') ds3231.resetStopFlag() end -- Don't forget to release it after use ds3231 = nil package.loaded["ds3231"] = nil ``` #### Notes Other examples of using this module can be found in [ds3231-example.lua](../../lua_modules/ds3231/ds3231-example.lua) and [ds3231-web.lua](../../lua_modules/ds3231/ds3231-web.lua) files.