├── README ├── examples ├── SRAM │ └── SRAM.pde ├── MAC │ └── MAC.pde └── RTC │ └── RTC.pde ├── MCP7941x.h └── MCP7941x.cpp /README: -------------------------------------------------------------------------------- 1 | Arduino Library for using the MCP7941x IC. 2 | 3 | Only currently supports 24hr clock and doesn't do any validation. 4 | 5 | The MCP79411 is an I2C RTC chip which also includes 1K of EEPROM, 6 | 64 bytes of SRAM and a Unique ID. 7 | 8 | There are 3 flavours of the MCP7941x, which differ in the Unique ID content: 9 | MCP79410 - Blank 10 | MCP79411 - EUI-48 Mac Address 11 | MCP79412 - EUI-64 Mac Address 12 | 13 | -------------------------------------------------------------------------------- /examples/SRAM/SRAM.pde: -------------------------------------------------------------------------------- 1 | /* 2 | Example for the MCP7941x Library - Set/Get SRAM Data 3 | 4 | Ian Chilton 5 | November 2011 6 | */ 7 | 8 | #include "Wire.h" 9 | #include "MCP7941x.h" 10 | 11 | // Create new instance of class: 12 | MCP7941x rtc = MCP7941x(); 13 | 14 | void setup() 15 | { 16 | Serial.begin(9600); 17 | 18 | // Write 64 bytes of data: 19 | for( int i=0; i<64; i++ ) 20 | { 21 | rtc.setSramByte(0x20 + i, i); 22 | } 23 | 24 | // Read 64 bytes of data: 25 | for( int i=0; i<64; i++ ) 26 | { 27 | Serial.print(0x20 + i, HEX); 28 | Serial.print(" = "); 29 | Serial.println(rtc.getSramByte(0x20 + i), HEX); 30 | } 31 | } 32 | 33 | 34 | void loop() 35 | { 36 | // Sleep for 1s: 37 | delay(1000); 38 | } 39 | 40 | -------------------------------------------------------------------------------- /examples/MAC/MAC.pde: -------------------------------------------------------------------------------- 1 | /* 2 | Example for the MCP7941x Library - Read MAC Address 3 | 4 | Ian Chilton 5 | November 2011 6 | */ 7 | 8 | #include "Wire.h" 9 | #include "MCP7941x.h" 10 | 11 | static uint8_t mymac[6] = { 0,0,0,0,0,0 }; 12 | 13 | // Create new instance of class: 14 | MCP7941x rtc = MCP7941x(); 15 | 16 | 17 | void setup() 18 | { 19 | Serial.begin(9600); 20 | 21 | // Get the mac address and store in mymac: 22 | rtc.getMacAddress(mymac); 23 | } 24 | 25 | 26 | void loop() 27 | { 28 | // Print the mac address: 29 | for( int i=0; i<6; i++ ) 30 | { 31 | if (mymac[i] < 10) 32 | { 33 | Serial.print(0); 34 | } 35 | 36 | Serial.print( mymac[i], HEX ); 37 | Serial.print( i < 5 ? ":" : "" ); 38 | } 39 | 40 | Serial.println(); 41 | 42 | // Sleep for 10s: 43 | delay(10000); 44 | } 45 | 46 | -------------------------------------------------------------------------------- /MCP7941x.h: -------------------------------------------------------------------------------- 1 | /* 2 | MCP7941x.h - Arduino Library for using the MCP7941x IC. 3 | 4 | Ian Chilton 5 | November 2011 6 | */ 7 | 8 | #ifndef MCP7941x_h 9 | #define MCP7941x_h 10 | 11 | #define MCP7941x_EEPROM_I2C_ADDR 0x57 12 | #define MAC_LOCATION 0xF2 // Starts at 0xF0 but we are only interested in 6 bytes. 13 | 14 | #define MCP7941x_RTC_I2C_ADDR 0x6F 15 | #define RTC_LOCATION 0x00 16 | 17 | 18 | #if (ARDUINO >= 100) 19 | #include 20 | #else 21 | #include 22 | #endif 23 | 24 | 25 | class MCP7941x 26 | { 27 | public: 28 | 29 | MCP7941x(); 30 | 31 | byte decToBcd ( byte val ); 32 | byte bcdToDec ( byte val ); 33 | 34 | void getMacAddress ( byte *mac_address ); 35 | void unlockUniqueID(); 36 | void writeMacAddress ( byte *mac_address ); 37 | 38 | void setDateTime ( byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year ); 39 | void getDateTime ( byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year ); 40 | void enableClock (); 41 | void disableClock (); 42 | void enableBattery (); 43 | 44 | void setSramByte ( byte location, byte data ); 45 | byte getSramByte ( byte location ); 46 | 47 | private: 48 | 49 | }; 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /examples/RTC/RTC.pde: -------------------------------------------------------------------------------- 1 | /* 2 | Example for the MCP7941x Library - Set/Get Date/Time 3 | 4 | Ian Chilton 5 | November 2011 6 | */ 7 | 8 | #include "Wire.h" 9 | #include "MCP7941x.h" 10 | 11 | // Create new instance of class: 12 | MCP7941x rtc = MCP7941x(); 13 | 14 | 15 | void displayDateTime( 16 | byte second, 17 | byte minute, 18 | byte hour, 19 | byte dayOfWeek, 20 | byte dayOfMonth, 21 | byte month, 22 | byte year) 23 | { 24 | if (hour < 10) 25 | { 26 | Serial.print("0"); 27 | } 28 | 29 | Serial.print(hour, DEC); 30 | Serial.print(":"); 31 | 32 | if (minute < 10) 33 | { 34 | Serial.print("0"); 35 | } 36 | 37 | Serial.print(minute, DEC); 38 | Serial.print(":"); 39 | 40 | if (second < 10) 41 | { 42 | Serial.print("0"); 43 | } 44 | 45 | Serial.print(second, DEC); 46 | Serial.print(" "); 47 | 48 | if (dayOfMonth < 10) 49 | { 50 | Serial.print("0"); 51 | } 52 | 53 | Serial.print(dayOfMonth, DEC); 54 | Serial.print("/"); 55 | 56 | if (month < 10) 57 | { 58 | Serial.print("0"); 59 | } 60 | 61 | Serial.print(month, DEC); 62 | Serial.print("/"); 63 | 64 | Serial.print(year, DEC); 65 | 66 | Serial.print(" ("); 67 | 68 | switch(dayOfWeek) 69 | { 70 | case 1: 71 | Serial.print("Sunday"); 72 | break; 73 | 74 | case 2: 75 | Serial.print("Monday"); 76 | break; 77 | 78 | case 3: 79 | Serial.print("Tuesday"); 80 | break; 81 | 82 | case 4: 83 | Serial.print("Wednesday"); 84 | break; 85 | 86 | case 5: 87 | Serial.print("Thursday"); 88 | break; 89 | 90 | case 6: 91 | Serial.print("Friday"); 92 | break; 93 | 94 | case 7: 95 | Serial.print("Saturday"); 96 | break; 97 | } 98 | 99 | Serial.println(")"); 100 | } 101 | 102 | 103 | void setup() 104 | { 105 | Serial.begin(9600); 106 | 107 | byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; 108 | 109 | // Set the time? 110 | boolean setTime = false; 111 | 112 | // If you have a battery, you should only need to do the set once and after that, 113 | // it should remember the date/time even when the power is off. 114 | 115 | // Set these to the values you want to set the date/time to: 116 | second = 0; 117 | minute = 59; 118 | hour = 23; 119 | dayOfWeek = 3; // 1 = Sunday, 7 = Saturday 120 | dayOfMonth = 8; 121 | month = 11; 122 | year = 11; 123 | 124 | if (setTime == true) 125 | { 126 | // Set the Date/Time: 127 | rtc.setDateTime(second, minute, hour, dayOfWeek, dayOfMonth, month, year); 128 | } 129 | else 130 | { 131 | // Enable (start) the clock without changing it: 132 | rtc.enableClock(); 133 | } 134 | } 135 | 136 | 137 | void loop() 138 | { 139 | byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; 140 | 141 | // Get the date/time from the RTC: 142 | rtc.getDateTime(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); 143 | 144 | // Display the Date/Time on the serial line: 145 | displayDateTime(second, minute, hour, dayOfWeek, dayOfMonth, month, year); 146 | 147 | // Sleep for 1s: 148 | delay(1000); 149 | } 150 | 151 | -------------------------------------------------------------------------------- /MCP7941x.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MCP7941x.cpp - Arduino Library for using the MCP7941x IC. 3 | 4 | Ian Chilton 5 | November 2011 6 | 7 | Only currently supports 24hr clock and doesn't do any validation. 8 | */ 9 | 10 | 11 | #if (ARDUINO >= 100) 12 | #include 13 | #define WireSend(x) Wire.write(x) 14 | #define WireReceive() Wire.read() 15 | #else 16 | #include 17 | #define WireSend(x) Wire.send(x) 18 | #define WireReceive(x) Wire.receive(x) 19 | #endif 20 | 21 | #include "Wire.h" 22 | 23 | #include "MCP7941x.h" 24 | 25 | 26 | // Constructor: 27 | MCP7941x::MCP7941x() 28 | { 29 | Wire.begin(); 30 | } 31 | 32 | 33 | // Convert normal decimal numbers to binary coded decimal: 34 | byte MCP7941x::decToBcd(byte val) 35 | { 36 | return ( (val/10*16) + (val%10) ); 37 | } 38 | 39 | 40 | // Convert binary coded decimal to normal decimal numbers: 41 | byte MCP7941x::bcdToDec(byte val) 42 | { 43 | return ( (val/16*10) + (val%16) ); 44 | } 45 | 46 | 47 | // Function to read the mac address from the eeprom: 48 | void MCP7941x::getMacAddress(byte *mac_address) 49 | { 50 | Wire.beginTransmission(MCP7941x_EEPROM_I2C_ADDR); 51 | WireSend(MAC_LOCATION); 52 | Wire.endTransmission(); 53 | 54 | Wire.requestFrom(MCP7941x_EEPROM_I2C_ADDR, 6); 55 | 56 | for( int i=0; i<6; i++ ) 57 | { 58 | mac_address[i] = WireReceive(); 59 | } 60 | } 61 | 62 | 63 | // Unlock the unique id area ready for writing: 64 | void MCP7941x::unlockUniqueID() 65 | { 66 | // Write 0x55 to the memory location 0x09 and stop: 67 | Wire.beginTransmission(MCP7941x_RTC_I2C_ADDR); 68 | WireSend(0x09); 69 | WireSend(0x55); 70 | Wire.endTransmission(); 71 | 72 | // Write 0xAA to the memory location 0x09 and stop: 73 | Wire.beginTransmission(MCP7941x_RTC_I2C_ADDR); 74 | WireSend(0x09); 75 | WireSend(0xAA); 76 | Wire.endTransmission(); 77 | } 78 | 79 | 80 | // Unlock the unique id area and write in the mac address: 81 | void MCP7941x::writeMacAddress(byte *mac_address) 82 | { 83 | Wire.beginTransmission(MCP7941x_EEPROM_I2C_ADDR); 84 | WireSend(0xF2); 85 | 86 | for( int i=0; i<6; i++ ) 87 | { 88 | WireSend(mac_address[i]); 89 | } 90 | 91 | Wire.endTransmission(); 92 | } 93 | 94 | 95 | // Set the date/time, set to 24hr and enable the clock: 96 | // (assumes you're passing in valid numbers) 97 | void MCP7941x::setDateTime( 98 | byte second, // 0-59 99 | byte minute, // 0-59 100 | byte hour, // 1-23 101 | byte dayOfWeek, // 1-7 102 | byte dayOfMonth, // 1-28/29/30/31 103 | byte month, // 1-12 104 | byte year) // 0-99 105 | { 106 | Wire.beginTransmission(MCP7941x_RTC_I2C_ADDR); 107 | WireSend(RTC_LOCATION); 108 | 109 | WireSend(decToBcd(second) & 0x7f); // set seconds and disable clock (01111111) 110 | WireSend(decToBcd(minute) & 0x7f); // set minutes (01111111) 111 | WireSend(decToBcd(hour) & 0x3f); // set hours and to 24hr clock (00111111) 112 | WireSend(0x08 | (decToBcd(dayOfWeek) & 0x07)); // set the day and enable battery backup (00000111)|(00001000) 113 | WireSend(decToBcd(dayOfMonth) & 0x3f); // set the date in month (00111111) 114 | WireSend(decToBcd(month) & 0x1f); // set the month (00011111) 115 | WireSend(decToBcd(year)); // set the year (11111111) 116 | 117 | Wire.endTransmission(); 118 | 119 | // Start Clock: 120 | Wire.beginTransmission(MCP7941x_RTC_I2C_ADDR); 121 | WireSend(RTC_LOCATION); 122 | WireSend(decToBcd(second) | 0x80); // set seconds and enable clock (10000000) 123 | Wire.endTransmission(); 124 | } 125 | 126 | 127 | // Get the date/time: 128 | void MCP7941x::getDateTime( 129 | byte *second, 130 | byte *minute, 131 | byte *hour, 132 | byte *dayOfWeek, 133 | byte *dayOfMonth, 134 | byte *month, 135 | byte *year) 136 | { 137 | Wire.beginTransmission(MCP7941x_RTC_I2C_ADDR); 138 | WireSend(RTC_LOCATION); 139 | Wire.endTransmission(); 140 | 141 | Wire.requestFrom(MCP7941x_RTC_I2C_ADDR, 7); 142 | 143 | // A few of these need masks because certain bits are control bits 144 | *second = bcdToDec(WireReceive() & 0x7f); // 01111111 145 | *minute = bcdToDec(WireReceive() & 0x7f); // 01111111 146 | *hour = bcdToDec(WireReceive() & 0x3f); // 00111111 147 | *dayOfWeek = bcdToDec(WireReceive() & 0x07); // 01111111 148 | *dayOfMonth = bcdToDec(WireReceive() & 0x3f); // 00111111 149 | *month = bcdToDec(WireReceive() & 0x1f); // 00011111 150 | *year = bcdToDec(WireReceive()); // 11111111 151 | } 152 | 153 | 154 | // Enable the clock without changing the date/time: 155 | void MCP7941x::enableClock() 156 | { 157 | // Get the current seconds value as the enable/disable bit is in the same 158 | // byte of memory as the seconds value: 159 | Wire.beginTransmission(MCP7941x_RTC_I2C_ADDR); 160 | WireSend(RTC_LOCATION); 161 | Wire.endTransmission(); 162 | 163 | Wire.requestFrom(MCP7941x_RTC_I2C_ADDR, 1); 164 | 165 | int second = bcdToDec(WireReceive() & 0x7f); // 01111111 166 | 167 | // Start Clock: 168 | Wire.beginTransmission(MCP7941x_RTC_I2C_ADDR); 169 | WireSend(RTC_LOCATION); 170 | WireSend(decToBcd(second) | 0x80); // set seconds and enable clock (10000000) 171 | Wire.endTransmission(); 172 | } 173 | 174 | 175 | // Disable the clock without changing the date/time: 176 | void MCP7941x::disableClock() 177 | { 178 | // Get the current seconds value as the enable/disable bit is in the same 179 | // byte of memory as the seconds value: 180 | Wire.beginTransmission(MCP7941x_RTC_I2C_ADDR); 181 | WireSend(RTC_LOCATION); 182 | Wire.endTransmission(); 183 | 184 | Wire.requestFrom(MCP7941x_RTC_I2C_ADDR, 1); 185 | 186 | int second = bcdToDec(WireReceive() & 0x7f); // 01111111 187 | 188 | // Start Clock: 189 | Wire.beginTransmission(MCP7941x_RTC_I2C_ADDR); 190 | WireSend(RTC_LOCATION); 191 | WireSend(decToBcd(second)); // set seconds and disable clock (01111111) 192 | Wire.endTransmission(); 193 | } 194 | 195 | 196 | 197 | // Enable the battery: 198 | void MCP7941x::enableBattery() 199 | { 200 | // Get the current seconds value as the enable/disable bit is in the same 201 | // byte of memory as the seconds value: 202 | Wire.beginTransmission(MCP7941x_RTC_I2C_ADDR); 203 | WireSend(RTC_LOCATION + 0x03); 204 | Wire.endTransmission(); 205 | 206 | Wire.requestFrom(MCP7941x_RTC_I2C_ADDR, 1); 207 | 208 | int day = bcdToDec(WireReceive() & 0x07); // 00000111 209 | 210 | // Start Clock: 211 | Wire.beginTransmission(MCP7941x_RTC_I2C_ADDR); 212 | WireSend(RTC_LOCATION + 0x03); 213 | WireSend(decToBcd(day) | 0x08); // set day and enable battery (00001000) 214 | Wire.endTransmission(); 215 | } 216 | 217 | 218 | // Store byte of data in SRAM: 219 | void MCP7941x::setSramByte ( byte location, byte data ) 220 | { 221 | if (location >= 0x20 && location <= 0x5f) 222 | { 223 | Wire.beginTransmission(MCP7941x_RTC_I2C_ADDR); 224 | WireSend(location); 225 | WireSend(data); 226 | Wire.endTransmission(); 227 | } 228 | } 229 | 230 | 231 | // Read byte of data from SRAM: 232 | byte MCP7941x::getSramByte ( byte location ) 233 | { 234 | if (location >= 0x20 && location <= 0x5f) 235 | { 236 | Wire.beginTransmission(MCP7941x_RTC_I2C_ADDR); 237 | WireSend(location); 238 | Wire.endTransmission(); 239 | 240 | Wire.requestFrom(MCP7941x_RTC_I2C_ADDR, 1); 241 | 242 | return WireReceive(); 243 | } 244 | } 245 | 246 | --------------------------------------------------------------------------------