├── .github ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── githubci.yml ├── TinyRTClib.cpp ├── TinyRTClib.h ├── examples └── Trinket_Meter │ └── Trinket_Meter.ino ├── keywords.txt └── library.properties /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for opening an issue on an Adafruit Arduino library repository. To 2 | improve the speed of resolution please review the following guidelines and 3 | common troubleshooting steps below before creating the issue: 4 | 5 | - **Do not use GitHub issues for troubleshooting projects and issues.** Instead use 6 | the forums at http://forums.adafruit.com to ask questions and troubleshoot why 7 | something isn't working as expected. In many cases the problem is a common issue 8 | that you will more quickly receive help from the forum community. GitHub issues 9 | are meant for known defects in the code. If you don't know if there is a defect 10 | in the code then start with troubleshooting on the forum first. 11 | 12 | - **If following a tutorial or guide be sure you didn't miss a step.** Carefully 13 | check all of the steps and commands to run have been followed. Consult the 14 | forum if you're unsure or have questions about steps in a guide/tutorial. 15 | 16 | - **For Arduino projects check these very common issues to ensure they don't apply**: 17 | 18 | - For uploading sketches or communicating with the board make sure you're using 19 | a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes 20 | very hard to tell the difference between a data and charge cable! Try using the 21 | cable with other devices or swapping to another cable to confirm it is not 22 | the problem. 23 | 24 | - **Be sure you are supplying adequate power to the board.** Check the specs of 25 | your board and plug in an external power supply. In many cases just 26 | plugging a board into your computer is not enough to power it and other 27 | peripherals. 28 | 29 | - **Double check all soldering joints and connections.** Flakey connections 30 | cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints. 31 | 32 | - **Ensure you are using an official Arduino or Adafruit board.** We can't 33 | guarantee a clone board will have the same functionality and work as expected 34 | with this code and don't support them. 35 | 36 | If you're sure this issue is a defect in the code and checked the steps above 37 | please fill in the following fields to provide enough troubleshooting information. 38 | You may delete the guideline and text above to just leave the following details: 39 | 40 | - Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE** 41 | 42 | - Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO 43 | VERSION HERE** 44 | 45 | - List the steps to reproduce the problem below (if possible attach a sketch or 46 | copy the sketch code in too): **LIST REPRO STEPS BELOW** 47 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for creating a pull request to contribute to Adafruit's GitHub code! 2 | Before you open the request please review the following guidelines and tips to 3 | help it be more easily integrated: 4 | 5 | - **Describe the scope of your change--i.e. what the change does and what parts 6 | of the code were modified.** This will help us understand any risks of integrating 7 | the code. 8 | 9 | - **Describe any known limitations with your change.** For example if the change 10 | doesn't apply to a supported platform of the library please mention it. 11 | 12 | - **Please run any tests or examples that can exercise your modified code.** We 13 | strive to not break users of the code and running tests/examples helps with this 14 | process. 15 | 16 | Thank you again for contributing! We will try to test and integrate the change 17 | as soon as we can, but be aware we have many GitHub repositories to manage and 18 | can't immediately respond to every request. There is no need to bump or check in 19 | on a pull request (it will clutter the discussion of the request). 20 | 21 | Also don't be worried if the request is closed or not integrated--sometimes the 22 | priorities of Adafruit's GitHub code (education, ease of use) might not match the 23 | priorities of the pull request. Don't fret, the open source community thrives on 24 | forks and GitHub makes it easy to keep your changes in a forked repo. 25 | 26 | After reviewing the guidelines above you can delete this text from the pull request. 27 | -------------------------------------------------------------------------------- /.github/workflows/githubci.yml: -------------------------------------------------------------------------------- 1 | name: Arduino Library CI 2 | 3 | on: [pull_request, push, repository_dispatch] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/setup-python@v4 11 | with: 12 | python-version: '3.x' 13 | - uses: actions/checkout@v3 14 | - uses: actions/checkout@v3 15 | with: 16 | repository: adafruit/ci-arduino 17 | path: ci 18 | 19 | - name: pre-install 20 | run: bash ci/actions_install.sh 21 | 22 | - name: test platforms 23 | run: python3 ci/build_platform.py trinket_3v trinket_5v 24 | 25 | - name: clang 26 | run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r . 27 | -------------------------------------------------------------------------------- /TinyRTClib.cpp: -------------------------------------------------------------------------------- 1 | // Code by JeeLabs http://news.jeelabs.org/code/ 2 | // Released to the public domain! Enjoy! 3 | // Adafruit modifications for Aradruit DS1307 breakout 4 | // board Product 268, Arduino Due and Trinket/Gemma 5 | 6 | // This code could be merged into Adafruit RTClib if the 7 | // Arduino IDE would properly handle conditionals 8 | //#ifdef __AVR__ 9 | #include 10 | // #if defined( __AVR_ATtinyX5__ ) 11 | #include 12 | #define WIRE TinyWireM 13 | // #else 14 | // #warning AVR 15 | // #include 16 | // #define WIRE Wire 17 | // #endif 18 | //#else 19 | // #include 20 | // #define PROGMEM 21 | // #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) 22 | // #define WIRE Wire1 23 | //#endif 24 | #include "TinyRTClib.h" 25 | 26 | #define DS1307_ADDRESS 0x68 27 | #define SECONDS_PER_DAY 86400L 28 | 29 | #define SECONDS_FROM_1970_TO_2000 946684800 30 | 31 | #if (ARDUINO >= 100) 32 | #include // capital A so it is error prone on case-sensitive filesystems 33 | #else 34 | #include 35 | #endif 36 | 37 | //////////////////////////////////////////////////////////////////////////////// 38 | // utility code, some of this could be exposed in the DateTime API if needed 39 | 40 | const uint8_t daysInMonth[] PROGMEM = {31, 28, 31, 30, 31, 30, 41 | 31, 31, 30, 31, 30, 31}; 42 | 43 | // number of days since 2000/01/01, valid for 2001..2099 44 | static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d) { 45 | if (y >= 2000) 46 | y -= 2000; 47 | uint16_t days = d; 48 | for (uint8_t i = 1; i < m; ++i) 49 | days += pgm_read_byte(daysInMonth + i - 1); 50 | if (m > 2 && y % 4 == 0) 51 | ++days; 52 | return days + 365 * y + (y + 3) / 4 - 1; 53 | } 54 | 55 | static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s) { 56 | return ((days * 24L + h) * 60 + m) * 60 + s; 57 | } 58 | 59 | //////////////////////////////////////////////////////////////////////////////// 60 | // DateTime implementation - ignores time zones and DST changes 61 | // NOTE: also ignores leap seconds, see http://en.wikipedia.org/wiki/Leap_second 62 | 63 | DateTime::DateTime(uint32_t t) { 64 | t -= SECONDS_FROM_1970_TO_2000; // bring to 2000 timestamp from 1970 65 | 66 | ss = t % 60; 67 | t /= 60; 68 | mm = t % 60; 69 | t /= 60; 70 | hh = t % 24; 71 | uint16_t days = t / 24; 72 | uint8_t leap; 73 | for (yOff = 0;; ++yOff) { 74 | leap = yOff % 4 == 0; 75 | if (days < 365 + leap) 76 | break; 77 | days -= 365 + leap; 78 | } 79 | for (m = 1;; ++m) { 80 | uint8_t daysPerMonth = pgm_read_byte(daysInMonth + m - 1); 81 | if (leap && m == 2) 82 | ++daysPerMonth; 83 | if (days < daysPerMonth) 84 | break; 85 | days -= daysPerMonth; 86 | } 87 | d = days + 1; 88 | } 89 | 90 | DateTime::DateTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, 91 | uint8_t min, uint8_t sec) { 92 | if (year >= 2000) 93 | year -= 2000; 94 | yOff = year; 95 | m = month; 96 | d = day; 97 | hh = hour; 98 | mm = min; 99 | ss = sec; 100 | } 101 | 102 | static uint8_t conv2d(const char *p) { 103 | uint8_t v = 0; 104 | if ('0' <= *p && *p <= '9') 105 | v = *p - '0'; 106 | return 10 * v + *++p - '0'; 107 | } 108 | 109 | // A convenient constructor for using "the compiler's time": 110 | // DateTime now (__DATE__, __TIME__); 111 | // NOTE: using PSTR would further reduce the RAM footprint 112 | DateTime::DateTime(const char *date, const char *time) { 113 | // sample input: date = "Dec 26 2009", time = "12:34:56" 114 | yOff = conv2d(date + 9); 115 | // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 116 | switch (date[0]) { 117 | case 'J': 118 | m = date[1] == 'a' ? 1 : m = date[2] == 'n' ? 6 : 7; 119 | break; 120 | case 'F': 121 | m = 2; 122 | break; 123 | case 'A': 124 | m = date[2] == 'r' ? 4 : 8; 125 | break; 126 | case 'M': 127 | m = date[2] == 'r' ? 3 : 5; 128 | break; 129 | case 'S': 130 | m = 9; 131 | break; 132 | case 'O': 133 | m = 10; 134 | break; 135 | case 'N': 136 | m = 11; 137 | break; 138 | case 'D': 139 | m = 12; 140 | break; 141 | } 142 | d = conv2d(date + 4); 143 | hh = conv2d(time); 144 | mm = conv2d(time + 3); 145 | ss = conv2d(time + 6); 146 | } 147 | 148 | uint8_t DateTime::dayOfWeek() const { 149 | uint16_t day = date2days(yOff, m, d); 150 | return (day + 6) % 7; // Jan 1, 2000 is a Saturday, i.e. returns 6 151 | } 152 | 153 | uint32_t DateTime::unixtime(void) const { 154 | uint32_t t; 155 | uint16_t days = date2days(yOff, m, d); 156 | t = time2long(days, hh, mm, ss); 157 | t += SECONDS_FROM_1970_TO_2000; // seconds from 1970 to 2000 158 | 159 | return t; 160 | } 161 | 162 | long DateTime::secondstime(void) const { 163 | long t; 164 | uint16_t days = date2days(yOff, m, d); 165 | t = time2long(days, hh, mm, ss); 166 | return t; 167 | } 168 | 169 | //////////////////////////////////////////////////////////////////////////////// 170 | // RTC_DS1307 implementation 171 | 172 | static uint8_t bcd2bin(uint8_t val) { return val - 6 * (val >> 4); } 173 | static uint8_t bin2bcd(uint8_t val) { return val + 6 * (val / 10); } 174 | 175 | uint8_t RTC_DS1307::begin(void) { return 1; } 176 | 177 | #if (ARDUINO >= 100) 178 | 179 | uint8_t RTC_DS1307::isrunning(void) { 180 | WIRE.beginTransmission(DS1307_ADDRESS); 181 | WIRE.write(0); 182 | WIRE.endTransmission(); 183 | 184 | WIRE.requestFrom(DS1307_ADDRESS, 1); 185 | uint8_t ss = WIRE.read(); 186 | return !(ss >> 7); 187 | } 188 | 189 | void RTC_DS1307::adjust(const DateTime &dt) { 190 | WIRE.beginTransmission(DS1307_ADDRESS); 191 | WIRE.write(0); 192 | WIRE.write(bin2bcd(dt.second())); 193 | WIRE.write(bin2bcd(dt.minute())); 194 | WIRE.write(bin2bcd(dt.hour())); 195 | WIRE.write(bin2bcd(0)); 196 | WIRE.write(bin2bcd(dt.day())); 197 | WIRE.write(bin2bcd(dt.month())); 198 | WIRE.write(bin2bcd(dt.year() - 2000)); 199 | WIRE.write(0); 200 | WIRE.endTransmission(); 201 | } 202 | 203 | DateTime RTC_DS1307::now() { 204 | WIRE.beginTransmission(DS1307_ADDRESS); 205 | WIRE.write(0); 206 | WIRE.endTransmission(); 207 | 208 | WIRE.requestFrom(DS1307_ADDRESS, 7); 209 | uint8_t ss = bcd2bin(WIRE.read() & 0x7F); 210 | uint8_t mm = bcd2bin(WIRE.read()); 211 | uint8_t hh = bcd2bin(WIRE.read()); 212 | WIRE.read(); 213 | uint8_t d = bcd2bin(WIRE.read()); 214 | uint8_t m = bcd2bin(WIRE.read()); 215 | uint16_t y = bcd2bin(WIRE.read()) + 2000; 216 | 217 | return DateTime(y, m, d, hh, mm, ss); 218 | } 219 | 220 | #else 221 | 222 | uint8_t RTC_DS1307::isrunning(void) { 223 | WIRE.beginTransmission(DS1307_ADDRESS); 224 | WIRE.send(0); 225 | WIRE.endTransmission(); 226 | 227 | WIRE.requestFrom(DS1307_ADDRESS, 1); 228 | uint8_t ss = WIRE.receive(); 229 | return !(ss >> 7); 230 | } 231 | 232 | void RTC_DS1307::adjust(const DateTime &dt) { 233 | WIRE.beginTransmission(DS1307_ADDRESS); 234 | WIRE.send(0); 235 | WIRE.send(bin2bcd(dt.second())); 236 | WIRE.send(bin2bcd(dt.minute())); 237 | WIRE.send(bin2bcd(dt.hour())); 238 | WIRE.send(bin2bcd(0)); 239 | WIRE.send(bin2bcd(dt.day())); 240 | WIRE.send(bin2bcd(dt.month())); 241 | WIRE.send(bin2bcd(dt.year() - 2000)); 242 | WIRE.send(0); 243 | WIRE.endTransmission(); 244 | } 245 | 246 | DateTime RTC_DS1307::now() { 247 | WIRE.beginTransmission(DS1307_ADDRESS); 248 | WIRE.send(0); 249 | WIRE.endTransmission(); 250 | 251 | WIRE.requestFrom(DS1307_ADDRESS, 7); 252 | uint8_t ss = bcd2bin(WIRE.receive() & 0x7F); 253 | uint8_t mm = bcd2bin(WIRE.receive()); 254 | uint8_t hh = bcd2bin(WIRE.receive()); 255 | WIRE.receive(); 256 | uint8_t d = bcd2bin(WIRE.receive()); 257 | uint8_t m = bcd2bin(WIRE.receive()); 258 | uint16_t y = bcd2bin(WIRE.receive()) + 2000; 259 | 260 | return DateTime(y, m, d, hh, mm, ss); 261 | } 262 | 263 | #endif 264 | 265 | //////////////////////////////////////////////////////////////////////////////// 266 | // RTC_Millis implementation 267 | 268 | long RTC_Millis::offset = 0; 269 | 270 | void RTC_Millis::adjust(const DateTime &dt) { 271 | offset = dt.unixtime() - millis() / 1000; 272 | } 273 | 274 | DateTime RTC_Millis::now() { return (uint32_t)(offset + millis() / 1000); } 275 | 276 | //////////////////////////////////////////////////////////////////////////////// 277 | -------------------------------------------------------------------------------- /TinyRTClib.h: -------------------------------------------------------------------------------- 1 | // Code by JeeLabs http://news.jeelabs.org/code/ 2 | // Released to the public domain! Enjoy! 3 | // No changes from RTClib.h 4 | 5 | #ifndef _RTCLIB_H_ 6 | #define _RTCLIB_H_ 7 | 8 | // Simple general-purpose date/time class (no TZ / DST / leap second handling!) 9 | class DateTime { 10 | public: 11 | DateTime(uint32_t t = 0); 12 | DateTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour = 0, 13 | uint8_t min = 0, uint8_t sec = 0); 14 | DateTime(const char *date, const char *time); 15 | uint16_t year() const { return 2000 + yOff; } 16 | uint8_t month() const { return m; } 17 | uint8_t day() const { return d; } 18 | uint8_t hour() const { return hh; } 19 | uint8_t minute() const { return mm; } 20 | uint8_t second() const { return ss; } 21 | uint8_t dayOfWeek() const; 22 | 23 | // 32-bit times as seconds since 1/1/2000 24 | long secondstime() const; 25 | // 32-bit times as seconds since 1/1/1970 26 | uint32_t unixtime(void) const; 27 | 28 | protected: 29 | uint8_t yOff, m, d, hh, mm, ss; 30 | }; 31 | 32 | // RTC based on the DS1307 chip connected via I2C and the Wire library 33 | class RTC_DS1307 { 34 | public: 35 | static uint8_t begin(void); 36 | static void adjust(const DateTime &dt); 37 | uint8_t isrunning(void); 38 | static DateTime now(); 39 | }; 40 | 41 | // RTC using the internal millis() clock, has to be initialized before use 42 | // NOTE: this clock won't be correct once the millis() timer rolls over (>49d?) 43 | class RTC_Millis { 44 | public: 45 | static void begin(const DateTime &dt) { adjust(dt); } 46 | static void adjust(const DateTime &dt); 47 | static DateTime now(); 48 | 49 | protected: 50 | static long offset; 51 | }; 52 | 53 | #endif // _RTCLIB_H_ 54 | -------------------------------------------------------------------------------- /examples/Trinket_Meter/Trinket_Meter.ino: -------------------------------------------------------------------------------- 1 | // Adafruit Trinket analog meter clock 2 | // Date and time functions using a DS1307 RTC connected via I2C and the TinyWireM lib 3 | 4 | // Download these libraries from Adafruit's Github repository and install in Arduino Libraries 5 | #include 6 | #include 7 | 8 | //For debug, uncomment serial code, use a FTDI Friend with its RX pin connected to Pin 3 9 | // You will need a terminal program (such as freeware PuTTY for Windows) set to the 10 | // USB port of the FTDI friend at 9600 baud. Uncomment out Serial commands to see what's up 11 | //#include // See http://forum.arduino.cc/index.php?topic=112013.0 12 | 13 | #define HOUR_PIN 1 // Hour display via PWM on Trinket GPIO #1 14 | #define MINUTE_PIN 4 // Minute display via PWM on Trinket GPIO #4 (via Timer 1 calls) 15 | 16 | //SendOnlySoftwareSerial Serial(3); // Serial transmission on Trinket Pin 3 17 | RTC_DS1307 rtc; // Set up real time clock 18 | 19 | void setup () { 20 | pinMode(HOUR_PIN, OUTPUT); // define PWM meter pins as outputs 21 | pinMode(MINUTE_PIN, OUTPUT); 22 | PWM4_init(); // Set timer 1 to work PWM on Trinket Pin 4 23 | 24 | TinyWireM.begin(); // Begin I2C 25 | rtc.begin(); // Begin DS1307 real time clock 26 | //Serial.begin(9600); // Begin Serial Monitor at 9600 baud 27 | if (! rtc.isrunning()) { // Uncomment lines below first use of clock to set time 28 | //Serial.println("RTC is NOT running!"); 29 | // following line sets the RTC to the date & time this sketch was compiled 30 | //rtc.adjust(DateTime(__DATE__, __TIME__)); 31 | } 32 | } 33 | 34 | void loop () { 35 | uint8_t hourvalue, minutevalue; 36 | uint8_t hourvoltage, minutevoltage; 37 | 38 | DateTime now = rtc.now(); // Get the RTC info 39 | hourvalue = now.hour(); // Get the hour 40 | if(hourvalue > 12) hourvalue -= 12; // This clock is 12 hour, is 13-24, convert to 1-12 41 | minutevalue = now.minute(); // Get the minutes 42 | // if you have calibration issues, you can change the last two values (zero higher, 255 lower) 43 | // to have the needle move less if your scale is not pasted on 100% straight. 44 | hourvoltage = map(hourvalue, 0, 12, 0, 255); // Convert hour to PWM duty cycle 45 | minutevoltage = map(minutevalue, 0, 60, 0, 255); // Convert minutes to PWM duty cycle 46 | /* 47 | // Uncomment out this and other serial code to check that your clock is working. 48 | Serial.print(now.year(), DEC); 49 | Serial.print('/'); 50 | Serial.print(now.month(), DEC); 51 | Serial.print('/'); 52 | Serial.print(now.day(), DEC); 53 | Serial.print(' '); 54 | Serial.print(now.hour(), DEC); 55 | Serial.print(':'); 56 | Serial.print(now.minute(), DEC); 57 | Serial.print(':'); 58 | Serial.print(now.second(), DEC); 59 | Serial.print(" - "); 60 | Serial.print(hourvoltage, DEC); 61 | Serial.print(' '); 62 | Serial.print(minutevoltage, DEC); 63 | Serial.println(); 64 | */ 65 | analogWrite(HOUR_PIN, hourvoltage); 66 | analogWrite4(minutevoltage); 67 | 68 | // code to put the processor to sleep might be preferable - we will delay 69 | delay(5000); // check time every 5 seconds. You can change this. 70 | } 71 | 72 | void PWM4_init() { 73 | // Set up PWM on Trinket GPIO #4 (PB4, pin 3) using Timer 1 74 | TCCR1 = _BV (CS10); // no prescaler 75 | GTCCR = _BV (COM1B1) | _BV (PWM1B); // clear OC1B on compare 76 | OCR1B = 127; // duty cycle initialize to 50% 77 | OCR1C = 255; // frequency 78 | } 79 | 80 | // Function to allow analogWrite on Trinket GPIO #4 81 | void analogWrite4(uint8_t duty_value) { 82 | OCR1B = duty_value; // duty may be 0 to 255 (0 to 100%) 83 | } 84 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For TinyRTC 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | DateTime KEYWORD1 10 | RTC_DS1307 KEYWORD1 11 | RTC_Millis KEYWORD1 12 | 13 | ####################################### 14 | # Methods and Functions (KEYWORD2) 15 | ####################################### 16 | 17 | year KEYWORD2 18 | month KEYWORD2 19 | day KEYWORD2 20 | hour KEYWORD2 21 | minute KEYWORD2 22 | second KEYWORD2 23 | dayOfWeek KEYWORD2 24 | secondstime KEYWORD2 25 | unixtime KEYWORD2 26 | begin KEYWORD2 27 | adjust KEYWORD2 28 | isrunning KEYWORD2 29 | now KEYWORD2 30 | 31 | ####################################### 32 | # Constants (LITERAL1) 33 | ####################################### 34 | 35 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=TinyRTCLib 2 | version=1.1.2 3 | author=Adafruit 4 | maintainer=Adafruit 5 | sentence=A tiny version of RTCLib, for use with TinyWireM 6 | paragraph=A tiny version of RTCLib, for use with TinyWireM 7 | category=Timing 8 | url=https://github.com/adafruit/TinyRTCLib 9 | architectures=* 10 | depends=TinyWireM 11 | --------------------------------------------------------------------------------