Skip to content

Commit

Permalink
At24c32 (#71)
Browse files Browse the repository at this point in the history
* support At24C32 memory

This is the often included eeprom on DS3231 boards

* new version
  • Loading branch information
Makuna committed Aug 27, 2018
1 parent a6fee95 commit 46349c9
Show file tree
Hide file tree
Showing 8 changed files with 287 additions and 17 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -7,6 +7,7 @@ An RTC library with deep device support.

Now supports esp8266.
Now supports SoftwareWire library.
Now supports AT24C32 EEPROM which is often included on on DS3231 boards

For quick questions jump on Gitter and ask away.
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Makuna/Rtc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
Expand Down
5 changes: 2 additions & 3 deletions examples/DS1307_Memory/DS1307_Memory.ino
Expand Up @@ -119,10 +119,9 @@ void loop ()
Serial.print("data read (");
Serial.print(gotten);
Serial.print(") = \"");
while (gotten > 0)
for (uint8_t ch = 0; ch < gotten; ch++)
{
Serial.print((char)buff[count - gotten]);
gotten--;
Serial.print((char)buff[ch]);
}
Serial.println("\"");
}
Expand Down
175 changes: 175 additions & 0 deletions examples/DS3231_Memory/DS3231_Memory.ino
@@ -0,0 +1,175 @@

// CONNECTIONS:
// DS1307 SDA --> SDA
// DS1307 SCL --> SCL
// DS1307 VCC --> 5v
// DS1307 GND --> GND

#define countof(a) (sizeof(a) / sizeof(a[0]))

/* for software wire use below
#include <SoftwareWire.h> // must be included here so that Arduino library object file references work
#include <RtcDS3231.h>
#include <EepromAt24C32.h>
SoftwareWire myWire(SDA, SCL);
RtcDS1307<SoftwareWire> Rtc(myWire);
/* for software wire use above */

/* for normal hardware wire use below */
#include <Wire.h> // must be included here so that Arduino library object file references work
#include <RtcDS3231.h>
#include <EepromAt24C32.h>

RtcDS3231<TwoWire> Rtc(Wire);
EepromAt24c32<TwoWire> RtcEeprom(Wire);

// if you have any of the address pins on the RTC soldered together
// then you need to provide the state of those pins, normally they
// are connected to vcc with a reading of 1, if soldered they are
// grounded with a reading of 0. The bits are in the order A2 A1 A0
// thus the following would have the A2 soldered together
// EepromAt24c32<TwoWire> RtcEeprom(Wire, 0b011);

/* for normal hardware wire use above */

// nothing longer than 32 bytes
// rtc eeprom memory is 32 byte pages
// writing is limited to each page, so it will wrap at page
// boundaries.
// But reading is only limited by the buffer in Wire class which
// by default is 32
const char data[] = "What time is it in Greenwich?";
const uint16_t stringAddr = 64; // stored on page boundary

void setup ()
{
Serial.begin(57600);

Serial.print("compiled: ");
Serial.print(__DATE__);
Serial.println(__TIME__);

//--------RTC SETUP ------------
// if you are using ESP-01 then uncomment the line below to reset the pins to
// the available pins for SDA, SCL
// Wire.begin(0, 2); // due to limited pins, use pin 0 and 2 for SDA, SCL

Rtc.Begin();
RtcEeprom.Begin();

RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
printDateTime(compiled);
Serial.println();

if (!Rtc.IsDateTimeValid())
{
Serial.println("RTC lost confidence in the DateTime!");
Rtc.SetDateTime(compiled);
}

if (!Rtc.GetIsRunning())
{
Serial.println("RTC was not actively running, starting now");
Rtc.SetIsRunning(true);
}

RtcDateTime now = Rtc.GetDateTime();
if (now < compiled)
{
Serial.println("RTC is older than compile time! (Updating DateTime)");
Rtc.SetDateTime(compiled);
}

// never assume the Rtc was last configured by you, so
// just clear them to your needed state
Rtc.Enable32kHzPin(false);
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);

/* comment out on a second run to see that the info is stored long term */
// Store something in memory on the Eeprom

// store starting address of string
RtcEeprom.SetMemory(0, stringAddr);
// store the string, nothing longer than 32 bytes due to paging
uint8_t written = RtcEeprom.SetMemory(stringAddr, (const uint8_t*)data, sizeof(data) - 1); // remove the null terminator strings add
// store the length of the string
RtcEeprom.SetMemory(1, written); // store the
/* end of comment out section */
}

void loop ()
{
if (!Rtc.IsDateTimeValid())
{
// Common Cuases:
// 1) the battery on the device is low or even missing and the power line was disconnected
Serial.println("RTC lost confidence in the DateTime!");
}

RtcDateTime now = Rtc.GetDateTime();

printDateTime(now);
Serial.println();

delay(5000);

// read data

// get the offset we stored our data from address zero
uint8_t address = RtcEeprom.GetMemory(0);
if (address != stringAddr)
{
Serial.print("address didn't match ");
Serial.println(address);
}

{
// get the size of the data from address 1
uint8_t count = RtcEeprom.GetMemory(1);
uint8_t buff[64];

// get our data from the address with the given size
uint8_t gotten = RtcEeprom.GetMemory(address, buff, count);

if (gotten != count ||
count != sizeof(data) - 1) // remove the extra null terminator strings add
{
Serial.print("something didn't match, count = ");
Serial.print(count, DEC);
Serial.print(", gotten = ");
Serial.print(gotten, DEC);
Serial.println();
}
Serial.print("data read (");
Serial.print(gotten);
Serial.print(") = \"");
for (uint8_t ch = 0; ch < gotten; ch++)
{
Serial.print((char)buff[ch]);
}
Serial.println("\"");
}


delay(5000);
}



void printDateTime(const RtcDateTime& dt)
{
char datestring[20];

snprintf_P(datestring,
countof(datestring),
PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
dt.Month(),
dt.Day(),
dt.Year(),
dt.Hour(),
dt.Minute(),
dt.Second() );
Serial.print(datestring);
}

1 change: 1 addition & 0 deletions keywords.txt
Expand Up @@ -9,6 +9,7 @@
DS3231AlarmOne KEYWORD1
DS3231AlarmTwo KEYWORD1
RtcDS3231 KEYWORD1
EepromAt24c32 KEYWORD1
RtcTemperature KEYWORD1
RtcDateTime KEYWORD1
DayOfWeek KEYWORD1
Expand Down
21 changes: 10 additions & 11 deletions library.json
@@ -1,14 +1,13 @@
{
"name": "RTC",
"keywords": "RTC, DS1307, DS3231, clock",
"description": "A library that makes interfacing DS1307 and DS3231 Real Time Clock modules easy.",
"repository":
{
"type": "git",
"url": "https://github.com/Makuna/Rtc.git"
},
"version": "2.1.1",
"frameworks": "arduino",
"platforms": "*"
"name": "RTC",
"keywords": "RTC, DS1307, DS3231, AT24C32, clock",
"description": "A library that makes interfacing DS1307 and DS3231 Real Time Clock modules easy.",
"repository": {
"type": "git",
"url": "https://github.com/Makuna/Rtc.git"
},
"version": "2.1.2",
"frameworks": "arduino",
"platforms": "*"
}

2 changes: 1 addition & 1 deletion library.properties
@@ -1,5 +1,5 @@
name=Rtc by Makuna
version=2.1.1
version=2.1.2
author=Michael C. Miller (makuna@live.com)
maintainer=Michael C. Miller (makuna@live.com)
sentence=A library that makes interfacing DS1307 and DS3231 Real Time Clock modules easy.
Expand Down
95 changes: 95 additions & 0 deletions src/EepromAT24C32.h
@@ -0,0 +1,95 @@
#pragma once

//I2C Slave Address
const uint8_t AT24C32_ADDRESS = 0x50; // 0b0 1010 A2 A1 A0

template<class T_WIRE_METHOD> class EepromAt24c32
{
public:
EepromAt24c32(T_WIRE_METHOD& wire, uint8_t addressBits = 0b111) :
_address(AT24C32_ADDRESS | (addressBits & 0b00000111)),
_wire(wire)
{
}

void Begin()
{
_wire.begin();
}

void SetMemory(uint16_t memoryAddress, uint8_t value)
{
SetMemory(memoryAddress, &value, 1);
}

uint8_t GetMemory(uint16_t memoryAddress)
{
uint8_t value;

GetMemory(memoryAddress, &value, 1);

return value;
}

// note: this method will write within a single page of eeprom.
// Pages are 32 bytes (5 bits), so writing past a page boundary will
// just wrap within the page of the starting memory address.
//
// xxxppppp pppaaaaa => p = page #, a = address within the page
//
uint8_t SetMemory(uint16_t memoryAddress, const uint8_t* pValue, uint8_t countBytes)
{
uint8_t countWritten = 0;

beginTransmission(memoryAddress);

while (countBytes > 0)
{
_wire.write(*pValue++);
delay(10); // per spec, memory writes

countBytes--;
countWritten++;
}

_wire.endTransmission();

return countWritten;
}

// reading data doea not wrap within pages, but due to only using
// 12 (32K) or 13 (64K) bits are used, they will wrap within the memory limits
// of the installed EEPROM
uint8_t GetMemory(uint16_t memoryAddress, uint8_t* pValue, uint8_t countBytes)
{
// set address to read from
beginTransmission(memoryAddress);
_wire.endTransmission();

// read the data
uint8_t countRead = 0;

countRead = _wire.requestFrom(_address, countBytes);
countBytes = countRead;

while (countBytes-- > 0)
{
*pValue++ = _wire.read();
}

return countRead;
}

private:
const uint8_t _address;

T_WIRE_METHOD& _wire;

void beginTransmission(uint16_t memoryAddress)
{
_wire.beginTransmission(_address);
_wire.write(memoryAddress >> 8);
_wire.write(memoryAddress & 0xFf);

}
};
4 changes: 2 additions & 2 deletions src/RtcDS1307.h
Expand Up @@ -180,12 +180,12 @@ template<class T_WIRE_METHOD> class RtcDS1307
_wire.write(address);
_wire.endTransmission();

_wire.requestFrom(DS1307_ADDRESS, countBytes);
countRead = _wire.requestFrom(DS1307_ADDRESS, countBytes);
countBytes = countRead;

while (countBytes-- > 0)
{
*pValue++ = _wire.read();
countRead++;
}
}

Expand Down

0 comments on commit 46349c9

Please sign in to comment.